rust-lang / rustc_codegen_cranelift

Cranelift based backend for rustc
Apache License 2.0
1.6k stars 101 forks source link

VerifierError on tokio-compat #970

Closed l4l closed 4 years ago

l4l commented 4 years ago

This one looks a bit more complicated. Got entry block parameters (2) must match function signature (1) for https://github.com/tokio-rs/tokio-compat/commit/180076a0d31f12c19c4a7e0f449487a22a7fea02 (master).

rustc_codegen_cranelift: 9f602bf4dae1a86dde890552e3c0c7fa2ca9196f

VerifierErrors ``` error: VerifierErrors([VerifierError { location: block0, context: None, message: "entry block parameters (2) must match function signature (1)" }]) error: cranelift verify error: function u0:6(i64) -> i8 system_v { ss0 = explicit_slot 1 ss1 = explicit_slot 8 ss2 = explicit_slot 8 ss3 = explicit_slot 1 ss4 = explicit_slot 32 ss5 = explicit_slot 1 ss6 = explicit_slot 8 ss7 = explicit_slot 8 ss8 = explicit_slot 1 ss9 = explicit_slot 8 ss10 = explicit_slot 8 ss11 = explicit_slot 8 gv0 = symbol colocated u1:0 gv1 = symbol colocated u1:1 gv2 = symbol colocated u1:0 sig0 = (i64) -> i64 system_v sig1 = (i64, i8) -> i64 system_v sig2 = (i64, i64) system_v sig3 = (i64) -> i64 system_v sig4 = (i64) -> i64 system_v sig5 = (i64, i64) -> i8 system_v sig6 = (i64) system_v sig7 = (i64) system_v sig8 = (i64) system_v sig9 = (i64) system_v fn0 = u0:15 sig0 fn1 = u0:16 sig1 fn2 = u0:17 sig2 fn3 = colocated u0:4 sig3 fn4 = u0:18 sig4 fn5 = u0:19 sig5 fn6 = u0:20 sig6 fn7 = u0:21 sig7 fn8 = u0:20 sig8 fn9 = u0:20 sig9 jt0 = jump_table [block2, block18] jt1 = jump_table [block15, block13] block0(v0: i64, v1: i64): ; ^~~~~~~~~~~~~~~~~~~~~~~~~ ; error: block0: entry block parameters (2) must match function signature (1) nop stack_store v0, ss1 stack_store v1, ss2 jump block1 block1: nop @0000 v2 = stack_load.i64 ss1 @0000 v3 = load.i8 v2+48 @0000 v4 = uextend.i64 v3 @0000 v5 = icmp_imm eq v4, 3 @0000 brnz v5, block17 @0000 jump block20 block20: @0000 br_table.i64 v4, block19, jt0 block2: @0000 nop @0000 v6 = stack_load.i64 ss2 @0000 stack_store v6, ss10 @0001 v7 = stack_load.i64 ss1 @0001 v8 = stack_load.i64 ss1 @0001 v9 = load.i64 v8 @0001 store v9, v7+8 @0002 jump block3 block3: @0002 nop @0005 v10 = stack_load.i64 ss1 @0005 v11 = load.i64 v10+8 @0005 v12 = iadd_imm v11, 8 @0005 v13 = call fn0(v12) v14 -> v13 @0005 jump block4 block4: @0005 nop @0007 v15 = iconst.i8 2 @0007 stack_store v15, ss3 @0004 v16 = stack_load.i8 ss3 @0004 v17 = call fn1(v14, v16) v18 -> v17 @0004 jump block5 block5: @0004 nop @0009 v19 = iconst.i64 0 @0009 v20 = icmp.i64 ne v18, v19 @0009 v21 = bint.i8 v20 @0002 v22 = uextend.i32 v21 @0002 brz v22, block6 @0002 jump block7 block6: @0002 nop @0002 v23 = iconst.i64 8 @000c v24 = iconst.i8 1 @000c stack_store v24, ss0 @000c v25 = stack_load.i64 ss1 @000c v26 = iconst.i8 1 @000c store v26, v25+48 @000c v27 = stack_load.i8 ss0 @000c return v27 block7: @000c nop @000e v28 = stack_load.i64 ss1 @000e v29 = load.i64 v28+8 @000d v30 = stack_addr.i64 ss4 @000d call fn2(v30, v29) @000d jump block8 block8: @000d nop @0010 v31 = stack_load.i64 ss1 @0010 v32 = stack_addr.i64 ss4 @0010 v33 = iadd_imm v31, 16 @0010 v34 = load.i64 aligned v32 @0010 v35 = load.i64 aligned v32+8 @0010 v36 = load.i64 aligned v32+16 @0010 v37 = load.i64 aligned v32+24 @0010 store aligned v34, v33 @0010 store aligned v35, v33+8 @0010 store aligned v36, v33+16 @0010 store aligned v37, v33+24 @0011 jump block9 block9: @0011 nop @0012 v38 = stack_load.i64 ss1 @0012 v39 = iadd_imm v38, 16 @0012 v40 = call fn3(v39) @0012 stack_store v40, ss6 @0012 jump block10 block10: @0012 nop @0012 v41 = stack_load.i64 ss10 @0012 stack_store v41, ss7 @0014 v42 = stack_load.i64 ss7 @0014 v43 = call fn4(v42) v44 -> v43 @0014 jump block11 block11: @0014 nop @0012 v45 = stack_load.i64 ss6 @0012 v46 = call fn5(v45, v44) @0012 stack_store v46, ss5 @0012 jump block12 block12: @0012 nop @0011 v47 = stack_load.i8 ss5 @0011 v48 = iadd_imm v47, -2 @0011 v49 = icmp_imm ule v48, 0 @0011 v50 = iconst.i64 0 @0011 v51 = iadd_imm v50, 1 @0011 v52 = iconst.i64 0 @0011 v53 = select v49, v51, v52 @0011 jump block21 block21: @0011 br_table.i64 v53, block14, jt1 block13: @0011 nop @0011 v54 = iconst.i8 0 @0011 stack_store v54, ss0 @0011 v55 = stack_load.i64 ss1 @0011 v56 = iconst.i8 3 @0011 store v56, v55+48 @0011 v57 = stack_load.i8 ss0 @0011 return v57 block14: @0011 nop @0011 v58 = global_value.i64 gv0 @0011 call fn6(v58) @0011 trap unreachable block15: @0011 nop @0011 v59 = stack_load.i8 ss5 @0011 stack_store v59, ss8 @0018 v60 = stack_load.i64 ss1 @0018 v61 = iadd_imm v60, 16 @0018 stack_store v61, ss11 @0018 v62 = stack_load.i64 ss11 @0018 call fn7(v62) @0018 jump block16 block16: @0018 nop @0002 jump block3 block17: @0002 nop @0000 v63 = stack_load.i64 ss2 @0000 stack_store v63, ss9 @0011 v64 = stack_load.i64 ss9 @0011 stack_store v64, ss10 @0011 jump block9 block18: @0011 nop @0000 v65 = iconst.i8 0 @0000 brz v65, block22 @0000 jump block18 block22: @0000 v66 = global_value.i64 gv1 @0000 call fn8(v66) @0000 trap user0 block19: @0000 nop @0000 v67 = global_value.i64 gv2 @0000 call fn9(v67) @0000 trap unreachable } ; 1 verifier error detected (see above). Compilation aborted. ```
That's called IR, right? ``` // WARNING: This output format is intended for human consumers only // and is subject to change without notice. Knock yourself out. fn runtime::idle::::idle::{{closure}}#0(_1: std::pin::Pin<&mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}]>, _2: std::future::ResumeTy) -> std::ops::GeneratorState<(), ()> { debug _task_context => _23; // in scope 0 at src/runtime/idle.rs:52:41: 57:6 debug self => ((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])).0: &mut runtime::idle::Rx); // in scope 0 at src/runtime/idle.rs:52:30: 52:39 let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at src/runtime/idle.rs:52:41: 57:6 let mut _3: bool; // in scope 0 at src/runtime/idle.rs:53:15: 53:56 let mut _4: usize; // in scope 0 at src/runtime/idle.rs:53:15: 53:51 let mut _5: &std::sync::atomic::AtomicUsize; // in scope 0 at src/runtime/idle.rs:53:15: 53:27 let _6: &std::sync::atomic::AtomicUsize; // in scope 0 at src/runtime/idle.rs:53:15: 53:27 let mut _7: &std::sync::Arc; // in scope 0 at src/runtime/idle.rs:53:15: 53:27 let mut _8: std::sync::atomic::Ordering; // in scope 0 at src/runtime/idle.rs:53:33: 53:50 let mut _9: impl std::future::Future; // in scope 0 at src/runtime/idle.rs:55:21: 55:35 let mut _10: &mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>; // in scope 0 at src/runtime/idle.rs:55:21: 55:28 let mut _11: std::task::Poll>; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _12: std::pin::Pin<&mut impl std::future::Future>; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _13: &mut impl std::future::Future; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _14: &mut impl std::future::Future; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _15: &mut std::task::Context; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _16: &mut std::task::Context; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _17: std::future::ResumeTy; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _18: isize; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _20: std::future::ResumeTy; // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _21: (); // in scope 0 at src/runtime/idle.rs:55:21: 55:41 let mut _22: (); // in scope 0 at src/runtime/idle.rs:52:41: 57:6 let mut _23: std::future::ResumeTy; // in scope 0 at src/runtime/idle.rs:52:41: 57:6 let mut _24: isize; // in scope 0 at src/runtime/idle.rs:52:41: 57:6 scope 1 { debug self => (((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).0: &mut runtime::idle::Rx); // in scope 1 at src/runtime/idle.rs:52:30: 52:39 scope 2 { } scope 3 { debug pinned => (((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).1: impl std::future::Future); // in scope 3 at src/runtime/idle.rs:55:21: 55:41 let _19: std::option::Option<()>; // in scope 3 at src/runtime/idle.rs:55:21: 55:41 scope 4 { } scope 5 { debug result => _19; // in scope 5 at src/runtime/idle.rs:55:21: 55:41 } } } bb0: { _24 = discriminant((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}]))); // bb0[0]: scope 0 at src/runtime/idle.rs:52:41: 57:6 switchInt(move _24) -> [0u32: bb1, 1u32: bb17, 3u32: bb16, otherwise: bb18]; // bb0[1]: scope 0 at src/runtime/idle.rs:52:41: 57:6 } bb1: { _23 = move _2; // bb1[0]: scope 0 at src/runtime/idle.rs:52:41: 57:6 (((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).0: &mut runtime::idle::Rx) = move ((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])).0: &mut runtime::idle::Rx); // bb1[1]: scope 0 at src/runtime/idle.rs:52:30: 52:39 goto -> bb2; // bb1[2]: scope 1 at src/runtime/idle.rs:53:9: 56:10 } bb2: { StorageLive(_3); // bb2[0]: scope 1 at src/runtime/idle.rs:53:15: 53:56 StorageLive(_4); // bb2[1]: scope 1 at src/runtime/idle.rs:53:15: 53:51 StorageLive(_5); // bb2[2]: scope 1 at src/runtime/idle.rs:53:15: 53:27 StorageLive(_6); // bb2[3]: scope 1 at src/runtime/idle.rs:53:15: 53:27 StorageLive(_7); // bb2[4]: scope 1 at src/runtime/idle.rs:53:15: 53:27 _7 = &((*(((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).0: &mut runtime::idle::Rx)).1: std::sync::Arc); // bb2[5]: scope 1 at src/runtime/idle.rs:53:15: 53:27 _6 = const as std::ops::Deref>::deref(move _7) -> bb3; // bb2[6]: scope 1 at src/runtime/idle.rs:53:15: 53:27 // ty::Const // + ty: for<'r> fn(&'r std::sync::Arc) -> &'r as std::ops::Deref>::Target { as std::ops::Deref>::deref} // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:53:15: 53:27 // + literal: Const { ty: for<'r> fn(&'r std::sync::Arc) -> &'r as std::ops::Deref>::Target { as std::ops::Deref>::deref}, val: Value(Scalar()) } } bb3: { _5 = _6; // bb3[0]: scope 1 at src/runtime/idle.rs:53:15: 53:27 StorageDead(_7); // bb3[1]: scope 1 at src/runtime/idle.rs:53:26: 53:27 StorageLive(_8); // bb3[2]: scope 1 at src/runtime/idle.rs:53:33: 53:50 discriminant(_8) = 2; // bb3[3]: scope 1 at src/runtime/idle.rs:53:33: 53:50 _4 = const std::sync::atomic::AtomicUsize::load(move _5, move _8) -> bb4; // bb3[4]: scope 1 at src/runtime/idle.rs:53:15: 53:51 // ty::Const // + ty: for<'r> fn(&'r std::sync::atomic::AtomicUsize, std::sync::atomic::Ordering) -> usize {std::sync::atomic::AtomicUsize::load} // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:53:28: 53:32 // + literal: Const { ty: for<'r> fn(&'r std::sync::atomic::AtomicUsize, std::sync::atomic::Ordering) -> usize {std::sync::atomic::AtomicUsize::load}, val: Value(Scalar()) } } bb4: { StorageDead(_8); // bb4[0]: scope 1 at src/runtime/idle.rs:53:50: 53:51 StorageDead(_5); // bb4[1]: scope 1 at src/runtime/idle.rs:53:50: 53:51 _3 = Ne(move _4, const 0usize); // bb4[2]: scope 1 at src/runtime/idle.rs:53:15: 53:56 // ty::Const // + ty: usize // + val: Value(Scalar(0x0000000000000000)) // mir::Constant // + span: src/runtime/idle.rs:53:55: 53:56 // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) } StorageDead(_6); // bb4[3]: scope 1 at src/runtime/idle.rs:53:55: 53:56 StorageDead(_4); // bb4[4]: scope 1 at src/runtime/idle.rs:53:55: 53:56 switchInt(_3) -> [false: bb5, otherwise: bb6]; // bb4[5]: scope 1 at src/runtime/idle.rs:53:9: 56:10 } bb5: { _22 = const (); // bb5[0]: scope 1 at src/runtime/idle.rs:53:9: 56:10 // ty::Const // + ty: () // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:53:9: 56:10 // + literal: Const { ty: (), val: Value(Scalar()) } StorageDead(_3); // bb5[1]: scope 1 at src/runtime/idle.rs:53:55: 53:56 ((_0 as Complete).0: ()) = move _22; // bb5[2]: scope 0 at src/runtime/idle.rs:57:6: 57:6 discriminant(_0) = 1; // bb5[3]: scope 0 at src/runtime/idle.rs:57:6: 57:6 discriminant((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}]))) = 1; // bb5[4]: scope 0 at src/runtime/idle.rs:57:6: 57:6 return; // bb5[5]: scope 0 at src/runtime/idle.rs:57:6: 57:6 } bb6: { StorageLive(_9); // bb6[0]: scope 1 at src/runtime/idle.rs:55:21: 55:35 StorageLive(_10); // bb6[1]: scope 1 at src/runtime/idle.rs:55:21: 55:28 _10 = &mut ((*(((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).0: &mut runtime::idle::Rx)).0: tokio::sync::mpsc::unbounded::UnboundedReceiver<()>); // bb6[2]: scope 1 at src/runtime/idle.rs:55:21: 55:28 _9 = const tokio::sync::mpsc::unbounded::UnboundedReceiver::<()>::recv(move _10) -> bb7; // bb6[3]: scope 1 at src/runtime/idle.rs:55:21: 55:35 // ty::Const // + ty: for<'_> fn(&mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>) -> impl std::future::Future {tokio::sync::mpsc::unbounded::UnboundedReceiver::<()>::recv} // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:55:29: 55:33 // + literal: Const { ty: for<'_> fn(&mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>) -> impl std::future::Future {tokio::sync::mpsc::unbounded::UnboundedReceiver::<()>::recv}, val: Value(Scalar()) } } bb7: { StorageDead(_10); // bb7[0]: scope 1 at src/runtime/idle.rs:55:34: 55:35 (((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).1: impl std::future::Future) = move _9; // bb7[1]: scope 1 at src/runtime/idle.rs:55:21: 55:41 goto -> bb8; // bb7[2]: scope 3 at src/runtime/idle.rs:55:21: 55:41 } bb8: { StorageLive(_11); // bb8[0]: scope 3 at src/runtime/idle.rs:55:21: 55:41 StorageLive(_12); // bb8[1]: scope 4 at src/runtime/idle.rs:55:21: 55:41 StorageLive(_13); // bb8[2]: scope 4 at src/runtime/idle.rs:55:21: 55:41 StorageLive(_14); // bb8[3]: scope 4 at src/runtime/idle.rs:55:21: 55:41 _14 = &mut (((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).1: impl std::future::Future); // bb8[4]: scope 4 at src/runtime/idle.rs:55:21: 55:41 _13 = _14; // bb8[5]: scope 4 at src/runtime/idle.rs:55:21: 55:41 _12 = const std::pin::Pin::<&mut impl std::future::Future>::new_unchecked(move _13) -> bb9; // bb8[6]: scope 4 at src/runtime/idle.rs:55:21: 55:41 // ty::Const // + ty: unsafe fn(&mut impl std::future::Future) -> std::pin::Pin<&mut impl std::future::Future> {std::pin::Pin::<&mut impl std::future::Future>::new_unchecked} // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:55:21: 55:41 // + user_ty: UserType(0) // + literal: Const { ty: unsafe fn(&mut impl std::future::Future) -> std::pin::Pin<&mut impl std::future::Future> {std::pin::Pin::<&mut impl std::future::Future>::new_unchecked}, val: Value(Scalar()) } } bb9: { StorageDead(_13); // bb9[0]: scope 4 at src/runtime/idle.rs:55:40: 55:41 StorageLive(_15); // bb9[1]: scope 4 at src/runtime/idle.rs:55:21: 55:41 StorageLive(_16); // bb9[2]: scope 4 at src/runtime/idle.rs:55:21: 55:41 StorageLive(_17); // bb9[3]: scope 4 at src/runtime/idle.rs:55:21: 55:41 _17 = _23; // bb9[4]: scope 4 at src/runtime/idle.rs:55:21: 55:41 _16 = const std::future::get_context(move _17) -> bb10; // bb9[5]: scope 4 at src/runtime/idle.rs:55:21: 55:41 // ty::Const // + ty: unsafe fn(std::future::ResumeTy) -> &mut std::task::Context {std::future::get_context} // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:55:21: 55:41 // + literal: Const { ty: unsafe fn(std::future::ResumeTy) -> &mut std::task::Context {std::future::get_context}, val: Value(Scalar()) } } bb10: { _15 = _16; // bb10[0]: scope 4 at src/runtime/idle.rs:55:21: 55:41 StorageDead(_17); // bb10[1]: scope 4 at src/runtime/idle.rs:55:40: 55:41 _11 = const ::poll(move _12, move _15) -> bb11; // bb10[2]: scope 4 at src/runtime/idle.rs:55:21: 55:41 // ty::Const // + ty: for<'r, 's, 't0> fn(std::pin::Pin<&'r mut impl std::future::Future>, &'s mut std::task::Context<'t0>) -> std::task::Poll<::Output> {::poll} // + val: Value(Scalar()) // mir::Constant // + span: src/runtime/idle.rs:55:21: 55:41 // + literal: Const { ty: for<'r, 's, 't0> fn(std::pin::Pin<&'r mut impl std::future::Future>, &'s mut std::task::Context<'t0>) -> std::task::Poll<::Output> {::poll}, val: Value(Scalar()) } } bb11: { StorageDead(_15); // bb11[0]: scope 4 at src/runtime/idle.rs:55:40: 55:41 StorageDead(_12); // bb11[1]: scope 4 at src/runtime/idle.rs:55:40: 55:41 _18 = discriminant(_11); // bb11[2]: scope 3 at src/runtime/idle.rs:55:21: 55:41 switchInt(move _18) -> [0isize: bb14, 1isize: bb12, otherwise: bb13]; // bb11[3]: scope 3 at src/runtime/idle.rs:55:21: 55:41 } bb12: { StorageDead(_16); // bb12[0]: scope 3 at src/runtime/idle.rs:55:40: 55:41 StorageDead(_14); // bb12[1]: scope 3 at src/runtime/idle.rs:55:40: 55:41 StorageDead(_11); // bb12[2]: scope 3 at src/runtime/idle.rs:55:40: 55:41 StorageLive(_20); // bb12[3]: scope 3 at src/runtime/idle.rs:55:21: 55:41 StorageLive(_21); // bb12[4]: scope 3 at src/runtime/idle.rs:55:21: 55:41 ((_0 as Yielded).0: ()) = move _21; // bb12[5]: scope 3 at src/runtime/idle.rs:55:21: 55:41 discriminant(_0) = 0; // bb12[6]: scope 3 at src/runtime/idle.rs:55:21: 55:41 discriminant((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}]))) = 3; // bb12[7]: scope 3 at src/runtime/idle.rs:55:21: 55:41 return; // bb12[8]: scope 3 at src/runtime/idle.rs:55:21: 55:41 } bb13: { unreachable; // bb13[0]: scope 3 at src/runtime/idle.rs:55:21: 55:41 } bb14: { StorageLive(_19); // bb14[0]: scope 3 at src/runtime/idle.rs:55:21: 55:41 _19 = ((_11 as Ready).0: std::option::Option<()>); // bb14[1]: scope 3 at src/runtime/idle.rs:55:21: 55:41 StorageDead(_19); // bb14[2]: scope 3 at src/runtime/idle.rs:55:40: 55:41 StorageDead(_16); // bb14[3]: scope 3 at src/runtime/idle.rs:55:40: 55:41 StorageDead(_14); // bb14[4]: scope 3 at src/runtime/idle.rs:55:40: 55:41 StorageDead(_11); // bb14[5]: scope 3 at src/runtime/idle.rs:55:40: 55:41 drop((((*(_1.0: &mut [static generator@src/runtime/idle.rs:52:41: 57:6 self:&mut runtime::idle::Rx for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}])) as variant#3).1: impl std::future::Future)) -> bb15; // bb14[6]: scope 1 at src/runtime/idle.rs:55:40: 55:41 } bb15: { StorageDead(_9); // bb15[0]: scope 1 at src/runtime/idle.rs:55:41: 55:42 StorageDead(_3); // bb15[1]: scope 1 at src/runtime/idle.rs:53:55: 53:56 goto -> bb2; // bb15[2]: scope 1 at src/runtime/idle.rs:53:9: 56:10 } bb16: { StorageLive(_3); // bb16[0]: scope 0 at src/runtime/idle.rs:52:41: 57:6 StorageLive(_9); // bb16[1]: scope 0 at src/runtime/idle.rs:52:41: 57:6 StorageLive(_20); // bb16[2]: scope 0 at src/runtime/idle.rs:52:41: 57:6 StorageLive(_21); // bb16[3]: scope 0 at src/runtime/idle.rs:52:41: 57:6 _20 = move _2; // bb16[4]: scope 0 at src/runtime/idle.rs:52:41: 57:6 StorageDead(_21); // bb16[5]: scope 3 at src/runtime/idle.rs:55:40: 55:41 _23 = move _20; // bb16[6]: scope 3 at src/runtime/idle.rs:55:21: 55:41 StorageDead(_20); // bb16[7]: scope 3 at src/runtime/idle.rs:55:40: 55:41 goto -> bb8; // bb16[8]: scope 3 at src/runtime/idle.rs:55:21: 55:41 } bb17: { assert(const false, "`async fn` resumed after completion") -> bb17; // bb17[0]: scope 0 at src/runtime/idle.rs:52:41: 57:6 // ty::Const // + ty: bool // + val: Value(Scalar(0x00)) // mir::Constant // + span: src/runtime/idle.rs:52:41: 57:6 // + literal: Const { ty: bool, val: Value(Scalar(0x00)) } } bb18: { unreachable; // bb18[0]: scope 0 at src/runtime/idle.rs:52:41: 57:6 } } Instance { def: Item(DefId(0:223 ~ tokio_compat[5f89]::runtime[0]::idle[0]::{{impl}}[1]::idle[0]::{{closure}}[0])), substs: [std::future::ResumeTy, (), (), for<'r, 's, 't0> {std::future::ResumeTy, &'r mut runtime::idle::Rx, bool, runtime::idle::Rx, &'s mut tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, tokio::sync::mpsc::unbounded::UnboundedReceiver<()>, impl std::future::Future, ()}, (&mut runtime::idle::Rx,)] } _ZN12tokio_compat7runtime4idle2Rx4idle28_$u7b$$u7b$closure$u7d$$u7d$17h10cbd98b5376557bE ```
bjorn3 commented 4 years ago

That's called IR, right?

It's called MIR.

It seems that I haven't implemented something regarding Pin<&mut [generator]> as self(?) arg correctly.

bjorn3 commented 4 years ago

Thank you very much for testing all those crates!

bjorn3 commented 4 years ago

Current repro:

use futures_util::{compat::Future01CompatExt, future::FutureExt};
use std::future::Future;

pub fn spawn(
    future: Box<dyn futures_01::Future<Item = (), Error = ()> + Send>,
    context: &mut std::task::Context,
) {
    let future = future.compat().map(|_| ());
    let _ = Box::pin(with(future)).as_mut().poll(context);
}

async fn with(f: impl Future<Output = ()>) {
    f.await
}
bjorn3 commented 4 years ago

No external crates:

use std::future::Future;
use std::task::*;
use std::pin::Pin;

pub fn spawn(context: &mut Context) {
    let future = Compat01As03;
    let _ = Box::pin(with(future)).as_mut().poll(context);
}

pub struct Compat01As03;

impl Future for Compat01As03 {
    type Output = ();

    fn poll(
        self: Pin<&mut Self>,
        _cx: &mut Context<'_>,
    ) -> Poll<Self::Output> {
        loop {}
    }
}

async fn with(f: impl Future<Output = ()>) {
    f.await
}
bjorn3 commented 4 years ago

Minimal repro:

#![feature(generators, generator_trait)]

use std::ops::Generator;

pub fn with() {
    Box::pin(move |mut _task_context| {
        yield ();
    }).as_mut().resume(0);
}
bjorn3 commented 4 years ago

Fixed in eab4c9063ec63bf484347cbd6b21117d336db4a5. I had to sync fn_sig_for_fn_abi with upstream for the generator resume arg support that recently landed in rustc.