Skip to content

Commit 7151aaf

Browse files
authored
Rollup merge of rust-lang#99124 - compiler-errors:issue-99122, r=oli-obk
Fix sized check ICE in asm check Fixes (beta nominated, so doesn't close) rust-lang#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.
2 parents d89c183 + 5c6560f commit 7151aaf

File tree

4 files changed

+58
-21
lines changed

4 files changed

+58
-21
lines changed

compiler/rustc_typeck/src/check/intrinsicck.rs

+13-21
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_errors::struct_span_err;
44
use rustc_hir as hir;
55
use rustc_index::vec::Idx;
66
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
7-
use rustc_middle::ty::{self, Article, FloatTy, InferTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
7+
use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
88
use rustc_session::lint;
99
use rustc_span::{Span, Symbol, DUMMY_SP};
1010
use rustc_target::abi::{Pointer, VariantIdx};
@@ -99,8 +99,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9999
err.emit();
100100
}
101101

102+
// FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
102103
fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
103-
if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
104+
// Type still may have region variables, but `Sized` does not depend
105+
// on those, so just erase them before querying.
106+
if self.tcx.erase_regions(ty).is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
104107
return true;
105108
}
106109
if let ty::Foreign(..) = ty.kind() {
@@ -128,30 +131,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128131
64 => InlineAsmType::I64,
129132
_ => unreachable!(),
130133
};
134+
135+
// Expect types to be fully resolved, no const or type variables.
136+
if ty.has_infer_types_or_consts() {
137+
assert!(self.is_tainted_by_errors());
138+
return None;
139+
}
140+
131141
let asm_ty = match *ty.kind() {
132142
// `!` is allowed for input but not for output (issue #87802)
133143
ty::Never if is_input => return None,
134144
ty::Error(_) => return None,
135145
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
136146
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
137-
// Somewhat of a hack: fallback in the presence of errors does not actually
138-
// fall back to i32, but to ty::Error. For integer inference variables this
139-
// means that they don't get any fallback and stay as `{integer}`.
140-
// Since compilation can't succeed anyway, it's fine to use this to avoid printing
141-
// "cannot use value of type `{integer}`", even though that would absolutely
142-
// work due due i32 fallback if the current function had no other errors.
143-
ty::Infer(InferTy::IntVar(_)) => {
144-
assert!(self.is_tainted_by_errors());
145-
Some(InlineAsmType::I32)
146-
}
147147
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
148148
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64),
149149
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128),
150150
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize),
151-
ty::Infer(InferTy::FloatVar(_)) => {
152-
assert!(self.is_tainted_by_errors());
153-
Some(InlineAsmType::F32)
154-
}
155151
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
156152
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
157153
ty::FnPtr(_) => Some(asm_ty_isize),
@@ -191,6 +187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
191187
_ => None,
192188
}
193189
}
190+
ty::Infer(_) => unreachable!(),
194191
_ => None,
195192
};
196193
let Some(asm_ty) = asm_ty else {
@@ -204,11 +201,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
204201
return None;
205202
};
206203

207-
if ty.has_infer_types_or_consts() {
208-
assert!(self.is_tainted_by_errors());
209-
return None;
210-
}
211-
212204
// Check that the type implements Copy. The only case where this can
213205
// possibly fail is for SIMD types which don't #[derive(Copy)].
214206
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, DUMMY_SP) {

src/test/ui/asm/issue-99122-2.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
// needs-asm-support
3+
// only-x86_64
4+
5+
// This demonstrates why we need to erase regions before sized check in intrinsicck
6+
7+
struct NoCopy;
8+
9+
struct Wrap<'a, T, Tail: ?Sized>(&'a T, Tail);
10+
11+
pub unsafe fn test() {
12+
let i = NoCopy;
13+
let j = Wrap(&i, ());
14+
let pointer = &j as *const _;
15+
core::arch::asm!(
16+
"nop",
17+
in("eax") pointer,
18+
);
19+
}
20+
21+
fn main() {}

src/test/ui/asm/issue-99122.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// needs-asm-support
2+
// only-x86_64
3+
4+
pub unsafe fn test() {
5+
let pointer = 1u32 as *const _;
6+
//~^ ERROR cannot cast to a pointer of an unknown kind
7+
core::arch::asm!(
8+
"nop",
9+
in("eax") pointer,
10+
);
11+
}
12+
13+
fn main() {}

src/test/ui/asm/issue-99122.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0641]: cannot cast to a pointer of an unknown kind
2+
--> $DIR/issue-99122.rs:5:27
3+
|
4+
LL | let pointer = 1u32 as *const _;
5+
| ^^^^^^^^ needs more type information
6+
|
7+
= note: the type information given here is insufficient to check whether the pointer cast is valid
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0641`.

0 commit comments

Comments
 (0)