Skip to content

Commit ee25582

Browse files
Do no emit missing_transmute_annotations lint if the transmute is the only expr in the function
1 parent ffa1279 commit ee25582

File tree

4 files changed

+90
-95
lines changed

4 files changed

+90
-95
lines changed

clippy_lints/src/transmute/missing_transmute_annotations.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
12
use rustc_errors::Applicability;
23
use rustc_hir::{GenericArg, HirId, Local, Node, Path, TyKind};
34
use rustc_lint::LateContext;
45
use rustc_middle::lint::in_external_macro;
56
use rustc_middle::ty::Ty;
67

7-
use clippy_utils::diagnostics::span_lint_and_sugg;
8-
98
use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
109

1110
fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option<Local<'tcx>> {
@@ -29,6 +28,15 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId)
2928
}
3029
}
3130

31+
fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {
32+
let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id);
33+
if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id) {
34+
let body = cx.tcx.hir().body(body_id);
35+
return body.value.peel_blocks().hir_id == expr_hir_id;
36+
}
37+
false
38+
}
39+
3240
pub(super) fn check<'tcx>(
3341
cx: &LateContext<'tcx>,
3442
path: &Path<'tcx>,
@@ -54,14 +62,17 @@ pub(super) fn check<'tcx>(
5462
return false;
5563
}
5664
// If it's being set as a local variable value...
57-
if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id)
65+
if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) {
5866
// ... which does have type annotations.
59-
&& let Some(ty) = local.ty
60-
{
61-
// If this is a `let x: _ =`, we shouldn't lint.
62-
if !matches!(ty.kind, TyKind::Infer) {
67+
if let Some(ty) = local.ty
68+
// If this is a `let x: _ =`, we should lint.
69+
&& !matches!(ty.kind, TyKind::Infer)
70+
{
6371
return false;
6472
}
73+
// We check if this transmute is not the only element in the function
74+
} else if is_function_block(cx, expr_hir_id) {
75+
return false;
6576
}
6677
span_lint_and_sugg(
6778
cx,

tests/ui/missing_transmute_annotations.fixed

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern crate macro_rules;
99
macro_rules! local_bad_transmute {
1010
($e:expr) => {
1111
std::mem::transmute::<[u16; 2], i32>($e)
12+
//~^ ERROR: transmute used without annotations
1213
};
1314
}
1415

@@ -17,55 +18,46 @@ fn bar(x: i32) -> i32 {
1718
}
1819

1920
unsafe fn foo1() -> i32 {
20-
std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])
21-
//~^ ERROR: transmute used without annotations
21+
// Should not warn!
22+
std::mem::transmute([1u16, 2u16])
2223
}
2324

24-
unsafe fn foo2() -> i32 {
25-
std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])
26-
//~^ ERROR: transmute used without annotations
27-
}
25+
// Should not warn!
26+
const _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
2827

29-
unsafe fn foo3() -> i32 {
30-
std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])
31-
//~^ ERROR: transmute used without annotations
28+
#[repr(i32)]
29+
enum Foo {
30+
A = 0,
3231
}
3332

34-
unsafe fn foo4() -> i32 {
35-
std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])
33+
unsafe fn foo2() -> i32 {
34+
let mut i: i32 = 0;
35+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
36+
//~^ ERROR: transmute used without annotations
37+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
38+
//~^ ERROR: transmute used without annotations
39+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
40+
//~^ ERROR: transmute used without annotations
41+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
3642
//~^ ERROR: transmute used without annotations
37-
}
3843

39-
unsafe fn foo5() -> i32 {
4044
let x: i32 = bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));
4145
//~^ ERROR: transmute used without annotations
42-
bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]))
46+
bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));
4347
//~^ ERROR: transmute used without annotations
44-
}
4548

46-
unsafe fn foo6() -> i32 {
47-
local_bad_transmute!([1u16, 2u16])
48-
//~^ ERROR: transmute used without annotations
49-
}
49+
i = local_bad_transmute!([1u16, 2u16]);
5050

