diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-03-15 18:42:35 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-03-24 00:50:28 +0100 |
| commit | ee2558223f51b894475dcd1458b21f7ea393508a (patch) | |
| tree | d337e869113574909b7542ad737fdbb2bceea134 | |
| parent | ffa12798c0f24fb2fe8659aa917a9b9308f8bc7b (diff) | |
| download | rust-ee2558223f51b894475dcd1458b21f7ea393508a.tar.gz rust-ee2558223f51b894475dcd1458b21f7ea393508a.zip | |
Do no emit `missing_transmute_annotations` lint if the `transmute` is the only expr in the function
| -rw-r--r-- | clippy_lints/src/transmute/missing_transmute_annotations.rs | 25 | ||||
| -rw-r--r-- | tests/ui/missing_transmute_annotations.fixed | 56 | ||||
| -rw-r--r-- | tests/ui/missing_transmute_annotations.rs | 54 | ||||
| -rw-r--r-- | tests/ui/missing_transmute_annotations.stderr | 50 |
4 files changed, 90 insertions, 95 deletions
diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs index 84f3d9c169a..ec7041b945b 100644 --- a/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -1,11 +1,10 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_errors::Applicability; use rustc_hir::{GenericArg, HirId, Local, Node, Path, TyKind}; use rustc_lint::LateContext; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::Ty; -use clippy_utils::diagnostics::span_lint_and_sugg; - use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS; 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) } } +fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { + let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); + if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id) { + let body = cx.tcx.hir().body(body_id); + return body.value.peel_blocks().hir_id == expr_hir_id; + } + false +} + pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, path: &Path<'tcx>, @@ -54,14 +62,17 @@ pub(super) fn check<'tcx>( return false; } // If it's being set as a local variable value... - if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) + if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) { // ... which does have type annotations. - && let Some(ty) = local.ty - { - // If this is a `let x: _ =`, we shouldn't lint. - if !matches!(ty.kind, TyKind::Infer) { + if let Some(ty) = local.ty + // If this is a `let x: _ =`, we should lint. + && !matches!(ty.kind, TyKind::Infer) + { return false; } + // We check if this transmute is not the only element in the function + } else if is_function_block(cx, expr_hir_id) { + return false; } span_lint_and_sugg( cx, diff --git a/tests/ui/missing_transmute_annotations.fixed b/tests/ui/missing_transmute_annotations.fixed index 7fe8063f40f..a3c94ab139e 100644 --- a/tests/ui/missing_transmute_annotations.fixed +++ b/tests/ui/missing_transmute_annotations.fixed @@ -9,6 +9,7 @@ extern crate macro_rules; macro_rules! local_bad_transmute { ($e:expr) => { std::mem::transmute::<[u16; 2], i32>($e) + //~^ ERROR: transmute used without annotations }; } @@ -17,55 +18,46 @@ fn bar(x: i32) -> i32 { } unsafe fn foo1() -> i32 { - std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) - //~^ ERROR: transmute used without annotations + // Should not warn! + std::mem::transmute([1u16, 2u16]) } -unsafe fn foo2() -> i32 { - std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) - //~^ ERROR: transmute used without annotations -} +// Should not warn! +const _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) }; -unsafe fn foo3() -> i32 { - std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) - //~^ ERROR: transmute used without annotations +#[repr(i32)] +enum Foo { + A = 0, } -unsafe fn foo4() -> i32 { - std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) +unsafe fn foo2() -> i32 { + let mut i: i32 = 0; + i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]); + //~^ ERROR: transmute used without annotations + i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]); + //~^ ERROR: transmute used without annotations + i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]); + //~^ ERROR: transmute used without annotations + i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]); //~^ ERROR: transmute used without annotations -} -unsafe fn foo5() -> i32 { let x: i32 = bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])); //~^ ERROR: transmute used without annotations - bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])) + bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16])); //~^ ERROR: transmute used without annotations -} -unsafe fn foo6() -> i32 { - local_bad_transmute!([1u16, 2u16]) - //~^ ERROR: transmute used without annotations -} + i = local_bad_transmute!([1u16, 2u16]); -unsafe fn foo7() -> i32 { // Should not warn. - bad_transmute!([1u16, 2u16]) -} - -#[repr(i32)] -enum Foo { - A = 0, -} + i = bad_transmute!([1u16, 2u16]); -unsafe fn foo8() -> Foo { - std::mem::transmute::<i32, Foo>(0i32) + i = std::mem::transmute::<[i16; 2], i32>([0i16, 0i16]); //~^ ERROR: transmute used without annotations -} -unsafe fn foo9() -> i32 { - std::mem::transmute::<Foo, i32>(Foo::A) + i = std::mem::transmute::<Foo, i32>(Foo::A); //~^ ERROR: transmute used without annotations + + i } fn main() { diff --git a/tests/ui/missing_transmute_annotations.rs b/tests/ui/missing_transmute_annotations.rs index 9c42077054e..c12e1b0f8d2 100644 --- a/tests/ui/missing_transmute_annotations.rs +++ b/tests/ui/missing_transmute_annotations.rs @@ -9,6 +9,7 @@ extern crate macro_rules; macro_rules! local_bad_transmute { ($e:expr) => { std::mem::transmute($e) + //~^ ERROR: transmute used without annotations }; } @@ -17,55 +18,46 @@ fn bar(x: i32) -> i32 { } unsafe fn foo1() -> i32 { + // Should not warn! std::mem::transmute([1u16, 2u16]) - //~^ ERROR: transmute used without annotations } -unsafe fn foo2() -> i32 { - std::mem::transmute::<_, _>([1u16, 2u16]) - //~^ ERROR: transmute used without annotations -} +// Should not warn! +const _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) }; -unsafe fn foo3() -> i32 { - std::mem::transmute::<_, i32>([1u16, 2u16]) - //~^ ERROR: transmute used without annotations +#[repr(i32)] +enum Foo { + A = 0, } -unsafe fn foo4() -> i32 { - std::mem::transmute::<[u16; 2], _>([1u16, 2u16]) +unsafe fn foo2() -> i32 { + let mut i: i32 = 0; + i = std::mem::transmute([1u16, 2u16]); + //~^ ERROR: transmute used without annotations + i = std::mem::transmute::<_, _>([1u16, 2u16]); + //~^ ERROR: transmute used without annotations + i = std::mem::transmute::<_, i32>([1u16, 2u16]); + //~^ ERROR: transmute used without annotations + i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]); //~^ ERROR: transmute used without annotations -} -unsafe fn foo5() -> i32 { let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16])); //~^ ERROR: transmute used without annotations - bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16])) + bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16])); //~^ ERROR: transmute used without annotations -} -unsafe fn foo6() -> i32 { - local_bad_transmute!([1u16, 2u16]) - //~^ ERROR: transmute used without annotations -} + i = local_bad_transmute!([1u16, 2u16]); -unsafe fn foo7() -> i32 { // Should not warn. - bad_transmute!([1u16, 2u16]) -} - -#[repr(i32)] -enum Foo { - A = 0, -} + i = bad_transmute!([1u16, 2u16]); -unsafe fn foo8() -> Foo { - std::mem::transmute(0i32) + i = std::mem::transmute([0i16, 0i16]); //~^ ERROR: transmute used without annotations -} -unsafe fn foo9() -> i32 { - std::mem::transmute(Foo::A) + i = std::mem::transmute(Foo::A); //~^ ERROR: transmute used without annotations + + i } fn main() { diff --git a/tests/ui/missing_transmute_annotations.stderr b/tests/ui/missing_transmute_annotations.stderr index 180cd007b13..5903ed488ef 100644 --- a/tests/ui/missing_transmute_annotations.stderr +++ b/tests/ui/missing_transmute_annotations.stderr @@ -1,40 +1,40 @@ error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:20:15 + --> tests/ui/missing_transmute_annotations.rs:35:19 | -LL | std::mem::transmute([1u16, 2u16]) - | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` +LL | i = std::mem::transmute([1u16, 2u16]); + | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` | = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:25:15 + --> tests/ui/missing_transmute_annotations.rs:37:19 | -LL | std::mem::transmute::<_, _>([1u16, 2u16]) - | ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` +LL | i = std::mem::transmute::<_, _>([1u16, 2u16]); + | ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:30:15 + --> tests/ui/missing_transmute_annotations.rs:39:19 | -LL | std::mem::transmute::<_, i32>([1u16, 2u16]) - | ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` +LL | i = std::mem::transmute::<_, i32>([1u16, 2u16]); + | ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:35:15 + --> tests/ui/missing_transmute_annotations.rs:41:19 | -LL | std::mem::transmute::<[u16; 2], _>([1u16, 2u16]) - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` +LL | i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:40:32 + --> tests/ui/missing_transmute_annotations.rs:44:32 | LL | let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16])); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:42:19 + --> tests/ui/missing_transmute_annotations.rs:46:19 | -LL | bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16])) +LL | bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16])); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` error: transmute used without annotations @@ -43,31 +43,31 @@ error: transmute used without annotations LL | std::mem::transmute($e) | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` ... -LL | local_bad_transmute!([1u16, 2u16]) - | ---------------------------------- in this macro invocation +LL | i = local_bad_transmute!([1u16, 2u16]); + | ---------------------------------- in this macro invocation | = note: this error originates in the macro `local_bad_transmute` (in Nightly builds, run with -Z macro-backtrace for more info) error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:62:15 + --> tests/ui/missing_transmute_annotations.rs:54:19 | -LL | std::mem::transmute(0i32) - | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<i32, Foo>` +LL | i = std::mem::transmute([0i16, 0i16]); + | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[i16; 2], i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:67:15 + --> tests/ui/missing_transmute_annotations.rs:57:19 | -LL | std::mem::transmute(Foo::A) - | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>` +LL | i = std::mem::transmute(Foo::A); + | ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:72:35 + --> tests/ui/missing_transmute_annotations.rs:64:35 | LL | let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) }; | ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` error: transmute used without annotations - --> tests/ui/missing_transmute_annotations.rs:75:30 + --> tests/ui/missing_transmute_annotations.rs:67:30 | LL | let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]); | ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>` |
