Skip to content

Rustc creates invalid mir for core::cell::BorrowRef::new #49327

Closed
@bjorn3

Description

@bjorn3

Repro (copy of necessary parts of libcore/cell.rs): https://play.rust-lang.org/?gist=41cc5138c7765666a646bbcb09748ff3&version=stable

Notice the second statement in bb1: _4 = discriminant(_2); _2 is of type usize on which you are not allowed to the discriminant. _4 isn't used anywhere. This has been detected while fixing miri.

cc @solson @oli-obk

fn <impl at src/main.rs:11:1: 22:2>::new(_1: &std::cell::Cell<usize>) -> std::option::Option<BorrowRef> {
    let mut _0: std::option::Option<BorrowRef>; // return place
    scope 1 {
        let _5: usize;                   // "b" in scope 1 at src/main.rs:16:13: 16:14
    }
    let mut _2: usize;
    let mut _3: &std::cell::Cell<usize>;
    let mut _4: u8;
    let mut _6: ();
    let mut _7: &std::cell::Cell<usize>;
    let mut _8: usize;
    let mut _9: usize;
    let mut _10: (usize, bool);
    let mut _11: BorrowRef;
    let mut _12: &std::cell::Cell<usize>;

    bb0: {                              
        StorageLive(_2);                 // bb0[0]: scope 0 at src/main.rs:14:15: 14:27
        StorageLive(_3);                 // bb0[1]: scope 0 at src/main.rs:14:15: 14:21
        _3 = _1;                         // bb0[2]: scope 0 at src/main.rs:14:15: 14:21
        _2 = const <std::cell::Cell<T>>::get(move _3) -> bb1; // bb0[3]: scope 0 at src/main.rs:14:15: 14:27
                                         // ty::Const
                                         // └ ty: for<'r> fn(&'r std::cell::Cell<usize>) -> usize {<std::cell::Cell<T>><usize>::get}
                                         // └ val: Function(DefId(2/0:1406 ~ core[3d52]::cell[0]::{{impl}}[0]::get[0]), Slice([usize]))
                                         // mir::Constant
                                         // └ span: src/main.rs:14:15: 14:27
                                         // └ ty: for<'r> fn(&'r std::cell::Cell<usize>) -> usize {<std::cell::Cell<T>><usize>::get}
                                         // └ literal: const <std::cell::Cell<T>>::get
    }

    bb1: {                              
        StorageDead(_3);                 // bb1[0]: scope 0 at src/main.rs:14:27: 14:27
        _4 = discriminant(_2);           // bb1[1]: scope 0 at src/main.rs:14:9: 20:10
        switchInt(_2) -> [18446744073709551615usize: bb2, otherwise: bb3]; // bb1[2]: scope 0 at src/main.rs:15:13: 15:20
    }

    bb2: {                              
        _0 = std::option::Option<BorrowRef>::None; // bb2[0]: scope 0 at src/main.rs:15:24: 15:28
        goto -> bb4;                     // bb2[1]: scope 0 at src/main.rs:14:9: 20:10
    }

    bb3: {                              
        StorageLive(_5);                 // bb3[0]: scope 0 at src/main.rs:16:13: 16:14
        _5 = _2;                         // bb3[1]: scope 0 at src/main.rs:16:13: 16:14
        StorageLive(_7);                 // bb3[2]: scope 1 at src/main.rs:17:17: 17:23
        _7 = _1;                         // bb3[3]: scope 1 at src/main.rs:17:17: 17:23
        StorageLive(_8);                 // bb3[4]: scope 1 at src/main.rs:17:28: 17:33
        StorageLive(_9);                 // bb3[5]: scope 1 at src/main.rs:17:28: 17:29
        _9 = _5;                         // bb3[6]: scope 1 at src/main.rs:17:28: 17:29
        _10 = CheckedAdd(move _9, const 1usize); // bb3[7]: scope 1 at src/main.rs:17:28: 17:33
                                         // ty::Const
                                         // └ ty: usize
                                         // └ val: Integral(Usize(Us64(1)))
                                         // mir::Constant
                                         // └ span: src/main.rs:17:32: 17:33
                                         // └ ty: usize
                                         // └ literal: const 1usize
        assert(!move (_10.1: bool), "attempt to add with overflow") -> bb5; // bb3[8]: scope 1 at src/main.rs:17:28: 17:33
    }

    bb4: {                              
        StorageDead(_5);                 // bb4[0]: scope 0 at src/main.rs:20:10: 20:10
        StorageDead(_2);                 // bb4[1]: scope 0 at src/main.rs:21:6: 21:6
        return;                          // bb4[2]: scope 0 at src/main.rs:21:6: 21:6
    }

    bb5: {                              
        _8 = move (_10.0: usize);        // bb5[0]: scope 1 at src/main.rs:17:28: 17:33
        StorageDead(_9);                 // bb5[1]: scope 1 at src/main.rs:17:33: 17:33
        _6 = const <std::cell::Cell<T>>::set(move _7, move _8) -> bb6; // bb5[2]: scope 1 at src/main.rs:17:17: 17:34
                                         // ty::Const
                                         // └ ty: for<'r> fn(&'r std::cell::Cell<usize>, usize) {<std::cell::Cell<T>><usize>::set}
                                         // └ val: Function(DefId(2/0:1430 ~ core[3d52]::cell[0]::{{impl}}[10]::set[0]), Slice([usize]))
                                         // mir::Constant
                                         // └ span: src/main.rs:17:17: 17:34
                                         // └ ty: for<'r> fn(&'r std::cell::Cell<usize>, usize) {<std::cell::Cell<T>><usize>::set}
                                         // └ literal: const <std::cell::Cell<T>>::set
    }

    bb6: {                              
        StorageDead(_8);                 // bb6[0]: scope 1 at src/main.rs:17:34: 17:34
        StorageDead(_7);                 // bb6[1]: scope 1 at src/main.rs:17:34: 17:34
        StorageLive(_11);                // bb6[2]: scope 1 at src/main.rs:18:22: 18:50
        StorageLive(_12);                // bb6[3]: scope 1 at src/main.rs:18:42: 18:48
        _12 = _1;                        // bb6[4]: scope 1 at src/main.rs:18:42: 18:48
        _11 = BorrowRef { borrow: move _12 }; // bb6[5]: scope 1 at src/main.rs:18:22: 18:50
        StorageDead(_12);                // bb6[6]: scope 1 at src/main.rs:18:50: 18:50
        _0 = std::option::Option<BorrowRef>::Some(move _11,); // bb6[7]: scope 1 at src/main.rs:18:17: 18:51
        StorageDead(_11);                // bb6[8]: scope 1 at src/main.rs:18:51: 18:51
        goto -> bb4;                     // bb6[9]: scope 0 at src/main.rs:14:9: 20:10
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions