Skip to content

Underscore binding does not warn about lifetime violation #68502

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

Closed
jonhoo opened this issue Jan 24, 2020 · 2 comments
Closed

Underscore binding does not warn about lifetime violation #68502

jonhoo opened this issue Jan 24, 2020 · 2 comments

Comments

@jonhoo
Copy link
Contributor

jonhoo commented Jan 24, 2020

This code, as expected, fails to compile:

let x = vec![0];
let y = &x[0];
drop(x);
drop(y);

with

error: cannot move out of `x` because it is borrowed

But this code compiles just fine:

let x = vec![0];
let y = &x[0];
drop(x);
let _ = y;

even though y is "used" after its referent has been dropped. Is this expected behavior?

@Centril
Copy link
Contributor

Centril commented Jan 24, 2020

Another example:

fn foo() {
    struct NoCopy;
    let x = NoCopy;
    drop(x);
    let _ = x;
}

with the MIR:

fn  foo() -> () {
    let mut _0: ();                      // return place in scope 0 at src/lib.rs:1:10: 1:10
    let _1: foo::NoCopy;                 // "x" in scope 0 at src/lib.rs:3:9: 3:10
    let _2: ();                          // in scope 0 at src/lib.rs:4:5: 4:12
    let mut _3: foo::NoCopy;             // in scope 0 at src/lib.rs:4:10: 4:11
    scope 1 {
        scope 2 {
        }
    }

    bb0: {
        StorageLive(_1);                 // bb0[0]: scope 0 at src/lib.rs:3:9: 3:10
        StorageLive(_2);                 // bb0[1]: scope 1 at src/lib.rs:4:5: 4:12
        StorageLive(_3);                 // bb0[2]: scope 1 at src/lib.rs:4:10: 4:11
        _3 = move _1;                    // bb0[3]: scope 1 at src/lib.rs:4:10: 4:11
        _2 = const std::mem::drop::<foo::NoCopy>(move _3) -> bb1; // bb0[4]: scope 1 at src/lib.rs:4:5: 4:12
                                         // ty::Const
                                         // + ty: fn(foo::NoCopy) {std::mem::drop::<foo::NoCopy>}
                                         // + val: Scalar(<ZST>)
                                         // mir::Constant
                                         // + span: src/lib.rs:4:5: 4:9
                                         // + literal: Const { ty: fn(foo::NoCopy) {std::mem::drop::<foo::NoCopy>}, val: Scalar(<ZST>) }
    }

    bb1: {
        StorageDead(_3);                 // bb1[0]: scope 1 at src/lib.rs:4:11: 4:12
        StorageDead(_2);                 // bb1[1]: scope 1 at src/lib.rs:4:12: 4:13
        StorageDead(_1);                 // bb1[2]: scope 0 at src/lib.rs:6:1: 6:2
        return;                          // bb1[3]: scope 0 at src/lib.rs:6:2: 6:2
    }
}

Compare this with if you had added #[derive(Clone, Copy)] to NoCopy:

    bb1: {
        StorageDead(_3);                 // bb1[0]: scope 1 at src/lib.rs:5:11: 5:12
        StorageDead(_2);                 // bb1[1]: scope 1 at src/lib.rs:5:12: 5:13
        StorageLive(_4);                 // bb1[2]: scope 1 at src/lib.rs:6:9: 6:10
        _4 = _1;                         // bb1[3]: scope 1 at src/lib.rs:6:13: 6:14
        StorageDead(_4);                 // bb1[4]: scope 1 at src/lib.rs:7:1: 7:2
        StorageDead(_1);                 // bb1[5]: scope 0 at src/lib.rs:7:1: 7:2
        return;                          // bb1[6]: scope 0 at src/lib.rs:7:2: 7:2
    }

As you can see, in the first MIR output, there is no _4 = _1. That is, the let _ = y; does not appear in the MIR. This is by design, as _ is essentially not reading the place (well, match is a bit different, but details...).

So yes, this is by design.

@Centril Centril closed this as completed Jan 24, 2020
@jonhoo
Copy link
Contributor Author

jonhoo commented Jan 24, 2020

Ah, interesting, I suppose this ties in with the discussion back in #10488, where the conclusion was that _ neither drops nor moves. Thanks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants