diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 6e537c668843..55b1520fda06 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 ffdf2a2f4c0c..c6afa9f6897a 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 19ba166fa42a..5955107cf2d3 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 64a36e2d2681..e304ac28fb6d 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 b23e7ae8e77b..f7a0a55d5880 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 4e38d969192f..691cb43b724a 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 543f6a3ccf79..8f3c2b7ce97f 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 eb3236d30065..529a4af591b2 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) {