-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #103008 - aliemjay:opaque-parent-substs, r=oli-obk
replace ReErased with fresh region vars in opaque types See inline comments. Prior art #102943. cc ``@compiler-errors`` ``@oli-obk`` Fixes #100267 Fixes #101940 Fixes #102649 Fixes #102510
- Loading branch information
Showing
4 changed files
with
209 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// When WF checking the hidden type in the ParamEnv of the opaque type, | ||
// one complication arises when the hidden type is a closure/generator: | ||
// the "parent_substs" of the type may reference lifetime parameters | ||
// not present in the opaque type. | ||
// These region parameters are not really useful in this check. | ||
// So here we ignore them and replace them with fresh region variables. | ||
|
||
// check-pass | ||
|
||
#![feature(type_alias_impl_trait)] | ||
#![allow(dead_code)] | ||
|
||
// Basic test | ||
mod test1 { | ||
// Hidden type = Closure['_#0r] | ||
type Opaque = impl Sized; | ||
|
||
fn define<'a: 'a>() -> Opaque { | ||
|| {} | ||
} | ||
} | ||
|
||
// the region vars cannot both be equal to `'static` or `'empty` | ||
mod test2 { | ||
trait Trait {} | ||
|
||
// Hidden type = Closure['a, '_#0r, '_#1r] | ||
// Constraints = [('_#0r: 'a), ('a: '_#1r)] | ||
type Opaque<'a> | ||
where | ||
&'a (): Trait, | ||
= impl Sized + 'a; | ||
|
||
fn define<'a, 'x, 'y>() -> Opaque<'a> | ||
where | ||
&'a (): Trait, | ||
'x: 'a, | ||
'a: 'y, | ||
{ | ||
|| {} | ||
} | ||
} | ||
|
||
// the region var cannot be equal to `'a` or `'b` | ||
mod test3 { | ||
trait Trait {} | ||
|
||
// Hidden type = Closure['a, 'b, '_#0r] | ||
// Constraints = [('_#0r: 'a), ('_#0r: 'b)] | ||
type Opaque<'a, 'b> | ||
where | ||
(&'a (), &'b ()): Trait, | ||
= impl Sized + 'a + 'b; | ||
|
||
fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> | ||
where | ||
(&'a (), &'b ()): Trait, | ||
'x: 'a, | ||
'x: 'b, | ||
{ | ||
|| {} | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// If the hidden type is a closure, we require the "outlives" bounds that appear on the | ||
// defining site to also appear on the opaque type. | ||
// | ||
// It's not clear if this is the desired behavior but at least | ||
// it's consistent and has no back-compat risk. | ||
|
||
// check-fail | ||
|
||
#![feature(type_alias_impl_trait)] | ||
#![allow(dead_code)] | ||
|
||
// requires `'a: 'b` bound | ||
mod test1 { | ||
type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
//~^ ERROR lifetime bound not satisfied | ||
|
||
fn define<'a, 'b>() -> Opaque<'a, 'b> | ||
where | ||
'a: 'b, | ||
{ | ||
|| {} | ||
} | ||
} | ||
|
||
// Same as the above but through indirection `'x` | ||
mod test2 { | ||
type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
//~^ ERROR cannot infer an appropriate lifetime | ||
|
||
fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> | ||
where | ||
'a: 'x, | ||
'x: 'b, | ||
{ | ||
|| {} | ||
} | ||
} | ||
|
||
// fixed version of the above | ||
mod test2_fixed { | ||
type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b; | ||
|
||
fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> | ||
where | ||
'a: 'x, | ||
'x: 'b, | ||
{ | ||
|| {} | ||
} | ||
} | ||
|
||
// requires `T: 'static` | ||
mod test3 { | ||
type Opaque<T> = impl Sized; | ||
//~^ ERROR the parameter type `T` may not live long enough | ||
|
||
fn define<T>() -> Opaque<T> | ||
where | ||
T: 'static, | ||
{ | ||
|| {} | ||
} | ||
} | ||
|
||
fn main() {} |
64 changes: 64 additions & 0 deletions
64
src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
error[E0478]: lifetime bound not satisfied | ||
--> $DIR/closure_wf_outlives.rs:14:27 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
note: lifetime parameter instantiated with the lifetime `'a` as defined here | ||
--> $DIR/closure_wf_outlives.rs:14:17 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^ | ||
note: but lifetime parameter must outlive the lifetime `'b` as defined here | ||
--> $DIR/closure_wf_outlives.rs:14:21 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^ | ||
|
||
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements | ||
--> $DIR/closure_wf_outlives.rs:27:27 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
note: first, the lifetime cannot outlive the lifetime `'a` as defined here... | ||
--> $DIR/closure_wf_outlives.rs:27:17 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^ | ||
note: ...so that the declared lifetime parameter bounds are satisfied | ||
--> $DIR/closure_wf_outlives.rs:27:27 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
note: but, the lifetime must be valid for the lifetime `'b` as defined here... | ||
--> $DIR/closure_wf_outlives.rs:27:21 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^ | ||
note: ...so that the declared lifetime parameter bounds are satisfied | ||
--> $DIR/closure_wf_outlives.rs:27:27 | ||
| | ||
LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error[E0310]: the parameter type `T` may not live long enough | ||
--> $DIR/closure_wf_outlives.rs:54:22 | ||
| | ||
LL | type Opaque<T> = impl Sized; | ||
| ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... | ||
| | ||
note: ...that is required by this bound | ||
--> $DIR/closure_wf_outlives.rs:59:12 | ||
| | ||
LL | T: 'static, | ||
| ^^^^^^^ | ||
help: consider adding an explicit lifetime bound... | ||
| | ||
LL | type Opaque<T: 'static> = impl Sized; | ||
| +++++++++ | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
Some errors have detailed explanations: E0310, E0478, E0495. | ||
For more information about an error, try `rustc --explain E0310`. |