Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: unable to satisfy constraints involving placeholders due to unknown implied bounds
--> $DIR/mixed-ambiguous-alias-outlives.rs:35:9
|
LL | forall<'a, U> {
| ^^^^^^

error: unable to satisfy constraints involving placeholders due to unknown implied bounds
--> $DIR/mixed-ambiguous-alias-outlives.rs:63:9
|
LL | forall<'a, U> {
| ^^^^^^

error: unable to satisfy constraints involving placeholders due to unknown implied bounds
--> $DIR/mixed-ambiguous-alias-outlives.rs:75:9
|
LL | forall<'a, U, V> {
| ^^^^^^

error: aborting due to 3 previous errors

85 changes: 85 additions & 0 deletions tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//@ revisions: pass fail
//@[pass] check-pass
//@ compile-flags: -Zassumptions-on-binders

#![feature(test_binder_constraints, non_lifetime_binders)]
#![expect(incomplete_features)]

trait Project {
type Assoc;
}

impl<T> Project for T {
type Assoc = T;
}

// The alias involving U cannot leave its non-lifetime binder and becomes ambiguous.
// Keep the other alias candidate until the root, where its outlives assumption is known.
#[cfg(pass)]
core::test_binder_constraints! {
impl<T: Project<Assoc: 'static>> {
forall<'a, U> {
or {
for<> <U as Project>::Assoc: 'a,
for<> T::Assoc: 'a,
}
}
}
}

// If the concrete candidate is rejected at the root, the ambiguous alternative must
// still cause an error rather than disappearing with the rejected candidate.
#[cfg(fail)]
core::test_binder_constraints! {
impl<T: Project> {
forall<'a, U> {
//[fail]~^ ERROR unable to satisfy constraints involving placeholders
or {
for<> <U as Project>::Assoc: 'a,
for<> T::Assoc: 'a,
}
}
}
}

// The order of the alternatives must not change whether the bound can be proved.
#[cfg(pass)]
core::test_binder_constraints! {
impl<T: Project<Assoc: 'static>> {
forall<'a, U> {
or {
for<> T::Assoc: 'a,
for<> <U as Project>::Assoc: 'a,
}
}
}
}

// A required ambiguous constraint still makes the whole AND ambiguous, even when
// its sibling is known to hold.
#[cfg(fail)]
core::test_binder_constraints! {
impl<T: Project<Assoc: 'static>> {
forall<'a, U> {
//[fail]~^ ERROR unable to satisfy constraints involving placeholders
for<> <U as Project>::Assoc: 'a,
for<> T::Assoc: 'a,
}
}
}

// Ambiguity shared by every OR alternative is still required after canonicalization.
#[cfg(fail)]
core::test_binder_constraints! {
impl {
forall<'a, U, V> {
//[fail]~^ ERROR unable to satisfy constraints involving placeholders
or {
for<> <U as Project>::Assoc: 'a,
for<> <V as Project>::Assoc: 'a,
}
}
}
}

fn main() {}
Loading