rust
rust copied to clipboard
Cannot resolve TAIT when used with impl/dyn Trait inside RPIT
The condition seems complex, but a practical instance is async fn foo() -> Result<TAIT>
I tried this code:
#![feature(type_alias_impl_trait)]
trait Trait {}
type TAIT = impl Trait;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
fn foo() -> TAIT {
struct Bar;
impl Trait for Bar {}
Bar
}
async fn bar() -> Result<TAIT> {
Ok(foo())
}
I expected to see this happen: it compiles
Instead, this happened: error:
error: concrete type differs from previous defining opaque type use
--> src/tmp.rs:15:32
|
15 | async fn bar() -> Result<TAIT> {
| ________________________________^
16 | | Ok(foo())
17 | | }
| |_^ expected `Bar`, got `TAIT`
|
note: previous use here
--> src/tmp.rs:12:5
|
12 | Bar
| ^^^
Notes:
- It compiles in
nightly-2022-08-12, but failed innightly-2022-09-13 fn() -> Result<TAIT>works, andasync fn() -> Option<TAIT>works
Meta
rustc --version --verbose:
rustc 1.65.0-nightly (fa6ee9375 2022-09-12)
binary: rustc
commit-hash: fa6ee9375242ae784dab1837dfc0b92f43e787ce
commit-date: 2022-09-12
host: aarch64-apple-darwin
release: 1.65.0-nightly
LLVM version: 15.0.0
@rustbot label F-type_alias_impl_trait
nightly-2022-08-18 works, and nightly-2022-08-19 breaks
https://github.com/rust-lang/rust/commits/master?since=2022-08-18&until=2022-08-18
trait Trait {}
type TAIT = impl Trait;
struct Bar;
impl Trait for Bar {}
fn foo() -> TAIT {
Bar
}
// ok
async fn bar() -> (TAIT, Bar) {
(foo(), Bar)
}
// err: concrete type differs
// async fn bar() -> (TAIT, impl Trait) {
// (foo(), Bar)
// }
// err: concrete type differs
// async fn bar() -> (TAIT, Box<dyn Trait>) {
// (foo(), Box::new(Bar))
// }
Caused by https://github.com/rust-lang/rust/pull/99860
Any ideas? cc @oli-obk @compiler-errors
nightly-2022-05-24 also works (a version before #97346 which is reverted by #99860
TAIT and RPIT were made to work the same in the revert, thus TAIT was changed from before #97346 instead of just reverting to the old behaviour.
I will need to look at some typeck logs to see what's goin on here
FYI, it seems that the bug is not related to async but to every nested impl trait.
// err: concrete type differs
fn bar() -> impl Iterator<Item = (TAIT, impl Trait)> {
std::iter::once((foo(), Bar))
}
I've tested with the following codes:
#![feature(type_alias_impl_trait)]
trait Trait {}
type TAIT = impl Trait;
struct Bar;
impl Trait for Bar {}
fn foo() -> TAIT {
Bar
}
fn haha() -> (impl Iterator<Item = TAIT>, impl Trait) {
(std::iter::empty::<Bar>(), Bar)
}
fn bar() -> impl Iterator<Item = (TAIT, impl Trait)> {
std::iter::once((foo(), Bar))
}
It seems that the result of mir_borrowck for bar is wrong:
│ │ │ ├─106ms DEBUG rustc_borrowck do_mir_borrowck: result = BorrowCheckResult {
│ │ │ │ concrete_opaque_types: VecMap(
│ │ │ │ [
│ │ │ │ (
│ │ │ │ DefId(0:13 ~ lib[af95]::bar::{opaque#0}),
│ │ │ │ OpaqueHiddenType {
│ │ │ │ span: ../playground/tait-bug/src/lib.rs:19:5: 19:34 (#0),
│ │ │ │ ty: std::iter::Once<(TAIT, Bar)>,
│ │ │ │ },
│ │ │ │ ),
│ │ │ │ (
│ │ │ │ DefId(0:11 ~ lib[af95]::TAIT::{opaque#0}),
│ │ │ │ OpaqueHiddenType {
│ │ │ │ span: ../playground/tait-bug/src/lib.rs:19:5: 19:34 (#0),
│ │ │ │ ty: TAIT,
│ │ │ │ },
│ │ │ │ ),
│ │ │ │ (
│ │ │ │ DefId(0:14 ~ lib[af95]::bar::{opaque#1}),
│ │ │ │ OpaqueHiddenType {
│ │ │ │ span: ../playground/tait-bug/src/lib.rs:19:5: 19:34 (#0),
│ │ │ │ ty: Bar,
│ │ │ │ },
│ │ │ │ ),
│ │ │ │ ],
│ │ │ │ ),
│ │ │ │ closure_requirements: None,
│ │ │ │ used_mut_upvars: [],
│ │ │ │ tainted_by_errors: None,
│ │ │ │ }
It seems that 0:11 wasn't be resolved correctly.
I think @oli-obk fixed this (inadvertently?) in #102700
Just tested it and I can confirm it works now! Thanks!
BTW, what about adding this issue as a test cast?
Yes a minimized test PR would be appreciated.
@rustbot claim