Skip to content

Commit 45971a5

Browse files
Add ui test for missing_transmute_annotation
1 parent 05272ce commit 45971a5

File tree

5 files changed

+124
-16
lines changed

5 files changed

+124
-16
lines changed
Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
use rustc_errors::Applicability;
2-
use rustc_hir::{GenericArg, Path, TyKind};
2+
use rustc_hir::{GenericArg, HirId, Node, Path, TyKind};
33
use rustc_lint::LateContext;
4+
use rustc_middle::lint::in_external_macro;
45
use rustc_middle::ty::Ty;
56

67
use clippy_utils::diagnostics::span_lint_and_sugg;
78

89
use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
910

10-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, path: &Path<'tcx>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
11+
pub(super) fn check<'tcx>(
12+
cx: &LateContext<'tcx>,
13+
path: &Path<'tcx>,
14+
from_ty: Ty<'tcx>,
15+
to_ty: Ty<'tcx>,
16+
expr_hir_id: HirId,
17+
) -> bool {
1118
let last = path.segments.last().unwrap();
19+
if in_external_macro(cx.tcx.sess, last.ident.span) {
20+
// If it comes from a non-local macro, we ignore it.
21+
return false;
22+
}
1223
let args = last.args;
1324
let missing_generic = match args {
1425
Some(args) if !args.args.is_empty() => args.args.iter().any(|arg| match arg {
@@ -18,18 +29,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, path: &Path<'tcx>, from_ty: Ty
1829
}),
1930
_ => true,
2031
};
21-
if missing_generic {
22-
span_lint_and_sugg(
23-
cx,
24-
MISSING_TRANSMUTE_ANNOTATIONS,
25-
last.ident.span.with_hi(path.span.hi()),
26-
"transmute used without annotations",
27-
"consider adding missing annotations",
28-
format!("{}::<{from_ty}, {to_ty}>", last.ident.as_str()),
29-
Applicability::MaybeIncorrect,
30-
);
31-
true
32-
} else {
33-
false
32+
if !missing_generic {
33+
return false;
34+
}
35+
// If it's being set as a local variable value...
36+
if let Some((_, node)) = cx.tcx.hir().parent_iter(expr_hir_id).next()
37+
&& let Node::Local(local) = node
38+
// ... which does have type annotations.
39+
&& local.ty.is_some()
40+
{
41+
return false;
3442
}
43+
span_lint_and_sugg(
44+
cx,
45+
MISSING_TRANSMUTE_ANNOTATIONS,
46+
last.ident.span.with_hi(path.span.hi()),
47+
"transmute used without annotations",
48+
"consider adding missing annotations",
49+
format!("{}::<{from_ty}, {to_ty}>", last.ident.as_str()),
50+
Applicability::MaybeIncorrect,
51+
);
52+
true
3553
}

clippy_lints/src/transmute/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
612612
| transmuting_null::check(cx, e, arg, to_ty)
613613
| transmute_null_to_fn::check(cx, e, arg, to_ty)
614614
| transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, &self.msrv)
615-
| missing_transmute_annotations::check(cx, path, from_ty, to_ty)
615+
| missing_transmute_annotations::check(cx, path, from_ty, to_ty, e.hir_id)
616616
| transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
617617
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
618618
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![warn(clippy::missing_transmute_annotations)]
2+
3+
macro_rules! bad_transmute {
4+
($e:expr) => {
5+
std::mem::transmute::<[u16; 2], i32>($e)
6+
};
7+
}
8+
9+
fn main() {
10+
unsafe {
11+
let x: i32 = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
12+
//~^ ERROR: transmute used without annotations
13+
let x: i32 = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
14+
//~^ ERROR: transmute used without annotations
15+
let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
16+
//~^ ERROR: transmute used without annotations
17+
let x: i32 = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
18+
//~^ ERROR: transmute used without annotations
19+
let x: i32 = bad_transmute!([1u16, 2u16]);
20+
//~^ ERROR: transmute used without annotations
21+
22+
// Should not warn.
23+
let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
24+
}
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![warn(clippy::missing_transmute_annotation)]
2+
3+
macro_rules! bad_transmute {
4+
($e:expr) => {
5+
std::mem::transmute($e)
6+
};
7+
}
8+
9+
fn main() {
10+
unsafe {
11+
let x: i32 = std::mem::transmute([1u16, 2u16]);
12+
//~^ ERROR: transmute used without annotations
13+
let x: i32 = std::mem::transmute::<_, _>([1u16, 2u16]);
14+
//~^ ERROR: transmute used without annotations
15+
let x = std::mem::transmute::<_, i32>([1u16, 2u16]);
16+
//~^ ERROR: transmute used without annotations
17+
let x: i32 = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
18+
//~^ ERROR: transmute used without annotations
19+
let x: i32 = bad_transmute!([1u16, 2u16]);
20+
//~^ ERROR: transmute used without annotations
21+
22+
// Should not warn.
23+
let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
24+
}
25+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error: transmute used without annotations
2+
--> $DIR/missing_transmute_annotations.rs:11:32
3+
|
4+
LL | let x: i32 = std::mem::transmute([1u16, 2u16]);
5+
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
6+
|
7+
= note: `-D clippy::missing-transmute-annotation` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotation)]`
9+
10+
error: transmute used without annotations
11+
--> $DIR/missing_transmute_annotations.rs:13:32
12+
|
13+
LL | let x: i32 = std::mem::transmute::<_, _>([1u16, 2u16]);
14+
| ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
15+
16+
error: transmute used without annotations
17+
--> $DIR/missing_transmute_annotations.rs:15:27
18+
|
19+
LL | let x = std::mem::transmute::<_, i32>([1u16, 2u16]);
20+
| ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
21+
22+
error: transmute used without annotations
23+
--> $DIR/missing_transmute_annotations.rs:17:32
24+
|
25+
LL | let x: i32 = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
27+
28+
error: transmute used without annotations
29+
--> $DIR/missing_transmute_annotations.rs:5:19
30+
|
31+
LL | std::mem::transmute($e)
32+
| ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
33+
...
34+
LL | let x: i32 = bad_transmute!([1u16, 2u16]);
35+
| ---------------------------- in this macro invocation
36+
|
37+
= note: this error originates in the macro `bad_transmute` (in Nightly builds, run with -Z macro-backtrace for more info)
38+
39+
error: aborting due to 5 previous errors
40+

0 commit comments

Comments
 (0)