51-
unsafe fn foo7() -> i32 {
5251
// Should not warn.
53-
bad_transmute!([1u16, 2u16])
54-
}
55-
56-
#[repr(i32)]
57-
enum Foo {
58-
A = 0,
59-
}
52+
i = bad_transmute!([1u16, 2u16]);
6053

61-
unsafe fn foo8() -> Foo {
62-
std::mem::transmute::<i32, Foo>(0i32)
54+
i = std::mem::transmute::<[i16; 2], i32>([0i16, 0i16]);
6355
//~^ ERROR: transmute used without annotations
64-
}
6556

66-
unsafe fn foo9() -> i32 {
67-
std::mem::transmute::<Foo, i32>(Foo::A)
57+
i = std::mem::transmute::<Foo, i32>(Foo::A);
6858
//~^ ERROR: transmute used without annotations
59+
60+
i
6961
}
7062

7163
fn main() {

tests/ui/missing_transmute_annotations.rs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern crate macro_rules;
99
macro_rules! local_bad_transmute {
1010
($e:expr) => {
1111
std::mem::transmute($e)
12+
//~^ ERROR: transmute used without annotations
1213
};
1314
}
1415

@@ -17,55 +18,46 @@ fn bar(x: i32) -> i32 {
1718
}
1819

1920
unsafe fn foo1() -> i32 {
21+
// Should not warn!
2022
std::mem::transmute([1u16, 2u16])
21-
//~^ ERROR: transmute used without annotations
2223
}
2324

24-
unsafe fn foo2() -> i32 {
25-
std::mem::transmute::<_, _>([1u16, 2u16])
26-
//~^ ERROR: transmute used without annotations
27-
}
25+
// Should not warn!
26+
const _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
2827

29-
unsafe fn foo3() -> i32 {
30-
std::mem::transmute::<_, i32>([1u16, 2u16])
31-
//~^ ERROR: transmute used without annotations
28+
#[repr(i32)]
29+
enum Foo {
30+
A = 0,
3231
}
3332

34-
unsafe fn foo4() -> i32 {
35-
std::mem::transmute::<[u16; 2], _>([1u16, 2u16])
33+
unsafe fn foo2() -> i32 {
34+
let mut i: i32 = 0;
35+
i = std::mem::transmute([1u16, 2u16]);
36+
//~^ ERROR: transmute used without annotations
37+
i = std::mem::transmute::<_, _>([1u16, 2u16]);
38+
//~^ ERROR: transmute used without annotations
39+
i = std::mem::transmute::<_, i32>([1u16, 2u16]);
40+
//~^ ERROR: transmute used without annotations
41+
i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
3642
//~^ ERROR: transmute used without annotations
37-
}
3843

39-
unsafe fn foo5() -> i32 {
4044
let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
4145
//~^ ERROR: transmute used without annotations
42-
bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]))
46+
bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
4347
//~^ ERROR: transmute used without annotations
44-
}
4548

46-
unsafe fn foo6() -> i32 {
47-
local_bad_transmute!([1u16, 2u16])
48-
//~^ ERROR: transmute used without annotations
49-
}
49+
i = local_bad_transmute!([1u16, 2u16]);
5050

51-
unsafe fn foo7() -> i32 {
5251
// Should not warn.
53-
bad_transmute!([1u16, 2u16])
54-
}
55-
56-
#[repr(i32)]
57-
enum Foo {
58-
A = 0,
59-
}
52+
i = bad_transmute!([1u16, 2u16]);
6053

61-
unsafe fn foo8() -> Foo {
62-
std::mem::transmute(0i32)
54+
i = std::mem::transmute([0i16, 0i16]);
6355
//~^ ERROR: transmute used without annotations
64-
}
6556

66-
unsafe fn foo9() -> i32 {
67-
std::mem::transmute(Foo::A)
57+
i = std::mem::transmute(Foo::A);
6858
//~^ ERROR: transmute used without annotations
59+
60+
i
6961
}
7062

