Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5e53d92
fix
bb1yd Jun 28, 2026
a0b3416
add safety section for mem::zeroed
hxuhack Apr 1, 2026
b78c8ac
Provide a `supertrait_def_ids()` function in rustc_type_ir's interner
ChayimFriedman2 Aug 21, 2026
940498d
fix const_item_mutation lint to use needs_drop instead of has_dtor
Rachit2323 Aug 24, 2026
98a157a
Add test for the fn item uniqueness note with late bound lifetimes
zakrad Aug 31, 2026
21228c2
Do not suppress the fn item uniqueness note for late bound lifetimes
zakrad Aug 31, 2026
ee766dc
post GH comment on types nominations
lqd Sep 18, 2026
75b444d
Constify `impl FromStr for NonZero<T>`
sorairolake Sep 6, 2026
c30f2a4
Use `end_point` for trailing brace in `let...else` diagnostics
lapla-cogito Sep 19, 2026
1b3f10d
add Dir::try_clone
RalfJung Sep 19, 2026
6524ec5
Remove incorrect parse error recovery code that mistakes `as` casts f…
fmease Sep 12, 2026
c095a72
add test
inkreasing Sep 18, 2026
fe96227
recover true and false as bool type
inkreasing Sep 18, 2026
8026b7b
bless tests
inkreasing Sep 18, 2026
e224f8f
Further simplify `parse_assoc_op_cast`
fmease Sep 12, 2026
8a0a23d
Trigger "C array" parse error recovery in far fewer cases
fmease Sep 12, 2026
2e15f7b
Better account for `Self` that might be a typo of `self`
estebank Jul 27, 2026
09fb849
Detect more cases of method shadowing with incorrect arguments
estebank Mar 9, 2026
c28b7a9
Use verbose suggestion for parenthetical `Fn` notation and fully-qual…
estebank Sep 19, 2026
9c1bd2d
Add mod_id to TypeckRootCtxt
camsteffen Jul 23, 2026
06f21bf
Restrict Visibility methods to ModId
camsteffen Jul 23, 2026
e710a60
Prefer ModId in more places
camsteffen Jul 23, 2026
2532b72
Use ModId more in late lint pass
camsteffen Jul 23, 2026
837ce84
Add .seek_read_exact(), .seek_write_all() to std::os::windows::fs::Fi…
json420 Sep 20, 2026
dff5c55
Rollup merge of #158515 - bb1yd:let-else-detect-invisible-delimiter, …
mu001999 Sep 20, 2026
d773407
Rollup merge of #160028 - estebank:issue-91525, r=jackh726
mu001999 Sep 20, 2026
d0f47c8
Rollup merge of #160097 - Rachit2323:const-mutation-needs-drop, r=jac…
mu001999 Sep 20, 2026
4cacf17
Rollup merge of #161435 - ChayimFriedman2:supertraits-query, r=jackh726
mu001999 Sep 20, 2026
a4e0bbb
Rollup merge of #161894 - zakrad:fix-fn-item-note-late-bound-145558, …
mu001999 Sep 20, 2026
e398c65
Rollup merge of #162990 - lqd:types-magic, r=Mark-Simulacrum
mu001999 Sep 20, 2026
fdd54bd
Rollup merge of #153662 - estebank:suggest-fully-qualified-path, r=da…
mu001999 Sep 20, 2026
e0677bb
Rollup merge of #154665 - safer-rust:fix-doc, r=Mark-Simulacrum
mu001999 Sep 20, 2026
a40454f
Rollup merge of #159787 - camsteffen:fnctxt-modid, r=mu001999
mu001999 Sep 20, 2026
a49b3c8
Rollup merge of #162700 - fmease:rm-dead-ascr-recov, r=fee1-dead
mu001999 Sep 20, 2026
5435e38
Rollup merge of #162705 - fmease:fix-c-array-diag, r=JonathanBrouwer
mu001999 Sep 20, 2026
797bcaf
Rollup merge of #162875 - json420:seek_read_exact, r=clarfonthey
mu001999 Sep 20, 2026
955bef3
Rollup merge of #162988 - inkreasing:attempt2-fix-162947, r=chenyukang
mu001999 Sep 20, 2026
fe2cec8
Rollup merge of #162995 - sorairolake:const-nonzero-from-str, r=jhpratt
mu001999 Sep 20, 2026
96c6172
Rollup merge of #163006 - lapla-cogito:letelse_fullwidthbrace, r=folk…
mu001999 Sep 20, 2026
55518ef
Rollup merge of #163007 - RalfJung:dirfd-clone, r=ChrisDenton
mu001999 Sep 20, 2026
0cf807e
Rollup merge of #163039 - estebank:fn-paren-sugg, r=fmease
mu001999 Sep 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::*;
use rustc_index::IndexVec;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::CRATE_MOD_ID;
use rustc_span::{DUMMY_SP, Span, span_bug};
use tracing::{debug, instrument};

