about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/intrinsicck.rs34
-rw-r--r--src/test/ui/asm/issue-99122-2.rs21
-rw-r--r--src/test/ui/asm/issue-99122.rs13
-rw-r--r--src/test/ui/asm/issue-99122.stderr11
4 files changed, 58 insertions, 21 deletions
diff --git a/compiler/rustc_typeck/src/check/intrinsicck.rs b/compiler/rustc_typeck/src/check/intrinsicck.rs
index cc91f2431e0..a5add1e9a8a 100644
--- a/compiler/rustc_typeck/src/check/intrinsicck.rs
+++ b/compiler/rustc_typeck/src/check/intrinsicck.rs
@@ -4,7 +4,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_index::vec::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
-use rustc_middle::ty::{self, Article, FloatTy, InferTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
+use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
 use rustc_session::lint;
 use rustc_span::{Span, Symbol, DUMMY_SP};
 use rustc_target::abi::{Pointer, VariantIdx};
@@ -99,8 +99,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.emit();
     }
 
+    // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
     fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
-        if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
+        // Type still may have region variables, but `Sized` does not depend
+        // on those, so just erase them before querying.
+        if self.tcx.erase_regions(ty).is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
             return true;
         }
         if let ty::Foreign(..) = ty.kind() {
@@ -128,30 +131,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             64 => InlineAsmType::I64,
             _ => unreachable!(),
         };
+
+        // Expect types to be fully resolved, no const or type variables.
+        if ty.has_infer_types_or_consts() {
+            assert!(self.is_tainted_by_errors());
+            return None;
+        }
+
         let asm_ty = match *ty.kind() {
             // `!` is allowed for input but not for output (issue #87802)
             ty::Never if is_input => return None,
             ty::Error(_) => return None,
             ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
             ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
-            // Somewhat of a hack: fallback in the presence of errors does not actually
-            // fall back to i32, but to ty::Error. For integer inference variables this
-            // means that they don't get any fallback and stay as `{integer}`.
-            // Since compilation can't succeed anyway, it's fine to use this to avoid printing
-            // "cannot use value of type `{integer}`", even though that would absolutely
-            // work due due i32 fallback if the current function had no other errors.
-            ty::Infer(InferTy::IntVar(_)) => {
-                assert!(self.is_tainted_by_errors());
-                Some(InlineAsmType::I32)
-            }
             ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
             ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64),
             ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128),
             ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize),
-            ty::Infer(InferTy::FloatVar(_)) => {
-                assert!(self.is_tainted_by_errors());
-                Some(InlineAsmType::F32)
-            }
             ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
             ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
             ty::FnPtr(_) => Some(asm_ty_isize),
@@ -191,6 +187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     _ => None,
                 }
             }
+            ty::Infer(_) => unreachable!(),
             _ => None,
         };
         let Some(asm_ty) = asm_ty else {
@@ -204,11 +201,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        if ty.has_infer_types_or_consts() {
-            assert!(self.is_tainted_by_errors());
-            return None;
-        }
-
         // Check that the type implements Copy. The only case where this can
         // possibly fail is for SIMD types which don't #[derive(Copy)].
         if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, DUMMY_SP) {
diff --git a/src/test/ui/asm/issue-99122-2.rs b/src/test/ui/asm/issue-99122-2.rs
new file mode 100644
index 00000000000..cfb9fd90a55
--- /dev/null
+++ b/src/test/ui/asm/issue-99122-2.rs
@@ -0,0 +1,21 @@
+// check-pass
+// needs-asm-support
+// only-x86_64
+
+// This demonstrates why we need to erase regions before sized check in intrinsicck
+
+struct NoCopy;
+
+struct Wrap<'a, T, Tail: ?Sized>(&'a T, Tail);
+
+pub unsafe fn test() {
+    let i = NoCopy;
+    let j = Wrap(&i, ());
+    let pointer = &j as *const _;
+    core::arch::asm!(
+        "nop",
+        in("eax") pointer,
+    );
+}
+
+fn main() {}
diff --git a/src/test/ui/asm/issue-99122.rs b/src/test/ui/asm/issue-99122.rs
new file mode 100644
index 00000000000..744a563d3d1
--- /dev/null
+++ b/src/test/ui/asm/issue-99122.rs
@@ -0,0 +1,13 @@
+// needs-asm-support
+// only-x86_64
+
+pub unsafe fn test() {
+    let pointer = 1u32 as *const _;
+    //~^ ERROR cannot cast to a pointer of an unknown kind
+    core::arch::asm!(
+        "nop",
+        in("eax") pointer,
+    );
+}
+
+fn main() {}
diff --git a/src/test/ui/asm/issue-99122.stderr b/src/test/ui/asm/issue-99122.stderr
new file mode 100644
index 00000000000..2758a4ac437
--- /dev/null
+++ b/src/test/ui/asm/issue-99122.stderr
@@ -0,0 +1,11 @@
+error[E0641]: cannot cast to a pointer of an unknown kind
+  --> $DIR/issue-99122.rs:5:27
+   |
+LL |     let pointer = 1u32 as *const _;
+   |                           ^^^^^^^^ needs more type information
+   |
+   = note: the type information given here is insufficient to check whether the pointer cast is valid
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0641`.