Skip to content

Commit db4e980

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
2 parents 542d036 + 3ac69d7 commit db4e980

File tree

4 files changed

+52
-21
lines changed

4 files changed

+52
-21
lines changed

Diff for: 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) {

Diff for: src/test/ui/asm/issue-99122-2.rs

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

Diff for: src/test/ui/asm/issue-99122.rs

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

Diff for: 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:2: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)