Specialize ZeroSized constants
ZeroSized constants can be represented as `mir::Const::Val` even if their layout is not yet known. In those cases, CrateItem::body() was crashing when trying to convert a `ConstValue::ZeroSized` into its stable counterpart `ConstantKind::Allocated`. Instead, we now map `ConstValue::ZeroSized` into a new variant: `ConstantKind::ZeroSized`.
This commit is contained in:
@@ -1284,11 +1284,15 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
|||||||
let kind = match self.kind() {
|
let kind = match self.kind() {
|
||||||
ty::Value(val) => {
|
ty::Value(val) => {
|
||||||
let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
|
let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
|
||||||
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
|
if matches!(const_val, mir::ConstValue::ZeroSized) {
|
||||||
self.ty(),
|
ConstantKind::ZeroSized
|
||||||
const_val,
|
} else {
|
||||||
tables,
|
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
|
||||||
))
|
self.ty(),
|
||||||
|
const_val,
|
||||||
|
tables,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
|
ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
|
||||||
ty::ErrorCt(_) => unreachable!(),
|
ty::ErrorCt(_) => unreachable!(),
|
||||||
@@ -1402,6 +1406,11 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
|
|||||||
let id = tables.intern_const(*self);
|
let id = tables.intern_const(*self);
|
||||||
Const::new(kind, ty, id)
|
Const::new(kind, ty, id)
|
||||||
}
|
}
|
||||||
|
mir::Const::Val(val, ty) if matches!(val, mir::ConstValue::ZeroSized) => {
|
||||||
|
let ty = ty.stable(tables);
|
||||||
|
let id = tables.intern_const(*self);
|
||||||
|
Const::new(ConstantKind::ZeroSized, ty, id)
|
||||||
|
}
|
||||||
mir::Const::Val(val, ty) => {
|
mir::Const::Val(val, ty) => {
|
||||||
let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
|
let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
|
||||||
let ty = ty.stable(tables);
|
let ty = ty.stable(tables);
|
||||||
|
|||||||
@@ -444,6 +444,9 @@ pub enum ConstantKind {
|
|||||||
Allocated(Allocation),
|
Allocated(Allocation),
|
||||||
Unevaluated(UnevaluatedConst),
|
Unevaluated(UnevaluatedConst),
|
||||||
Param(ParamConst),
|
Param(ParamConst),
|
||||||
|
/// Store ZST constants.
|
||||||
|
/// We have to special handle these constants since its type might be generic.
|
||||||
|
ZeroSized,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ impl Visitable for Const {
|
|||||||
match &self.kind() {
|
match &self.kind() {
|
||||||
super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
|
super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
|
||||||
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
|
super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
|
||||||
super::ty::ConstantKind::Param(_) => {}
|
super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {}
|
||||||
}
|
}
|
||||||
self.ty().visit(visitor)
|
self.ty().visit(visitor)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user