]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/const_eval.rs
Rollup merge of #61750 - tmandry:fix-install, r=Mark-Simulacrum
[rust.git] / src / librustc_mir / const_eval.rs
index 2c68ed58d50d40edbd0ae5649b14c2678e6240dd..fb031f9e7ec164ae59f57d59d733bccb60499887 100644 (file)
@@ -12,7 +12,7 @@
 use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
 use rustc::mir;
 use rustc::ty::{self, TyCtxt, query::TyCtxtAt};
-use rustc::ty::layout::{self, LayoutOf, VariantIdx, Size};
+use rustc::ty::layout::{self, LayoutOf, VariantIdx};
 use rustc::ty::subst::Subst;
 use rustc::traits::Reveal;
 use rustc::util::common::ErrorReported;
@@ -24,7 +24,7 @@
 use crate::interpret::{self,
     PlaceTy, MPlaceTy, MemPlace, OpTy, ImmTy, Immediate, Scalar,
     RawConst, ConstValue,
-    EvalResult, EvalError, InterpError, GlobalId, InterpretCx, StackPopCleanup,
+    InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpretCx, StackPopCleanup,
     Allocation, AllocId, MemoryKind,
     snapshot, RefTracking,
 };
 /// that inform us about the generic bounds of the constant. E.g., using an associated constant
 /// of a function's generic parameter will require knowledge about the bounds on the generic
 /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument.
-pub(crate) fn mk_eval_cx<'a, 'mir, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub(crate) fn mk_eval_cx<'mir, 'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
-) -> CompileTimeEvalContext<'a, 'mir, 'tcx> {
+) -> CompileTimeEvalContext<'mir, 'tcx> {
     debug!("mk_eval_cx: {:?}", param_env);
     InterpretCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new())
 }
 
-pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub(crate) fn eval_promoted<'mir, 'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     cid: GlobalId<'tcx>,
-    mir: &'mir mir::Body<'tcx>,
+    body: &'mir mir::Body<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-) -> EvalResult<'tcx, MPlaceTy<'tcx>> {
+) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
     let span = tcx.def_span(cid.instance.def_id());
     let mut ecx = mk_eval_cx(tcx, span, param_env);
-    eval_body_using_ecx(&mut ecx, cid, mir, param_env)
+    eval_body_using_ecx(&mut ecx, cid, body, param_env)
 }
 
 fn mplace_to_const<'tcx>(
-    ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
+    ecx: &CompileTimeEvalContext<'_, 'tcx>,
     mplace: MPlaceTy<'tcx>,
 ) -> &'tcx ty::Const<'tcx> {
     let MemPlace { ptr, align, meta } = *mplace;
@@ -84,7 +84,7 @@ fn mplace_to_const<'tcx>(
 }
 
 fn op_to_const<'tcx>(
-    ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
+    ecx: &CompileTimeEvalContext<'_, 'tcx>,
     op: OpTy<'tcx>,
 ) -> &'tcx ty::Const<'tcx> {
     // We do not normalize just any data.  Only non-union scalars and slices.
@@ -117,7 +117,7 @@ fn op_to_const<'tcx>(
                 ),
                 Scalar::Raw { .. } => (
                     ecx.tcx.intern_const_alloc(Allocation::from_byte_aligned_bytes(
-                        b"" as &[u8], (),
+                        b"" as &[u8],
                     )),
                     0,
                 ),
@@ -137,25 +137,25 @@ fn op_to_const<'tcx>(
 
 // Returns a pointer to where the result lives
 fn eval_body_using_ecx<'mir, 'tcx>(
-    ecx: &mut CompileTimeEvalContext<'_, 'mir, 'tcx>,
+    ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
     cid: GlobalId<'tcx>,
-    mir: &'mir mir::Body<'tcx>,
+    body: &'mir mir::Body<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-) -> EvalResult<'tcx, MPlaceTy<'tcx>> {
+) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
     debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env);
     let tcx = ecx.tcx.tcx;
-    let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
+    let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?;
     assert!(!layout.is_unsized());
     let ret = ecx.allocate(layout, MemoryKind::Stack);
 
     let name = ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()));
     let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
     trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom);
-    assert!(mir.arg_count == 0);
+    assert!(body.arg_count == 0);
     ecx.push_stack_frame(
         cid.instance,
-        mir.span,
-        mir,
+        body.span,
+        body,
         Some(ret.into()),
         StackPopCleanup::None { cleanup: false },
     )?;
@@ -165,7 +165,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
 
     // Intern the result
     let mutability = if tcx.is_mutable_static(cid.instance.def_id()) ||
