Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Unification fails when type alias impl trait is used in non-return position #64445

Closed
jonhoo opened this issue Sep 13, 2019 · 12 comments
Closed
Labels
A-inference Area: Type inference A-typesystem Area: The type system C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jonhoo
Copy link
Contributor

jonhoo commented Sep 13, 2019

The following code fails to compile, but I believe this should be a supported use-case under rust-lang/rfcs#2515 (and #63063):

#![feature(type_alias_impl_trait)]
type X = impl Iterator<Item = u64> + Unpin;

struct Foo(X);
impl Foo {
    fn new(z: Vec<u64>) -> Self {
        Foo(z.into_iter())
    }
}

with

error[E0308]: mismatched types
  --> src/lib.rs:12:13
   |
12 |         Foo(z.into_iter())
   |             ^^^^^^^^^^^^^ expected opaque type, found struct `std::vec::IntoIter`
   |
   = note: expected type `X`
              found type `std::vec::IntoIter<u64>`

This code on the other hand works just fine with the above X:

fn foo(z: Vec<u64>) -> X {
    z.into_iter()
}

Including both Foo and foo in the same file still produces the same error, so foo does not "help" identify X.

@Centril Centril added C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-inference Area: Type inference labels Sep 14, 2019
@Centril
Copy link
Contributor

Centril commented Sep 14, 2019

I'm going to say this is a bug... @cramertj confirm?

@Centril Centril added the A-typesystem Area: The type system label Sep 14, 2019
@varkor
Copy link
Member

varkor commented Sep 16, 2019

I think the "defining uses" for TAIT are far too restrictive at the moment. I know that @alexreg was intending to look into similar issues.

@jonhoo
Copy link
Contributor Author

jonhoo commented Sep 16, 2019

This is also becoming increasingly common for people writing their own impl Future blocks as library authors move to async fn and -> impl Future functions (e.g., tokio::TcpStream::connect), since it is now impossible to name the return type so that it can be embedded in other (custom) futures. You can hack around it with Box or by adding generic parameters, but neither of those solutions are particularly attractive.

@cramertj
Copy link
Member

I'm going to say this is a bug... @cramertj confirm?

Yes, the current set of defining uses is significantly reduced from what is allowed by the RFC.

@alexreg
Copy link
Contributor

alexreg commented Sep 24, 2019

@varkor @cramertj I think we need a new summary-post (issue?) detailing the defining uses. I will expand it to consts/statics for sure, but within fn bodies is more subject to debate (and trickier to implement).

@cramertj
Copy link
Member

RFC 2071 specified that any unification site inside the module could count as a defining use.

@varkor
Copy link
Member

varkor commented Sep 24, 2019

As long as each use uniquely defines the underlying type, it should be permitted as a defining use. That's as I understand the intention, and the one that makes the most sense (one that albeit might be trickier to implement in some cases).

@alexreg
Copy link
Contributor

alexreg commented Sep 24, 2019

@varkor Yeah, it certainly will... I think I'm going to need some advice on how to implement it inside of bodies, in this case!

@varkor
Copy link
Member

varkor commented Sep 24, 2019

We can start with the easier cases, and then slowly address the remaining cases. Let's get consts and statics working first.

@clarfonthey
Copy link
Contributor

clarfonthey commented Oct 23, 2019

I think that the error I'm dealing with is also this. Example:

#![feature(type_alias_impl_trait)]
use core::iter::Map;

trait Thing {
    type Iter: Iterator<Item = u32>;
    fn do_thing(val: u32) -> u32;
}

type DoThing<T: Thing> = impl FnOnce(u32) -> u32;

struct ThingIter<T: Thing> {
    inner: Map<T::Iter, DoThing<T>>,
}

Playground link

@nikomatsakis
Copy link
Contributor

This should not be permitted under min_type_alias_impl_trait but is; filed #86732.

@oli-obk
Copy link
Contributor

oli-obk commented May 3, 2022

This is supported since #94081 and we have tests for it

@oli-obk oli-obk closed this as completed May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference A-typesystem Area: The type system C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Development

No branches or pull requests

9 participants