Skip to content

Unsafe blocks fail to parse as expressions in comparisons #95410

@clarfonthey

Description

@clarfonthey

Example gist: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=01dfdf28913f8fe69d419dfd7472dc49

In short, take these three functions:

fn test_one() -> u32 {
    unsafe { 2 }
}

fn test_two() -> bool {
    let x: u32 = unsafe { 2 };
    let y: u32 = unsafe { 2 };
    x == y
}

fn test_three() -> bool {
    unsafe { 2 } == unsafe { 2 }
}

The first two of these functions parse correctly, but the last one does not. The parser complains about seeing == after an unsafe block, and in its recovery, assumes that the unsafe block has type () instead of {integer}.

Exact output:

Compiling playground v0.0.1 (/playground)
error: expected expression, found `==`
  --> src/lib.rs:12:18
   |
12 |     unsafe { 2 } == unsafe { 2 }
   |                  ^^ expected expression

error[[E0308]](https://doc.rust-lang.org/nightly/error-index.html#E0308): mismatched types
   |
12 |     unsafe { 2 } == unsafe { 2 }
   |              ^ expected `()`, found integer

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

This fails on the current stable compiler and nightly, those being 1.59.0 and 2022-03-27, respectively.

I found this code when using unions:

union Test {
    raw: u8,
    // other stuff that doesn't matter
}

impl PartialEq for Test {
    fn eq(&self, rhs: &Test) -> bool {
        unsafe { self.raw } == unsafe { rhs.raw }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions