Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr.rs')
| -rw-r--r-- | crates/hir-def/src/expr.rs | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/crates/hir-def/src/expr.rs b/crates/hir-def/src/expr.rs index 48028b7c6a..bbea608c55 100644 --- a/crates/hir-def/src/expr.rs +++ b/crates/hir-def/src/expr.rs @@ -17,6 +17,7 @@ use std::fmt; use hir_expand::name::Name; use intern::Interned; use la_arena::{Idx, RawIdx}; +use smallvec::SmallVec; use crate::{ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, @@ -29,6 +30,8 @@ pub use syntax::ast::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, Unar pub type ExprId = Idx<Expr>; +pub type BindingId = Idx<Binding>; + /// FIXME: this is a hacky function which should be removed pub(crate) fn dummy_expr_id() -> ExprId { ExprId::from_raw(RawIdx::from(u32::MAX)) @@ -52,13 +55,21 @@ pub type LabelId = Idx<Label>; // We convert float values into bits and that's how we don't need to deal with f32 and f64. // For PartialEq, bits comparison should work, as ordering is not important // https://github.com/rust-lang/rust-analyzer/issues/12380#issuecomment-1137284360 -#[derive(Default, Debug, Clone, Eq, PartialEq)] +#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] pub struct FloatTypeWrapper(u64); impl FloatTypeWrapper { pub fn new(value: f64) -> Self { Self(value.to_bits()) } + + pub fn into_f64(self) -> f64 { + f64::from_bits(self.0) + } + + pub fn into_f32(self) -> f32 { + f64::from_bits(self.0) as f32 + } } impl fmt::Display for FloatTypeWrapper { @@ -101,6 +112,26 @@ pub enum Expr { tail: Option<ExprId>, label: Option<LabelId>, }, + TryBlock { + id: BlockId, + statements: Box<[Statement]>, + tail: Option<ExprId>, + }, + Async { + id: BlockId, + statements: Box<[Statement]>, + tail: Option<ExprId>, + }, + Const { + id: BlockId, + statements: Box<[Statement]>, + tail: Option<ExprId>, + }, + Unsafe { + id: BlockId, + statements: Box<[Statement]>, + tail: Option<ExprId>, + }, Loop { body: ExprId, label: Option<LabelId>, @@ -164,15 +195,6 @@ pub enum Expr { Try { expr: ExprId, }, - TryBlock { - body: ExprId, - }, - Async { - body: ExprId, - }, - Const { - body: ExprId, - }, Cast { expr: ExprId, type_ref: Interned<TypeRef>, @@ -214,9 +236,6 @@ pub enum Expr { exprs: Box<[ExprId]>, is_assignee_expr: bool, }, - Unsafe { - body: ExprId, - }, Array(Array), Literal(Literal), Underscore, @@ -282,13 +301,20 @@ impl Expr { Expr::Let { expr, .. } => { f(*expr); } - Expr::Block { statements, tail, .. } => { + Expr::Block { statements, tail, .. } + | Expr::TryBlock { statements, tail, .. } + | Expr::Unsafe { statements, tail, .. } + | Expr::Async { statements, tail, .. } + | Expr::Const { statements, tail, .. } => { for stmt in statements.iter() { match stmt { - Statement::Let { initializer, .. } => { + 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), } @@ -297,10 +323,6 @@ impl Expr { f(expr); } } - Expr::TryBlock { body } - | Expr::Unsafe { body } - | Expr::Async { body } - | Expr::Const { body } => f(*body), Expr::Loop { body, .. } => f(*body), Expr::While { condition, body, .. } => { f(*condition); @@ -415,6 +437,13 @@ impl BindingAnnotation { } #[derive(Debug, Clone, Eq, PartialEq)] +pub struct Binding { + pub name: Name, + pub mode: BindingAnnotation, + pub definitions: SmallVec<[PatId; 1]>, +} + +#[derive(Debug, Clone, Eq, PartialEq)] pub struct RecordFieldPat { pub name: Name, pub pat: PatId, @@ -432,7 +461,7 @@ pub enum Pat { Slice { prefix: Box<[PatId]>, slice: Option<PatId>, suffix: Box<[PatId]> }, Path(Box<Path>), Lit(ExprId), - Bind { mode: BindingAnnotation, name: Name, subpat: Option<PatId> }, + Bind { id: BindingId, subpat: Option<PatId> }, TupleStruct { path: Option<Box<Path>>, args: Box<[PatId]>, ellipsis: Option<usize> }, Ref { pat: PatId, mutability: Mutability }, Box { inner: PatId }, |