-
Notifications
You must be signed in to change notification settings - Fork 13k
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 #113636 - compiler-errors:opaque-recursive-check-bad, r…
…=oli-obk Restrict recursive opaque type check We have a recursive opaque check in writeback to avoid inferring the hidden of an opaque type to be itself: https://github.com/rust-lang/rust/blob/33a2c2487ac5d9927830ea4c1844335c6b9f77db/compiler/rustc_hir_typeck/src/writeback.rs#L556-L575 Issue #113619 treats `make_option2` as not defining the TAIT `TestImpl` since it is inferred to have the definition `TestImpl := B<TestImpl>`, which fails this check. This regressed in #102700 (5d15beb), I think due to the refactoring that made us record the hidden types of TAITs during writeback. However, nothing actually seems to go bad if we relax this recursion checker to only check for directly recursive definitions. This PR fixes #113619 by changing this recursive check from being a visitor to just checking that the hidden type is exactly the same as the opaque being inferred. Alternatively, we may be able to fix #113619 by restricting this recursion check only to RPITs/async fns. It seems to only be possible to use misuse the recursion check to cause ICEs for TAITs (though I didn't try too hard to create a bad RPIT example... may be possible, actually.) r? `@oli-obk` -- Fixes #113314
- Loading branch information
Showing
5 changed files
with
87 additions
and
20 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
21 changes: 21 additions & 0 deletions
21
tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.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,21 @@ | ||
// issue: 113314 | ||
|
||
#![feature(type_alias_impl_trait)] | ||
|
||
type Op = impl std::fmt::Display; | ||
fn foo() -> Op { &"hello world" } | ||
|
||
fn transform<S>() -> impl std::fmt::Display { | ||
&0usize | ||
} | ||
fn bad() -> Op { | ||
transform::<Op>() | ||
//~^ ERROR concrete type differs from previous defining opaque type use | ||
} | ||
|
||
fn main() { | ||
let mut x = foo(); | ||
println!("{x}"); | ||
x = bad(); | ||
println!("{x}"); | ||
} |
14 changes: 14 additions & 0 deletions
14
tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.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,14 @@ | ||
error: concrete type differs from previous defining opaque type use | ||
--> $DIR/recursive-tait-conflicting-defn-2.rs:12:5 | ||
| | ||
LL | transform::<Op>() | ||
| ^^^^^^^^^^^^^^^^^ expected `&'static &'static str`, got `impl std::fmt::Display` | ||
| | ||
note: previous use here | ||
--> $DIR/recursive-tait-conflicting-defn-2.rs:6:18 | ||
| | ||
LL | fn foo() -> Op { &"hello world" } | ||
| ^^^^^^^^^^^^^^ | ||
|
||
error: aborting due to previous error | ||
|
34 changes: 34 additions & 0 deletions
34
tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.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,34 @@ | ||
// issue: 113596 | ||
|
||
#![feature(type_alias_impl_trait)] | ||
|
||
trait Test {} | ||
|
||
struct A; | ||
|
||
impl Test for A {} | ||
|
||
struct B<T> { | ||
inner: T, | ||
} | ||
|
||
impl<T: Test> Test for B<T> {} | ||
|
||
type TestImpl = impl Test; | ||
|
||
fn test() -> TestImpl { | ||
A | ||
} | ||
|
||
fn make_option() -> Option<TestImpl> { | ||
Some(test()) | ||
} | ||
|
||
fn make_option2() -> Option<TestImpl> { | ||
let inner = make_option().unwrap(); | ||
|
||
Some(B { inner }) | ||
//~^ ERROR concrete type differs from previous defining opaque type use | ||
} | ||
|
||
fn main() {} |
14 changes: 14 additions & 0 deletions
14
tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.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,14 @@ | ||
error: concrete type differs from previous defining opaque type use | ||
--> $DIR/recursive-tait-conflicting-defn.rs:30:3 | ||
| | ||
LL | Some(B { inner }) | ||
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>` | ||
| | ||
note: previous use here | ||
--> $DIR/recursive-tait-conflicting-defn.rs:20:3 | ||
| | ||
LL | A | ||
| ^ | ||
|
||
error: aborting due to previous error | ||
|