From 4d03de651d3fb4f035f172ca6fc44b9d88b2fa57 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 16 Sep 2025 11:18:03 -0500 Subject: [PATCH 1/9] Optimize impl_trait_ref usage in sanitizer --- .../cfi/typeid/itanium_cxx_abi/transform.rs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 82a2a64f23078..7395bcfa201e1 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -10,8 +10,9 @@ use rustc_hir as hir; use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::{ - self, ExistentialPredicateStableCmpExt as _, Instance, InstanceKind, IntTy, List, TraitRef, Ty, - TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy, + self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, InstanceKind, IntTy, + List, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + UintTy, }; use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, sym}; @@ -466,20 +467,20 @@ fn implemented_method<'tcx>( let method_id; let trait_id; let trait_method; - let ancestor = if let Some(impl_id) = tcx.impl_of_assoc(instance.def_id()) { - // Implementation in an `impl` block - trait_ref = tcx.impl_trait_ref(impl_id)?; - method_id = tcx.trait_item_of(instance.def_id())?; + let assoc = tcx.opt_associated_item(instance.def_id())?; + let ancestor = if let AssocContainer::TraitImpl(Ok(trait_method_id)) = assoc.container { + let impl_id = tcx.parent(instance.def_id()); + trait_ref = tcx.impl_trait_ref(impl_id).unwrap(); + method_id = trait_method_id; trait_method = tcx.associated_item(method_id); trait_id = trait_ref.skip_binder().def_id; impl_id - } else if let InstanceKind::Item(def_id) = instance.def - && let Some(trait_method_bound) = tcx.opt_associated_item(def_id) + } else if let AssocContainer::Trait = assoc.container + && let InstanceKind::Item(def_id) = instance.def { - // Provided method in a `trait` block - trait_method = trait_method_bound; - method_id = instance.def_id(); - trait_id = tcx.trait_of_assoc(method_id)?; + trait_method = assoc; + method_id = def_id; + trait_id = tcx.parent(method_id); trait_ref = ty::EarlyBinder::bind(TraitRef::from_assoc(tcx, trait_id, instance.args)); trait_id } else { From 9b2c9a8c5b15fc0df2abd790d5f5643c48bf5d1e Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 16 Sep 2025 17:36:19 -0500 Subject: [PATCH 2/9] Refactor default_could_be_derived --- .../src/default_could_be_derived.rs | 60 ++++++++----------- compiler/rustc_lint/src/lib.rs | 2 +- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 1d92cfbc03916..8f028b1d96a21 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -1,14 +1,12 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, Diag}; use rustc_hir as hir; -use rustc_hir::attrs::AttributeKind; -use rustc_hir::find_attr; use rustc_middle::ty; use rustc_middle::ty::TyCtxt; -use rustc_session::{declare_lint, impl_lint_pass}; -use rustc_span::Symbol; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::def_id::DefId; use rustc_span::symbol::sym; +use rustc_span::{Span, Symbol}; use crate::{LateContext, LateLintPass}; @@ -52,27 +50,24 @@ declare_lint! { @feature_gate = default_field_values; } -#[derive(Default)] -pub(crate) struct DefaultCouldBeDerived; - -impl_lint_pass!(DefaultCouldBeDerived => [DEFAULT_OVERRIDES_DEFAULT_FIELDS]); +declare_lint_pass!(DefaultCouldBeDerived => [DEFAULT_OVERRIDES_DEFAULT_FIELDS]); impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { // Look for manual implementations of `Default`. - let Some(default_def_id) = cx.tcx.get_diagnostic_item(sym::Default) else { return }; - let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; - let parent = cx.tcx.parent(impl_item.owner_id.to_def_id()); - if find_attr!(cx.tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) { - // We don't care about what `#[derive(Default)]` produces in this lint. + let hir::ImplItemImplKind::Trait { trait_item_def_id, .. } = impl_item.impl_kind else { + return; + }; + if !trait_item_def_id.is_ok_and(|id| cx.tcx.is_diagnostic_item(sym::default_fn, id)) { return; } - let Some(trait_ref) = cx.tcx.impl_trait_ref(parent) else { return }; - let trait_ref = trait_ref.instantiate_identity(); - if trait_ref.def_id != default_def_id { + let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; + let impl_id = cx.tcx.local_parent(impl_item.owner_id.def_id); + if cx.tcx.is_automatically_derived(impl_id.to_def_id()) { + // We don't care about what `#[derive(Default)]` produces in this lint. return; } - let ty = trait_ref.self_ty(); + let ty = cx.tcx.type_of(impl_id).instantiate_identity(); let ty::Adt(def, _) = ty.kind() else { return }; // We now know we have a manually written definition of a `::default()`. @@ -150,11 +145,10 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { return; } - let Some(local) = parent.as_local() else { return }; - let hir_id = cx.tcx.local_def_id_to_hir_id(local); - let hir::Node::Item(item) = cx.tcx.hir_node(hir_id) else { return }; - cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, item.span, |diag| { - mk_lint(cx.tcx, diag, type_def_id, parent, orig_fields, fields); + let hir_id = cx.tcx.local_def_id_to_hir_id(impl_id); + let span = cx.tcx.hir_span_with_body(hir_id); + cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, span, |diag| { + mk_lint(cx.tcx, diag, type_def_id, orig_fields, fields, span); }); } } @@ -163,9 +157,9 @@ fn mk_lint( tcx: TyCtxt<'_>, diag: &mut Diag<'_, ()>, type_def_id: DefId, - impl_def_id: DefId, orig_fields: FxHashMap>, fields: &[hir::ExprField<'_>], + impl_span: Span, ) { diag.primary_message("`Default` impl doesn't use the declared default field values"); @@ -186,18 +180,14 @@ fn mk_lint( if removed_all_fields { let msg = "to avoid divergence in behavior between `Struct { .. }` and \ `::default()`, derive the `Default`"; - if let Some(hir::Node::Item(impl_)) = tcx.hir_get_if_local(impl_def_id) { - diag.multipart_suggestion_verbose( - msg, - vec![ - (tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()), - (impl_.span, String::new()), - ], - Applicability::MachineApplicable, - ); - } else { - diag.help(msg); - } + diag.multipart_suggestion_verbose( + msg, + vec![ + (tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()), + (impl_span, String::new()), + ], + Applicability::MachineApplicable, + ); } else { let msg = "use the default values in the `impl` with `Struct { mandatory_field, .. }` to \ avoid them diverging over time"; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b2abd0e2e2c5e..b4c18483a923b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -191,7 +191,7 @@ late_lint_methods!( BuiltinCombinedModuleLateLintPass, [ ForLoopsOverFallibles: ForLoopsOverFallibles, - DefaultCouldBeDerived: DefaultCouldBeDerived::default(), + DefaultCouldBeDerived: DefaultCouldBeDerived, DerefIntoDynSupertrait: DerefIntoDynSupertrait, DropForgetUseless: DropForgetUseless, ImproperCTypesLint: ImproperCTypesLint, From dcf76b68116f1b6b3955a3c3d5dc1adf987feb53 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 24 Jul 2025 16:08:35 -0500 Subject: [PATCH 3/9] Move some TyCtxt trait methods close together --- compiler/rustc_middle/src/ty/context.rs | 13 ------------- compiler/rustc_middle/src/ty/mod.rs | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index de2b2e6c64f25..bf99aa76a0d64 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3530,19 +3530,6 @@ impl<'tcx> TyCtxt<'tcx> { crate::dep_graph::make_metadata(self) } - /// Given an `impl_id`, return the trait it implements. - /// Return `None` if this is an inherent impl. - pub fn impl_trait_ref( - self, - def_id: impl IntoQueryParam, - ) -> Option>> { - Some(self.impl_trait_header(def_id)?.trait_ref) - } - - pub fn impl_polarity(self, def_id: impl IntoQueryParam) -> ty::ImplPolarity { - self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity) - } - pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool { if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = self.coroutine_kind(def_id) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b6adc606b8736..7387832cc2211 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1970,6 +1970,19 @@ impl<'tcx> TyCtxt<'tcx> { } } + pub fn impl_polarity(self, def_id: impl IntoQueryParam) -> ty::ImplPolarity { + self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity) + } + + /// Given an `impl_id`, return the trait it implements. + /// Return `None` if this is an inherent impl. + pub fn impl_trait_ref( + self, + def_id: impl IntoQueryParam, + ) -> Option>> { + Some(self.impl_trait_header(def_id)?.trait_ref) + } + pub fn is_exportable(self, def_id: DefId) -> bool { self.exportable_items(def_id.krate).contains(&def_id) } From c17b2dc2831bd127b77b7c2e075cea993a0dbee2 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Sat, 9 Aug 2025 16:39:04 -0500 Subject: [PATCH 4/9] Split trait_id_of_impl into impl(_opt)_trait_id --- .../src/diagnostics/mutability_errors.rs | 3 +-- .../src/check/always_applicable.rs | 6 ++---- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 8 +------- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 18 ++++++++++++------ .../rustc_monomorphize/src/partitioning.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 4 +--- .../src/error_reporting/traits/call_kind.rs | 2 +- .../src/traits/project.rs | 2 +- .../traits/specialize/specialization_graph.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 2 +- 12 files changed, 24 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6b5af15febea0..b4990ffc7739c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -708,8 +708,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return (false, false, None); } let my_def = self.body.source.def_id(); - let Some(td) = - tcx.trait_impl_of_assoc(my_def).and_then(|id| self.infcx.tcx.trait_id_of_impl(id)) + let Some(td) = tcx.trait_impl_of_assoc(my_def).map(|id| self.infcx.tcx.impl_trait_id(id)) else { return (false, false, None); }; diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index 0ff01477ff24c..f4130e1d8f908 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -148,8 +148,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>( ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", ty::ImplPolarity::Negative => "!", }; - let trait_name = tcx - .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); + let trait_name = tcx.item_name(tcx.impl_trait_id(impl_def_id.to_def_id())); let mut err = struct_span_code_err!( tcx.dcx(), impl_span, @@ -187,8 +186,7 @@ fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>( let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let impl_span = tcx.def_span(impl_def_id.to_def_id()); - let trait_name = tcx - .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait")); + let trait_name = tcx.item_name(tcx.impl_trait_id(impl_def_id.to_def_id())); let polarity = match tcx.impl_polarity(impl_def_id) { ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", ty::ImplPolarity::Negative => "!", diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 04f112e4a39cc..35be28f7f7b81 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -242,7 +242,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *source { // Note: this cannot come from an inherent impl, // because the first probing succeeded. - CandidateSource::Impl(def) => self.tcx.trait_id_of_impl(def), + CandidateSource::Impl(def) => Some(self.tcx.impl_trait_id(def)), CandidateSource::Trait(_) => None, } }) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 8a9d39408947c..14043be65f623 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1176,9 +1176,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // things failed, so lets look at all traits, for diagnostic purposes now: self.reset(); - let span = self.span; - let tcx = self.tcx; - self.assemble_extension_candidates_for_all_traits(); let out_of_scope_traits = match self.pick_core(&mut Vec::new()) { @@ -1187,10 +1184,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .into_iter() .map(|source| match source { CandidateSource::Trait(id) => id, - CandidateSource::Impl(impl_id) => match tcx.trait_id_of_impl(impl_id) { - Some(id) => id, - None => span_bug!(span, "found inherent method when looking at traits"), - }, + CandidateSource::Impl(impl_id) => self.tcx.impl_trait_id(impl_id), }) .collect(), Some(Err(MethodError::NoMatch(NoMatchData { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 44602e6289940..02f8e27ab1947 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3720,7 +3720,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { static_candidates.iter().all(|sc| match *sc { CandidateSource::Trait(def_id) => def_id != info.def_id, CandidateSource::Impl(def_id) => { - self.tcx.trait_id_of_impl(def_id) != Some(info.def_id) + self.tcx.impl_opt_trait_id(def_id) != Some(info.def_id) } }) }) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7387832cc2211..43507cf44de17 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1913,12 +1913,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. - /// If it implements no trait, returns `None`. - pub fn trait_id_of_impl(self, def_id: DefId) -> Option { - self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id) - } - /// If the given `DefId` is an associated item, returns the `DefId` and `DefKind` of the parent trait or impl. pub fn assoc_parent(self, def_id: DefId) -> Option<(DefId, DefKind)> { if !self.def_kind(def_id).is_assoc() { @@ -1983,6 +1977,18 @@ impl<'tcx> TyCtxt<'tcx> { Some(self.impl_trait_header(def_id)?.trait_ref) } + /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. + pub fn impl_trait_id(self, def_id: DefId) -> DefId { + self.impl_opt_trait_id(def_id) + .unwrap_or_else(|| panic!("expected impl of trait for {def_id:?}")) + } + + /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. + /// If it implements no trait, returns `None`. + pub fn impl_opt_trait_id(self, def_id: DefId) -> Option { + self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id) + } + pub fn is_exportable(self, def_id: DefId) -> bool { self.exportable_items(def_id.krate).contains(&def_id) } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index d784d3540c410..b87ab840a32d5 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -649,7 +649,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( if let Some((impl_def_id, DefKind::Impl { of_trait })) = assoc_parent { if of_trait && tcx.sess.opts.incremental.is_some() - && tcx.is_lang_item(tcx.trait_id_of_impl(impl_def_id).unwrap(), LangItem::Drop) + && tcx.is_lang_item(tcx.impl_trait_id(impl_def_id), LangItem::Drop) { // Put `Drop::drop` into the same cgu as `drop_in_place` // since `drop_in_place` is the only thing that can diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index d1a703fc5d841..74f689228b7d6 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -404,9 +404,7 @@ fn check_item<'tcx>( let items = tcx.associated_item_def_ids(id.owner_id); worklist.extend(items.iter().map(|ii_ref| ii_ref.expect_local())); - let Some(trait_def_id) = tcx.trait_id_of_impl(id.owner_id.to_def_id()) else { - unreachable!(); - }; + let trait_def_id = tcx.impl_trait_id(id.owner_id.to_def_id()); if !trait_def_id.is_local() { return; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index f54ebd76cab07..2c18ffc105503 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -77,7 +77,7 @@ pub fn call_kind<'tcx>( let container_id = assoc.container_id(tcx); match assoc.container { AssocContainer::InherentImpl => None, - AssocContainer::TraitImpl(_) => tcx.trait_id_of_impl(container_id), + AssocContainer::TraitImpl(_) => Some(tcx.impl_trait_id(container_id)), AssocContainer::Trait => Some(container_id), } }); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index fab5102427c70..fea4b7cec62b6 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1979,7 +1979,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source; let assoc_item_id = obligation.predicate.def_id; - let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); + let trait_def_id = tcx.impl_trait_id(impl_def_id); let param_env = obligation.param_env; let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 12ba12be8838f..f80731fdf93a7 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -354,7 +354,7 @@ pub(crate) fn assoc_def( impl_def_id: DefId, assoc_def_id: DefId, ) -> Result { - let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); + let trait_def_id = tcx.impl_trait_id(impl_def_id); let trait_def = tcx.trait_def(trait_def_id); // This function may be called while we are still building the diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index e28ebaabc0a1f..23bbd9ca6d639 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -131,7 +131,7 @@ fn resolve_associated_item<'tcx>( assert!(!rcvr_args.has_infer()); assert!(!trait_ref.has_infer()); - let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap(); + let trait_def_id = tcx.impl_trait_id(impl_data.impl_def_id); let trait_def = tcx.trait_def(trait_def_id); let leaf_def = trait_def .ancestors(tcx, impl_data.impl_def_id)? From ca5073759c232cbed39e9b61abba0e33bfaa1aaa Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 16 Sep 2025 17:50:04 -0500 Subject: [PATCH 5/9] Remove some impl_trait_ref usages --- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/collect/predicates_of.rs | 14 +++++++---- .../rustc_hir_analysis/src/impl_wf_check.rs | 9 ++++--- .../src/impl_wf_check/min_specialization.rs | 2 +- .../rustc_hir_typeck/src/method/confirm.rs | 6 ++--- compiler/rustc_middle/src/ty/trait_def.rs | 4 +--- compiler/rustc_ty_utils/src/implied_bounds.rs | 10 ++++---- compiler/rustc_ty_utils/src/opaque_types.rs | 24 +++---------------- 8 files changed, 30 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 6e537c668843c..55b1520fda06b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -245,7 +245,7 @@ pub(super) fn check_item<'tcx>( // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` hir::ItemKind::Impl(ref impl_) => { - crate::impl_wf_check::check_impl_wf(tcx, def_id)?; + crate::impl_wf_check::check_impl_wf(tcx, def_id, impl_.of_trait.is_some())?; let mut res = Ok(()); if let Some(of_trait) = impl_.of_trait { let header = tcx.impl_trait_header(def_id).unwrap(); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ffdf2a2f4c0c8..c6afa9f6897a4 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -350,9 +350,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // before uses of `U`. This avoids false ambiguity errors // in trait checking. See `setup_constraining_predicates` // for details. - if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { + if let Node::Item(&Item { kind: ItemKind::Impl(impl_), .. }) = node { let self_ty = tcx.type_of(def_id).instantiate_identity(); - let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::instantiate_identity); + let trait_ref = impl_ + .of_trait + .is_some() + .then(|| tcx.impl_trait_ref(def_id).unwrap().instantiate_identity()); cgp::setup_constraining_predicates( tcx, &mut predicates, @@ -460,11 +463,12 @@ fn const_evaluatable_predicates_of<'tcx>( } if let hir::Node::Item(item) = node - && let hir::ItemKind::Impl(_) = item.kind + && let hir::ItemKind::Impl(impl_) = item.kind { - if let Some(of_trait) = tcx.impl_trait_ref(def_id) { + if impl_.of_trait.is_some() { debug!("visit impl trait_ref"); - of_trait.instantiate_identity().visit_with(&mut collector); + let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + trait_ref.instantiate_identity().visit_with(&mut collector); } debug!("visit self_ty"); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 19ba166fa42a8..5955107cf2d39 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -56,6 +56,7 @@ mod min_specialization; pub(crate) fn check_impl_wf( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, + of_trait: bool, ) -> Result<(), ErrorGuaranteed> { debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }); @@ -63,9 +64,9 @@ pub(crate) fn check_impl_wf( // since unconstrained type/const params cause ICEs in projection, so we want to // detect those specifically and project those to `TyKind::Error`. let mut res = tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id); - res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id)); + res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id, of_trait)); - if tcx.features().min_specialization() { + if of_trait && tcx.features().min_specialization() { res = res.and(check_min_specialization(tcx, impl_def_id)); } res @@ -74,6 +75,7 @@ pub(crate) fn check_impl_wf( pub(crate) fn enforce_impl_lifetime_params_are_constrained( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, + of_trait: bool, ) -> Result<(), ErrorGuaranteed> { let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); @@ -83,7 +85,8 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); + let impl_trait_ref = + of_trait.then(|| tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity()); impl_trait_ref.error_reported()?; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 64a36e2d26813..e304ac28fb6df 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -93,7 +93,7 @@ pub(super) fn check_min_specialization( } fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Option { - let trait_ref = tcx.impl_trait_ref(impl1_def_id)?; + let trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap(); let trait_def = tcx.trait_def(trait_ref.skip_binder().def_id); let impl2_node = trait_def.ancestors(tcx, impl1_def_id.to_def_id()).ok()?.nth(1)?; diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index b23e7ae8e77bc..f7a0a55d5880d 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -18,8 +18,8 @@ use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, }; use rustc_middle::ty::{ - self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, - TypeVisitableExt, UserArgs, + self, AssocContainer, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, + TypeFoldable, TypeVisitableExt, UserArgs, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Span}; @@ -272,7 +272,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { probe::InherentImplPick => { let impl_def_id = pick.item.container_id(self.tcx); assert!( - self.tcx.impl_trait_ref(impl_def_id).is_none(), + matches!(pick.item.container, AssocContainer::InherentImpl), "impl {impl_def_id:?} is not an inherent impl" ); self.fresh_args_for_item(self.span, impl_def_id) diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 4e38d969192f4..691cb43b724a4 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -271,9 +271,7 @@ pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] { pub(super) fn trait_impls_in_crate_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] { let mut trait_impls = Vec::new(); for id in tcx.hir_free_items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) - && tcx.impl_trait_ref(id.owner_id).is_some() - { + if tcx.def_kind(id.owner_id) == (DefKind::Impl { of_trait: true }) { trait_impls.push(id.owner_id.to_def_id()) } } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 543f6a3ccf794..8f3c2b7ce97f0 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -42,12 +42,14 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' )); tcx.arena.alloc_slice(&assumed_wf_types) } - DefKind::Impl { .. } => { + DefKind::Impl { of_trait } => { // Trait arguments and the self type for trait impls or only the self type for // inherent impls. - let tys = match tcx.impl_trait_ref(def_id) { - Some(trait_ref) => trait_ref.skip_binder().args.types().collect(), - None => vec![tcx.type_of(def_id).instantiate_identity()], + let tys = if of_trait { + let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + trait_ref.skip_binder().args.types().collect() + } else { + vec![tcx.type_of(def_id).instantiate_identity()] }; let mut impl_spans = impl_spans(tcx, def_id); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index eb3236d30065c..529a4af591b29 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -62,24 +62,6 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { self.span = old; } - fn parent_impl_trait_ref(&self) -> Option> { - let parent = self.parent()?; - if matches!(self.tcx.def_kind(parent), DefKind::Impl { .. }) { - Some(self.tcx.impl_trait_ref(parent)?.instantiate_identity()) - } else { - None - } - } - - fn parent(&self) -> Option { - match self.tcx.def_kind(self.item) { - DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { - Some(self.tcx.local_parent(self.item)) - } - _ => None, - } - } - #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { let body = self.tcx.hir_body_owned_by(self.item).value; @@ -236,13 +218,13 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // This avoids having to do normalization of `Self::AssocTy` by only // supporting the case of a method defining opaque types from assoc types // in the same impl block. - if let Some(impl_trait_ref) = self.parent_impl_trait_ref() { + if let Some(parent) = self.tcx.trait_impl_of_assoc(self.item.to_def_id()) { + let impl_trait_ref = + self.tcx.impl_trait_ref(parent).unwrap().instantiate_identity(); // If the trait ref of the associated item and the impl differs, // then we can't use the impl's identity args below, so // just skip. if alias_ty.trait_ref(self.tcx) == impl_trait_ref { - let parent = self.parent().expect("we should have a parent here"); - for &assoc in self.tcx.associated_items(parent).in_definition_order() { trace!(?assoc); if assoc.expect_trait_impl() != Ok(alias_ty.def_id) { From ae8ff943c15d2095816282a50caeeec49511949b Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 13 Oct 2025 12:55:24 -0500 Subject: [PATCH 6/9] Remove some impl_opt_trait_header usages --- compiler/rustc_privacy/src/lib.rs | 41 +++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c9dbb204f61f7..11e6be687ec0e 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -344,13 +344,14 @@ trait VisibilityLike: Sized { // associated types for which we can't determine visibility precisely. fn of_impl( def_id: LocalDefId, + of_trait: bool, tcx: TyCtxt<'_>, effective_visibilities: &EffectiveVisibilities, ) -> Self { let mut find = FindMin::<_, SHALLOW> { tcx, effective_visibilities, min: Self::MAX }; find.visit(tcx.type_of(def_id).instantiate_identity()); - if let Some(trait_ref) = tcx.impl_trait_ref(def_id) { - find.visit_trait(trait_ref.instantiate_identity()); + if of_trait { + find.visit_trait(tcx.impl_trait_ref(def_id).unwrap().instantiate_identity()); } find.min } @@ -699,13 +700,20 @@ impl<'tcx> EmbargoVisitor<'tcx> { // its trait if it exists (which require reaching the `DefId`s in them). let item_ev = EffectiveVisibility::of_impl::( owner_id.def_id, + of_trait, self.tcx, &self.effective_visibilities, ); self.update_eff_vis(owner_id.def_id, item_ev, None, Level::Direct); - self.reach(owner_id.def_id, item_ev).generics().predicates().ty().trait_ref(); + { + let mut reach = self.reach(owner_id.def_id, item_ev); + reach.generics().predicates().ty(); + if of_trait { + reach.trait_ref(); + } + } for assoc_item in self.tcx.associated_items(owner_id).in_definition_order() { if assoc_item.is_impl_trait_in_trait() { @@ -820,9 +828,9 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { } fn trait_ref(&mut self) -> &mut Self { - if let Some(trait_ref) = self.ev.tcx.impl_trait_ref(self.item_def_id) { - self.visit_trait(trait_ref.instantiate_identity()); - } + self.visit_trait( + self.ev.tcx.impl_trait_ref(self.item_def_id).unwrap().instantiate_identity(), + ); self } } @@ -1395,9 +1403,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn trait_ref(&mut self) -> &mut Self { self.in_primary_interface = true; - if let Some(trait_ref) = self.tcx.impl_trait_ref(self.item_def_id) { - let _ = self.visit_trait(trait_ref.instantiate_identity()); - } + let _ = self + .visit_trait(self.tcx.impl_trait_ref(self.item_def_id).unwrap().instantiate_identity()); self } @@ -1666,7 +1673,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. DefKind::Impl { of_trait } => { - let impl_vis = ty::Visibility::of_impl::(def_id, tcx, &Default::default()); + let impl_vis = + ty::Visibility::of_impl::(def_id, of_trait, tcx, &Default::default()); // We are using the non-shallow version here, unlike when building the // effective visisibilities table to avoid large number of false positives. @@ -1679,8 +1687,12 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { // lints shouldn't be emitted even if `from` effective visibility // is larger than `Priv` nominal visibility and if `Priv` can leak // in some scenarios due to type inference. - let impl_ev = - EffectiveVisibility::of_impl::(def_id, tcx, self.effective_visibilities); + let impl_ev = EffectiveVisibility::of_impl::( + def_id, + of_trait, + tcx, + self.effective_visibilities, + ); let mut check = self.check(def_id, impl_vis, Some(impl_ev)); @@ -1694,7 +1706,10 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { // normalization they produce very ridiculous false positives. // FIXME: Remove this when full normalization is implemented. check.skip_assoc_tys = true; - check.ty().trait_ref(); + check.ty(); + if of_trait { + check.trait_ref(); + } for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() { if assoc_item.is_impl_trait_in_trait() { From e60e9f08264bdc69bf6029016fe8a93dc99d36cc Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 13 Oct 2025 12:56:21 -0500 Subject: [PATCH 7/9] Split impl_(opt_)trait_ref --- .../src/check/always_applicable.rs | 3 +- .../rustc_hir_analysis/src/check/check.rs | 4 +-- .../src/check/compare_impl_item.rs | 5 ++- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/coherence/builtin.rs | 4 +-- .../src/coherence/orphan.rs | 4 +-- .../rustc_hir_analysis/src/collect/dump.rs | 2 +- .../src/collect/predicates_of.rs | 16 ++++------ .../src/hir_ty_lowering/mod.rs | 5 +-- .../rustc_hir_analysis/src/impl_wf_check.rs | 6 ++-- .../src/impl_wf_check/min_specialization.rs | 8 ++--- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 8 ++--- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 32 ++++++++++++++----- compiler/rustc_middle/src/ty/print/mod.rs | 2 +- .../src/check_call_recursion.rs | 2 +- compiler/rustc_passes/src/dead.rs | 11 +++---- compiler/rustc_privacy/src/lib.rs | 11 +++---- .../rustc_public_bridge/src/context/impls.rs | 2 +- .../cfi/typeid/itanium_cxx_abi/transform.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- .../src/error_reporting/infer/region.rs | 2 +- .../src/error_reporting/traits/ambiguity.rs | 3 +- .../src/error_reporting/traits/mod.rs | 2 +- .../traits/on_unimplemented.rs | 3 +- .../src/traits/coherence.rs | 7 ++-- .../rustc_trait_selection/src/traits/mod.rs | 5 +-- .../src/traits/specialize/mod.rs | 14 ++------ .../traits/specialize/specialization_graph.rs | 10 +++--- compiler/rustc_ty_utils/src/implied_bounds.rs | 4 +-- compiler/rustc_ty_utils/src/opaque_types.rs | 3 +- compiler/rustc_ty_utils/src/sig_types.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/html/render/mod.rs | 2 +- .../passes/collect_intra_doc_links.rs | 2 +- 41 files changed, 95 insertions(+), 111 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index f4130e1d8f908..f39d1b7af345a 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -210,8 +210,7 @@ fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>( ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args); let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id()); - let fresh_adt_ty = - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty(); + let fresh_adt_ty = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_impl_args).self_ty(); ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty) .expect("equating fully generic trait ref should never fail"); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4c910d25c30a8..c59ed39ae211e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1191,9 +1191,7 @@ fn check_impl_items_against_trait<'tcx>( tcx, ty_impl_item, ty_trait_item, - tcx.impl_trait_ref(ty_impl_item.container_id(tcx)) - .unwrap() - .instantiate_identity(), + tcx.impl_trait_ref(ty_impl_item.container_id(tcx)).instantiate_identity(), ); } ty::AssocKind::Const { .. } => {} 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 5b504cc246d85..936b02cac5bb2 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -38,8 +38,7 @@ pub(super) fn compare_impl_item( ) -> Result<(), ErrorGuaranteed> { let impl_item = tcx.associated_item(impl_item_def_id); let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?); - let impl_trait_ref = - tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity(); + let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).instantiate_identity(); debug!(?impl_trait_ref); match impl_item.kind { @@ -443,7 +442,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let impl_m = tcx.associated_item(impl_m_def_id.to_def_id()); let trait_m = tcx.associated_item(impl_m.expect_trait_impl()?); let impl_trait_ref = - tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).unwrap().instantiate_identity(); + tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).instantiate_identity(); // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during instantiation later. check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 0166c3b980de3..f1c84a14de306 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -244,7 +244,7 @@ fn missing_items_err( let snippet = with_types_for_signature!(suggestion_signature( tcx, trait_item, - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(), + tcx.impl_trait_ref(impl_def_id).instantiate_identity(), )); let code = format!("{padding}{snippet}\n{padding}"); if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 55b1520fda06b..5649a6e9a3d80 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1258,7 +1258,7 @@ fn check_impl<'tcx>( // `#[rustc_reservation_impl]` impls are not real impls and // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). - let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity(); + let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity(); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. tcx.ensure_ok().coherent_trait(trait_ref.def_id)?; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b7a74ac445bfc..6dee1675b6dee 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -377,7 +377,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span); let source = tcx.type_of(impl_did).instantiate_identity(); - let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity(); + let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity(); assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.args.type_at(1); @@ -707,7 +707,7 @@ fn visit_implementation_of_coerce_pointee_validity( checker: &Checker<'_>, ) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; - let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty(); + let self_ty = tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().self_ty(); let span = tcx.def_span(checker.impl_def_id); if !tcx.is_builtin_derived(checker.impl_def_id.into()) { return Err(tcx.dcx().emit_err(errors::CoercePointeeNoUserValidityAssertion { span })); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index c4aeb4c85bb9e..27682d0cc95b8 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -22,7 +22,7 @@ pub(crate) fn orphan_check_impl( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); + let trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); trait_ref.error_reported()?; match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) { @@ -294,7 +294,7 @@ fn orphan_check<'tcx>( ) -> Result<(), OrphanCheckErr, FxIndexSet>> { // We only accept this routine to be invoked on implementations // of a trait, not inherent implementations. - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(impl_def_id); debug!(trait_ref = ?trait_ref.skip_binder()); // If the *trait* is local to the crate, ok. diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 44cc2dec1cb52..b167f31a246c6 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -108,7 +108,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { let vtable_entries = match tcx.hir_item(id).kind { hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => { - let trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate_identity(); + let trait_ref = tcx.impl_trait_ref(def_id).instantiate_identity(); if trait_ref.has_non_region_param() { tcx.dcx().span_err( attr.span(), diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index c6afa9f6897a4..e66accc7dcffd 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -118,8 +118,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let impl_def_id = tcx.parent(fn_def_id); - let impl_trait_ref_args = - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args; + let impl_trait_ref_args = tcx.impl_trait_ref(impl_def_id).instantiate_identity().args; let impl_assoc_args = impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args); @@ -162,9 +161,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen if let Some(of_trait) = impl_.of_trait && of_trait.defaultness.is_default() { - is_default_impl_trait = tcx - .impl_trait_ref(def_id) - .map(|t| ty::Binder::dummy(t.instantiate_identity())); + is_default_impl_trait = + Some(ty::Binder::dummy(tcx.impl_trait_ref(def_id).instantiate_identity())); } } ItemKind::Trait(_, _, _, _, _, self_bounds, ..) @@ -352,10 +350,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // for details. if let Node::Item(&Item { kind: ItemKind::Impl(impl_), .. }) = node { let self_ty = tcx.type_of(def_id).instantiate_identity(); - let trait_ref = impl_ - .of_trait - .is_some() - .then(|| tcx.impl_trait_ref(def_id).unwrap().instantiate_identity()); + let trait_ref = + impl_.of_trait.is_some().then(|| tcx.impl_trait_ref(def_id).instantiate_identity()); cgp::setup_constraining_predicates( tcx, &mut predicates, @@ -467,7 +463,7 @@ fn const_evaluatable_predicates_of<'tcx>( { if impl_.of_trait.is_some() { debug!("visit impl trait_ref"); - let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(def_id); trait_ref.instantiate_identity().visit_with(&mut collector); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index eb660804c2b52..e218bbf69f015 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1387,10 +1387,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => { // `Self` in an impl of a trait -- we have a concrete self type and a // trait reference. - let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { - // A cycle error occurred, most likely. - self.dcx().span_bug(span, "expected cycle error"); - }; + let trait_ref = tcx.impl_trait_ref(impl_def_id); self.probe_single_bound_for_assoc_item( || { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 5955107cf2d39..3dede69ce1063 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -85,8 +85,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); - let impl_trait_ref = - of_trait.then(|| tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity()); + let impl_trait_ref = of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate_identity()); impl_trait_ref.error_reported()?; @@ -174,7 +173,8 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); + let impl_trait_ref = + tcx.impl_opt_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); impl_trait_ref.error_reported()?; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index e304ac28fb6df..41af59388f798 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -93,7 +93,7 @@ pub(super) fn check_min_specialization( } fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Option { - let trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(impl1_def_id); let trait_def = tcx.trait_def(trait_ref.skip_binder().def_id); let impl2_node = trait_def.ancestors(tcx, impl1_def_id.to_def_id()).ok()?.nth(1)?; @@ -215,7 +215,7 @@ fn unconstrained_parent_impl_args<'tcx>( let impl_generic_predicates = tcx.predicates_of(impl_def_id); let mut unconstrained_parameters = FxHashSet::default(); let mut constrained_params = FxHashSet::default(); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); // Unfortunately the functions in `constrained_generic_parameters` don't do // what we want here. We want only a list of constrained parameters while @@ -224,7 +224,7 @@ fn unconstrained_parent_impl_args<'tcx>( for (clause, _) in impl_generic_predicates.predicates.iter() { if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() { let unbound_trait_ref = proj.projection_term.trait_ref(tcx); - if Some(unbound_trait_ref) == impl_trait_ref { + if unbound_trait_ref == impl_trait_ref { continue; } @@ -373,7 +373,7 @@ fn check_predicates<'tcx>( .map(|(c, _span)| c.as_predicate()); // Include the well-formed predicates of the type parameters of the impl. - for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().instantiate_identity().args { + for arg in tcx.impl_trait_ref(impl1_def_id).instantiate_identity().args { let Some(term) = arg.as_term() else { continue; }; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index c1dbf904c6fa0..2605aa18b91ee 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3629,7 +3629,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ocx = ObligationCtxt::new_with_diagnostics(self); let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id); let impl_trait_ref = - self.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(self.tcx, impl_args); + self.tcx.impl_trait_ref(impl_def_id).instantiate(self.tcx, impl_args); let cause = self.misc(base_expr.span); // Match the impl self type against the base ty. If this fails, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index ed88e32a2736c..f478cab740e4b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -711,7 +711,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } else { self.tcx - .impl_trait_ref(obligation.impl_or_alias_def_id) + .impl_opt_trait_ref(obligation.impl_or_alias_def_id) .map(|impl_def| impl_def.skip_binder()) // It is possible that this is absent. In this case, we make no progress. .ok_or(expr)? diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index a615ac9d912dd..99a9566c74cef 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -285,7 +285,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti && let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container { let impl_def_id = item.container_id(tcx); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( tcx, impl_def_id, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 02f8e27ab1947..3f549bc6a372f 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1962,8 +1962,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Provide the best span we can. Use the item, if local to crate, else // the impl, if local to crate (item may be defaulted), else nothing. let Some(item) = self.associated_value(impl_did, item_name).or_else(|| { - let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?; - self.associated_value(impl_trait_ref.skip_binder().def_id, item_name) + let impl_trait_id = self.tcx.impl_opt_trait_id(impl_did)?; + self.associated_value(impl_trait_id, item_name) }) else { continue; }; @@ -1978,7 +1978,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let impl_ty = self.tcx.at(span).type_of(impl_did).instantiate_identity(); - let insertion = match self.tcx.impl_trait_ref(impl_did) { + let insertion = match self.tcx.impl_opt_trait_ref(impl_did) { None => String::new(), Some(trait_ref) => { format!( @@ -2013,7 +2013,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note(note_str); } if let Some(sugg_span) = sugg_span - && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) + && let Some(trait_ref) = self.tcx.impl_opt_trait_ref(impl_did) && let Some(sugg) = print_disambiguation_help( self.tcx, err, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bf99aa76a0d64..29f6281798bd3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -679,7 +679,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { - self.impl_trait_ref(impl_def_id).unwrap() + self.impl_trait_ref(impl_def_id) } fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 43507cf44de17..dd8c51f2af81b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1937,6 +1937,14 @@ impl<'tcx> TyCtxt<'tcx> { } } + pub fn impl_is_of_trait(self, def_id: impl IntoQueryParam) -> bool { + let def_id = def_id.into_query_param(); + let DefKind::Impl { of_trait } = self.def_kind(def_id) else { + panic!("expected Impl for {def_id:?}"); + }; + of_trait + } + /// If the given `DefId` is an associated item of an impl, /// returns the `DefId` of the impl; otherwise returns `None`. pub fn impl_of_assoc(self, def_id: DefId) -> Option { @@ -1969,24 +1977,32 @@ impl<'tcx> TyCtxt<'tcx> { } /// Given an `impl_id`, return the trait it implements. - /// Return `None` if this is an inherent impl. pub fn impl_trait_ref( self, def_id: impl IntoQueryParam, + ) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { + self.impl_opt_trait_ref(def_id).unwrap() + } + + /// Given an `impl_id`, return the trait it implements. + /// Returns `None` if it is an inherent impl. + pub fn impl_opt_trait_ref( + self, + def_id: impl IntoQueryParam, ) -> Option>> { - Some(self.impl_trait_header(def_id)?.trait_ref) + self.impl_trait_header(def_id).map(|header| header.trait_ref) } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. - pub fn impl_trait_id(self, def_id: DefId) -> DefId { - self.impl_opt_trait_id(def_id) - .unwrap_or_else(|| panic!("expected impl of trait for {def_id:?}")) + pub fn impl_trait_id(self, def_id: impl IntoQueryParam) -> DefId { + self.impl_trait_ref(def_id).skip_binder().def_id } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. - /// If it implements no trait, returns `None`. - pub fn impl_opt_trait_id(self, def_id: DefId) -> Option { - self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id) + /// Returns `None` if it is an inherent impl. + pub fn impl_opt_trait_id(self, def_id: impl IntoQueryParam) -> Option { + let def_id = def_id.into_query_param(); + self.impl_is_of_trait(def_id).then(|| self.impl_trait_id(def_id)) } pub fn is_exportable(self, def_id: DefId) -> bool { diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index d636e8ef31ff5..0fd68e74e0441 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -45,7 +45,7 @@ pub trait Printer<'tcx>: Sized { ) -> Result<(), PrintError> { let tcx = self.tcx(); let self_ty = tcx.type_of(impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); + let impl_trait_ref = tcx.impl_opt_trait_ref(impl_def_id); let (self_ty, impl_trait_ref) = if tcx.generics_of(impl_def_id).count() <= args.len() { ( self_ty.instantiate(tcx, args), diff --git a/compiler/rustc_mir_transform/src/check_call_recursion.rs b/compiler/rustc_mir_transform/src/check_call_recursion.rs index a9acb1da5a3e0..cac6308617acf 100644 --- a/compiler/rustc_mir_transform/src/check_call_recursion.rs +++ b/compiler/rustc_mir_transform/src/check_call_recursion.rs @@ -44,7 +44,7 @@ impl<'tcx> MirLint<'tcx> for CheckDropRecursion { // First check if `body` is an `fn drop()` of `Drop` if let DefKind::AssocFn = tcx.def_kind(def_id) && let Some(impl_id) = tcx.trait_impl_of_assoc(def_id.to_def_id()) - && let trait_ref = tcx.impl_trait_ref(impl_id).unwrap() + && let trait_ref = tcx.impl_trait_ref(impl_id) && tcx.is_lang_item(trait_ref.instantiate_identity().def_id, LangItem::Drop) // avoid erroneous `Drop` impls from causing ICEs below && let sig = tcx.fn_sig(def_id).instantiate_identity() diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 3c2c9683a4d19..49dd21f537cff 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -377,7 +377,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id()) && self.tcx.is_automatically_derived(impl_of) - && let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity() + && let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity() && self.tcx.has_attr(trait_ref.def_id, sym::rustc_trivial_field_reads) { if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() @@ -486,12 +486,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { (self.tcx.local_parent(local_def_id), trait_item_id) } // impl items are live if the corresponding traits are live - DefKind::Impl { of_trait: true } => ( - local_def_id, - self.tcx - .impl_trait_ref(local_def_id) - .and_then(|trait_ref| trait_ref.skip_binder().def_id.as_local()), - ), + DefKind::Impl { of_trait: true } => { + (local_def_id, self.tcx.impl_trait_id(local_def_id).as_local()) + } _ => bug!(), }; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 11e6be687ec0e..85646b575bff6 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -351,7 +351,7 @@ trait VisibilityLike: Sized { let mut find = FindMin::<_, SHALLOW> { tcx, effective_visibilities, min: Self::MAX }; find.visit(tcx.type_of(def_id).instantiate_identity()); if of_trait { - find.visit_trait(tcx.impl_trait_ref(def_id).unwrap().instantiate_identity()); + find.visit_trait(tcx.impl_trait_ref(def_id).instantiate_identity()); } find.min } @@ -828,9 +828,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { } fn trait_ref(&mut self) -> &mut Self { - self.visit_trait( - self.ev.tcx.impl_trait_ref(self.item_def_id).unwrap().instantiate_identity(), - ); + self.visit_trait(self.ev.tcx.impl_trait_ref(self.item_def_id).instantiate_identity()); self } } @@ -1403,8 +1401,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn trait_ref(&mut self) -> &mut Self { self.in_primary_interface = true; - let _ = self - .visit_trait(self.tcx.impl_trait_ref(self.item_def_id).unwrap().instantiate_identity()); + let _ = self.visit_trait(self.tcx.impl_trait_ref(self.item_def_id).instantiate_identity()); self } @@ -1778,7 +1775,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { } if let DefKind::Impl { of_trait: true } = tcx.def_kind(def_id) { - let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(def_id); let trait_ref = trait_ref.instantiate_identity(); visitor.span = tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().trait_ref.path.span; diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index 9b3948d232d78..d9fa65431f5c6 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -189,7 +189,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { } pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder<'tcx, TraitRef<'tcx>> { - self.tcx.impl_trait_ref(impl_def).unwrap() + self.tcx.impl_trait_ref(impl_def) } pub fn generics_of(&self, def_id: DefId) -> &'tcx ty::Generics { diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 7395bcfa201e1..021b206e1e2ef 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -470,7 +470,7 @@ fn implemented_method<'tcx>( let assoc = tcx.opt_associated_item(instance.def_id())?; let ancestor = if let AssocContainer::TraitImpl(Ok(trait_method_id)) = assoc.container { let impl_id = tcx.parent(instance.def_id()); - trait_ref = tcx.impl_trait_ref(impl_id).unwrap(); + trait_ref = tcx.impl_trait_ref(impl_id); method_id = trait_method_id; trait_method = tcx.associated_item(method_id); trait_id = trait_ref.skip_binder().def_id; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 95a7ec61868d9..ee2621af84280 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -403,7 +403,7 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> { args: &'tcx [GenericArg<'tcx>], ) -> Result<(), PrintError> { let self_ty = self.tcx.type_of(impl_def_id); - let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); + let impl_trait_ref = self.tcx.impl_opt_trait_ref(impl_def_id); let generics = self.tcx.generics_of(impl_def_id); // We have two cases to worry about here: // 1. We're printing a nested item inside of an impl item, like an inner diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index aeac40a65bdfc..d5bc831b650aa 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -311,7 +311,7 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id }; let self_ty = self.tcx.type_of(impl_def_id); - let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); + let impl_trait_ref = self.tcx.impl_opt_trait_ref(impl_def_id); let generics = self.tcx.generics_of(impl_def_id); // We have two cases to worry about here: // 1. We're printing a nested item inside of an impl item, like an inner diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 9a8ccea3aca87..0765434d3c435 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -574,7 +574,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(impl_item_def_id.to_def_id()) else { return; }; - let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = self.tcx.impl_trait_ref(impl_def_id); let trait_args = trait_ref .instantiate_identity() // Replace the explicit self type with `Self` for better suggestion rendering diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index edb002c69e760..a0cc6091866d8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -47,8 +47,7 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( ); let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args); let impl_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 9052031ce4fd8..ded5969e83c5c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -354,7 +354,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { use std::fmt::Write; - let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); + let trait_ref = tcx.impl_opt_trait_ref(impl_def_id)?.instantiate_identity(); let mut w = "impl".to_owned(); #[derive(Debug, Default)] diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index b7d470df0cf44..a5cb374ea0eb1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -44,8 +44,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.tcx.for_each_relevant_impl(trait_pred.def_id(), trait_self_ty, |def_id| { let impl_args = self.fresh_args_for_item(obligation.cause.span, def_id); - let impl_trait_ref = - tcx.impl_trait_ref(def_id).unwrap().instantiate(tcx, impl_args); + let impl_trait_ref = tcx.impl_trait_ref(def_id).instantiate(tcx, impl_args); let impl_self_ty = impl_trait_ref.self_ty(); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 22ef214082c47..e488fb6802f84 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -137,8 +137,8 @@ pub fn overlapping_trait_impls( // Before doing expensive operations like entering an inference context, do // a quick check via fast_reject to tell if the impl headers could possibly // unify. - let impl1_args = tcx.impl_trait_ref(impl1_def_id).unwrap().skip_binder().args; - let impl2_args = tcx.impl_trait_ref(impl2_def_id).unwrap().skip_binder().args; + let impl1_args = tcx.impl_trait_ref(impl1_def_id).skip_binder().args; + let impl2_args = tcx.impl_trait_ref(impl2_def_id).skip_binder().args; let may_overlap = DeepRejectCtxt::relate_infer_infer(tcx).args_may_unify(impl1_args, impl2_args); @@ -209,8 +209,7 @@ fn fresh_impl_header<'tcx>( impl_def_id, impl_args, self_ty: tcx.type_of(impl_def_id).instantiate(tcx, impl_args), - trait_ref: is_of_trait - .then(|| tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args)), + trait_ref: is_of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args)), predicates: tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_args) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 3d27756e3e5ff..0f3b38ef66751 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -835,10 +835,7 @@ fn is_impossible_associated_item( let param_env = ty::ParamEnv::empty(); let fresh_args = infcx.fresh_args_for_item(tcx.def_span(impl_def_id), impl_def_id); - let impl_trait_ref = tcx - .impl_trait_ref(impl_def_id) - .expect("expected impl to correspond to trait") - .instantiate(tcx, fresh_args); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_args); let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index ab01d0707e0f1..a00680b471346 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -117,7 +117,7 @@ pub fn translate_args_with_cause<'tcx>( param_env, source_impl, source_args, target_node ); let source_trait_ref = - infcx.tcx.impl_trait_ref(source_impl).unwrap().instantiate(infcx.tcx, source_args); + infcx.tcx.impl_trait_ref(source_impl).instantiate(infcx.tcx, source_args); // translate the Self and Param parts of the generic parameters, since those // vary across impls @@ -176,11 +176,7 @@ fn fulfill_implication<'tcx>( let target_trait_ref = ocx.normalize( cause, param_env, - infcx - .tcx - .impl_trait_ref(target_impl) - .expect("expected source impl to be a trait impl") - .instantiate(infcx.tcx, target_args), + infcx.tcx.impl_trait_ref(target_impl).instantiate(infcx.tcx, target_args), ); // do the impls unify? If not, no specialization. @@ -307,11 +303,7 @@ pub(super) fn specializes( let parent_impl_trait_ref = ocx.normalize( cause, param_env, - infcx - .tcx - .impl_trait_ref(parent_impl_def_id) - .expect("expected source impl to be a trait impl") - .instantiate(infcx.tcx, parent_args), + infcx.tcx.impl_trait_ref(parent_impl_def_id).instantiate(infcx.tcx, parent_args), ); // do the impls unify? If not, no specialization. diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index f80731fdf93a7..02db81d7a7590 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -38,7 +38,7 @@ enum Inserted<'tcx> { impl<'tcx> Children { /// Insert an impl into this set of children without comparing to any existing impls. fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) { - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder(); + let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder(); if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer) { @@ -54,7 +54,7 @@ impl<'tcx> Children { /// an impl with a parent. The impl must be present in the list of /// children already. fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) { - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder(); + let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder(); let vec: &mut Vec; if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer) @@ -164,7 +164,7 @@ impl<'tcx> Children { if le && !ge { debug!( "descending as child of TraitRef {:?}", - tcx.impl_trait_ref(possible_sibling).unwrap().instantiate_identity() + tcx.impl_trait_ref(possible_sibling).instantiate_identity() ); // The impl specializes `possible_sibling`. @@ -172,7 +172,7 @@ impl<'tcx> Children { } else if ge && !le { debug!( "placing as parent of TraitRef {:?}", - tcx.impl_trait_ref(possible_sibling).unwrap().instantiate_identity() + tcx.impl_trait_ref(possible_sibling).instantiate_identity() ); replace_children.push(possible_sibling); @@ -242,7 +242,7 @@ impl<'tcx> Graph { assert!(impl_def_id.is_local()); // FIXME: use `EarlyBinder` in `self.children` - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder(); + let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder(); let trait_def_id = trait_ref.def_id; debug!( diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 8f3c2b7ce97f0..990120db9726b 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -46,7 +46,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' // Trait arguments and the self type for trait impls or only the self type for // inherent impls. let tys = if of_trait { - let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(def_id); trait_ref.skip_binder().args.types().collect() } else { vec![tcx.type_of(def_id).instantiate_identity()] @@ -113,7 +113,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( tcx, impl_def_id.to_def_id(), - tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity().args, + tcx.impl_trait_ref(impl_def_id).instantiate_identity().args, ); tcx.arena.alloc_from_iter( ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id)) diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 529a4af591b29..4dd45a09a4df3 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -219,8 +219,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // supporting the case of a method defining opaque types from assoc types // in the same impl block. if let Some(parent) = self.tcx.trait_impl_of_assoc(self.item.to_def_id()) { - let impl_trait_ref = - self.tcx.impl_trait_ref(parent).unwrap().instantiate_identity(); + let impl_trait_ref = self.tcx.impl_trait_ref(parent).instantiate_identity(); // If the trait ref of the associated item and the impl differs, // then we can't use the impl's identity args below, so // just skip. diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index d95660810e5ff..07f379d3f9a8f 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -88,7 +88,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( DefKind::Impl { of_trait } => { if of_trait { let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().trait_ref.path.span; - let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..]; + let args = &tcx.impl_trait_ref(item).instantiate_identity().args[1..]; try_visit!(visitor.visit(span, args)); } let span = match tcx.hir_node_by_def_id(item).ty() { diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 100e07fc7bd83..ddfce7aeb92da 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -34,7 +34,7 @@ pub(crate) fn synthesize_blanket_impls( 'blanket_impls: for &impl_def_id in trait_impls.blanket_impls() { trace!("considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`"); - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(impl_def_id); if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) { continue; } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 971c7f62bb6dc..1cd4b880abe79 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -448,7 +448,7 @@ pub(crate) fn build_impl( let tcx = cx.tcx; let _prof_timer = tcx.sess.prof.generic_activity("build_impl"); - let associated_trait = tcx.impl_trait_ref(did).map(ty::EarlyBinder::skip_binder); + let associated_trait = tcx.impl_opt_trait_ref(did).map(ty::EarlyBinder::skip_binder); // Do not inline compiler-internal items unless we're a compiler-internal crate. let is_compiler_internal = |did| { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index c3b1e3eb6c087..13178ee4e9934 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2403,7 +2403,7 @@ fn get_id_for_impl(tcx: TyCtxt<'_>, impl_id: ItemId) -> String { (ty, Some(ty::TraitRef::new(tcx, trait_, [ty]))) } ItemId::Blanket { impl_id, .. } | ItemId::DefId(impl_id) => { - if let Some(trait_ref) = tcx.impl_trait_ref(impl_id) { + if let Some(trait_ref) = tcx.impl_opt_trait_ref(impl_id) { let trait_ref = trait_ref.skip_binder(); (trait_ref.self_ty(), Some(trait_ref)) } else { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 155abef616942..d09949e6868d6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -847,7 +847,7 @@ fn trait_impls_for<'a>( for &trait_ in tcx.doc_link_traits_in_scope(module) { tcx.for_each_relevant_impl(trait_, ty, |impl_| { - let trait_ref = tcx.impl_trait_ref(impl_).expect("this is not an inherent impl"); + let trait_ref = tcx.impl_trait_ref(impl_); // Check if these are the same type. let impl_type = trait_ref.skip_binder().self_ty(); trace!( From b323f567d9ecb34090f8f16815bad1a122244501 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 22 Jul 2025 17:05:45 -0500 Subject: [PATCH 8/9] Remove Option from impl_trait_header --- .../src/const_eval/fn_queries.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 4 +-- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../rustc_hir_analysis/src/coherence/mod.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 28 +++++++++---------- .../src/collect/item_bounds.rs | 20 ++++++------- compiler/rustc_hir_analysis/src/delegation.rs | 3 +- .../src/hir_ty_lowering/errors.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 6 +--- compiler/rustc_metadata/src/rmeta/encoder.rs | 3 +- compiler/rustc_middle/src/query/erase.rs | 4 +-- compiler/rustc_middle/src/query/mod.rs | 3 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 13 +++++---- compiler/rustc_monomorphize/src/collector.rs | 6 ++-- .../src/error_reporting/traits/ambiguity.rs | 2 +- .../traits/fulfillment_errors.rs | 4 +-- .../src/traits/effects.rs | 4 +-- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/mod.rs | 2 +- .../src/traits/specialize/mod.rs | 2 +- src/librustdoc/clean/inline.rs | 6 +++- src/librustdoc/clean/mod.rs | 6 +++- 24 files changed, 63 insertions(+), 67 deletions(-) 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 35c3e3ed3150e..530d8d4b1fa62 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::TyCtxt; fn parent_impl_or_trait_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { let parent_id = tcx.local_parent(def_id); match tcx.def_kind(parent_id) { - DefKind::Impl { of_trait: true } => tcx.impl_trait_header(parent_id).unwrap().constness, + DefKind::Impl { of_trait: true } => tcx.impl_trait_header(parent_id).constness, DefKind::Trait => { if tcx.is_const_trait(parent_id.into()) { hir::Constness::Const diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index c59ed39ae211e..95b47c8aba671 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -806,10 +806,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), DefKind::Impl { of_trait } => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().impl_trait_header(def_id); tcx.ensure_ok().predicates_of(def_id); tcx.ensure_ok().associated_items(def_id); - if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { + if of_trait { + let impl_trait_header = tcx.impl_trait_header(def_id); res = res.and( tcx.ensure_ok() .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5649a6e9a3d80..f3d6398b20853 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -248,7 +248,7 @@ pub(super) fn check_item<'tcx>( crate::impl_wf_check::check_impl_wf(tcx, def_id, impl_.of_trait.is_some())?; let mut res = Ok(()); if let Some(of_trait) = impl_.of_trait { - let header = tcx.impl_trait_header(def_id).unwrap(); + let header = tcx.impl_trait_header(def_id); let is_auto = tcx.trait_is_auto(header.trait_ref.skip_binder().def_id); if let (hir::Defaultness::Default { .. }, true) = (of_trait.defaultness, is_auto) { let sp = of_trait.trait_ref.path.span; diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index fbb442440beae..bc3231cff9b47 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -163,7 +163,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let mut res = tcx.ensure_ok().specialization_graph_of(def_id); for &impl_def_id in impls { - let impl_header = tcx.impl_trait_header(impl_def_id).unwrap(); + let impl_header = tcx.impl_trait_header(impl_def_id); let trait_ref = impl_header.trait_ref.instantiate_identity(); let trait_def = tcx.trait_def(trait_ref.def_id); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b6a662f425602..89ab710ff8218 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1291,28 +1291,26 @@ pub fn suggest_impl_trait<'tcx>( None } -fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option> { +fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader<'_> { let icx = ItemCtxt::new(tcx, def_id); let item = tcx.hir_expect_item(def_id); let impl_ = item.expect_impl(); + let of_trait = impl_ + .of_trait + .unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}")); + let selfty = tcx.type_of(def_id).instantiate_identity(); let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); - if is_rustc_reservation && impl_.of_trait.is_none() { - tcx.dcx().span_err(item.span, "reservation impls can't be inherent"); - } - impl_.of_trait.map(|of_trait| { - let selfty = tcx.type_of(def_id).instantiate_identity(); - check_impl_constness(tcx, of_trait.constness, &of_trait.trait_ref); + check_impl_constness(tcx, of_trait.constness, &of_trait.trait_ref); - let trait_ref = icx.lowerer().lower_impl_trait_ref(&of_trait.trait_ref, selfty); + let trait_ref = icx.lowerer().lower_impl_trait_ref(&of_trait.trait_ref, selfty); - ty::ImplTraitHeader { - trait_ref: ty::EarlyBinder::bind(trait_ref), - safety: of_trait.safety, - polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation), - constness: of_trait.constness, - } - }) + ty::ImplTraitHeader { + trait_ref: ty::EarlyBinder::bind(trait_ref), + safety: of_trait.safety, + polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation), + constness: of_trait.constness, + } } fn check_impl_constness( diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 129b26d8ff0ce..67284e1621568 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -514,17 +514,15 @@ pub(super) fn impl_super_outlives( tcx: TyCtxt<'_>, def_id: DefId, ) -> ty::EarlyBinder<'_, ty::Clauses<'_>> { - tcx.impl_trait_header(def_id).expect("expected an impl of trait").trait_ref.map_bound( - |trait_ref| { - let clause: ty::Clause<'_> = trait_ref.upcast(tcx); - tcx.mk_clauses_from_iter(util::elaborate(tcx, [clause]).filter(|clause| { - matches!( - clause.kind().skip_binder(), - ty::ClauseKind::TypeOutlives(_) | ty::ClauseKind::RegionOutlives(_) - ) - })) - }, - ) + tcx.impl_trait_header(def_id).trait_ref.map_bound(|trait_ref| { + let clause: ty::Clause<'_> = trait_ref.upcast(tcx); + tcx.mk_clauses_from_iter(util::elaborate(tcx, [clause]).filter(|clause| { + matches!( + clause.kind().skip_binder(), + ty::ClauseKind::TypeOutlives(_) | ty::ClauseKind::RegionOutlives(_) + ) + })) + }) } struct AssocTyToOpaque<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index f5821aed03f29..125fc21a5cc1c 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -272,8 +272,7 @@ fn create_generic_args<'tcx>( (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { let callee_generics = tcx.generics_of(sig_id); let parent = tcx.parent(def_id.into()); - let parent_args = - tcx.impl_trait_header(parent).unwrap().trait_ref.instantiate_identity().args; + let parent_args = tcx.impl_trait_header(parent).trait_ref.instantiate_identity().args; let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id); let method_args = tcx.mk_args(&trait_args[callee_generics.parent_count..]); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 165051744641f..25ba888e94607 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -473,7 +473,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } else { // Find all the types that have an `impl` for the trait. tcx.all_impls(trait_def_id) - .filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id)) + .map(|impl_def_id| tcx.impl_trait_header(impl_def_id)) .filter(|header| { // Consider only accessible traits tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index e218bbf69f015..4ff8f5d9e9c7e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1615,7 +1615,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .is_accessible_from(self.item_def_id(), tcx) && tcx.all_impls(*trait_def_id) .any(|impl_def_id| { - let header = tcx.impl_trait_header(impl_def_id).unwrap(); + let header = tcx.impl_trait_header(impl_def_id); let trait_ref = header.trait_ref.instantiate( tcx, infcx.fresh_args_for_item(DUMMY_SP, impl_def_id), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3f549bc6a372f..aacd2f511a3c3 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3980,11 +3980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self .tcx .all_impls(candidate.def_id) - .map(|imp_did| { - self.tcx.impl_trait_header(imp_did).expect( - "inherent impls can't be candidates, only trait impls can be", - ) - }) + .map(|imp_did| self.tcx.impl_trait_header(imp_did)) .filter(|header| header.polarity != ty::ImplPolarity::Positive) .any(|header| { let imp = header.trait_ref.instantiate_identity(); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index db66938457f09..e13ef7e70f447 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2115,7 +2115,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; let def_id = id.owner_id.to_def_id(); - if of_trait && let Some(header) = tcx.impl_trait_header(def_id) { + if of_trait { + let header = tcx.impl_trait_header(def_id); record!(self.tables.impl_trait_header[def_id] <- header); self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id)); diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index cad10fcfb0101..fd46a65f2bbe0 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -200,8 +200,8 @@ impl EraseType for Option> { type Result = [u8; size_of::>>()]; } -impl EraseType for Option> { - type Result = [u8; size_of::>>()]; +impl EraseType for ty::ImplTraitHeader<'_> { + type Result = [u8; size_of::>()]; } impl EraseType for Option>> { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 448c26ef31813..3c4a4d229a3d4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1104,8 +1104,7 @@ rustc_queries! { } /// Given an `impl_id`, return the trait it implements along with some header information. - /// Return `None` if this is an inherent impl. - query impl_trait_header(impl_id: DefId) -> Option> { + query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> { desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } cache_on_disk_if { impl_id.is_local() } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 29f6281798bd3..545235c46c62b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3472,7 +3472,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Whether the trait impl is marked const. This does not consider stability or feature gates. pub fn is_const_trait_impl(self, def_id: DefId) -> bool { self.def_kind(def_id) == DefKind::Impl { of_trait: true } - && self.impl_trait_header(def_id).unwrap().constness == hir::Constness::Const + && self.impl_trait_header(def_id).constness == hir::Constness::Const } pub fn is_sdylib_interface_build(self) -> bool { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index dd8c51f2af81b..5ca631f3d33f0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1614,8 +1614,8 @@ impl<'tcx> TyCtxt<'tcx> { def_id1: DefId, def_id2: DefId, ) -> Option { - let impl1 = self.impl_trait_header(def_id1).unwrap(); - let impl2 = self.impl_trait_header(def_id2).unwrap(); + let impl1 = self.impl_trait_header(def_id1); + let impl2 = self.impl_trait_header(def_id2); let trait_ref1 = impl1.trait_ref.skip_binder(); let trait_ref2 = impl2.trait_ref.skip_binder(); @@ -1973,7 +1973,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn impl_polarity(self, def_id: impl IntoQueryParam) -> ty::ImplPolarity { - self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity) + self.impl_trait_header(def_id).polarity } /// Given an `impl_id`, return the trait it implements. @@ -1981,7 +1981,7 @@ impl<'tcx> TyCtxt<'tcx> { self, def_id: impl IntoQueryParam, ) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { - self.impl_opt_trait_ref(def_id).unwrap() + self.impl_trait_header(def_id).trait_ref } /// Given an `impl_id`, return the trait it implements. @@ -1990,7 +1990,8 @@ impl<'tcx> TyCtxt<'tcx> { self, def_id: impl IntoQueryParam, ) -> Option>> { - self.impl_trait_header(def_id).map(|header| header.trait_ref) + let def_id = def_id.into_query_param(); + self.impl_is_of_trait(def_id).then(|| self.impl_trait_ref(def_id)) } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. @@ -2097,7 +2098,7 @@ impl<'tcx> TyCtxt<'tcx> { let def_id: DefId = def_id.into(); match self.def_kind(def_id) { DefKind::Impl { of_trait: true } => { - let header = self.impl_trait_header(def_id).unwrap(); + let header = self.impl_trait_header(def_id); header.constness == hir::Constness::Const && self.is_const_trait(header.trait_ref.skip_binder().def_id) } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2169ed3c254b8..93f647c05e02d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1568,7 +1568,7 @@ impl<'v> RootCollector<'_, 'v> { } } } - DefKind::Impl { .. } => { + DefKind::Impl { of_trait: true } => { if self.strategy == MonoItemCollectionStrategy::Eager { create_mono_items_for_default_impls(self.tcx, id, self.output); } @@ -1715,9 +1715,7 @@ fn create_mono_items_for_default_impls<'tcx>( item: hir::ItemId, output: &mut MonoItems<'tcx>, ) { - let Some(impl_) = tcx.impl_trait_header(item.owner_id) else { - return; - }; + let impl_ = tcx.impl_trait_header(item.owner_id); if matches!(impl_.polarity, ty::ImplPolarity::Negative) { return; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index a0cc6091866d8..eb72f71382ef9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -57,7 +57,7 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( return false; } - let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); + let impl_trait_header = tcx.impl_trait_header(impl_def_id); let impl_polarity = impl_trait_header.polarity; match (impl_polarity, predicate_polarity) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 4305d4160ebf5..373819d96f4a9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1867,7 +1867,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .tcx .all_impls(trait_pred.def_id()) .filter_map(|def_id| { - let imp = self.tcx.impl_trait_header(def_id).unwrap(); + let imp = self.tcx.impl_trait_header(def_id); if imp.polarity != ty::ImplPolarity::Positive || !self.tcx.is_user_visible_dep(def_id.krate) { @@ -1906,7 +1906,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // ignore `do_not_recommend` items .filter(|def_id| !self.tcx.do_not_recommend_impl(*def_id)) // Ignore automatically derived impls and `!Trait` impls. - .filter_map(|def_id| self.tcx.impl_trait_header(def_id)) + .map(|def_id| self.tcx.impl_trait_header(def_id)) .filter_map(|header| { (header.polarity != ty::ImplPolarity::Negative || self.tcx.is_automatically_derived(def_id)) diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index d694a092853af..7f2a9999d6464 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -458,9 +458,7 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>( Err(_) => Err(EvaluationFailure::NoSolution), Ok(Some(source)) => match source { ImplSource::UserDefined(impl_) => { - if tcx.impl_trait_header(impl_.impl_def_id).unwrap().constness - != hir::Constness::Const - { + if tcx.impl_trait_header(impl_.impl_def_id).constness != hir::Constness::Const { return Err(EvaluationFailure::NoSolution); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index cb980d5ce8b43..cecb43e537a8e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -604,7 +604,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Before we create the generic parameters and everything, first // consider a "quick reject". This avoids creating more types // and so forth that we need to. - let impl_trait_header = self.tcx().impl_trait_header(impl_def_id).unwrap(); + let impl_trait_header = self.tcx().impl_trait_header(impl_def_id); if !drcx .args_may_unify(obligation_args, impl_trait_header.trait_ref.skip_binder().args) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9be5d0673f73c..614c09d913f72 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2487,7 +2487,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { impl_def_id: DefId, obligation: &PolyTraitObligation<'tcx>, ) -> Normalized<'tcx, GenericArgsRef<'tcx>> { - let impl_trait_header = self.tcx().impl_trait_header(impl_def_id).unwrap(); + let impl_trait_header = self.tcx().impl_trait_header(impl_def_id); match self.match_impl(impl_def_id, impl_trait_header, obligation) { Ok(args) => args, Err(()) => { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index a00680b471346..ca6fd780dd88f 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -252,7 +252,7 @@ pub(super) fn specializes( } } - let specializing_impl_trait_header = tcx.impl_trait_header(specializing_impl_def_id).unwrap(); + let specializing_impl_trait_header = tcx.impl_trait_header(specializing_impl_def_id); // We determine whether there's a subset relationship by: // diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 1cd4b880abe79..b470af50f68fe 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -566,7 +566,11 @@ pub(crate) fn build_impl( clean::enter_impl_trait(cx, |cx| clean_ty_generics(cx, did)), ), }; - let polarity = tcx.impl_polarity(did); + let polarity = if associated_trait.is_some() { + tcx.impl_polarity(did) + } else { + ty::ImplPolarity::Positive + }; let trait_ = associated_trait .map(|t| clean_trait_ref_with_constraints(cx, ty::Binder::dummy(t), ThinVec::new())); if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 481395ffb836c..4a95f21a3a5bd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2934,7 +2934,11 @@ fn clean_impl<'tcx>( trait_, for_, items, - polarity: tcx.impl_polarity(def_id), + polarity: if impl_.of_trait.is_some() { + tcx.impl_polarity(def_id) + } else { + ty::ImplPolarity::Positive + }, kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::fake_variadic) { ImplKind::FakeVariadic } else { From d9a53899db3ad02c913576600a14a14298564692 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 7 Oct 2025 15:49:06 -0500 Subject: [PATCH 9/9] Fix clippy for impl_trait_header changes --- .../src/derive/derive_ord_xor_partial_ord.rs | 2 +- .../src/derive/derived_hash_with_manual_eq.rs | 2 +- .../clippy/clippy_lints/src/fallible_impl_from.rs | 8 +++----- .../clippy/clippy_lints/src/from_over_into.rs | 3 +-- .../clippy_lints/src/implicit_saturating_sub.rs | 6 ++---- .../clippy_lints/src/methods/suspicious_splitn.rs | 3 +-- .../clippy/clippy_lints/src/missing_inline.rs | 2 +- .../clippy_lints/src/non_canonical_impls.rs | 12 ++++++------ .../src/non_send_fields_in_send_ty.rs | 2 +- .../clippy_lints/src/only_used_in_recursion.rs | 15 +++++++-------- .../clippy_lints/src/return_self_not_must_use.rs | 3 +-- .../clippy/clippy_lints/src/unused_io_amount.rs | 5 ++--- src/tools/clippy/clippy_lints/src/use_self.rs | 5 +++-- .../clippy_lints_internal/src/msrv_attr_impl.rs | 5 +---- 14 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs b/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs index 274c699ff9d24..2bd5e2cbfb1ad 100644 --- a/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs +++ b/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs @@ -28,7 +28,7 @@ pub(super) fn check<'tcx>( return; } - let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation"); + let trait_ref = cx.tcx.impl_trait_ref(impl_id); // Only care about `impl PartialOrd for Foo` // For `impl PartialOrd for A, input_types is [A, B] diff --git a/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs b/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs index afc02ce32d48e..dc3fbe5d7012c 100644 --- a/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs +++ b/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>( return; } - let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation"); + let trait_ref = cx.tcx.impl_trait_ref(impl_id); // Only care about `impl PartialEq for Foo` // For `impl PartialEq for A, input_types is [A, B] diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 4446b912bf7ee..c42998ffc3f59 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -52,11 +52,9 @@ declare_lint_pass!(FallibleImplFrom => [FALLIBLE_IMPL_FROM]); impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { // check for `impl From for ..` - if let hir::ItemKind::Impl(_) = &item.kind - && let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) - && cx - .tcx - .is_diagnostic_item(sym::From, impl_trait_ref.skip_binder().def_id) + if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = &item.kind + && let impl_trait_id = cx.tcx.impl_trait_id(item.owner_id) + && cx.tcx.is_diagnostic_item(sym::From, impl_trait_id) { lint_impl_body(cx, item.owner_id, item.span); } diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index fd807290dc090..ed55f90848f89 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -76,8 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { // `impl Into for self_ty` && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args && span_is_local(item.span) - && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) - .map(ty::EarlyBinder::instantiate_identity) + && let middle_trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity() && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id) && !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::Opaque, _)) && self.msrv.meets(cx, msrvs::RE_REBALANCING_COHERENCE) diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index 678a29924e528..7b6f8729cb759 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -339,8 +339,7 @@ fn check_with_condition<'tcx>( ExprKind::Path(QPath::TypeRelative(_, name)) => { if name.ident.name == sym::MIN && let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id) - && let Some(impl_id) = cx.tcx.impl_of_assoc(const_id) - && let None = cx.tcx.impl_trait_ref(impl_id) // An inherent impl + && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(const_id) && cx.tcx.type_of(impl_id).instantiate_identity().is_integral() { print_lint_and_sugg(cx, var_name, expr); @@ -350,8 +349,7 @@ fn check_with_condition<'tcx>( if let ExprKind::Path(QPath::TypeRelative(_, name)) = func.kind && name.ident.name == sym::min_value && let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id) - && let Some(impl_id) = cx.tcx.impl_of_assoc(func_id) - && let None = cx.tcx.impl_trait_ref(impl_id) // An inherent impl + && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(func_id) && cx.tcx.type_of(impl_id).instantiate_identity().is_integral() { print_lint_and_sugg(cx, var_name, expr); diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs index 9876681ddbb3a..be1481ebb996e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs @@ -10,8 +10,7 @@ use super::SUSPICIOUS_SPLITN; pub(super) fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, count: u128) { if count <= 1 && let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && let Some(impl_id) = cx.tcx.impl_of_assoc(call_id) - && cx.tcx.impl_trait_ref(impl_id).is_none() + && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(call_id) && let self_ty = cx.tcx.type_of(impl_id).instantiate_identity() && (self_ty.is_slice() || self_ty.is_str()) { diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 6323e728666ce..bccc72c2a516c 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -167,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { let container_id = assoc_item.container_id(cx.tcx); let trait_def_id = match assoc_item.container { AssocContainer::Trait => Some(container_id), - AssocContainer::TraitImpl(_) => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id), + AssocContainer::TraitImpl(_) => Some(cx.tcx.impl_trait_id(container_id)), AssocContainer::InherentImpl => None, }; diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs index 3285023b34aa8..e11f775018ed8 100644 --- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs +++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::{Block, Body, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, LangItem, UnOp}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::{EarlyBinder, TyCtxt, TypeckResults}; +use rustc_middle::ty::{TyCtxt, TypeckResults}; use rustc_session::impl_lint_pass; use rustc_span::sym; use rustc_span::symbol::kw; @@ -173,10 +173,11 @@ impl LateLintPass<'_> for NonCanonicalImpls { } }); + let trait_impl = cx.tcx.impl_trait_ref(item.owner_id).skip_binder(); + match trait_ { Trait::Clone => { if let Some(copy_trait) = self.copy_trait - && let Some(trait_impl) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::skip_binder) && implements_trait(cx, trait_impl.self_ty(), copy_trait, &[]) { for (assoc, _, block) in assoc_fns { @@ -185,10 +186,9 @@ impl LateLintPass<'_> for NonCanonicalImpls { } }, Trait::PartialOrd => { - if let Some(trait_impl) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::skip_binder) - // If `Self` and `Rhs` are not the same type, then a corresponding `Ord` impl is not possible, - // since it doesn't have an `Rhs` - && let [lhs, rhs] = trait_impl.args.as_slice() + // If `Self` and `Rhs` are not the same type, then a corresponding `Ord` impl is not possible, + // since it doesn't have an `Rhs` + if let [lhs, rhs] = trait_impl.args.as_slice() && lhs == rhs && let Some(ord_trait) = self.ord_trait && implements_trait(cx, trait_impl.self_ty(), ord_trait, &[]) diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index b810bc01fbdcb..fd5562f310e48 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -87,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { && let Some(trait_id) = of_trait.trait_ref.trait_def_id() && send_trait == trait_id && of_trait.polarity == ImplPolarity::Positive - && let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) + && let ty_trait_ref = cx.tcx.impl_trait_ref(item.owner_id) && let self_ty = ty_trait_ref.instantiate_identity().self_ty() && let ty::Adt(adt_def, impl_trait_args) = self_ty.kind() { diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 784ea34bac58f..51644f7dce6cf 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -6,9 +6,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdMap; -use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind}; +use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemImplKind, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, ConstKind, EarlyBinder, GenericArgKind, GenericArgsRef}; +use rustc_middle::ty::{self, ConstKind, GenericArgKind, GenericArgsRef}; use rustc_session::impl_lint_pass; use rustc_span::Span; use rustc_span::symbol::{Ident, kw}; @@ -320,15 +320,14 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(ref sig, _), owner_id, + impl_kind, .. }) => { - if let Node::Item(item) = cx.tcx.parent_hir_node(owner_id.into()) - && let Some(trait_ref) = cx - .tcx - .impl_trait_ref(item.owner_id) - .map(EarlyBinder::instantiate_identity) - && let Some(trait_item_id) = cx.tcx.trait_item_of(owner_id) + if let ImplItemImplKind::Trait { trait_item_def_id, .. } = impl_kind + && let Ok(trait_item_id) = trait_item_def_id { + let impl_id = cx.tcx.parent(owner_id.into()); + let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity(); ( trait_item_id, FnKind::ImplTraitFn( diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs index b057396034c07..83a226b29e75f 100644 --- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs +++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs @@ -113,10 +113,9 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse { ) { if matches!(kind, FnKind::Method(_, _)) // We are only interested in methods, not in functions or associated functions. - && let Some(impl_def) = cx.tcx.impl_of_assoc(fn_def.to_def_id()) // We don't want this method to be te implementation of a trait because the // `#[must_use]` should be put on the trait definition directly. - && cx.tcx.trait_id_of_impl(impl_def).is_none() + && cx.tcx.inherent_impl_of_assoc(fn_def.to_def_id()).is_some() { let hir_id = cx.tcx.local_def_id_to_hir_id(fn_def); check_method(cx, decl, fn_def, span, hir_id.expect_owner()); diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index cff798f7a89a0..2884bbd9280d2 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -85,9 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount { /// get desugared to match. fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) { let fn_def_id = block.hir_id.owner.to_def_id(); - if let Some(impl_id) = cx.tcx.impl_of_assoc(fn_def_id) - && let Some(trait_id) = cx.tcx.trait_id_of_impl(impl_id) - { + if let Some(impl_id) = cx.tcx.trait_impl_of_assoc(fn_def_id) { + let trait_id = cx.tcx.impl_trait_id(impl_id); // We don't want to lint inside io::Read or io::Write implementations, as the author has more // information about their trait implementation than our lint, see https://github.com/rust-lang/rust-clippy/issues/4836 if let Some(trait_name) = cx.tcx.get_diagnostic_name(trait_id) diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index f46dedf1261e9..eba60501ae214 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -10,7 +10,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty}; use rustc_hir::{ self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParamKind, HirId, Impl, - ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, + ImplItemImplKind, ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty as MiddleTy; @@ -142,13 +142,14 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // We want to skip types in trait `impl`s that aren't declared as `Self` in the trait // declaration. The collection of those types is all this method implementation does. if let ImplItemKind::Fn(FnSig { decl, .. }, ..) = impl_item.kind + && let ImplItemImplKind::Trait { .. } = impl_item.impl_kind && let Some(&mut StackItem::Check { impl_id, ref mut types_to_skip, .. }) = self.stack.last_mut() - && let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_id) { + let impl_trait_ref = cx.tcx.impl_trait_ref(impl_id); // `self_ty` is the semantic self type of `impl for `. This cannot be // `Self`. let self_ty = impl_trait_ref.instantiate_identity().self_ty(); diff --git a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs index 66aeb910891a2..e529bc2d2fa5b 100644 --- a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs +++ b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs @@ -26,10 +26,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { items, .. }) = &item.kind - && let Some(trait_ref) = cx - .tcx - .impl_trait_ref(item.owner_id) - .map(EarlyBinder::instantiate_identity) + && let trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity() && internal_paths::EARLY_LINT_PASS.matches(cx, trait_ref.def_id) && let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind() && self_ty_def.is_struct()