]> 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 f25e4b0ae8639f4b8d164dc3e1851721740df95d..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};
+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(),
@@ -961,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),