Skip to content

Commit c0b365d

Browse files
committed
use uX::from instead of _ as uX in non - const contexts
1 parent 5df0f72 commit c0b365d

File tree

4 files changed

+132
-47
lines changed

4 files changed

+132
-47
lines changed

compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
2929
function: &Operand<'tcx>,
3030
arg: String,
3131
span: Span,
32+
is_in_const: bool,
3233
) -> Option<Error> {
3334
let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder();
3435
let [input] = fn_sig.inputs() else { return None };
@@ -96,9 +97,16 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
9697
)),
9798
// uNN → fNN
9899
(Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
99-
// bool → { x8 }
100-
(Bool, Int(..) | Uint(..)) => err(format!("({arg}) as {}", fn_sig.output())),
100+
// bool → { x8 } in const context since `From::from` is not const yet
101+
// FIXME: is it possible to know when the parentheses arent necessary?
102+
// FIXME(const_traits): Remove this when From::from is constified?
103+
(Bool, Int(..) | Uint(..)) if is_in_const => {
104+
err(format!("({arg}) as {}", fn_sig.output()))
105+
}
106+
// " using `x8::from`
107+
(Bool, Int(..) | Uint(..)) => err(format!("{}::from({arg})", fn_sig.output())),
101108
// u8 → bool
109+
// FIXME: Remove parentheses when they're unnecessary.
102110
(Uint(_), Bool) => err(format!("({arg} == 1)")),
103111
_ => return None,
104112
})
@@ -115,7 +123,13 @@ impl<'tcx> Visitor<'tcx> for UnnecessaryTransmuteChecker<'_, 'tcx> {
115123
&& self.tcx.is_intrinsic(func_def_id, sym::transmute)
116124
&& let span = self.body.source_info(location).span
117125
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(arg)
118-
&& let Some(lint) = self.is_unnecessary_transmute(func, snippet, span)
126+
&& let def_id = self.body.source.def_id()
127+
&& let Some(lint) = self.is_unnecessary_transmute(
128+
func,
129+
snippet,
130+
span,
131+
self.tcx.hir_body_const_context(def_id.expect_local()).is_some(),
132+
)
119133
&& let Some(hir_id) = terminator.source_info.scope.lint_root(&self.body.source_scopes)
120134
{
121135
self.tcx.emit_node_span_lint(UNNECESSARY_TRANSMUTES, hir_id, span, lint);

tests/ui/transmute/unnecessary-transmutation.fixed

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@ pub fn bytes_at_home(x: u32) -> [u8; 4] {
88
//~^ ERROR
99
}
1010

11+
pub const fn intinator_const(from: bool) -> u8 {
12+
unsafe { (from) as u8 }
13+
//~^ ERROR
14+
}
15+
16+
pub static X: u8 = unsafe { (true) as u8 };
17+
//~^ ERROR
18+
pub const Y: u8 = unsafe { (true) as u8 };
19+
//~^ ERROR
20+
21+
pub struct Z {}
22+
impl Z {
23+
pub const fn intinator_assoc(x: bool) -> u8 {
24+
unsafe { (x) as u8 }
25+
//~^ ERROR
26+
}
27+
}
28+
1129
fn main() {
30+
const { unsafe { (true) as u8 } };
31+
//~^ ERROR
1232
unsafe {
1333
let x: u16 = u16::from_ne_bytes(*b"01");
1434
//~^ ERROR
@@ -83,12 +103,12 @@ fn main() {
83103

84104
let z: bool = (1u8 == 1);
85105
//~^ ERROR
86-
let z: u8 = (z) as u8;
106+
let z: u8 = u8::from(z);
87107
//~^ ERROR
88108

89109
let z: bool = transmute(1i8);
90110
// no error!
91-
let z: i8 = (z) as i8;
111+
let z: i8 = i8::from(z);
92112
//~^ ERROR
93113
}
94114
}

tests/ui/transmute/unnecessary-transmutation.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@ pub fn bytes_at_home(x: u32) -> [u8; 4] {
88
//~^ ERROR
99
}
1010

11+
pub const fn intinator_const(from: bool) -> u8 {
12+
unsafe { transmute(from) }
13+
//~^ ERROR
14+
}
15+
16+
pub static X: u8 = unsafe { transmute(true) };
17+
//~^ ERROR
18+
pub const Y: u8 = unsafe { transmute(true) };
19+
//~^ ERROR
20+
21+
pub struct Z {}
22+
impl Z {
23+
pub const fn intinator_assoc(x: bool) -> u8 {
24+
unsafe { transmute(x) }
25+
//~^ ERROR
26+
}
27+
}
28+
1129
fn main() {
30+
const { unsafe { transmute::<_, u8>(true) } };
31+
//~^ ERROR
1232
unsafe {
1333
let x: u16 = transmute(*b"01");
1434
//~^ ERROR

0 commit comments

Comments
 (0)