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

Futures involving uninhabited variables are incorrectly considered uninhabited. #59972

Open
Lymia opened this Issue Apr 14, 2019 · 7 comments

Comments

Projects
None yet
8 participants
@Lymia
Copy link
Contributor

Lymia commented Apr 14, 2019

The following code crashes with an illegal instruction, presumably because all the code after contains_never is considered unreachable:

#![feature(futures_api, async_await, await_macro)]

pub enum Uninhabited { }

fn uninhabited_async() -> Uninhabited {
    unreachable!()
}

async fn noop() { }

async fn contains_never() {
    let error = uninhabited_async();
    await!(noop());
    let error2 = error;
}

fn main() {
    contains_never();
}

It seems the root cause is that the struct representing the future contains a field of type Uninhabited as it is preserved across the (unreachable) yield point and thus is considered uninhabited itself, despite being perfectly constructible.

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Apr 14, 2019

This sounds like it is caused by the fact that generators have an "incorrect" layout (claiming to have fields with certain types when really these might not be initialized), and some code not taking that special case into account properly.

Cc @eddyb @cramertj

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Apr 15, 2019

@tmandry

This comment has been minimized.

Copy link
Contributor

tmandry commented Apr 15, 2019

This is actually already fixed in #59897 (currently a WIP), around here. I'll make sure to add this as a test to that PR!

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Apr 16, 2019

@tmandry does that mean that generators will no longer "cheat" in their layout, and

// Locals variables which live across yields are stored
can be removed? That'd be cool :D

I'd also have to adjust

ty::Generator(..) => {
-- can that be treated like any other type then because the variants have all the right information?

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Apr 17, 2019

@RalfJung I don't think it's that simple, we'd likely still need to keep uninitialized variables for now.
Although... I suppose the state variants, for yields across which they're not live, could just omit those variables, despite not using that space for anything else.

@tmandry

This comment has been minimized.

Copy link
Contributor

tmandry commented Apr 17, 2019

@RalfJung I don't think it's that simple, we'd likely still need to keep uninitialized variables for now.
Although... I suppose the state variants, for yields across which they're not live, could just omit those variables, despite not using that space for anything else.

We could do that, yes, with some further changes to my PR. I would like to get there, and then we can have UB checking for our generators as well :)

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Apr 18, 2019

triage: P-high. removing nominated tag.

@pnkfelix pnkfelix added P-high and removed I-nominated labels Apr 18, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.