Skip to content

Cannot resolve TAIT when used with impl/dyn Trait inside RPIT #101750

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
Tracked by #5977
xxchan opened this issue Sep 13, 2022 · 12 comments · Fixed by #103704
Closed
Tracked by #5977

Cannot resolve TAIT when used with impl/dyn Trait inside RPIT #101750

xxchan opened this issue Sep 13, 2022 · 12 comments · Fixed by #103704
Assignees
Labels
C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]`

Comments

@xxchan
Copy link
Contributor

xxchan commented Sep 13, 2022

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 in nightly-2022-09-13
  • fn() -> Result<TAIT> works, and async 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
@xxchan xxchan added the C-bug Category: This is a bug. label Sep 13, 2022
@xxchan
Copy link
Contributor Author

xxchan commented Sep 13, 2022

@rustbot label F-type_alias_impl_trait

@xxchan
Copy link
Contributor Author

xxchan commented Sep 13, 2022

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

@xxchan
Copy link
Contributor Author

xxchan commented Sep 13, 2022

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))
// }

@xxchan xxchan changed the title Cannot resolve TAIT when used with async and Result Cannot resolve TAIT when used with async and impl/dyn Trait Sep 13, 2022
@xxchan
Copy link
Contributor Author

xxchan commented Sep 13, 2022

Caused by #99860

Any ideas? cc @oli-obk @compiler-errors

@xxchan
Copy link
Contributor Author

xxchan commented Sep 16, 2022

nightly-2022-05-24 also works (a version before #97346 which is reverted by #99860

@oli-obk
Copy link
Contributor

oli-obk commented Sep 16, 2022

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

@TennyZhuang
Copy link
Contributor

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))
}

@TennyZhuang
Copy link
Contributor

TennyZhuang commented Oct 7, 2022

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.

@xxchan xxchan changed the title Cannot resolve TAIT when used with async and impl/dyn Trait Cannot resolve TAIT when used with impl/dyn Trait inside RPIT Oct 7, 2022
@compiler-errors
Copy link
Member

I think @oli-obk fixed this (inadvertently?) in #102700

@xxchan
Copy link
Contributor Author

xxchan commented Oct 16, 2022

Just tested it and I can confirm it works now! Thanks!

BTW, what about adding this issue as a test cast?

@compiler-errors
Copy link
Member

Yes a minimized test PR would be appreciated.

@compiler-errors compiler-errors added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Oct 16, 2022
@xxchan
Copy link
Contributor Author

xxchan commented Oct 16, 2022

@rustbot claim

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]`
Development

Successfully merging a pull request may close this issue.

5 participants