about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille Gillot <gillot.camille@gmail.com>2025-08-15 18:28:40 +0000
committerCamille Gillot <gillot.camille@gmail.com>2025-08-22 20:10:27 +0000
commit9fe0b28db2439efa1a8147870c3e50f26f426ab5 (patch)
treee88ed373b5365e11873863dba6fc6a532d15ff91
parenta3c878f813dd9c7c788cbe8d817699f2ef927e4e (diff)
downloadrust-9fe0b28db2439efa1a8147870c3e50f26f426ab5.tar.gz
rust-9fe0b28db2439efa1a8147870c3e50f26f426ab5.zip
Simplify implementation.
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs90
1 files changed, 46 insertions, 44 deletions
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index fffff7e6f8c..7567f8ba348 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -7,7 +7,7 @@ use rustc_hir as hir;
 use rustc_index::Idx;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefId;
 use tracing::trace;
 
@@ -38,6 +38,37 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     ty
 }
 
+/// Try to display a sensible error with as much information as possible.
+fn skeleton_string<'tcx>(
+    ty: Ty<'tcx>,
+    sk: Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>>,
+) -> String {
+    match sk {
+        Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"),
+        Ok(SizeSkeleton::Known(size, _)) => {
+            if let Some(v) = u128::from(size.bytes()).checked_mul(8) {
+                format!("{v} bits")
+            } else {
+                // `u128` should definitely be able to hold the size of different architectures
+                // larger sizes should be reported as error `are too big for the target architecture`
+                // otherwise we have a bug somewhere
+                bug!("{:?} overflow for u128", size)
+            }
+        }
+        Ok(SizeSkeleton::Generic(size)) => {
+            format!("generic size {size}")
+        }
+        Err(LayoutError::TooGeneric(bad)) => {
+            if *bad == ty {
+                "this type does not have a fixed size".to_owned()
+            } else {
+                format!("size can vary because of {bad}")
+            }
+        }
+        Err(err) => err.to_string(),
+    }
+}
+
 fn check_transmute<'tcx>(
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
@@ -45,40 +76,36 @@ fn check_transmute<'tcx>(
     to: Ty<'tcx>,
     hir_id: HirId,
 ) {
-    let dl = &tcx.data_layout;
-    let span = tcx.hir_span(hir_id);
+    let span = || tcx.hir_span(hir_id);
     let normalize = |ty| {
         if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) {
             ty
         } else {
             Ty::new_error_with_message(
                 tcx,
-                span,
+                span(),
                 format!("tried to normalize non-wf type {ty:#?} in check_transmute"),
             )
         }
     };
+
     let from = normalize(from);
     let to = normalize(to);
     trace!(?from, ?to);
-    if from.has_non_region_infer() || to.has_non_region_infer() {
-        // Note: this path is currently not reached in any test, so any
-        // example that triggers this would be worth minimizing and
-        // converting into a test.
-        tcx.sess.dcx().span_bug(span, "argument to transmute has inference variables");
-    }
+
     // Transmutes that are only changing lifetimes are always ok.
     if from == to {
         return;
     }
 
-    let skel = |ty| SizeSkeleton::compute(ty, tcx, typing_env);
-    let sk_from = skel(from);
-    let sk_to = skel(to);
+    let sk_from = SizeSkeleton::compute(from, tcx, typing_env);
+    let sk_to = SizeSkeleton::compute(to, tcx, typing_env);
     trace!(?sk_from, ?sk_to);
 
     // Check for same size using the skeletons.
-    if let (Ok(sk_from), Ok(sk_to)) = (sk_from, sk_to) {
+    if let Ok(sk_from) = sk_from
+        && let Ok(sk_to) = sk_to
+    {
         if sk_from.same_size(sk_to) {
             return;
         }
@@ -86,10 +113,11 @@ fn check_transmute<'tcx>(
         // Special-case transmuting from `typeof(function)` and
         // `Option<typeof(function)>` to present a clearer error.
         let from = unpack_option_like(tcx, from);
-        if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to)
-            && size_to == Pointer(dl.instruction_address_space).size(&tcx)
+        if let ty::FnDef(..) = from.kind()
+            && let SizeSkeleton::Known(size_to, _) = sk_to
+            && size_to == Pointer(tcx.data_layout.instruction_address_space).size(&tcx)
         {
-            struct_span_code_err!(tcx.sess.dcx(), span, E0591, "can't transmute zero-sized type")
+            struct_span_code_err!(tcx.sess.dcx(), span(), E0591, "can't transmute zero-sized type")
                 .with_note(format!("source type: {from}"))
                 .with_note(format!("target type: {to}"))
                 .with_help("cast with `as` to a pointer instead")
@@ -98,35 +126,9 @@ fn check_transmute<'tcx>(
         }
     }
 
-    // Try to display a sensible error with as much information as possible.
-    let skeleton_string = |ty: Ty<'tcx>, sk: Result<_, &_>| match sk {
-        Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"),
-        Ok(SizeSkeleton::Known(size, _)) => {
-            if let Some(v) = u128::from(size.bytes()).checked_mul(8) {
-                format!("{v} bits")
-            } else {
-                // `u128` should definitely be able to hold the size of different architectures
-                // larger sizes should be reported as error `are too big for the target architecture`
-                // otherwise we have a bug somewhere
-                bug!("{:?} overflow for u128", size)
-            }
-        }
-        Ok(SizeSkeleton::Generic(size)) => {
-            format!("generic size {size}")
-        }
-        Err(LayoutError::TooGeneric(bad)) => {
-            if *bad == ty {
-                "this type does not have a fixed size".to_owned()
-            } else {
-                format!("size can vary because of {bad}")
-            }
-        }
-        Err(err) => err.to_string(),
-    };
-
     let mut err = struct_span_code_err!(
         tcx.sess.dcx(),
-        span,
+        span(),
         E0512,
         "cannot transmute between types of different sizes, or dependently-sized types"
     );