Skip to content

Instantly share code, notes, and snippets.

@davidtwco
Last active July 19, 2023 14:36
Show Gist options
  • Save davidtwco/5217cf09b356d0ee41b03a6ac929414f to your computer and use it in GitHub Desktop.
Save davidtwco/5217cf09b356d0ee41b03a6ac929414f to your computer and use it in GitHub Desktop.
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 6aeba13f639..4e1aaa0c997 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -85,7 +85,7 @@ fn unsize_ptr<'tcx>(
let mut result = None;
for i in 0..src_layout.fields.count() {
- let src_f = src_layout.field(fx, i);
+ let src_f = src_layout.field(fx, i).expect("tainted field ty");
assert_eq!(src_layout.fields.offset(i).bytes(), 0);
assert_eq!(dst_layout.fields.offset(i).bytes(), 0);
if src_f.is_zst() {
@@ -93,7 +93,7 @@ fn unsize_ptr<'tcx>(
}
assert_eq!(src_layout.size, src_f.size);
- let dst_f = dst_layout.field(fx, i);
+ let dst_f = dst_layout.field(fx, i).expect("tainted field ty");
assert_ne!(src_f.ty, dst_f.ty);
assert_eq!(result, None);
result = Some(unsize_ptr(fx, src, src_f, dst_f, old_info));
@@ -197,7 +197,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
(crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info))
}
ty::Slice(_) | ty::Str => {
- let unit = layout.field(fx, 0);
+ let unit = layout.field(fx, 0).expect("tainted field ty");
// The info in this case is the length of the str, so the size is that
// times the unit size.
(
@@ -218,7 +218,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
// Recurse to get the size of the dynamically sized field (must be
// the last field).
- let field_layout = layout.field(fx, i);
+ let field_layout = layout.field(fx, i).expect("tainted field ty");
let (unsized_size, mut unsized_align) = size_and_align_of_dst(fx, field_layout, info);
// FIXME (#26403, #27023): We should be adding padding
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index ec0b61a7ce5..45b31ab5da2 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -13,7 +13,7 @@ fn codegen_field<'tcx>(
field: FieldIdx,
) -> (Pointer, TyAndLayout<'tcx>) {
let field_offset = layout.fields.offset(field.index());
- let field_layout = layout.field(&*fx, field.index());
+ let field_layout = layout.field(&*fx, field.index()).expect("tainted field ty");
let simple = |fx: &mut FunctionCx<'_, '_, '_>| {
(base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()), field_layout)
@@ -222,7 +222,8 @@ pub(crate) fn value_field(
1 => val2,
_ => bug!("field should be 0 or 1"),
};
- let field_layout = layout.field(&*fx, usize::from(field));
+ let field_layout =
+ layout.field(&*fx, usize::from(field)).expect("tainted field ty");
CValue::by_val(val, field_layout)
}
_ => unreachable!("value_field for ByValPair with abi {:?}", layout.abi),
@@ -671,7 +672,7 @@ pub(crate) fn place_field(
match self.inner {
CPlaceInner::VarPair(local, var1, var2) => {
- let layout = layout.field(&*fx, field.index());
+ let layout = layout.field(&*fx, field.index()).expect("tainted field ty");
match field.as_u32() {
0 => return CPlace { inner: CPlaceInner::Var(local, var1), layout },
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 43d0aafbd50..a9436770f7c 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -862,7 +862,7 @@ fn write_operand_repeatedly(&mut self, cg_elem: OperandRef<'tcx, RValue<'gcc>>,
self.cond_br(keep_going, body_bb, next_bb);
self.switch_to_block(body_bb);
- let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
+ let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).expect("tainted field ty").size);
cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[self.const_usize(1)]);
diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs
index 521b64ad34d..af78ea0c8df 100644
--- a/compiler/rustc_codegen_gcc/src/type_.rs
+++ b/compiler/rustc_codegen_gcc/src/type_.rs
@@ -250,7 +250,7 @@ pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
for i in layout.fields.index_by_increasing_offset() {
let target_offset = layout.fields.offset(i as usize);
- let field = layout.field(cx, i);
+ let field = layout.field(cx, i).expect("tainted field ty");
let effective_field_align =
layout.align.abi.min(field.align.abi).restrict_for_offset(target_offset);
packed |= effective_field_align < field.align.abi;
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 84d57838512..14820e9cca0 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -128,7 +128,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
},
}
}
- FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).gcc_type(cx), count),
+ FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).expect("tainted field ty").gcc_type(cx), count),
FieldsShape::Arbitrary { .. } =>
match name {
None => {
@@ -278,7 +278,7 @@ fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index:
// pointee types, to avoid bitcasting every `OperandRef::deref`.
match self.ty.kind() {
ty::Ref(..) | ty::RawPtr(_) => {
- return self.field(cx, index).gcc_type(cx);
+ return self.field(cx, index).expect("tainted field ty").gcc_type(cx);
}
// only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index c6996f2e16a..bb3466f02bc 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -230,8 +230,9 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
};
let layout = cx.layout_of(layout_type);
- let addr_field = layout.field(cx, abi::FAT_PTR_ADDR);
- let extra_field = layout.field(cx, abi::FAT_PTR_EXTRA);
+ let addr_field = layout.field(cx, abi::FAT_PTR_ADDR).expect("tainted field ty");
+ let extra_field =
+ layout.field(cx, abi::FAT_PTR_EXTRA).expect("tainted field ty");
let (addr_field_name, extra_field_name) = match fat_pointer_kind {
FatPtrKind::Dyn => ("pointer", "vtable"),
@@ -978,7 +979,8 @@ fn build_struct_type_di_node<'ll, 'tcx>(
// This is struct with named fields
Cow::Borrowed(f.name.as_str())
};
- let field_layout = struct_type_and_layout.field(cx, i);
+ let field_layout =
+ struct_type_and_layout.field(cx, i).expect("tainted field ty");
build_field_di_node(
cx,
owner,
@@ -1157,7 +1159,7 @@ fn build_union_type_di_node<'ll, 'tcx>(
.iter()
.enumerate()
.map(|(i, f)| {
- let field_layout = union_ty_and_layout.field(cx, i);
+ let field_layout = union_ty_and_layout.field(cx, i).expect("tainted field ty");
build_field_di_node(
cx,
owner,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index 88040557a9b..6ef6a8e5d41 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -808,7 +808,9 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
}));
debug_assert_eq!(
- cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
+ cx.size_and_align_of(
+ enum_type_and_layout.field(cx, tag_field).expect("tainted field ty").ty
+ ),
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
);
@@ -853,7 +855,9 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>(
cx,
enum_type_di_node,
TAG_FIELD_NAME,
- cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
+ cx.size_and_align_of(
+ enum_type_and_layout.field(cx, tag_field).expect("tainted field ty").ty,
+ ),
enum_type_and_layout.fields.offset(tag_field),
DIFlags::FlagZero,
tag_base_type_di_node,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index b4beb80ca8b..bf3e0fa450c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -281,7 +281,8 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
super::tuple_field_name(field_index)
};
- let field_layout = variant_layout.field(cx, field_index);
+ let field_layout =
+ variant_layout.field(cx, field_index).expect("tainted field ty");
build_field_di_node(
cx,
@@ -362,7 +363,8 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
.map(|s| Cow::from(s.as_str()))
.unwrap_or_else(|| super::tuple_field_name(field_index));
- let field_type = variant_layout.field(cx, field_index).ty;
+ let field_type =
+ variant_layout.field(cx, field_index).expect("tainted field ty").ty;
build_field_di_node(
cx,
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 2dbd467cc84..007a0c68ed5 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -80,7 +80,9 @@ fn uncached_llvm_type<'a, 'tcx>(
}
}
}
- FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).llvm_type(cx), count),
+ FieldsShape::Array { count, .. } => {
+ cx.type_array(layout.field(cx, 0).expect("tainted field ty").llvm_type(cx), count)
+ }
FieldsShape::Arbitrary { .. } => match name {
None => {
let (llfields, packed, new_field_remapping) = struct_llfields(cx, layout);
@@ -110,7 +112,7 @@ fn struct_llfields<'a, 'tcx>(
let mut field_remapping = smallvec![0; field_count];
for i in layout.fields.index_by_increasing_offset() {
let target_offset = layout.fields.offset(i as usize);
- let field = layout.field(cx, i);
+ let field = layout.field(cx, i).expect("tainted field ty");
let effective_field_align =
layout.align.abi.min(field.align.abi).restrict_for_offset(target_offset);
packed |= effective_field_align < field.align.abi;
@@ -332,7 +334,7 @@ fn scalar_pair_element_llvm_type<'a>(
// pointee types, to avoid bitcasting every `OperandRef::deref`.
match *self.ty.kind() {
ty::Ref(..) | ty::RawPtr(_) => {
- return self.field(cx, index).llvm_type(cx);
+ return self.field(cx, index).expect("tainted field ty").llvm_type(cx);
}
// only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below
@@ -432,7 +434,7 @@ fn scalar_copy_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<&'a Type
// Vectors, even for non-power-of-two sizes, have the same layout as
// arrays but don't count as aggregate types
if let FieldsShape::Array { count, .. } = self.layout.fields()
- && let element = self.field(cx, 0)
+ && let element = self.field(cx, 0).expect("tainted field ty")
&& element.ty.is_integral()
{
// `cx.type_ix(bits)` is tempting here, but while that works great
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index dc862803274..310f472310c 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -233,7 +233,7 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
let mut result = None;
for i in 0..src_layout.fields.count() {
- let src_f = src_layout.field(bx.cx(), i);
+ let src_f = src_layout.field(bx.cx(), i).expect("tainted field ty");
if src_f.is_zst() {
continue;
}
@@ -242,7 +242,7 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
assert_eq!(dst_layout.fields.offset(i).bytes(), 0);
assert_eq!(src_layout.size, src_f.size);
- let dst_f = dst_layout.field(bx.cx(), i);
+ let dst_f = dst_layout.field(bx.cx(), i).expect("tainted field ty");
assert_ne!(src_f.ty, dst_f.ty);
assert_eq!(result, None);
result = Some(unsize_ptr(bx, src, src_f.ty, dst_f.ty, old_info));
diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs
index c34f1dbf856..9c13814c814 100644
--- a/compiler/rustc_codegen_ssa/src/glue.rs
+++ b/compiler/rustc_codegen_ssa/src/glue.rs
@@ -38,7 +38,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(size, align)
}
ty::Slice(_) | ty::Str => {
- let unit = layout.field(bx, 0);
+ let unit = layout.field(bx, 0).expect("tainted field ty");
// The info in this case is the length of the str, so the size is that
// times the unit size.
(
@@ -67,7 +67,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// Recurse to get the size of the dynamically sized field (must be
// the last field).
- let field_ty = layout.field(bx, i).ty;
+ let field_ty = layout.field(bx, i).expect("tainted field ty").ty;
let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
// FIXME (#26403, #27023): We should be adding padding
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 34b8d8b5a6f..37028be7a96 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -127,11 +127,11 @@ fn layout(&self) -> TyAndLayout<'tcx> {
}
fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self {
- self.field(bx.cx(), field.index())
+ self.field(bx.cx(), field.index()).expect("tainted field ty")
}
fn project_constant_index(&self, bx: &mut Bx, index: u64) -> Self {
- self.field(bx.cx(), index as usize)
+ self.field(bx.cx(), index as usize).expect("tainted field ty")
}
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
@@ -578,7 +578,9 @@ pub fn compute_per_local_var_debug_info(
mir::ProjectionElem::Field(field, _) => {
let i = field.index();
fragment_start += fragment_layout.fields.offset(i);
- fragment_layout = fragment_layout.field(self.cx, i);
+ fragment_layout = fragment_layout
+ .field(self.cx, i)
+ .expect("tainted field ty");
}
_ => span_bug!(
var.source_info.span,
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 31c293d7c29..a6ea1c3c4e0 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -271,7 +271,7 @@ pub fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
i: usize,
) -> Self {
- let field = self.layout.field(bx.cx(), i);
+ let field = self.layout.field(bx.cx(), i).expect("tainted field ty");
let offset = self.layout.fields.offset(i);
let mut val = match (self.val, self.layout.abi) {
@@ -528,7 +528,7 @@ fn maybe_codegen_consume_direct(
// ZSTs don't require any actual memory access.
// FIXME(eddyb) deduplicate this with the identical
// checks in `codegen_consume` and `extract_field`.
- let elem = o.layout.field(bx.cx(), 0);
+ let elem = o.layout.field(bx.cx(), 0).expect("tainted field ty");
if elem.is_zst() {
o = OperandRef::zero_sized(elem);
} else {
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 90eab55f76e..60c970f5fca 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -95,7 +95,7 @@ pub fn project_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
ix: usize,
) -> Self {
- let field = self.layout.field(bx.cx(), ix);
+ let field = self.layout.field(bx.cx(), ix).expect("tainted field ty");
let offset = self.layout.fields.offset(ix);
let effective_field_align = self.align.restrict_for_offset(offset);
@@ -390,7 +390,7 @@ pub fn project_index<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
) -> Self {
// Statically compute the offset if we can, otherwise just use the element size,
// as this will yield the lowest alignment.
- let layout = self.layout.field(bx, 0);
+ let layout = self.layout.field(bx, 0).expect("tainted field ty");
let offset = if let Some(llindex) = bx.const_to_opt_uint(llindex) {
layout.size.checked_mul(llindex, bx).unwrap_or(layout.size)
} else {
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index dd7a1fcc165..2814ca813b3 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -416,7 +416,7 @@ fn unsize_into(
// Example: `Arc<T>` -> `Arc<Trait>`
// here we need to increase the size of every &T thin ptr field to a fat ptr
for i in 0..src.layout.fields.count() {
- let cast_ty_field = cast_ty.field(self, i);
+ let cast_ty_field = cast_ty.field(self, i)?;
if cast_ty_field.is_zst() {
continue;
}
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 04e046fbda3..811ae3680f5 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -603,7 +603,7 @@ pub(super) fn size_and_align_of(
// Recurse to get the size of the dynamically sized field (must be
// the last field). Can't have foreign types here, how would we
// adjust alignment and size for them?
- let field = layout.field(self, layout.fields.count() - 1);
+ let field = layout.field(self, layout.fields.count() - 1)?;
let Some((unsized_size, mut unsized_align)) =
self.size_and_align_of(metadata, &field)?
else {
@@ -651,7 +651,7 @@ pub(super) fn size_and_align_of(
ty::Slice(_) | ty::Str => {
let len = metadata.unwrap_meta().to_target_usize(self)?;
- let elem = layout.field(self, 0);
+ let elem = layout.field(self, 0)?;
// Make sure the slice is not too big.
let size = elem.size.bytes().saturating_mul(len); // we rely on `max_size_of_val` being smaller than `u64::MAX`.
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index d7d31fe1887..cda6a2c196e 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -40,7 +40,7 @@ pub fn mplace_field(
field: usize,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
let offset = base.layout.fields.offset(field);
- let field_layout = base.layout.field(self, field);
+ let field_layout = base.layout.field(self, field)?;
// Offset may need adjustment for unsized fields.
let (meta, offset) = if field_layout.is_unsized() {
@@ -96,7 +96,7 @@ pub fn operand_field(
Right(value) => value,
};
- let field_layout = base.layout.field(self, field);
+ let field_layout = base.layout.field(self, field)?;
let offset = base.layout.fields.offset(field);
// This makes several assumptions about what layouts we will encounter; we match what
// codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
@@ -196,7 +196,7 @@ pub fn operand_index(
}
let offset = stride * index; // `Size` multiplication
// All fields have the same layout.
- let field_layout = base.layout.field(self, 0);
+ let field_layout = base.layout.field(self, 0)?;
base.offset(offset, field_layout, self)
}
_ => span_bug!(
@@ -217,7 +217,7 @@ pub fn operand_array_fields<'a>(
let abi::FieldsShape::Array { stride, .. } = base.layout.fields else {
span_bug!(self.cur_span(), "operand_array_fields: expected an array layout");
};
- let field_layout = base.layout.field(self, 0);
+ let field_layout = base.layout.field(self, 0)?;
let dl = &self.tcx.data_layout;
// `Size` multiplication
Ok((0..len).map(move |i| base.offset(stride * i, field_layout, dl)))
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index 2d1970791ca..03678455be6 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -136,7 +136,11 @@ fn might_permit_raw_init_lax<'tcx>(
}
FieldsShape::Arbitrary { offsets, .. } => {
for idx in 0..offsets.len() {
- if !might_permit_raw_init_lax(this.field(cx, idx), cx, init_kind)? {
+ if !might_permit_raw_init_lax(
+ this.field(cx, idx).expect("tainted field ty"),
+ cx,
+ init_kind,
+ )? {
// We found a field that is unhappy with this kind of initialization.
return Ok(false);
}
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index ecbbfd92539..2d6a192f35a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -139,6 +139,16 @@ fn projected_ty_from_poly_trait_ref(
/// report.
fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
+ /// Returns the error encountered in some prior pass that was translated to
+ /// a ty-error (if such an error exists).
+ fn tainted_by_errors(&self) -> Option<ErrorGuaranteed>;
+
+ /// Returns `true` if an error was encountered in some prior pass that was translated to
+ /// a ty-error.
+ fn is_tainted_by_errors(&self) -> bool {
+ self.tainted_by_errors().is_some()
+ }
+
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
fn astconv(&self) -> &dyn AstConv<'tcx>
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index c160cf2df6e..d1d8129fdde 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -37,6 +37,7 @@
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
use rustc_trait_selection::traits::ObligationCtxt;
+use std::cell::Cell;
use std::iter;
mod generics_of;
@@ -113,6 +114,7 @@ pub fn provide(providers: &mut Providers) {
pub struct ItemCtxt<'tcx> {
tcx: TyCtxt<'tcx>,
item_def_id: LocalDefId,
+ tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
}
///////////////////////////////////////////////////////////////////////////
@@ -337,7 +339,7 @@ fn bad_placeholder<'tcx>(
impl<'tcx> ItemCtxt<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
- ItemCtxt { tcx, item_def_id }
+ ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
}
pub fn to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
@@ -488,8 +490,13 @@ fn probe_adt(&self, _span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
ty.ty_adt_def()
}
- fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
- // There's no obvious place to track this, so just let it go.
+ fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+ debug!("set_tainted_by_errors(ErrorGuaranteed)");
+ self.tainted_by_errors.set(Some(e));
+ }
+
+ fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
+ self.tainted_by_errors.get()
}
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
@@ -1174,7 +1181,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
bug!("unexpected sort of node in fn_sig(): {:?}", x);
}
};
- ty::EarlyBinder::bind(output)
+
+ if let Some(e) = icx.tainted_by_errors() {
+ ty::EarlyBinder::bind_tainted(output, e)
+ } else {
+ ty::EarlyBinder::bind(output)
+ }
}
fn infer_return_ty_for_fn_sig<'tcx>(
@@ -1356,18 +1368,19 @@ fn impl_trait_ref(
) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
let icx = ItemCtxt::new(tcx, def_id);
let impl_ = tcx.hir().expect_item(def_id).expect_impl();
- impl_
- .of_trait
- .as_ref()
- .map(|ast_trait_ref| {
- let selfty = tcx.type_of(def_id).instantiate_identity();
- icx.astconv().instantiate_mono_trait_ref(
- ast_trait_ref,
- selfty,
- check_impl_constness(tcx, impl_.constness, ast_trait_ref),
- )
- })
- .map(ty::EarlyBinder::bind)
+ let impl_trait_ref = impl_.of_trait.as_ref().map(|ast_trait_ref| {
+ let selfty = tcx.type_of(def_id).instantiate_identity();
+ icx.astconv().instantiate_mono_trait_ref(
+ ast_trait_ref,
+ selfty,
+ check_impl_constness(tcx, impl_.constness, ast_trait_ref),
+ )
+ });
+ if let Some(e) = icx.tainted_by_errors.get() {
+ impl_trait_ref.map(|itr| ty::EarlyBinder::bind_tainted(itr, e))
+ } else {
+ impl_trait_ref.map(ty::EarlyBinder::bind)
+ }
}
fn check_impl_constness(
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c39edaa1577..b406e46db3d 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -511,7 +511,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
bug!("unexpected sort of node in type_of(): {:?}", x);
}
};
- ty::EarlyBinder::bind(output)
+
+ if let Some(e) = icx.tainted_by_errors.get() {
+ ty::EarlyBinder::bind_tainted(output, e)
+ } else {
+ ty::EarlyBinder::bind(output)
+ }
}
fn infer_placeholder_type<'a>(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 6a82b00211e..c135a368a36 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -315,6 +315,10 @@ fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
self.infcx.set_tainted_by_errors(e)
}
+ fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
+ self.infcx.tainted_by_errors()
+ }
+
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
// FIXME: normalization and escaping regions
let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index bb7147ac80f..3989bd87c04 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -1,6 +1,9 @@
middle_adjust_for_foreign_abi_error =
target architecture {$arch} does not support `extern {$abi}` ABI
+middle_already_reported =
+ an error has already been reported elsewhere (this should not usually be printed)
+
middle_assert_async_resume_after_panic = `async fn` resumed after panicking
middle_assert_async_resume_after_return = `async fn` resumed after completion
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index 57b2de84b47..33415c14426 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -130,6 +130,9 @@ pub enum LayoutError<'tcx> {
#[diag(middle_cannot_be_normalized)]
NormalizationFailure { ty: Ty<'tcx>, failure_ty: String },
+ #[diag(middle_already_reported)]
+ AlreadyReported,
+
#[diag(middle_cycle)]
Cycle,
}
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 2c481745d98..0692259cd57 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -170,8 +170,25 @@ impl<T> EraseType for rustc_hir::MaybeOwner<&'_ T> {
type Result = [u8; size_of::<rustc_hir::MaybeOwner<&'static ()>>()];
}
-impl<T: EraseType> EraseType for ty::EarlyBinder<T> {
- type Result = T::Result;
+impl EraseType for ty::EarlyBinder<Ty<'_>> {
+ type Result = [u8; size_of::<ty::EarlyBinder<Ty<'static>>>()];
+}
+
+impl EraseType for ty::EarlyBinder<ty::Const<'_>> {
+ type Result = [u8; size_of::<ty::EarlyBinder<ty::Const<'static>>>()];
+}
+
+impl EraseType for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>> {
+ type Result = [u8; size_of::<ty::EarlyBinder<ty::Binder<'static, ty::FnSig<'static>>>>()];
+}
+
+impl EraseType for ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
+ type Result = [u8; size_of::<ty::EarlyBinder<&'static ty::List<ty::Clause<'static>>>>()];
+}
+
+impl EraseType for ty::EarlyBinder<&'_ [(ty::Clause<'_>, rustc_span::Span)]> {
+ type Result =
+ [u8; size_of::<ty::EarlyBinder<&'static [(ty::Clause<'static>, rustc_span::Span)]>>()];
}
impl EraseType for ty::Binder<'_, ty::FnSig<'_>> {
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 97dab5cb47e..5dd5a2c85ee 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -11,7 +11,7 @@
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_serialize::{self, Decodable, Encodable};
-use rustc_span::sym;
+use rustc_span::{sym, ErrorGuaranteed};
use rustc_type_ir::WithCachedTypeInfo;
use smallvec::SmallVec;
@@ -535,6 +535,9 @@ fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFl
#[derive(Encodable, Decodable, HashStable)]
pub struct EarlyBinder<T> {
value: T,
+ /// If computation of `T` produced an error then this binder is "tainted", and this information
+ /// is useful to avoid later parts of the compilation.
+ tainted: Option<ErrorGuaranteed>,
}
/// For early binders, you should first call `instantiate` before using any visitors.
@@ -543,11 +546,15 @@ impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
impl<T> EarlyBinder<T> {
pub fn bind(value: T) -> EarlyBinder<T> {
- EarlyBinder { value }
+ EarlyBinder { value, tainted: None }
+ }
+
+ pub fn bind_tainted(value: T, tainted: ErrorGuaranteed) -> EarlyBinder<T> {
+ EarlyBinder { value, tainted: Some(tainted) }
}
pub fn as_ref(&self) -> EarlyBinder<&T> {
- EarlyBinder { value: &self.value }
+ EarlyBinder { value: &self.value, tainted: self.tainted }
}
pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<U>
@@ -562,7 +569,7 @@ pub fn map_bound<F, U>(self, f: F) -> EarlyBinder<U>
F: FnOnce(T) -> U,
{
let value = f(self.value);
- EarlyBinder { value }
+ EarlyBinder { value, tainted: self.tainted }
}
pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<U>, E>
@@ -570,11 +577,11 @@ pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<U>, E>
F: FnOnce(T) -> Result<U, E>,
{
let value = f(self.value)?;
- Ok(EarlyBinder { value })
+ Ok(EarlyBinder { value, tainted: self.tainted })
}
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
- EarlyBinder { value }
+ EarlyBinder { value, tainted: self.tainted }
}
/// Skips the binder and returns the "bound" value.
@@ -595,14 +602,14 @@ pub fn skip_binder(self) -> T {
impl<T> EarlyBinder<Option<T>> {
pub fn transpose(self) -> Option<EarlyBinder<T>> {
- self.value.map(|value| EarlyBinder { value })
+ self.value.map(|value| EarlyBinder { value, tainted: self.tainted })
}
}
impl<T, U> EarlyBinder<(T, U)> {
pub fn transpose_tuple2(self) -> (EarlyBinder<T>, EarlyBinder<U>) {
- let EarlyBinder { value: (lhs, rhs) } = self;
- (EarlyBinder { value: lhs }, EarlyBinder { value: rhs })
+ let EarlyBinder { value: (lhs, rhs), tainted } = self;
+ (EarlyBinder { value: lhs, tainted }, EarlyBinder { value: rhs, tainted })
}
}
@@ -638,7 +645,7 @@ impl<'tcx, I: IntoIterator> Iterator for IterInstantiated<'_, 'tcx, I>
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
- Some(EarlyBinder { value: self.it.next()? }.instantiate(self.tcx, self.args))
+ Some(EarlyBinder::bind(self.it.next()?).instantiate(self.tcx, self.args))
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -652,7 +659,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, 'tcx, I
I::Item: TypeFoldable<TyCtxt<'tcx>>,
{
fn next_back(&mut self) -> Option<Self::Item> {
- Some(EarlyBinder { value: self.it.next_back()? }.instantiate(self.tcx, self.args))
+ Some(EarlyBinder::bind(self.it.next_back()?).instantiate(self.tcx, self.args))
}
}
@@ -699,7 +706,7 @@ impl<'tcx, I: IntoIterator> Iterator for IterInstantiatedCopied<'_, 'tcx, I>
type Item = <I::Item as Deref>::Target;
fn next(&mut self) -> Option<Self::Item> {
- self.it.next().map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args))
+ self.it.next().map(|value| EarlyBinder::bind(*value).instantiate(self.tcx, self.args))
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -714,9 +721,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, '
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
{
fn next_back(&mut self) -> Option<Self::Item> {
- self.it
- .next_back()
- .map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args))
+ self.it.next_back().map(|value| EarlyBinder::bind(*value).instantiate(self.tcx, self.args))
}
}
@@ -742,7 +747,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> {
type Item = EarlyBinder<T::Item>;
fn next(&mut self) -> Option<Self::Item> {
- self.t.next().map(|value| EarlyBinder { value })
+ self.t.next().map(|value| EarlyBinder::bind(value))
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -756,6 +761,14 @@ pub fn instantiate(self, tcx: TyCtxt<'tcx>, args: &[GenericArg<'tcx>]) -> T {
self.value.fold_with(&mut folder)
}
+ pub fn instantiate_if_not_tainted(
+ self,
+ tcx: TyCtxt<'tcx>,
+ args: &[GenericArg<'tcx>],
+ ) -> Result<T, ErrorGuaranteed> {
+ if let Some(e) = self.tainted { Err(e) } else { Ok(self.instantiate(tcx, args)) }
+ }
+
/// Makes the identity replacement `T0 => T0, ..., TN => TN`.
/// Conceptually, this converts universally bound variables into placeholders
/// when inside of a given item.
@@ -768,6 +781,10 @@ pub fn instantiate_identity(self) -> T {
self.value
}
+ pub fn instantiate_identity_if_not_tainted(self) -> Result<T, ErrorGuaranteed> {
+ if let Some(e) = self.tainted { Err(e) } else { Ok(self.instantiate_identity()) }
+ }
+
/// Returns the inner value, but only if it contains no bound vars.
pub fn no_bound_vars(self) -> Option<T> {
if !self.value.has_param() { Some(self.value) } else { None }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 62805d1e8b5..77fd9b0719b 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -4,7 +4,7 @@
use crate::ty::normalize_erasing_regions::NormalizationError;
use crate::ty::{self, ConstKind, ReprOptions, Ty, TyCtxt, TypeVisitableExt};
use rustc_error_messages::DiagnosticMessage;
-use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
+use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::IndexVec;
@@ -212,6 +212,7 @@ pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
+ AlreadyReported(ErrorGuaranteed),
Cycle,
}
@@ -223,6 +224,7 @@ pub fn diagnostic_message(&self) -> DiagnosticMessage {
Unknown(_) => middle_unknown_layout,
SizeOverflow(_) => middle_values_too_big,
NormalizationFailure(_, _) => middle_cannot_be_normalized,
+ AlreadyReported(..) => middle_already_reported,
Cycle => middle_cycle,
}
}
@@ -236,6 +238,7 @@ pub fn into_diagnostic(self) -> crate::error::LayoutError<'tcx> {
NormalizationFailure(ty, e) => {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
}
+ AlreadyReported(..) => E::AlreadyReported,
Cycle => E::Cycle,
}
}
@@ -256,6 +259,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
t,
e.get_type_for_failure()
),
+ LayoutError::AlreadyReported(..) => {
+ write!(f, "an error has already been reported elsewhere")
+ }
LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"),
}
}
@@ -322,6 +328,7 @@ pub fn compute(
// We can't extract SizeSkeleton info from other layout errors
Err(
e @ LayoutError::Cycle
+ | e @ LayoutError::AlreadyReported(_)
| e @ LayoutError::SizeOverflow(_)
| e @ LayoutError::NormalizationFailure(..),
) => return Err(e),
@@ -714,6 +721,8 @@ impl<'tcx, C> TyAbiInterface<'tcx, C> for Ty<'tcx>
where
C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
{
+ type ErrorGuaranteed = ty::ErrorGuaranteed;
+
fn ty_and_layout_for_variant(
this: TyAndLayout<'tcx>,
cx: &C,
@@ -768,7 +777,11 @@ fn ty_and_layout_for_variant(
TyAndLayout { ty: this.ty, layout }
}
- fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> TyAndLayout<'tcx> {
+ fn ty_and_layout_field(
+ this: TyAndLayout<'tcx>,
+ cx: &C,
+ i: usize,
+ ) -> Result<TyAndLayout<'tcx>, ty::ErrorGuaranteed> {
enum TyMaybeWithLayout<'tcx> {
Ty(Ty<'tcx>),
TyAndLayout(TyAndLayout<'tcx>),
@@ -778,7 +791,7 @@ fn field_ty_or_layout<'tcx>(
this: TyAndLayout<'tcx>,
cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
i: usize,
- ) -> TyMaybeWithLayout<'tcx> {
+ ) -> Result<TyMaybeWithLayout<'tcx>, ty::ErrorGuaranteed> {
let tcx = cx.tcx();
let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
TyAndLayout {
@@ -822,10 +835,10 @@ fn field_ty_or_layout<'tcx>(
// NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing
// the `Result` should always work because the type is
// always either `*mut ()` or `&'static mut ()`.
- return TyMaybeWithLayout::TyAndLayout(TyAndLayout {
+ return Ok(TyMaybeWithLayout::TyAndLayout(TyAndLayout {
ty: this.ty,
..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap()
- });
+ }));
}
let mk_dyn_vtable = || {
@@ -879,12 +892,12 @@ fn field_ty_or_layout<'tcx>(
}
};
- TyMaybeWithLayout::Ty(metadata)
+ Ok(TyMaybeWithLayout::Ty(metadata))
}
// Arrays and slices.
- ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element),
- ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
+ ty::Array(element, _) | ty::Slice(element) => Ok(TyMaybeWithLayout::Ty(element)),
+ ty::Str => Ok(TyMaybeWithLayout::Ty(tcx.types.u8)),
// Tuples, generators and closures.
ty::Closure(_, ref args) => field_ty_or_layout(
@@ -894,50 +907,50 @@ fn field_ty_or_layout<'tcx>(
),
ty::Generator(def_id, ref args, _) => match this.variants {
- Variants::Single { index } => TyMaybeWithLayout::Ty(
+ Variants::Single { index } => Ok(TyMaybeWithLayout::Ty(
args.as_generator()
.state_tys(def_id, tcx)
.nth(index.as_usize())
.unwrap()
.nth(i)
.unwrap(),
- ),
+ )),
Variants::Multiple { tag, tag_field, .. } => {
if i == tag_field {
- return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
+ return Ok(TyMaybeWithLayout::TyAndLayout(tag_layout(tag)));
}
- TyMaybeWithLayout::Ty(args.as_generator().prefix_tys().nth(i).unwrap())
+ Ok(TyMaybeWithLayout::Ty(args.as_generator().prefix_tys().nth(i).unwrap()))
}
},
- ty::Tuple(tys) => TyMaybeWithLayout::Ty(tys[i]),
+ ty::Tuple(tys) => Ok(TyMaybeWithLayout::Ty(tys[i])),
// ADTs.
ty::Adt(def, args) => {
match this.variants {
Variants::Single { index } => {
let field = &def.variant(index).fields[FieldIdx::from_usize(i)];
- TyMaybeWithLayout::Ty(field.ty(tcx, args))
+ Ok(TyMaybeWithLayout::Ty(field.ty_if_not_tainted(tcx, args)?))
}
// Discriminant field for enums (where applicable).
Variants::Multiple { tag, .. } => {
assert_eq!(i, 0);
- return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
+ return Ok(TyMaybeWithLayout::TyAndLayout(tag_layout(tag)));
}
}
}
ty::Dynamic(_, _, ty::DynStar) => {
if i == 0 {
- TyMaybeWithLayout::Ty(Ty::new_mut_ptr(tcx, tcx.types.unit))
+ Ok(TyMaybeWithLayout::Ty(Ty::new_mut_ptr(tcx, tcx.types.unit)))
} else if i == 1 {
// FIXME(dyn-star) same FIXME as above applies here too
- TyMaybeWithLayout::Ty(Ty::new_imm_ref(
+ Ok(TyMaybeWithLayout::Ty(Ty::new_imm_ref(
tcx,
tcx.lifetimes.re_static,
Ty::new_array(tcx, tcx.types.usize, 3),
- ))
+ )))
} else {
bug!("no field {i} on dyn*")
}
@@ -952,16 +965,16 @@ fn field_ty_or_layout<'tcx>(
}
}
- match field_ty_or_layout(this, cx, i) {
+ match field_ty_or_layout(this, cx, i)? {
TyMaybeWithLayout::Ty(field_ty) => {
- cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| {
+ Ok(cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| {
bug!(
"failed to get layout for `{field_ty}`: {e:?},\n\
despite it being a field (#{i}) of an existing layout: {this:#?}",
)
- })
+ }))
}
- TyMaybeWithLayout::TyAndLayout(field_layout) => field_layout,
+ TyMaybeWithLayout::TyAndLayout(field_layout) => Ok(field_layout),
}
}
@@ -1046,7 +1059,7 @@ fn ty_and_layout_pointee_info_at(
for i in 0..variant.fields.count() {
let field_start = variant.fields.offset(i);
if field_start <= offset {
- let field = variant.field(cx, i);
+ let field = variant.field(cx, i).expect("tainted field ty");
result = field.to_result().ok().and_then(|field| {
if ptr_end <= field_start + field.size {
// We found the right field, look inside it.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 0411890ab51..fd86f17daed 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2170,6 +2170,17 @@ pub fn ty(&self, tcx: TyCtxt<'tcx>, arg: GenericArgsRef<'tcx>) -> Ty<'tcx> {
tcx.type_of(self.did).instantiate(tcx, arg)
}
+ /// Returns the type of this field, if the type is not tainted with an error from earlier
+ /// in compilation. The resulting type is not normalized. The `arg` is typically obtained via
+ /// the second field of [`TyKind::Adt`].
+ pub fn ty_if_not_tainted(
+ &self,
+ tcx: TyCtxt<'tcx>,
+ arg: GenericArgsRef<'tcx>,
+ ) -> Result<Ty<'tcx>, ErrorGuaranteed> {
+ tcx.type_of(self.did).instantiate_if_not_tainted(tcx, arg)
+ }
+
/// Computes the `Ident` of this variant by looking up the `Span`
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
Ident::new(self.name, tcx.def_ident_span(self.did).unwrap())
diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs
index 247256f076b..bfb3e683fa3 100644
--- a/compiler/rustc_target/src/abi/call/loongarch.rs
+++ b/compiler/rustc_target/src/abi/call/loongarch.rs
@@ -88,7 +88,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
}
FieldsShape::Array { count, .. } => {
for _ in 0..count {
- let elem_layout = arg_layout.field(cx, 0);
+ let elem_layout = arg_layout.field(cx, 0).expect("tainted field ty");
should_use_fp_conv_helper(
cx,
&elem_layout,
@@ -105,7 +105,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
abi::Variants::Single { .. } => (),
}
for i in arg_layout.fields.index_by_increasing_offset() {
- let field = arg_layout.field(cx, i);
+ let field = arg_layout.field(cx, i).expect("tainted field ty");
should_use_fp_conv_helper(cx, &field, xlen, flen, field1_kind, field2_kind)?;
}
}
diff --git a/compiler/rustc_target/src/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs
index 2700f67b209..cb4b458cc98 100644
--- a/compiler/rustc_target/src/abi/call/mips64.rs
+++ b/compiler/rustc_target/src/abi/call/mips64.rs
@@ -24,7 +24,7 @@ fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
- match ret.layout.field(cx, i).abi {
+ match ret.layout.field(cx, i).expect("tainted field ty").abi {
abi::Abi::Scalar(scalar) => match scalar.primitive() {
abi::F32 => Some(Reg::f32()),
abi::F64 => Some(Reg::f64()),
@@ -105,7 +105,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
let mut last_offset = Size::ZERO;
for i in 0..arg.layout.fields.count() {
- let field = arg.layout.field(cx, i);
+ let field = arg.layout.field(cx, i).expect("tainted field ty");
let offset = arg.layout.fields.offset(i);
// We only care about aligned doubles
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 03e7b3e7b40..f4a5e4f3547 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -374,7 +374,7 @@ pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, H
assert_eq!(start, Size::ZERO);
let result = if count > 0 {
- layout.field(cx, 0).homogeneous_aggregate(cx)?
+ layout.field(cx, 0).expect("tainted field ty").homogeneous_aggregate(cx)?
} else {
HomogeneousAggregate::NoData
};
@@ -392,7 +392,7 @@ pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, H
return Err(Heterogeneous);
}
- let field = layout.field(cx, i);
+ let field = layout.field(cx, i).expect("tainted field ty");
result = result.merge(field.homogeneous_aggregate(cx)?)?;
diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs
index d90dce2a087..cbd52f3c110 100644
--- a/compiler/rustc_target/src/abi/call/riscv.rs
+++ b/compiler/rustc_target/src/abi/call/riscv.rs
@@ -94,7 +94,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
}
FieldsShape::Array { count, .. } => {
for _ in 0..count {
- let elem_layout = arg_layout.field(cx, 0);
+ let elem_layout = arg_layout.field(cx, 0).expect("tainted field ty");
should_use_fp_conv_helper(
cx,
&elem_layout,
@@ -111,7 +111,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
abi::Variants::Single { .. } => (),
}
for i in arg_layout.fields.index_by_increasing_offset() {
- let field = arg_layout.field(cx, i);
+ let field = arg_layout.field(cx, i).expect("tainted field ty");
should_use_fp_conv_helper(cx, &field, xlen, flen, field1_kind, field2_kind)?;
}
}
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index cbed5b4afc1..bd2d7916675 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -117,7 +117,12 @@ fn parse_structure<'a, Ty, C>(
if offset < layout.fields.offset(i) {
offset = layout.fields.offset(i);
}
- data = parse_structure(cx, layout.field(cx, i), data.clone(), offset);
+ data = parse_structure(
+ cx,
+ layout.field(cx, i).expect("tainted_field_ty"),
+ data.clone(),
+ offset,
+ );
}
}
_ => {
diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index b738c3133d9..a7e07d49e79 100644
--- a/compiler/rustc_target/src/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
@@ -101,7 +101,7 @@ fn contains_vector<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
Abi::Vector { .. } => true,
Abi::Aggregate { .. } => {
for i in 0..layout.fields.count() {
- if contains_vector(cx, layout.field(cx, i)) {
+ if contains_vector(cx, layout.field(cx, i).expect("tainted field ty")) {
return true;
}
}
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index d1efe977699..17ef236b951 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -59,7 +59,7 @@ fn classify<'a, Ty, C>(
Abi::ScalarPair(..) | Abi::Aggregate { .. } => {
for i in 0..layout.fields.count() {
let field_off = off + layout.fields.offset(i);
- classify(cx, layout.field(cx, i), cls, field_off)?;
+ classify(cx, layout.field(cx, i).expect("tainted field ty"), cls, field_off)?;
}
match &layout.variants {
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 589cd3cf96b..452a5db126e 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -40,12 +40,18 @@ fn deref(&self) -> &&'a LayoutS {
/// Trait that needs to be implemented by the higher-level type representation
/// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
pub trait TyAbiInterface<'a, C>: Sized {
+ type ErrorGuaranteed: std::fmt::Debug;
+
fn ty_and_layout_for_variant(
this: TyAndLayout<'a, Self>,
cx: &C,
variant_index: VariantIdx,
) -> TyAndLayout<'a, Self>;
- fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
+ fn ty_and_layout_field(
+ this: TyAndLayout<'a, Self>,
+ cx: &C,
+ i: usize,
+ ) -> Result<TyAndLayout<'a, Self>, Self::ErrorGuaranteed>;
fn ty_and_layout_pointee_info_at(
this: TyAndLayout<'a, Self>,
cx: &C,
@@ -65,7 +71,11 @@ pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self
Ty::ty_and_layout_for_variant(self, cx, variant_index)
}
- pub fn field<C>(self, cx: &C, i: usize) -> Self
+ pub fn field<C>(
+ self,
+ cx: &C,
+ i: usize,
+ ) -> Result<Self, <Ty as TyAbiInterface<'a, C>>::ErrorGuaranteed>
where
Ty: TyAbiInterface<'a, C>,
{
@@ -88,7 +98,7 @@ pub fn is_single_fp_element<C>(self, cx: &C) -> bool
Abi::Scalar(scalar) => matches!(scalar.primitive(), F32 | F64),
Abi::Aggregate { .. } => {
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
- self.field(cx, 0).is_single_fp_element(cx)
+ self.field(cx, 0).expect("tainted field ty").is_single_fp_element(cx)
} else {
false
}
@@ -134,7 +144,7 @@ pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>)
for index in indices {
offset += layout.fields.offset(index);
- layout = layout.field(cx, index);
+ layout = layout.field(cx, index).expect("tainted field ty");
}
offset
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index d0a7414b4ff..dd3d410b6fe 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -584,7 +584,7 @@ fn make_thin_self_ptr<'tcx>(
&& !fat_pointer_layout.ty.is_ref()
{
for i in 0..fat_pointer_layout.fields.count() {
- let field_layout = fat_pointer_layout.field(cx, i);
+ let field_layout = fat_pointer_layout.field(cx, i).expect("tainted field ty");
if !field_layout.is_zst() {
fat_pointer_layout = field_layout;
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index b840ff184e0..d51d84d4c4d 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -63,7 +63,9 @@ fn layout_of<'tcx>(
record_layout_for_printing(&cx, layout);
- sanity_check_layout(&cx, &layout);
+ if let Err(e) = sanity_check_layout(&cx, &layout) {
+ return Err(cx.tcx.arena.alloc(LayoutError::AlreadyReported(e)));
+ }
Ok(layout)
}
@@ -974,7 +976,7 @@ fn variant_info_for_adt<'tcx>(
.iter()
.enumerate()
.map(|(i, &name)| {
- let field_layout = layout.field(cx, i);
+ let field_layout = layout.field(cx, i).expect("tainted field ty");
let offset = layout.fields.offset(i);
min_size = min_size.max(offset + field_layout.size);
FieldInfo {
@@ -1054,7 +1056,7 @@ fn variant_info_for_generator<'tcx>(
.zip(upvar_names)
.enumerate()
.map(|(field_idx, (_, name))| {
- let field_layout = layout.field(cx, field_idx);
+ let field_layout = layout.field(cx, field_idx).expect("tainted field ty");
let offset = layout.fields.offset(field_idx);
upvars_size = upvars_size.max(offset + field_layout.size);
FieldInfo {
@@ -1077,7 +1079,8 @@ fn variant_info_for_generator<'tcx>(
.iter()
.enumerate()
.map(|(field_idx, local)| {
- let field_layout = variant_layout.field(cx, field_idx);
+ let field_layout =
+ variant_layout.field(cx, field_idx).expect("tainted field ty");
let offset = variant_layout.fields.offset(field_idx);
// The struct is as large as the last field's end
variant_size = variant_size.max(offset + field_layout.size);
diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
index 8633334381a..78f081887b9 100644
--- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs
+++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
@@ -10,7 +10,7 @@
pub(super) fn sanity_check_layout<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
layout: &TyAndLayout<'tcx>,
-) {
+) -> Result<(), rustc_errors::ErrorGuaranteed> {
// Type-level uninhabitedness should always imply ABI uninhabitedness.
if layout.ty.is_privately_uninhabited(cx.tcx, cx.param_env) {
assert!(layout.abi.is_uninhabited());
@@ -22,40 +22,45 @@ pub(super) fn sanity_check_layout<'tcx>(
if !cfg!(debug_assertions) {
// Stop here, the rest is kind of expensive.
- return;
+ return Ok(());
}
/// Yields non-ZST fields of the type
fn non_zst_fields<'tcx, 'a>(
cx: &'a LayoutCx<'tcx, TyCtxt<'tcx>>,
layout: &'a TyAndLayout<'tcx>,
- ) -> impl Iterator<Item = (Size, TyAndLayout<'tcx>)> + 'a {
+ ) -> impl Iterator<Item = Result<(Size, TyAndLayout<'tcx>), rustc_errors::ErrorGuaranteed>> + 'a
+ {
(0..layout.layout.fields().count()).filter_map(|i| {
- let field = layout.field(cx, i);
- // Also checking `align == 1` here leads to test failures in
- // `layout/zero-sized-array-union.rs`, where a type has a zero-size field with
- // alignment 4 that still gets ignored during layout computation (which is okay
- // since other fields already force alignment 4).
- let zst = field.is_zst();
- (!zst).then(|| (layout.fields.offset(i), field))
+ match layout.field(cx, i) {
+ Ok(field) => {
+ // Also checking `align == 1` here leads to test failures in
+ // `layout/zero-sized-array-union.rs`, where a type has a zero-size field with
+ // alignment 4 that still gets ignored during layout computation (which is okay
+ // since other fields already force alignment 4).
+ let zst = field.is_zst();
+ (!zst).then(|| Ok((layout.fields.offset(i), field)))
+ }
+ Err(e) => Some(Err(e)),
+ }
})
}
fn skip_newtypes<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
layout: &TyAndLayout<'tcx>,
- ) -> TyAndLayout<'tcx> {
+ ) -> Result<TyAndLayout<'tcx>, rustc_errors::ErrorGuaranteed> {
if matches!(layout.layout.variants(), Variants::Multiple { .. }) {
// Definitely not a newtype of anything.
- return *layout;
+ return Ok(*layout);
}
let mut fields = non_zst_fields(cx, layout);
let Some(first) = fields.next() else {
// No fields here, so this could be a primitive or enum -- either way it's not a newtype around a thing
- return *layout;
+ return Ok(*layout);
};
if fields.next().is_none() {
- let (offset, first) = first;
+ let (offset, first) = first?;
if offset == Size::ZERO && first.layout.size() == layout.size {
// This is a newtype, so keep recursing.
// FIXME(RalfJung): I don't think it would be correct to do any checks for
@@ -64,10 +69,13 @@ fn skip_newtypes<'tcx>(
}
}
// No more newtypes here.
- *layout
+ Ok(*layout)
}
- fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayout<'tcx>) {
+ fn check_layout_abi<'tcx>(
+ cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+ layout: &TyAndLayout<'tcx>,
+ ) -> Result<(), rustc_errors::ErrorGuaranteed> {
// Verify the ABI mandated alignment and size.
let align = layout.abi.inherent_align(cx).map(|align| align.abi);
let size = layout.abi.inherent_size(cx);
@@ -77,7 +85,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
Abi::Uninhabited | Abi::Aggregate { .. },
"ABI unexpectedly missing alignment and/or size in {layout:#?}"
);
- return;
+ return Ok(());
};
assert_eq!(
layout.layout.align().abi,
@@ -94,7 +102,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
match layout.layout.abi() {
Abi::Scalar(_) => {
// Check that this matches the underlying field.
- let inner = skip_newtypes(cx, layout);
+ let inner = skip_newtypes(cx, layout)?;
assert!(
matches!(inner.layout.abi(), Abi::Scalar(_)),
"`Scalar` type {} is newtype around non-`Scalar` type {}",
@@ -107,7 +115,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
}
FieldsShape::Union(..) => {
// FIXME: I guess we could also check something here? Like, look at all fields?
- return;
+ return Ok(());
}
FieldsShape::Arbitrary { .. } => {
// Should be an enum, the only field is the discriminant.
@@ -122,7 +130,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
"`Scalar` layout for multiple-field type in {inner:#?}",
);
let offset = inner.layout.fields().offset(0);
- let field = inner.field(cx, 0);
+ let field = inner.field(cx, 0).expect("tainted field ty");
// The field should be at the right offset, and match the `scalar` layout.
assert_eq!(
offset,
@@ -146,7 +154,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
}
Abi::ScalarPair(scalar1, scalar2) => {
// Check that the underlying pair of fields matches.
- let inner = skip_newtypes(cx, layout);
+ let inner = skip_newtypes(cx, layout)?;
assert!(
matches!(inner.layout.abi(), Abi::ScalarPair(..)),
"`ScalarPair` type {} is newtype around non-`ScalarPair` type {}",
@@ -156,7 +164,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
if matches!(inner.layout.variants(), Variants::Multiple { .. }) {
// FIXME: ScalarPair for enums is enormously complicated and it is very hard
// to check anything about them.
- return;
+ return Ok(());
}
match inner.layout.fields() {
FieldsShape::Arbitrary { .. } => {
@@ -164,7 +172,7 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
}
FieldsShape::Union(..) => {
// FIXME: I guess we could also check something here? Like, look at all fields?
- return;
+ return Ok(());
}
_ => {
panic!("`ScalarPair` layout with unexpected field shape in {inner:#?}");
@@ -175,12 +183,12 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
panic!(
"`ScalarPair` layout for type with not even one non-ZST field: {inner:#?}"
)
- });
+ })?;
let (offset2, field2) = fields.next().unwrap_or_else(|| {
panic!(
"`ScalarPair` layout for type with less than two non-ZST fields: {inner:#?}"
)
- });
+ })?;
assert_matches!(
fields.next(),
None,
@@ -240,9 +248,11 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
}
Abi::Uninhabited | Abi::Aggregate { .. } => {} // Nothing to check.
}
+
+ Ok(())
}
- check_layout_abi(cx, layout);
+ check_layout_abi(cx, layout)?;
if let Variants::Multiple { variants, .. } = &layout.variants {
for variant in variants.iter() {
@@ -296,4 +306,6 @@ fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: &TyAndLayou
}
}
}
+
+ Ok(())
}
diff --git a/tests/ui/consts/issue-112824-type-mismatch-type-error-1.rs b/tests/ui/consts/issue-112824-type-mismatch-type-error-1.rs
index edbf4eb8f69..50ec7ae10c3 100644
--- a/tests/ui/consts/issue-112824-type-mismatch-type-error-1.rs
+++ b/tests/ui/consts/issue-112824-type-mismatch-type-error-1.rs
@@ -8,11 +8,13 @@ pub struct Opcode2 {
impl Opcode2 {
pub const OP2: Opcode2 = Opcode2 { s: Opcode(0x1) };
+ //~^ ERROR evaluation of constant value failed [E0080]
}
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
move |i| match msg_type {
Opcode2::OP2 => unimplemented!(),
+ //~^ ERROR could not evaluate constant pattern
}
}
diff --git a/tests/ui/consts/issue-112824-type-mismatch-type-error-1.stderr b/tests/ui/consts/issue-112824-type-mismatch-type-error-1.stderr
index 68362788545..01a5ff569c1 100644
--- a/tests/ui/consts/issue-112824-type-mismatch-type-error-1.stderr
+++ b/tests/ui/consts/issue-112824-type-mismatch-type-error-1.stderr
@@ -17,7 +17,19 @@ help: you might be missing a type parameter
LL | pub struct Opcode2<S> {
| +++
-error: aborting due to 2 previous errors
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-112824-type-mismatch-type-error-1.rs:10:5
+ |
+LL | pub const OP2: Opcode2 = Opcode2 { s: Opcode(0x1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ an error has already been reported elsewhere (this should not usually be printed)
+
+error: could not evaluate constant pattern
+ --> $DIR/issue-112824-type-mismatch-type-error-1.rs:16:9
+ |
+LL | Opcode2::OP2 => unimplemented!(),
+ | ^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0261, E0412.
-For more information about an error, try `rustc --explain E0261`.
+Some errors have detailed explanations: E0080, E0261, E0412.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/issue-112824-type-mismatch-type-error.rs b/tests/ui/consts/issue-112824-type-mismatch-type-error.rs
index 018dfbba185..e85e3d1c6ca 100644
--- a/tests/ui/consts/issue-112824-type-mismatch-type-error.rs
+++ b/tests/ui/consts/issue-112824-type-mismatch-type-error.rs
@@ -6,11 +6,13 @@
impl Opcode2 {
pub const OP2: Opcode2 = Opcode2(Opcode(0x1));
+ //~^ ERROR evaluation of constant value failed [E0080]
}
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
move |i| match msg_type {
Opcode2::OP2 => unimplemented!(),
+ //~^ ERROR could not evaluate constant pattern
}
}
diff --git a/tests/ui/consts/issue-112824-type-mismatch-type-error.stderr b/tests/ui/consts/issue-112824-type-mismatch-type-error.stderr
index 7ebd5ad30ac..72b7fdda0a9 100644
--- a/tests/ui/consts/issue-112824-type-mismatch-type-error.stderr
+++ b/tests/ui/consts/issue-112824-type-mismatch-type-error.stderr
@@ -17,7 +17,19 @@ help: you might be missing a type parameter
LL | pub struct Opcode2<S>(&'a S);
| +++
-error: aborting due to 2 previous errors
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-112824-type-mismatch-type-error.rs:8:5
+ |
+LL | pub const OP2: Opcode2 = Opcode2(Opcode(0x1));
+ | ^^^^^^^^^^^^^^^^^^^^^^ an error has already been reported elsewhere (this should not usually be printed)
+
+error: could not evaluate constant pattern
+ --> $DIR/issue-112824-type-mismatch-type-error.rs:14:9
+ |
+LL | Opcode2::OP2 => unimplemented!(),
+ | ^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0261, E0412.
-For more information about an error, try `rustc --explain E0261`.
+Some errors have detailed explanations: E0080, E0261, E0412.
+For more information about an error, try `rustc --explain E0080`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment