Skip to content

Accessing union field inside unsafe function requires extra unsafe block #53193

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
gnzlbg opened this issue Aug 8, 2018 · 7 comments
Closed

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Aug 8, 2018

Playground

Is this by design?

pub unsafe fn foo() -> u8 {
    union U {
        v: u8,
        c: u8,
    }
    // const C: u8 = unsafe { U { v: 0 }.c }; // OK
    const C: u8 = U { v: 0 }.c; // ERROR
    C
}

it produces:

error[E0133]: access to union field is unsafe and requires unsafe function or block
 --> src/main.rs:9:19
  |
9 |     const C: u8 = U { v: 0 }.c;
  |                   ^^^^^^^^^^^^ access to union field
  |
  = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior

Wrapping the access in an unsafe block compiles, but since the function is already unsafe, that feels a bit redundant.

In non-unsafe functions one doesn't need to open two unsafe blocks to perform union field access unsafe { unsafe { ...union access... } } :D Is this doubly-unsafe ? :D

cc @oli-obk @RalfJung @eddyb

@oli-obk
Copy link
Contributor

oli-obk commented Aug 8, 2018

huh... has it been this way since unions were introduced or is this a regression?

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Aug 8, 2018

No idea. I use unions a lot and this is the first time I see this. I did not managed to find an open issue about it.

@oli-obk
Copy link
Contributor

oli-obk commented Aug 8, 2018

Ah! I overlooked the constant. Yea, the body of the constant is its own scope and does require its own unsafe blocks.

This is working as intended to the best of my knowledge

@oli-obk
Copy link
Contributor

oli-obk commented Aug 8, 2018

if you declare a safe function inside an unsafe block you don't expect to be able to use unsafe things inside that safe function either.

http://play.rust-lang.org/?gist=364ef241902e1916d7dc1919d38ad19d&version=stable&mode=debug&edition=2015

pub unsafe fn foo() -> fn(*const u8) -> u8 {
    fn helper(ptr: *const u8) -> u8 {
        *ptr
    }
    helper
}

@petrochenkov
Copy link
Contributor

Fun fact: this worked before Rust 1.6.0 (not for unions, of course) - #47864 (comment).

@oli-obk
Copy link
Contributor

oli-obk commented Aug 8, 2018

duplicate of #35716

@oli-obk oli-obk closed this as completed Aug 8, 2018
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Aug 8, 2018

Thank you for the clarification @oli-obk - maybe that note ("the body of the constant is its own scope and requires its own unsafe block, just like safe functions inside unsafe functions") could be added to the error message in this case ?

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

3 participants