Rollup merge of #99124 - compiler-errors:issue-99122, r=oli-obk
Fix sized check ICE in asm check Fixes (beta nominated, so doesn't close) #99122 1. Moves a check for unresolved inference variables to _before_ other checks that could possibly ICE. We're not changing behavior here, just doing the same thing earlier in the function. 2. Erases region variables in sized check (which are not resolved at this point) because rustc will also ICE when region vars are passed to a query which does not canonicalize them.
This commit is contained in:
commit
7151aaf940
@ -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) {
|
||||
|
21
src/test/ui/asm/issue-99122-2.rs
Normal file
21
src/test/ui/asm/issue-99122-2.rs
Normal file
@ -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() {}
|
13
src/test/ui/asm/issue-99122.rs
Normal file
13
src/test/ui/asm/issue-99122.rs
Normal file
@ -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() {}
|
11
src/test/ui/asm/issue-99122.stderr
Normal file
11
src/test/ui/asm/issue-99122.stderr
Normal file
@ -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`.
|
Loading…
x
Reference in New Issue
Block a user