-                     !layout.ty.is_freeze(tcx, param_env, mir.span) {
+                     !layout.ty.is_freeze(tcx, param_env, body.span) {
         Mutability::Mutable
     } else {
         Mutability::Immutable
@@ -176,8 +176,8 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     Ok(ret)
 }
 
-impl<'tcx> Into<EvalError<'tcx>> for ConstEvalError {
-    fn into(self) -> EvalError<'tcx> {
+impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalError {
+    fn into(self) -> InterpErrorInfo<'tcx> {
         InterpError::MachineError(self.to_string()).into()
     }
 }
@@ -216,7 +216,7 @@ fn cause(&self) -> Option<&dyn Error> {
 }
 
 // Extra machine state for CTFE, and the Machine instance
-pub struct CompileTimeInterpreter<'a, 'mir, 'tcx: 'a+'mir> {
+pub struct CompileTimeInterpreter<'mir, 'tcx> {
     /// When this value is negative, it indicates the number of interpreter
     /// steps *until* the loop detector is enabled. When it is positive, it is
     /// the number of steps after the detector has been enabled modulo the loop
@@ -224,10 +224,10 @@ pub struct CompileTimeInterpreter<'a, 'mir, 'tcx: 'a+'mir> {
     pub(super) steps_since_detector_enabled: isize,
 
     /// Extra state to detect loops.
-    pub(super) loop_detector: snapshot::InfiniteLoopDetector<'a, 'mir, 'tcx>,
+    pub(super) loop_detector: snapshot::InfiniteLoopDetector<'mir, 'tcx>,
 }
 
-impl<'a, 'mir, 'tcx> CompileTimeInterpreter<'a, 'mir, 'tcx> {
+impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
     fn new() -> Self {
         CompileTimeInterpreter {
             loop_detector: Default::default(),
@@ -297,8 +297,8 @@ fn get_mut_or<E>(
     }
 }
 
-type CompileTimeEvalContext<'a, 'mir, 'tcx> =
-    InterpretCx<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>;
+type CompileTimeEvalContext<'mir, 'tcx> =
+    InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>;
 
 impl interpret::MayLeak for ! {
     #[inline(always)]
@@ -308,9 +308,7 @@ fn may_leak(self) -> bool {
     }
 }
 
-impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
-    for CompileTimeInterpreter<'a, 'mir, 'tcx>
-{
+impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> {
     type MemoryKinds = !;
     type PointerTag = ();
 
@@ -323,17 +321,17 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
     const STATIC_KIND: Option<!> = None; // no copying of statics allowed
 
     #[inline(always)]
-    fn enforce_validity(_ecx: &InterpretCx<'a, 'mir, 'tcx, Self>) -> bool {
+    fn enforce_validity(_ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool {
         false // for now, we don't enforce validity
     }
 
     fn find_fn(
-        ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
+        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
         dest: Option<PlaceTy<'tcx>>,
         ret: Option<mir::BasicBlock>,
-    ) -> EvalResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
+    ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
         debug!("eval_fn_call: {:?}", instance);
         // Only check non-glue functions
         if let ty::InstanceDef::Item(def_id) = instance.def {
@@ -354,7 +352,7 @@ fn find_fn(
         }
         // This is a const fn. Call it.
         Ok(Some(match ecx.load_mir(instance.def) {
-            Ok(mir) => mir,
+            Ok(body) => body,
             Err(err) => {
                 if let InterpError::NoMirFor(ref path) = err.kind {
                     return Err(
@@ -368,11 +366,11 @@ fn find_fn(
     }
 
     fn call_intrinsic(
-        ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
+        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
         dest: PlaceTy<'tcx>,
-    ) -> EvalResult<'tcx> {
+    ) -> InterpResult<'tcx> {
         if ecx.emulate_intrinsic(instance, args, dest)? {
             return Ok(());
         }
@@ -384,11 +382,11 @@ fn call_intrinsic(
     }
 
     fn ptr_op(
-        _ecx: &InterpretCx<'a, 'mir, 'tcx, Self>,
+        _ecx: &InterpretCx<'mir, 'tcx, Self>,
         _bin_op: mir::BinOp,
         _left: ImmTy<'tcx>,
         _right: ImmTy<'tcx>,
-    ) -> EvalResult<'tcx, (Scalar, bool)> {
+    ) -> InterpResult<'tcx, (Scalar, bool)> {
         Err(
             ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into(),
         )
@@ -396,40 +394,40 @@ fn ptr_op(
 
     fn find_foreign_static(
         _def_id: DefId,
-        _tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
-        _memory_extra: &(),
-    ) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>> {
+        _tcx: TyCtxtAt<'tcx, 'tcx>,
+    ) -> InterpResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>> {
         err!(ReadForeignStatic)
     }
 
     #[inline(always)]
-    fn adjust_static_allocation<'b>(
-        alloc: &'b Allocation,
+    fn tag_allocation<'b>(
+        _id: AllocId,
+        alloc: Cow<'b, Allocation>,
+        _kind: Option<MemoryKind<!>>,
         _memory_extra: &(),
-    ) -> Cow<'b, Allocation<Self::PointerTag>> {
-        // We do not use a tag so we can just cheaply forward the reference
-        Cow::Borrowed(alloc)
+    ) -> (Cow<'b, Allocation<Self::PointerTag>>, Self::PointerTag) {
+        // We do not use a tag so we can just cheaply forward the allocation
+        (alloc, ())
     }
 
     #[inline(always)]
-    fn new_allocation(
-        _size: Size,
-        _extra: &Self::MemoryExtra,
-        _kind: MemoryKind<!>,
-    ) -> (Self::AllocExtra, Self::PointerTag) {
-        ((), ())
+    fn tag_static_base_pointer(
+        _id: AllocId,
+        _memory_extra: &(),
+    ) -> Self::PointerTag {
+        ()
     }
 
     fn box_alloc(
-        _ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
+        _ecx: &mut InterpretCx<'mir, 'tcx, Self>,
         _dest: PlaceTy<'tcx>,
-    ) -> EvalResult<'tcx> {
+    ) -> InterpResult<'tcx> {
         Err(
             ConstEvalError::NeedsRfc("heap allocations via `box` keyword".to_string()).into(),
         )
     }
 
-    fn before_terminator(ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>) -> EvalResult<'tcx> {
+    fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         {
             let steps = &mut ecx.machine.steps_since_detector_enabled;
 
@@ -454,27 +452,22 @@ fn before_terminator(ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>) -> EvalResult<
     }
 
     #[inline(always)]
-    fn stack_push(
-        _ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
-    ) -> EvalResult<'tcx> {
+    fn stack_push(_ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         Ok(())
     }
 
     /// Called immediately before a stack frame gets popped.
     #[inline(always)]
-    fn stack_pop(
-        _ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
-        _extra: (),
-    ) -> EvalResult<'tcx> {
+    fn stack_pop(_ecx: &mut InterpretCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> {
         Ok(())
     }
 }
 
-/// Projects to a field of a (variant of a) const.
+/// Extracts a field of a (variant of a) const.
 // this function uses `unwrap` copiously, because an already validated constant must have valid
 // fields and can thus never fail outside of compiler bugs
-pub fn const_field<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub fn const_field<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     variant: Option<VariantIdx>,
     field: mir::Field,
@@ -498,8 +491,8 @@ pub fn const_field<'a, 'tcx>(
 
 // this function uses `unwrap` copiously, because an already validated constant must have valid
 // fields and can thus never fail outside of compiler bugs
-pub fn const_variant_index<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub fn const_variant_index<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     val: &'tcx ty::Const<'tcx>,
 ) -> VariantIdx {
@@ -509,17 +502,17 @@ pub fn const_variant_index<'a, 'tcx>(
     ecx.read_discriminant(op).unwrap().1
 }
 
-pub fn error_to_const_error<'a, 'mir, 'tcx>(
-    ecx: &InterpretCx<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>,
-    mut error: EvalError<'tcx>
+pub fn error_to_const_error<'mir, 'tcx>(
+    ecx: &InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
+    mut error: InterpErrorInfo<'tcx>,
 ) -> ConstEvalErr<'tcx> {
     error.print_backtrace();
     let stacktrace = ecx.generate_stacktrace(None);
     ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span }
 }
 
-fn validate_and_turn_into_const<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn validate_and_turn_into_const<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     constant: RawConst<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
@@ -561,8 +554,8 @@ fn validate_and_turn_into_const<'a, 'tcx>(
     })
 }
 
-pub fn const_eval_provider<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub fn const_eval_provider<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
     // see comment in const_eval_provider for what we're doing here
@@ -585,8 +578,8 @@ pub fn const_eval_provider<'a, 'tcx>(
     })
 }
 
-pub fn const_eval_raw_provider<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+pub fn const_eval_raw_provider<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc::mir::interpret::ConstEvalRawResult<'tcx> {
     // Because the constant is computed twice (once per value of `Reveal`), we are at risk of
@@ -628,14 +621,14 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
     let mut ecx = InterpretCx::new(tcx.at(span), key.param_env, CompileTimeInterpreter::new());
 
     let res = ecx.load_mir(cid.instance.def);
-    res.map(|mir| {
+    res.map(|body| {
         if let Some(index) = cid.promoted {
-            &mir.promoted[index]
+            &body.promoted[index]
         } else {
-            mir
+            body
         }
     }).and_then(
-        |mir| eval_body_using_ecx(&mut ecx, cid, mir, key.param_env)
+        |body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env)
     ).and_then(|place| {
         Ok(RawConst {
             alloc_id: place.to_ptr().expect("we allocated this ptr!").alloc_id,