Expand Down Expand Up @@ -48,9 +49,7 @@ pub(super) fn index_hir<'hir>(
};

match item {
OwnerNode::Crate(citem) => {
collector.visit_mod(citem, citem.spans.inner_span, hir::CRATE_HIR_ID)
}
OwnerNode::Crate(citem) => collector.visit_mod(citem, citem.spans.inner_span, CRATE_MOD_ID),
OwnerNode::Item(item) => collector.visit_item(item),
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ use rustc_ast::Label;
use rustc_ast::visit::{VisitorResult, try_visit, visit_opt, walk_list};
use rustc_attr_ir::Attribute;
use rustc_hir_id::HirId;
use rustc_span::def_id::LocalDefId;
use rustc_span::def_id::{LocalDefId, LocalModId};
use rustc_span::{Ident, Span, Symbol};

use crate::hir::*;
Expand Down Expand Up @@ -311,7 +311,7 @@ pub trait Visitor<'v>: Sized {
fn visit_ident(&mut self, ident: Ident) -> Self::Result {
walk_ident(self, ident)
}
fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, _n: HirId) -> Self::Result {
fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, _id: LocalModId) -> Self::Result {
walk_mod(self, m)
}
fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) -> Self::Result {
Expand Down Expand Up @@ -583,7 +583,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
}
ItemKind::Mod(ident, ref module) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_mod(module, item.span, item.hir_id()));
try_visit!(visitor.visit_mod(
module,
item.span,
LocalModId::new_unchecked(item.owner_id.def_id)
));
}
ItemKind::ForeignMod { abi: _, items } => {
walk_list!(visitor, visit_foreign_item_ref, items);
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use rustc_middle::ty::{
self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized,
fold_regions,
};
use rustc_span::def_id::LocalModId;
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, span_bug, sym};
use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
use rustc_trait_selection::infer::InferCtxtExt;
Expand Down Expand Up @@ -497,6 +498,10 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
self.item_def_id
}

fn mod_id(&self) -> LocalModId {
self.tcx.parent_module_from_def_id(self.item_def_id)
}

fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
if let RegionInferReason::ObjectLifetimeDefault(sugg_sp) = reason {
// FIXME: Account for trailing plus `dyn Trait+`, the need of parens in
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Do not suggest the other syntax if we are in trait impl:
// the desugaring would contain an associated type constraint.
if !is_impl {
err.span_suggestion(
err.span_suggestion_verbose(
span,
"use parenthetical notation instead",
fn_trait_to_string(self.tcx(), trait_segment, true),
Expand Down Expand Up @@ -199,8 +199,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.visible_traits()
.filter(|trait_def_id| {
let viz = tcx.visibility(*trait_def_id);
let def_id = self.item_def_id();
viz.is_accessible_from(def_id, tcx)
viz.is_accessible_from(self.mod_id(), tcx)
})
.collect();

Expand Down Expand Up @@ -568,7 +567,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
.filter(|header| {
// Consider only accessible traits
tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
tcx.visibility(trait_def_id).is_accessible_from(self.mod_id(), tcx)
&& header.polarity != ty::ImplPolarity::Negative
})
.map(|header| header.trait_ref.instantiate_identity().skip_norm_wip().self_ty())
Expand Down Expand Up @@ -2036,7 +2035,7 @@ impl<'a, 'tcx> rustc_errors::Diagnostic<'a, ()> for AmbiguityBetweenVariantAndAs
could_refer_to(DefKind::Variant, variant_def_id, "");
could_refer_to(mode.def_kind_for_diagnostics(), item_def_id, " also");

lint.span_suggestion(
lint.span_suggestion_verbose(
span,
"use fully-qualified syntax",
format!("<{} as {}>::{}", self_ty, tcx.item_name(bound_def_id), segment_ident),
Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use rustc_middle::ty::{
const_lit_matches_ty, fold_regions,
};
use rustc_session::diagnostics::feature_err;
use rustc_span::def_id::ModId;
use rustc_span::def_id::{LocalModId, ModId};
use rustc_span::{DUMMY_SP, Ident, Span, bug, kw, span_bug, sym};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, FulfillmentError};
Expand Down Expand Up @@ -142,6 +142,9 @@ pub trait HirTyLowerer<'tcx> {
/// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered.
fn item_def_id(&self) -> LocalDefId;

/// Returns the containing module.
fn mod_id(&self) -> LocalModId;

/// Returns the region to use when a lifetime is omitted (and not elided).
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;

Expand Down Expand Up @@ -1814,7 +1817,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
) -> Option<(ty::AssocItem, /*scope*/ ModId)> {
let tcx = self.tcx();

let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, self.item_def_id());
let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, self.mod_id());
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
// `ident` again and again.
Expand Down Expand Up @@ -1879,7 +1882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
})
// Consider only accessible traits
&& tcx.visibility(*trait_def_id)
.is_accessible_from(self.item_def_id(), tcx)
.is_accessible_from(self.mod_id(), tcx)
&& tcx.all_impls(*trait_def_id)
.any(|impl_def_id| {
let header = tcx.impl_trait_header(impl_def_id);
Expand Down Expand Up @@ -3424,7 +3427,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
hir::TyKind::FieldOf(ty, hir::TyFieldPath { variant, field }) => self.lower_field_of(
self.lower_ty(ty),
self.item_def_id(),
self.mod_id(),
ty.span,
hir_ty.hir_id,
*variant,
Expand Down Expand Up @@ -3478,7 +3481,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
fn lower_field_of(
&self,
ty: Ty<'tcx>,
item_def_id: LocalDefId,
mod_id: LocalModId,
ty_span: Span,
hir_id: HirId,
variant: Option<Ident>,
Expand Down Expand Up @@ -3528,8 +3531,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
(FIRST_VARIANT, def.non_enum_variant())
};
let (ident, def_scope) =
tcx.adjust_ident_and_get_scope(field, def.did(), item_def_id);
let (ident, def_scope) = tcx.adjust_ident_and_get_scope(field, def.did(), mod_id);
if let Some((field_idx, field)) = variant
.fields
.iter_enumerated()
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_hir_id/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustc_data_structures::stable_hash::{
StableHash, StableHashCtxt, StableHasher, StableOrd, ToStableHashKey,
};
use rustc_macros::{Decodable, Encodable, StableHash};
use rustc_span::def_id::{CRATE_DEF_ID, DefId, DefIndex, DefPathHash, LocalDefId};
use rustc_span::def_id::{CRATE_DEF_ID, DefId, DefIndex, DefPathHash, LocalDefId, LocalModId};

#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
pub struct OwnerId {
Expand All @@ -42,6 +42,12 @@ impl From<OwnerId> for DefId {
}
}

impl From<LocalModId> for OwnerId {
fn from(value: LocalModId) -> Self {
OwnerId { def_id: value.to_local_def_id() }
}
}

impl OwnerId {
#[inline]
pub fn to_def_id(self) -> DefId {
Expand Down Expand Up @@ -141,6 +147,12 @@ impl fmt::Display for HirId {
}
}

impl From<LocalModId> for HirId {
fn from(id: LocalModId) -> Self {
HirId::make_owner(id.to_local_def_id())
}
}

rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
rustc_data_structures::define_id_collections!(
ItemLocalMap,
Expand Down
105 changes: 65 additions & 40 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_errors::{Applicability, Diag, MultiSpan, listify};
use rustc_hir::def::Res;
use rustc_errors::{Applicability, Diag, MultiSpan, listify, pluralize};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, find_attr};
use rustc_infer::infer::DefineOpaqueTypes;
Expand Down Expand Up @@ -28,7 +28,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if expr_ty == expected {
return;
}
self.annotate_alternative_method_deref(err, expr, error);
self.annotate_alternative_method_deref_for_unop(err, expr, error);
self.explain_self_literal(err, expr, expected, expr_ty);

// Use `||` to give these suggestions a precedence
Expand Down Expand Up @@ -752,11 +752,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::ExprKind::Path(hir::QPath::Resolved(
None,
hir::Path {
res:
hir::def::Res::Def(
hir::def::DefKind::Static { .. } | hir::def::DefKind::Const,
def_id,
),
res: hir::def::Res::Def(DefKind::Static { .. } | DefKind::Const, def_id),
..
},
)) => {
Expand Down Expand Up @@ -929,7 +925,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}

fn annotate_alternative_method_deref(
fn annotate_alternative_method_deref_for_unop(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
Expand All @@ -949,7 +945,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::ExprKind::Unary(hir::UnOp::Deref, deref) = lhs.kind else {
return;
};
let hir::ExprKind::MethodCall(path, base, args, _) = deref.kind else {
self.annotate_alternative_method_deref(err, deref, Some(expected))
}

#[tracing::instrument(skip(self, err), level = "debug")]
pub(crate) fn annotate_alternative_method_deref(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
expected: Option<Ty<'tcx>>,
) {
let hir::ExprKind::MethodCall(path, base, args, _) = expr.kind else {
return;
};
let Some(self_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(base) else {
Expand All @@ -959,7 +965,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Ok(pick) = self.lookup_probe_for_diagnostic(
path.ident,
self_ty,
deref,
expr,
probe::ProbeScope::TraitsInScope,
None,
) else {
Expand All @@ -969,10 +975,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Ok(in_scope_methods) = self.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
expected,
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
expr.hir_id,
probe::ProbeScope::TraitsInScope,
) else {
return;
Expand All @@ -984,45 +990,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Ok(all_methods) = self.probe_for_name_many(
probe::Mode::MethodCall,
path.ident,
Some(expected),
expected,
probe::IsSuggestion(true),
self_ty,
deref.hir_id,
expr.hir_id,
probe::ProbeScope::AllTraits,
) else {
return;
};

let suggestions: Vec<_> = all_methods
.into_iter()
.filter(|c| c.item.def_id != pick.item.def_id)
.map(|c| {
.filter_map(|c| {
if c.item.def_id == pick.item.def_id {
return None;
}
let m = c.item;
let generic_args = ty::GenericArgs::for_item(self.tcx, m.def_id, |param, _| {
self.var_for_def(deref.span, param)
self.var_for_def(expr.span, param)
});
let mutability =
match self.tcx.fn_sig(m.def_id).skip_binder().input(0).skip_binder().kind() {
ty::Ref(_, _, hir::Mutability::Mut) => "&mut ",
ty::Ref(_, _, _) => "&",
_ => "",
};
vec![
(
deref.span.until(base.span),
format!(
"{}({}",
with_no_trimmed_paths!(
self.tcx.def_path_str_with_args(m.def_id, generic_args,)
),
mutability,
),
),
let fn_sig = self.tcx.fn_sig(m.def_id);
if fn_sig.skip_binder().inputs().skip_binder().len() != args.len() + 1 {
return None;
}
let rcvr_ty = fn_sig.skip_binder().input(0).skip_binder();
let (mutability, ty) = match rcvr_ty.kind() {
ty::Ref(_, ty, hir::Mutability::Mut) => ("&mut ", ty),
ty::Ref(_, ty, _) => ("&", ty),
_ => ("", &rcvr_ty),
};
let path = match self.tcx.assoc_parent(m.def_id) {
Some((_, DefKind::Impl { of_trait: true })) => {
// We have `impl Trait for T {}`, suggest `<T as Trait>::method`.
self.tcx.def_path_str_with_args(m.def_id, generic_args).to_string()
}
Some((_, DefKind::Impl { of_trait: false })) => {
if let ty::Adt(def, _) = ty.kind() {
// We have `impl T {}`, suggest `T::method`.
format!("{}::{}", self.tcx.def_path_str(def.did()), path.ident)
} else {
// This should be unreachable, as `impl &'a T {}` is invalid.
format!("{ty}::{}", path.ident)
}
}
// Fallback for arbitrary self types.
_ => with_no_trimmed_paths!(
self.tcx.def_path_str_with_args(m.def_id, generic_args)
)
.to_string(),
};
Some(vec![
(expr.span.until(base.span), format!("{path}({}", mutability)),
match &args {
[] => (base.span.shrink_to_hi().with_hi(deref.span.hi()), ")".to_string()),
[] => (base.span.shrink_to_hi().with_hi(expr.span.hi()), ")".to_string()),
[first, ..] => (base.span.between(first.span), ", ".to_string()),
},
]
])
})
.collect();
if suggestions.is_empty() {
Expand Down Expand Up @@ -1076,9 +1099,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
if suggestions.len() > other_methods_in_scope.len() {
let n = suggestions.len() - other_methods_in_scope.len();
err.note(format!(
"additionally, there are {} other available methods that aren't in scope",
suggestions.len() - other_methods_in_scope.len()
"additionally, there {are} {n} other available method{s} that {are}n't in scope",
are = pluralize!("is", n),
s = pluralize!(n),
));
}
err.multipart_suggestions(
Expand Down Expand Up @@ -1293,7 +1318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::def::Res::Def(kind, def_id) = path.res else {
return;
};
let callable_kind = if matches!(kind, hir::def::DefKind::Ctor(_, _)) {
let callable_kind = if matches!(kind, DefKind::Ctor(_, _)) {
CallableKind::Constructor
} else {
CallableKind::Function
Expand Down
Loading
Loading