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

GAT & TAIT with lifetime type parameters fail std::marker::Sized requirement #89008

Closed
rustrial opened this issue Sep 16, 2021 · 8 comments · Fixed by #103335
Closed

GAT & TAIT with lifetime type parameters fail std::marker::Sized requirement #89008

rustrial opened this issue Sep 16, 2021 · 8 comments · Fixed by #103335
Labels
A-GATs Area: Generic associated types (GATs) 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-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` GATs-triaged Issues using the `generic_associated_types` feature that have been triaged S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test.

Comments

@rustrial
Copy link

rustrial commented Sep 16, 2021

Playing around with (the not yet stable) GAT and TAIT features I stumbled over the below problem, where type parameters to nested TAIT/GAT with lifetime parameters cause a "this type parameter needs to be std::marker::Sized" compiler error.

The following code fails to compile with below compiler error (Playground):

#![feature(type_alias_impl_trait)]
#![feature(generic_associated_types)]

extern crate futures;
use futures::Stream;
use std::future::Future;

trait X {
    type LineStream<'a, Repr>: Stream<Item = Repr> where Self: 'a;

    type LineStreamFut<'a,Repr>: Future<Output = Self::LineStream<'a, Repr>> where Self: 'a;

    fn line_stream<'a,Repr>(&'a self) -> Self::LineStreamFut<'a,Repr>;
}

struct Y;

impl X for Y {
    type LineStream<'a, Repr> = impl Stream<Item = Repr>;

    type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>> ;

    fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
        async {futures::stream::empty()}
    }
}

fn main() {}
warning: the cargo feature `edition2021` has been stabilized in the 1.56 release and is no longer necessary to be listed in the manifest
  See https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-edition-field for more information about using this feature.
   Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `Repr` cannot be known at compilation time
  --> src/main.rs:23:43
   |
23 |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
   |                        ----               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |                        |
   |                        this type parameter needs to be `std::marker::Sized`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error

In contrast, the following code, without lifetime type parameters compiles without any error.

#![feature(type_alias_impl_trait)]
#![feature(generic_associated_types)]

extern crate futures;
use futures::Stream;
use std::future::Future;

trait X {
    type LineStream<Repr>: Stream<Item = Repr>;

    type LineStreamFut<Repr>: Future<Output = Self::LineStream<Repr>>;

    fn line_stream<Repr>(&self) -> Self::LineStreamFut<Repr>;
}

struct Y;

impl X for Y {
    type LineStream<Repr> = impl Stream<Item = Repr>;

    type LineStreamFut<Repr> = impl Future<Output = Self::LineStream<Repr>> ;

    fn line_stream<Repr>(&self) -> Self::LineStreamFut<Repr> {
        async {futures::stream::empty()}
    }
}

fn main() {}

Meta

cargo version --verbose:

cargo 1.56.0-nightly (e515c3277 2021-09-08)
release: 1.56.0
commit-hash: e515c3277bf0681bfc79a9e763861bfe26bb05db
commit-date: 2021-09-08
@rustrial rustrial added the C-bug Category: This is a bug. label Sep 16, 2021
@jackh726 jackh726 added F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` labels Sep 16, 2021
@jackh726
Copy link
Member

This gives a different error. Minimized:

#![feature(type_alias_impl_trait)]
#![feature(generic_associated_types)]

use std::future::Future;
use std::marker::PhantomData;

pub trait Stream {
    type Item;
}

trait X {
    type LineStream<'a, Repr>: Stream<Item = Repr> where Self: 'a;
    type LineStreamFut<'a, Repr>: Future<Output = Self::LineStream<'a, Repr>> where Self: 'a;
    fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr>;
}

struct Y;

impl X for Y {
    type LineStream<'a, Repr> = impl Stream<Item = Repr>;
    type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
    fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
        async { Empty { _phantom: PhantomData } }
    }
}

pub struct Empty<T> {
    _phantom: PhantomData<T>,
}

impl<T> Stream for Empty<T> {
    type Item = T;
}

