diff --git a/tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.fail.stderr b/tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.fail.stderr new file mode 100644 index 0000000000000..4ef1c3c8ba733 --- /dev/null +++ b/tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.fail.stderr @@ -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 + diff --git a/tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.rs b/tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.rs new file mode 100644 index 0000000000000..6f05e57fc5b2f --- /dev/null +++ b/tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.rs @@ -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 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> { + forall<'a, U> { + or { + for<> ::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 { + forall<'a, U> { + //[fail]~^ ERROR unable to satisfy constraints involving placeholders + or { + for<> ::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> { + forall<'a, U> { + or { + for<> T::Assoc: 'a, + for<> ::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> { + forall<'a, U> { + //[fail]~^ ERROR unable to satisfy constraints involving placeholders + for<> ::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<> ::Assoc: 'a, + for<> ::Assoc: 'a, + } + } + } +} + +fn main() {}