Do not assume child bound assumptions for rigid alias

This commit is contained in:
Michael Goulet 2025-01-22 21:07:10 +00:00
parent fdd1a3b026
commit 3f8ce7c973
7 changed files with 123 additions and 36 deletions

View File

@ -345,6 +345,20 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
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_super_predicates(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_assumptions(def_id).map_bound(IntoIterator::into_iter)
}
fn predicates_of(
self,
def_id: DefId,

View File

@ -19,6 +19,11 @@ use crate::solve::{
MaybeCause, NoSolution, QueryResult,
};
enum AliasBoundKind {
SelfBounds,
NonSelfBounds,
}
/// A candidate is a possible way to prove a goal.
///
/// It consists of both the `source`, which describes how that goal would be proven,
@ -510,7 +515,12 @@ where
candidates: &mut Vec<Candidate<I>>,
) {
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,
goal: Goal<I, G>,
candidates: &mut Vec<Candidate<I>>,
consider_self_bounds: AliasBoundKind,
) {
let (kind, alias_ty) = match self_ty.kind() {
ty::Bool
@ -580,16 +591,37 @@ where
}
};
for assumption in
self.cx().item_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,
[],
));
match consider_self_bounds {
AliasBoundKind::SelfBounds => {
for assumption in self
.cx()
.item_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,
[],
));
}
}
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));
@ -600,9 +632,12 @@ where
// Recurse on the self type of the projection.
match self.structurally_normalize_ty(goal.param_env, alias_ty.self_ty()) {
Ok(next_self_ty) => {
self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates)
}
Ok(next_self_ty) => self.assemble_alias_bound_candidates_recur(
next_self_ty,
goal,
candidates,
AliasBoundKind::NonSelfBounds,
),
Err(NoSolution) => {}
}
}

View File

@ -203,6 +203,16 @@ pub trait Interner:
def_id: Self::DefId,
) -> 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(
self,
def_id: Self::DefId,

View File

@ -1,5 +1,5 @@
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)
| - 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 {
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
= 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: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
= 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
--> $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
error: aborting due to 20 previous errors
error: aborting due to 21 previous errors
Some errors have detailed explanations: E0015, E0635.
For more information about an error, try `rustc --explain E0015`.