]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_mir_build/src/build/expr/as_constant.rs
Auto merge of #105125 - matthiaskrgr:rollup-fr0snmj, r=matthiaskrgr
[rust.git] / compiler / rustc_mir_build / src / build / expr / as_constant.rs
index 32c0207cb680c2f89a51f255b1e8e47d792439ef..717c62315745b303ca7cef8e1e4d539c24930b4d 100644 (file)
@@ -8,7 +8,9 @@
 };
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
-use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt};
+use rustc_middle::ty::{
+    self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex,
+};
 use rustc_span::DUMMY_SP;
 use rustc_target::abi::Size;
 
@@ -19,84 +21,87 @@ pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> {
         let this = self;
         let tcx = this.tcx;
         let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
-        match *kind {
+        match kind {
             ExprKind::Scope { region_scope: _, lint_level: _, value } => {
-                this.as_constant(&this.thir[value])
-            }
-            ExprKind::Literal { lit, neg } => {
-                let literal =
-                    match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) {
-                        Ok(c) => c,
-                        Err(LitToConstError::Reported(guar)) => {
-                            ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar))
-                        }
-                        Err(LitToConstError::TypeError) => {
-                            bug!("encountered type error in `lit_to_mir_constant")
-                        }
-                    };
-
-                Constant { span, user_ty: None, literal }
+                this.as_constant(&this.thir[*value])
             }
-            ExprKind::NonHirLiteral { lit, ref user_ty } => {
-                let user_ty = user_ty.as_ref().map(|user_ty| {
-                    this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
+            _ => as_constant_inner(
+                expr,
+                |user_ty| {
+                    Some(this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
                         span,
                         user_ty: user_ty.clone(),
                         inferred_ty: ty,
-                    })
-                });
-                let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty);
+                    }))
+                },
+                tcx,
+            ),
+        }
+    }
+}
 
-                Constant { span, user_ty: user_ty, literal }
-            }
-            ExprKind::ZstLiteral { ref user_ty } => {
-                let user_ty = user_ty.as_ref().map(|user_ty| {
-                    this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
-                        span,
-                        user_ty: user_ty.clone(),
-                        inferred_ty: ty,
-                    })
-                });
-                let literal = ConstantKind::Val(ConstValue::ZeroSized, ty);
+pub fn as_constant_inner<'tcx>(
+    expr: &Expr<'tcx>,
+    push_cuta: impl FnMut(&Box<CanonicalUserType<'tcx>>) -> Option<UserTypeAnnotationIndex>,
+    tcx: TyCtxt<'tcx>,
+) -> Constant<'tcx> {
+    let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
+    match *kind {
+        ExprKind::Literal { lit, neg } => {
+            let literal =
+                match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) {
+                    Ok(c) => c,
+                    Err(LitToConstError::Reported(guar)) => {
+                        ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar))
+                    }
+                    Err(LitToConstError::TypeError) => {
+                        bug!("encountered type error in `lit_to_mir_constant")
+                    }
+                };
 
-                Constant { span, user_ty: user_ty, literal }
-            }
-            ExprKind::NamedConst { def_id, substs, ref user_ty } => {
-                let user_ty = user_ty.as_ref().map(|user_ty| {
-                    this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
-                        span,
-                        user_ty: user_ty.clone(),
-                        inferred_ty: ty,
-                    })
-                });
+            Constant { span, user_ty: None, literal }
+        }
+        ExprKind::NonHirLiteral { lit, ref user_ty } => {
+            let user_ty = user_ty.as_ref().map(push_cuta).flatten();
 
-                let uneval =
-                    mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
-                let literal = ConstantKind::Unevaluated(uneval, ty);
+            let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty);
 
-                Constant { user_ty, span, literal }
-            }
-            ExprKind::ConstParam { param, def_id: _ } => {
-                let const_param = tcx.mk_const(param, expr.ty);
-                let literal = ConstantKind::Ty(const_param);
+            Constant { span, user_ty: user_ty, literal }
+        }
+        ExprKind::ZstLiteral { ref user_ty } => {
+            let user_ty = user_ty.as_ref().map(push_cuta).flatten();
 
-                Constant { user_ty: None, span, literal }
-            }
-            ExprKind::ConstBlock { did: def_id, substs } => {
-                let uneval =
-                    mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
-                let literal = ConstantKind::Unevaluated(uneval, ty);
+            let literal = ConstantKind::Val(ConstValue::ZeroSized, ty);
 
-                Constant { user_ty: None, span, literal }
-            }
-            ExprKind::StaticRef { alloc_id, ty, .. } => {
-                let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx));
-                let literal = ConstantKind::Val(const_val, ty);
+            Constant { span, user_ty: user_ty, literal }
+        }
+        ExprKind::NamedConst { def_id, substs, ref user_ty } => {
+            let user_ty = user_ty.as_ref().map(push_cuta).flatten();
 
-                Constant { span, user_ty: None, literal }
-            }
-            _ => span_bug!(span, "expression is not a valid constant {:?}", kind),
+            let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
+            let literal = ConstantKind::Unevaluated(uneval, ty);
+
+            Constant { user_ty, span, literal }
+        }
+        ExprKind::ConstParam { param, def_id: _ } => {
+            let const_param = tcx.mk_const(ty::ConstKind::Param(param), expr.ty);
+            let literal = ConstantKind::Ty(const_param);
+
+            Constant { user_ty: None, span, literal }
+        }
+        ExprKind::ConstBlock { did: def_id, substs } => {
+            let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
+            let literal = ConstantKind::Unevaluated(uneval, ty);
+
+            Constant { user_ty: None, span, literal }
+        }
+        ExprKind::StaticRef { alloc_id, ty, .. } => {
+            let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx));
+            let literal = ConstantKind::Val(const_val, ty);
+
+            Constant { span, user_ty: None, literal }
         }
+        _ => span_bug!(span, "expression is not a valid constant {:?}", kind),
     }
 }