Skip to content

Commit 26c486f

Browse files
committed
Port more zero arg intrinsics to the const_eval query
1 parent bd9b93d commit 26c486f

File tree

7 files changed

+72
-66
lines changed

7 files changed

+72
-66
lines changed

src/librustc/mir/interpret/error.rs

+9
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,15 @@ fn print_backtrace(backtrace: &mut Backtrace) {
198198
eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
199199
}
200200

201+
impl From<ErrorHandled> for InterpErrorInfo<'tcx> {
202+
fn from(err: ErrorHandled) -> Self {
203+
match err {
204+
ErrorHandled::Reported => InterpError::ReferencedConstant,
205+
ErrorHandled::TooGeneric => InterpError::TooGeneric,
206+
}.into()
207+
}
208+
}
209+
201210
impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> {
202211
fn from(kind: InterpError<'tcx, u64>) -> Self {
203212
let backtrace = match env::var("RUST_CTFE_BACKTRACE") {

src/librustc_codegen_llvm/intrinsic.rs

+5-20
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
137137
let llfn = self.get_intrinsic(&("llvm.debugtrap"));
138138
self.call(llfn, &[], None)
139139
}
140-
"size_of" => {
141-
let tp_ty = substs.type_at(0);
142-
self.const_usize(self.size_of(tp_ty).bytes())
143-
}
144140
"va_start" => {
145141
self.va_start(args[0].immediate())
146142
}
@@ -192,10 +188,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
192188
self.const_usize(self.size_of(tp_ty).bytes())
193189
}
194190
}
195-
"min_align_of" => {
196-
let tp_ty = substs.type_at(0);
197-
self.const_usize(self.align_of(tp_ty).bytes())
198-
}
199191
"min_align_of_val" => {
200192
let tp_ty = substs.type_at(0);
201193
if let OperandValue::Pair(_, meta) = args[0].val {
@@ -205,10 +197,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
205197
self.const_usize(self.align_of(tp_ty).bytes())
206198
}
207199
}
208-
"pref_align_of" => {
209-
let tp_ty = substs.type_at(0);
210-
self.const_usize(self.layout_of(tp_ty).align.pref.bytes())
211-
}
200+
"size_of" |
201+
"pref_align_of" |
202+
"min_align_of" |
203+
"needs_drop" |
204+
"type_id" |
212205
"type_name" => {
213206
let gid = GlobalId {
214207
instance,
@@ -217,9 +210,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
217210
let ty_name = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).unwrap();
218211
OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self)
219212
}
220-
"type_id" => {
221-
self.const_u64(self.tcx.type_id_hash(substs.type_at(0)))
222-
}
223213
"init" => {
224214
let ty = substs.type_at(0);
225215
if !self.layout_of(ty).is_zst() {
@@ -242,11 +232,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
242232
"uninit" | "forget" => {
243233
return;
244234
}
245-
"needs_drop" => {
246-
let tp_ty = substs.type_at(0);
247-
248-
self.const_bool(self.type_needs_drop(tp_ty))
249-
}
250235
"offset" => {
251236
let ptr = args[0].immediate();
252237
let offset = args[1].immediate();

src/librustc_mir/const_eval.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ pub fn const_eval_provider<'tcx>(
596596
ty::FnDef(_, substs) => substs,
597597
_ => bug!("intrinsic with type {:?}", ty),
598598
};
599-
return Ok(eval_intrinsic(tcx, def_id, substs));
599+
return Ok(eval_intrinsic(tcx, key.param_env, def_id, substs));
600600
}
601601

602602
tcx.const_eval_raw(key).and_then(|val| {
@@ -606,12 +606,15 @@ pub fn const_eval_provider<'tcx>(
606606

607607
fn eval_intrinsic<'tcx>(
608608
tcx: TyCtxt<'tcx>,
609+
param_env: ty::ParamEnv<'tcx>,
609610
def_id: DefId,
610611
substs: SubstsRef<'tcx>,
611612
) -> &'tcx ty::Const<'tcx> {
612-
match &*tcx.item_name(def_id).as_str() {
613+
let tp_ty = substs.type_at(0);
614+
let name = &*tcx.item_name(def_id).as_str();
615+
match name {
613616
"type_name" => {
614-
let alloc = alloc_type_name(tcx, substs.type_at(0));
617+
let alloc = alloc_type_name(tcx, tp_ty);
615618
tcx.mk_const(ty::Const {
616619
val: ConstValue::Slice {
617620
data: alloc,
@@ -621,6 +624,24 @@ fn eval_intrinsic<'tcx>(
621624
ty: tcx.mk_static_str(),
622625
})
623626
},
627+
"needs_drop" => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)),
628+
"size_of" |
629+
"min_align_of" |
630+
"pref_align_of" => {
631+
let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap();
632+
let n = match name {
633+
"pref_align_of" => layout.align.pref.bytes(),
634+
"min_align_of" => layout.align.abi.bytes(),
635+
"size_of" => layout.size.bytes(),
636+
_ => bug!(),
637+
};
638+
ty::Const::from_usize(tcx, n)
639+
},
640+
"type_id" => ty::Const::from_bits(
641+
tcx,
642+
tcx.type_id_hash(tp_ty).into(),
643+
param_env.and(tcx.types.u64),
644+
),
624645
other => bug!("`{}` is not a zero arg intrinsic", other),
625646
}
626647
}

src/librustc_mir/interpret/eval_context.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
1414
use rustc::ty::query::TyCtxtAt;
1515
use rustc_data_structures::indexed_vec::IndexVec;
1616
use rustc::mir::interpret::{
17-
ErrorHandled,
1817
GlobalId, Scalar, Pointer, FrameInfo, AllocId,
1918
InterpResult, InterpError,
2019
truncate, sign_extend,
@@ -652,12 +651,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
652651
// Our result will later be validated anyway, and there seems no good reason
653652
// to have to fail early here. This is also more consistent with
654653
// `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
655-
let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
656-
match err {
657-
ErrorHandled::Reported => InterpError::ReferencedConstant,
658-
ErrorHandled::TooGeneric => InterpError::TooGeneric,
659-
}
660-
})?;
654+
let val = self.tcx.const_eval_raw(param_env.and(gid))?;
661655
self.raw_const_to_mplace(val)
662656
}
663657

