Skip to content

Commit d550cc9

Browse files
committed
Port more zero arg intrinsics to the const_eval query
1 parent 30782e6 commit d550cc9

File tree

7 files changed

+72
-68
lines changed

7 files changed

+72
-68
lines changed

src/librustc/mir/interpret/error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,15 @@ fn print_backtrace(backtrace: &mut Backtrace) {
215215
eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
216216
}
217217

218+
impl From<ErrorHandled> for InterpErrorInfo<'tcx> {
219+
fn from(err: ErrorHandled) -> Self {
220+
match err {
221+
ErrorHandled::Reported => err_inval!(ReferencedConstant),
222+
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
223+
}
224+
}
225+
}
226+
218227
impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
219228
fn from(kind: InterpError<'tcx>) -> Self {
220229
let backtrace = match env::var("RUSTC_CTFE_BACKTRACE") {

src/librustc_codegen_llvm/intrinsic.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
135135
let llfn = self.get_intrinsic(&("llvm.debugtrap"));
136136
self.call(llfn, &[], None)
137137
}
138-
"size_of" => {
139-
let tp_ty = substs.type_at(0);
140-
self.const_usize(self.size_of(tp_ty).bytes())
141-
}
142138
"va_start" => {
143139
self.va_start(args[0].immediate())
144140
}
@@ -190,10 +186,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
190186
self.const_usize(self.size_of(tp_ty).bytes())
191187
}
192188
}
193-
"min_align_of" => {
194-
let tp_ty = substs.type_at(0);
195-
self.const_usize(self.align_of(tp_ty).bytes())
196-
}
197189
"min_align_of_val" => {
198190
let tp_ty = substs.type_at(0);
199191
if let OperandValue::Pair(_, meta) = args[0].val {
@@ -203,10 +195,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
203195
self.const_usize(self.align_of(tp_ty).bytes())
204196
}
205197
}
206-
"pref_align_of" => {
207-
let tp_ty = substs.type_at(0);
208-
self.const_usize(self.layout_of(tp_ty).align.pref.bytes())
209-
}
198+
"size_of" |
199+
"pref_align_of" |
200+
"min_align_of" |
201+
"needs_drop" |
202+
"type_id" |
210203
"type_name" => {
211204
let gid = GlobalId {
212205
instance,
@@ -215,9 +208,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
215208
let ty_name = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).unwrap();
216209
OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self)
217210
}
218-
"type_id" => {
219-
self.const_u64(self.tcx.type_id_hash(substs.type_at(0)))
220-
}
221211
"init" => {
222212
let ty = substs.type_at(0);
223213
if !self.layout_of(ty).is_zst() {
@@ -240,11 +230,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
240230
"uninit" | "forget" => {
241231
return;
242232
}
243-
"needs_drop" => {
244-
let tp_ty = substs.type_at(0);
245-
246-
self.const_bool(self.type_needs_drop(tp_ty))
247-
}
248233
"offset" => {
249234
let ptr = args[0].immediate();
250235
let offset = args[1].immediate();

src/librustc_mir/const_eval.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ pub fn const_eval_provider<'tcx>(
613613
ty::FnDef(_, substs) => substs,
614614
_ => bug!("intrinsic with type {:?}", ty),
615615
};
616-
return Ok(eval_intrinsic(tcx, def_id, substs));
616+
return Ok(eval_intrinsic(tcx, key.param_env, def_id, substs));
617617
}
618618

619619
tcx.const_eval_raw(key).and_then(|val| {
@@ -623,12 +623,15 @@ pub fn const_eval_provider<'tcx>(
623623

624624
fn eval_intrinsic<'tcx>(
625625
tcx: TyCtxt<'tcx>,
626+
param_env: ty::ParamEnv<'tcx>,
626627
def_id: DefId,
627628
substs: SubstsRef<'tcx>,
628629
) -> &'tcx ty::Const<'tcx> {
629-
match &*tcx.item_name(def_id).as_str() {
630+
let tp_ty = substs.type_at(0);
631+
let name = &*tcx.item_name(def_id).as_str();
632+
match name {
630633
"type_name" => {
631-
let alloc = alloc_type_name(tcx, substs.type_at(0));
634+
let alloc = alloc_type_name(tcx, tp_ty);
632635
tcx.mk_const(ty::Const {
633636
val: ConstValue::Slice {
634637
data: alloc,
@@ -638,6 +641,24 @@ fn eval_intrinsic<'tcx>(
638641
ty: tcx.mk_static_str(),
639642
})
640643
},
644+
"needs_drop" => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)),
645+
"size_of" |
646+
"min_align_of" |
647+
"pref_align_of" => {
648+
let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap();
649+
let n = match name {
650+
"pref_align_of" => layout.align.pref.bytes(),
651+
"min_align_of" => layout.align.abi.bytes(),
652+
"size_of" => layout.size.bytes(),
653+
_ => bug!(),
654+
};
655+
ty::Const::from_usize(tcx, n)
656+
},
657+
"type_id" => ty::Const::from_bits(
658+
tcx,
659+
tcx.type_id_hash(tp_ty).into(),
660+
param_env.and(tcx.types.u64),
661+
),
641662
other => bug!("`{}` is not a zero arg intrinsic", other),
642663
}
643664
}

src/librustc_mir/interpret/eval_context.rs

Lines changed: 1 addition & 9 deletions
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, truncate, sign_extend,
2019
};
@@ -669,14 +668,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
669668
// Our result will later be validated anyway, and there seems no good reason
670669
// to have to fail early here. This is also more consistent with
671670
// `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
672-
let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
673-
match err {
674-
ErrorHandled::Reported =>
675-
err_inval!(ReferencedConstant),
676-
ErrorHandled::TooGeneric =>
677-
err_inval!(TooGeneric),
678-
}
679-
})?;
671+
let val = self.tcx.const_eval_raw(param_env.and(gid))?;
680672
self.raw_const_to_mplace(val)
681673
}
682674

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use syntax::symbol::Symbol;
66
use rustc::ty;
77
use rustc::ty::layout::{LayoutOf, Primitive, Size};
88
use rustc::mir::BinOp;
9-
use rustc::mir::interpret::{InterpResult, Scalar};
9+
use rustc::mir::interpret::{InterpResult, Scalar, GlobalId};
1010

1111
use super::{
12-
Machine, PlaceTy, OpTy, InterpCx, Immediate,
12+
Machine, PlaceTy, OpTy, InterpCx,
1313
};
1414

1515
mod type_name;
@@ -49,41 +49,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
4949

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

8966
| "ctpop"

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
1414
|
1515
LL | intrinsics::size_of::<T>()
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
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+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
23+
--> $SRC_DIR/libcore/intrinsics.rs:LL:COL
24+
|
25+
LL | pub fn size_of<T>() -> usize;
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1727
= note: ...which requires computing layout of `Foo`...
1828
= note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
1929
= note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
1414
|
1515
LL | bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
23+
--> $SRC_DIR/libcore/intrinsics.rs:LL:COL
24+
|
25+
LL | pub fn size_of<T>() -> usize;
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1727
= note: ...which requires computing layout of `Foo`...
1828
= note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
1929
= note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle

0 commit comments

Comments
 (0)