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

TAIT: Compiler struggles to infer the type #101897

Open
toiglak opened this issue Sep 16, 2022 · 2 comments
Open

TAIT: Compiler struggles to infer the type #101897

toiglak opened this issue Sep 16, 2022 · 2 comments
Labels
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. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@toiglak
Copy link

toiglak commented Sep 16, 2022

I tried this code:

#![feature(type_alias_impl_trait)]

trait Foo {}

impl<T: Foo> Foo for &T {}

trait Bar {
    // I need this associated type to be implemented separately.
    // This is why I didn't put it inside `Baz` definition.
    type Bar<'a>: Foo;
}

trait Baz: Bar {
    fn baz<'a>(&'a self) -> Self::Bar<'a>;
}

// Problem:

struct Qux<T: Foo> {
    field: T,
}

impl<T: Foo> Bar for Qux<T> {
    type Bar<'a> = impl Foo + 'a; // Error: unconstrained opaque type.
                                  // `Bar` must be used in combination with a concrete type within
                                  // the same module.
}

impl<T: Foo> Baz for Qux<T> {
    fn baz<'a>(&'a self) -> Self::Bar<'a> {
        &self.field // Error: expected opaque type `<Qux<T> as Bar>::Bar<'a>`.
                    //        found reference `&T`
    }
}

fn main() {}

I got the exact errors visible in the comments.
I expected this to compile, but it didn't.

I found a following workaround:

trait Bar {
    type Bar<'a>: Foo where Self: 'a; // <--
}

// ...

struct Qux<T: Foo> {
    field: T,
}

type Temp<'a, T: Foo + 'a> = impl Foo + 'a; // <--

impl<T: Foo> Bar for Qux<T> {
    type Bar<'a> = Temp<'a, T> where Self : 'a; // <--
}

impl<T: Foo> Baz for Qux<T> {
    fn baz<'a>(&'a self) -> Self::Bar<'a> {
        &self.field
    }
}

Meta

rustc --version --verbose:

rustc 1.65.0-nightly (cf9ed0dd5 2022-09-15)
binary: rustc
commit-hash: cf9ed0dd5836201843d28bbad50abfbe1913af2a
commit-date: 2022-09-15
host: aarch64-apple-darwin
release: 1.65.0-nightly
LLVM version: 15.0.0
@toiglak toiglak added the C-bug Category: This is a bug. label Sep 16, 2022
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Oct 28, 2022
Note scope of TAIT more accurately

This maybe explains why the person was confused in rust-lang#101897, since we say "same module" but really should've said "same impl".

r? `@oli-obk`
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Oct 28, 2022
Note scope of TAIT more accurately

This maybe explains why the person was confused in rust-lang#101897, since we say "same module" but really should've said "same impl".

r? ``@oli-obk``
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 29, 2022
Note scope of TAIT more accurately

This maybe explains why the person was confused in rust-lang#101897, since we say "same module" but really should've said "same impl".

r? `@oli-obk`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 29, 2022
Note scope of TAIT more accurately

This maybe explains why the person was confused in rust-lang#101897, since we say "same module" but really should've said "same impl".

r? ``@oli-obk``
@jplatte
Copy link
Contributor

jplatte commented Oct 30, 2022

@rustbot label F-type_alias_impl_trait T-compiler T-types

@rustbot rustbot added 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. T-types Relevant to the types team, which will review and decide on the PR/issue. labels Oct 30, 2022
@oli-obk
Copy link
Contributor

oli-obk commented Oct 30, 2022

Yea... this is mostly expected. The impl Trait is inside one impl, and only that impl can constrain it.

I think we could allow impls for traits to restrict opaque types from supertrait's impls in the same crate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
Status: Can do after stabilization
Development

No branches or pull requests

4 participants