From 2b761e201b762e0b297d9f8c367bb8d583479ba8 Mon Sep 17 00:00:00 2001 From: Joao Roberto Date: Wed, 23 Sep 2026 10:54:49 -0300 Subject: [PATCH] Test mixed ambiguous ORs under assumptions on binders An OR where one side is an alias outlives that can't leave a non-lifetime binder, and the other side can be proved from the root assumptions, should hold in either order. Also cover the AND case where the ambiguous constraint is still required, and the case where every side of the OR is ambiguous. --- ...mixed-ambiguous-alias-outlives.fail.stderr | 20 +++++ .../mixed-ambiguous-alias-outlives.rs | 85 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.fail.stderr create mode 100644 tests/ui/assumptions_on_binders/mixed-ambiguous-alias-outlives.rs 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() {}