Skip to content

Commit b016af5

Browse files
Do no emit missing_transmute_annotations lint if the transmute is the only expr in the function
1 parent 7a72740 commit b016af5

File tree

4 files changed

+88
-96
lines changed

4 files changed

+88
-96
lines changed

clippy_lints/src/transmute/missing_transmute_annotations.rs

Lines changed: 22 additions & 8 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;
2-
use rustc_hir::{GenericArg, HirId, Local, Node, Path, TyKind};
3+
use rustc_hir::{GenericArg, HirId, ItemKind, 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,18 @@ 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+
for (_, node) in cx.tcx.hir().parent_iter(expr_hir_id) {
33+
if let Node::Item(item) = node
34+
&& let ItemKind::Fn(_, _, body_id) = item.kind
35+
{
36+
let body = cx.tcx.hir().body(body_id);
37+
return body.value.peel_blocks().hir_id == expr_hir_id;
38+
}
39+
}
40+
false
41+
}
42+
3243
pub(super) fn check<'tcx>(
3344
cx: &LateContext<'tcx>,
3445
path: &Path<'tcx>,
@@ -54,14 +65,17 @@ pub(super) fn check<'tcx>(
5465
return false;
5566
}
5667
// If it's being set as a local variable value...
57-
if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id)
68+
if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) {
5869
// ... 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) {
70+
if let Some(ty) = local.ty
71+
// If this is a `let x: _ =`, we shouldn't lint.
72+
&& !matches!(ty.kind, TyKind::Infer)
73+
{
6374
return false;
6475
}
76+
// We check if this transmute is not the only element in the function
77+
} else if is_function_block(cx, expr_hir_id) {
78+
return false;
6579
}
6680
span_lint_and_sugg(
6781
cx,

tests/ui/missing_transmute_annotations.fixed

Lines changed: 21 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,43 @@ 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
25+
#[repr(i32)]
26+
enum Foo {
27+
A = 0,
2728
}
2829

29-
unsafe fn foo3() -> i32 {
30-
std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])
30+
unsafe fn foo2() -> i32 {
31+
let mut i: i32 = 0;
32+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
3133
//~^ ERROR: transmute used without annotations
32-
}
33-
34-
unsafe fn foo4() -> i32 {
35-
std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])
34+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
35+
//~^ ERROR: transmute used without annotations
36+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
37+
//~^ ERROR: transmute used without annotations
38+
i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
3639
//~^ ERROR: transmute used without annotations
37-
}
3840

39-
unsafe fn foo5() -> i32 {
4041
let x: i32 = bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));
4142
//~^ ERROR: transmute used without annotations
42-
bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]))
43+
bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));
4344
//~^ ERROR: transmute used without annotations
44-
}
4545

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

51-
unsafe fn foo7() -> i32 {
5248
// Should not warn.
53-
bad_transmute!([1u16, 2u16])
54-
}
49+
i = bad_transmute!([1u16, 2u16]);
5550

56-
#[repr(i32)]
57-
enum Foo {
58-
A = 0,
59-
}
60-
61-
unsafe fn foo8() -> Foo {
62-
std::mem::transmute::<i32, Foo>(0i32)
51+
i = std::mem::transmute::<[i16; 2], i32>([0i16, 0i16]);
6352
//~^ ERROR: transmute used without annotations
64-
}
6553

66-
unsafe fn foo9() -> i32 {
67-
std::mem::transmute::<Foo, i32>(Foo::A)
54+
i = std::mem::transmute::<Foo, i32>(Foo::A);
6855
//~^ ERROR: transmute used without annotations
56+
57+
i
6958
}
7059

7160
fn main() {

tests/ui/missing_transmute_annotations.rs

Lines changed: 20 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,43 @@ 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
25+
#[repr(i32)]
26+
enum Foo {
27+
A = 0,
2728
}
2829

29-
unsafe fn foo3() -> i32 {
30-
std::mem::transmute::<_, i32>([1u16, 2u16])
30+
unsafe fn foo2() -> i32 {
31+
let mut i: i32 = 0;
32+
i = std::mem::transmute([1u16, 2u16]);
3133
//~^ ERROR: transmute used without annotations
32-
}
33-
34-
unsafe fn foo4() -> i32 {
35-
std::mem::transmute::<[u16; 2], _>([1u16, 2u16])
34+
i = std::mem::transmute::<_, _>([1u16, 2u16]);
35+
//~^ ERROR: transmute used without annotations
36+
i = std::mem::transmute::<_, i32>([1u16, 2u16]);
37+
//~^ ERROR: transmute used without annotations
38+
i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
3639
//~^ ERROR: transmute used without annotations
37-
}
3840

39-
unsafe fn foo5() -> i32 {
4041
let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
4142
//~^ ERROR: transmute used without annotations
42-
bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]))
43+
bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
4344
//~^ ERROR: transmute used without annotations
44-
}
4545

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

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

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

66-
unsafe fn foo9() -> i32 {
67-
std::mem::transmute(Foo::A)
54+
i = std::mem::transmute(Foo::A);
6855
//~^ ERROR: transmute used without annotations
56+
57+
i
6958
}
7059

7160
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:32: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:34: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:36: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:38: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:41: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:43: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:51: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:54: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:61: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:64: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)