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.rs69
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 },