src/librustc_mir/interpret/intrinsics.rs

+13-36
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use rustc::ty;
77
use rustc::ty::layout::{LayoutOf, Primitive, Size};
88
use rustc::mir::BinOp;
99
use rustc::mir::interpret::{
10-
InterpResult, InterpError, Scalar,
10+
InterpResult, InterpError, Scalar, GlobalId,
1111
};
1212

1313
use super::{
14-
Machine, PlaceTy, OpTy, InterpretCx, Immediate,
14+
Machine, PlaceTy, OpTy, InterpretCx,
1515
};
1616

1717
mod type_name;
@@ -51,41 +51,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
5151

5252
let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
5353
match intrinsic_name {
54-
"min_align_of" => {
55-
let elem_ty = substs.type_at(0);
56-
let elem_align = self.layout_of(elem_ty)?.align.abi.bytes();
57-
let align_val = Scalar::from_uint(elem_align, dest.layout.size);
58-
self.write_scalar(align_val, dest)?;
59-
}
60-
61-
"needs_drop" => {
62-
let ty = substs.type_at(0);
63-
let ty_needs_drop = ty.needs_drop(self.tcx.tcx, self.param_env);
64-
let val = Scalar::from_bool(ty_needs_drop);
65-
self.write_scalar(val, dest)?;
66-
}
67-
68-
"size_of" => {
69-
let ty = substs.type_at(0);
70-
let size = self.layout_of(ty)?.size.bytes() as u128;
71-
let size_val = Scalar::from_uint(size, dest.layout.size);
72-
self.write_scalar(size_val, dest)?;
73-
}
74-
75-
"type_id" => {
76-
let ty = substs.type_at(0);
77-
let type_id = self.tcx.type_id_hash(ty) as u128;
78-
let id_val = Scalar::from_uint(type_id, dest.layout.size);
79-
self.write_scalar(id_val, dest)?;
80-
}
81-
54+
"min_align_of" |
55+
"needs_drop" |
56+
"size_of" |
57+
"type_id" |
8258
"type_name" => {
83-
let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0));
84-
let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
85-
let id_ptr = self.memory.tag_static_base_pointer(name_id.into());
86-
let alloc_len = alloc.bytes.len() as u64;
87-
let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self);
88-
self.write_immediate(name_val, dest)?;
59+
let gid = GlobalId {
60+
instance,
61+
promoted: None,
62+
};
63+
let val = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid))?;
64+
let val = self.eval_const_to_op(val, None)?;
65+
self.copy_op(val, dest)?;
8966
}
9067

9168
| "ctpop"

src/test/ui/consts/const-size_of-cycle.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
99
|
1010
LL | intrinsics::size_of::<T>()
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
13+
--> $SRC_DIR/libcore/intrinsics.rs:LL:COL
14+
|
15+
LL | pub fn size_of<T>() -> usize;
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
18+
--> $SRC_DIR/libcore/intrinsics.rs:LL:COL
19+
|
20+
LL | pub fn size_of<T>() -> usize;
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1222
= note: ...which requires computing layout of `Foo`...
1323
= note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
1424
note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...

src/test/ui/issues/issue-44415.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
99
|
1010
LL | bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
13+
--> $SRC_DIR/libcore/intrinsics.rs:LL:COL
14+
|
15+
LL | pub fn size_of<T>() -> usize;
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
18+
--> $SRC_DIR/libcore/intrinsics.rs:LL:COL
19+
|
20+
LL | pub fn size_of<T>() -> usize;
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1222
= note: ...which requires computing layout of `Foo`...
1323
= note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
1424
note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...

0 commit comments

Comments
 (0)