Skip to content

Commit 50ad4c8

Browse files
authored
Rollup merge of #145050 - lcnr:add-opaque-type-tests, r=lqd
add member constraints tests taken from #139587.
2 parents 2a7354e + ac862c0 commit 50ad4c8

10 files changed

+101
-1
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ check-pass
2+
// FIXME(-Znext-solver): enable this test
3+
4+
trait Id {
5+
type This;
6+
}
7+
impl<T> Id for T {
8+
type This = T;
9+
}
10+
11+
// We have two member constraints here:
12+
//
13+
// - 'unconstrained member ['a, 'static]
14+
// - 'unconstrained member ['static]
15+
//
16+
// Applying the first constraint results in `'unconstrained: 'a`
17+
// while the second then adds `'unconstrained: 'static`. If applying
18+
// member constraints were to require the member region equal to the
19+
// choice region, applying the first constraint first and then the
20+
// second would result in a `'a: 'static` requirement.
21+
fn test<'a>() -> impl Id<This = impl Sized + use<>> + use<'a> {
22+
&()
23+
}
24+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ check-pass
2+
// FIXME(-Znext-solver): enable this test
3+
4+
// These functions currently do not normalize the opaque type but will do
5+
// so in the future. At this point we've got a new use of the opaque with fully
6+
// universal arguments but for which lifetimes in the hidden type are unconstrained.
7+
//
8+
// Applying the member constraints would then incompletely infer `'unconstrained` to `'static`.
9+
fn new_defining_use<F: FnOnce(T) -> R, T, R>(_: F) {}
10+
11+
fn rpit1<'a, 'b: 'b>(x: &'b ()) -> impl Sized + use<'a, 'b> {
12+
new_defining_use(rpit1::<'a, 'b>);
13+
x
14+
}
15+
16+
struct Inv<'a, 'b>(*mut (&'a (), &'b ()));
17+
fn rpit2<'a>(_: ()) -> impl Sized + use<'a> {
18+
new_defining_use(rpit2::<'a>);
19+
Inv::<'a, 'static>(std::ptr::null_mut())
20+
}
21+
fn main() {}

tests/ui/nll/member-constraints/nested-impl-trait-pass.rs renamed to tests/ui/impl-trait/member-constraints/nested-impl-trait-pass.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
// Nested impl-traits can impose different member constraints on the same region variable.
22

33
//@ check-pass
4+
// FIXME(-Znext-solver): enable this test
45

56
trait Cap<'a> {}
67
impl<T> Cap<'_> for T {}
78

89
// Assuming the hidden type is `[&'?15 u8; 1]`, we have two distinct member constraints:
910
// - '?15 member ['static, 'a, 'b] // from outer impl-trait
1011
// - '?15 member ['static, 'a] // from inner impl-trait
11-
// To satisfy both we can only choose 'a.
12+
// To satisfy both we can only choose 'a. Concretely, first member constraint requires ?15
13+
// to outlive at least 'b while the second requires ?15 to outlive 'a. As 'a outlives 'b we
14+
// end up with 'a as the final member region.
1215
fn pass_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a>> + Cap<'b>
1316
where
1417
's: 'a,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@ check-pass
5+
6+
// We've got `'0 member ['a, 'b, 'static]` and `'1 member ['a, 'b, 'static]`.
7+
//
8+
// As '0 gets outlived by 'a - its "upper bound" - the only applicable choice
9+
// region is 'a.
10+
//
11+
// '1 has to outlive 'b so the only applicable choice regions are 'b and 'static.
12+
// Considering this member constraint by itself would choose 'b as it is the
13+
// smaller of the two regions.
14+
//
15+
// However, this is only the case when ignoring the member constraint on '0.
16+
// After applying this constraint and requiring '0 to outlive 'a. As '1 outlives
17+
// '0, the region 'b is no longer an applicable choice region for '1 as 'b does
18+
// does not outlive 'a. We would therefore choose 'static.
19+
//
20+
// This means applying member constraints is order dependent. We handle this by
21+
// first applying member constraints for regions 'x and then consider the resulting
22+
// constraints when applying member constraints for regions 'y with 'y: 'x.
23+
fn with_constraints<'r0, 'r1, 'a, 'b>() -> *mut (&'r0 (), &'r1 ())
24+
where
25+
'r1: 'r0,
26+
'a: 'r0,
27+
'r1: 'b,
28+
{
29+
loop {}
30+
}
31+
fn foo<'a, 'b>() -> impl Sized + use<'a, 'b> {
32+
with_constraints::<'_, '_, 'a, 'b>()
33+
}
34+
fn main() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-pass
2+
// FIXME(-Znext-solver): enable this test
3+
4+
// A regression test for an error in `redis` while working on #139587.
5+
//
6+
// We check for structural equality when adding defining uses of opaques.
7+
// In this test one defining use had anonymized regions while the other
8+
// one did not, causing an error.
9+
struct W<T>(T);
10+
fn constrain<F: FnOnce(T) -> R, T, R>(f: F) -> R {
11+
loop {}
12+
}
13+
fn foo<'a>(x: for<'b> fn(&'b ())) -> impl Sized + use<'a> {
14+
let mut r = constrain(foo::<'_>);
15+
r = W(x);
16+
r
17+
}
18+
fn main() {}

0 commit comments

Comments
 (0)