Skip to content

Commit c4cf115

Browse files
committedNov 20, 2018
Auto merge of rust-lang#55720 - RalfJung:const-eval-raw, r=oli-obk
Make const_eval_raw query return just an AllocId r? @oli-obk

21 files changed

+138
-109
lines changed
 

‎src/librustc/ich/impls_ty.rs

+4
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ impl_stable_hash_for!(
317317
ByRef(id, alloc, offset),
318318
}
319319
);
320+
impl_stable_hash_for!(struct ::mir::interpret::RawConst<'tcx> {
321+
alloc_id,
322+
ty,
323+
});
320324

321325
impl_stable_hash_for! {
322326
impl<Tag> for struct mir::interpret::Pointer<Tag> {

‎src/librustc/mir/interpret/error.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use ty::{self, Ty, layout};
1616
use ty::layout::{Size, Align, LayoutError};
1717
use rustc_target::spec::abi::Abi;
1818

19-
use super::{Pointer, InboundsCheck, ScalarMaybeUndef};
19+
use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef};
2020

2121
use backtrace::Backtrace;
2222

@@ -46,6 +46,7 @@ impl ErrorHandled {
4646
}
4747
}
4848

49+
pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
4950
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
5051

5152
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]

‎src/librustc/mir/interpret/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ mod pointer;
2222

2323
pub use self::error::{
2424
EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
25-
FrameInfo, ConstEvalResult, ErrorHandled,
25+
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled,
2626
};
2727

28-
pub use self::value::{Scalar, ConstValue, ScalarMaybeUndef};
28+
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
2929

3030
pub use self::allocation::{
3131
InboundsCheck, Allocation, AllocationExtra,

‎src/librustc/mir/interpret/value.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,28 @@
1010

1111
use std::fmt;
1212

13-
use ty::layout::{HasDataLayout, Size};
14-
use ty::subst::Substs;
15-
use hir::def_id::DefId;
13+
use crate::ty::{Ty, subst::Substs, layout::{HasDataLayout, Size}};
14+
use crate::hir::def_id::DefId;
1615

1716
use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate};
1817

18+
/// Represents the result of a raw const operation, pre-validation.
19+
#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
20+
pub struct RawConst<'tcx> {
21+
// the value lives here, at offset 0, and that allocation definitely is a `AllocType::Memory`
22+
// (so you can use `AllocMap::unwrap_memory`).
23+
pub alloc_id: AllocId,
24+
pub ty: Ty<'tcx>,
25+
}
26+
1927
/// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which
2028
/// matches the LocalValue optimizations for easy conversions between Value and ConstValue.
2129
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
2230
pub enum ConstValue<'tcx> {
2331
/// Never returned from the `const_eval` query, but the HIR contains these frequently in order
2432
/// to allow HIR creation to happen for everything before needing to be able to run constant
2533
/// evaluation
34+
/// FIXME: The query should then return a type that does not even have this variant.
2635
Unevaluated(DefId, &'tcx Substs<'tcx>),
2736

2837
/// Used only for types with layout::abi::Scalar ABI and ZSTs

