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

ICE for generators involving Never type #93161

Closed
RalfJung opened this issue Jan 21, 2022 · 1 comment · Fixed by #93313
Closed

ICE for generators involving Never type #93161

RalfJung opened this issue Jan 21, 2022 · 1 comment · Fixed by #93313
Assignees

Comments

@RalfJung
Copy link
Member

RalfJung commented Jan 21, 2022

Building the following code ICEs with current master (not yet on nightly):

#![feature(never_type)]

use std::future::Future;

// See if we can run a basic `async fn`
pub async fn foo(x: &u32, y: u32) -> u32 {
    let y = &y;
    let z = 9;
    let z = &z;
    let y = async { *y + *z }.await;
    let a = 10;
    let a = &a;
    *x + y + *a
}

async fn add(x: u32, y: u32) -> u32 {
    let a = async { x + y };
    a.await
}

async fn build_aggregate(a: u32, b: u32, c: u32, d: u32) -> u32 {
    let x = (add(a, b).await, add(c, d).await);
    x.0 + x.1
}

enum Never {}
fn never() -> Never {
    panic!()
}

async fn includes_never(crash: bool, x: u32) -> u32 {
    let mut result = async { x * x }.await;
    if !crash {
        return result;
    }
    #[allow(unused)]
    let bad = never();
    result *= async { x + x }.await;
    drop(bad);
    result
}

async fn partial_init(x: u32) -> u32 {
    #[allow(unreachable_code)]
    let _x: (String, !) = (String::new(), return async { x + x }.await);
}

async fn read_exact(_from: &mut &[u8], _to: &mut [u8]) -> Option<()> {
    Some(())
}

async fn hello_world() {
    let data = [0u8; 1];
    let mut reader = &data[..];

    let mut marker = [0u8; 1];
    read_exact(&mut reader, &mut marker).await.unwrap();
}

fn run_fut<T>(fut: impl Future<Output = T>) -> T {
    use std::sync::Arc;
    use std::task::{Context, Poll, Wake, Waker};

    struct MyWaker;
    impl Wake for MyWaker {
        fn wake(self: Arc<Self>) {
            unimplemented!()
        }
    }

    let waker = Waker::from(Arc::new(MyWaker));
    let mut context = Context::from_waker(&waker);

    let mut pinned = Box::pin(fut);
    loop {
        match pinned.as_mut().poll(&mut context) {
            Poll::Pending => continue,
            Poll::Ready(v) => return v,
        }
    }
}

fn main() {
    let x = 5;
    assert_eq!(run_fut(foo(&x, 7)), 31);
    assert_eq!(run_fut(build_aggregate(1, 2, 3, 4)), 10);
    assert_eq!(run_fut(includes_never(false, 4)), 16);
    assert_eq!(run_fut(partial_init(4)), 8);
    run_fut(hello_world());
}

Output:

error: internal compiler error: compiler/rustc_mir_transform/src/generator.rs:755:13: Broken MIR: generator contains type Never in MIR, but typeck only knows about {ResumeTy, bool, u32, impl Future<Output = [async output]>, (), impl Future<Output = [async output]>} and [bool, u32]
  --> tests/run-pass/async-fn.rs:31:53
   |
31 |   async fn includes_never(crash: bool, x: u32) -> u32 {
   |  _____________________________________________________^
32 | |     let mut result = async { x * x }.await;
33 | |     if !crash {
34 | |         return result;
...  |
40 | |     result
41 | | }
   | |_^

thread 'rustc' panicked at 'Box<dyn Any>', /rustc/84e918971d643c6a33067d5125214ab800ce5307/compiler/rustc_errors/src/lib.rs:1115:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.60.0-nightly (84e918971 2022-01-21) running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [optimized_mir] optimizing MIR for `includes_never::{closure#0}`
#1 [layout_of] computing layout of `[static generator@tests/run-pass/async-fn.rs:31:53: 41:2]`
end of query stack

This is a regression, the same code worked fine yesterday. Likely cause: #91032

eholk added a commit to eholk/rust that referenced this issue Jan 21, 2022
Generator drop tracking caused an ICE for generators involving the Never
type (Issue rust-lang#93161). Since this breaks miri, we temporarily disable drop
tracking so miri is unblocked while we properly fix the issue.
@eholk
Copy link
Contributor

eholk commented Jan 21, 2022

@rustbot claim

eholk added a commit to eholk/rust that referenced this issue Jan 21, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 22, 2022
…ng, r=nikomatsakis

Disable drop range tracking in generators

Generator drop tracking caused an ICE for generators involving the Never type (Issue rust-lang#93161). Since this breaks a test case with miri, we temporarily disable drop tracking so miri is unblocked while we properly fix the issue.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 22, 2022
…ng, r=nikomatsakis

Disable drop range tracking in generators

Generator drop tracking caused an ICE for generators involving the Never type (Issue rust-lang#93161). Since this breaks a test case with miri, we temporarily disable drop tracking so miri is unblocked while we properly fix the issue.
bors added a commit to rust-lang-ci/rust that referenced this issue Jan 23, 2022
…, r=nikomatsakis

Disable drop range tracking in generators

Generator drop tracking caused an ICE for generators involving the Never type (Issue rust-lang#93161). Since this breaks a test case with miri, we temporarily disable drop tracking so miri is unblocked while we properly fix the issue.
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 20, 2022
Check if call return type is visibly uninhabited when building MIR

The main motivation behind the change is to expose information about diverging
calls to the generator transform and match the precision of drop range tracking
which already understands that call expressions with visibly uninhabited types
diverges.

This change should also accept strictly more programs than before. That is
programs that were previously rejected due to errors raised by control-flow
sensitive checks in a code that is no longer considered reachable.

Fixes rust-lang#93161.
@bors bors closed this as completed in 38e3f52 Apr 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants