]> git.proxmox.com Git - rustc.git/blob - src/librustc_mir/build/expr/as_constant.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc_mir / build / expr / as_constant.rs
1 //! See docs in build/expr/mod.rs
2
3 use crate::build::Builder;
4 use crate::hair::*;
5 use rustc::mir::*;
6 use rustc::ty::CanonicalUserTypeAnnotation;
7
8 impl<'a, 'tcx> Builder<'a, 'tcx> {
9 /// Compile `expr`, yielding a compile-time constant. Assumes that
10 /// `expr` is a valid compile-time constant!
11 pub fn as_constant<M>(&mut self, expr: M) -> Constant<'tcx>
12 where
13 M: Mirror<'tcx, Output = Expr<'tcx>>,
14 {
15 let expr = self.hir.mirror(expr);
16 self.expr_as_constant(expr)
17 }
18
19 fn expr_as_constant(&mut self, expr: Expr<'tcx>) -> Constant<'tcx> {
20 let this = self;
21 let Expr {
22 ty,
23 temp_lifetime: _,
24 span,
25 kind,
26 } = expr;
27 match kind {
28 ExprKind::Scope {
29 region_scope: _,
30 lint_level: _,
31 value,
32 } => this.as_constant(value),
33 ExprKind::Literal { literal, user_ty } => {
34 let user_ty = user_ty.map(|user_ty| {
35 this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
36 span,
37 user_ty,
38 inferred_ty: ty,
39 })
40 });
41 assert_eq!(literal.ty, ty);
42 Constant {
43 span,
44 user_ty,
45 literal,
46 }
47 },
48 ExprKind::StaticRef { literal, .. } => {
49 Constant {
50 span,
51 user_ty: None,
52 literal,
53 }
54 }
55 _ => span_bug!(span, "expression is not a valid constant {:?}", kind),
56 }
57 }
58 }