7163
fn main() {

tests/ui/missing_transmute_annotations.stderr

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
error: transmute used without annotations
2-
--> tests/ui/missing_transmute_annotations.rs:20:15
2+
--> tests/ui/missing_transmute_annotations.rs:35:19
33
|
4-
LL | std::mem::transmute([1u16, 2u16])
5-
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
4+
LL | i = std::mem::transmute([1u16, 2u16]);
5+
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
66
|
77
= note: `-D clippy::missing-transmute-annotations` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`
99

1010
error: transmute used without annotations
11-
--> tests/ui/missing_transmute_annotations.rs:25:15
11+
--> tests/ui/missing_transmute_annotations.rs:37:19
1212
|
13-
LL | std::mem::transmute::<_, _>([1u16, 2u16])
14-
| ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
13+
LL | i = std::mem::transmute::<_, _>([1u16, 2u16]);
14+
| ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
1515

1616
error: transmute used without annotations
17-
--> tests/ui/missing_transmute_annotations.rs:30:15
17+
--> tests/ui/missing_transmute_annotations.rs:39:19
1818
|
19-
LL | std::mem::transmute::<_, i32>([1u16, 2u16])
20-
| ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
19+
LL | i = std::mem::transmute::<_, i32>([1u16, 2u16]);
20+
| ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
2121

2222
error: transmute used without annotations
23-
--> tests/ui/missing_transmute_annotations.rs:35:15
23+
--> tests/ui/missing_transmute_annotations.rs:41:19
2424
|
25-
LL | std::mem::transmute::<[u16; 2], _>([1u16, 2u16])
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
25+
LL | i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
2727

2828
error: transmute used without annotations
29-
--> tests/ui/missing_transmute_annotations.rs:40:32
29+
--> tests/ui/missing_transmute_annotations.rs:44:32
3030
|
3131
LL | let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
3333

3434
error: transmute used without annotations
35-
--> tests/ui/missing_transmute_annotations.rs:42:19
35+
--> tests/ui/missing_transmute_annotations.rs:46:19
3636
|
37-
LL | bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]))
37+
LL | bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
3838
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
3939

4040
error: transmute used without annotations
@@ -43,31 +43,31 @@ error: transmute used without annotations
4343
LL | std::mem::transmute($e)
4444
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
4545
...
46-
LL | local_bad_transmute!([1u16, 2u16])
47-
| ---------------------------------- in this macro invocation
46+
LL | i = local_bad_transmute!([1u16, 2u16]);
47+
| ---------------------------------- in this macro invocation
4848
|
4949
= note: this error originates in the macro `local_bad_transmute` (in Nightly builds, run with -Z macro-backtrace for more info)
5050

5151
error: transmute used without annotations
52-
--> tests/ui/missing_transmute_annotations.rs:62:15
52+
--> tests/ui/missing_transmute_annotations.rs:54:19
5353
|
54-
LL | std::mem::transmute(0i32)
55-
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<i32, Foo>`
54+
LL | i = std::mem::transmute([0i16, 0i16]);
55+
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[i16; 2], i32>`
5656

5757
error: transmute used without annotations
58-
--> tests/ui/missing_transmute_annotations.rs:67:15
58+
--> tests/ui/missing_transmute_annotations.rs:57:19
5959
|
60-
LL | std::mem::transmute(Foo::A)
61-
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>`
60+
LL | i = std::mem::transmute(Foo::A);
61+
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>`
6262

6363
error: transmute used without annotations
64-
--> tests/ui/missing_transmute_annotations.rs:72:35
64+
--> tests/ui/missing_transmute_annotations.rs:64:35
6565
|
6666
LL | let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) };
6767
| ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
6868

6969
error: transmute used without annotations
70-
--> tests/ui/missing_transmute_annotations.rs:75:30
70+
--> tests/ui/missing_transmute_annotations.rs:67:30
7171
|
7272
LL | let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);
7373
| ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`

0 commit comments

Comments
 (0)