]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_mir_build/src/thir/mod.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_mir_build / src / thir / mod.rs
index ed3d3927825af23312621346113ae63672d3910c..6f20195db0b5eee6d09bbeb2a5d7c188f23c66ac 100644 (file)
@@ -4,13 +4,12 @@
 //! unit-tested and separated from the Rust source and compiler data
 //! structures.
 
-use self::cx::Cx;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::middle::region;
-use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp};
+use rustc_middle::mir::{BinOp, BorrowKind, FakeReadCause, Field, UnOp};
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{AdtDef, Const, Ty, UpvarSubsts, UserType};
@@ -19,58 +18,57 @@ use rustc_target::abi::VariantIdx;
 use rustc_target::asm::InlineAsmRegOrRegClass;
 
 crate mod constant;
+
 crate mod cx;
+pub use cx::build_thir;
 
 crate mod pattern;
-crate use self::pattern::PatTyProj;
-crate use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange};
+pub use self::pattern::{Ascription, BindingMode, FieldPat, Pat, PatKind, PatRange, PatTyProj};
+
+mod arena;
+pub use arena::Arena;
 
 mod util;
 
 #[derive(Copy, Clone, Debug)]
-crate enum LintLevel {
+pub enum LintLevel {
     Inherited,
     Explicit(hir::HirId),
 }
 
-#[derive(Clone, Debug)]
-crate struct Block<'tcx> {
-    crate targeted_by_break: bool,
-    crate region_scope: region::Scope,
-    crate opt_destruction_scope: Option<region::Scope>,
-    crate span: Span,
-    crate stmts: Vec<StmtRef<'tcx>>,
-    crate expr: Option<ExprRef<'tcx>>,
-    crate safety_mode: BlockSafety,
+#[derive(Debug)]
+pub struct Block<'thir, 'tcx> {
+    pub targeted_by_break: bool,
+    pub region_scope: region::Scope,
+    pub opt_destruction_scope: Option<region::Scope>,
+    pub span: Span,
+    pub stmts: &'thir [Stmt<'thir, 'tcx>],
+    pub expr: Option<&'thir Expr<'thir, 'tcx>>,
+    pub safety_mode: BlockSafety,
 }
 
 #[derive(Copy, Clone, Debug)]
-crate enum BlockSafety {
+pub enum BlockSafety {
     Safe,
     ExplicitUnsafe(hir::HirId),
     PushUnsafe,
     PopUnsafe,
 }
 
-#[derive(Clone, Debug)]
-crate enum StmtRef<'tcx> {
-    Mirror(Box<Stmt<'tcx>>),
-}
-
-#[derive(Clone, Debug)]
-crate struct Stmt<'tcx> {
-    crate kind: StmtKind<'tcx>,
-    crate opt_destruction_scope: Option<region::Scope>,
+#[derive(Debug)]
+pub struct Stmt<'thir, 'tcx> {
+    pub kind: StmtKind<'thir, 'tcx>,
+    pub opt_destruction_scope: Option<region::Scope>,
 }
 
-#[derive(Clone, Debug)]
-crate enum StmtKind<'tcx> {
+#[derive(Debug)]
+pub enum StmtKind<'thir, 'tcx> {
     Expr {
         /// scope for this statement; may be used as lifetime of temporaries
         scope: region::Scope,
 
         /// expression being evaluated in this statement
-        expr: ExprRef<'tcx>,
+        expr: &'thir Expr<'thir, 'tcx>,
     },
 
     Let {
@@ -88,7 +86,7 @@ crate enum StmtKind<'tcx> {
         pattern: Pat<'tcx>,
 
         /// let pat: ty = <INIT> ...
-        initializer: Option<ExprRef<'tcx>>,
+        initializer: Option<&'thir Expr<'thir, 'tcx>>,
 
         /// the lint level for this let-statement
         lint_level: LintLevel,
@@ -96,13 +94,13 @@ crate enum StmtKind<'tcx> {
 }
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
-rustc_data_structures::static_assert_size!(Expr<'_>, 168);
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+rustc_data_structures::static_assert_size!(Expr<'_, '_>, 144);
 
 /// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`)
 /// into instances of this `Expr` enum. This lowering can be done
 /// basically as lazily or as eagerly as desired: every recursive
-/// reference to an expression in this enum is an `ExprRef<'tcx>`, which
+/// reference to an expression in this enum is an `&'thir Expr<'thir, 'tcx>`, which
 /// may in turn be another instance of this enum (boxed), or else an
 /// unlowered `&'tcx H::Expr`. Note that instances of `Expr` are very
 /// short-lived. They are created by `Thir::to_expr`, analyzed and
@@ -113,105 +111,105 @@ rustc_data_structures::static_assert_size!(Expr<'_>, 168);
 /// MIR simplifications are already done in the impl of `Thir`. For
 /// example, method calls and overloaded operators are absent: they are
 /// expected to be converted into `Expr::Call` instances.
-#[derive(Clone, Debug)]
-crate struct Expr<'tcx> {
+#[derive(Debug)]
+pub struct Expr<'thir, 'tcx> {
     /// type of this expression
-    crate ty: Ty<'tcx>,
+    pub ty: Ty<'tcx>,
 
     /// lifetime of this expression if it should be spilled into a
     /// temporary; should be None only if in a constant context
-    crate temp_lifetime: Option<region::Scope>,
+    pub temp_lifetime: Option<region::Scope>,
 
     /// span of the expression in the source
-    crate span: Span,
+    pub span: Span,
 
     /// kind of expression
-    crate kind: ExprKind<'tcx>,
+    pub kind: ExprKind<'thir, 'tcx>,
 }
 
-#[derive(Clone, Debug)]
-crate enum ExprKind<'tcx> {
+#[derive(Debug)]
+pub enum ExprKind<'thir, 'tcx> {
     Scope {
         region_scope: region::Scope,
         lint_level: LintLevel,
-        value: ExprRef<'tcx>,
+        value: &'thir Expr<'thir, 'tcx>,
     },
     Box {
-        value: ExprRef<'tcx>,
+        value: &'thir Expr<'thir, 'tcx>,
     },
     If {
-        cond: ExprRef<'tcx>,
-        then: ExprRef<'tcx>,
-        else_opt: Option<ExprRef<'tcx>>,
+        cond: &'thir Expr<'thir, 'tcx>,
+        then: &'thir Expr<'thir, 'tcx>,
+        else_opt: Option<&'thir Expr<'thir, 'tcx>>,
     },
     Call {
         ty: Ty<'tcx>,
-        fun: ExprRef<'tcx>,
-        args: Vec<ExprRef<'tcx>>,
-        // Whether this is from a call in HIR, rather than from an overloaded
-        // operator. True for overloaded function call.
+        fun: &'thir Expr<'thir, 'tcx>,
+        args: &'thir [Expr<'thir, 'tcx>],
+        /// Whether this is from a call in HIR, rather than from an overloaded
+        /// operator. `true` for overloaded function call.
         from_hir_call: bool,
         /// This `Span` is the span of the function, without the dot and receiver
         /// (e.g. `foo(a, b)` in `x.foo(a, b)`
         fn_span: Span,
     },
     Deref {
-        arg: ExprRef<'tcx>,
+        arg: &'thir Expr<'thir, 'tcx>,
     }, // NOT overloaded!
     Binary {
         op: BinOp,
-        lhs: ExprRef<'tcx>,
-        rhs: ExprRef<'tcx>,
+        lhs: &'thir Expr<'thir, 'tcx>,
+        rhs: &'thir Expr<'thir, 'tcx>,
     }, // NOT overloaded!
     LogicalOp {
         op: LogicalOp,
-        lhs: ExprRef<'tcx>,
-        rhs: ExprRef<'tcx>,
+        lhs: &'thir Expr<'thir, 'tcx>,
+        rhs: &'thir Expr<'thir, 'tcx>,
     }, // NOT overloaded!
     // LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands.
     Unary {
         op: UnOp,
-        arg: ExprRef<'tcx>,
+        arg: &'thir Expr<'thir, 'tcx>,
     }, // NOT overloaded!
     Cast {
-        source: ExprRef<'tcx>,
+        source: &'thir Expr<'thir, 'tcx>,
     },
     Use {
-        source: ExprRef<'tcx>,
+        source: &'thir Expr<'thir, 'tcx>,
     }, // Use a lexpr to get a vexpr.
     NeverToAny {
-        source: ExprRef<'tcx>,
+        source: &'thir Expr<'thir, 'tcx>,
     },
     Pointer {
         cast: PointerCast,
-        source: ExprRef<'tcx>,
+        source: &'thir Expr<'thir, 'tcx>,
     },
     Loop {
-        body: ExprRef<'tcx>,
+        body: &'thir Expr<'thir, 'tcx>,
     },
     Match {
-        scrutinee: ExprRef<'tcx>,
-        arms: Vec<Arm<'tcx>>,
+        scrutinee: &'thir Expr<'thir, 'tcx>,
+        arms: &'thir [Arm<'thir, 'tcx>],
     },
     Block {
-        body: &'tcx hir::Block<'tcx>,
+        body: Block<'thir, 'tcx>,
     },
     Assign {
-        lhs: ExprRef<'tcx>,
-        rhs: ExprRef<'tcx>,
+        lhs: &'thir Expr<'thir, 'tcx>,
+        rhs: &'thir Expr<'thir, 'tcx>,
     },
     AssignOp {
         op: BinOp,
-        lhs: ExprRef<'tcx>,
-        rhs: ExprRef<'tcx>,
+        lhs: &'thir Expr<'thir, 'tcx>,
+        rhs: &'thir Expr<'thir, 'tcx>,
     },
     Field {
-        lhs: ExprRef<'tcx>,
+        lhs: &'thir Expr<'thir, 'tcx>,
         name: Field,
     },
     Index {
-        lhs: ExprRef<'tcx>,
-        index: ExprRef<'tcx>,
+        lhs: &'thir Expr<'thir, 'tcx>,
+        index: &'thir Expr<'thir, 'tcx>,
     },
     VarRef {
         id: hir::HirId,
@@ -226,35 +224,35 @@ crate enum ExprKind<'tcx> {
     },
     Borrow {
         borrow_kind: BorrowKind,
-        arg: ExprRef<'tcx>,
+        arg: &'thir Expr<'thir, 'tcx>,
     },
     /// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
     AddressOf {
         mutability: hir::Mutability,
-        arg: ExprRef<'tcx>,
+        arg: &'thir Expr<'thir, 'tcx>,
     },
     Break {
         label: region::Scope,
-        value: Option<ExprRef<'tcx>>,
+        value: Option<&'thir Expr<'thir, 'tcx>>,
     },
     Continue {
         label: region::Scope,
     },
     Return {
-        value: Option<ExprRef<'tcx>>,
+        value: Option<&'thir Expr<'thir, 'tcx>>,
     },
     ConstBlock {
         value: &'tcx Const<'tcx>,
     },
     Repeat {
-        value: ExprRef<'tcx>,
+        value: &'thir Expr<'thir, 'tcx>,
         count: &'tcx Const<'tcx>,
     },
     Array {
-        fields: Vec<ExprRef<'tcx>>,
+        fields: &'thir [Expr<'thir, 'tcx>],
     },
     Tuple {
-        fields: Vec<ExprRef<'tcx>>,
+        fields: &'thir [Expr<'thir, 'tcx>],
     },
     Adt {
         adt_def: &'tcx AdtDef,
@@ -265,24 +263,25 @@ crate enum ExprKind<'tcx> {
         /// Bar::<T> { ... }`.
         user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
 
-        fields: Vec<FieldExprRef<'tcx>>,
-        base: Option<FruInfo<'tcx>>,
+        fields: &'thir [FieldExpr<'thir, 'tcx>],
+        base: Option<FruInfo<'thir, 'tcx>>,
     },
     PlaceTypeAscription {
-        source: ExprRef<'tcx>,
+        source: &'thir Expr<'thir, 'tcx>,
         /// Type that the user gave to this expression
         user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
     },
     ValueTypeAscription {
-        source: ExprRef<'tcx>,
+        source: &'thir Expr<'thir, 'tcx>,
         /// Type that the user gave to this expression
         user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
     },
     Closure {
         closure_id: DefId,
         substs: UpvarSubsts<'tcx>,
-        upvars: Vec<ExprRef<'tcx>>,
+        upvars: &'thir [Expr<'thir, 'tcx>],
         movability: Option<hir::Movability>,
+        fake_reads: Vec<(&'thir Expr<'thir, 'tcx>, FakeReadCause, hir::HirId)>,
     },
     Literal {
         literal: &'tcx Const<'tcx>,
@@ -302,7 +301,7 @@ crate enum ExprKind<'tcx> {
     },
     InlineAsm {
         template: &'tcx [InlineAsmTemplatePiece],
-        operands: Vec<InlineAsmOperand<'tcx>>,
+        operands: &'thir [InlineAsmOperand<'thir, 'tcx>],
         options: InlineAsmOptions,
         line_spans: &'tcx [Span],
     },
@@ -310,158 +309,77 @@ crate enum ExprKind<'tcx> {
     ThreadLocalRef(DefId),
     LlvmInlineAsm {
         asm: &'tcx hir::LlvmInlineAsmInner,
-        outputs: Vec<ExprRef<'tcx>>,
-        inputs: Vec<ExprRef<'tcx>>,
+        outputs: &'thir [Expr<'thir, 'tcx>],
+        inputs: &'thir [Expr<'thir, 'tcx>],
     },
     Yield {
-        value: ExprRef<'tcx>,
+        value: &'thir Expr<'thir, 'tcx>,
     },
 }
 
-#[derive(Clone, Debug)]
-crate enum ExprRef<'tcx> {
-    Thir(&'tcx hir::Expr<'tcx>),
-    Mirror(Box<Expr<'tcx>>),
+#[derive(Debug)]
+pub struct FieldExpr<'thir, 'tcx> {
+    pub name: Field,
+    pub expr: &'thir Expr<'thir, 'tcx>,
 }
 
-#[derive(Clone, Debug)]
-crate struct FieldExprRef<'tcx> {
-    crate name: Field,
-    crate expr: ExprRef<'tcx>,
+#[derive(Debug)]
+pub struct FruInfo<'thir, 'tcx> {
+    pub base: &'thir Expr<'thir, 'tcx>,
+    pub field_types: &'thir [Ty<'tcx>],
 }
 
-#[derive(Clone, Debug)]
-crate struct FruInfo<'tcx> {
-    crate base: ExprRef<'tcx>,
-    crate field_types: Vec<Ty<'tcx>>,
+#[derive(Debug)]
+pub struct Arm<'thir, 'tcx> {
+    pub pattern: Pat<'tcx>,
+    pub guard: Option<Guard<'thir, 'tcx>>,
+    pub body: &'thir Expr<'thir, 'tcx>,
+    pub lint_level: LintLevel,
+    pub scope: region::Scope,
+    pub span: Span,
 }
 
-#[derive(Clone, Debug)]
-crate struct Arm<'tcx> {
-    crate pattern: Pat<'tcx>,
-    crate guard: Option<Guard<'tcx>>,
-    crate body: ExprRef<'tcx>,
-    crate lint_level: LintLevel,
-    crate scope: region::Scope,
-    crate span: Span,
-}
-
-#[derive(Clone, Debug)]
-crate enum Guard<'tcx> {
-    If(ExprRef<'tcx>),
-    IfLet(Pat<'tcx>, ExprRef<'tcx>),
+#[derive(Debug)]
+pub enum Guard<'thir, 'tcx> {
+    If(&'thir Expr<'thir, 'tcx>),
+    IfLet(Pat<'tcx>, &'thir Expr<'thir, 'tcx>),
 }
 
 #[derive(Copy, Clone, Debug)]
-crate enum LogicalOp {
+pub enum LogicalOp {
     And,
     Or,
 }
 
-impl<'tcx> ExprRef<'tcx> {
-    crate fn span(&self) -> Span {
-        match self {
-            ExprRef::Thir(expr) => expr.span,
-            ExprRef::Mirror(expr) => expr.span,
-        }
-    }
-}
-
-#[derive(Clone, Debug)]
-crate enum InlineAsmOperand<'tcx> {
+#[derive(Debug)]
+pub enum InlineAsmOperand<'thir, 'tcx> {
     In {
         reg: InlineAsmRegOrRegClass,
-        expr: ExprRef<'tcx>,
+        expr: &'thir Expr<'thir, 'tcx>,
     },
     Out {
         reg: InlineAsmRegOrRegClass,
         late: bool,
-        expr: Option<ExprRef<'tcx>>,
+        expr: Option<&'thir Expr<'thir, 'tcx>>,
     },
     InOut {
         reg: InlineAsmRegOrRegClass,
         late: bool,
-        expr: ExprRef<'tcx>,
+        expr: &'thir Expr<'thir, 'tcx>,
     },
     SplitInOut {
         reg: InlineAsmRegOrRegClass,
         late: bool,
-        in_expr: ExprRef<'tcx>,
-        out_expr: Option<ExprRef<'tcx>>,
+        in_expr: &'thir Expr<'thir, 'tcx>,
+        out_expr: Option<&'thir Expr<'thir, 'tcx>>,
     },
     Const {
-        expr: ExprRef<'tcx>,
+        expr: &'thir Expr<'thir, 'tcx>,
     },
     SymFn {
-        expr: ExprRef<'tcx>,
+        expr: &'thir Expr<'thir, 'tcx>,
     },
     SymStatic {
         def_id: DefId,
     },
 }
-
-///////////////////////////////////////////////////////////////////////////
-// The Mirror trait
-
-/// "Mirroring" is the process of converting from a HIR type into one
-/// of the THIR types defined in this file. This is basically a "on
-/// the fly" desugaring step that hides a lot of the messiness in the
-/// tcx. For example, the mirror of a `&'tcx hir::Expr` is an
-/// `Expr<'tcx>`.
-///
-/// Mirroring is gradual: when you mirror an outer expression like `e1
-/// + e2`, the references to the inner expressions `e1` and `e2` are
-/// `ExprRef<'tcx>` instances, and they may or may not be eagerly
-/// mirrored. This allows a single AST node from the compiler to
-/// expand into one or more Thir nodes, which lets the Thir nodes be
-/// simpler.
-crate trait Mirror<'tcx> {
-    type Output;
-
-    fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Self::Output;
-}
-
-impl<'tcx> Mirror<'tcx> for Expr<'tcx> {
-    type Output = Expr<'tcx>;
-
-    fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Expr<'tcx> {
-        self
-    }
-}
-
-impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> {
-    type Output = Expr<'tcx>;
-
-    fn make_mirror(self, hir: &mut Cx<'_, 'tcx>) -> Expr<'tcx> {
-        match self {
-            ExprRef::Thir(h) => h.make_mirror(hir),
-            ExprRef::Mirror(m) => *m,
-        }
-    }
-}
-
-impl<'tcx> Mirror<'tcx> for Stmt<'tcx> {
-    type Output = Stmt<'tcx>;
-
-    fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Stmt<'tcx> {
-        self
-    }
-}
-
-impl<'tcx> Mirror<'tcx> for StmtRef<'tcx> {
-    type Output = Stmt<'tcx>;
-
-    fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Stmt<'tcx> {
-        match self {
-            StmtRef::Mirror(m) => *m,
-        }
-    }
-}
-
-impl<'tcx> Mirror<'tcx> for Block<'tcx> {
-    type Output = Block<'tcx>;
-
-    fn make_mirror(self, _: &mut Cx<'_, 'tcx>) -> Block<'tcx> {
-        self
-    }
-}