Skip to content

Commit cf1e2e9

Browse files
committed
Auto merge of #8612 - SabrinaJewson:suggest-from-utf8-unchecked-in-const, r=flip1995
Suggest from_utf8_unchecked in const contexts Unfortunately I couldn't figure out how to check whether a given expression is in an `unsafe` context or not, so I just unconditionally emit the wrapping `unsafe {}` block in the suggestion. If there is an easy way to get it to work better then I would love to hear it. changelog: Suggest `from_utf8_unchecked` instead of `from_utf8` in const contexts for ``[`transmute_bytes_to_str`]`` refs: #8379
2 parents 880ff24 + 41ef4f7 commit cf1e2e9

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

clippy_lints/src/transmute/transmute_ref_to_ref.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@ pub(super) fn check<'tcx>(
3232
""
3333
};
3434

35+
let snippet = snippet(cx, arg.span, "..");
36+
3537
span_lint_and_sugg(
3638
cx,
3739
TRANSMUTE_BYTES_TO_STR,
3840
e.span,
3941
&format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
4042
"consider using",
41-
format!(
42-
"std::str::from_utf8{}({}).unwrap()",
43-
postfix,
44-
snippet(cx, arg.span, ".."),
45-
),
46-
Applicability::Unspecified,
43+
if const_context {
44+
format!("std::str::from_utf8_unchecked{postfix}({snippet})")
45+
} else {
46+
format!("std::str::from_utf8{postfix}({snippet}).unwrap()")
47+
},
48+
Applicability::MaybeIncorrect,
4749
);
4850
triggered = true;
4951
} else {

tests/ui/transmute.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ mod num_to_bytes {
134134
}
135135
}
136136

137-
fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
138-
let _: &str = unsafe { std::mem::transmute(b) };
137+
fn bytes_to_str(mb: &mut [u8]) {
138+
const B: &[u8] = b"";
139+
140+
let _: &str = unsafe { std::mem::transmute(B) };
139141
let _: &mut str = unsafe { std::mem::transmute(mb) };
142+
const _: &str = unsafe { std::mem::transmute(B) };
140143
}
141144

142145
fn main() {}

tests/ui/transmute.stderr

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,18 +227,24 @@ LL | let _: [u8; 16] = std::mem::transmute(0i128);
227227
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
228228

229229
error: transmute from a `&[u8]` to a `&str`
230-
--> $DIR/transmute.rs:138:28
230+
--> $DIR/transmute.rs:140:28
231231
|
232-
LL | let _: &str = unsafe { std::mem::transmute(b) };
233-
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
232+
LL | let _: &str = unsafe { std::mem::transmute(B) };
233+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
234234
|
235235
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
236236

237237
error: transmute from a `&mut [u8]` to a `&mut str`
238-
--> $DIR/transmute.rs:139:32
238+
--> $DIR/transmute.rs:141:32
239239
|
240240
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
241241
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
242242

243-
error: aborting due to 38 previous errors
243+
error: transmute from a `&[u8]` to a `&str`
244+
--> $DIR/transmute.rs:142:30
245+
|
246+
LL | const _: &str = unsafe { std::mem::transmute(B) };
247+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
248+
249+
error: aborting due to 39 previous errors
244250

0 commit comments

Comments
 (0)