From 03dff82d598233d4f1193d763f73c71a76ad6187 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:26:47 +0000 Subject: [PATCH 1/9] Add `of_trait` to DefKind::Impl. --- .../rustc_borrowck/src/diagnostics/mod.rs | 14 +++++----- .../src/diagnostics/region_name.rs | 4 +-- .../src/const_eval/fn_queries.rs | 3 +- compiler/rustc_hir/src/def.rs | 12 ++++---- compiler/rustc_hir/src/target.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 28 ++++++++++--------- .../src/coherence/inherent_impls.rs | 2 +- .../src/collect/lifetimes.rs | 2 +- .../rustc_hir_analysis/src/impl_wf_check.rs | 2 +- .../infer/error_reporting/need_type_info.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 16 +++++------ compiler/rustc_metadata/src/rmeta/table.rs | 3 +- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- .../rustc_monomorphize/src/polymorphize.rs | 2 +- compiler/rustc_passes/src/dead.rs | 8 ++---- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 4 +-- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_save_analysis/src/lib.rs | 2 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 2 +- src/librustdoc/formats/item_type.rs | 2 +- .../passes/collect_intra_doc_links.rs | 4 +-- .../clippy_lints/src/same_name_method.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- 28 files changed, 68 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 3006e27e1d5b5..a89643fcfd484 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1182,13 +1182,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } let parent_did = tcx.parent(method_did); - let parent_self_ty = (tcx.def_kind(parent_did) - == rustc_hir::def::DefKind::Impl) - .then_some(parent_did) - .and_then(|did| match tcx.type_of(did).kind() { - ty::Adt(def, ..) => Some(def.did()), - _ => None, - }); + let parent_self_ty = + matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. }) + .then_some(parent_did) + .and_then(|did| match tcx.type_of(did).kind() { + ty::Adt(def, ..) => Some(def.did()), + _ => None, + }); let is_option_or_result = parent_self_ty.map_or(false, |def_id| { matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result)) }); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 237e063d8d11f..a82e695d64905 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -852,9 +852,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let tcx = self.infcx.tcx; let region_parent = tcx.parent(region.def_id); - if tcx.def_kind(region_parent) != DefKind::Impl { + let DefKind::Impl { .. } = tcx.def_kind(region_parent) else { return None; - } + }; let found = tcx .any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region)); diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index f92277b111374..9eaab1f47a7ea 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -17,7 +17,8 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let parent_id = tcx.local_parent(def_id); - tcx.def_kind(parent_id) == DefKind::Impl && tcx.constness(parent_id) == hir::Constness::Const + matches!(tcx.def_kind(parent_id), DefKind::Impl { .. }) + && tcx.constness(parent_id) == hir::Constness::Const } /// Checks whether an item is considered to be `const`. If it is a constructor, it is const. If diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index f1801a0f844f7..0599ae04a90ab 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -116,7 +116,9 @@ pub enum DefKind { LifetimeParam, /// A use of `global_asm!`. GlobalAsm, - Impl, + Impl { + of_trait: bool, + }, Closure, Generator, } @@ -155,7 +157,7 @@ impl DefKind { DefKind::AnonConst => "constant expression", DefKind::InlineConst => "inline constant", DefKind::Field => "field", - DefKind::Impl => "implementation", + DefKind::Impl { .. } => "implementation", DefKind::Closure => "closure", DefKind::Generator => "generator", DefKind::ExternCrate => "extern crate", @@ -171,7 +173,7 @@ impl DefKind { | DefKind::AssocFn | DefKind::Enum | DefKind::OpaqueTy - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Use | DefKind::InlineConst | DefKind::ExternCrate => "an", @@ -216,7 +218,7 @@ impl DefKind { | DefKind::Use | DefKind::ForeignMod | DefKind::GlobalAsm - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::ImplTraitPlaceholder => None, } } @@ -255,7 +257,7 @@ impl DefKind { | DefKind::ForeignMod | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Field | DefKind::TyParam | DefKind::ConstParam diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 5917d5e346e37..961deac544a88 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -116,7 +116,7 @@ impl Target { DefKind::Union => Target::Union, DefKind::Trait => Target::Trait, DefKind::TraitAlias => Target::TraitAlias, - DefKind::Impl => Target::Impl, + DefKind::Impl { .. } => Target::Impl, _ => panic!("impossible case reached"), } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 15a66ccc0f412..02d7c7e9d8499 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -529,19 +529,21 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { check_enum(tcx, id.owner_id.def_id); } DefKind::Fn => {} // entirely within check_item_body - DefKind::Impl => { - let it = tcx.hir().item(id); - let hir::ItemKind::Impl(impl_) = it.kind else { return }; - debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); - if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { - check_impl_items_against_trait( - tcx, - it.span, - it.owner_id.def_id, - impl_trait_ref.subst_identity(), - &impl_.items, - ); - check_on_unimplemented(tcx, it); + DefKind::Impl { of_trait } => { + if of_trait { + let it = tcx.hir().item(id); + let hir::ItemKind::Impl(impl_) = it.kind else { return }; + debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); + if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { + check_impl_items_against_trait( + tcx, + it.span, + it.owner_id.def_id, + impl_trait_ref.subst_identity(), + &impl_.items, + ); + check_on_unimplemented(tcx, it); + } } } DefKind::Trait => { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 940a450101ca0..2d2ac4f61947b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -177,7 +177,7 @@ impl<'tcx> InherentCollect<'tcx> { } fn check_item(&mut self, id: hir::ItemId) { - if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl) { + if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl { of_trait: false }) { return; } diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 3f8d620fe6934..d8606f759b24b 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -1563,7 +1563,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // See issue #83753. If someone writes an associated type on a non-trait, just treat it as // there being no supertrait HRTBs. match tcx.def_kind(def_id) { - DefKind::Trait | DefKind::TraitAlias | DefKind::Impl => {} + DefKind::Trait | DefKind::TraitAlias | DefKind::Impl { .. } => {} _ => break None, } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 4fe893442b9bd..4f30318412d7e 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -55,7 +55,7 @@ fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { let min_specialization = tcx.features().min_specialization; let module = tcx.hir_module_items(module_def_id); for id in module.items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) { enforce_impl_params_are_constrained(tcx, id.owner_id.def_id); if min_specialization { check_min_specialization(tcx, id.owner_id.def_id); 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 c092efbb557cf..2b5a19914a327 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 @@ -1061,7 +1061,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { }; let parent_def_id = generics.parent.unwrap(); - if tcx.def_kind(parent_def_id) == DefKind::Impl { + if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) { let parent_ty = tcx.bound_type_of(parent_def_id).subst(tcx, substs); match (parent_ty.kind(), &ty.kind) { ( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 060ade8a42f71..43047051f0f65 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -838,7 +838,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::ForeignMod | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Field => true, DefKind::TyParam | DefKind::ConstParam @@ -873,7 +873,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool { | DefKind::ImplTraitPlaceholder | DefKind::Enum | DefKind::Union - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Trait | DefKind::TraitAlias | DefKind::Macro(..) @@ -951,7 +951,7 @@ fn should_encode_variances(def_kind: DefKind) -> bool { | DefKind::Const | DefKind::ForeignMod | DefKind::TyAlias - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Trait | DefKind::TraitAlias | DefKind::Macro(..) @@ -988,7 +988,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool { | DefKind::InlineConst | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Field | DefKind::TyParam | DefKind::Closure @@ -1018,7 +1018,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::ForeignTy - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::AssocFn | DefKind::AssocConst | DefKind::Closure @@ -1081,7 +1081,7 @@ fn should_encode_const(def_kind: DefKind) -> bool { | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder | DefKind::ForeignTy - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::AssocFn | DefKind::Closure | DefKind::Generator @@ -1860,7 +1860,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { FxHashMap::default(); for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) { if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) { let trait_ref = trait_ref.subst_identity(); @@ -2261,7 +2261,7 @@ pub fn provide(providers: &mut Providers) { let mut trait_impls = Vec::new(); for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) && tcx.impl_trait_ref(id.owner_id).is_some() { trait_impls.push(id.owner_id.to_def_id()) diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 99bec570600a0..b89d48ec15ae9 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -136,7 +136,8 @@ fixed_size_enum! { ( Field ) ( LifetimeParam ) ( GlobalAsm ) - ( Impl ) + ( Impl { of_trait: false } ) + ( Impl { of_trait: true } ) ( Closure ) ( Generator ) ( Static(ast::Mutability::Not) ) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 7f2994fd79b98..ba93330d58120 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -203,7 +203,7 @@ impl<'hir> Map<'hir> { ItemKind::Use(..) => DefKind::Use, ItemKind::ForeignMod { .. } => DefKind::ForeignMod, ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, - ItemKind::Impl { .. } => DefKind::Impl, + ItemKind::Impl(impl_) => DefKind::Impl { of_trait: impl_.of_trait.is_some() }, }, Node::ForeignItem(item) => match item.kind { ForeignItemKind::Fn(..) => DefKind::Fn, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6d8c9d7376333..e49c6062b3354 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2427,7 +2427,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn impl_of_method(self, def_id: DefId) -> Option { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { let parent = self.parent(def_id); - if let DefKind::Impl = self.def_kind(parent) { + if let DefKind::Impl { .. } = self.def_kind(parent) { return Some(parent); } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e907ce46c86fb..35831ff870642 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -167,7 +167,7 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::Fn | DefKind::AssocFn | DefKind::AssocConst - | DefKind::Impl, + | DefKind::Impl { .. }, def_id, ) => Some(def_id), Res::Err => None, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 83b8988cecaf8..8f6338472df58 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1238,7 +1238,7 @@ impl<'v> RootCollector<'_, 'v> { collect_const_value(self.tcx, val, &mut self.output); } } - DefKind::Impl => { + DefKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { let item = self.tcx.hir().item(id); create_mono_items_for_default_impls(self.tcx, item, self.output); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index aba842817ef7a..207ad332c22c2 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -172,7 +172,7 @@ fn mark_used_by_default_parameters<'tcx>( | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl => { + | DefKind::Impl { .. } => { for param in &generics.params { debug!(?param, "(other)"); if let ty::GenericParamDefKind::Lifetime = param.kind { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 83adfeb6b10b6..fe0cb71d2c18d 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -526,10 +526,8 @@ fn check_item<'tcx>( } } } - DefKind::Impl => { - let of_trait = tcx.impl_trait_ref(id.owner_id); - - if of_trait.is_some() { + DefKind::Impl { of_trait } => { + if of_trait { worklist.push(id.owner_id.def_id); } @@ -541,7 +539,7 @@ fn check_item<'tcx>( // And we access the Map here to get HirId from LocalDefId for id in local_def_ids { - if of_trait.is_some() || has_allow_dead_code_or_lang_attr(tcx, id) { + if of_trait || has_allow_dead_code_or_lang_attr(tcx, id) { worklist.push(id); } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6afdcc37fe86e..678f1815d012c 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -145,7 +145,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { // Don't run unused pass for #[derive()] let parent = tcx.local_parent(local_def_id); - if let DefKind::Impl = tcx.def_kind(parent) + if let DefKind::Impl { .. } = tcx.def_kind(parent) && tcx.has_attr(parent.to_def_id(), sym::automatically_derived) { return; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index ad09522038678..9559ee9320f5c 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -320,7 +320,7 @@ fn check_item<'tcx>( worklist.push(id.owner_id.def_id); } - if !matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if !matches!(tcx.def_kind(id.owner_id), DefKind::Impl { of_trait: true }) { return; } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9cff62e85146e..4675bd79c4629 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -593,7 +593,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { | DefKind::InlineConst | DefKind::Field | DefKind::GlobalAsm - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => (), } @@ -1997,7 +1997,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { // Subitems of inherent impls have their own publicity. // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. - DefKind::Impl => { + DefKind::Impl { .. } => { let item = tcx.hir().item(id); if let hir::ItemKind::Impl(ref impl_) = item.kind { let impl_vis = diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 44f3bf1be055d..e927ec9cb67ff 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -987,7 +987,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Generator, _, ) diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index a9a92cc4f62ed..ad151bc2e1bf5 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -733,7 +733,7 @@ impl<'tcx> SaveContext<'tcx> { | HirDefKind::Use | HirDefKind::Field | HirDefKind::GlobalAsm - | HirDefKind::Impl + | HirDefKind::Impl { .. } | HirDefKind::Closure | HirDefKind::Generator, _, diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 961c04974e508..2fe9d135fa562 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -21,7 +21,7 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { assumed_wf_types.extend(liberated_sig.inputs_and_output); tcx.intern_type_list(&assumed_wf_types) } - DefKind::Impl => { + DefKind::Impl { .. } => { match tcx.impl_trait_ref(def_id) { Some(trait_ref) => { let types: Vec<_> = trait_ref.skip_binder().substs.types().collect(); diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index aafedc17499a7..452e14918faf7 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -140,7 +140,7 @@ impl From for ItemType { | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => Self::ForeignType, } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7e3149a59e3af..b2208da9060dc 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -359,7 +359,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { _ => def_id, }) .and_then(|self_id| match tcx.def_kind(self_id) { - DefKind::Impl => self.def_id_to_res(self_id), + DefKind::Impl { .. } => self.def_id_to_res(self_id), DefKind::Use => None, def_kind => Some(Res::Def(def_kind, self_id)), }) @@ -1761,7 +1761,7 @@ fn resolution_failure( } Trait | TyAlias | ForeignTy | OpaqueTy | ImplTraitPlaceholder | TraitAlias | TyParam | Static(_) => "associated item", - Impl | GlobalAsm => unreachable!("not a path"), + Impl { .. } | GlobalAsm => unreachable!("not a path"), } } else { "associated item" diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 17763128cd143..a37e2772d3558 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { let mut map = FxHashMap::::default(); for id in cx.tcx.hir().items() { - if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl) + if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. }) && let item = cx.tcx.hir().item(id) && let ItemKind::Impl(Impl { items, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 26f279f55855f..3b8713e2b108c 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -552,7 +552,7 @@ fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) .filter(|item| item.ident.name == name) .map(|child| child.res.expect_non_local()) .collect(), - DefKind::Impl => tcx + DefKind::Impl { .. } => tcx .associated_item_def_ids(def_id) .iter() .copied() From 2a51e73ac9a1616300e3db93e094baa4b86b895f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:31:04 +0000 Subject: [PATCH 2/9] Do not fetch HIR for inherent impls. --- .../src/coherence/inherent_impls.rs | 92 ++++++++----------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 2d2ac4f61947b..f0b6ab03ad693 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -14,7 +14,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; use rustc_span::symbol::sym; -use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { @@ -57,86 +56,76 @@ const ADD_ATTR: &str = "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items"; impl<'tcx> InherentCollect<'tcx> { - fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) { - let impl_def_id = item.owner_id; - if let Some(def_id) = def_id.as_local() { + fn check_def_id(&mut self, impl_def_id: LocalDefId, self_ty: Ty<'tcx>, ty_def_id: DefId) { + if let Some(ty_def_id) = ty_def_id.as_local() { // Add the implementation to the mapping from implementation to base // type def ID, if there is a base type for this implementation and // the implementation does not have any associated traits. - let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); + let vec = self.impls_map.inherent_impls.entry(ty_def_id).or_default(); vec.push(impl_def_id.to_def_id()); return; } if self.tcx.features().rustc_attrs { - let hir::ItemKind::Impl(&hir::Impl { items, .. }) = item.kind else { - bug!("expected `impl` item: {:?}", item); - }; + let items = self.tcx.associated_item_def_ids(impl_def_id); - if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { + if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) { + let impl_span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, - span, + impl_span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(span, ADD_ATTR_TO_TY) + .span_help(impl_span, ADD_ATTR_TO_TY) .emit(); return; } - for impl_item in items { - if !self - .tcx - .has_attr(impl_item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl) - { + for &impl_item in items { + if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + let impl_span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, - span, + impl_span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR) + .span_help(self.tcx.def_span(impl_item), ADD_ATTR) .emit(); return; } } if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) { - self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id.def_id); + self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id); } else { bug!("unexpected self type: {:?}", self_ty); } } else { + let impl_span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, - span, + impl_span, E0116, "cannot define inherent `impl` for a type outside of the crate \ where the type is defined" ) - .span_label(span, "impl for type defined outside of crate.") + .span_label(impl_span, "impl for type defined outside of crate.") .note("define and implement a trait or new type instead") .emit(); } } - fn check_primitive_impl( - &mut self, - impl_def_id: LocalDefId, - ty: Ty<'tcx>, - items: &[hir::ImplItemRef], - span: Span, - ) { + fn check_primitive_impl(&mut self, impl_def_id: LocalDefId, ty: Ty<'tcx>) { + let items = self.tcx.associated_item_def_ids(impl_def_id); if !self.tcx.hir().rustc_coherence_is_core() { if self.tcx.features().rustc_attrs { - for item in items { - if !self - .tcx - .has_attr(item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl) - { + for &impl_item in items { + if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + let span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, span, @@ -144,12 +133,13 @@ impl<'tcx> InherentCollect<'tcx> { "cannot define inherent `impl` for primitive types outside of `core`", ) .help(INTO_CORE) - .span_help(item.span, ADD_ATTR) + .span_help(self.tcx.def_span(impl_item), ADD_ATTR) .emit(); return; } } } else { + let span = self.tcx.def_span(impl_def_id); let mut err = struct_span_err!( self.tcx.sess, span, @@ -181,31 +171,23 @@ impl<'tcx> InherentCollect<'tcx> { return; } - let item = self.tcx.hir().item(id); - let impl_span = self.tcx.hir().span(id.hir_id()); - let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else { - return; - }; - - let self_ty = self.tcx.type_of(item.owner_id); + let id = id.owner_id.def_id; + let item_span = self.tcx.def_span(id); + let self_ty = self.tcx.type_of(id); match *self_ty.kind() { - ty::Adt(def, _) => { - self.check_def_id(item, self_ty, def.did(), impl_span); - } - ty::Foreign(did) => { - self.check_def_id(item, self_ty, did, impl_span); - } + ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), + ty::Foreign(did) => self.check_def_id(id, self_ty, did), ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { - self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span); + self.check_def_id(id, self_ty, data.principal_def_id().unwrap()); } ty::Dynamic(..) => { struct_span_err!( self.tcx.sess, - impl_span, + item_span, E0785, "cannot define inherent `impl` for a dyn auto trait" ) - .span_label(impl_span, "impl requires at least one non-auto trait") + .span_label(item_span, "impl requires at least one non-auto trait") .note("define and implement a new trait or type instead") .emit(); } @@ -221,18 +203,16 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Ref(..) | ty::Never | ty::FnPtr(_) - | ty::Tuple(..) => { - self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span) - } + | ty::Tuple(..) => self.check_primitive_impl(id, self_ty), ty::Alias(..) | ty::Param(_) => { let mut err = struct_span_err!( self.tcx.sess, - impl_span, + item_span, E0118, "no nominal type found for inherent implementation" ); - err.span_label(impl_span, "impl requires a nominal type") + err.span_label(item_span, "impl requires a nominal type") .note("either implement a trait on it or create a newtype to wrap it instead"); err.emit(); @@ -245,7 +225,7 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => { - bug!("unexpected impl self type of impl: {:?} {:?}", item.owner_id, self_ty); + bug!("unexpected impl self type of impl: {:?} {:?}", id, self_ty); } ty::Error(_) => {} } From e9e12266ced4c43f07c53017f5ed094e93157a18 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:35:31 +0000 Subject: [PATCH 3/9] Do not fetch HIR for reachable. --- compiler/rustc_passes/src/reachable.rs | 29 ++++++++++++-------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 9559ee9320f5c..051100c56f813 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -325,26 +325,23 @@ fn check_item<'tcx>( } // We need only trait impls here, not inherent impls, and only non-exported ones - let item = tcx.hir().item(id); - if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) = - item.kind - { - if !effective_visibilities.is_reachable(item.owner_id.def_id) { - worklist.extend(items.iter().map(|ii_ref| ii_ref.id.owner_id.def_id)); + if effective_visibilities.is_reachable(id.owner_id.def_id) { + return; + } - let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else { - unreachable!(); - }; + let items = tcx.associated_item_def_ids(id.owner_id); + worklist.extend(items.iter().map(|ii_ref| ii_ref.expect_local())); - if !trait_def_id.is_local() { - return; - } + let Some(trait_def_id) = tcx.trait_id_of_impl(id.owner_id.to_def_id()) else { + unreachable!(); + }; - worklist.extend( - tcx.provided_trait_methods(trait_def_id).map(|assoc| assoc.def_id.expect_local()), - ); - } + if !trait_def_id.is_local() { + return; } + + worklist + .extend(tcx.provided_trait_methods(trait_def_id).map(|assoc| assoc.def_id.expect_local())); } fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { From facecf6e1b96f3dc1c2a3f1bcfb56caa018e78cf Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:49:54 +0000 Subject: [PATCH 4/9] Fetch less HIR in signature check. --- .../rustc_hir_analysis/src/check/check.rs | 99 ++--- .../src/check/compare_impl_item.rs | 64 ++-- compiler/rustc_hir_analysis/src/check/mod.rs | 20 +- tests/rustdoc-ui/issue-105742.rs | 21 - tests/rustdoc-ui/issue-105742.stderr | 362 +----------------- tests/ui/error-codes/E0520.stderr | 2 +- .../specialization-no-default.stderr | 10 +- .../ui/specialization/issue-50452-fail.stderr | 2 +- .../non-defaulted-item-fail.stderr | 12 +- .../specialization-no-default.stderr | 10 +- .../ui/traits/negative-impls/no-items.stderr | 2 +- 11 files changed, 97 insertions(+), 507 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 02d7c7e9d8499..d5def62885043 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -530,46 +530,33 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } DefKind::Fn => {} // entirely within check_item_body DefKind::Impl { of_trait } => { - if of_trait { - let it = tcx.hir().item(id); - let hir::ItemKind::Impl(impl_) = it.kind else { return }; - debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); - if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { - check_impl_items_against_trait( - tcx, - it.span, - it.owner_id.def_id, - impl_trait_ref.subst_identity(), - &impl_.items, - ); - check_on_unimplemented(tcx, it); - } + if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(id.owner_id) { + check_impl_items_against_trait( + tcx, + id.owner_id.def_id, + impl_trait_ref.subst_identity(), + ); + check_on_unimplemented(tcx, id); } } DefKind::Trait => { - let it = tcx.hir().item(id); - let hir::ItemKind::Trait(_, _, _, _, items) = it.kind else { - return; - }; - check_on_unimplemented(tcx, it); - - for item in items.iter() { - let item = tcx.hir().trait_item(item.id); - match &item.kind { - hir::TraitItemKind::Fn(sig, _) => { - let abi = sig.header.abi; - fn_maybe_err(tcx, item.ident.span, abi); + let assoc_items = tcx.associated_items(id.owner_id); + check_on_unimplemented(tcx, id); + + for assoc_item in assoc_items.in_definition_order() { + match assoc_item.kind { + ty::AssocKind::Fn => { + let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi(); + fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi); } - hir::TraitItemKind::Type(.., Some(default)) => { - let assoc_item = tcx.associated_item(item.owner_id); + ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => { let trait_substs = - InternalSubsts::identity_for_item(tcx, it.owner_id.to_def_id()); + InternalSubsts::identity_for_item(tcx, id.owner_id.to_def_id()); let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds( tcx, assoc_item, assoc_item, - default.span, - tcx.mk_trait_ref(it.owner_id.to_def_id(), trait_substs), + tcx.mk_trait_ref(id.owner_id.to_def_id(), trait_substs), ); } _ => {} @@ -681,7 +668,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } } -pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { +pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) { // an error would be reported if this fails. let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id()); } @@ -691,7 +678,7 @@ pub(super) fn check_specialization_validity<'tcx>( trait_def: &ty::TraitDef, trait_item: &ty::AssocItem, impl_id: DefId, - impl_item: &hir::ImplItemRef, + impl_item: DefId, ) { let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) else { return }; let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| { @@ -737,10 +724,8 @@ pub(super) fn check_specialization_validity<'tcx>( fn check_impl_items_against_trait<'tcx>( tcx: TyCtxt<'tcx>, - full_impl_span: Span, impl_id: LocalDefId, impl_trait_ref: ty::TraitRef<'tcx>, - impl_item_refs: &[hir::ImplItemRef], ) { // If the trait reference itself is erroneous (so the compilation is going // to fail), skip checking the items here -- the `impl_item` table in `tcx` @@ -749,12 +734,14 @@ fn check_impl_items_against_trait<'tcx>( return; } + let impl_item_refs = tcx.associated_item_def_ids(impl_id); + // Negative impls are not expected to have any items match tcx.impl_polarity(impl_id) { ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { if let [first_item_ref, ..] = impl_item_refs { - let first_item_span = tcx.hir().impl_item(first_item_ref.id).span; + let first_item_span = tcx.def_span(first_item_ref); struct_span_err!( tcx.sess, first_item_span, @@ -769,43 +756,27 @@ fn check_impl_items_against_trait<'tcx>( let trait_def = tcx.trait_def(impl_trait_ref.def_id); - for impl_item in impl_item_refs { - let ty_impl_item = tcx.associated_item(impl_item.id.owner_id); + for &impl_item in impl_item_refs { + let ty_impl_item = tcx.associated_item(impl_item); let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id { tcx.associated_item(trait_item_id) } else { // Checked in `associated_item`. - tcx.sess.delay_span_bug(impl_item.span, "missing associated item in trait"); + tcx.sess.delay_span_bug(tcx.def_span(impl_item), "missing associated item in trait"); continue; }; - let impl_item_full = tcx.hir().impl_item(impl_item.id); - match impl_item_full.kind { - hir::ImplItemKind::Const(..) => { + match ty_impl_item.kind { + ty::AssocKind::Const => { let _ = tcx.compare_impl_const(( - impl_item.id.owner_id.def_id, + impl_item.expect_local(), ty_impl_item.trait_item_def_id.unwrap(), )); } - hir::ImplItemKind::Fn(..) => { - let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - compare_impl_method( - tcx, - &ty_impl_item, - &ty_trait_item, - impl_trait_ref, - opt_trait_span, - ); + ty::AssocKind::Fn => { + compare_impl_method(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref); } - hir::ImplItemKind::Type(impl_ty) => { - let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - compare_impl_ty( - tcx, - &ty_impl_item, - impl_ty.span, - &ty_trait_item, - impl_trait_ref, - opt_trait_span, - ); + ty::AssocKind::Type => { + compare_impl_ty(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref); } } @@ -840,6 +811,8 @@ fn check_impl_items_against_trait<'tcx>( .map_or(false, |node_item| !node_item.defining_node.is_from_trait()); if !is_implemented_here { + let full_impl_span = + tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); match tcx.eval_default_body_stability(trait_item_id, full_impl_span) { EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable( tcx, @@ -866,6 +839,8 @@ fn check_impl_items_against_trait<'tcx>( } if !missing_items.is_empty() { + let full_impl_span = + tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span); } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index a926deb2393de..50f9bbc022e7c 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -33,7 +33,6 @@ use std::iter; /// # Parameters /// /// - `impl_m`: type of the method we are checking -/// - `impl_m_span`: span to use for reporting errors /// - `trait_m`: the method in the trait /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation pub(super) fn compare_impl_method<'tcx>( @@ -41,23 +40,19 @@ pub(super) fn compare_impl_method<'tcx>( impl_m: &ty::AssocItem, trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, - trait_item_span: Option, ) { debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); - let impl_m_span = tcx.def_span(impl_m.def_id); - let _: Result<_, ErrorGuaranteed> = try { - compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)?; - compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false)?; + compare_self_type(tcx, impl_m, trait_m, impl_trait_ref)?; + compare_number_of_generics(tcx, impl_m, trait_m, false)?; compare_generic_param_kinds(tcx, impl_m, trait_m, false)?; - compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?; + compare_number_of_method_arguments(tcx, impl_m, trait_m)?; compare_synthetic_generics(tcx, impl_m, trait_m)?; - compare_asyncness(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?; + compare_asyncness(tcx, impl_m, trait_m)?; compare_method_predicate_entailment( tcx, impl_m, - impl_m_span, trait_m, impl_trait_ref, CheckImpliedWfMode::Check, @@ -131,11 +126,10 @@ pub(super) fn compare_impl_method<'tcx>( /// /// Finally we register each of these predicates as an obligation and check that /// they hold. -#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))] +#[instrument(level = "debug", skip(tcx, impl_trait_ref))] fn compare_method_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, check_implied_wf: CheckImpliedWfMode, @@ -148,6 +142,7 @@ fn compare_method_predicate_entailment<'tcx>( // FIXME(@lcnr): remove that after removing `cause.body_id` from // obligations. let impl_m_def_id = impl_m.def_id.expect_local(); + let impl_m_span = tcx.def_span(impl_m_def_id); let cause = ObligationCause::new( impl_m_span, impl_m_def_id, @@ -315,7 +310,6 @@ fn compare_method_predicate_entailment<'tcx>( return compare_method_predicate_entailment( tcx, impl_m, - impl_m_span, trait_m, impl_trait_ref, CheckImpliedWfMode::Skip, @@ -353,7 +347,6 @@ fn compare_method_predicate_entailment<'tcx>( return compare_method_predicate_entailment( tcx, impl_m, - impl_m_span, trait_m, impl_trait_ref, CheckImpliedWfMode::Skip, @@ -535,9 +528,7 @@ enum CheckImpliedWfMode { fn compare_asyncness<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, - trait_item_span: Option, ) -> Result<(), ErrorGuaranteed> { if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async { match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() { @@ -549,9 +540,9 @@ fn compare_asyncness<'tcx>( } _ => { return Err(tcx.sess.emit_err(crate::errors::AsyncTraitImplShouldBeAsync { - span: impl_m_span, + span: tcx.def_span(impl_m.def_id), method_name: trait_m.name, - trait_item_span, + trait_item_span: tcx.hir().span_if_local(trait_m.def_id), })); } }; @@ -606,7 +597,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during substitution later. - compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?; + compare_number_of_generics(tcx, impl_m, trait_m, true)?; compare_generic_param_kinds(tcx, impl_m, trait_m, true)?; check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?; @@ -1094,7 +1085,6 @@ fn extract_spans_for_error_reporting<'tcx>( fn compare_self_type<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { @@ -1130,6 +1120,7 @@ fn compare_self_type<'tcx>( (false, true) => { let self_descr = self_string(impl_m); + let impl_m_span = tcx.def_span(impl_m.def_id); let mut err = struct_span_err!( tcx.sess, impl_m_span, @@ -1149,6 +1140,7 @@ fn compare_self_type<'tcx>( (true, false) => { let self_descr = self_string(trait_m); + let impl_m_span = tcx.def_span(impl_m.def_id); let mut err = struct_span_err!( tcx.sess, impl_m_span, @@ -1196,7 +1188,6 @@ fn compare_number_of_generics<'tcx>( tcx: TyCtxt<'tcx>, impl_: &ty::AssocItem, trait_: &ty::AssocItem, - trait_span: Option, delay: bool, ) -> Result<(), ErrorGuaranteed> { let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts(); @@ -1256,6 +1247,7 @@ fn compare_number_of_generics<'tcx>( .collect(); (Some(arg_spans), impl_trait_spans) } else { + let trait_span = tcx.hir().span_if_local(trait_.def_id); (trait_span.map(|s| vec![s]), vec![]) }; @@ -1338,9 +1330,7 @@ fn compare_number_of_generics<'tcx>( fn compare_number_of_method_arguments<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, - trait_item_span: Option, ) -> Result<(), ErrorGuaranteed> { let impl_m_fty = tcx.fn_sig(impl_m.def_id); let trait_m_fty = tcx.fn_sig(trait_m.def_id); @@ -1362,7 +1352,7 @@ fn compare_number_of_method_arguments<'tcx>( } }) }) - .or(trait_item_span); + .or_else(|| tcx.hir().span_if_local(trait_m.def_id)); let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let pos = impl_number_args.saturating_sub(1); @@ -1377,7 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>( arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo()) } }) - .unwrap_or(impl_m_span); + .unwrap_or_else(|| tcx.def_span(impl_m.def_id)); let mut err = struct_span_err!( tcx.sess, @@ -1747,22 +1737,16 @@ pub(super) fn compare_impl_const_raw( pub(super) fn compare_impl_ty<'tcx>( tcx: TyCtxt<'tcx>, impl_ty: &ty::AssocItem, - impl_ty_span: Span, trait_ty: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, - trait_item_span: Option, ) { debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref); let _: Result<(), ErrorGuaranteed> = try { - compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?; - + compare_number_of_generics(tcx, impl_ty, trait_ty, false)?; compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?; - - let sp = tcx.def_span(impl_ty.def_id); - compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?; - - check_type_bounds(tcx, trait_ty, impl_ty, impl_ty_span, impl_trait_ref)?; + compare_type_predicate_entailment(tcx, impl_ty, trait_ty, impl_trait_ref)?; + check_type_bounds(tcx, trait_ty, impl_ty, impl_trait_ref)?; }; } @@ -1771,7 +1755,6 @@ pub(super) fn compare_impl_ty<'tcx>( fn compare_type_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, impl_ty: &ty::AssocItem, - impl_ty_span: Span, trait_ty: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { @@ -1808,6 +1791,7 @@ fn compare_type_predicate_entailment<'tcx>( debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); + let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id); let param_env = ty::ParamEnv::new( tcx.intern_predicates(&hybrid_preds.predicates), @@ -1873,7 +1857,6 @@ pub(super) fn check_type_bounds<'tcx>( tcx: TyCtxt<'tcx>, trait_ty: &ty::AssocItem, impl_ty: &ty::AssocItem, - impl_ty_span: Span, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { // Given @@ -2009,8 +1992,15 @@ pub(super) fn check_type_bounds<'tcx>( let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); - let assumed_wf_types = - ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty.def_id.expect_local()); + let impl_ty_span = match tcx.hir().get_by_def_id(impl_ty_def_id) { + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(_, Some(ty)), + .. + }) => ty.span, + hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span, + _ => bug!(), + }; + let assumed_wf_types = ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty_def_id); let normalize_cause = ObligationCause::new( impl_ty_span, diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index bec693439a46c..7b013cabc3ab5 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -75,7 +75,6 @@ pub use check::check_abi; use check::check_mod_item_types; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; -use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; @@ -169,27 +168,24 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { } } -fn report_forbidden_specialization( - tcx: TyCtxt<'_>, - impl_item: &hir::ImplItemRef, - parent_impl: DefId, -) { +fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_impl: DefId) { + let span = tcx.def_span(impl_item); + let ident = tcx.item_name(impl_item); let mut err = struct_span_err!( tcx.sess, - impl_item.span, + span, E0520, - "`{}` specializes an item from a parent `impl`, but \ - that item is not marked `default`", - impl_item.ident + "`{}` specializes an item from a parent `impl`, but that item is not marked `default`", + ident, ); - err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident)); + err.span_label(span, format!("cannot specialize default item `{}`", ident)); match tcx.span_of_impl(parent_impl) { Ok(span) => { err.span_label(span, "parent `impl` is here"); err.note(&format!( "to specialize, `{}` in the parent `impl` must be marked `default`", - impl_item.ident + ident )); } Err(cname) => { diff --git a/tests/rustdoc-ui/issue-105742.rs b/tests/rustdoc-ui/issue-105742.rs index cb1de7433cfaa..9f36e5315ecc2 100644 --- a/tests/rustdoc-ui/issue-105742.rs +++ b/tests/rustdoc-ui/issue-105742.rs @@ -3,38 +3,17 @@ use std::ops::Index; pub fn next<'a, T>(s: &'a mut dyn SVec) { -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR let _ = s; } pub trait SVec: Index< ::Item, -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR Output = ::Item, -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR Output = ::Item> as SVec>::Item, -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR -//~^^^^^ ERROR -//~^^^^^^ ERROR -//~^^^^^^^ ERROR -//~^^^^^^^^ ERROR > { type Item<'a, T>; fn len(&self) -> ::Item; //~^ ERROR //~^^ ERROR - //~^^^ ERROR - //~^^^^ ERROR } diff --git a/tests/rustdoc-ui/issue-105742.stderr b/tests/rustdoc-ui/issue-105742.stderr index ffb602cf86190..4d2ee97268917 100644 --- a/tests/rustdoc-ui/issue-105742.stderr +++ b/tests/rustdoc-ui/issue-105742.stderr @@ -1,360 +1,11 @@ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>> as SVec>::Item, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item> as SVec>::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:5:40 - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:5:40 - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>> as SVec>::Item, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item> as SVec>::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0038]: the trait `SVec` cannot be made into an object - --> $DIR/issue-105742.rs:5:31 - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-105742.rs:12:17 - | -LL | pub trait SVec: Index< - | ____________----__^ - | | | - | | this trait cannot be made into an object... -LL | | ::Item, -LL | | -LL | | -... | -LL | |/ Output = ::Item, -LL | || -LL | || -LL | || -LL | || -LL | || Output = ::Item> as SVec>::Item, - | ||_________________________________________________^ ...because it uses `Self` as a type parameter -... | -LL | | -LL | | > { - | |__^ ...because it uses `Self` as a type parameter - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 - | -LL | fn len(&self) -> ::Item; - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | fn len(&self) -> ::Item<'_>; - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 - | -LL | fn len(&self) -> ::Item; - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | fn len(&self) -> ::Item; - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 + --> $DIR/issue-105742.rs:16:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 + --> $DIR/issue-105742.rs:14:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -364,13 +15,13 @@ LL | fn len(&self) -> ::Item<'_>; | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 + --> $DIR/issue-105742.rs:16:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 + --> $DIR/issue-105742.rs:14:10 | LL | type Item<'a, T>; | ^^^^ - @@ -379,7 +30,6 @@ help: add missing generic argument LL | fn len(&self) -> ::Item; | +++ -error: aborting due to 23 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/error-codes/E0520.stderr b/tests/ui/error-codes/E0520.stderr index 12ecead13de5f..06658a49b83aa 100644 --- a/tests/ui/error-codes/E0520.stderr +++ b/tests/ui/error-codes/E0520.stderr @@ -15,7 +15,7 @@ LL | impl SpaceLlama for T { | ------------------------------- parent `impl` is here ... LL | default fn fly(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `fly` + | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `fly` | = note: to specialize, `fly` in the parent `impl` must be marked `default` diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr index 770be2af28146..f9e62a99baee8 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr @@ -15,7 +15,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn foo(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` @@ -26,7 +26,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn bar(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `bar` + | ^^^^^^^^^^^^^ cannot specialize default item `bar` | = note: to specialize, `bar` in the parent `impl` must be marked `default` @@ -37,7 +37,7 @@ LL | impl Bar for T { | ----------------- parent `impl` is here ... LL | type T = (); - | ^^^^^^^^^^^^ cannot specialize default item `T` + | ^^^^^^ cannot specialize default item `T` | = note: to specialize, `T` in the parent `impl` must be marked `default` @@ -48,7 +48,7 @@ LL | impl Baz for T { | ------------------------ parent `impl` is here ... LL | fn baz(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `baz` + | ^^^^^^^^^^^^^ cannot specialize default item `baz` | = note: to specialize, `baz` in the parent `impl` must be marked `default` @@ -59,7 +59,7 @@ LL | impl Redundant for T { | ------------------------------ parent `impl` is here ... LL | fn redundant(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` + | ^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` | = note: to specialize, `redundant` in the parent `impl` must be marked `default` diff --git a/tests/ui/specialization/issue-50452-fail.stderr b/tests/ui/specialization/issue-50452-fail.stderr index 5c136adc451d5..3fc29fff230a3 100644 --- a/tests/ui/specialization/issue-50452-fail.stderr +++ b/tests/ui/specialization/issue-50452-fail.stderr @@ -12,7 +12,7 @@ error[E0520]: `foo` specializes an item from a parent `impl`, but that item is n --> $DIR/issue-50452-fail.rs:10:5 | LL | fn foo() {} - | ^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^ cannot specialize default item `foo` ... LL | impl Foo for T { | ----------------- parent `impl` is here diff --git a/tests/ui/specialization/non-defaulted-item-fail.stderr b/tests/ui/specialization/non-defaulted-item-fail.stderr index faa14555a4f39..9d62a353da728 100644 --- a/tests/ui/specialization/non-defaulted-item-fail.stderr +++ b/tests/ui/specialization/non-defaulted-item-fail.stderr @@ -15,7 +15,7 @@ LL | impl Foo for Box { | ---------------------- parent `impl` is here ... LL | type Ty = Vec<()>; - | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `Ty` + | ^^^^^^^ cannot specialize default item `Ty` | = note: to specialize, `Ty` in the parent `impl` must be marked `default` @@ -26,7 +26,7 @@ LL | impl Foo for Box { | ---------------------- parent `impl` is here ... LL | const CONST: u8 = 42; - | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `CONST` + | ^^^^^^^^^^^^^^^ cannot specialize default item `CONST` | = note: to specialize, `CONST` in the parent `impl` must be marked `default` @@ -37,7 +37,7 @@ LL | impl Foo for Box { | ---------------------- parent `impl` is here ... LL | fn foo(&self) -> bool { true } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` @@ -48,7 +48,7 @@ LL | impl Foo for Vec {} | ---------------------- parent `impl` is here ... LL | type Ty = Vec<()>; - | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `Ty` + | ^^^^^^^ cannot specialize default item `Ty` | = note: to specialize, `Ty` in the parent `impl` must be marked `default` @@ -59,7 +59,7 @@ LL | impl Foo for Vec {} | ---------------------- parent `impl` is here ... LL | const CONST: u8 = 42; - | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `CONST` + | ^^^^^^^^^^^^^^^ cannot specialize default item `CONST` | = note: to specialize, `CONST` in the parent `impl` must be marked `default` @@ -70,7 +70,7 @@ LL | impl Foo for Vec {} | ---------------------- parent `impl` is here ... LL | fn foo(&self) -> bool { true } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` diff --git a/tests/ui/specialization/specialization-no-default.stderr b/tests/ui/specialization/specialization-no-default.stderr index 842cec9c79fbb..695a3f6cc45d1 100644 --- a/tests/ui/specialization/specialization-no-default.stderr +++ b/tests/ui/specialization/specialization-no-default.stderr @@ -15,7 +15,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn foo(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` @@ -26,7 +26,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn bar(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `bar` + | ^^^^^^^^^^^^^ cannot specialize default item `bar` | = note: to specialize, `bar` in the parent `impl` must be marked `default` @@ -37,7 +37,7 @@ LL | impl Bar for T { | ----------------- parent `impl` is here ... LL | type T = (); - | ^^^^^^^^^^^^ cannot specialize default item `T` + | ^^^^^^ cannot specialize default item `T` | = note: to specialize, `T` in the parent `impl` must be marked `default` @@ -48,7 +48,7 @@ LL | impl Baz for T { | ------------------------ parent `impl` is here ... LL | fn baz(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `baz` + | ^^^^^^^^^^^^^ cannot specialize default item `baz` | = note: to specialize, `baz` in the parent `impl` must be marked `default` @@ -59,7 +59,7 @@ LL | impl Redundant for T { | ------------------------------ parent `impl` is here ... LL | default fn redundant(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` | = note: to specialize, `redundant` in the parent `impl` must be marked `default` diff --git a/tests/ui/traits/negative-impls/no-items.stderr b/tests/ui/traits/negative-impls/no-items.stderr index 67b94bba12143..040d9d14503f0 100644 --- a/tests/ui/traits/negative-impls/no-items.stderr +++ b/tests/ui/traits/negative-impls/no-items.stderr @@ -2,7 +2,7 @@ error[E0749]: negative impls cannot have any items --> $DIR/no-items.rs:8:5 | LL | type Foo = i32; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to previous error From 0d39f9d94d2eddd31e4743ae1e3ea269bb3e0984 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 19:46:51 +0000 Subject: [PATCH 5/9] Do not fetch HIR to monomorphize impls. --- compiler/rustc_monomorphize/src/collector.rs | 114 +++++++------------ 1 file changed, 42 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8f6338472df58..dd7ee220d7311 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1191,28 +1191,14 @@ impl<'v> RootCollector<'_, 'v> { fn process_item(&mut self, id: hir::ItemId) { match self.tcx.def_kind(id.owner_id) { DefKind::Enum | DefKind::Struct | DefKind::Union => { - let item = self.tcx.hir().item(id); - match item.kind { - hir::ItemKind::Enum(_, ref generics) - | hir::ItemKind::Struct(_, ref generics) - | hir::ItemKind::Union(_, ref generics) => { - if generics.params.is_empty() { - if self.mode == MonoItemCollectionMode::Eager { - debug!( - "RootCollector: ADT drop-glue for {}", - self.tcx.def_path_str(item.owner_id.to_def_id()) - ); - - let ty = Instance::new( - item.owner_id.to_def_id(), - InternalSubsts::empty(), - ) - .ty(self.tcx, ty::ParamEnv::reveal_all()); - visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); - } - } - } - _ => bug!(), + if self.tcx.generics_of(id.owner_id).count() == 0 + && self.mode == MonoItemCollectionMode::Eager + { + debug!("RootCollector: ADT drop-glue for `{id:?}`",); + + let ty = + self.tcx.bound_type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap(); + visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } } DefKind::GlobalAsm => { @@ -1240,8 +1226,7 @@ impl<'v> RootCollector<'_, 'v> { } DefKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { - let item = self.tcx.hir().item(id); - create_mono_items_for_default_impls(self.tcx, item, self.output); + create_mono_items_for_default_impls(self.tcx, id, self.output); } } DefKind::Fn => { @@ -1326,66 +1311,51 @@ fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { generics.requires_monomorphization(tcx) } +#[instrument(level = "debug", skip(tcx, output))] fn create_mono_items_for_default_impls<'tcx>( tcx: TyCtxt<'tcx>, - item: &'tcx hir::Item<'tcx>, + item: hir::ItemId, output: &mut MonoItems<'tcx>, ) { - match item.kind { - hir::ItemKind::Impl(ref impl_) => { - if matches!(impl_.polarity, hir::ImplPolarity::Negative(_)) { - return; - } + let polarity = tcx.impl_polarity(item.owner_id); + if matches!(polarity, ty::ImplPolarity::Negative) { + return; + } - for param in impl_.generics.params { - match param.kind { - hir::GenericParamKind::Lifetime { .. } => {} - hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => { - return; - } - } - } + if tcx.generics_of(item.owner_id).own_requires_monomorphization() { + return; + } - debug!( - "create_mono_items_for_default_impls(item={})", - tcx.def_path_str(item.owner_id.to_def_id()) - ); + let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else { + return; + }; - if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) { - let trait_ref = trait_ref.subst_identity(); + let trait_ref = trait_ref.subst_identity(); - let param_env = ty::ParamEnv::reveal_all(); - let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); - let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); - for method in tcx.provided_trait_methods(trait_ref.def_id) { - if overridden_methods.contains_key(&method.def_id) { - continue; - } + let param_env = ty::ParamEnv::reveal_all(); + let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); + let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); + for method in tcx.provided_trait_methods(trait_ref.def_id) { + if overridden_methods.contains_key(&method.def_id) { + continue; + } - if tcx.generics_of(method.def_id).own_requires_monomorphization() { - continue; - } + if tcx.generics_of(method.def_id).own_requires_monomorphization() { + continue; + } - let substs = - InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize] - } - }); - let instance = - ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs); - - let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); - if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, &instance) - { - output.push(mono_item); - } - } + let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { + GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + trait_ref.substs[param.index as usize] } + }); + let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs); + + let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); + if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, &instance) { + output.push(mono_item); } - _ => bug!(), } } From e49e7f6a2e62670704ec52e10f7639c17afe4f8e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 20:15:12 +0000 Subject: [PATCH 6/9] Do not fetch HIR to compute symbols. --- .../src/back/symbol_export.rs | 67 ++++++++++--------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 57a99e74c21ad..11bd47a8f0c79 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -2,9 +2,8 @@ use std::collections::hash_map::Entry::*; use rustc_ast::expand::allocator::ALLOCATOR_METHODS; use rustc_data_structures::fx::FxHashMap; -use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; -use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{ metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, @@ -12,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::Instance; -use rustc_middle::ty::{self, SymbolName, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, SymbolName, TyCtxt}; use rustc_session::config::{CrateType, OomStrategy}; use rustc_target::spec::SanitizerSet; @@ -74,32 +73,34 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< // // As a result, if this id is an FFI item (foreign item) then we only // let it through if it's included statically. - match tcx.hir().get_by_def_id(def_id) { - Node::ForeignItem(..) => { - tcx.native_library(def_id).map_or(false, |library| library.kind.is_statically_included()).then_some(def_id) - } + if let Some(parent_id) = tcx.opt_local_parent(def_id) + && let DefKind::ForeignMod = tcx.def_kind(parent_id) + { + let library = tcx.native_library(def_id)?; + return library.kind.is_statically_included().then_some(def_id); + } - // Only consider nodes that actually have exported symbols. - Node::Item(&hir::Item { - kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..), - .. - }) - | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => { - let generics = tcx.generics_of(def_id); - if !generics.requires_monomorphization(tcx) - // Functions marked with #[inline] are codegened with "internal" - // linkage and are not exported unless marked with an extern - // indicator - && (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) - || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator()) - { - Some(def_id) - } else { - None - } - } + // Only consider nodes that actually have exported symbols. + match tcx.def_kind(def_id) { + DefKind::Fn | DefKind::Static(_) => {} + DefKind::AssocFn if tcx.impl_of_method(def_id.to_def_id()).is_some() => {} + _ => return None, + }; - _ => None, + let generics = tcx.generics_of(def_id); + if generics.requires_monomorphization(tcx) { + return None; + } + + // Functions marked with #[inline] are codegened with "internal" + // linkage and are not exported unless marked with an extern + // indicator + if !Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) + || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator() + { + Some(def_id) + } else { + None } }) .map(|def_id| { @@ -118,7 +119,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())), export_level ); - (def_id.to_def_id(), SymbolExportInfo { + let info = SymbolExportInfo { level: export_level, kind: if tcx.is_static(def_id.to_def_id()) { if codegen_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { @@ -130,8 +131,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< SymbolExportKind::Text }, used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) - || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) || used, - }) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + || used, + }; + (def_id.to_def_id(), info) }) .collect(); @@ -457,9 +460,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel let target = &tcx.sess.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level if target.contains("emscripten") { - if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) = - tcx.hir().get_if_local(sym_def_id) - { + if let DefKind::Static(_) = tcx.def_kind(sym_def_id) { return SymbolExportLevel::Rust; } } From 68fb752035aa954b7881b846ec1cd5bd3354a4cf Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 20:20:45 +0000 Subject: [PATCH 7/9] Do not fetch HIR to check target features. --- compiler/rustc_codegen_ssa/src/target_features.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 739963fffd132..a6afbad5b2402 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -3,12 +3,12 @@ use rustc_attr::InstructionSetAttr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::sym; @@ -440,12 +440,9 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxHashSet { /// Checks the function annotated with `#[target_feature]` is not a safe /// trait method implementation, reporting an error if it is. pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) { - let hir_id = tcx.hir().local_def_id_to_hir_id(id); - let node = tcx.hir().get(hir_id); - if let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) = node { - let parent_id = tcx.hir().get_parent_item(hir_id); - let parent_item = tcx.hir().expect_item(parent_id.def_id); - if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = parent_item.kind { + if let DefKind::AssocFn = tcx.def_kind(id) { + let parent_id = tcx.local_parent(id); + if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) { tcx.sess .struct_span_err( attr_span, From 40cb4d1bc78f9479b6c29ade5d2ecf89dc4eba35 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 21:08:14 +0000 Subject: [PATCH 8/9] Even less HIR. --- .../rustc_hir_analysis/src/check/check.rs | 18 ++++------ .../src/check/intrinsicck.rs | 4 +-- .../src/coherence/builtin.rs | 3 +- .../src/coherence/orphan.rs | 36 ++++++++++--------- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d5def62885043..71ed9253668cb 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -21,7 +21,9 @@ use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{ + self, AdtDef, DefIdTree, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, +}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, Span}; @@ -174,16 +176,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { Ok(l) => l, // Foreign statics that overflow their allowed size should emit an error Err(LayoutError::SizeOverflow(_)) - if { - let node = tcx.hir().get_by_def_id(def_id); - matches!( - node, - hir::Node::ForeignItem(hir::ForeignItem { - kind: hir::ForeignItemKind::Static(..), - .. - }) - ) - } => + if matches!(tcx.def_kind(def_id), DefKind::Static(_) + if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) => { tcx.sess .struct_span_err(span, "extern static is too large for the current architecture") @@ -215,7 +209,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { let item = tcx.hir().item(id); let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else { - tcx.sess.delay_span_bug(tcx.hir().span(id.hir_id()), "expected opaque item"); + tcx.sess.delay_span_bug(item.span, "expected opaque item"); return; }; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 122b6ead8e9d7..56ac18c492792 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -414,7 +414,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that sym actually points to a function. Later passes // depend on this. hir::InlineAsmOperand::SymFn { anon_const } => { - let ty = self.tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + let ty = self.tcx.type_of(anon_const.def_id); match ty.kind() { ty::Never | ty::Error(_) => {} ty::FnDef(..) => {} @@ -422,7 +422,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let mut err = self.tcx.sess.struct_span_err(*op_sp, "invalid `sym` operand"); err.span_label( - self.tcx.hir().span(anon_const.body.hir_id), + self.tcx.def_span(anon_const.def_id), &format!("is {} `{}`", ty.kind().article(), ty), ); err.help("`sym` operands must refer to either a function or a static"); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 8c2423e3ca0d1..c0ba385987d77 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -202,8 +202,7 @@ fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'_>, impl_did: LocalDefId) fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); - let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_did); - let span = tcx.hir().span(impl_hir_id); + let span = tcx.def_span(impl_did); let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index d0db8cabfddb2..49a9a2ea29309 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -38,26 +38,28 @@ fn do_orphan_check_impl<'tcx>( def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let trait_def_id = trait_ref.def_id; - - let item = tcx.hir().expect_item(def_id); - let hir::ItemKind::Impl(impl_) = item.kind else { - bug!("{:?} is not an impl: {:?}", def_id, item); - }; let sp = tcx.def_span(def_id); - let tr = impl_.of_trait.as_ref().unwrap(); - match traits::orphan_check(tcx, item.owner_id.to_def_id()) { + match traits::orphan_check(tcx, def_id.to_def_id()) { Ok(()) => {} - Err(err) => emit_orphan_check_error( - tcx, - sp, - item.span, - tr.path.span, - trait_ref, - impl_.self_ty.span, - &impl_.generics, - err, - )?, + Err(err) => { + let item = tcx.hir().expect_item(def_id); + let hir::ItemKind::Impl(impl_) = item.kind else { + bug!("{:?} is not an impl: {:?}", def_id, item); + }; + let tr = impl_.of_trait.as_ref().unwrap(); + + emit_orphan_check_error( + tcx, + sp, + item.span, + tr.path.span, + trait_ref, + impl_.self_ty.span, + &impl_.generics, + err, + )? + } } // In addition to the above rules, we restrict impls of auto traits From 065f0b222d4e23ae3d4215061c5df7d248855717 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 14 Feb 2023 18:12:49 +0000 Subject: [PATCH 9/9] Move query out of path. --- compiler/rustc_hir_analysis/src/coherence/orphan.rs | 9 +++++++-- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 49a9a2ea29309..f0a0e7e3e9293 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -38,7 +38,6 @@ fn do_orphan_check_impl<'tcx>( def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let trait_def_id = trait_ref.def_id; - let sp = tcx.def_span(def_id); match traits::orphan_check(tcx, def_id.to_def_id()) { Ok(()) => {} @@ -48,6 +47,7 @@ fn do_orphan_check_impl<'tcx>( bug!("{:?} is not an impl: {:?}", def_id, item); }; let tr = impl_.of_trait.as_ref().unwrap(); + let sp = tcx.def_span(def_id); emit_orphan_check_error( tcx, @@ -237,7 +237,10 @@ fn do_orphan_check_impl<'tcx>( | ty::GeneratorWitnessMIR(..) | ty::Bound(..) | ty::Placeholder(..) - | ty::Infer(..) => span_bug!(sp, "weird self type for autotrait impl"), + | ty::Infer(..) => { + let sp = tcx.def_span(def_id); + span_bug!(sp, "weird self type for autotrait impl") + } ty::Error(..) => (LocalImpl::Allow, NonlocalImpl::Allow), }; @@ -256,6 +259,7 @@ fn do_orphan_check_impl<'tcx>( is one of the trait object's trait bounds", trait = tcx.def_path_str(trait_def_id), ); + let sp = tcx.def_span(def_id); let reported = struct_span_err!(tcx.sess, sp, E0321, "{}", msg).note(label).emit(); return Err(reported); @@ -284,6 +288,7 @@ fn do_orphan_check_impl<'tcx>( non-struct/enum type", )), } { + let sp = tcx.def_span(def_id); let reported = struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); return Err(reported); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index dd7ee220d7311..bbe4e67977c94 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1191,8 +1191,8 @@ impl<'v> RootCollector<'_, 'v> { fn process_item(&mut self, id: hir::ItemId) { match self.tcx.def_kind(id.owner_id) { DefKind::Enum | DefKind::Struct | DefKind::Union => { - if self.tcx.generics_of(id.owner_id).count() == 0 - && self.mode == MonoItemCollectionMode::Eager + if self.mode == MonoItemCollectionMode::Eager + && self.tcx.generics_of(id.owner_id).count() == 0 { debug!("RootCollector: ADT drop-glue for `{id:?}`",);