From 41463407326c03e8920c397b99e6bda07ee523b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 15 Feb 2024 01:58:43 +0000 Subject: [PATCH] Split item bounds and item's own assumptions --- .../src/diagnostics/conflict_errors.rs | 2 +- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 7 +++ .../src/collect/item_bounds.rs | 53 +++++++++++++++++-- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 4 +- .../src/infer/error_reporting/mod.rs | 9 ++-- .../infer/error_reporting/note_and_explain.rs | 12 +++-- .../rustc_infer/src/infer/outlives/verify.rs | 2 +- compiler/rustc_lint/src/unused.rs | 4 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 14 +++++ .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 8 +++ compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 15 +++++- compiler/rustc_middle/src/ty/context.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 10 ++-- .../src/traits/select/mod.rs | 24 ++++----- .../clippy_lints/src/future_not_send.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 8 +-- 20 files changed, 136 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 18cf6f64fbc03..c3359f4d8b08e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -701,7 +701,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .copied() .find_map(find_fn_kind_from_did), ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx - .explicit_item_bounds(def_id) + .explicit_item_own_assumptions(def_id) .iter_instantiated_copied(tcx, args) .find_map(|(clause, span)| find_fn_kind_from_did((clause, span))), ty::Closure(_, args) => match args.as_closure().kind() { diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 2f8e065df3303..980323e486fbf 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -427,7 +427,7 @@ fn fn_sig_suggestion<'tcx>( let asyncness = if tcx.asyncness(assoc.def_id).is_async() { output = if let ty::Alias(_, alias_ty) = *output.kind() { - tcx.explicit_item_bounds(alias_ty.def_id) + tcx.explicit_item_own_assumptions(alias_ty.def_id) .iter_instantiated_copied(tcx, alias_ty.args) .find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty()) .unwrap_or_else(|| { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 4891dae47c66c..9489dae291479 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -66,6 +66,9 @@ pub fn provide(providers: &mut Providers) { type_alias_is_lazy: type_of::type_alias_is_lazy, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, + item_own_assumptions: item_bounds::item_own_assumptions, + explicit_item_own_assumptions: item_bounds::explicit_item_own_assumptions, + item_non_self_assumptions: item_bounds::item_non_self_assumptions, generics_of: generics_of::generics_of, predicates_of: predicates_of::predicates_of, predicates_defined_on, @@ -637,7 +640,9 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure().generics_of(def_id); tcx.ensure().predicates_of(def_id); tcx.ensure().explicit_item_bounds(def_id); + tcx.ensure().explicit_item_own_assumptions(def_id); tcx.ensure().item_bounds(def_id); + tcx.ensure().item_own_assumptions(def_id); } hir::ItemKind::TyAlias(..) => { @@ -693,6 +698,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { hir::TraitItemKind::Type(_, Some(_)) => { tcx.ensure().item_bounds(def_id); + tcx.ensure().item_own_assumptions(def_id); tcx.ensure().type_of(def_id); // Account for `type T = _;`. let mut visitor = HirPlaceholderCollector::default(); @@ -702,6 +708,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { hir::TraitItemKind::Type(_, None) => { tcx.ensure().item_bounds(def_id); + tcx.ensure().item_own_assumptions(def_id); // #74612: Visit and try to find bad placeholders // even if there is no concrete type. let mut visitor = HirPlaceholderCollector::default(); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 39ca1bba06545..0f56517bd7504 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -1,5 +1,6 @@ use super::ItemCtxt; use crate::astconv::{AstConv, PredicateFilter}; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::GenericArgs; @@ -19,6 +20,7 @@ fn associated_type_bounds<'tcx>( assoc_item_def_id: LocalDefId, ast_bounds: &'tcx [hir::GenericBound<'tcx>], span: Span, + filter: PredicateFilter, ) -> &'tcx [(ty::Clause<'tcx>, Span)] { let item_ty = Ty::new_projection( tcx, @@ -27,7 +29,7 @@ fn associated_type_bounds<'tcx>( ); let icx = ItemCtxt::new(tcx, assoc_item_def_id); - let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All); + let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter); // Associated types are implicitly sized unless a `?Sized` bound is found icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); @@ -63,10 +65,11 @@ fn opaque_type_bounds<'tcx>( ast_bounds: &'tcx [hir::GenericBound<'tcx>], item_ty: Ty<'tcx>, span: Span, + filter: PredicateFilter, ) -> &'tcx [(ty::Clause<'tcx>, Span)] { ty::print::with_no_queries!({ let icx = ItemCtxt::new(tcx, opaque_def_id); - let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All); + let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter); // Opaque types are implicitly sized unless a `?Sized` bound is found icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); debug!(?bounds); @@ -78,6 +81,21 @@ fn opaque_type_bounds<'tcx>( pub(super) fn explicit_item_bounds( tcx: TyCtxt<'_>, def_id: LocalDefId, +) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> { + explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All) +} + +pub(super) fn explicit_item_own_assumptions( + tcx: TyCtxt<'_>, + def_id: LocalDefId, +) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> { + explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly) +} + +pub(super) fn explicit_item_bounds_with_filter( + tcx: TyCtxt<'_>, + def_id: LocalDefId, + filter: PredicateFilter, ) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> { match tcx.opt_rpitit_info(def_id.to_def_id()) { // RPITIT's bounds are the same as opaque type bounds, but with @@ -95,6 +113,7 @@ pub(super) fn explicit_item_bounds( ty::GenericArgs::identity_for_item(tcx, def_id), ), item.span, + filter, )); } Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!( @@ -109,7 +128,7 @@ pub(super) fn explicit_item_bounds( kind: hir::TraitItemKind::Type(bounds, _), span, .. - }) => associated_type_bounds(tcx, def_id, bounds, *span), + }) => associated_type_bounds(tcx, def_id, bounds, *span, filter), hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }), span, @@ -117,7 +136,7 @@ pub(super) fn explicit_item_bounds( }) => { let args = GenericArgs::identity_for_item(tcx, def_id); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); - opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) + opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter) } // Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking // for the item bounds of the *opaques* in a trait's default method signature, we @@ -135,7 +154,7 @@ pub(super) fn explicit_item_bounds( let args = GenericArgs::identity_for_item(tcx, def_id); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); tcx.arena.alloc_slice( - &opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) + &opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter) .to_vec() .fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }), ) @@ -155,6 +174,30 @@ pub(super) fn item_bounds( }) } +pub(super) fn item_own_assumptions( + tcx: TyCtxt<'_>, + def_id: DefId, +) -> ty::EarlyBinder<&'_ ty::List>> { + tcx.explicit_item_own_assumptions(def_id).map_bound(|bounds| { + tcx.mk_clauses_from_iter( + util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(), + ) + }) +} + +pub(super) fn item_non_self_assumptions( + tcx: TyCtxt<'_>, + def_id: DefId, +) -> ty::EarlyBinder<&'_ ty::List>> { + let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect(); + let own_bounds: FxIndexSet<_> = tcx.item_own_assumptions(def_id).skip_binder().iter().collect(); + if all_bounds.len() == own_bounds.len() { + ty::EarlyBinder::bind(ty::List::empty()) + } else { + ty::EarlyBinder::bind(tcx.mk_clauses_from_iter(all_bounds.difference(&own_bounds).copied())) + } +} + struct AssocTyToOpaque<'tcx> { tcx: TyCtxt<'tcx>, fn_def_id: DefId, diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 0311aa94cd485..0663da432f20a 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -649,7 +649,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for ty in [first_ty, second_ty] { for (clause, _) in self .tcx - .explicit_item_bounds(rpit_def_id) + .explicit_item_own_assumptions(rpit_def_id) .iter_instantiated_copied(self.tcx, args) { let pred = clause.kind().rebind(match clause.kind().skip_binder() { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 5bdd9412d0e51..85e89d83aee8d 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -329,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .deduce_closure_signature_from_predicates( expected_ty, self.tcx - .explicit_item_bounds(def_id) + .explicit_item_own_assumptions(def_id) .iter_instantiated_copied(self.tcx, args) .map(|(c, s)| (c.as_predicate(), s)), ), @@ -875,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self .tcx - .explicit_item_bounds(def_id) + .explicit_item_own_assumptions(def_id) .iter_instantiated_copied(self.tcx, args) .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, ty::Error(_) => return Some(ret_ty), diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b953b25d6c4cf..d45b12cb5466c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -400,8 +400,10 @@ impl<'tcx> InferCtxt<'tcx> { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - self.tcx.explicit_item_bounds(def_id).iter_instantiated_copied(self.tcx, args).find_map( - |(predicate, _)| { + self.tcx + .explicit_item_own_assumptions(def_id) + .iter_instantiated_copied(self.tcx, args) + .find_map(|(predicate, _)| { predicate .kind() .map_bound(|kind| match kind { @@ -414,8 +416,7 @@ impl<'tcx> InferCtxt<'tcx> { }) .no_bound_vars() .flatten() - }, - ) + }) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 3c42f13141dd0..b15f0d4b96cc6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -299,8 +299,11 @@ impl Trait for X { } (ty::Dynamic(t, _, ty::DynKind::Dyn), ty::Alias(ty::Opaque, alias)) if let Some(def_id) = t.principal_def_id() - && tcx.explicit_item_bounds(alias.def_id).skip_binder().iter().any( - |(pred, _span)| match pred.kind().skip_binder() { + && tcx + .explicit_item_own_assumptions(alias.def_id) + .skip_binder() + .iter() + .any(|(pred, _span)| match pred.kind().skip_binder() { ty::ClauseKind::Trait(trait_predicate) if trait_predicate.polarity == ty::ImplPolarity::Positive => @@ -308,8 +311,7 @@ impl Trait for X { trait_predicate.def_id() == def_id } _ => false, - }, - ) => + }) => { diag.help(format!( "you can box the `{}` to coerce it to `Box<{}>`, but you'll have to \ @@ -412,7 +414,7 @@ impl Trait for X { ty::Alias(..) => values.expected, _ => values.found, }; - let preds = tcx.explicit_item_bounds(opaque_ty.def_id); + let preds = tcx.explicit_item_own_assumptions(opaque_ty.def_id); for (pred, _span) in preds.skip_binder() { let ty::ClauseKind::Trait(trait_predicate) = pred.kind().skip_binder() else { diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 3ef37bf3466f1..022f6406d030d 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -300,7 +300,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { alias_ty: ty::AliasTy<'tcx>, ) -> impl Iterator> { let tcx = self.tcx; - let bounds = tcx.item_bounds(alias_ty.def_id); + let bounds = tcx.item_own_assumptions(alias_ty.def_id); trace!("{:#?}", bounds.skip_binder()); bounds .iter_instantiated(tcx, alias_ty.args) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 35ee0c530463b..73b55753fe989 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -294,7 +294,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => { elaborate( cx.tcx, - cx.tcx.explicit_item_bounds(def).instantiate_identity_iter_copied(), + cx.tcx + .explicit_item_own_assumptions(def) + .instantiate_identity_iter_copied(), ) // We only care about self bounds for the impl-trait .filter_only_self() diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 72e9744295bc9..d586bf83c9ea3 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1047,6 +1047,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ty::EarlyBinder::bind(&*output) } + fn get_explicit_item_own_assumptions( + self, + index: DefIndex, + tcx: TyCtxt<'tcx>, + ) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> { + let lazy = self.root.tables.explicit_item_own_assumptions.get(self, index); + let output = if lazy.is_default() { + &mut [] + } else { + tcx.arena.alloc_from_iter(lazy.decode((self, tcx))) + }; + ty::EarlyBinder::bind(&*output) + } + fn get_variant( self, kind: DefKind, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index d79d4b226a54f..a467ede604ad8 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -206,6 +206,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) { provide! { tcx, def_id, other, cdata, explicit_item_bounds => { cdata.get_explicit_item_bounds(def_id.index, tcx) } + explicit_item_own_assumptions => { cdata.get_explicit_item_own_assumptions(def_id.index, tcx) } explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4a24c038f7ae0..8a769dfc0fb89 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1470,6 +1470,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); + self.encode_explicit_item_own_assumptions(def_id); self.tables .is_type_alias_impl_trait .set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id)); @@ -1578,6 +1579,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds); } + fn encode_explicit_item_own_assumptions(&mut self, def_id: DefId) { + debug!("EncodeContext::encode_explicit_item_own_assumptions({:?})", def_id); + let bounds = self.tcx.explicit_item_own_assumptions(def_id).skip_binder(); + record_defaulted_array!(self.tables.explicit_item_own_assumptions[def_id] <- bounds); + } + #[instrument(level = "debug", skip(self))] fn encode_info_for_assoc_item(&mut self, def_id: DefId) { let tcx = self.tcx; @@ -1590,6 +1597,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { AssocItemContainer::TraitContainer => { if let ty::AssocKind::Type = item.kind { self.encode_explicit_item_bounds(def_id); + self.encode_explicit_item_own_assumptions(def_id); } } AssocItemContainer::ImplContainer => { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4d0a6cb60ee76..617d1b1067660 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -387,6 +387,7 @@ define_tables! { // corresponding DefPathHash. def_path_hashes: Table, explicit_item_bounds: Table, Span)>>, + explicit_item_own_assumptions: Table, Span)>>, inferred_outlives_of: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 60d195e4d3ef9..9a6032374f6c8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -372,7 +372,12 @@ rustc_queries! { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern - feedable + } + + query explicit_item_own_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern } /// Elaborated version of the predicates from `explicit_item_bounds`. @@ -399,6 +404,14 @@ rustc_queries! { desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } } + query item_own_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx ty::List>> { + desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } + } + + query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx ty::List>> { + desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } + } + /// Look up all native libraries this crate depends on. /// These are assembled from the following places: /// - `extern` blocks (depending on their `link` attributes) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7033a4a833dca..d4c16a1bbf21e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1763,7 +1763,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { + self.explicit_item_own_assumptions(def_id).skip_binder().iter().any(|&(predicate, _)| { let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { return false; }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 335e6ff28226e..bd8e6f97b4655 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1329,8 +1329,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { )) } ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { - self.tcx.item_bounds(def_id).instantiate(self.tcx, args).iter().find_map( - |pred| { + self.tcx + .item_own_assumptions(def_id) + .instantiate(self.tcx, args) + .iter() + .find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() // args tuple will always be args[1] @@ -1344,8 +1347,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } else { None } - }, - ) + }) } ty::Dynamic(data, _, ty::Dyn) => { data.iter().find_map(|pred| { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ab0c53e6a9b0a..269fffdf6c185 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1617,21 +1617,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => return ControlFlow::Continue(()), }; - for bound in - self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) - { - // HACK: On subsequent recursions, we only care about bounds that don't - // share the same type as `self_ty`. This is because for truly rigid - // projections, we will never be able to equate, e.g. `::A` - // with `<::A as Tr>::A`. - if in_parent_alias_type { - match bound.kind().skip_binder() { - ty::ClauseKind::Trait(tr) if tr.self_ty() == self_ty => continue, - ty::ClauseKind::Projection(p) if p.self_ty() == self_ty => continue, - _ => {} - } - } + // HACK: On subsequent recursions, we only care about bounds that don't + // share the same type as `self_ty`. This is because for truly rigid + // projections, we will never be able to equate, e.g. `::A` + // with `<::A as Tr>::A`. + let relevant_bounds = if in_parent_alias_type { + self.tcx().item_non_self_assumptions(alias_ty.def_id) + } else { + self.tcx().item_own_assumptions(alias_ty.def_id) + }; + for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args) { for_each(self, bound, idx)?; idx += 1; } diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 9fb59a320d488..60afcc969eb30 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { } let ret_ty = return_ty(cx, cx.tcx.local_def_id_to_hir_id(fn_def_id).expect_owner()); if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() { - let preds = cx.tcx.explicit_item_bounds(def_id); + let preds = cx.tcx.explicit_item_own_assumptions(def_id); let mut is_future = false; for (p, _span) in preds.iter_instantiated_copied(cx.tcx, args) { if let Some(trait_pred) = p.as_trait_clause() { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 6762c88300503..c9d077d603bd0 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -96,7 +96,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied() { + for (predicate, _span) in cx.tcx.explicit_item_own_assumptions(def_id).instantiate_identity_iter_copied() { match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through // and check substitutions to find `U`. @@ -328,7 +328,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { }, ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { - for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { + for (predicate, _) in cx.tcx.explicit_item_own_assumptions(def_id).skip_binder() { if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { return true; @@ -729,7 +729,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option sig_from_bounds( cx, ty, - cx.tcx.item_bounds(def_id).iter_instantiated(cx.tcx, args), + cx.tcx.item_own_assumptions(def_id).iter_instantiated(cx.tcx, args), cx.tcx.opt_parent(def_id), ), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)), @@ -807,7 +807,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option for (pred, _) in cx .tcx - .explicit_item_bounds(ty.def_id) + .explicit_item_own_assumptions(ty.def_id) .iter_instantiated_copied(cx.tcx, ty.args) { match pred.kind().skip_binder() {