From b5dfa6a78df6eb934c353e94cf679af03235d21a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 7 Apr 2022 22:24:07 +0200 Subject: [PATCH 1/3] Compute `ty_param_owner` using DefIdTree. --- compiler/rustc_middle/src/hir/map/mod.rs | 15 +++++++-------- compiler/rustc_typeck/src/astconv/mod.rs | 8 ++++---- compiler/rustc_typeck/src/check/fn_ctxt/mod.rs | 3 +-- compiler/rustc_typeck/src/collect.rs | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 561653f3bebf7..6dab680c97957 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1,5 +1,5 @@ use crate::hir::{ModuleItems, Owner}; -use crate::ty::TyCtxt; +use crate::ty::{DefIdTree, TyCtxt}; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -545,13 +545,12 @@ impl<'hir> Map<'hir> { }); } - pub fn ty_param_owner(self, id: HirId) -> LocalDefId { - match self.get(id) { - Node::Item(&Item { kind: ItemKind::Trait(..) | ItemKind::TraitAlias(..), .. }) => { - id.expect_owner() - } - Node::GenericParam(_) => self.get_parent_item(id), - _ => bug!("ty_param_owner: {} not a type parameter", self.node_to_string(id)), + pub fn ty_param_owner(self, def_id: LocalDefId) -> LocalDefId { + let def_kind = self.tcx.def_kind(def_id); + match def_kind { + DefKind::Trait | DefKind::TraitAlias => def_id, + DefKind::TyParam | DefKind::ConstParam => self.tcx.local_parent(def_id).unwrap(), + _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind), } } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b6287031665a3..d46c4bdf98dcb 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2265,11 +2265,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert_eq!(opt_self_ty, None); self.prohibit_generics(path.segments); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - let item_id = tcx.hir().get_parent_node(hir_id); - let item_def_id = tcx.hir().local_def_id(item_id); + let def_id = def_id.expect_local(); + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let item_def_id = tcx.hir().ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&def_id]; + let index = generics.param_def_id_to_index[&def_id.to_def_id()]; tcx.mk_ty_param(index, tcx.hir().name(hir_id)) } Res::SelfTy { trait_: Some(_), alias_to: None } => { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 55a5eb966c222..77cba1c22c408 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -184,8 +184,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { _: Ident, ) -> ty::GenericPredicates<'tcx> { let tcx = self.tcx; - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - let item_def_id = tcx.hir().ty_param_owner(hir_id); + let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local()); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; ty::GenericPredicates { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index ec783a16ef73f..62187b2bdfcad 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -558,7 +558,7 @@ fn type_param_predicates( // `where T: Foo`. let param_id = tcx.hir().local_def_id_to_hir_id(def_id); - let param_owner = tcx.hir().ty_param_owner(param_id); + let param_owner = tcx.hir().ty_param_owner(def_id); let generics = tcx.generics_of(param_owner); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id)); From f89d64d7aa91f7ba5ca4ffd4eb6ab42cf61b12c0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 8 Apr 2022 23:06:20 +0200 Subject: [PATCH 2/3] Use def_key in `tcx.item_name` when possible. --- compiler/rustc_hir/src/definitions.rs | 5 +++ compiler/rustc_middle/src/hir/map/mod.rs | 13 ++++--- compiler/rustc_middle/src/query/mod.rs | 5 +-- compiler/rustc_middle/src/ty/mod.rs | 35 ++++++++++--------- .../rustc_monomorphize/src/polymorphize.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 10 +++--- compiler/rustc_typeck/src/astconv/generics.rs | 3 +- compiler/rustc_typeck/src/astconv/mod.rs | 6 ++-- compiler/rustc_typeck/src/check/expr.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 2 +- 10 files changed, 41 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index c62d3b9be2fcc..4908992085a6e 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -147,6 +147,11 @@ impl DefKey { // DefPathHashes in this DefPathTable. DefPathHash::new(parent.stable_crate_id(), local_hash) } + + #[inline] + pub fn get_opt_name(&self) -> Option { + self.disambiguated_data.data.get_opt_name() + } } /// A pair of `DefPathData` and an integer disambiguator. The integer is diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 6dab680c97957..65796fbc698d8 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -554,13 +554,12 @@ impl<'hir> Map<'hir> { } } - pub fn ty_param_name(self, id: HirId) -> Symbol { - match self.get(id) { - Node::Item(&Item { kind: ItemKind::Trait(..) | ItemKind::TraitAlias(..), .. }) => { - kw::SelfUpper - } - Node::GenericParam(param) => param.name.ident().name, - _ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)), + pub fn ty_param_name(self, def_id: LocalDefId) -> Symbol { + let def_kind = self.tcx.def_kind(def_id); + match def_kind { + DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper, + DefKind::TyParam | DefKind::ConstParam => self.tcx.item_name(def_id.to_def_id()), + _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind), } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 89761bf4e27a0..bbe1d367b77ca 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -517,10 +517,7 @@ rustc_queries! { /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates(key: (DefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing the bounds for type parameter `{}`", { - let id = tcx.hir().local_def_id_to_hir_id(key.1); - tcx.hir().ty_param_name(id) - }} + desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir().ty_param_name(key.1) } } query trait_def(key: DefId) -> ty::TraitDef { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 45a215354d081..9151c2cd5e07e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1986,27 +1986,25 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) } - fn item_name_from_hir(self, def_id: DefId) -> Option { - self.hir().get_if_local(def_id).and_then(|node| node.ident()) - } - - fn item_name_from_def_id(self, def_id: DefId) -> Option { + fn opt_item_name(self, def_id: DefId) -> Option { if def_id.index == CRATE_DEF_INDEX { Some(self.crate_name(def_id.krate)) } else { let def_key = self.def_key(def_id); match def_key.disambiguated_data.data { // The name of a constructor is that of its parent. - rustc_hir::definitions::DefPathData::Ctor => self.item_name_from_def_id(DefId { - krate: def_id.krate, - index: def_key.parent.unwrap(), - }), - _ => def_key.disambiguated_data.data.get_opt_name(), + rustc_hir::definitions::DefPathData::Ctor => self + .opt_item_name(DefId { krate: def_id.krate, index: def_key.parent.unwrap() }), + // The name of opaque types only exists in HIR. + rustc_hir::definitions::DefPathData::ImplTrait + if let Some(def_id) = def_id.as_local() => + self.hir().opt_name(self.hir().local_def_id_to_hir_id(def_id)), + _ => def_key.get_opt_name(), } } } - /// Look up the name of an item across crates. This does not look at HIR. + /// Look up the name of a definition across crates. This does not look at HIR. /// /// When possible, this function should be used for cross-crate lookups over /// [`opt_item_name`] to avoid invalidating the incremental cache. If you @@ -2018,18 +2016,21 @@ impl<'tcx> TyCtxt<'tcx> { pub fn item_name(self, id: DefId) -> Symbol { // Look at cross-crate items first to avoid invalidating the incremental cache // unless we have to. - self.item_name_from_def_id(id).unwrap_or_else(|| { + self.opt_item_name(id).unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); }) } - /// Look up the name and span of an item or [`Node`]. + /// Look up the name and span of a definition. /// /// See [`item_name`][Self::item_name] for more information. - pub fn opt_item_name(self, def_id: DefId) -> Option { - // Look at the HIR first so the span will be correct if this is a local item. - self.item_name_from_hir(def_id) - .or_else(|| self.item_name_from_def_id(def_id).map(Ident::with_dummy_span)) + pub fn opt_item_ident(self, def_id: DefId) -> Option { + let def = self.opt_item_name(def_id)?; + let span = def_id + .as_local() + .and_then(|id| self.def_ident_span(id)) + .unwrap_or(rustc_span::DUMMY_SP); + Some(Ident::new(def, span)) } pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> { diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 489d513c104b1..cf13c856a71c1 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -201,7 +201,7 @@ fn emit_unused_generic_params_error<'tcx>( return; } - let fn_span = match tcx.opt_item_name(def_id) { + let fn_span = match tcx.opt_item_ident(def_id) { Some(ident) => ident.span, _ => tcx.def_span(def_id), }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 7c3f306717a69..c920c80d1bba1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2064,7 +2064,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ObligationCauseCode::BindingObligation(item_def_id, span) => { let item_name = tcx.def_path_str(item_def_id); let mut multispan = MultiSpan::from(span); - if let Some(ident) = tcx.opt_item_name(item_def_id) { + if let Some(ident) = tcx.opt_item_ident(item_def_id) { let sm = tcx.sess.source_map(); let same_line = match (sm.lookup_line(ident.span.hi()), sm.lookup_line(span.lo())) { @@ -2267,7 +2267,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if !is_upvar_tys_infer_tuple { let msg = format!("required because it appears within the type `{}`", ty); match ty.kind() { - ty::Adt(def, _) => match self.tcx.opt_item_name(def.did()) { + ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) { Some(ident) => err.span_note(ident.span, &msg), None => err.note(&msg), }, @@ -2475,7 +2475,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); let sp = self .tcx - .opt_item_name(trait_item_def_id) + .opt_item_ident(trait_item_def_id) .map(|i| i.span) .unwrap_or_else(|| self.tcx.def_span(trait_item_def_id)); let mut assoc_span: MultiSpan = sp.into(); @@ -2486,7 +2486,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let Some(ident) = self .tcx .opt_associated_item(trait_item_def_id) - .and_then(|i| self.tcx.opt_item_name(i.container.id())) + .and_then(|i| self.tcx.opt_item_ident(i.container.id())) { assoc_span.push_span_label(ident.span, "in this trait"); } @@ -2511,7 +2511,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let Some(ident) = self .tcx .opt_associated_item(trait_item_def_id) - .and_then(|i| self.tcx.opt_item_name(i.container.id())) + .and_then(|i| self.tcx.opt_item_ident(i.container.id())) { assoc_span.push_span_label(ident.span, "in this trait"); } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index a50301dbc87f0..5f5b81b892475 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -82,8 +82,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { - let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id); - let param_name = tcx.hir().ty_param_name(param_hir_id); + let param_name = tcx.hir().ty_param_name(param_local_id); let param_type = tcx.infer_ctxt().enter(|infcx| { infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id)) }); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index d46c4bdf98dcb..e58617b985d07 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1620,8 +1620,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("find_bound_for_assoc_item: predicates={:#?}", predicates); - let param_hir_id = tcx.hir().local_def_id_to_hir_id(ty_param_def_id); - let param_name = tcx.hir().ty_param_name(param_hir_id); + let param_name = tcx.hir().ty_param_name(ty_param_def_id); self.one_bound_for_assoc_type( || { traits::transitive_bounds_that_define_assoc_type( @@ -2266,11 +2265,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.prohibit_generics(path.segments); let def_id = def_id.expect_local(); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let item_def_id = tcx.hir().ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - tcx.mk_ty_param(index, tcx.hir().name(hir_id)) + tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)) } Res::SelfTy { trait_: Some(_), alias_to: None } => { // `Self` in trait or type alias. diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 82641a489f66a..669521bc4725e 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2195,7 +2195,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => return, }; let param_span = self.tcx.hir().span(param_hir_id); - let param_name = self.tcx.hir().ty_param_name(param_hir_id); + let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local()); err.span_label(param_span, &format!("type parameter '{}' declared here", param_name)); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 62187b2bdfcad..026151ce7df82 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -561,7 +561,7 @@ fn type_param_predicates( let param_owner = tcx.hir().ty_param_owner(def_id); let generics = tcx.generics_of(param_owner); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id)); + let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner.to_def_id() { From 672ce1509b6238015c9d915542dc2c7a472c780a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 9 Apr 2022 12:31:20 +0200 Subject: [PATCH 3/3] Bless tests. --- src/test/ui/const-generics/occurs-check/unused-substs-1.stderr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr index 8431d989278ba..48e12e903b86a 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -8,6 +8,9 @@ LL | let _ = A; note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | +LL | struct A + | - required by a bound in this +LL | where LL | A: Bar; | ^^^^^^ required by this bound in `A`