]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/qualify_min_const_fn.rs
Auto merge of #66507 - ecstatic-morse:const-if-match, r=oli-obk
[rust.git] / src / librustc_mir / transform / qualify_min_const_fn.rs
index da1fba2518ac77dc80bd8e303d7109dd0719738f..71f13c169d41eb12d278495f3a3581cc33864288 100644 (file)
@@ -80,7 +80,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
 fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> McfResult {
     for ty in ty.walk() {
         match ty.kind {
-            ty::Ref(_, _, hir::Mutability::MutMutable) => return Err((
+            ty::Ref(_, _, hir::Mutability::Mutable) => return Err((
                 span,
                 "mutable references in const fn are unstable".into(),
             )),
@@ -150,7 +150,8 @@ fn check_rvalue(
                 _ => check_operand(tcx, operand, span, def_id, body),
             }
         }
-        Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _) => {
+        Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _)
+        | Rvalue::Cast(CastKind::Pointer(PointerCast::ArrayToPointer), operand, _) => {
             check_operand(tcx, operand, span, def_id, body)
         }
         Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) |
@@ -215,7 +216,9 @@ fn check_statement(
             check_rvalue(tcx, body, def_id, rval, span)
         }
 
-        StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => {
+        | StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _)
+        if !tcx.features().const_if_match
+        => {
             Err((span, "loops and conditional expressions are not stable in const fn".into()))
         }
 
@@ -248,7 +251,10 @@ fn check_operand(
         Operand::Move(place) | Operand::Copy(place) => {
             check_place(tcx, place, span, def_id, body)
         }
-        Operand::Constant(_) => Ok(()),
+        Operand::Constant(c) => match c.check_static_ptr(tcx) {
+            Some(_) => Err((span, "cannot access `static` items in const fn".into())),
+            None => Ok(()),
+        },
     }
 }
 
@@ -263,9 +269,10 @@ fn check_place(
     while let &[ref proj_base @ .., elem] = cursor {
         cursor = proj_base;
         match elem {
-            ProjectionElem::Downcast(..) => {
-                return Err((span, "`match` or `if let` in `const fn` is unstable".into()));
-            }
+            ProjectionElem::Downcast(..) if !tcx.features().const_if_match
+                => return Err((span, "`match` or `if let` in `const fn` is unstable".into())),
+            ProjectionElem::Downcast(_symbol, _variant_index) => {}
+
             ProjectionElem::Field(..) => {
                 let base_ty = Place::ty_from(&place.base, &proj_base, body, tcx).ty;
                 if let Some(def) = base_ty.ty_adt_def() {
@@ -284,13 +291,7 @@ fn check_place(
         }
     }
 
-    match place.base {
-        PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => {
-            Err((span, "cannot access `static` items in const fn".into()))
-        }
-        PlaceBase::Local(_)
-        | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => Ok(()),
-    }
+    Ok(())
 }
 
 /// Returns whether `allow_internal_unstable(..., <feature_gate>, ...)` is present.
@@ -323,10 +324,19 @@ fn check_terminator(
             check_operand(tcx, value, span, def_id, body)
         },
 
-        TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } => Err((
+        | TerminatorKind::FalseEdges { .. }
+        | TerminatorKind::SwitchInt { .. }
+        if !tcx.features().const_if_match
+        => Err((
             span,
             "loops and conditional expressions are not stable in const fn".into(),
         )),
+
+        TerminatorKind::FalseEdges { .. } => Ok(()),
+        TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => {
+            check_operand(tcx, discr, span, def_id, body)
+        }
+
         | TerminatorKind::Abort | TerminatorKind::Unreachable => {
             Err((span, "const fn with unreachable code is not stable".into()))
         }