Skip to content

Commit 5074489

Browse files
committed
Unregress using scalar unions in constants.
1 parent 7486b9c commit 5074489

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

src/librustc_mir/const_eval.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
6565
fn mplace_to_const<'tcx>(
6666
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
6767
mplace: MPlaceTy<'tcx>,
68-
) -> EvalResult<'tcx, ty::Const<'tcx>> {
68+
) -> ty::Const<'tcx> {
6969
let MemPlace { ptr, align, meta } = *mplace;
7070
// extract alloc-offset pair
7171
assert!(meta.is_none());
72-
let ptr = ptr.to_ptr()?;
73-
let alloc = ecx.memory.get(ptr.alloc_id)?;
72+
let ptr = ptr.to_ptr().unwrap();
73+
let alloc = ecx.memory.get(ptr.alloc_id).unwrap();
7474
assert!(alloc.align >= align);
7575
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes());
7676
let mut alloc = alloc.clone();
@@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>(
7979
// interned this? I thought that is the entire point of that `FinishStatic` stuff?
8080
let alloc = ecx.tcx.intern_const_alloc(alloc);
8181
let val = ConstValue::ByRef(ptr, alloc);
82-
Ok(ty::Const { val, ty: mplace.layout.ty })
82+
ty::Const { val, ty: mplace.layout.ty }
8383
}
8484

8585
fn op_to_const<'tcx>(
8686
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
8787
op: OpTy<'tcx>,
88-
) -> EvalResult<'tcx, ty::Const<'tcx>> {
89-
// We do not normalize just any data. Only scalar layout and slices.
88+
) -> ty::Const<'tcx> {
89+
// We do not normalize just any data. Only non-union scalars and slices.
9090
let normalize = match op.layout.abi {
91-
layout::Abi::Scalar(..) => true,
91+
layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()),
9292
layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
9393
_ => false,
9494
};
@@ -100,11 +100,11 @@ fn op_to_const<'tcx>(
100100
let val = match normalized_op {
101101
Ok(mplace) => return mplace_to_const(ecx, mplace),
102102
Err(Immediate::Scalar(x)) =>
103-
ConstValue::Scalar(x.not_undef()?),
103+
ConstValue::Scalar(x.not_undef().unwrap()),
104104
Err(Immediate::ScalarPair(a, b)) =>
105-
ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?),
105+
ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()),
106106
};
107-
Ok(ty::Const { val, ty: op.layout.ty })
107+
ty::Const { val, ty: op.layout.ty }
108108
}
109109

110110
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
@@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>(
488488
let field = ecx.operand_field(down, field.index() as u64).unwrap();
489489
// and finally move back to the const world, always normalizing because
490490
// this is not called for statics.
491-
op_to_const(&ecx, field).unwrap()
491+
op_to_const(&ecx, field)
492492
}
493493

494494
// this function uses `unwrap` copiously, because an already validated constant must have valid
@@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>(
534534
// Now that we validated, turn this into a proper constant.
535535
let def_id = cid.instance.def.def_id();
536536
if tcx.is_static(def_id).is_some() || cid.promoted.is_some() {
537-
mplace_to_const(&ecx, mplace)
537+
Ok(mplace_to_const(&ecx, mplace))
538538
} else {
539-
op_to_const(&ecx, mplace.into())
539+
Ok(op_to_const(&ecx, mplace.into()))
540540
}
541541
})();
542542

src/test/ui/consts/union_constant.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-pass
2+
3+
union Uninit {
4+
_never_use: *const u8,
5+
uninit: (),
6+
}
7+
8+
const UNINIT: Uninit = Uninit { uninit: () };
9+
10+
fn main() {}
11+

0 commit comments

Comments
 (0)