Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/hir.rs')
| -rw-r--r-- | crates/hir-def/src/hir.rs | 228 |
1 files changed, 79 insertions, 149 deletions
diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index d9358a2882..8596346943 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -17,16 +17,17 @@ pub mod type_ref; use std::fmt; -use hir_expand::name::Name; -use intern::{Interned, Symbol}; +use hir_expand::{name::Name, MacroDefId}; +use intern::Symbol; use la_arena::{Idx, RawIdx}; use rustc_apfloat::ieee::{Half as f16, Quad as f128}; use syntax::ast; +use type_ref::TypeRefId; use crate::{ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, path::{GenericArgs, Path}, - type_ref::{Mutability, Rawness, TypeRef}, + type_ref::{Mutability, Rawness}, BlockId, ConstBlockId, }; @@ -48,6 +49,22 @@ pub enum ExprOrPatId { ExprId(ExprId), PatId(PatId), } + +impl ExprOrPatId { + pub fn as_expr(self) -> Option<ExprId> { + match self { + Self::ExprId(v) => Some(v), + _ => None, + } + } + + pub fn as_pat(self) -> Option<PatId> { + match self { + Self::PatId(v) => Some(v), + _ => None, + } + } +} stdx::impl_from!(ExprId, PatId for ExprOrPatId); #[derive(Debug, Clone, Eq, PartialEq)] @@ -204,7 +221,6 @@ pub enum Expr { Call { callee: ExprId, args: Box<[ExprId]>, - is_assignee_expr: bool, }, MethodCall { receiver: ExprId, @@ -239,8 +255,6 @@ pub enum Expr { path: Option<Box<Path>>, fields: Box<[RecordLitField]>, spread: Option<ExprId>, - ellipsis: bool, - is_assignee_expr: bool, }, Field { expr: ExprId, @@ -251,7 +265,7 @@ pub enum Expr { }, Cast { expr: ExprId, - type_ref: Interned<TypeRef>, + type_ref: TypeRefId, }, Ref { expr: ExprId, @@ -265,11 +279,17 @@ pub enum Expr { expr: ExprId, op: UnaryOp, }, + /// `op` cannot be bare `=` (but can be `op=`), these are lowered to `Assignment` instead. BinaryOp { lhs: ExprId, rhs: ExprId, op: Option<BinaryOp>, }, + // Assignments need a special treatment because of destructuring assignment. + Assignment { + target: PatId, + value: ExprId, + }, Range { lhs: Option<ExprId>, rhs: Option<ExprId>, @@ -278,19 +298,17 @@ pub enum Expr { Index { base: ExprId, index: ExprId, - is_assignee_expr: bool, }, Closure { args: Box<[PatId]>, - arg_types: Box<[Option<Interned<TypeRef>>]>, - ret_type: Option<Interned<TypeRef>>, + arg_types: Box<[Option<TypeRefId>]>, + ret_type: Option<TypeRefId>, body: ExprId, closure_kind: ClosureKind, capture_by: CaptureBy, }, Tuple { exprs: Box<[ExprId]>, - is_assignee_expr: bool, }, Array(Array), Literal(Literal), @@ -301,7 +319,7 @@ pub enum Expr { #[derive(Debug, Clone, PartialEq, Eq)] pub struct OffsetOf { - pub container: Interned<TypeRef>, + pub container: TypeRefId, pub fields: Box<[Name]>, } @@ -446,7 +464,7 @@ pub enum Movability { #[derive(Debug, Clone, Eq, PartialEq)] pub enum Array { - ElementList { elements: Box<[ExprId]>, is_assignee_expr: bool }, + ElementList { elements: Box<[ExprId]> }, Repeat { initializer: ExprId, repeat: ExprId }, } @@ -467,7 +485,7 @@ pub struct RecordLitField { pub enum Statement { Let { pat: PatId, - type_ref: Option<Interned<TypeRef>>, + type_ref: Option<TypeRefId>, initializer: Option<ExprId>, else_branch: Option<ExprId>, }, @@ -475,133 +493,13 @@ pub enum Statement { expr: ExprId, has_semi: bool, }, - // At the moment, we only use this to figure out if a return expression - // is really the last statement of a block. See #16566 - Item, + Item(Item), } -impl Expr { - pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) { - match self { - Expr::Missing => {} - Expr::Path(_) | Expr::OffsetOf(_) => {} - Expr::InlineAsm(it) => it.operands.iter().for_each(|(_, op)| match op { - AsmOperand::In { expr, .. } - | AsmOperand::Out { expr: Some(expr), .. } - | AsmOperand::InOut { expr, .. } => f(*expr), - AsmOperand::SplitInOut { in_expr, out_expr, .. } => { - f(*in_expr); - if let Some(out_expr) = out_expr { - f(*out_expr); - } - } - AsmOperand::Out { expr: None, .. } - | AsmOperand::Const(_) - | AsmOperand::Label(_) - | AsmOperand::Sym(_) => (), - }), - Expr::If { condition, then_branch, else_branch } => { - f(*condition); - f(*then_branch); - if let &Some(else_branch) = else_branch { - f(else_branch); - } - } - Expr::Let { expr, .. } => { - f(*expr); - } - Expr::Const(_) => (), - Expr::Block { statements, tail, .. } - | Expr::Unsafe { statements, tail, .. } - | Expr::Async { statements, tail, .. } => { - for stmt in statements.iter() { - match stmt { - Statement::Let { initializer, else_branch, .. } => { - if let &Some(expr) = initializer { - f(expr); - } - if let &Some(expr) = else_branch { - f(expr); - } - } - Statement::Expr { expr: expression, .. } => f(*expression), - Statement::Item => (), - } - } - if let &Some(expr) = tail { - f(expr); - } - } - Expr::Loop { body, .. } => f(*body), - Expr::Call { callee, args, .. } => { - f(*callee); - args.iter().copied().for_each(f); - } - Expr::MethodCall { receiver, args, .. } => { - f(*receiver); - args.iter().copied().for_each(f); - } - Expr::Match { expr, arms } => { - f(*expr); - arms.iter().map(|arm| arm.expr).for_each(f); - } - Expr::Continue { .. } => {} - Expr::Break { expr, .. } - | Expr::Return { expr } - | Expr::Yield { expr } - | Expr::Yeet { expr } => { - if let &Some(expr) = expr { - f(expr); - } - } - Expr::Become { expr } => f(*expr), - Expr::RecordLit { fields, spread, .. } => { - for field in fields.iter() { - f(field.expr); - } - if let &Some(expr) = spread { - f(expr); - } - } - Expr::Closure { body, .. } => { - f(*body); - } - Expr::BinaryOp { lhs, rhs, .. } => { - f(*lhs); - f(*rhs); - } - Expr::Range { lhs, rhs, .. } => { - if let &Some(lhs) = rhs { - f(lhs); - } - if let &Some(rhs) = lhs { - f(rhs); - } - } - Expr::Index { base, index, .. } => { - f(*base); - f(*index); - } - Expr::Field { expr, .. } - | Expr::Await { expr } - | Expr::Cast { expr, .. } - | Expr::Ref { expr, .. } - | Expr::UnaryOp { expr, .. } - | Expr::Box { expr } => { - f(*expr); - } - Expr::Tuple { exprs, .. } => exprs.iter().copied().for_each(f), - Expr::Array(a) => match a { - Array::ElementList { elements, .. } => elements.iter().copied().for_each(f), - Array::Repeat { initializer, repeat } => { - f(*initializer); - f(*repeat) - } - }, - Expr::Literal(_) => {} - Expr::Underscore => {} - } - } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Item { + MacroDef(Box<MacroDefId>), + Other, } /// Explicit binding annotations given in the HIR for a binding. Note @@ -665,18 +563,49 @@ pub struct RecordFieldPat { pub enum Pat { Missing, Wild, - Tuple { args: Box<[PatId]>, ellipsis: Option<u32> }, + Tuple { + args: Box<[PatId]>, + ellipsis: Option<u32>, + }, Or(Box<[PatId]>), - Record { path: Option<Box<Path>>, args: Box<[RecordFieldPat]>, ellipsis: bool }, - Range { start: Option<Box<LiteralOrConst>>, end: Option<Box<LiteralOrConst>> }, - Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> }, - Path(Box<Path>), + Record { + path: Option<Box<Path>>, + args: Box<[RecordFieldPat]>, + ellipsis: bool, + }, + Range { + start: Option<Box<LiteralOrConst>>, + end: Option<Box<LiteralOrConst>>, + }, + Slice { + prefix: Box<[PatId]>, + slice: Option<PatId>, + suffix: Box<[PatId]>, + }, + /// This might refer to a variable if a single segment path (specifically, on destructuring assignment). + Path(Path), Lit(ExprId), - Bind { id: BindingId, subpat: Option<PatId> }, - TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<u32> }, - Ref { pat: PatId, mutability: Mutability }, - Box { inner: PatId }, + Bind { + id: BindingId, + subpat: Option<PatId>, + }, + TupleStruct { + path: Option<Box<Path>>, + args: Box<[PatId]>, + ellipsis: Option<u32>, + }, + Ref { + pat: PatId, + mutability: Mutability, + }, + Box { + inner: PatId, + }, ConstBlock(ExprId), + /// An expression inside a pattern. That can only occur inside assignments. + /// + /// E.g. in `(a, *b) = (1, &mut 2)`, `*b` is an expression. + Expr(ExprId), } impl Pat { @@ -687,7 +616,8 @@ impl Pat { | Pat::Path(..) | Pat::ConstBlock(..) | Pat::Wild - | Pat::Missing => {} + | Pat::Missing + | Pat::Expr(_) => {} Pat::Bind { subpat, .. } => { subpat.iter().copied().for_each(f); } |