unsafe block not returning expected value

I’m getting some compile errors in something I belive it should work,

fn function() -> bool {
    unsafe { 1 } == 1
}

This gets me this error

error: expected expression, found `==`
 --> src/main.rs:9:18
  |
9 |     unsafe { 1 } == 1
  |                  ^^ expected expression

error[E0308]: mismatched types
 --> src/main.rs:9:14
  |
9 |     unsafe { 1 } == 1
  |              ^ expected `()`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `testcon` due to 2 previous errors

I get that this is kind of useless, but that 1 is really a unsafe function.
But then this works just fine.

fn function() -> bool {
    let var = unsafe { 1 };
    var == 1
}

I get that maybe both will be optimized to be exactly the same but I’m curious about the why

>Solution :

The problem is that unsafe is a kind of block expression, so when it appears at the beginning of a statement we can omit the semicolon at the end, but this means it is parsed as a whole statement and we cannot use it as part of an expression. This is mentioned in the reference:

An expression that consists of only a block expression or control flow expression, if used in a context where a statement is permitted, can omit the trailing semicolon. This can cause an ambiguity between it being parsed as a standalone statement and as a part of another expression; in this case, it is parsed as a statement.

The fix is to wrap it in parentheses:

fn function() -> bool {
    (unsafe { 1 }) == 1
}

Leave a Reply