fn main() {}
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == impl Stream`
  --> src/main.rs:22:43
   |
20 |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
   |                                 ------------------------ the expected opaque type
21 |     type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
22 |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found struct `Empty`
   |
   = note: expected opaque type `impl Stream`
                   found struct `Empty<_>`

@jackh726
Copy link
Member

GATs issue triage: not blocking. Seems like a TAITs bug; not sure there's anything for GATs to change here.

@jackh726 jackh726 added the GATs-triaged Issues using the `generic_associated_types` feature that have been triaged label Oct 23, 2021
@jackh726 jackh726 added the S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. label Mar 12, 2022
@oli-obk
Copy link
Contributor

oli-obk commented May 3, 2022

Compiles just fine now.

@oli-obk
Copy link
Contributor

oli-obk commented May 3, 2022

@jackh726 I guess this issue can just be closed if there's a test already?

@jackh726
Copy link
Member

jackh726 commented May 3, 2022

I think test needs to be moved to correct place?

@oli-obk oli-obk added the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Sep 9, 2022
@SarthakSingh31
Copy link
Contributor

Hello, first time contributing to rust. I was trying to resolve this issue and after looking at the test I am a little confused. To me it looks like the test code is failing correctly and I can't understand where the TAIT bug is.

// check-fail
// edition:2021
// known-bug: #88908
// This should pass, but seems to run into a TAIT bug.
#![feature(type_alias_impl_trait)]
use std::future::Future;
trait Stream {
type Item;
}
struct Empty<T>(T);
impl<T> Stream for Empty<T> {
type Item = ();
}
fn empty<T>() -> Empty<T> {
todo!()
}
trait X {
type LineStream<'a, Repr>: Stream<Item = Repr> where Self: 'a;
type LineStreamFut<'a,Repr>: Future<Output = Self::LineStream<'a, Repr>> where Self: 'a;
fn line_stream<'a,Repr>(&'a self) -> Self::LineStreamFut<'a,Repr>;
}
struct Y;
impl X for Y {
type LineStream<'a, Repr> = impl Stream<Item = Repr>;
type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>> ;
fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
async {empty()}
}
}
fn main() {}

<Empty<T> as Steam>::Item has a concrete type () whereas the line_stream function is generic over Steam::Item. So to me it looks like the raised error is correct.

error[E0271]: type mismatch resolving `<Empty<_> as Stream>::Item == Repr`
--> $DIR/issue-89008.rs:38:43
|
LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Empty<_> as Stream>::Item == Repr`
| |
| this type parameter
|
note: expected this to be `()`
--> $DIR/issue-89008.rs:17:17
|
LL | type Item = ();
| ^^
= note: expected unit type `()`
found type parameter `Repr`

Changing the Stream implementation to

impl<T> Stream for Empty<T> {
    type Item = T;
}

makes the code compile.

I am sorry if I am missing something here. If the test is correct then would moving the test to src/test/ui/type-alias-impl-trait resolve this issue? @jackh726

I also don't think #88908 relates to this test.

@jackh726
Copy link
Member

Yeah, I messed up my minimization. The test should just use the original MCVE in the OP. And that is indeed fixed.

@jackh726 jackh726 added E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. and removed E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. labels Oct 20, 2022
@jackh726
Copy link
Member

For clarity: this can be closed when the current known-bug test is moved to the main directory for GAT tests and changed to use the OP MCVE.

notriddle added a commit to notriddle/rust that referenced this issue Oct 21, 2022
…h726

Replaced wrong test with the correct mcve

Closes rust-lang#89008.

The old test was wrong and the compiler was [correctly raising an error](rust-lang#89008 (comment)). The bug in the issue was resolved at some point but due to the wrong test the issue was never closed.

This pr replaces that test with the correct MCVE (made by `@jackh726).`

The error raised by the bug changed between when the bug was posted (2021-09-08) and when the MCVE [was posted](rust-lang#89008 (comment)) (2021-10-23).
I ran them both through `nightly-2021-09-08` and they produce identical error messages. They also produce identical but different from before error messages when ran through `nightly-2021-10-23`.

<details>
  <summary>Error message with <code>nightly-2021-09-08</code></summary>

The code with the original bug report:
  ```
error[E0277]: the size for values of type `Repr` cannot be known at compilation time
  --> src/main.rs:23:43
   |
23 |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
   |                        ----               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |                        |
   |                        this type parameter needs to be `std::marker::Sized`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `test-234234` due to previous error
  ```

MVCE:
```
error[E0277]: the size for values of type `Repr` cannot be known at compilation time
  --> src/main.rs:30:43
   |
30 |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
   |                        ----               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |                        |
   |                        this type parameter needs to be `std::marker::Sized`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `test-234234` due to previous error
```
</details>

<details>
<summary>Error message with <code>nightly-2021-10-23</code></summary>

The code with the original bug report:
```
error[E0271]: type mismatch resolving `<impl futures::Future as futures::Future>::Output == impl futures::Stream`
  --> src/main.rs:23:43
   |
19 |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
   |                                 ------------------------ the expected opaque type
...
23 |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found struct `futures::stream::Empty`
   |
   = note: expected opaque type `impl futures::Stream`
                   found struct `futures::stream::Empty<_>`

error: could not find defining uses
  --> src/main.rs:19:33
   |
19 |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0271`.
error: could not compile `test-234234` due to 2 previous errors
```

MCVE:
```
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == impl Stream`
  --> src/main.rs:30:43
   |
28 |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
   |                                 ------------------------ the expected opaque type
29 |     type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
30 |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found struct `Empty`
   |
   = note: expected opaque type `impl Stream`
                   found struct `Empty<_>`

error: could not find defining uses
  --> src/main.rs:28:33
   |
28 |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0271`.
error: could not compile `test-234234` due to 2 previous errors
```
</details>
@bors bors closed this as completed in e67f09a Oct 22, 2022
@fmease fmease added the A-GATs Area: Generic associated types (GATs) label Nov 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-GATs Area: Generic associated types (GATs) 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-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` GATs-triaged Issues using the `generic_associated_types` feature that have been triaged S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test.
Development

Successfully merging a pull request may close this issue.

5 participants