Skip to content

Commit e3f6931

Browse files
RalfJungpietroalbini
authored andcommitted
do not normalize non-scalar constants to a ConstValue::ScalarPair
1 parent 310a921 commit e3f6931

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

src/librustc_mir/const_eval.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc::hir::{self, def_id::DefId};
1717
use rustc::mir::interpret::ConstEvalErr;
1818
use rustc::mir;
1919
use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
20-
use rustc::ty::layout::{LayoutOf, TyLayout};
20+
use rustc::ty::layout::{self, LayoutOf, TyLayout};
2121
use rustc::ty::subst::Subst;
2222
use rustc_data_structures::indexed_vec::IndexVec;
2323

@@ -90,8 +90,18 @@ pub fn eval_promoted<'a, 'mir, 'tcx>(
9090
pub fn op_to_const<'tcx>(
9191
ecx: &EvalContext<'_, '_, 'tcx, CompileTimeEvaluator>,
9292
op: OpTy<'tcx>,
93-
normalize: bool,
93+
may_normalize: bool,
9494
) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
95+
// We do not normalize just any data. Only scalar layout and fat pointers.
96+
let normalize = may_normalize
97+
&& match op.layout.abi {
98+
layout::Abi::Scalar(..) => true,
99+
layout::Abi::ScalarPair(..) => {
100+
// Must be a fat pointer
101+
op.layout.ty.builtin_deref(true).is_some()
102+
},
103+
_ => false,
104+
};
95105
let normalized_op = if normalize {
96106
ecx.try_read_value(op)?
97107
} else {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
2222

2323
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant cannot be used
2424

25-
const FIELD_PATH: Struct = Struct { //~ ERROR this constant cannot be used
25+
const FIELD_PATH: Struct = Struct { //~ ERROR this constant likely exhibits undefined behavior
2626
a: 42,
2727
b: unsafe { UNION.field3 },
2828
};

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant can
66
|
77
= note: #[deny(const_err)] on by default
88

9-
error: this constant cannot be used
9+
error[E0080]: this constant likely exhibits undefined behavior
1010
--> $DIR/union-ice.rs:25:1
1111
|
12-
LL | / const FIELD_PATH: Struct = Struct { //~ ERROR this constant cannot be used
12+
LL | / const FIELD_PATH: Struct = Struct { //~ ERROR this constant likely exhibits undefined behavior
1313
LL | | a: 42,
1414
LL | | b: unsafe { UNION.field3 },
1515
LL | | };
16-
| |__^ attempted to read undefined bytes
16+
| |__^ type validation failed: encountered undefined bytes at .b
17+
|
18+
= 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
1719

1820
error[E0080]: this constant likely exhibits undefined behavior
1921
--> $DIR/union-ice.rs:35:1

src/test/ui/issues/issue-54387.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// compile-pass
2+
3+
pub struct GstRc {
4+
_obj: *const (),
5+
_borrowed: bool,
6+
}
7+
8+
const FOO: Option<GstRc> = None;
9+
10+
fn main() {
11+
let _meh = FOO;
12+
}

0 commit comments

Comments
 (0)