diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a41d4b01e0e..d31ec91fcaa 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1776,13 +1776,14 @@ impl<'hir> LoweringContext<'_, 'hir> { binding: hir::HirId, attrs: AttrVec, ) -> hir::Expr<'hir> { + let hir_id = self.next_id(); let res = Res::Local(binding); let expr_path = hir::ExprKind::Path(hir::QPath::Resolved( None, self.arena.alloc(hir::Path { span: self.lower_span(span), res, - segments: arena_vec![self; hir::PathSegment::from_ident(ident, res)], + segments: arena_vec![self; hir::PathSegment::from_ident(ident, hir_id, res)], }), )); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 219e1b81d1e..61470d93bdb 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -246,9 +246,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment<'hir>) { - if let Some(hir_id) = path_segment.hir_id { - self.insert(path_span, hir_id, Node::PathSegment(path_segment)); - } + self.insert(path_span, path_segment.hir_id, Node::PathSegment(path_segment)); intravisit::walk_path_segment(self, path_span, path_segment); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index e3f02968d4d..778203acf7d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1431,13 +1431,14 @@ impl<'hir> LoweringContext<'_, 'hir> { GenericParamKind::Const { .. } => None, GenericParamKind::Type { .. } => { let def_id = self.local_def_id(id).to_def_id(); + let hir_id = self.next_id(); let res = Res::Def(DefKind::TyParam, def_id); let ty_path = self.arena.alloc(hir::Path { span: param_span, res, segments: self .arena - .alloc_from_iter([hir::PathSegment::from_ident(ident, res)]), + .alloc_from_iter([hir::PathSegment::from_ident(ident, hir_id, res)]), }); let ty_id = self.next_id(); let bounded_ty = diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index bc183c6e313..097855bb6bf 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1260,6 +1260,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx); } TyKind::ImplicitSelf => { + let hir_id = self.lower_node_id(t.id); let res = self.expect_full_res(t.id); let res = self.lower_res(res); hir::TyKind::Path(hir::QPath::Resolved( @@ -1268,6 +1269,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { res, segments: arena_vec![self; hir::PathSegment::from_ident( Ident::with_dummy_span(kw::SelfUpper), + hir_id, res )], span: self.lower_span(t.span), @@ -2194,13 +2196,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::PredicateOrigin::ImplTrait, ); + let hir_id = self.next_id(); let res = Res::Def(DefKind::TyParam, def_id.to_def_id()); let ty = hir::TyKind::Path(hir::QPath::Resolved( None, self.arena.alloc(hir::Path { span: self.lower_span(span), res, - segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident), res)], + segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident), hir_id, res)], }), )); diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 61c32816e17..a23f5fddc57 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -255,13 +255,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } Some(res) => { + let hir_id = self.next_id(); let res = self.lower_res(res); hir::PatKind::Path(hir::QPath::Resolved( None, self.arena.alloc(hir::Path { span: self.lower_span(ident.span), res, - segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident), res)], + segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident), hir_id, res)], }), )) } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 6ec8bcbc1e5..5f0ddd5ac1c 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -250,15 +250,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let res = self.expect_full_res(segment.id); - let id = self.lower_node_id(segment.id); + let hir_id = self.lower_node_id(segment.id); debug!( "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", - segment.ident, segment.id, id, + segment.ident, segment.id, hir_id, ); hir::PathSegment { ident: self.lower_ident(segment.ident), - hir_id: Some(id), + hir_id, res: self.lower_res(res), infer_args, args: if generic_args.is_empty() && generic_args.span.is_empty() { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index dd9590016b9..66d2614b190 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -935,10 +935,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { _, ) = hir_map.body(fn_body_id).value.kind { - let opt_suggestions = path_segment - .hir_id - .map(|path_hir_id| self.infcx.tcx.typeck(path_hir_id.owner)) - .and_then(|typeck| typeck.type_dependent_def_id(*hir_id)) + let opt_suggestions = self + .infcx + .tcx + .typeck(path_segment.hir_id.owner) + .type_dependent_def_id(*hir_id) .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) .map(|def_id| self.infcx.tcx.associated_items(def_id)) .map(|assoc_items| { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index bd53e7670a6..561045ff4ef 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -203,7 +203,7 @@ pub struct PathSegment<'hir> { /// The identifier portion of this path segment. pub ident: Ident, - pub hir_id: Option, + pub hir_id: HirId, pub res: Res, @@ -223,12 +223,12 @@ pub struct PathSegment<'hir> { impl<'hir> PathSegment<'hir> { /// Converts an identifier to the corresponding segment. - pub fn from_ident(ident: Ident, res: Res) -> PathSegment<'hir> { - PathSegment { ident, hir_id: None, res, infer_args: true, args: None } + pub fn from_ident(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> { + PathSegment { ident, hir_id, res, infer_args: true, args: None } } pub fn invalid() -> Self { - Self::from_ident(Ident::empty(), Res::Err) + Self::from_ident(Ident::empty(), HirId::INVALID, Res::Err) } pub fn args(&self) -> &GenericArgs<'hir> { diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 346ac9e9644..e586d5cd5d9 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -20,6 +20,9 @@ pub struct HirId { } impl HirId { + /// Signal local id which should never be used. + pub const INVALID: HirId = HirId { owner: CRATE_DEF_ID, local_id: ItemLocalId::INVALID }; + #[inline] pub fn expect_owner(self) -> LocalDefId { assert_eq!(self.local_id.index(), 0); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 3d5e22add71..036becf4b7c 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -724,7 +724,7 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>( segment: &'v PathSegment<'v>, ) { visitor.visit_ident(segment.ident); - walk_list!(visitor, visit_id, segment.hir_id); + visitor.visit_id(segment.hir_id); if let Some(ref args) = segment.args { visitor.visit_generic_args(path_span, args); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index a20bcd93045..126c39c3bad 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -909,7 +909,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { None? } let substs = self.node_substs_opt(expr.hir_id)?; - let span = tcx.hir().span(segment.hir_id?); + let span = tcx.hir().span(segment.hir_id); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); InsertableGenericArgs { insert_span, @@ -963,7 +963,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { if generics.has_impl_trait() { return None; } - let span = tcx.hir().span(segment.hir_id?); + let span = tcx.hir().span(segment.hir_id); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); Some(InsertableGenericArgs { insert_span, @@ -996,7 +996,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { if !segment.infer_args || generics.has_impl_trait() { None?; } - let span = tcx.hir().span(segment.hir_id?); + let span = tcx.hir().span(segment.hir_id); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id } }; diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index 769d3243d58..f2b2daaf20b 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -912,7 +912,10 @@ impl<'tcx> DumpVisitor<'tcx> { _, ) | Res::SelfTy { .. } => { - self.dump_path_segment_ref(id, &hir::PathSegment::from_ident(ident, Res::Err)); + self.dump_path_segment_ref( + id, + &hir::PathSegment::from_ident(ident, hir::HirId::INVALID, Res::Err), + ); } def => { error!("unexpected definition kind when processing collected idents: {:?}", def) diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 4b110b824e0..c58ccde4390 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -649,7 +649,7 @@ impl<'tcx> SaveContext<'tcx> { } pub fn get_path_segment_data(&self, path_seg: &hir::PathSegment<'_>) -> Option { - self.get_path_segment_data_with_id(path_seg, path_seg.hir_id?) + self.get_path_segment_data_with_id(path_seg, path_seg.hir_id) } pub fn get_path_segment_data_with_id( diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index a49244d16d0..faf3d7a1000 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1113,7 +1113,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let ident = Ident::new(assoc_item.name, binding.item_name.span); let item_segment = hir::PathSegment { ident, - hir_id: Some(binding.hir_id), + hir_id: binding.hir_id, res: Res::Err, args: Some(binding.gen_args), infer_args: false, diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index d4b5e5e2fe4..eeb0e9ce738 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -291,62 +291,60 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { // Creates lifetime name suggestions from the lifetime parameter names fn get_lifetime_args_suggestions_from_param_names( &self, - path_hir_id: Option, + path_hir_id: hir::HirId, num_params_to_take: usize, ) -> String { debug!(?path_hir_id); - if let Some(path_hir_id) = path_hir_id { - let mut ret = Vec::new(); - for (id, node) in self.tcx.hir().parent_iter(path_hir_id) { - debug!(?id); - let params = if let Some(generics) = node.generics() { - generics.params - } else if let hir::Node::Ty(ty) = node - && let hir::TyKind::BareFn(bare_fn) = ty.kind - { - bare_fn.generic_params - } else { - &[] - }; - ret.extend(params.iter().filter_map(|p| { - let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } - = p.kind - else { return None }; - let hir::ParamName::Plain(name) = p.name else { return None }; - Some(name.to_string()) - })); - // Suggest `'static` when in const/static item-like. - if let hir::Node::Item(hir::Item { - kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. }, - .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const { .. }, - .. - }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Const { .. }, - .. - }) - | hir::Node::ForeignItem(hir::ForeignItem { - kind: hir::ForeignItemKind::Static { .. }, - .. - }) - | hir::Node::AnonConst(..) = node - { - ret.extend( - std::iter::repeat("'static".to_owned()) - .take(num_params_to_take.saturating_sub(ret.len())), - ); - } - if ret.len() >= num_params_to_take { - return ret[..num_params_to_take].join(", "); - } - // We cannot refer to lifetimes defined in an outer function. - if let hir::Node::Item(_) = node { - break; - } + let mut ret = Vec::new(); + for (id, node) in self.tcx.hir().parent_iter(path_hir_id) { + debug!(?id); + let params = if let Some(generics) = node.generics() { + generics.params + } else if let hir::Node::Ty(ty) = node + && let hir::TyKind::BareFn(bare_fn) = ty.kind + { + bare_fn.generic_params + } else { + &[] + }; + ret.extend(params.iter().filter_map(|p| { + let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } + = p.kind + else { return None }; + let hir::ParamName::Plain(name) = p.name else { return None }; + Some(name.to_string()) + })); + // Suggest `'static` when in const/static item-like. + if let hir::Node::Item(hir::Item { + kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. }, + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Const { .. }, + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Const { .. }, + .. + }) + | hir::Node::ForeignItem(hir::ForeignItem { + kind: hir::ForeignItemKind::Static { .. }, + .. + }) + | hir::Node::AnonConst(..) = node + { + ret.extend( + std::iter::repeat("'static".to_owned()) + .take(num_params_to_take.saturating_sub(ret.len())), + ); + } + if ret.len() >= num_params_to_take { + return ret[..num_params_to_take].join(", "); + } + // We cannot refer to lifetimes defined in an outer function. + if let hir::Node::Item(_) = node { + break; } } @@ -690,8 +688,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { num = num_trait_generics_except_self, ); - if let Some(hir_id) = self.path_segment.hir_id - && let Some(parent_node) = self.tcx.hir().find_parent_node(hir_id) + if let Some(parent_node) = self.tcx.hir().find_parent_node(self.path_segment.hir_id) && let Some(parent_node) = self.tcx.hir().find(parent_node) && let hir::Node::Expr(expr) = parent_node { match expr.kind { diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 34d590fb244..151ec2b28ad 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -166,25 +166,23 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) { if let ExprKind::MethodCall(segment, ..) = expr.kind { - if let Some(hir_id) = segment.hir_id { - let hir = self.tcx.hir(); - let body_id = hir.enclosing_body_owner(hir_id); - // FIXME: this is showing error messages for parts of the code that are not - // compiled (because of cfg)! - // - // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 - let typeck_results = self.tcx.typeck_body( - hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"), + let hir = self.tcx.hir(); + let body_id = hir.enclosing_body_owner(segment.hir_id); + // FIXME: this is showing error messages for parts of the code that are not + // compiled (because of cfg)! + // + // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 + let typeck_results = self + .tcx + .typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body")); + if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) { + self.matches.insert( + segment.ident.span, + match hir.span_if_local(def_id) { + Some(span) => LinkFromSrc::Local(clean::Span::new(span)), + None => LinkFromSrc::External(def_id), + }, ); - if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) { - self.matches.insert( - segment.ident.span, - match hir.span_if_local(def_id) { - Some(span) => LinkFromSrc::Local(clean::Span::new(span)), - None => LinkFromSrc::External(def_id), - }, - ); - } } } else if self.handle_macro(expr.span) { // We don't want to go deeper into the macro.