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

Surprising impact of unused &mut #850

Closed
jrmuizel opened this issue Jul 23, 2019 · 6 comments
Closed

Surprising impact of unused &mut #850

jrmuizel opened this issue Jul 23, 2019 · 6 comments
Labels
A-aliasing Area: This affects the aliasing model (Stacked/Tree Borrows) C-support Category: Not necessarily a bug, but someone asking for support

Comments

@jrmuizel
Copy link

The following code fails with miri

use std::ptr::NonNull;
use std::cell::Cell;

struct F {
x: Cell<u32>,
       y: u32
}

impl F {
    fn new() -> F {
        F { x: Cell::new(5), y: 9 }
    }
}

#[test]
fn it_works() {
    let mut b = Box::new(F::new());
    let p: NonNull<F> = (&*b).into();

    fn f(rr: &F, mut p: NonNull<F>) {
        let r = unsafe { p.as_ref() };
        r.x.set(9);
    }

    {
        let m = &mut *b;
    }
    f(&b, p);
    b.y = 5;
}
error[E0080]: Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [SharedReadWrite for <79372> (call 36446)]
   --> /Users/jrmuizel/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/cell.rs:430:31
    |
430 |         mem::replace(unsafe { &mut *self.value.get() }, val)
    |                               ^^^^^^^^^^^^^^^^^^^^^^ Miri evaluation error: not granting access to tag <untagged> because incompatible item is protected: [SharedReadWrite for <79372> (call 36446)]
    |
    = note: inside call to `std::cell::Cell::<u32>::replace` at /Users/jrmuizel/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/cell.rs:387:19
note: inside call to `std::cell::Cell::<u32>::set` at src/lib.rs:23:9
   --> src/lib.rs:23:9
    |
23  |         r.x.set(9);
    |         ^^^^^^^^^^
note: inside call to `it_works::f` at src/lib.rs:29:5
   --> src/lib.rs:29:5
    |
29  |     f(&b, p);
    |     ^^^^^^^^
note: inside call to `it_works` at src/lib.rs:17:1
   --> src/lib.rs:17:1
    |
17  | / fn it_works() {
18  | |     let mut b = Box::new(F::new());
19  | |     let p: NonNull<F> = (&*b).into();
20  | |
...   |
30  | |     b.y = 5;
31  | | }
    | |_^

Commenting out let m = &mut *b; causes miri to succeed. I found this surprising as I wouldn't have expected let m = &mut *b; to have an effect.

@oli-obk oli-obk added the C-bug Category: This is a bug. label Jul 23, 2019
@RalfJung
Copy link
Member

At first glance, this seems like a duplicate of rust-lang/unsafe-code-guidelines#133 -- could you verify?

@RalfJung RalfJung added A-aliasing Area: This affects the aliasing model (Stacked/Tree Borrows) C-support Category: Not necessarily a bug, but someone asking for support and removed C-bug Category: This is a bug. labels Jul 23, 2019
@jrmuizel
Copy link
Author

That seems possible. I'll do some experimentation.

@RalfJung
Copy link
Member

RalfJung commented Aug 3, 2019

Closing as duplicate for now, feel free to reopen if you disagree.

@RalfJung RalfJung closed this as completed Aug 3, 2019
@jrmuizel
Copy link
Author

Is there a way to get miri to give a backtrace for the let m = &mut *b; operation?

@RalfJung
Copy link
Member

@saethlin is our 'making backtraces nicer' wizard so they might have an idea

@saethlin
Copy link
Member

Yes, but also no. I spent a few hours hacking on this and I can't figure out how to stitch together enough state to figure out what the tag of that &mut is so that I can locate it and print its creation span. This is the best thing I've come up with (on top of my draft diagnostics in #2030):

test it_works ... error: Undefined Behavior: not granting access to tag <untagged> because incompatible item is protected: [SharedReadWrite for <157304> (call 47369)]
   --> /home/ben/.rustup/toolchains/miri/lib/rustlib/src/rust/library/core/src/cell.rs:404:31
    |
404 |         mem::replace(unsafe { &mut *self.value.get() }, val)
    |                               ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <untagged> because incompatible item is protected: [SharedReadWrite for <157304> (call 47369)]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: tag was most recently created at offsets [0x0..0x4]
   --> src/main.rs:22:9
    |
22  |         r.x.set(9);
    |         ^^^^^^^^^^
help: this tag was also created here at offsets [0x0..0x8]
   --> src/main.rs:18:25
    |
18  |     let p: NonNull<F> = (&*b).into();
    |                         ^^^^^^^^^^^^
help: <157290> was protected due to a tag which was created here
   --> src/main.rs:28:7
    |
28  |     f(&b, p);
    |       ^^
help: this protector is live for this call
   --> src/main.rs:20:5
    |
20  | /     fn f(rr: &F, mut p: NonNull<F>) {
21  | |         let r = unsafe { p.as_ref() };
22  | |         r.x.set(9);
23  | |     }
    | |_____^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-aliasing Area: This affects the aliasing model (Stacked/Tree Borrows) C-support Category: Not necessarily a bug, but someone asking for support
Projects
None yet
Development

No branches or pull requests

4 participants