1
Fork 0

Rollup merge of #135902 - compiler-errors:item-non-self-bound-in-new-solver, r=lcnr

Do not consider child bound assumptions for rigid alias

r? lcnr

See first commit for the important details. For second commit, I also stacked a somewhat opinionated name change, though I can separate that if needed.

Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/149
This commit is contained in:
León Orell Valerian Liehr 2025-01-29 03:12:19 +01:00 committed by GitHub
commit 42f46437ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 212 additions and 134 deletions

View file

@ -457,7 +457,7 @@ fn fn_sig_suggestion<'tcx>(
let asyncness = if tcx.asyncness(assoc.def_id).is_async() { let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
output = if let ty::Alias(_, alias_ty) = *output.kind() { output = if let ty::Alias(_, alias_ty) = *output.kind() {
tcx.explicit_item_super_predicates(alias_ty.def_id) tcx.explicit_item_self_bounds(alias_ty.def_id)
.iter_instantiated_copied(tcx, alias_ty.args) .iter_instantiated_copied(tcx, alias_ty.args)
.find_map(|(bound, _)| { .find_map(|(bound, _)| {
bound.as_projection_clause()?.no_bound_vars()?.term.as_type() bound.as_projection_clause()?.no_bound_vars()?.term.as_type()

View file

@ -65,9 +65,9 @@ pub fn provide(providers: &mut Providers) {
type_alias_is_lazy: type_of::type_alias_is_lazy, type_alias_is_lazy: type_of::type_alias_is_lazy,
item_bounds: item_bounds::item_bounds, item_bounds: item_bounds::item_bounds,
explicit_item_bounds: item_bounds::explicit_item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds,
item_super_predicates: item_bounds::item_super_predicates, item_self_bounds: item_bounds::item_self_bounds,
explicit_item_super_predicates: item_bounds::explicit_item_super_predicates, explicit_item_self_bounds: item_bounds::explicit_item_self_bounds,
item_non_self_assumptions: item_bounds::item_non_self_assumptions, item_non_self_bounds: item_bounds::item_non_self_bounds,
impl_super_outlives: item_bounds::impl_super_outlives, impl_super_outlives: item_bounds::impl_super_outlives,
generics_of: generics_of::generics_of, generics_of: generics_of::generics_of,
predicates_of: predicates_of::predicates_of, predicates_of: predicates_of::predicates_of,
@ -328,9 +328,9 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
self.tcx.ensure().generics_of(def_id); self.tcx.ensure().generics_of(def_id);
self.tcx.ensure().predicates_of(def_id); self.tcx.ensure().predicates_of(def_id);
self.tcx.ensure().explicit_item_bounds(def_id); self.tcx.ensure().explicit_item_bounds(def_id);
self.tcx.ensure().explicit_item_super_predicates(def_id); self.tcx.ensure().explicit_item_self_bounds(def_id);
self.tcx.ensure().item_bounds(def_id); self.tcx.ensure().item_bounds(def_id);
self.tcx.ensure().item_super_predicates(def_id); self.tcx.ensure().item_self_bounds(def_id);
if self.tcx.is_conditionally_const(def_id) { if self.tcx.is_conditionally_const(def_id) {
self.tcx.ensure().explicit_implied_const_bounds(def_id); self.tcx.ensure().explicit_implied_const_bounds(def_id);
self.tcx.ensure().const_conditions(def_id); self.tcx.ensure().const_conditions(def_id);
@ -822,7 +822,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
hir::TraitItemKind::Type(_, Some(_)) => { hir::TraitItemKind::Type(_, Some(_)) => {
tcx.ensure().item_bounds(def_id); tcx.ensure().item_bounds(def_id);
tcx.ensure().item_super_predicates(def_id); tcx.ensure().item_self_bounds(def_id);
tcx.ensure().type_of(def_id); tcx.ensure().type_of(def_id);
// Account for `type T = _;`. // Account for `type T = _;`.
let mut visitor = HirPlaceholderCollector::default(); let mut visitor = HirPlaceholderCollector::default();
@ -839,7 +839,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
hir::TraitItemKind::Type(_, None) => { hir::TraitItemKind::Type(_, None) => {
tcx.ensure().item_bounds(def_id); tcx.ensure().item_bounds(def_id);
tcx.ensure().item_super_predicates(def_id); tcx.ensure().item_self_bounds(def_id);
// #74612: Visit and try to find bad placeholders // #74612: Visit and try to find bad placeholders
// even if there is no concrete type. // even if there is no concrete type.
let mut visitor = HirPlaceholderCollector::default(); let mut visitor = HirPlaceholderCollector::default();

View file

@ -350,7 +350,7 @@ pub(super) fn explicit_item_bounds(
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All) explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
} }
pub(super) fn explicit_item_super_predicates( pub(super) fn explicit_item_self_bounds(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: LocalDefId, def_id: LocalDefId,
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> { ) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
@ -434,11 +434,11 @@ pub(super) fn item_bounds(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<'_,
}) })
} }
pub(super) fn item_super_predicates( pub(super) fn item_self_bounds(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
) -> ty::EarlyBinder<'_, ty::Clauses<'_>> { ) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
tcx.explicit_item_super_predicates(def_id).map_bound(|bounds| { tcx.explicit_item_self_bounds(def_id).map_bound(|bounds| {
tcx.mk_clauses_from_iter( tcx.mk_clauses_from_iter(
util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(), util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
) )
@ -447,13 +447,12 @@ pub(super) fn item_super_predicates(
/// This exists as an optimization to compute only the item bounds of the item /// This exists as an optimization to compute only the item bounds of the item
/// that are not `Self` bounds. /// that are not `Self` bounds.
pub(super) fn item_non_self_assumptions( pub(super) fn item_non_self_bounds(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
) -> ty::EarlyBinder<'_, ty::Clauses<'_>> { ) -> ty::EarlyBinder<'_, ty::Clauses<'_>> {
let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect(); let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
let own_bounds: FxIndexSet<_> = let own_bounds: FxIndexSet<_> = tcx.item_self_bounds(def_id).skip_binder().iter().collect();
tcx.item_super_predicates(def_id).skip_binder().iter().collect();
if all_bounds.len() == own_bounds.len() { if all_bounds.len() == own_bounds.len() {
ty::EarlyBinder::bind(ty::ListWithCachedTypeInfo::empty()) ty::EarlyBinder::bind(ty::ListWithCachedTypeInfo::empty())
} else { } else {

View file

@ -308,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty, expected_ty,
closure_kind, closure_kind,
self.tcx self.tcx
.explicit_item_super_predicates(def_id) .explicit_item_self_bounds(def_id)
.iter_instantiated_copied(self.tcx, args) .iter_instantiated_copied(self.tcx, args)
.map(|(c, s)| (c.as_predicate(), s)), .map(|(c, s)| (c.as_predicate(), s)),
), ),
@ -1019,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
.tcx .tcx
.explicit_item_super_predicates(def_id) .explicit_item_self_bounds(def_id)
.iter_instantiated_copied(self.tcx, args) .iter_instantiated_copied(self.tcx, args)
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
ty::Error(_) => return Some(ret_ty), ty::Error(_) => return Some(ret_ty),

View file

@ -1847,30 +1847,26 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx.probe(|_| { fcx.probe(|_| {
let ocx = ObligationCtxt::new(fcx); let ocx = ObligationCtxt::new(fcx);
ocx.register_obligations( ocx.register_obligations(
fcx.tcx.item_super_predicates(rpit_def_id).iter_identity().filter_map( fcx.tcx.item_self_bounds(rpit_def_id).iter_identity().filter_map(|clause| {
|clause| { let predicate = clause
let predicate = clause .kind()
.kind() .map_bound(|clause| match clause {
.map_bound(|clause| match clause { ty::ClauseKind::Trait(trait_pred) => Some(ty::ClauseKind::Trait(
ty::ClauseKind::Trait(trait_pred) => Some( trait_pred.with_self_ty(fcx.tcx, ty),
ty::ClauseKind::Trait(trait_pred.with_self_ty(fcx.tcx, ty)), )),
), ty::ClauseKind::Projection(proj_pred) => Some(
ty::ClauseKind::Projection(proj_pred) => { ty::ClauseKind::Projection(proj_pred.with_self_ty(fcx.tcx, ty)),
Some(ty::ClauseKind::Projection( ),
proj_pred.with_self_ty(fcx.tcx, ty), _ => None,
)) })
} .transpose()?;
_ => None, Some(Obligation::new(
}) fcx.tcx,
.transpose()?; ObligationCause::dummy(),
Some(Obligation::new( fcx.param_env,
fcx.tcx, predicate,
ObligationCause::dummy(), ))
fcx.param_env, }),
predicate,
))
},
),
); );
ocx.select_where_possible().is_empty() ocx.select_where_possible().is_empty()
}) })

View file

@ -281,7 +281,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
alias_ty: ty::AliasTy<'tcx>, alias_ty: ty::AliasTy<'tcx>,
) -> impl Iterator<Item = ty::Region<'tcx>> { ) -> impl Iterator<Item = ty::Region<'tcx>> {
let tcx = self.tcx; let tcx = self.tcx;
let bounds = tcx.item_super_predicates(alias_ty.def_id); let bounds = tcx.item_self_bounds(alias_ty.def_id);
trace!("{:#?}", bounds.skip_binder()); trace!("{:#?}", bounds.skip_binder());
bounds bounds
.iter_instantiated(tcx, alias_ty.args) .iter_instantiated(tcx, alias_ty.args)

View file

@ -289,25 +289,22 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
} }
ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), ty::Adt(def, _) => is_def_must_use(cx, def.did(), span),
ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => { ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => {
elaborate( elaborate(cx.tcx, cx.tcx.explicit_item_self_bounds(def).iter_identity_copied())
cx.tcx, // We only care about self bounds for the impl-trait
cx.tcx.explicit_item_super_predicates(def).iter_identity_copied(), .filter_only_self()
) .find_map(|(pred, _span)| {
// We only care about self bounds for the impl-trait // We only look at the `DefId`, so it is safe to skip the binder here.
.filter_only_self() if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
.find_map(|(pred, _span)| { pred.kind().skip_binder()
// We only look at the `DefId`, so it is safe to skip the binder here. {
if let ty::ClauseKind::Trait(ref poly_trait_predicate) = let def_id = poly_trait_predicate.trait_ref.def_id;
pred.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;
is_def_must_use(cx, def_id, span) is_def_must_use(cx, def_id, span)
} else { } else {
None None
} }
}) })
.map(|inner| MustUsePath::Opaque(Box::new(inner))) .map(|inner| MustUsePath::Opaque(Box::new(inner)))
} }
ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| { ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()

View file

@ -241,7 +241,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) {
provide! { tcx, def_id, other, cdata, provide! { tcx, def_id, other, cdata,
explicit_item_bounds => { table_defaulted_array } explicit_item_bounds => { table_defaulted_array }
explicit_item_super_predicates => { table_defaulted_array } explicit_item_self_bounds => { table_defaulted_array }
explicit_predicates_of => { table } explicit_predicates_of => { table }
generics_of => { table } generics_of => { table }
inferred_outlives_of => { table_defaulted_array } inferred_outlives_of => { table_defaulted_array }

View file

@ -1554,7 +1554,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
if let DefKind::OpaqueTy = def_kind { if let DefKind::OpaqueTy = def_kind {
self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_bounds(def_id);
self.encode_explicit_item_super_predicates(def_id); self.encode_explicit_item_self_bounds(def_id);
record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id));
self.encode_precise_capturing_args(def_id); self.encode_precise_capturing_args(def_id);
if tcx.is_conditionally_const(def_id) { if tcx.is_conditionally_const(def_id) {
@ -1667,10 +1667,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds); record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds);
} }
fn encode_explicit_item_super_predicates(&mut self, def_id: DefId) { fn encode_explicit_item_self_bounds(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_explicit_item_super_predicates({:?})", def_id); debug!("EncodeContext::encode_explicit_item_self_bounds({:?})", def_id);
let bounds = self.tcx.explicit_item_super_predicates(def_id).skip_binder(); let bounds = self.tcx.explicit_item_self_bounds(def_id).skip_binder();
record_defaulted_array!(self.tables.explicit_item_super_predicates[def_id] <- bounds); record_defaulted_array!(self.tables.explicit_item_self_bounds[def_id] <- bounds);
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
@ -1685,7 +1685,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
AssocItemContainer::Trait => { AssocItemContainer::Trait => {
if let ty::AssocKind::Type = item.kind { if let ty::AssocKind::Type = item.kind {
self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_bounds(def_id);
self.encode_explicit_item_super_predicates(def_id); self.encode_explicit_item_self_bounds(def_id);
if tcx.is_conditionally_const(def_id) { if tcx.is_conditionally_const(def_id) {
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder()); <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());

View file

@ -386,7 +386,7 @@ define_tables! {
// corresponding DefPathHash. // corresponding DefPathHash.
def_path_hashes: Table<DefIndex, u64>, def_path_hashes: Table<DefIndex, u64>,
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
explicit_item_super_predicates: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, explicit_item_self_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,

View file

@ -393,7 +393,7 @@ rustc_queries! {
/// like closure signature deduction. /// like closure signature deduction.
/// ///
/// [explicit item bounds]: Self::explicit_item_bounds /// [explicit item bounds]: Self::explicit_item_bounds
query explicit_item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern separate_provide_extern
@ -427,11 +427,11 @@ rustc_queries! {
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
} }
query item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { query item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
} }
query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { query item_non_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> {
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
} }

View file

@ -345,6 +345,20 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.item_bounds(def_id).map_bound(IntoIterator::into_iter) self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
} }
fn item_self_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
}
fn item_non_self_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
}
fn predicates_of( fn predicates_of(
self, self,
def_id: DefId, def_id: DefId,
@ -2577,7 +2591,7 @@ impl<'tcx> TyCtxt<'tcx> {
let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
let future_trait = self.require_lang_item(LangItem::Future, None); let future_trait = self.require_lang_item(LangItem::Future, None);
self.explicit_item_super_predicates(def_id).skip_binder().iter().any(|&(predicate, _)| { self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
return false; return false;
}; };

View file

@ -64,7 +64,7 @@ impl<'tcx> TyCtxt<'tcx> {
args: ty::GenericArgsRef<'tcx>, args: ty::GenericArgsRef<'tcx>,
) -> &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { ) -> &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
let mut bounds: Vec<_> = self let mut bounds: Vec<_> = self
.item_super_predicates(def_id) .item_self_bounds(def_id)
.iter_instantiated(self, args) .iter_instantiated(self, args)
.filter_map(|clause| { .filter_map(|clause| {
clause clause

View file

@ -19,6 +19,11 @@ use crate::solve::{
MaybeCause, NoSolution, QueryResult, MaybeCause, NoSolution, QueryResult,
}; };
enum AliasBoundKind {
SelfBounds,
NonSelfBounds,
}
/// A candidate is a possible way to prove a goal. /// A candidate is a possible way to prove a goal.
/// ///
/// It consists of both the `source`, which describes how that goal would be proven, /// It consists of both the `source`, which describes how that goal would be proven,
@ -510,7 +515,12 @@ where
candidates: &mut Vec<Candidate<I>>, candidates: &mut Vec<Candidate<I>>,
) { ) {
let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| { let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates); ecx.assemble_alias_bound_candidates_recur(
goal.predicate.self_ty(),
goal,
candidates,
AliasBoundKind::SelfBounds,
);
}); });
} }
@ -528,6 +538,7 @@ where
self_ty: I::Ty, self_ty: I::Ty,
goal: Goal<I, G>, goal: Goal<I, G>,
candidates: &mut Vec<Candidate<I>>, candidates: &mut Vec<Candidate<I>>,
consider_self_bounds: AliasBoundKind,
) { ) {
let (kind, alias_ty) = match self_ty.kind() { let (kind, alias_ty) = match self_ty.kind() {
ty::Bool ty::Bool
@ -580,16 +591,37 @@ where
} }
}; };
for assumption in match consider_self_bounds {
self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args) AliasBoundKind::SelfBounds => {
{ for assumption in self
candidates.extend(G::probe_and_consider_implied_clause( .cx()
self, .item_self_bounds(alias_ty.def_id)
CandidateSource::AliasBound, .iter_instantiated(self.cx(), alias_ty.args)
goal, {
assumption, candidates.extend(G::probe_and_consider_implied_clause(
[], self,
)); CandidateSource::AliasBound,
goal,
assumption,
[],
));
}
}
AliasBoundKind::NonSelfBounds => {
for assumption in self
.cx()
.item_non_self_bounds(alias_ty.def_id)
.iter_instantiated(self.cx(), alias_ty.args)
{
candidates.extend(G::probe_and_consider_implied_clause(
self,
CandidateSource::AliasBound,
goal,
assumption,
[],
));
}
}
} }
candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty)); candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));
@ -600,9 +632,12 @@ where
// Recurse on the self type of the projection. // Recurse on the self type of the projection.
match self.structurally_normalize_ty(goal.param_env, alias_ty.self_ty()) { match self.structurally_normalize_ty(goal.param_env, alias_ty.self_ty()) {
Ok(next_self_ty) => { Ok(next_self_ty) => self.assemble_alias_bound_candidates_recur(
self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates) next_self_ty,
} goal,
candidates,
AliasBoundKind::NonSelfBounds,
),
Err(NoSolution) => {} Err(NoSolution) => {}
} }
} }

View file

@ -196,7 +196,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
self.tcx self.tcx
.explicit_item_super_predicates(def_id) .explicit_item_self_bounds(def_id)
.iter_instantiated_copied(self.tcx, args) .iter_instantiated_copied(self.tcx, args)
.find_map(|(predicate, _)| { .find_map(|(predicate, _)| {
predicate predicate

View file

@ -293,7 +293,7 @@ impl<T> Trait<T> for X {
(ty::Dynamic(t, _, ty::DynKind::Dyn), ty::Alias(ty::Opaque, alias)) (ty::Dynamic(t, _, ty::DynKind::Dyn), ty::Alias(ty::Opaque, alias))
if let Some(def_id) = t.principal_def_id() if let Some(def_id) = t.principal_def_id()
&& tcx && tcx
.explicit_item_super_predicates(alias.def_id) .explicit_item_self_bounds(alias.def_id)
.skip_binder() .skip_binder()
.iter() .iter()
.any(|(pred, _span)| match pred.kind().skip_binder() { .any(|(pred, _span)| match pred.kind().skip_binder() {
@ -422,7 +422,7 @@ impl<T> Trait<T> for X {
ty::Alias(..) => values.expected, ty::Alias(..) => values.expected,
_ => values.found, _ => values.found,
}; };
let preds = tcx.explicit_item_super_predicates(opaque_ty.def_id); let preds = tcx.explicit_item_self_bounds(opaque_ty.def_id);
for (pred, _span) in preds.skip_binder() { for (pred, _span) in preds.skip_binder() {
let ty::ClauseKind::Trait(trait_predicate) = pred.kind().skip_binder() let ty::ClauseKind::Trait(trait_predicate) = pred.kind().skip_binder()
else { else {

View file

@ -1087,28 +1087,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
sig_parts.map_bound(|sig| sig.tupled_inputs_ty.tuple_fields().as_slice()), sig_parts.map_bound(|sig| sig.tupled_inputs_ty.tuple_fields().as_slice()),
)) ))
} }
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
.tcx self.tcx.item_self_bounds(def_id).instantiate(self.tcx, args).iter().find_map(
.item_super_predicates(def_id) |pred| {
.instantiate(self.tcx, args) if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
.iter()
.find_map(|pred| {
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
&& self && self
.tcx .tcx
.is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput) .is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput)
// args tuple will always be args[1] // args tuple will always be args[1]
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
{ {
Some(( Some((
DefIdOrName::DefId(def_id), DefIdOrName::DefId(def_id),
pred.kind().rebind(proj.term.expect_type()), pred.kind().rebind(proj.term.expect_type()),
pred.kind().rebind(args.as_slice()), pred.kind().rebind(args.as_slice()),
)) ))
} else { } else {
None None
} }
}), },
)
}
ty::Dynamic(data, _, ty::Dyn) => data.iter().find_map(|pred| { ty::Dynamic(data, _, ty::Dyn) => data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder() if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
&& self.tcx.is_lang_item(proj.def_id, LangItem::FnOnceOutput) && self.tcx.is_lang_item(proj.def_id, LangItem::FnOnceOutput)

View file

@ -1620,9 +1620,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// projections, we will never be able to equate, e.g. `<T as Tr>::A` // projections, we will never be able to equate, e.g. `<T as Tr>::A`
// with `<<T as Tr>::A as Tr>::A`. // with `<<T as Tr>::A as Tr>::A`.
let relevant_bounds = if in_parent_alias_type { let relevant_bounds = if in_parent_alias_type {
self.tcx().item_non_self_assumptions(alias_ty.def_id) self.tcx().item_non_self_bounds(alias_ty.def_id)
} else { } else {
self.tcx().item_super_predicates(alias_ty.def_id) self.tcx().item_self_bounds(alias_ty.def_id)
}; };
for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args) { for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args) {

View file

@ -203,6 +203,16 @@ pub trait Interner:
def_id: Self::DefId, def_id: Self::DefId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>; ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
fn item_self_bounds(
self,
def_id: Self::DefId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
fn item_non_self_bounds(
self,
def_id: Self::DefId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
fn predicates_of( fn predicates_of(
self, self,
def_id: Self::DefId, def_id: Self::DefId,

View file

@ -79,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
&& let Some(future_trait) = cx.tcx.lang_items().future_trait() && let Some(future_trait) = cx.tcx.lang_items().future_trait()
&& let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send) && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
{ {
let preds = cx.tcx.explicit_item_super_predicates(def_id); let preds = cx.tcx.explicit_item_self_bounds(def_id);
let is_future = preds.iter_instantiated_copied(cx.tcx, args).any(|(p, _)| { let is_future = preds.iter_instantiated_copied(cx.tcx, args).any(|(p, _)| {
p.as_trait_clause() p.as_trait_clause()
.is_some_and(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait) .is_some_and(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait)

View file

@ -96,7 +96,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
return false; return false;
} }
for (predicate, _span) in cx.tcx.explicit_item_super_predicates(def_id).iter_identity_copied() { for (predicate, _span) in cx.tcx.explicit_item_self_bounds(def_id).iter_identity_copied() {
match predicate.kind().skip_binder() { match predicate.kind().skip_binder() {
// For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
// and check substitutions to find `U`. // and check substitutions to find `U`.
@ -322,7 +322,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::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => { ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_super_predicates(def_id).skip_binder() { for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() {
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().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) { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
return true; return true;
@ -712,7 +712,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds( ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds(
cx, cx,
ty, ty,
cx.tcx.item_super_predicates(def_id).iter_instantiated(cx.tcx, args), cx.tcx.item_self_bounds(def_id).iter_instantiated(cx.tcx, args),
cx.tcx.opt_parent(def_id), cx.tcx.opt_parent(def_id),
), ),
ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)), ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)),

View file

@ -1,5 +1,5 @@
error[E0382]: use of moved value: `x` error[E0382]: use of moved value: `x`
--> $DIR/cant-see-copy-bound-from-child-rigid.rs:14:9 --> $DIR/cant-see-copy-bound-from-child-rigid.rs:18:9
| |
LL | fn foo<T: Trait>(x: T::Assoc) -> (T::Assoc, T::Assoc) LL | fn foo<T: Trait>(x: T::Assoc) -> (T::Assoc, T::Assoc)
| - move occurs because `x` has type `<T as Trait>::Assoc`, which does not implement the `Copy` trait | - move occurs because `x` has type `<T as Trait>::Assoc`, which does not implement the `Copy` trait

View file

@ -0,0 +1,14 @@
error[E0382]: use of moved value: `x`
--> $DIR/cant-see-copy-bound-from-child-rigid.rs:18:9
|
LL | fn foo<T: Trait>(x: T::Assoc) -> (T::Assoc, T::Assoc)
| - move occurs because `x` has type `<T as Trait>::Assoc`, which does not implement the `Copy` trait
...
LL | (x, x)
| - ^ value used here after move
| |
| value moved here
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0382`.

View file

@ -1,3 +1,7 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
trait Id { trait Id {
type This: ?Sized; type This: ?Sized;
} }

View file

@ -99,26 +99,6 @@ note: `PartialEq` can't be used with `~const` because it isn't annotated with `#
--> $SRC_DIR/core/src/cmp.rs:LL:COL --> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:23:22
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^ can't be applied to `PartialEq`
|
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:23:22
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^ can't be applied to `PartialEq`
|
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:27:22 --> $DIR/const-impl-trait.rs:27:22
| |
@ -149,6 +129,36 @@ note: `PartialEq` can't be used with `~const` because it isn't annotated with `#
--> $SRC_DIR/core/src/cmp.rs:LL:COL --> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:23:22
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^ can't be applied to `PartialEq`
|
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:23:22
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^ can't be applied to `PartialEq`
|
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-impl-trait.rs:23:22
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^ can't be applied to `PartialEq`
|
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0015]: cannot call non-const operator in constants error[E0015]: cannot call non-const operator in constants
--> $DIR/const-impl-trait.rs:35:13 --> $DIR/const-impl-trait.rs:35:13
| |
@ -181,7 +191,7 @@ LL | a == a
| |
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 20 previous errors error: aborting due to 21 previous errors
Some errors have detailed explanations: E0015, E0635. Some errors have detailed explanations: E0015, E0635.
For more information about an error, try `rustc --explain E0015`. For more information about an error, try `rustc --explain E0015`.