‎src/librustc/ty/query/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use middle::stability::{self, DeprecationEntry};
2727
use middle::lib_features::LibFeatures;
2828
use middle::lang_items::{LanguageItems, LangItem};
2929
use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
30-
use mir::interpret::ConstEvalResult;
30+
use mir::interpret::{ConstEvalRawResult, ConstEvalResult};
3131
use mir::mono::CodegenUnit;
3232
use mir;
3333
use mir::interpret::GlobalId;
@@ -309,7 +309,7 @@ define_queries! { <'tcx>
309309
/// validation. Please add a comment to every use site explaining why using `const_eval`
310310
/// isn't sufficient
311311
[] fn const_eval_raw: const_eval_raw_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
312-
-> ConstEvalResult<'tcx>,
312+
-> ConstEvalRawResult<'tcx>,
313313

314314
/// Results of evaluating const items or constants embedded in
315315
/// other items (such as enum variant explicit discriminants).

‎src/librustc_mir/const_eval.rs

+32-24
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ use rustc::util::common::ErrorReported;
3131
use syntax::ast::Mutability;
3232
use syntax::source_map::{Span, DUMMY_SP};
3333

34-
use interpret::{self,
35-
PlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, ConstValue, Pointer,
34+
use crate::interpret::{self,
35+
PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, RawConst, ConstValue, Pointer,
3636
EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup,
3737
Allocation, AllocId, MemoryKind,
3838
snapshot, RefTracking,
@@ -94,11 +94,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
9494
cid: GlobalId<'tcx>,
9595
mir: &'mir mir::Mir<'tcx>,
9696
param_env: ty::ParamEnv<'tcx>,
97-
) -> EvalResult<'tcx, OpTy<'tcx>> {
97+
) -> EvalResult<'tcx, MPlaceTy<'tcx>> {
9898
let mut ecx = mk_borrowck_eval_cx(tcx, cid.instance, mir, DUMMY_SP).unwrap();
9999
eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env)
100100
}
101101

102+
// FIXME: These two conversion functions are bad hacks. We should just always use allocations.
102103
pub fn op_to_const<'tcx>(
103104
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
104105
op: OpTy<'tcx>,
@@ -144,13 +145,20 @@ pub fn op_to_const<'tcx>(
144145
};
145146
Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty))
146147
}
148+
pub fn const_to_op<'tcx>(
149+
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
150+
cnst: &ty::Const<'tcx>,
151+
) -> EvalResult<'tcx, OpTy<'tcx>> {
152+
let op = ecx.const_value_to_op(cnst.val)?;
153+
Ok(OpTy { op, layout: ecx.layout_of(cnst.ty)? })
154+
}
147155

148156
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
149157
tcx: TyCtxt<'a, 'tcx, 'tcx>,
150158
cid: GlobalId<'tcx>,
151159
mir: Option<&'mir mir::Mir<'tcx>>,
152160
param_env: ty::ParamEnv<'tcx>,
153-
) -> (EvalResult<'tcx, OpTy<'tcx>>, CompileTimeEvalContext<'a, 'mir, 'tcx>) {
161+
) -> (EvalResult<'tcx, MPlaceTy<'tcx>>, CompileTimeEvalContext<'a, 'mir, 'tcx>) {
154162
// we start out with the best span we have
155163
// and try improving it down the road when more information is available
156164
let span = tcx.def_span(cid.instance.def_id());
@@ -166,7 +174,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
166174
cid: GlobalId<'tcx>,
167175
mir: Option<&'mir mir::Mir<'tcx>>,
168176
param_env: ty::ParamEnv<'tcx>,
169-
) -> EvalResult<'tcx, OpTy<'tcx>> {
177+
) -> EvalResult<'tcx, MPlaceTy<'tcx>> {
170178
debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env);
171179
let tcx = ecx.tcx.tcx;
172180
let mut mir = match mir {
@@ -206,7 +214,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
206214
ecx.memory.intern_static(ret.ptr.to_ptr()?.alloc_id, mutability)?;
207215

208216
debug!("eval_body_using_ecx done: {:?}", *ret);
209-
Ok(ret.into())
217+
Ok(ret)
210218
}
211219

