From e0f73052a93eee54400b7d4f788181b28bb54b4d Mon Sep 17 00:00:00 2001 From: GrayJack Date: Sun, 18 Aug 2019 07:13:33 -0300 Subject: [PATCH 01/14] Constify LinkedList new function --- src/liballoc/collections/linked_list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index a14a3fe9994ab..816a71f255798 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -276,7 +276,7 @@ impl LinkedList { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> Self { + pub const fn new() -> Self { LinkedList { head: None, tail: None, From fdd8b967c180192fb74bf17f07e2fda040bb9865 Mon Sep 17 00:00:00 2001 From: Sam Radhakrishan Date: Thu, 29 Aug 2019 02:43:09 +0530 Subject: [PATCH 02/14] Fixes #63976. Incorrect error message. Fix incorrect error message when accessing private field of union --- src/librustc_typeck/check/expr.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index d139cd4264c86..4943270e193ec 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1396,8 +1396,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx().sess, expr.span, E0616, - "field `{}` of struct `{}` is private", + "field `{}` of `{}` `{}` is private", field, + if let Some(def_kind) = self.tcx().def_kind(base_did){ def_kind.descr(base_did) } + else { " " }, struct_path ); // Also check if an accessible method exists, which is often what is meant. From 378c32bc90b230d1f8feffee135942d442d2a5b7 Mon Sep 17 00:00:00 2001 From: Sam Radhakrishan Date: Fri, 30 Aug 2019 00:57:20 +0530 Subject: [PATCH 03/14] Fix test. --- src/librustc_typeck/check/expr.rs | 9 ++++++--- src/test/ui/privacy/union-field-privacy-2.rs | 2 +- src/test/ui/privacy/union-field-privacy-2.stderr | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 4943270e193ec..a53fb12367d0e 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1392,14 +1392,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_did: DefId, ) { let struct_path = self.tcx().def_path_str(base_did); + let kind_name = match self.tcx().def_kind(base_did) { + Some(def_kind) => def_kind.descr(base_did), + _ => " ", + }; let mut err = struct_span_err!( self.tcx().sess, expr.span, E0616, - "field `{}` of `{}` `{}` is private", + "field `{}` of {} `{}` is private", field, - if let Some(def_kind) = self.tcx().def_kind(base_did){ def_kind.descr(base_did) } - else { " " }, + kind_name, struct_path ); // Also check if an accessible method exists, which is often what is meant. diff --git a/src/test/ui/privacy/union-field-privacy-2.rs b/src/test/ui/privacy/union-field-privacy-2.rs index 48279630c6302..c2458f74bc8f9 100644 --- a/src/test/ui/privacy/union-field-privacy-2.rs +++ b/src/test/ui/privacy/union-field-privacy-2.rs @@ -11,5 +11,5 @@ fn main() { let a = u.a; // OK let b = u.b; // OK - let c = u.c; //~ ERROR field `c` of struct `m::U` is private + let c = u.c; //~ ERROR field `c` of union `m::U` is private } diff --git a/src/test/ui/privacy/union-field-privacy-2.stderr b/src/test/ui/privacy/union-field-privacy-2.stderr index df054b8cff8a6..8789178caac26 100644 --- a/src/test/ui/privacy/union-field-privacy-2.stderr +++ b/src/test/ui/privacy/union-field-privacy-2.stderr @@ -1,4 +1,4 @@ -error[E0616]: field `c` of struct `m::U` is private +error[E0616]: field `c` of union `m::U` is private --> $DIR/union-field-privacy-2.rs:14:13 | LL | let c = u.c; From c6e7f039aabe3338c400d197a689c94bde425ba6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 15 Aug 2019 18:20:35 +0200 Subject: [PATCH 04/14] Merge oli-obk mail addresses --- .mailmap | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.mailmap b/.mailmap index c5ecfb54fca52..91b2e762d8e40 100644 --- a/.mailmap +++ b/.mailmap @@ -181,12 +181,19 @@ Neil Pankey Nick Platt Nicole Mazzuca Nif Ward -Oliver Schneider oli-obk -Oliver Schneider Oliver 'ker' Schneider -Oliver Schneider Oliver Schneider -Oliver Schneider Oliver Schneider -Oliver Schneider Oliver Schneider -Oliver Schneider Oliver Schneider +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer +Oliver Scherer Ožbolt Menegatti gareins Paul Faria Paul Faria Peer Aramillo Irizar parir From 30782e6d14518d25112eadf149aac96796afa409 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 7 Jun 2019 19:22:42 +0200 Subject: [PATCH 05/14] Get rid of special const intrinsic query in favour of `const_eval` --- src/librustc/query/mod.rs | 9 ----- src/librustc_codegen_llvm/intrinsic.rs | 11 +++++-- src/librustc_codegen_ssa/mir/block.rs | 3 +- src/librustc_codegen_ssa/traits/intrinsic.rs | 4 +-- src/librustc_mir/const_eval.rs | 33 +++++++++++++++++++ src/librustc_mir/interpret/intrinsics.rs | 2 +- .../interpret/intrinsics/type_name.rs | 21 +++--------- src/librustc_mir/interpret/mod.rs | 4 +-- src/librustc_mir/lib.rs | 1 - 9 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index c4f7ca51f4a7a..af9d857e54283 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -463,15 +463,6 @@ rustc_queries! { no_force desc { "extract field of const" } } - - /// Produces an absolute path representation of the given type. See also the documentation - /// on `std::any::type_name`. - query type_name(key: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { - eval_always - no_force - desc { "get absolute path of type" } - } - } TypeChecking { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 9483ffca448e3..73ce0aadfeba1 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -15,6 +15,7 @@ use rustc_codegen_ssa::glue; use rustc_codegen_ssa::base::{to_immediate, wants_msvc_seh, compare_simd_types}; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive}; +use rustc::mir::interpret::GlobalId; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc::hir; use syntax::ast::{self, FloatTy}; @@ -81,13 +82,14 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn codegen_intrinsic_call( &mut self, - callee_ty: Ty<'tcx>, + instance: ty::Instance<'tcx>, fn_ty: &FnType<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, &'ll Value>], llresult: &'ll Value, span: Span, ) { let tcx = self.tcx; + let callee_ty = instance.ty(tcx); let (def_id, substs) = match callee_ty.sty { ty::FnDef(def_id, substs) => (def_id, substs), @@ -206,8 +208,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.const_usize(self.layout_of(tp_ty).align.pref.bytes()) } "type_name" => { - let tp_ty = substs.type_at(0); - let ty_name = self.tcx.type_name(tp_ty); + let gid = GlobalId { + instance, + promoted: None, + }; + let ty_name = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).unwrap(); OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self) } "type_id" => { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d2a7571fde1e2..578c852fa1870 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -668,8 +668,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }).collect(); - let callee_ty = instance.as_ref().unwrap().ty(bx.tcx()); - bx.codegen_intrinsic_call(callee_ty, &fn_ty, &args, dest, + bx.codegen_intrinsic_call(*instance.as_ref().unwrap(), &fn_ty, &args, dest, terminator.source_info.span); if let ReturnDest::IndirectOperand(dst, _) = ret_dest { diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs index ede30a0bed756..7c79cd6021031 100644 --- a/src/librustc_codegen_ssa/traits/intrinsic.rs +++ b/src/librustc_codegen_ssa/traits/intrinsic.rs @@ -1,6 +1,6 @@ use super::BackendTypes; use crate::mir::operand::OperandRef; -use rustc::ty::Ty; +use rustc::ty::{self, Ty}; use rustc_target::abi::call::FnType; use syntax_pos::Span; @@ -10,7 +10,7 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes { /// add them to librustc_codegen_llvm/context.rs fn codegen_intrinsic_call( &mut self, - callee_ty: Ty<'tcx>, + instance: ty::Instance<'tcx>, fn_ty: &FnType<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, Self::Value>], llresult: Self::Value, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 5aa487d901663..59ed430174deb 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -13,8 +13,10 @@ use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef}; use rustc::mir; use rustc::ty::{self, Ty, TyCtxt, subst::Subst}; use rustc::ty::layout::{self, LayoutOf, VariantIdx}; +use rustc::ty::subst::{Subst, SubstsRef}; use rustc::traits::Reveal; use rustc_data_structures::fx::FxHashMap; +use crate::interpret::alloc_type_name; use syntax::source_map::{Span, DUMMY_SP}; @@ -604,11 +606,42 @@ pub fn const_eval_provider<'tcx>( other => return other, } } + + if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def { + let ty = key.value.instance.ty(tcx); + let substs = match ty.sty { + ty::FnDef(_, substs) => substs, + _ => bug!("intrinsic with type {:?}", ty), + }; + return Ok(eval_intrinsic(tcx, def_id, substs)); + } + tcx.const_eval_raw(key).and_then(|val| { validate_and_turn_into_const(tcx, val, key) }) } +fn eval_intrinsic<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + substs: SubstsRef<'tcx>, +) -> &'tcx ty::Const<'tcx> { + match &*tcx.item_name(def_id).as_str() { + "type_name" => { + let alloc = alloc_type_name(tcx, substs.type_at(0)); + tcx.mk_const(ty::Const { + val: ConstValue::Slice { + data: alloc, + start: 0, + end: alloc.bytes.len(), + }, + ty: tcx.mk_static_str(), + }) + }, + other => bug!("`{}` is not a zero arg intrinsic", other), + } +} + pub fn const_eval_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 334f1ea1a6901..e94795c032269 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -14,7 +14,7 @@ use super::{ mod type_name; -pub use type_name::*; +pub(crate) use type_name::alloc_type_name; fn numeric_intrinsic<'tcx, Tag>( name: &str, diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index f207cfc6b39cd..b9e81266d2dc0 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -7,7 +7,7 @@ use rustc::ty::{ use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; use rustc::hir::def_id::CrateNum; use std::fmt::Write; -use rustc::mir::interpret::{Allocation, ConstValue}; +use rustc::mir::interpret::Allocation; struct AbsolutePathPrinter<'tcx> { tcx: TyCtxt<'tcx>, @@ -213,22 +213,11 @@ impl Write for AbsolutePathPrinter<'_> { } } -/// Produces an absolute path representation of the given type. See also the documentation on -/// `std::any::type_name` -pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { - let alloc = alloc_type_name(tcx, ty); - tcx.mk_const(ty::Const { - val: ConstValue::Slice { - data: alloc, - start: 0, - end: alloc.bytes.len(), - }, - ty: tcx.mk_static_str(), - }) -} - /// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(super) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { +pub(crate) fn alloc_type_name<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx> +) -> &'tcx Allocation { let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); tcx.intern_const_alloc(alloc) diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 45d24347e4efd..3dd9689ad6c72 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -34,6 +34,6 @@ pub use self::visitor::{ValueVisitor, MutValueVisitor}; pub use self::validity::RefTracking; -pub(super) use self::intrinsics::type_name; - pub use self::intern::intern_const_alloc_recursive; + +pub(crate) use self::intrinsics::alloc_type_name; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index cccf7b9545bdb..d3fa90a35d071 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -60,7 +60,6 @@ pub fn provide(providers: &mut Providers<'_>) { let (param_env, (value, field)) = param_env_and_value.into_parts(); const_eval::const_field(tcx, param_env, None, field, value) }; - providers.type_name = interpret::type_name; } __build_diagnostic_array! { librustc_mir, DIAGNOSTICS } From d550cc99af532481b6a0fa417bac3b8f8ad93530 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 19:41:44 +0200 Subject: [PATCH 06/14] Port more zero arg intrinsics to the `const_eval` query --- src/librustc/mir/interpret/error.rs | 9 ++++ src/librustc_codegen_llvm/intrinsic.rs | 25 ++-------- src/librustc_mir/const_eval.rs | 27 ++++++++-- src/librustc_mir/interpret/eval_context.rs | 10 +--- src/librustc_mir/interpret/intrinsics.rs | 49 +++++-------------- src/test/ui/consts/const-size_of-cycle.stderr | 10 ++++ src/test/ui/issues/issue-44415.stderr | 10 ++++ 7 files changed, 72 insertions(+), 68 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index ef0e205184871..6c0846c86528b 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -215,6 +215,15 @@ fn print_backtrace(backtrace: &mut Backtrace) { eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace); } +impl From for InterpErrorInfo<'tcx> { + fn from(err: ErrorHandled) -> Self { + match err { + ErrorHandled::Reported => err_inval!(ReferencedConstant), + ErrorHandled::TooGeneric => err_inval!(TooGeneric), + } + } +} + impl<'tcx> From> for InterpErrorInfo<'tcx> { fn from(kind: InterpError<'tcx>) -> Self { let backtrace = match env::var("RUSTC_CTFE_BACKTRACE") { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 73ce0aadfeba1..5dcc8dd9bffd2 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -135,10 +135,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let llfn = self.get_intrinsic(&("llvm.debugtrap")); self.call(llfn, &[], None) } - "size_of" => { - let tp_ty = substs.type_at(0); - self.const_usize(self.size_of(tp_ty).bytes()) - } "va_start" => { self.va_start(args[0].immediate()) } @@ -190,10 +186,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.const_usize(self.size_of(tp_ty).bytes()) } } - "min_align_of" => { - let tp_ty = substs.type_at(0); - self.const_usize(self.align_of(tp_ty).bytes()) - } "min_align_of_val" => { let tp_ty = substs.type_at(0); if let OperandValue::Pair(_, meta) = args[0].val { @@ -203,10 +195,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.const_usize(self.align_of(tp_ty).bytes()) } } - "pref_align_of" => { - let tp_ty = substs.type_at(0); - self.const_usize(self.layout_of(tp_ty).align.pref.bytes()) - } + "size_of" | + "pref_align_of" | + "min_align_of" | + "needs_drop" | + "type_id" | "type_name" => { let gid = GlobalId { instance, @@ -215,9 +208,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let ty_name = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).unwrap(); OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self) } - "type_id" => { - self.const_u64(self.tcx.type_id_hash(substs.type_at(0))) - } "init" => { let ty = substs.type_at(0); if !self.layout_of(ty).is_zst() { @@ -240,11 +230,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { "uninit" | "forget" => { return; } - "needs_drop" => { - let tp_ty = substs.type_at(0); - - self.const_bool(self.type_needs_drop(tp_ty)) - } "offset" => { let ptr = args[0].immediate(); let offset = args[1].immediate(); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 59ed430174deb..04d13d6446583 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -613,7 +613,7 @@ pub fn const_eval_provider<'tcx>( ty::FnDef(_, substs) => substs, _ => bug!("intrinsic with type {:?}", ty), }; - return Ok(eval_intrinsic(tcx, def_id, substs)); + return Ok(eval_intrinsic(tcx, key.param_env, def_id, substs)); } tcx.const_eval_raw(key).and_then(|val| { @@ -623,12 +623,15 @@ pub fn const_eval_provider<'tcx>( fn eval_intrinsic<'tcx>( tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, ) -> &'tcx ty::Const<'tcx> { - match &*tcx.item_name(def_id).as_str() { + let tp_ty = substs.type_at(0); + let name = &*tcx.item_name(def_id).as_str(); + match name { "type_name" => { - let alloc = alloc_type_name(tcx, substs.type_at(0)); + let alloc = alloc_type_name(tcx, tp_ty); tcx.mk_const(ty::Const { val: ConstValue::Slice { data: alloc, @@ -638,6 +641,24 @@ fn eval_intrinsic<'tcx>( ty: tcx.mk_static_str(), }) }, + "needs_drop" => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)), + "size_of" | + "min_align_of" | + "pref_align_of" => { + let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap(); + let n = match name { + "pref_align_of" => layout.align.pref.bytes(), + "min_align_of" => layout.align.abi.bytes(), + "size_of" => layout.size.bytes(), + _ => bug!(), + }; + ty::Const::from_usize(tcx, n) + }, + "type_id" => ty::Const::from_bits( + tcx, + tcx.type_id_hash(tp_ty).into(), + param_env.and(tcx.types.u64), + ), other => bug!("`{}` is not a zero arg intrinsic", other), } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ac01d436bdc9b..44245f899c324 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -14,7 +14,6 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::query::TyCtxtAt; use rustc_data_structures::indexed_vec::IndexVec; use rustc::mir::interpret::{ - ErrorHandled, GlobalId, Scalar, Pointer, FrameInfo, AllocId, InterpResult, truncate, sign_extend, }; @@ -669,14 +668,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // 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. - let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { - match err { - ErrorHandled::Reported => - err_inval!(ReferencedConstant), - ErrorHandled::TooGeneric => - err_inval!(TooGeneric), - } - })?; + let val = self.tcx.const_eval_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index e94795c032269..cc568ef9433c8 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -6,10 +6,10 @@ use syntax::symbol::Symbol; use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; -use rustc::mir::interpret::{InterpResult, Scalar}; +use rustc::mir::interpret::{InterpResult, Scalar, GlobalId}; use super::{ - Machine, PlaceTy, OpTy, InterpCx, Immediate, + Machine, PlaceTy, OpTy, InterpCx, }; mod type_name; @@ -49,41 +49,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..]; match intrinsic_name { - "min_align_of" => { - let elem_ty = substs.type_at(0); - let elem_align = self.layout_of(elem_ty)?.align.abi.bytes(); - let align_val = Scalar::from_uint(elem_align, dest.layout.size); - self.write_scalar(align_val, dest)?; - } - - "needs_drop" => { - let ty = substs.type_at(0); - let ty_needs_drop = ty.needs_drop(self.tcx.tcx, self.param_env); - let val = Scalar::from_bool(ty_needs_drop); - self.write_scalar(val, dest)?; - } - - "size_of" => { - let ty = substs.type_at(0); - let size = self.layout_of(ty)?.size.bytes() as u128; - let size_val = Scalar::from_uint(size, dest.layout.size); - self.write_scalar(size_val, dest)?; - } - - "type_id" => { - let ty = substs.type_at(0); - let type_id = self.tcx.type_id_hash(ty) as u128; - let id_val = Scalar::from_uint(type_id, dest.layout.size); - self.write_scalar(id_val, dest)?; - } - + "min_align_of" | + "needs_drop" | + "size_of" | + "type_id" | "type_name" => { - let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0)); - let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); - let id_ptr = self.memory.tag_static_base_pointer(name_id.into()); - let alloc_len = alloc.bytes.len() as u64; - let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self); - self.write_immediate(name_val, dest)?; + let gid = GlobalId { + instance, + promoted: None, + }; + let val = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid))?; + let val = self.eval_const_to_op(val, None)?; + self.copy_op(val, dest)?; } | "ctpop" diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index fdba359e7464a..cf3f5955a648b 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -14,6 +14,16 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... | LL | intrinsics::size_of::() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... + --> $SRC_DIR/libcore/intrinsics.rs:LL:COL + | +LL | pub fn size_of() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... + --> $SRC_DIR/libcore/intrinsics.rs:LL:COL + | +LL | pub fn size_of() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr index 8008e53f65f4d..90fc34db4a7a9 100644 --- a/src/test/ui/issues/issue-44415.stderr +++ b/src/test/ui/issues/issue-44415.stderr @@ -14,6 +14,16 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... + --> $SRC_DIR/libcore/intrinsics.rs:LL:COL + | +LL | pub fn size_of() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... + --> $SRC_DIR/libcore/intrinsics.rs:LL:COL + | +LL | pub fn size_of() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle From 9310a6479816130c14f4b4e989652605c3948472 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 21 Jun 2019 09:34:09 +0200 Subject: [PATCH 07/14] Rename `eval_intrinsic` to `eval_nulary_intrinsic` --- src/librustc_mir/const_eval.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 04d13d6446583..02653a83c8516 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -613,7 +613,7 @@ pub fn const_eval_provider<'tcx>( ty::FnDef(_, substs) => substs, _ => bug!("intrinsic with type {:?}", ty), }; - return Ok(eval_intrinsic(tcx, key.param_env, def_id, substs)); + return Ok(eval_nulary_intrinsic(tcx, key.param_env, def_id, substs)); } tcx.const_eval_raw(key).and_then(|val| { @@ -621,7 +621,7 @@ pub fn const_eval_provider<'tcx>( }) } -fn eval_intrinsic<'tcx>( +fn eval_nulary_intrinsic<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, From 6f055c8ac5de902bc42f0cc7e72533ac3b2c5fb2 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 18 Jul 2019 16:19:43 +0200 Subject: [PATCH 08/14] Move nulary intrinsic logic to the other intrinsic logic --- src/librustc_mir/const_eval.rs | 46 +--------------------- src/librustc_mir/interpret/intrinsics.rs | 50 ++++++++++++++++++++++-- src/librustc_mir/interpret/mod.rs | 2 +- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 02653a83c8516..de83d7367ea5d 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -13,10 +13,10 @@ use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef}; use rustc::mir; use rustc::ty::{self, Ty, TyCtxt, subst::Subst}; use rustc::ty::layout::{self, LayoutOf, VariantIdx}; -use rustc::ty::subst::{Subst, SubstsRef}; +use rustc::ty::subst::Subst; use rustc::traits::Reveal; use rustc_data_structures::fx::FxHashMap; -use crate::interpret::alloc_type_name; +use crate::interpret::eval_nulary_intrinsic; use syntax::source_map::{Span, DUMMY_SP}; @@ -621,48 +621,6 @@ pub fn const_eval_provider<'tcx>( }) } -fn eval_nulary_intrinsic<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - def_id: DefId, - substs: SubstsRef<'tcx>, -) -> &'tcx ty::Const<'tcx> { - let tp_ty = substs.type_at(0); - let name = &*tcx.item_name(def_id).as_str(); - match name { - "type_name" => { - let alloc = alloc_type_name(tcx, tp_ty); - tcx.mk_const(ty::Const { - val: ConstValue::Slice { - data: alloc, - start: 0, - end: alloc.bytes.len(), - }, - ty: tcx.mk_static_str(), - }) - }, - "needs_drop" => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)), - "size_of" | - "min_align_of" | - "pref_align_of" => { - let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap(); - let n = match name { - "pref_align_of" => layout.align.pref.bytes(), - "min_align_of" => layout.align.abi.bytes(), - "size_of" => layout.size.bytes(), - _ => bug!(), - }; - ty::Const::from_usize(tcx, n) - }, - "type_id" => ty::Const::from_bits( - tcx, - tcx.type_id_hash(tp_ty).into(), - param_env.and(tcx.types.u64), - ), - other => bug!("`{}` is not a zero arg intrinsic", other), - } -} - pub fn const_eval_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index cc568ef9433c8..f9edc703f2079 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -5,8 +5,11 @@ use syntax::symbol::Symbol; use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; +use rustc::ty::subst::SubstsRef; +use rustc::hir::def_id::DefId; +use rustc::ty::TyCtxt; use rustc::mir::BinOp; -use rustc::mir::interpret::{InterpResult, Scalar, GlobalId}; +use rustc::mir::interpret::{InterpResult, Scalar, GlobalId, ConstValue}; use super::{ Machine, PlaceTy, OpTy, InterpCx, @@ -14,8 +17,6 @@ use super::{ mod type_name; -pub(crate) use type_name::alloc_type_name; - fn numeric_intrinsic<'tcx, Tag>( name: &str, bits: u128, @@ -37,6 +38,49 @@ fn numeric_intrinsic<'tcx, Tag>( Ok(Scalar::from_uint(bits_out, size)) } + +crate fn eval_nulary_intrinsic<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + def_id: DefId, + substs: SubstsRef<'tcx>, +) -> &'tcx ty::Const<'tcx> { + let tp_ty = substs.type_at(0); + let name = &*tcx.item_name(def_id).as_str(); + match name { + "type_name" => { + let alloc = type_name::alloc_type_name(tcx, tp_ty); + tcx.mk_const(ty::Const { + val: ConstValue::Slice { + data: alloc, + start: 0, + end: alloc.bytes.len(), + }, + ty: tcx.mk_static_str(), + }) + }, + "needs_drop" => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)), + "size_of" | + "min_align_of" | + "pref_align_of" => { + let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap(); + let n = match name { + "pref_align_of" => layout.align.pref.bytes(), + "min_align_of" => layout.align.abi.bytes(), + "size_of" => layout.size.bytes(), + _ => bug!(), + }; + ty::Const::from_usize(tcx, n) + }, + "type_id" => ty::Const::from_bits( + tcx, + tcx.type_id_hash(tp_ty).into(), + param_env.and(tcx.types.u64), + ), + other => bug!("`{}` is not a zero arg intrinsic", other), + } +} + impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Returns `true` if emulation happened. pub fn emulate_intrinsic( diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 3dd9689ad6c72..f4bed928c8d0a 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -36,4 +36,4 @@ pub use self::validity::RefTracking; pub use self::intern::intern_const_alloc_recursive; -pub(crate) use self::intrinsics::alloc_type_name; +pub(crate) use self::intrinsics::eval_nulary_intrinsic; From e8e8c1c076649d137c0ec99aef6cecaa61fb94c0 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 9 Aug 2019 16:05:39 +0200 Subject: [PATCH 09/14] Fixup interp error conversion --- src/librustc/mir/interpret/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 6c0846c86528b..71e6e74a9b5bd 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -220,7 +220,7 @@ impl From for InterpErrorInfo<'tcx> { match err { ErrorHandled::Reported => err_inval!(ReferencedConstant), ErrorHandled::TooGeneric => err_inval!(TooGeneric), - } + }.into() } } From 690c7992f5a554bb93ac9b86c38aa5982d30895d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 11 Aug 2019 17:37:27 +0200 Subject: [PATCH 10/14] Add more documentation --- src/librustc_mir/const_eval.rs | 6 ++++-- src/librustc_mir/interpret/intrinsics.rs | 5 +++-- src/librustc_mir/interpret/intrinsics/type_name.rs | 2 +- src/librustc_mir/interpret/mod.rs | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index de83d7367ea5d..e4b52cfcc3eb5 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -16,7 +16,7 @@ use rustc::ty::layout::{self, LayoutOf, VariantIdx}; use rustc::ty::subst::Subst; use rustc::traits::Reveal; use rustc_data_structures::fx::FxHashMap; -use crate::interpret::eval_nulary_intrinsic; +use crate::interpret::eval_nullary_intrinsic; use syntax::source_map::{Span, DUMMY_SP}; @@ -607,13 +607,15 @@ pub fn const_eval_provider<'tcx>( } } + // We call `const_eval` for zero arg intrinsics, too, in order to cache their value. + // Catch such calls and evaluate them instead of trying to load a constant's MIR. if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def { let ty = key.value.instance.ty(tcx); let substs = match ty.sty { ty::FnDef(_, substs) => substs, _ => bug!("intrinsic with type {:?}", ty), }; - return Ok(eval_nulary_intrinsic(tcx, key.param_env, def_id, substs)); + return Ok(eval_nullary_intrinsic(tcx, key.param_env, def_id, substs)); } tcx.const_eval_raw(key).and_then(|val| { diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index f9edc703f2079..9645e0ca68997 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -38,8 +38,9 @@ fn numeric_intrinsic<'tcx, Tag>( Ok(Scalar::from_uint(bits_out, size)) } - -crate fn eval_nulary_intrinsic<'tcx>( +/// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated +/// inside an `InterpCx` and instead have their value computed directly from rustc internal info. +crate fn eval_nullary_intrinsic<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index b9e81266d2dc0..1e765a4ed982c 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -214,7 +214,7 @@ impl Write for AbsolutePathPrinter<'_> { } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(crate) fn alloc_type_name<'tcx>( +crate fn alloc_type_name<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx> ) -> &'tcx Allocation { diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index f4bed928c8d0a..0c61be283dfd0 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -36,4 +36,4 @@ pub use self::validity::RefTracking; pub use self::intern::intern_const_alloc_recursive; -pub(crate) use self::intrinsics::eval_nulary_intrinsic; +crate use self::intrinsics::eval_nullary_intrinsic; From 52f2f8a3f14f834ee72a63f1da77a18b36e291ae Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 11 Aug 2019 17:37:42 +0200 Subject: [PATCH 11/14] Also link "pref_align_of" --- src/librustc_mir/interpret/intrinsics.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 9645e0ca68997..0ef97219adfeb 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -95,6 +95,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..]; match intrinsic_name { "min_align_of" | + "pref_align_of" | "needs_drop" | "size_of" | "type_id" | From 343d36bfd7ef453d3421fc63d9a70a43a2ebee81 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 17 Aug 2019 15:26:04 +0200 Subject: [PATCH 12/14] Don't panic on layout errors --- src/librustc_mir/const_eval.rs | 111 ++++++++++++----------- src/librustc_mir/interpret/intrinsics.rs | 8 +- 2 files changed, 62 insertions(+), 57 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index e4b52cfcc3eb5..d96aff678b3d3 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -615,7 +615,12 @@ pub fn const_eval_provider<'tcx>( ty::FnDef(_, substs) => substs, _ => bug!("intrinsic with type {:?}", ty), }; - return Ok(eval_nullary_intrinsic(tcx, key.param_env, def_id, substs)); + return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs) + .map_err(|error| { + let span = tcx.def_span(def_id); + let error = ConstEvalErr { error: error.kind, stacktrace: vec![], span }; + error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic") + }) } tcx.const_eval_raw(key).and_then(|val| { @@ -680,63 +685,63 @@ pub fn const_eval_raw_provider<'tcx>( }) }).map_err(|error| { let err = error_to_const_error(&ecx, error); - // errors in statics are always emitted as fatal errors - if tcx.is_static(def_id) { - // Ensure that if the above error was either `TooGeneric` or `Reported` - // an error must be reported. + // errors in statics are always emitted as fatal errors + if tcx.is_static(def_id) { + // Ensure that if the above error was either `TooGeneric` or `Reported` + // an error must be reported. let v = err.report_as_error(ecx.tcx, "could not evaluate static initializer"); - tcx.sess.delay_span_bug( - err.span, - &format!("static eval failure did not emit an error: {:#?}", v) - ); - v - } else if def_id.is_local() { - // constant defined in this crate, we can figure out a lint level! - match tcx.def_kind(def_id) { - // constants never produce a hard error at the definition site. Anything else is - // a backwards compatibility hazard (and will break old versions of winapi for sure) - // - // note that validation may still cause a hard error on this very same constant, - // because any code that existed before validation could not have failed validation - // thus preventing such a hard error from being a backwards compatibility hazard - Some(DefKind::Const) | Some(DefKind::AssocConst) => { - let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + tcx.sess.delay_span_bug( + err.span, + &format!("static eval failure did not emit an error: {:#?}", v) + ); + v + } else if def_id.is_local() { + // constant defined in this crate, we can figure out a lint level! + match tcx.def_kind(def_id) { + // constants never produce a hard error at the definition site. Anything else is + // a backwards compatibility hazard (and will break old versions of winapi for sure) + // + // note that validation may still cause a hard error on this very same constant, + // because any code that existed before validation could not have failed validation + // thus preventing such a hard error from being a backwards compatibility hazard + Some(DefKind::Const) | Some(DefKind::AssocConst) => { + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + err.report_as_lint( + tcx.at(tcx.def_span(def_id)), + "any use of this value will cause an error", + hir_id, + Some(err.span), + ) + }, + // promoting runtime code is only allowed to error if it references broken constants + // any other kind of error will be reported to the user as a deny-by-default lint + _ => if let Some(p) = cid.promoted { + let span = tcx.promoted_mir(def_id)[p].span; + if let err_inval!(ReferencedConstant) = err.error { + err.report_as_error( + tcx.at(span), + "evaluation of constant expression failed", + ) + } else { err.report_as_lint( - tcx.at(tcx.def_span(def_id)), - "any use of this value will cause an error", - hir_id, + tcx.at(span), + "reaching this expression at runtime will panic or abort", + tcx.hir().as_local_hir_id(def_id).unwrap(), Some(err.span), ) - }, - // promoting runtime code is only allowed to error if it references broken constants - // any other kind of error will be reported to the user as a deny-by-default lint - _ => if let Some(p) = cid.promoted { - let span = tcx.promoted_mir(def_id)[p].span; - if let err_inval!(ReferencedConstant) = err.error { - err.report_as_error( - tcx.at(span), - "evaluation of constant expression failed", - ) - } else { - err.report_as_lint( - tcx.at(span), - "reaching this expression at runtime will panic or abort", - tcx.hir().as_local_hir_id(def_id).unwrap(), - Some(err.span), - ) - } - // anything else (array lengths, enum initializers, constant patterns) are reported - // as hard errors - } else { - err.report_as_error( + } + // anything else (array lengths, enum initializers, constant patterns) are reported + // as hard errors + } else { + err.report_as_error( ecx.tcx, - "evaluation of constant value failed", - ) - }, - } - } else { - // use of broken constant from other crate - err.report_as_error(ecx.tcx, "could not evaluate constant") + "evaluation of constant value failed", + ) + }, } + } else { + // use of broken constant from other crate + err.report_as_error(ecx.tcx, "could not evaluate constant") + } }) } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 0ef97219adfeb..7b39895e39878 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -45,10 +45,10 @@ crate fn eval_nullary_intrinsic<'tcx>( param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, -) -> &'tcx ty::Const<'tcx> { +) -> InterpResult<'tcx, &'tcx ty::Const<'tcx>> { let tp_ty = substs.type_at(0); let name = &*tcx.item_name(def_id).as_str(); - match name { + Ok(match name { "type_name" => { let alloc = type_name::alloc_type_name(tcx, tp_ty); tcx.mk_const(ty::Const { @@ -64,7 +64,7 @@ crate fn eval_nullary_intrinsic<'tcx>( "size_of" | "min_align_of" | "pref_align_of" => { - let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap(); + let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; let n = match name { "pref_align_of" => layout.align.pref.bytes(), "min_align_of" => layout.align.abi.bytes(), @@ -79,7 +79,7 @@ crate fn eval_nullary_intrinsic<'tcx>( param_env.and(tcx.types.u64), ), other => bug!("`{}` is not a zero arg intrinsic", other), - } + }) } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { From 5ff2a90ae810edceaf1503f9de73db2f47f33938 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 21 Aug 2019 20:29:45 +0200 Subject: [PATCH 13/14] Make flaky test a compile-fail test for now --- .../issues => compile-fail}/issue-44415.rs | 0 src/test/ui/issues/issue-44415.stderr | 38 ------------------- 2 files changed, 38 deletions(-) rename src/test/{ui/issues => compile-fail}/issue-44415.rs (100%) delete mode 100644 src/test/ui/issues/issue-44415.stderr diff --git a/src/test/ui/issues/issue-44415.rs b/src/test/compile-fail/issue-44415.rs similarity index 100% rename from src/test/ui/issues/issue-44415.rs rename to src/test/compile-fail/issue-44415.rs diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr deleted file mode 100644 index 90fc34db4a7a9..0000000000000 --- a/src/test/ui/issues/issue-44415.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0` - --> $DIR/issue-44415.rs:6:17 - | -LL | bytes: [u8; unsafe { intrinsics::size_of::() }], - | ^^^^^^ - | -note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`... - --> $DIR/issue-44415.rs:6:17 - | -LL | bytes: [u8; unsafe { intrinsics::size_of::() }], - | ^^^^^^ -note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... - --> $DIR/issue-44415.rs:6:26 - | -LL | bytes: [u8; unsafe { intrinsics::size_of::() }], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... - --> $SRC_DIR/libcore/intrinsics.rs:LL:COL - | -LL | pub fn size_of() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... - --> $SRC_DIR/libcore/intrinsics.rs:LL:COL - | -LL | pub fn size_of() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing layout of `Foo`... - = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... - = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle -note: cycle used when processing `Foo` - --> $DIR/issue-44415.rs:5:1 - | -LL | struct Foo { - | ^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0391`. From ff654b8184e8e526de6e2d4f08d5500e8f1dbf8d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 21 Aug 2019 22:28:20 +0200 Subject: [PATCH 14/14] Fix rebase fallout --- src/librustc_mir/const_eval.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index d96aff678b3d3..2df7c24a63da8 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -13,7 +13,6 @@ use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef}; use rustc::mir; use rustc::ty::{self, Ty, TyCtxt, subst::Subst}; use rustc::ty::layout::{self, LayoutOf, VariantIdx}; -use rustc::ty::subst::Subst; use rustc::traits::Reveal; use rustc_data_structures::fx::FxHashMap; use crate::interpret::eval_nullary_intrinsic;