Stop using the `const_eval` query for initializers of statics

As a side effect, we now represent most promoteds as `ConstValue::Scalar` again. This is useful because all implict promoteds are just references anyway and most explicit promoteds are numeric arguments to `asm!` or SIMD instructions.
This commit is contained in:
Oliver Scherer 2020-07-31 13:27:54 +02:00
parent 083f1d7a37
commit 2d7ac728e4
17 changed files with 53 additions and 108 deletions

View File

@ -12,7 +12,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::Node; use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{ use rustc_middle::mir::interpret::{
read_target_uint, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Pointer, read_target_uint, Allocation, ErrorHandled, GlobalAlloc, Pointer,
}; };
use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::MonoItem;
use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::ty::{self, Instance, Ty};
@ -85,10 +85,7 @@ pub fn codegen_static_initializer(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
def_id: DefId, def_id: DefId,
) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> { ) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> {
let alloc = match cx.tcx.const_eval_poly(def_id)? { let alloc = cx.tcx.eval_static_initializer(def_id)?;
ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => alloc,
val => bug!("static const eval returned {:#?}", val),
};
Ok((const_alloc_to_llvm(cx, alloc), alloc)) Ok((const_alloc_to_llvm(cx, alloc), alloc))
} }

View File

@ -13,7 +13,7 @@ use rustc_ast as ast;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::{AllocId, ConstValue, Pointer, Scalar}; use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::mir::AssertKind; use rustc_middle::mir::AssertKind;
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
@ -867,24 +867,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let ty = constant.literal.ty; let ty = constant.literal.ty;
let size = bx.layout_of(ty).size; let size = bx.layout_of(ty).size;
let scalar = match const_value { let scalar = match const_value {
// Promoted constants are evaluated into a ByRef instead of a Scalar, ConstValue::Scalar(s) => s,
// but we want the scalar value here. _ => span_bug!(
ConstValue::ByRef { alloc, offset } => { span,
let ptr = Pointer::new(AllocId(0), offset); "expected Scalar for promoted asm const, but got {:#?}",
alloc const_value
.read_scalar(&bx, ptr, size) ),
.and_then(|s| s.check_init())
.unwrap_or_else(|e| {
bx.tcx().sess.span_err(
span,
&format!("Could not evaluate asm const: {}", e),
);
// We are erroring out, just emit a dummy constant.
Scalar::from_u64(0)
})
}
_ => span_bug!(span, "expected ByRef for promoted asm const"),
}; };
let value = scalar.assert_bits(size); let value = scalar.assert_bits(size);
let string = match ty.kind() { let string = match ty.kind() {

View File

@ -1473,21 +1473,18 @@ declare_lint_pass!(
UnusedBrokenConst => [] UnusedBrokenConst => []
); );
fn check_const(cx: &LateContext<'_>, body_id: hir::BodyId) {
let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
// trigger the query once for all constants since that will already report the errors
// FIXME: Use ensure here
let _ = cx.tcx.const_eval_poly(def_id);
}
impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst { impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
match it.kind { match it.kind {
hir::ItemKind::Const(_, body_id) => { hir::ItemKind::Const(_, body_id) => {
check_const(cx, body_id); let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
// trigger the query once for all constants since that will already report the errors
// FIXME: Use ensure here
let _ = cx.tcx.const_eval_poly(def_id);
} }
hir::ItemKind::Static(_, _, body_id) => { hir::ItemKind::Static(_, _, body_id) => {
check_const(cx, body_id); let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
let _ = cx.tcx.eval_static_initializer(def_id);
} }
_ => {} _ => {}
} }

View File

@ -182,7 +182,7 @@ pub(super) fn op_to_const<'tcx>(
} }
} }
fn validate_and_turn_into_const<'tcx>( fn turn_into_const<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
constant: RawConst<'tcx>, constant: RawConst<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
@ -191,30 +191,21 @@ fn validate_and_turn_into_const<'tcx>(
let def_id = cid.instance.def.def_id(); let def_id = cid.instance.def.def_id();
let is_static = tcx.is_static(def_id); let is_static = tcx.is_static(def_id);
let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static); let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static);
let val = (|| {
let mplace = ecx.raw_const_to_mplace(constant)?;
// Turn this into a proper constant.
// Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides
// whether they become immediates.
if is_static || cid.promoted.is_some() {
let ptr = mplace.ptr.assert_ptr();
Ok(ConstValue::ByRef {
alloc: ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(),
offset: ptr.offset,
})
} else {
Ok(op_to_const(&ecx, mplace.into()))
}
})();
// FIXME: Can this ever be an error and not be a compiler bug or can we just ICE here? let mplace = ecx.raw_const_to_mplace(constant).map_err(|error| {
val.map_err(|error| { // FIXME: Can the above ever error and not be a compiler bug or can we just ICE here?
let err = ConstEvalErr::new(&ecx, error, None); let err = ConstEvalErr::new(&ecx, error, None);
err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
diag.note(note_on_undefined_behavior_error()); diag.note(note_on_undefined_behavior_error());
diag.emit(); diag.emit();
}) })
}) })?;
assert!(
!is_static || cid.promoted.is_some(),
"the const eval query should not be used for statics, use `const_eval_raw` instead"
);
// Turn this into a proper constant.
Ok(op_to_const(&ecx, mplace.into()))
} }
pub fn const_eval_validated_provider<'tcx>( pub fn const_eval_validated_provider<'tcx>(
@ -248,7 +239,7 @@ pub fn const_eval_validated_provider<'tcx>(
}); });
} }
tcx.const_eval_raw(key).and_then(|val| validate_and_turn_into_const(tcx, val, key)) tcx.const_eval_raw(key).and_then(|val| turn_into_const(tcx, val, key))
} }
pub fn const_eval_raw_provider<'tcx>( pub fn const_eval_raw_provider<'tcx>(

View File

@ -914,13 +914,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} else { } else {
self.param_env self.param_env
}; };
// We use `const_eval_raw` here, and get an unvalidated result. That is okay:
// Our result will later be validated anyway, and there seems no good reason
// to have to fail early here. This is also more consistent with
// `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
// FIXME: We can hit delay_span_bug if this is an invalid const, interning finds
// that problem, but we never run validation to show an error. Can we ensure
// this does not happen?
let val = self.tcx.const_eval_raw(param_env.and(gid))?; let val = self.tcx.const_eval_raw(param_env.and(gid))?;
self.raw_const_to_mplace(val) self.raw_const_to_mplace(val)
} }

