]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/hair/cx/expr.rs
Auto merge of #66507 - ecstatic-morse:const-if-match, r=oli-obk
[rust.git] / src / librustc_mir / hair / cx / expr.rs
index 7bb96661bb746a9c462a8faf414b28172d320fb4..694a3fd04eeb1f73d322683f529bf9fbc3e92a5b 100644 (file)
@@ -5,7 +5,7 @@
 use crate::hair::util::UserAnnotatedTyHelpers;
 use rustc_index::vec::Idx;
 use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
-use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
+use rustc::mir::interpret::{GlobalId, ErrorHandled, Scalar};
 use rustc::ty::{self, AdtKind, Ty};
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
@@ -341,9 +341,10 @@ fn make_mirror_unadjusted<'a, 'tcx>(
             } else {
                 // FIXME overflow
                 match (op.node, cx.constness) {
-                    // FIXME(eddyb) use logical ops in constants when
-                    // they can handle that kind of control-flow.
-                    (hir::BinOpKind::And, hir::Constness::Const) => {
+                    // Destroy control flow if `#![feature(const_if_match)]` is not enabled.
+                    (hir::BinOpKind::And, hir::Constness::Const)
+                        if !cx.tcx.features().const_if_match =>
+                    {
                         cx.control_flow_destroyed.push((
                             op.span,
                             "`&&` operator".into(),
@@ -354,7 +355,9 @@ fn make_mirror_unadjusted<'a, 'tcx>(
                             rhs: rhs.to_ref(),
                         }
                     }
-                    (hir::BinOpKind::Or, hir::Constness::Const) => {
+                    (hir::BinOpKind::Or, hir::Constness::Const)
+                        if !cx.tcx.features().const_if_match =>
+                    {
                         cx.control_flow_destroyed.push((
                             op.span,
                             "`||` operator".into(),
@@ -366,14 +369,14 @@ fn make_mirror_unadjusted<'a, 'tcx>(
                         }
                     }
 
-                    (hir::BinOpKind::And, hir::Constness::NotConst) => {
+                    (hir::BinOpKind::And, _) => {
                         ExprKind::LogicalOp {
                             op: LogicalOp::And,
                             lhs: lhs.to_ref(),
                             rhs: rhs.to_ref(),
                         }
                     }
-                    (hir::BinOpKind::Or, hir::Constness::NotConst) => {
+                    (hir::BinOpKind::Or, _) => {
                         ExprKind::LogicalOp {
                             op: LogicalOp::Or,
                             lhs: lhs.to_ref(),
@@ -533,11 +536,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
             convert_path_expr(cx, expr, res)
         }
 
-        hir::ExprKind::InlineAsm(ref asm, ref outputs, ref inputs) => {
+        hir::ExprKind::InlineAsm(ref asm) => {
             ExprKind::InlineAsm {
-                asm,
-                outputs: outputs.to_ref(),
-                inputs: inputs.to_ref(),
+                asm: &asm.inner,
+                outputs: asm.outputs_exprs.to_ref(),
+                inputs: asm.inputs_exprs.to_ref(),
             }
         }
 
@@ -628,6 +631,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
             let cast = if cx.tables().is_coercion_cast(source.hir_id) {
                 // Convert the lexpr to a vexpr.
                 ExprKind::Use { source: source.to_ref() }
+            } else if cx.tables().expr_ty(source).is_region_ptr() {
+                // Special cased so that we can type check that the element
+                // type of the source matches the pointed to type of the
+                // destination.
+                ExprKind::Pointer { source: source.to_ref(), cast: PointerCast::ArrayToPointer }
             } else {
                 // check whether this is casting an enum variant discriminant
                 // to prevent cycles, we refer to the discriminant initializer
@@ -687,7 +695,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
                             // and not the beginning of discriminants (which is always `0`)
                             let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
                             let lhs = mk_const(cx.tcx().mk_const(ty::Const {
-                                val: ConstValue::Unevaluated(did, substs),
+                                val: ty::ConstKind::Unevaluated(did, substs),
                                 ty: var_ty,
                             }));
                             let bin = ExprKind::Binary {
@@ -855,8 +863,8 @@ fn to_borrow_kind(&self) -> BorrowKind {
 impl ToBorrowKind for hir::Mutability {
     fn to_borrow_kind(&self) -> BorrowKind {
         match *self {
-            hir::MutMutable => BorrowKind::Mut { allow_two_phase_borrow: false },
-            hir::MutImmutable => BorrowKind::Shared,
+            hir::Mutability::Mutable => BorrowKind::Mut { allow_two_phase_borrow: false },
+            hir::Mutability::Immutable => BorrowKind::Shared,
         }
     }
 }
@@ -909,7 +917,7 @@ fn convert_path_expr<'a, 'tcx>(
             let local_def_id = cx.tcx.hir().local_def_id(hir_id);
             let index = generics.param_def_id_to_index[&local_def_id];
             let name = cx.tcx.hir().name(hir_id);
-            let val = ConstValue::Param(ty::ParamConst::new(index, name));
+            let val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
             ExprKind::Literal {
                 literal: cx.tcx.mk_const(
                     ty::Const {
@@ -927,7 +935,7 @@ fn convert_path_expr<'a, 'tcx>(
             debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
             ExprKind::Literal {
                 literal: cx.tcx.mk_const(ty::Const {
-                    val: ConstValue::Unevaluated(def_id, substs),
+                    val: ty::ConstKind::Unevaluated(def_id, substs),
                     ty: cx.tables().node_type(expr.hir_id),
                 }),
                 user_ty,
@@ -956,7 +964,29 @@ fn convert_path_expr<'a, 'tcx>(
             }
         }
 
-        Res::Def(DefKind::Static, id) => ExprKind::StaticRef { id },
+        // We encode uses of statics as a `*&STATIC` where the `&STATIC` part is
+        // a constant reference (or constant raw pointer for `static mut`) in MIR
+        Res::Def(DefKind::Static, id) => {
+            let ty = cx.tcx.type_of(id);
+            let ty = if cx.tcx.is_mutable_static(id) {
+                cx.tcx.mk_mut_ptr(ty)
+            } else if cx.tcx.is_foreign_item(id) {
+                cx.tcx.mk_imm_ptr(ty)
+            } else {
+                cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_static, ty)
+            };
+            let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id);
+            let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
+            ExprKind::Deref { arg: Expr {
+                ty,
+                temp_lifetime,
+                span: expr.span,
+                kind: ExprKind::StaticRef {
+                    literal: ty::Const::from_scalar(cx.tcx, Scalar::Ptr(ptr.into()), ty),
+                    def_id: id,
+                }
+            }.to_ref() }
+        },
 
         Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id),
 
@@ -1008,7 +1038,7 @@ fn convert_var(
                         let ref_closure_ty = cx.tcx.mk_ref(region,
                                                            ty::TypeAndMut {
                                                                ty: closure_ty,
-                                                               mutbl: hir::MutImmutable,
+                                                               mutbl: hir::Mutability::Immutable,
                                                            });
                         Expr {
                             ty: closure_ty,
@@ -1029,7 +1059,7 @@ fn convert_var(
                         let ref_closure_ty = cx.tcx.mk_ref(region,
                                                            ty::TypeAndMut {
                                                                ty: closure_ty,
-                                                               mutbl: hir::MutMutable,
+                                                               mutbl: hir::Mutability::Mutable,
                                                            });
                         Expr {
                             ty: closure_ty,