Closed
Description
I tried this code:
use std::mem::MaybeUninit;
#[derive(Debug)]
pub struct Foo {
pub field_1: u32,
pub field_2: u64,
}
const SUCCESS: u32 = 0;
unsafe fn ffi_init_foo(foo: *mut Foo) -> u32 {
(*foo).field_1 = 1;
(*foo).field_2 = 2;
SUCCESS
}
fn func_1() -> Result<Foo, u32>{
let mut foo = MaybeUninit::<Foo>::uninit();
let foo = 'block: {
let ret_val = unsafe {
ffi_init_foo(foo.as_mut_ptr())
};
if ret_val == SUCCESS {
break 'block unsafe { foo.assume_init() };
}
eprintln!("ERROR: {ret_val}");
return Err(ret_val);
};
Ok(foo)
}
// uses compiler suggestion!
fn func_2() -> Result<Foo, u32>{
let mut foo = MaybeUninit::<Foo>::uninit();
let foo = 'block: {
let ret_val = unsafe {
ffi_init_foo(foo.as_mut_ptr())
};
if ret_val == SUCCESS {
break 'block (unsafe { foo.assume_init() });
}
eprintln!("ERROR: {ret_val}");
return Err(ret_val);
};
Ok(foo)
}
// this works without warnings
fn func_3() -> Result<Foo, u32>{
let mut foo = MaybeUninit::<Foo>::uninit();
let foo = 'block: {
let ret_val = unsafe {
ffi_init_foo(foo.as_mut_ptr())
};
if ret_val == SUCCESS {
let foo = unsafe { foo.assume_init() };
break 'block foo;
}
eprintln!("ERROR: {ret_val}");
return Err(ret_val);
};
Ok(foo)
}
fn main() {
let _ = dbg!(func_1());
let _ = dbg!(func_2());
let _ = dbg!(func_3());
}
I expected func_1
to compile without warning but it produced:
warning: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression
--> src/main.rs:25:13
|
25 | break 'block unsafe { foo.assume_init() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(break_with_label_and_loop)]` on by default
help: wrap this expression in parentheses
|
25 | break 'block (unsafe { foo.assume_init() });
| + +
func_2
is the same as func_1
, but it follows the compilers suggestion and produces this warning:
warning: unnecessary parentheses around `break` value
--> src/main.rs:43:26
|
43 | break 'block (unsafe { foo.assume_init() });
| ^ ^
|
= note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
|
43 - break 'block (unsafe { foo.assume_init() });
43 + break 'block unsafe { foo.assume_init() };
|
func_3
compiles without warnings, but it adds a needless assignment.
Meta
rustc --version --verbose
:
1.87.0-nightly
(2025-02-21 794c12416b2138064af1)
The issue is also present on latest stable (1.85)