Skip to content

Commit 17737d6

Browse files
committed
use uX::from instead of _ as uX in non - const contexts
1 parent 427288b commit 17737d6

File tree

4 files changed

+133
-43
lines changed

4 files changed

+133
-43
lines changed

compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_hir::def::DefKind::*;
12
use rustc_middle::mir::visit::Visitor;
23
use rustc_middle::mir::{Body, Location, Operand, Terminator, TerminatorKind};
34
use rustc_middle::ty::*;
@@ -29,6 +30,7 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
2930
function: &Operand<'tcx>,
3031
arg: String,
3132
span: Span,
33+
is_in_const: bool,
3234
) -> Option<Error> {
3335
let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder();
3436
let [input] = fn_sig.inputs() else { return None };
@@ -69,9 +71,15 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
6971
(Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())),
7072
// uNN → fNN
7173
(Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
72-
// bool → { x8 }
73-
(Bool, Int(..) | Uint(..)) => err(format!("({arg}) as {}", fn_sig.output())),
74+
// bool → { x8 } in const context
75+
// is it possible to know when the parentheses arent necessary?
76+
(Bool, Int(..) | Uint(..)) if is_in_const => {
77+
err(format!("({arg}) as {}", fn_sig.output()))
78+
}
79+
// " using `x8::from`
80+
(Bool, Int(..) | Uint(..)) => err(format!("{}::from({arg})", fn_sig.output())),
7481
// u8 → bool
82+
// also want to fix parentheses, maybe
7583
(Uint(_), Bool) => err(format!("({arg} == 1)")),
7684
_ => return None,
7785
})
@@ -88,7 +96,18 @@ impl<'tcx> Visitor<'tcx> for UnnecessaryTransmuteChecker<'_, 'tcx> {
8896
&& self.tcx.is_intrinsic(func_def_id, sym::transmute)
8997
&& let span = self.body.source_info(location).span
9098
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(arg)
91-
&& let Some(lint) = self.is_unnecessary_transmute(func, snippet, span)
99+
&& let def_id = self.body.source.def_id()
100+
&& let Some(lint) = self.is_unnecessary_transmute(
101+
func,
102+
snippet,
103+
span,
104+
self.tcx.is_const_fn(def_id)
105+
|| self.tcx.is_conditionally_const(def_id)
106+
|| matches!(
107+
self.tcx.def_kind(def_id),
108+
AnonConst | Const | Static { .. } | AssocConst | InlineConst
109+
),
110+
)
92111
&& let Some(hir_id) = terminator.source_info.scope.lint_root(&self.body.source_scopes)
93112
{
94113
self.tcx.emit_node_span_lint(UNNECESSARY_TRANSMUTES, hir_id, span, lint);

tests/ui/transmute/unnecessary-transmutation.fixed

+22-2
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
@@ -74,12 +94,12 @@ fn main() {
7494

7595
let z: bool = (1u8 == 1);
7696
//~^ ERROR
77-
let z: u8 = (z) as u8;
97+
let z: u8 = u8::from(z);
7898
//~^ ERROR
7999

80100
let z: bool = transmute(1i8);
81101
// no error!
82-
let z: i8 = (z) as i8;
102+
let z: i8 = i8::from(z);
83103
//~^ ERROR
84104
}
85105
}

tests/ui/transmute/unnecessary-transmutation.rs

+20
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)