212220
impl<'tcx> Into<EvalError<'tcx>> for ConstEvalError {
@@ -494,7 +502,7 @@ pub fn const_field<'a, 'tcx>(
494502
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
495503
let result = (|| {
496504
// get the operand again
497-
let op = ecx.const_to_op(value)?;
505+
let op = const_to_op(&ecx, value)?;
498506
// downcast
499507
let down = match variant {
500508
None => op,
@@ -521,7 +529,7 @@ pub fn const_variant_index<'a, 'tcx>(
521529
) -> EvalResult<'tcx, VariantIdx> {
522530
trace!("const_variant_index: {:?}, {:?}", instance, val);
523531
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
524-
let op = ecx.const_to_op(val)?;
532+
let op = const_to_op(&ecx, val)?;
525533
Ok(ecx.read_discriminant(op)?.1)
526534
}
527535

@@ -534,15 +542,17 @@ pub fn error_to_const_error<'a, 'mir, 'tcx>(
534542
ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span }
535543
}
536544

537-
fn validate_const<'a, 'tcx>(
545+
fn validate_and_turn_into_const<'a, 'tcx>(
538546
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
539-
constant: &'tcx ty::Const<'tcx>,
547+
constant: RawConst<'tcx>,
540548
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
541549
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
542550
let cid = key.value;
543551
let ecx = mk_eval_cx(tcx, cid.instance, key.param_env).unwrap();
544552
let val = (|| {
545-
let op = ecx.const_to_op(constant)?;
553+
let op = ecx.raw_const_to_mplace(constant)?.into();
554+
// FIXME: Once the visitor infrastructure landed, change validation to
555+
// work directly on `MPlaceTy`.
546556
let mut ref_tracking = RefTracking::new(op);
547557
while let Some((op, path)) = ref_tracking.todo.pop() {
548558
ecx.validate_operand(
@@ -552,7 +562,10 @@ fn validate_const<'a, 'tcx>(
552562
/* const_mode */ true,
553563
)?;
554564
}
555-
Ok(constant)
565+
// Now that we validated, turn this into a proper constant
566+
let def_id = cid.instance.def.def_id();
567+
let normalize = tcx.is_static(def_id).is_none() && cid.promoted.is_none();
568+
op_to_const(&ecx, op, normalize)
556569
})();
557570

558571
val.map_err(|error| {
@@ -591,14 +604,14 @@ pub fn const_eval_provider<'a, 'tcx>(
591604
}
592605
}
593606
tcx.const_eval_raw(key).and_then(|val| {
594-
validate_const(tcx, val, key)
607+
validate_and_turn_into_const(tcx, val, key)
595608
})
596609
}
597610

598611
pub fn const_eval_raw_provider<'a, 'tcx>(
599612
tcx: TyCtxt<'a, 'tcx, 'tcx>,
600613
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
601-
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
614+
) -> ::rustc::mir::interpret::ConstEvalRawResult<'tcx> {
602615
// Because the constant is computed twice (once per value of `Reveal`), we are at risk of
603616
// reporting the same error twice here. To resolve this, we check whether we can evaluate the
604617
// constant in the more restrictive `Reveal::UserFacing`, which most likely already was
@@ -648,16 +661,11 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
648661
};
649662

650663
let (res, ecx) = eval_body_and_ecx(tcx, cid, None, key.param_env);
651-
res.and_then(|op| {
652-
let normalize = tcx.is_static(def_id).is_none() && cid.promoted.is_none();
653-
if !normalize {
654-
// Sanity check: These must always be a MemPlace
655-
match op.op {
656-
Operand::Indirect(_) => { /* all is good */ },
657-
Operand::Immediate(_) => bug!("const eval gave us an Immediate"),
658-
}
659-
}
660-
op_to_const(&ecx, op, normalize)
664+
res.and_then(|place| {
665+
Ok(RawConst {
666+
alloc_id: place.to_ptr().expect("we allocated this ptr!").alloc_id,
667+
ty: place.layout.ty
668+
})
661669
}).map_err(|error| {
662670
let err = error_to_const_error(&ecx, error);
663671
// errors in statics are always emitted as fatal errors

‎src/librustc_mir/interpret/eval_context.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -588,18 +588,26 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
588588
Ok(())
589589
}
590590

591-
pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
591+
pub fn const_eval_raw(
592+
&self,
593+
gid: GlobalId<'tcx>,
594+
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
592595
let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() {
593596
ty::ParamEnv::reveal_all()
594597
} else {
595598
self.param_env
596599
};
597-
self.tcx.const_eval(param_env.and(gid)).map_err(|err| {
600+
// We use `const_eval_raw` here, and get an unvalidated result. That is okay:
601+
// Our result will later be validated anyway, and there seems no good reason
602+
// to have to fail early here. This is also more consistent with
603+
// `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
604+
let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
598605
match err {
599-
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
600-
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
606+
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant,
607+
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric,
601608
}
602-
})
609+
})?;
610+
self.raw_const_to_mplace(val)
603611
}
604612

605613
pub fn dump_place(&self, place: Place<M::PointerTag>) {

‎src/librustc_mir/interpret/memory.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_data_structures::fx::{FxHashSet, FxHashMap};
2828
use syntax::ast::Mutability;
2929

3030
use super::{
31-
Pointer, AllocId, Allocation, ConstValue, GlobalId, AllocationExtra, InboundsCheck,
31+
Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InboundsCheck,
3232
EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic,
3333
Machine, AllocMap, MayLeak, ScalarMaybeUndef, ErrorHandled,
3434
};
@@ -374,14 +374,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
374374
ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
375375
ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
376376
}
377-
}).map(|const_val| {
378-
if let ConstValue::ByRef(_, allocation, _) = const_val.val {
379-
// We got tcx memory. Let the machine figure out whether and how to
380-
// turn that into memory with the right pointer tag.
381-
M::adjust_static_allocation(allocation)
382-
} else {
383-
bug!("Matching on non-ByRef static")
384-
}
377+
}).map(|raw_const| {
378+
let allocation = tcx.alloc_map.lock().unwrap_memory(raw_const.alloc_id);
379+
// We got tcx memory. Let the machine figure out whether and how to
380+
// turn that into memory with the right pointer tag.
381+
M::adjust_static_allocation(allocation)
385382
})
386383
}
387384

‎src/librustc_mir/interpret/operand.rs

+7-20
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
use std::convert::TryInto;
1515

16-
use rustc::{mir, ty};
16+
use rustc::mir;
1717
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx};
1818

1919
use rustc::mir::interpret::{
@@ -535,19 +535,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
535535
.collect()
536536
}
537537

538-
// Also used e.g. when miri runs into a constant.
539-
pub(super) fn const_value_to_op(
538+
// Used when miri runs into a constant, and by CTFE.
539+
// FIXME: CTFE should use allocations, then we can make this private (embed it into
540+
// `eval_operand`, ideally).
541+
pub(crate) fn const_value_to_op(
540542
&self,
541543
val: ConstValue<'tcx>,
542544
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
543545
trace!("const_value_to_op: {:?}", val);
544546
match val {
545547
ConstValue::Unevaluated(def_id, substs) => {
546548
let instance = self.resolve(def_id, substs)?;
547-
self.global_to_op(GlobalId {
549+
Ok(*OpTy::from(self.const_eval_raw(GlobalId {
548550
instance,
549551
promoted: None,
550-
})
552+
})?))
551553
}
552554
ConstValue::ByRef(id, alloc, offset) => {
553555
// We rely on mutability being set correctly in that allocation to prevent writes
@@ -565,21 +567,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
565567
Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()),
566568
}
567569
}
568-
pub fn const_to_op(
569-
&self,
570-
cnst: &ty::Const<'tcx>,
571-
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
572-
let op = self.const_value_to_op(cnst.val)?;
573-
Ok(OpTy { op, layout: self.layout_of(cnst.ty)? })
574-
}
575-
576-
pub(super) fn global_to_op(
577-
&self,
578-
gid: GlobalId<'tcx>
579-
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
580-
let cv = self.const_eval(gid)?;
581-
self.const_value_to_op(cv.val)
582-
}
583570

584571
/// Read discriminant, return the runtime value as well as the variant index.
585572
pub fn read_discriminant(

‎src/librustc_mir/interpret/place.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ use rustc::mir;
2020
use rustc::ty::{self, Ty};
2121
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx};
2222

23-
use rustc::mir::interpret::{
24-
GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic
25-
};
2623
use super::{
24+
GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic,
2725
EvalContext, Machine, AllocMap, AllocationExtra,
28-
Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind
26+
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind
2927
};
3028

3129
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
@@ -555,16 +553,10 @@ where
555553
Ok(match *mir_place {
556554
Promoted(ref promoted) => {
557555
let instance = self.frame().instance;
558-
let op = self.global_to_op(GlobalId {
556+
self.const_eval_raw(GlobalId {
559557
instance,
560558
promoted: Some(promoted.0),
561-
})?;
562-
let mplace = op.to_mem_place(); // these are always in memory
563-
let ty = self.monomorphize(promoted.1, self.substs());
564-
MPlaceTy {
565-
mplace,
566-
layout: self.layout_of(ty)?,
567-
}
559+
})?
568560
}
569561

570562
Static(ref static_) => {
@@ -981,6 +973,19 @@ where
981973
Ok(OpTy { op, layout: place.layout })
982974
}
983975

976+
pub fn raw_const_to_mplace(
977+
&self,
978+
raw: RawConst<'tcx>,
979+
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
980+
// This must be an allocation in `tcx`
981+
assert!(self.tcx.alloc_map.lock().get(raw.alloc_id).is_some());
982+
let layout = self.layout_of(raw.ty)?;
983+
Ok(MPlaceTy::from_aligned_ptr(
984+
Pointer::new(raw.alloc_id, Size::ZERO).with_default_tag(),
985+
layout,
986+
))
987+
}
988+
984989
/// Turn a place with a `dyn Trait` type into a place with the actual dynamic type.
985990
/// Also return some more information so drop doesn't have to run the same code twice.
986991
pub(super) fn unpack_dyn_trait(&self, mplace: MPlaceTy<'tcx, M::PointerTag>)

‎src/librustc_mir/transform/const_prop.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ use rustc::ty::layout::{
2929
};
3030

3131
use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind};
32-
use const_eval::{CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_borrowck_eval_cx};
32+
use const_eval::{
33+
CompileTimeInterpreter, const_to_op, error_to_const_error, eval_promoted, mk_borrowck_eval_cx
34+
};
3335
use transform::{MirPass, MirSource};
3436

3537
pub struct ConstProp;
@@ -262,7 +264,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
262264
source_info: SourceInfo,
263265
) -> Option<Const<'tcx>> {
264266
self.ecx.tcx.span = source_info.span;
265-
match self.ecx.const_to_op(c.literal) {
267+
match const_to_op(&self.ecx, c.literal) {
266268
Ok(op) => {
267269
Some((op, c.span))
268270
},
@@ -309,7 +311,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
309311
eval_promoted(this.tcx, cid, this.mir, this.param_env)
310312
})?;
311313
trace!("evaluated promoted {:?} to {:?}", promoted, res);
312-
Some((res, source_info.span))
314+
Some((res.into(), source_info.span))
313315
},
314316
_ => None,
315317
}

‎src/test/ui/consts/const-err4.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ union Foo {
1616

1717
enum Bar {
1818
Boo = [unsafe { Foo { b: () }.a }; 4][3],
19-
//~^ ERROR evaluation of constant value failed
19+
//~^ ERROR it is undefined behavior to use this value
2020
}
2121

2222
fn main() {

‎src/test/ui/consts/const-err4.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
error[E0080]: evaluation of constant value failed
1+
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/const-err4.rs:18:11
33
|
44
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
6+
|
7+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
68

79
error: aborting due to previous error
810

‎src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() {
3737
//~^ ERROR it is undefined behavior to use this value
3838

3939
const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
40-
//~^ ERROR any use of this value will cause an error
40+
//~^ ERROR it is undefined behavior to use this value
4141

4242
const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
4343
//~^ ERROR any use of this value will cause an error
@@ -52,7 +52,7 @@ fn main() {
5252
//~^ ERROR it is undefined behavior to use this value
5353

5454
const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
55-
//~^ ERROR any use of this value will cause an error
55+
//~^ ERROR it is undefined behavior to use this value
5656

5757
const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
5858
//~^ ERROR any use of this value will cause an error

‎src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
4040
|
4141
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4242

43-
error: any use of this value will cause an error
43+
error[E0080]: it is undefined behavior to use this value
4444
--> $DIR/const-pointer-values-in-various-types.rs:39:5
4545
|
4646
LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
47-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
48+
|
49+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4850

4951
error: any use of this value will cause an error
5052
--> $DIR/const-pointer-values-in-various-types.rs:42:5
@@ -78,11 +80,13 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
7880
|
7981
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
8082

81-
error: any use of this value will cause an error
83+
error[E0080]: it is undefined behavior to use this value
8284
--> $DIR/const-pointer-values-in-various-types.rs:54:5
8385
|
8486
LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
85-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
87+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
88+
|
89+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
8690

8791
error: any use of this value will cause an error
8892
--> $DIR/const-pointer-values-in-various-types.rs:57:5

‎src/test/ui/consts/const-eval/ub-enum.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ enum Enum {
1616
A = 0,
1717
}
1818
union TransmuteEnum {
19-
a: &'static u8,
20-
out: Enum,
19+
in1: &'static u8,
20+
out1: Enum,
2121
}
2222

2323
// A pointer is guaranteed non-null
24-
const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out };
24+
const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
2525
//~^ ERROR is undefined behavior
2626

2727
// (Potentially) invalid enum discriminant
@@ -48,8 +48,8 @@ const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
4848
const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
4949
//~^ ERROR is undefined behavior
5050

51-
// Undef enum discriminant. In an arry to avoid `Scalar` layout.
52-
const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2];
51+
// Undef enum discriminant.
52+
const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
5353
//~^ ERROR is undefined behavior
5454

5555
// Pointer value in an enum with a niche that is not just 0.

‎src/test/ui/consts/const-eval/ub-enum.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/ub-enum.rs:24:1
33
|
4-
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
4+
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

@@ -33,8 +33,8 @@ LL | const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
3333
error[E0080]: it is undefined behavior to use this value
3434
--> $DIR/ub-enum.rs:52:1
3535
|
36-
LL | const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2];
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at [0], but expected a valid enum discriminant
36+
LL | const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
3838
|
3939
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4040

‎src/test/ui/consts/const-eval/union-const-eval-field.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const fn read_field2() -> Field2 {
3434
}
3535

3636
const fn read_field3() -> Field3 {
37-
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value
37+
const FIELD3: Field3 = unsafe { UNION.field3 };
38+
//~^ ERROR it is undefined behavior to use this value
3839
FIELD3
3940
}
4041

Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error: any use of this value will cause an error
1+
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/union-const-eval-field.rs:37:5
33
|
4-
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
4+
LL | const FIELD3: Field3 = unsafe { UNION.field3 };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
66
|
7-
= note: #[deny(const_err)] on by default
7+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

99
error: aborting due to previous error
1010

11+
For more information about this error, try `rustc --explain E0080`.

‎src/test/ui/consts/const-eval/union-ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ union DummyUnion {
2020

2121
const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
2222

23-
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error
23+
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value
2424

2525
const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to use this value
2626
a: 42,

‎src/test/ui/consts/const-eval/union-ice.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: any use of this value will cause an error
1+
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/union-ice.rs:23:1
33
|
4-
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
4+
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
66
|
7-
= note: #[deny(const_err)] on by default
7+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

99
error[E0080]: it is undefined behavior to use this value
1010
--> $DIR/union-ice.rs:25:1

0 commit comments

Comments
 (0)
Please sign in to comment.