Skip to content

Commit 66bd645

Browse files
aliemjayoli-obk
authored andcommitted
test that we do not support higher-ranked regions in opaque type inference
1 parent 31478cd commit 66bd645

6 files changed

+292
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Regression test for #97099.
2+
// This was an ICE because `impl Sized` captures the lifetime 'a.
3+
4+
// check-fail
5+
6+
trait Trait<E> {
7+
type Assoc;
8+
}
9+
10+
struct Foo;
11+
12+
impl<'a> Trait<&'a ()> for Foo {
13+
type Assoc = ();
14+
}
15+
16+
fn foo() -> impl for<'a> Trait<&'a ()> {
17+
Foo
18+
}
19+
20+
fn bar() -> impl for<'a> Trait<&'a (), Assoc = impl Sized> {
21+
foo()
22+
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
23+
}
24+
25+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
2+
--> $DIR/higher-ranked-regions-diag.rs:21:5
3+
|
4+
LL | fn bar() -> impl for<'a> Trait<&'a (), Assoc = impl Sized> {
5+
| -- ---------- opaque type defined here
6+
| |
7+
| hidden type `<impl for<'a> Trait<&'a ()> as Trait<&'a ()>>::Assoc` captures the lifetime `'a` as defined here
8+
LL | foo()
9+
| ^^^^^
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0700`.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Basic tests for opaque type inference under for<_> binders.
2+
3+
// check-fail
4+
5+
#![feature(type_alias_impl_trait)]
6+
7+
trait Trait<'a> {
8+
type Ty;
9+
}
10+
impl<'a, T> Trait<'a> for T {
11+
type Ty = &'a ();
12+
}
13+
14+
mod basic_pass {
15+
use super::*;
16+
type Opq<'a> = impl Sized + 'a;
17+
fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {}
18+
//~^ ERROR: expected generic lifetime parameter, found `'a`
19+
}
20+
21+
mod capture_rpit {
22+
use super::*;
23+
fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {}
24+
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
25+
}
26+
27+
mod capture_tait {
28+
use super::*;
29+
type Opq0 = impl Sized;
30+
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>;
31+
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
32+
fn test() -> Opq2 {}
33+
//~^ ERROR hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds
34+
}
35+
36+
mod capture_tait_complex_pass {
37+
use super::*;
38+
type Opq0<'a> = impl Sized;
39+
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
40+
//~^ ERROR: concrete type differs from previous defining opaque type use
41+
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
42+
fn test() -> Opq2 {}
43+
//~^ ERROR: expected generic lifetime parameter, found `'a`
44+
}
45+
46+
// Same as the above, but make sure that different placeholder regions are not equal.
47+
mod capture_tait_complex_fail {
48+
use super::*;
49+
type Opq0<'a> = impl Sized;
50+
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a
51+
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
52+
fn test() -> Opq2 {}
53+
//~^ ERROR hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds
54+
}
55+
56+
// non-defining use because 'static is used.
57+
mod constrain_fail0 {
58+
use super::*;
59+
type Opq0<'a, 'b> = impl Sized;
60+
fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
61+
//~^ ERROR non-defining opaque type use in defining scope
62+
//~| ERROR: expected generic lifetime parameter, found `'a`
63+
}
64+
65+
// non-defining use because generic lifetime is used multiple times.
66+
mod constrain_fail {
67+
use super::*;
68+
type Opq0<'a, 'b> = impl Sized;
69+
fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
70+
//~^ ERROR non-defining opaque type use in defining scope
71+
//~| ERROR: expected generic lifetime parameter, found `'a`
72+
}
73+
74+
mod constrain_pass {
75+
use super::*;
76+
type Opq0<'a, 'b> = impl Sized;
77+
type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
78+
//~^ ERROR concrete type differs
79+
type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
80+
fn test() -> Opq2 {}
81+
//~^ ERROR: expected generic lifetime parameter, found `'a`
82+
}
83+
84+
fn main() {}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
error[E0792]: expected generic lifetime parameter, found `'a`
2+
--> $DIR/higher-ranked-regions-basic.rs:17:55
3+
|
4+
LL | type Opq<'a> = impl Sized + 'a;
5+
| -- this generic parameter must be used with a generic lifetime parameter
6+
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {}
7+
| ^^
8+
9+
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
10+
--> $DIR/higher-ranked-regions-basic.rs:23:58
11+
|
12+
LL | fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {}
13+
| -- ---------- ^^
14+
| | |
15+
| | opaque type defined here
16+
| hidden type `&'a ()` captures the lifetime `'a` as defined here
17+
18+
error[E0700]: hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds
19+
--> $DIR/higher-ranked-regions-basic.rs:32:23
20+
|
21+
LL | type Opq0 = impl Sized;
22+
| ---------- opaque type defined here
23+
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>;
24+
| -- hidden type `&'b ()` captures the lifetime `'b` as defined here
25+
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
26+
LL | fn test() -> Opq2 {}
27+
| ^^
28+
29+
error[E0792]: expected generic lifetime parameter, found `'a`
30+
--> $DIR/higher-ranked-regions-basic.rs:42:23
31+
|
32+
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
33+
| -- this generic parameter must be used with a generic lifetime parameter
34+
...
35+
LL | fn test() -> Opq2 {}
36+
| ^^
37+
38+
error: concrete type differs from previous defining opaque type use
39+
--> $DIR/higher-ranked-regions-basic.rs:39:21
40+
|
41+
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
42+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a ()`, got `{type error}`
43+
|
44+
note: previous use here
45+
--> $DIR/higher-ranked-regions-basic.rs:41:17
46+
|
47+
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
48+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49+
50+
error[E0700]: hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds
51+
--> $DIR/higher-ranked-regions-basic.rs:52:23
52+
|
53+
LL | type Opq0<'a> = impl Sized;
54+
| ---------- opaque type defined here
55+
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a
56+
| -- hidden type `&'b ()` captures the lifetime `'b` as defined here
57+
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
58+
LL | fn test() -> Opq2 {}
59+
| ^^
60+
61+
error[E0792]: non-defining opaque type use in defining scope
62+
--> $DIR/higher-ranked-regions-basic.rs:60:41
63+
|
64+
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
65+
| ^^^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter
66+
|
67+
note: for this opaque type
68+
--> $DIR/higher-ranked-regions-basic.rs:59:25
69+
|
70+
LL | type Opq0<'a, 'b> = impl Sized;
71+
| ^^^^^^^^^^
72+
73+
error[E0792]: expected generic lifetime parameter, found `'a`
74+
--> $DIR/higher-ranked-regions-basic.rs:60:65
75+
|
76+
LL | type Opq0<'a, 'b> = impl Sized;
77+
| -- this generic parameter must be used with a generic lifetime parameter
78+
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
79+
| ^^
80+
81+
error: non-defining opaque type use in defining scope
82+
--> $DIR/higher-ranked-regions-basic.rs:69:41
83+
|
84+
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
85+
| ^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
86+
|
87+
note: for this opaque type
88+
--> $DIR/higher-ranked-regions-basic.rs:68:25
89+
|
90+
LL | type Opq0<'a, 'b> = impl Sized;
91+
| ^^^^^^^^^^
92+
93+
error[E0792]: expected generic lifetime parameter, found `'a`
94+
--> $DIR/higher-ranked-regions-basic.rs:69:60
95+
|
96+
LL | type Opq0<'a, 'b> = impl Sized;
97+
| -- this generic parameter must be used with a generic lifetime parameter
98+
LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
99+
| ^^
100+
101+
error[E0792]: expected generic lifetime parameter, found `'a`
102+
--> $DIR/higher-ranked-regions-basic.rs:80:23
103+
|
104+
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
105+
| -- this generic parameter must be used with a generic lifetime parameter
106+
...
107+
LL | fn test() -> Opq2 {}
108+
| ^^
109+
110+
error: concrete type differs from previous defining opaque type use
111+
--> $DIR/higher-ranked-regions-basic.rs:77:21
112+
|
113+
LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
114+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a ()`, got `{type error}`
115+
|
116+
note: previous use here
117+
--> $DIR/higher-ranked-regions-basic.rs:79:17
118+
|
119+
LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
120+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
121+
122+
error: aborting due to 12 previous errors
123+
124+
Some errors have detailed explanations: E0700, E0792.
125+
For more information about an error, try `rustc --explain E0700`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Regression test for #97098.
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
pub trait Trait {
6+
type Assoc<'a>;
7+
}
8+
9+
pub type Foo = impl for<'a> Trait<Assoc<'a> = FooAssoc<'a>>;
10+
pub type FooAssoc<'a> = impl Sized;
11+
//~^ ERROR: concrete type differs from previous defining opaque type use
12+
13+
struct Struct;
14+
impl Trait for Struct {
15+
type Assoc<'a> = &'a u32;
16+
}
17+
18+
const FOO: Foo = Struct;
19+
//~^ ERROR: expected generic lifetime parameter, found `'a`
20+
21+
fn main() {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0792]: expected generic lifetime parameter, found `'a`
2+
--> $DIR/higher-ranked-regions-gat.rs:18:18
3+
|
4+
LL | pub type FooAssoc<'a> = impl Sized;
5+
| -- this generic parameter must be used with a generic lifetime parameter
6+
...
7+
LL | const FOO: Foo = Struct;
8+
| ^^^^^^
9+
10+
error: concrete type differs from previous defining opaque type use
11+
--> $DIR/higher-ranked-regions-gat.rs:10:25
12+
|
13+
LL | pub type FooAssoc<'a> = impl Sized;
14+
| ^^^^^^^^^^ expected `&'a u32`, got `{type error}`
15+
|
16+
note: previous use here
17+
--> $DIR/higher-ranked-regions-gat.rs:9:16
18+
|
19+
LL | pub type Foo = impl for<'a> Trait<Assoc<'a> = FooAssoc<'a>>;
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
22+
error: aborting due to 2 previous errors
23+
24+
For more information about this error, try `rustc --explain E0792`.

0 commit comments

Comments
 (0)