about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-02-25 18:12:32 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2024-03-24 00:50:26 +0100
commitffa12798c0f24fb2fe8659aa917a9b9308f8bc7b (patch)
tree34587896cc0fc38e895ced4e3d370d4a797d16d4
parent8e0496170d7f655f1e14887e22e12f7795bdb394 (diff)
Correctly handle `transmute` as return value from `block` and `let var: _ = transmute`
-rw-r--r--clippy_lints/src/transmute/missing_transmute_annotations.rs33
-rw-r--r--tests/ui/missing_transmute_annotations.fixed7
-rw-r--r--tests/ui/missing_transmute_annotations.rs7
-rw-r--r--tests/ui/missing_transmute_annotations.stderr32
4 files changed, 64 insertions, 15 deletions
diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs
index cbc52b6b801..84f3d9c169a 100644
--- a/clippy_lints/src/transmute/missing_transmute_annotations.rs
+++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs
@@ -1,5 +1,5 @@
 use rustc_errors::Applicability;
-use rustc_hir::{GenericArg, HirId, Node, Path, TyKind};
+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;
@@ -8,6 +8,27 @@ 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>> {
+    let mut parent_iter = cx.tcx.hir().parent_iter(expr_hir_id);
+    if let Some((_, node)) = parent_iter.next() {
+        match node {
+            Node::Local(local) => Some(*local),
+            Node::Block(_) => {
+                if let Some((parent_hir_id, Node::Expr(expr))) = parent_iter.next()
+                    && matches!(expr.kind, rustc_hir::ExprKind::Block(_, _))
+                {
+                    get_parent_local_binding_ty(cx, parent_hir_id)
+                } else {
+                    None
+                }
+            },
+            _ => None,
+        }
+    } else {
+        None
+    }
+}
+
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     path: &Path<'tcx>,
@@ -33,12 +54,14 @@ pub(super) fn check<'tcx>(
         return false;
     }
     // If it's being set as a local variable value...
-    if let Some((_, node)) = cx.tcx.hir().parent_iter(expr_hir_id).next()
-        && let Node::Local(local) = node
+    if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id)
         // ... which does have type annotations.
-        && local.ty.is_some()
+        && let Some(ty) = local.ty
     {
-        return false;
+        // If this is a `let x: _ =`, we shouldn't lint.
+        if !matches!(ty.kind, TyKind::Infer) {
+            return false;
+        }
     }
     span_lint_and_sugg(
         cx,
diff --git a/tests/ui/missing_transmute_annotations.fixed b/tests/ui/missing_transmute_annotations.fixed
index cf6117b171b..7fe8063f40f 100644
--- a/tests/ui/missing_transmute_annotations.fixed
+++ b/tests/ui/missing_transmute_annotations.fixed
@@ -1,6 +1,7 @@
 //@aux-build:macro_rules.rs
 
 #![warn(clippy::missing_transmute_annotations)]
+#![allow(clippy::let_with_type_underscore)]
 
 #[macro_use]
 extern crate macro_rules;
@@ -68,7 +69,12 @@ unsafe fn foo9() -> i32 {
 }
 
 fn main() {
+    let x: _ = unsafe { std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) };
+    //~^ ERROR: transmute used without annotations
     unsafe {
+        let x: _ = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+        //~^ ERROR: transmute used without annotations
+
         // Should not warn.
         std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
         let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
@@ -76,4 +82,5 @@ fn main() {
         let x: i32 = std::mem::transmute::<_, i32>([1u16, 2u16]);
         let x: i32 = std::mem::transmute([1u16, 2u16]);
     }
+    let x: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
 }
diff --git a/tests/ui/missing_transmute_annotations.rs b/tests/ui/missing_transmute_annotations.rs
index 53fd7a84939..9c42077054e 100644
--- a/tests/ui/missing_transmute_annotations.rs
+++ b/tests/ui/missing_transmute_annotations.rs
@@ -1,6 +1,7 @@
 //@aux-build:macro_rules.rs
 
 #![warn(clippy::missing_transmute_annotations)]
+#![allow(clippy::let_with_type_underscore)]
 
 #[macro_use]
 extern crate macro_rules;
@@ -68,7 +69,12 @@ unsafe fn foo9() -> i32 {
 }
 
 fn main() {
+    let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) };
+    //~^ ERROR: transmute used without annotations
     unsafe {
+        let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);
+        //~^ ERROR: transmute used without annotations
+
         // Should not warn.
         std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
         let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
@@ -76,4 +82,5 @@ fn main() {
         let x: i32 = std::mem::transmute::<_, i32>([1u16, 2u16]);
         let x: i32 = std::mem::transmute([1u16, 2u16]);
     }
+    let x: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
 }
diff --git a/tests/ui/missing_transmute_annotations.stderr b/tests/ui/missing_transmute_annotations.stderr
index 9f2e8e8c9e7..180cd007b13 100644
--- a/tests/ui/missing_transmute_annotations.stderr
+++ b/tests/ui/missing_transmute_annotations.stderr
@@ -1,5 +1,5 @@
 error: transmute used without annotations
-  --> tests/ui/missing_transmute_annotations.rs:19:15
+  --> tests/ui/missing_transmute_annotations.rs:20:15
    |
 LL |     std::mem::transmute([1u16, 2u16])
    |               ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
@@ -8,37 +8,37 @@ LL |     std::mem::transmute([1u16, 2u16])
    = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`
 
 error: transmute used without annotations
-  --> tests/ui/missing_transmute_annotations.rs:24:15
+  --> tests/ui/missing_transmute_annotations.rs:25:15
    |
 LL |     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:29:15
+  --> tests/ui/missing_transmute_annotations.rs:30:15
    |
 LL |     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:34:15
+  --> tests/ui/missing_transmute_annotations.rs:35:15
    |
 LL |     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:39:32
+  --> tests/ui/missing_transmute_annotations.rs:40: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:41:19
+  --> tests/ui/missing_transmute_annotations.rs:42:19
    |
 LL |     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:10:19
+  --> tests/ui/missing_transmute_annotations.rs:11:19
    |
 LL |         std::mem::transmute($e)
    |                   ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
@@ -49,16 +49,28 @@ LL |     local_bad_transmute!([1u16, 2u16])
    = 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:61:15
+  --> tests/ui/missing_transmute_annotations.rs:62:15
    |
 LL |     std::mem::transmute(0i32)
    |               ^^^^^^^^^ help: consider adding missing annotations: `transmute::<i32, Foo>`
 
 error: transmute used without annotations
-  --> tests/ui/missing_transmute_annotations.rs:66:15
+  --> tests/ui/missing_transmute_annotations.rs:67:15
    |
 LL |     std::mem::transmute(Foo::A)
    |               ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>`
 
-error: aborting due to 9 previous errors
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:72: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
+   |
+LL |         let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);
+   |                              ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: aborting due to 11 previous errors