ClosureVar(name) => write!(out, ".<closure-var({})>", name),
TupleElem(idx) => write!(out, ".{}", idx),
ArrayElem(idx) => write!(out, "[{}]", idx),
- Deref =>
- // This does not match Rust syntax, but it is more readable for long paths -- and
+ // `.<deref>` does not match Rust syntax, but it is more readable for long paths -- and
// some of the other items here also are not Rust syntax. Actually we can't
// even use the usual syntax because we are just showing the projections,
// not the root.
- {
- write!(out, ".<deref>")
- }
+ Deref => write!(out, ".<deref>"),
Tag => write!(out, ".<enum-tag>"),
DynDowncast => write!(out, ".<dyn-downcast>"),
}
ty::Adt(def, ..) if def.is_enum() => {
// we might be projecting *to* a variant, or to a field *in*a variant.
match layout.variants {
- layout::Variants::Single { index } =>
- // Inside a variant
- {
+ layout::Variants::Single { index } => {
+ // Inside a variant
PathElem::Field(def.variants[index].fields[field].ident.name)
}
_ => bug!(),
return Ok(());
}
// This is the element type size.
- let ty_size = self.ecx.layout_of(tys)?.size;
+ let layout = self.ecx.layout_of(tys)?;
+ // Empty tuples and fieldless structs (the only ZSTs that allow reaching this code)
+ // have no data to be checked.
+ if layout.is_zst() {
+ return Ok(());
+ }
// This is the size in bytes of the whole array.
- let size = ty_size * len;
+ let size = layout.size * len;
// Size is not 0, get a pointer.
let ptr = self.ecx.force_ptr(mplace.ptr)?;
// Some byte was undefined, determine which
// element that byte belongs to so we can
// provide an index.
- let i = (offset.bytes() / ty_size.bytes()) as usize;
+ let i = (offset.bytes() / layout.size.bytes()) as usize;
self.path.push(PathElem::ArrayElem(i));
throw_validation_failure!("undefined bytes", self.path)