From 064d5886544de3f28b0804fb15654ea49eb6b9c7 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 7 Aug 2025 14:20:19 +0200 Subject: [PATCH 1/3] move member-constraints tests --- .../member-constraints/min-choice-reject-ambiguous.rs | 0 .../member-constraints/min-choice-reject-ambiguous.stderr | 0 tests/ui/{nll => impl-trait}/member-constraints/min-choice.rs | 0 .../member-constraints/nested-impl-trait-fail.rs | 0 .../member-constraints/nested-impl-trait-fail.stderr | 0 .../member-constraints/nested-impl-trait-pass.rs | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{nll => impl-trait}/member-constraints/min-choice-reject-ambiguous.rs (100%) rename tests/ui/{nll => impl-trait}/member-constraints/min-choice-reject-ambiguous.stderr (100%) rename tests/ui/{nll => impl-trait}/member-constraints/min-choice.rs (100%) rename tests/ui/{nll => impl-trait}/member-constraints/nested-impl-trait-fail.rs (100%) rename tests/ui/{nll => impl-trait}/member-constraints/nested-impl-trait-fail.stderr (100%) rename tests/ui/{nll => impl-trait}/member-constraints/nested-impl-trait-pass.rs (100%) diff --git a/tests/ui/nll/member-constraints/min-choice-reject-ambiguous.rs b/tests/ui/impl-trait/member-constraints/min-choice-reject-ambiguous.rs similarity index 100% rename from tests/ui/nll/member-constraints/min-choice-reject-ambiguous.rs rename to tests/ui/impl-trait/member-constraints/min-choice-reject-ambiguous.rs diff --git a/tests/ui/nll/member-constraints/min-choice-reject-ambiguous.stderr b/tests/ui/impl-trait/member-constraints/min-choice-reject-ambiguous.stderr similarity index 100% rename from tests/ui/nll/member-constraints/min-choice-reject-ambiguous.stderr rename to tests/ui/impl-trait/member-constraints/min-choice-reject-ambiguous.stderr diff --git a/tests/ui/nll/member-constraints/min-choice.rs b/tests/ui/impl-trait/member-constraints/min-choice.rs similarity index 100% rename from tests/ui/nll/member-constraints/min-choice.rs rename to tests/ui/impl-trait/member-constraints/min-choice.rs diff --git a/tests/ui/nll/member-constraints/nested-impl-trait-fail.rs b/tests/ui/impl-trait/member-constraints/nested-impl-trait-fail.rs similarity index 100% rename from tests/ui/nll/member-constraints/nested-impl-trait-fail.rs rename to tests/ui/impl-trait/member-constraints/nested-impl-trait-fail.rs diff --git a/tests/ui/nll/member-constraints/nested-impl-trait-fail.stderr b/tests/ui/impl-trait/member-constraints/nested-impl-trait-fail.stderr similarity index 100% rename from tests/ui/nll/member-constraints/nested-impl-trait-fail.stderr rename to tests/ui/impl-trait/member-constraints/nested-impl-trait-fail.stderr diff --git a/tests/ui/nll/member-constraints/nested-impl-trait-pass.rs b/tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs similarity index 100% rename from tests/ui/nll/member-constraints/nested-impl-trait-pass.rs rename to tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs From 8441f95ec70a2ee5cde4d1b8c81203860e4f5bb9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 7 Aug 2025 14:29:11 +0200 Subject: [PATCH 2/3] add opaque type member constraint tests --- .../apply_member_constraint-no-req-eq.rs | 24 +++++++++++++ .../incomplete-constraint.rs | 21 ++++++++++++ .../nested-impl-trait-pass.rs | 5 ++- .../reject-choice-due-to-prev-constraint.rs | 34 +++++++++++++++++++ tests/ui/impl-trait/no-anonymize-regions.rs | 18 ++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 tests/ui/impl-trait/member-constraints/apply_member_constraint-no-req-eq.rs create mode 100644 tests/ui/impl-trait/member-constraints/incomplete-constraint.rs create mode 100644 tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs create mode 100644 tests/ui/impl-trait/no-anonymize-regions.rs diff --git a/tests/ui/impl-trait/member-constraints/apply_member_constraint-no-req-eq.rs b/tests/ui/impl-trait/member-constraints/apply_member_constraint-no-req-eq.rs new file mode 100644 index 0000000000000..3aa52fe264472 --- /dev/null +++ b/tests/ui/impl-trait/member-constraints/apply_member_constraint-no-req-eq.rs @@ -0,0 +1,24 @@ +//@ check-pass +// FIXME(-Znext-solver): enable this test + +trait Id { + type This; +} +impl Id for T { + type This = T; +} + +// We have two member constraints here: +// +// - 'unconstrained member ['a, 'static] +// - 'unconstrained member ['static] +// +// Applying the first constraint results in `'unconstrained: 'a` +// while the second then adds `'unconstrained: 'static`. If applying +// member constraints were to require the member region equal to the +// choice region, applying the first constraint first and then the +// second would result in a `'a: 'static` requirement. +fn test<'a>() -> impl Id> + use<'a> { + &() +} +fn main() {} diff --git a/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs b/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs new file mode 100644 index 0000000000000..92fd31516d72d --- /dev/null +++ b/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs @@ -0,0 +1,21 @@ +//@ check-pass +// FIXME(-Znext-solver): enable this test + +// These functions currently does not normalize the opaque type but will do +// so in the future. At this point we've got a new use of the opaque will fully +// universal arguments but for which lifetimes in the hidden type are unconstrained. +// +// Applying the member constraints would then incompletely infer `'unconstrained` to `'static`. +fn new_defining_use R, T, R>(_: F) {} + +fn rpit1<'a, 'b: 'b>(x: &'b ()) -> impl Sized + use<'a, 'b> { + new_defining_use(rpit1::<'a, 'b>); + x +} + +struct Inv<'a, 'b>(*mut (&'a (), &'b ())); +fn rpit2<'a>(_: ()) -> impl Sized + use<'a> { + new_defining_use(rpit2::<'a>); + Inv::<'a, 'static>(std::ptr::null_mut()) +} +fn main() {} diff --git a/tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs b/tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs index 4633ad6823024..6860fc5e6a532 100644 --- a/tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs +++ b/tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs @@ -1,6 +1,7 @@ // Nested impl-traits can impose different member constraints on the same region variable. //@ check-pass +// FIXME(-Znext-solver): enable this test trait Cap<'a> {} impl Cap<'_> for T {} @@ -8,7 +9,9 @@ impl Cap<'_> for T {} // Assuming the hidden type is `[&'?15 u8; 1]`, we have two distinct member constraints: // - '?15 member ['static, 'a, 'b] // from outer impl-trait // - '?15 member ['static, 'a] // from inner impl-trait -// To satisfy both we can only choose 'a. +// To satisfy both we can only choose 'a. Concretely, first member constraint requires ?15 +// to outlive at least 'b while the second requires ?15 to outlive 'a. As 'a outlives 'b we +// end up with 'a as the final member region. fn pass_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator> + Cap<'b> where 's: 'a, diff --git a/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs b/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs new file mode 100644 index 0000000000000..4018256b2c84e --- /dev/null +++ b/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs @@ -0,0 +1,34 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// We've got `'0 member ['a, 'b, 'static]` and `'1 member ['a, 'b, 'static]`. +// +// As '0 gets outlived by 'a - its "upper bound" - the only applicable choice +// region is 'a. +// +// '1 has to outlive 'b so the only applicabel choice regions are 'b and 'static. +// Considering this member constraint by itself would choose 'b as it is the +// smaller of the two regions. +// +// However, this is only the case when ignoring the member constraint on '0. +// After applying this constraint and requiring '0 to outlive 'a. As '1 outlives +// '0, the region 'b is no longer an applicable choice region for '1 as 'b does +// does not outlive 'a. We would therefore choose 'static. +// +// This means applying member constraints is order dependent. We handle this by +// first applying member constraints for regions 'x and then consider the resulting +// constraints when applying member constraints for regions 'y with 'y: 'x. +fn with_constraints<'r0, 'r1, 'a, 'b>() -> *mut (&'r0 (), &'r1 ()) +where + 'r1: 'r0, + 'a: 'r0, + 'r1: 'b, +{ + loop {} +} +fn foo<'a, 'b>() -> impl Sized + use<'a, 'b> { + with_constraints::<'_, '_, 'a, 'b>() +} +fn main() {} diff --git a/tests/ui/impl-trait/no-anonymize-regions.rs b/tests/ui/impl-trait/no-anonymize-regions.rs new file mode 100644 index 0000000000000..4f7f7c0641c65 --- /dev/null +++ b/tests/ui/impl-trait/no-anonymize-regions.rs @@ -0,0 +1,18 @@ +//@ check-pass +// FIXME(-Znext-solver): enable this test + +// A regression test for an error in `redis` while working on #139587. +// +// We check for structural equality when adding defining uses of opaques. +// In this test one defining use had anonymized regions while the other +// one did not, causing an error. +struct W(T); +fn constrain R, T, R>(f: F) -> R { + loop {} +} +fn foo<'a>(x: for<'b> fn(&'b ())) -> impl Sized + use<'a> { + let mut r = constrain(foo::<'_>); + r = W(x); + r +} +fn main() {} From ac862c0ffb7b9df22b24603925ce299f8638b712 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 8 Aug 2025 13:49:27 +0200 Subject: [PATCH 3/3] fix typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rémy Rakic --- .../ui/impl-trait/member-constraints/incomplete-constraint.rs | 4 ++-- .../reject-choice-due-to-prev-constraint.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs b/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs index 92fd31516d72d..4c085cc1eedf8 100644 --- a/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs +++ b/tests/ui/impl-trait/member-constraints/incomplete-constraint.rs @@ -1,8 +1,8 @@ //@ check-pass // FIXME(-Znext-solver): enable this test -// These functions currently does not normalize the opaque type but will do -// so in the future. At this point we've got a new use of the opaque will fully +// These functions currently do not normalize the opaque type but will do +// so in the future. At this point we've got a new use of the opaque with fully // universal arguments but for which lifetimes in the hidden type are unconstrained. // // Applying the member constraints would then incompletely infer `'unconstrained` to `'static`. diff --git a/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs b/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs index 4018256b2c84e..33f2d277fe58c 100644 --- a/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs +++ b/tests/ui/impl-trait/member-constraints/reject-choice-due-to-prev-constraint.rs @@ -8,7 +8,7 @@ // As '0 gets outlived by 'a - its "upper bound" - the only applicable choice // region is 'a. // -// '1 has to outlive 'b so the only applicabel choice regions are 'b and 'static. +// '1 has to outlive 'b so the only applicable choice regions are 'b and 'static. // Considering this member constraint by itself would choose 'b as it is the // smaller of the two regions. //