View File

@ -554,11 +554,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::ConstKind::Unevaluated(def, substs, promoted) => { ty::ConstKind::Unevaluated(def, substs, promoted) => {
let instance = self.resolve(def.did, substs)?; let instance = self.resolve(def.did, substs)?;
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
// The reason we use `const_eval_raw` everywhere else is to prevent cycles during // The reason we use `const_eval` here is that there can never be a `ty::ConstKind`
// validation, because validation automatically reads through any references, thus // that directly mentions the initializer of a static. Statics are always encoded
// potentially requiring the current static to be evaluated again. This is not a // as constants with vaule `&STATIC`.
// problem here, because we are building an operand which means an actual read is
// happening.
return Ok(self.const_eval(GlobalId { instance, promoted }, val.ty)?); return Ok(self.const_eval(GlobalId { instance, promoted }, val.ty)?);
} }
ty::ConstKind::Infer(..) ty::ConstKind::Infer(..)

View File

@ -364,8 +364,10 @@ fn collect_items_rec<'tcx>(
recursion_depth_reset = None; recursion_depth_reset = None;
if let Ok(val) = tcx.const_eval_poly(def_id) { if let Ok(alloc) = tcx.eval_static_initializer(def_id) {
collect_const_value(tcx, val, &mut neighbors); for &((), id) in alloc.relocations().values() {
collect_miri(tcx, id, &mut neighbors);
}
} }
} }
MonoItem::Fn(instance) => { MonoItem::Fn(instance) => {

View File

@ -631,14 +631,11 @@ pub fn write_allocations<'tcx>(
None => write!(w, " (deallocated)")?, None => write!(w, " (deallocated)")?,
Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?, Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?,
Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => { Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
match tcx.const_eval_poly(did) { match tcx.eval_static_initializer(did) {
Ok(ConstValue::ByRef { alloc, .. }) => { Ok(alloc) => {
write!(w, " (static: {}, ", tcx.def_path_str(did))?; write!(w, " (static: {}, ", tcx.def_path_str(did))?;
write_allocation_track_relocs(w, alloc)?; write_allocation_track_relocs(w, alloc)?;
} }
Ok(_) => {
span_bug!(tcx.def_span(did), " static item without `ByRef` initializer")
}
Err(_) => write!( Err(_) => write!(
w, w,
" (static: {}, error during initializer evaluation)", " (static: {}, error during initializer evaluation)",

View File

@ -111,7 +111,6 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::adjustment::{ use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
}; };
@ -2070,8 +2069,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S
// `#[link_section]` may contain arbitrary, or even undefined bytes, but it is // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
// the consumer's responsibility to ensure all bytes that have been read // the consumer's responsibility to ensure all bytes that have been read
// have defined values. // have defined values.
match tcx.const_eval_poly(id.to_def_id()) { match tcx.eval_static_initializer(id.to_def_id()) {
Ok(ConstValue::ByRef { alloc, .. }) => { Ok(alloc) => {
if alloc.relocations().len() != 0 { if alloc.relocations().len() != 0 {
let msg = "statics with a custom `#[link_section]` must be a \ let msg = "statics with a custom `#[link_section]` must be a \
simple list of bytes on the wasm target with no \ simple list of bytes on the wasm target with no \
@ -2079,7 +2078,6 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S
tcx.sess.span_err(span, msg); tcx.sess.span_err(span, msg);
} }
} }
Ok(_) => bug!("Matching on non-ByRef static"),
Err(_) => {} Err(_) => {}
} }
} }

View File

@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:37:5 --> $DIR/const-pointer-values-in-various-types.rs:37:5
| |
LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -76,7 +76,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:52:5 --> $DIR/const-pointer-values-in-various-types.rs:52:5
| |
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc47, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc38, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -100,7 +100,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:61:5 --> $DIR/const-pointer-values-in-various-types.rs:61:5
| |
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc62, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc50, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -148,7 +148,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:79:5 --> $DIR/const-pointer-values-in-various-types.rs:79:5
| |
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc86, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc71, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -188,7 +188,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:94:5 --> $DIR/const-pointer-values-in-various-types.rs:94:5
| |
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc101, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc86, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -212,7 +212,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/const-pointer-values-in-various-types.rs:103:5 --> $DIR/const-pointer-values-in-various-types.rs:103:5
| |
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc110, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc95, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

View File

@ -18,7 +18,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:30:1 --> $DIR/ub-enum.rs:30:1
| |
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc13 at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc12 at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:44:1 --> $DIR/ub-enum.rs:44:1
| |
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc20 at .<enum-tag>, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18 at .<enum-tag>, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:47:1 --> $DIR/ub-enum.rs:47:1
| |
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc25 at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22 at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
@ -58,7 +58,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:60:1 --> $DIR/ub-enum.rs:60:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc32 at .<enum-tag>, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc28 at .<enum-tag>, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

View File

@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL! LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
LL | | let out_of_bounds_ptr = &ptr[255]; LL | | let out_of_bounds_ptr = &ptr[255];
| | ^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc11 which has size 1 | | ^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc10 which has size 1
LL | | mem::transmute(out_of_bounds_ptr) LL | | mem::transmute(out_of_bounds_ptr)
LL | | } }; LL | | } };
| |____- | |____-

