forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#112842 - lcnr:non-defining-use, r=oli-obk
check for non-defining uses of RPIT This PR requires defining uses of RPIT and the async functions return type to use unique generic parameters as type and const arguments, (mostly) fixing rust-lang#111935. This changes the following snippet to an error (it compiled since 1.62): ```rust fn foo<T>() -> impl Sized { let _: () = foo::<u8>(); //~ ERROR non-defining use of `impl Sized` } ``` Since 1.62 we only checked that the generic arguments of opaque types are unique parameters for TAIT and ignored RPITs, so this PR changes the behavior here to be consistent. For defining uses which do not have unique params as arguments it is unclear how the hidden type should map to the generic params of the opaque. In the following snippet, should the hidden type of `foo<T>::opaque` be `T` or `u32`. ```rust fn foo<T>() -> impl Sized { let _: u32 = foo::<u32>(); foo::<T>() } ``` There are no crater regressions caused by this change. --- The same issue exists for lifetime arguments which is not fixed by this PR, currently resulting in an ICE in mir borrowck (I wasn't able to get an example which didn't ICE, it might be possible): ```rust fn foo<'a: 'a>() -> impl Sized { let _: &'static () = foo::<'static>(); //~^ ICE opaque type with non-universal region substs foo::<'a>() } ``` Fixing this for lifetimes as well is blocked on rust-lang#113916. Due to this issue, functions returning an RPIT with lifetime parameters equal in the region constraint graph would always result in an error, resulting in breakage found via crater: rust-lang#112842 (comment) ```rust trait Trait<'a, 'b> {} impl Trait<'_, '_> for () {} struct Type<'a>(&'a ()); impl<'a> Type<'a> { // `'b == 'a` fn do_stuff<'b: 'a>(&'b self) -> impl Trait<'a, 'b> { // This fails as long there is something in the body // which adds the outlives constraints to the constraint graph. // // This is the case for nested closures. (|| ())() } } ```
- Loading branch information
Showing
8 changed files
with
109 additions
and
37 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
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
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 |
---|---|---|
@@ -1,14 +1,24 @@ | ||
error[E0792]: expected generic type parameter, found `i32` | ||
--> $DIR/issue-99073-2.rs:9:22 | ||
| | ||
LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display { | ||
| - this generic parameter must be used with a generic type parameter | ||
LL | let f = || { | ||
LL | let i: u32 = test::<i32>(-1, false); | ||
| ^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: concrete type differs from previous defining opaque type use | ||
--> $DIR/issue-99073-2.rs:9:22 | ||
| | ||
LL | let i: u32 = test::<i32>(-1, false); | ||
| ^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `u32` | ||
| | ||
note: previous use here | ||
--> $DIR/issue-99073-2.rs:16:5 | ||
--> $DIR/issue-99073-2.rs:7:45 | ||
| | ||
LL | t | ||
| ^ | ||
LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display { | ||
| ^^^^^^^^^^^^ | ||
|
||
error: aborting due to previous error | ||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0792`. |
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
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 |
---|---|---|
@@ -1,14 +1,23 @@ | ||
error: concrete type differs from previous defining opaque type use | ||
error[E0792]: expected generic type parameter, found `&F` | ||
--> $DIR/issue-99073.rs:6:11 | ||
| | ||
LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() { | ||
| - this generic parameter must be used with a generic type parameter | ||
LL | move || f(fix(&f)) | ||
| ^^^^^^^^^^ | ||
|
||
error: concrete type differs from previous defining opaque type use | ||
--> $DIR/issue-99073.rs:6:13 | ||
| | ||
LL | move || f(fix(&f)) | ||
| ^^^^^^^^^^ expected `[closure@$DIR/issue-99073.rs:6:3: 6:10]`, got `G` | ||
| ^^^^^^^ expected `[closure@$DIR/issue-99073.rs:6:3: 6:10]`, got `G` | ||
| | ||
note: previous use here | ||
--> $DIR/issue-99073.rs:6:3 | ||
--> $DIR/issue-99073.rs:5:36 | ||
| | ||
LL | move || f(fix(&f)) | ||
| ^^^^^^^^^^^^^^^^^^ | ||
LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() { | ||
| ^^^^^^^^^ | ||
|
||
error: aborting due to previous error | ||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0792`. |
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,19 @@ | ||
// check-pass | ||
|
||
// related to #113916, check that using RPITs in functions with lifetime params | ||
// which are constrained to be equal compiles. | ||
|
||
trait Trait<'a, 'b> {} | ||
impl Trait<'_, '_> for () {} | ||
fn pass<'a: 'b, 'b: 'a>() -> impl Trait<'a, 'b> { | ||
(|| {})() | ||
} | ||
|
||
struct Foo<'a>(&'a ()); | ||
impl<'a> Foo<'a> { | ||
fn bar<'b: 'a>(&'b self) -> impl Trait<'a, 'b> { | ||
let _: &'a &'b &'a (); | ||
} | ||
} | ||
|
||
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,14 @@ | ||
// Regression test for #111935 that non-defining uses of RPIT result in errors | ||
#![allow(unconditional_recursion)] | ||
fn foo<T>() -> impl Sized { | ||
let _: () = foo::<u8>(); //~ ERROR expected generic type parameter, found `u8` | ||
} | ||
|
||
fn bar<T>(val: T) -> impl Sized { | ||
let _: u8 = bar(0u8); | ||
//~^ ERROR concrete type differs from previous defining opaque type use | ||
//~| ERROR expected generic type parameter, found `u8` | ||
val | ||
} | ||
|
||
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,31 @@ | ||
error[E0792]: expected generic type parameter, found `u8` | ||
--> $DIR/non-defining-use.rs:4:12 | ||
| | ||
LL | fn foo<T>() -> impl Sized { | ||
| - this generic parameter must be used with a generic type parameter | ||
LL | let _: () = foo::<u8>(); | ||
| ^^ | ||
|
||
error[E0792]: expected generic type parameter, found `u8` | ||
--> $DIR/non-defining-use.rs:8:12 | ||
| | ||
LL | fn bar<T>(val: T) -> impl Sized { | ||
| - this generic parameter must be used with a generic type parameter | ||
LL | let _: u8 = bar(0u8); | ||
| ^^ | ||
|
||
error: concrete type differs from previous defining opaque type use | ||
--> $DIR/non-defining-use.rs:8:17 | ||
| | ||
LL | let _: u8 = bar(0u8); | ||
| ^^^^^^^^ expected `T`, got `u8` | ||
| | ||
note: previous use here | ||
--> $DIR/non-defining-use.rs:7:22 | ||
| | ||
LL | fn bar<T>(val: T) -> impl Sized { | ||
| ^^^^^^^^^^ | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0792`. |