]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/expr.rs
Merge #11461
[rust.git] / crates / hir_def / src / expr.rs
index 5be838f4a7d842ae7fb45011eebadae56e5ea011..4dca8238880d9376833bf406c65369e8550737fe 100644 (file)
 
 use hir_expand::name::Name;
 use la_arena::{Idx, RawIdx};
-use syntax::ast::RangeOp;
 
 use crate::{
-    builtin_type::{BuiltinFloat, BuiltinInt},
+    builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
+    intern::Interned,
     path::{GenericArgs, Path},
     type_ref::{Mutability, Rawness, TypeRef},
+    BlockId,
 };
 
+pub use syntax::ast::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp};
+
 pub type ExprId = Idx<Expr>;
 pub(crate) fn dummy_expr_id() -> ExprId {
     ExprId::from_raw(RawIdx::from(!0))
@@ -37,11 +40,12 @@ pub struct Label {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Literal {
-    String(String),
-    ByteString(Vec<u8>),
+    String(Box<str>),
+    ByteString(Box<[u8]>),
     Char(char),
     Bool(bool),
-    Int(u64, Option<BuiltinInt>),
+    Int(i128, Option<BuiltinInt>),
+    Uint(u128, Option<BuiltinUint>),
     Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
 }
 
@@ -55,8 +59,13 @@ pub enum Expr {
         then_branch: ExprId,
         else_branch: Option<ExprId>,
     },
+    Let {
+        pat: PatId,
+        expr: ExprId,
+    },
     Block {
-        statements: Vec<Statement>,
+        id: BlockId,
+        statements: Box<[Statement]>,
         tail: Option<ExprId>,
         label: Option<LabelId>,
     },
@@ -77,17 +86,17 @@ pub enum Expr {
     },
     Call {
         callee: ExprId,
-        args: Vec<ExprId>,
+        args: Box<[ExprId]>,
     },
     MethodCall {
         receiver: ExprId,
         method_name: Name,
-        args: Vec<ExprId>,
-        generic_args: Option<GenericArgs>,
+        args: Box<[ExprId]>,
+        generic_args: Option<Box<GenericArgs>>,
     },
     Match {
         expr: ExprId,
-        arms: Vec<MatchArm>,
+        arms: Box<[MatchArm]>,
     },
     Continue {
         label: Option<Name>,
@@ -103,8 +112,8 @@ pub enum Expr {
         expr: Option<ExprId>,
     },
     RecordLit {
-        path: Option<Path>,
-        fields: Vec<RecordLitField>,
+        path: Option<Box<Path>>,
+        fields: Box<[RecordLitField]>,
         spread: Option<ExprId>,
     },
     Field {
@@ -128,7 +137,7 @@ pub enum Expr {
     },
     Cast {
         expr: ExprId,
-        type_ref: TypeRef,
+        type_ref: Interned<TypeRef>,
     },
     Ref {
         expr: ExprId,
@@ -157,65 +166,27 @@ pub enum Expr {
         index: ExprId,
     },
     Lambda {
-        args: Vec<PatId>,
-        arg_types: Vec<Option<TypeRef>>,
-        ret_type: Option<TypeRef>,
+        args: Box<[PatId]>,
+        arg_types: Box<[Option<Interned<TypeRef>>]>,
+        ret_type: Option<Interned<TypeRef>>,
         body: ExprId,
     },
     Tuple {
-        exprs: Vec<ExprId>,
+        exprs: Box<[ExprId]>,
     },
     Unsafe {
         body: ExprId,
     },
+    MacroStmts {
+        tail: ExprId,
+    },
     Array(Array),
     Literal(Literal),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum BinaryOp {
-    LogicOp(LogicOp),
-    ArithOp(ArithOp),
-    CmpOp(CmpOp),
-    Assignment { op: Option<ArithOp> },
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum LogicOp {
-    And,
-    Or,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum CmpOp {
-    Eq { negated: bool },
-    Ord { ordering: Ordering, strict: bool },
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum Ordering {
-    Less,
-    Greater,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ArithOp {
-    Add,
-    Mul,
-    Sub,
-    Div,
-    Rem,
-    Shl,
-    Shr,
-    BitXor,
-    BitOr,
-    BitAnd,
-}
-
-pub use syntax::ast::PrefixOp as UnaryOp;
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Array {
-    ElementList(Vec<ExprId>),
+    ElementList(Box<[ExprId]>),
     Repeat { initializer: ExprId, repeat: ExprId },
 }
 
@@ -234,8 +205,16 @@ pub struct RecordLitField {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Statement {
-    Let { pat: PatId, type_ref: Option<TypeRef>, initializer: Option<ExprId> },
-    Expr(ExprId),
+    Let {
+        pat: PatId,
+        type_ref: Option<Interned<TypeRef>>,
+        initializer: Option<ExprId>,
+        else_branch: Option<ExprId>,
+    },
+    Expr {
+        expr: ExprId,
+        has_semi: bool,
+    },
 }
 
 impl Expr {
@@ -246,23 +225,26 @@ pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
             Expr::If { condition, then_branch, else_branch } => {
                 f(*condition);
                 f(*then_branch);
-                if let Some(else_branch) = else_branch {
-                    f(*else_branch);
+                if let &Some(else_branch) = else_branch {
+                    f(else_branch);
                 }
             }
+            Expr::Let { expr, .. } => {
+                f(*expr);
+            }
             Expr::Block { statements, tail, .. } => {
-                for stmt in statements {
+                for stmt in statements.iter() {
                     match stmt {
                         Statement::Let { initializer, .. } => {
-                            if let Some(expr) = initializer {
-                                f(*expr);
+                            if let &Some(expr) = initializer {
+                                f(expr);
                             }
                         }
-                        Statement::Expr(e) => f(*e),
+                        Statement::Expr { expr: expression, .. } => f(*expression),
                     }
                 }
-                if let Some(expr) = tail {
-                    f(*expr);
+                if let &Some(expr) = tail {
+                    f(expr);
                 }
             }
             Expr::TryBlock { body }
@@ -280,34 +262,28 @@ pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
             }
             Expr::Call { callee, args } => {
                 f(*callee);
-                for arg in args {
-                    f(*arg);
-                }
+                args.iter().copied().for_each(f);
             }
             Expr::MethodCall { receiver, args, .. } => {
                 f(*receiver);
-                for arg in args {
-                    f(*arg);
-                }
+                args.iter().copied().for_each(f);
             }
             Expr::Match { expr, arms } => {
                 f(*expr);
-                for arm in arms {
-                    f(arm.expr);
-                }
+                arms.iter().map(|arm| arm.expr).for_each(f);
             }
             Expr::Continue { .. } => {}
             Expr::Break { expr, .. } | Expr::Return { expr } | Expr::Yield { expr } => {
-                if let Some(expr) = expr {
-                    f(*expr);
+                if let &Some(expr) = expr {
+                    f(expr);
                 }
             }
             Expr::RecordLit { fields, spread, .. } => {
-                for field in fields {
+                for field in fields.iter() {
                     f(field.expr);
                 }
-                if let Some(expr) = spread {
-                    f(*expr);
+                if let &Some(expr) = spread {
+                    f(expr);
                 }
             }
             Expr::Lambda { body, .. } => {
@@ -318,11 +294,11 @@ pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
                 f(*rhs);
             }
             Expr::Range { lhs, rhs, .. } => {
-                if let Some(lhs) = rhs {
-                    f(*lhs);
+                if let &Some(lhs) = rhs {
+                    f(lhs);
                 }
-                if let Some(rhs) = lhs {
-                    f(*rhs);
+                if let &Some(rhs) = lhs {
+                    f(rhs);
                 }
             }
             Expr::Index { base, index } => {
@@ -338,22 +314,15 @@ pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
             | Expr::Box { expr } => {
                 f(*expr);
             }
-            Expr::Tuple { exprs } => {
-                for expr in exprs {
-                    f(*expr);
-                }
-            }
+            Expr::Tuple { exprs } => exprs.iter().copied().for_each(f),
             Expr::Array(a) => match a {
-                Array::ElementList(exprs) => {
-                    for expr in exprs {
-                        f(*expr);
-                    }
-                }
+                Array::ElementList(exprs) => exprs.iter().copied().for_each(f),
                 Array::Repeat { initializer, repeat } => {
                     f(*initializer);
                     f(*repeat)
                 }
             },
+            Expr::MacroStmts { tail } => f(*tail),
             Expr::Literal(_) => {}
         }
     }
@@ -403,15 +372,15 @@ pub struct RecordFieldPat {
 pub enum Pat {
     Missing,
     Wild,
-    Tuple { args: Vec<PatId>, ellipsis: Option<usize> },
-    Or(Vec<PatId>),
-    Record { path: Option<Path>, args: Vec<RecordFieldPat>, ellipsis: bool },
+    Tuple { args: Box<[PatId]>, ellipsis: Option<usize> },
+    Or(Box<[PatId]>),
+    Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool },
     Range { start: ExprId, end: ExprId },
-    Slice { prefix: Vec<PatId>, slice: Option<PatId>, suffix: Vec<PatId> },
-    Path(Path),
+    Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> },
+    Path(Box<Path>),
     Lit(ExprId),
     Bind { mode: BindingAnnotation, name: Name, subpat: Option<PatId> },
-    TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> },
+    TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<usize> },
     Ref { pat: PatId, mutability: Mutability },
     Box { inner: PatId },
     ConstBlock(ExprId),