View File

@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref.rs:23:1 --> $DIR/ub-ref.rs:23:1
| |
LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc16, but expected initialized plain (non-pointer) bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc14, but expected initialized plain (non-pointer) bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

View File

@ -10,11 +10,7 @@ note: ...which requires const-evaluating `FOO`...
LL | static FOO: () = FOO; LL | static FOO: () = FOO;
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating `FOO`, completing the cycle = note: ...which again requires const-evaluating `FOO`, completing the cycle
note: cycle used when const-evaluating + checking `FOO` = note: cycle used when running analysis passes on this crate
--> $DIR/recursive-zst-static.rs:10:1
|
LL | static FOO: () = FOO;
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -10,11 +10,7 @@ note: ...which requires const-evaluating `FOO`...
LL | static FOO: () = FOO; LL | static FOO: () = FOO;
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating `FOO`, completing the cycle = note: ...which again requires const-evaluating `FOO`, completing the cycle
note: cycle used when const-evaluating + checking `FOO` = note: cycle used when running analysis passes on this crate
--> $DIR/recursive-zst-static.rs:10:1
|
LL | static FOO: () = FOO;
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -10,11 +10,7 @@ note: ...which requires const-evaluating `FOO`...
LL | pub static FOO: u32 = FOO; LL | pub static FOO: u32 = FOO;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating `FOO`, completing the cycle = note: ...which again requires const-evaluating `FOO`, completing the cycle
note: cycle used when const-evaluating + checking `FOO` = note: cycle used when running analysis passes on this crate
--> $DIR/recursive-static-definition.rs:1:1
|
LL | pub static FOO: u32 = FOO;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -16,11 +16,7 @@ note: ...which requires const-evaluating `C`...
LL | pub static mut C: u32 = unsafe { C = 1; 0 }; LL | pub static mut C: u32 = unsafe { C = 1; 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating `C`, completing the cycle = note: ...which again requires const-evaluating `C`, completing the cycle
note: cycle used when const-evaluating + checking `C` = note: cycle used when running analysis passes on this crate
--> $DIR/write-to-static-mut-in-static.rs:5:1
|
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors