From d09e5a3d9e57c631860ef195fad29f002569ae4d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 12 Nov 2019 15:09:25 +0300 Subject: Move definition of exprs to hir_def --- crates/ra_hir/src/expr.rs | 408 +------------------------------------ crates/ra_hir/src/expr/lower.rs | 82 ++------ crates/ra_hir/src/ty/infer/expr.rs | 4 +- crates/ra_hir/src/ty/lower.rs | 38 +++- crates/ra_hir/src/ty/primitive.rs | 26 --- 5 files changed, 56 insertions(+), 502 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 53da7f0bf..dd2bae9b4 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -6,29 +6,18 @@ pub(crate) mod validation; use std::{ops::Index, sync::Arc}; -use hir_def::{ - path::GenericArgs, - type_ref::{Mutability, TypeRef}, -}; -use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; +use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstPtr}; use rustc_hash::FxHashMap; -use crate::{ - db::HirDatabase, - ty::primitive::{UncertainFloatTy, UncertainIntTy}, - DefWithBody, Either, HasSource, Name, Path, Resolver, Source, -}; +use crate::{db::HirDatabase, DefWithBody, Either, HasSource, Resolver, Source}; pub use self::scope::ExprScopes; -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ExprId(RawId); -impl_arena_id!(ExprId); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct PatId(RawId); -impl_arena_id!(PatId); +pub use hir_def::expr::{ + ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, MatchArm, + Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, +}; /// The body of an item (function, const etc.). #[derive(Debug, Eq, PartialEq)] @@ -187,388 +176,3 @@ impl BodySourceMap { self.field_map[&(expr, field)] } } - -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Literal { - String(String), - ByteString(Vec), - Char(char), - Bool(bool), - Int(u64, UncertainIntTy), - Float(u64, UncertainFloatTy), // FIXME: f64 is not Eq -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Expr { - /// This is produced if syntax tree does not have a required expression piece. - Missing, - Path(Path), - If { - condition: ExprId, - then_branch: ExprId, - else_branch: Option, - }, - Block { - statements: Vec, - tail: Option, - }, - Loop { - body: ExprId, - }, - While { - condition: ExprId, - body: ExprId, - }, - For { - iterable: ExprId, - pat: PatId, - body: ExprId, - }, - Call { - callee: ExprId, - args: Vec, - }, - MethodCall { - receiver: ExprId, - method_name: Name, - args: Vec, - generic_args: Option, - }, - Match { - expr: ExprId, - arms: Vec, - }, - Continue, - Break { - expr: Option, - }, - Return { - expr: Option, - }, - RecordLit { - path: Option, - fields: Vec, - spread: Option, - }, - Field { - expr: ExprId, - name: Name, - }, - Await { - expr: ExprId, - }, - Try { - expr: ExprId, - }, - TryBlock { - body: ExprId, - }, - Cast { - expr: ExprId, - type_ref: TypeRef, - }, - Ref { - expr: ExprId, - mutability: Mutability, - }, - Box { - expr: ExprId, - }, - UnaryOp { - expr: ExprId, - op: UnaryOp, - }, - BinaryOp { - lhs: ExprId, - rhs: ExprId, - op: Option, - }, - Index { - base: ExprId, - index: ExprId, - }, - Lambda { - args: Vec, - arg_types: Vec>, - body: ExprId, - }, - Tuple { - exprs: Vec, - }, - Array(Array), - Literal(Literal), -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub enum BinaryOp { - LogicOp(LogicOp), - ArithOp(ArithOp), - CmpOp(CmpOp), - Assignment { op: Option }, -} - -#[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 ra_syntax::ast::PrefixOp as UnaryOp; -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Array { - ElementList(Vec), - Repeat { initializer: ExprId, repeat: ExprId }, -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct MatchArm { - pub pats: Vec, - pub guard: Option, - pub expr: ExprId, -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct RecordLitField { - pub name: Name, - pub expr: ExprId, -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Statement { - Let { pat: PatId, type_ref: Option, initializer: Option }, - Expr(ExprId), -} - -impl Expr { - pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) { - match self { - Expr::Missing => {} - Expr::Path(_) => {} - Expr::If { condition, then_branch, else_branch } => { - f(*condition); - f(*then_branch); - if let Some(else_branch) = else_branch { - f(*else_branch); - } - } - Expr::Block { statements, tail } => { - for stmt in statements { - match stmt { - Statement::Let { initializer, .. } => { - if let Some(expr) = initializer { - f(*expr); - } - } - Statement::Expr(e) => f(*e), - } - } - if let Some(expr) = tail { - f(*expr); - } - } - Expr::TryBlock { body } => f(*body), - Expr::Loop { body } => f(*body), - Expr::While { condition, body } => { - f(*condition); - f(*body); - } - Expr::For { iterable, body, .. } => { - f(*iterable); - f(*body); - } - Expr::Call { callee, args } => { - f(*callee); - for arg in args { - f(*arg); - } - } - Expr::MethodCall { receiver, args, .. } => { - f(*receiver); - for arg in args { - f(*arg); - } - } - Expr::Match { expr, arms } => { - f(*expr); - for arm in arms { - f(arm.expr); - } - } - Expr::Continue => {} - Expr::Break { expr } | Expr::Return { expr } => { - if let Some(expr) = expr { - f(*expr); - } - } - Expr::RecordLit { fields, spread, .. } => { - for field in fields { - f(field.expr); - } - if let Some(expr) = spread { - f(*expr); - } - } - Expr::Lambda { body, .. } => { - f(*body); - } - Expr::BinaryOp { lhs, rhs, .. } => { - f(*lhs); - f(*rhs); - } - Expr::Index { base, index } => { - f(*base); - f(*index); - } - Expr::Field { expr, .. } - | Expr::Await { expr } - | Expr::Try { expr } - | Expr::Cast { expr, .. } - | Expr::Ref { expr, .. } - | Expr::UnaryOp { expr, .. } - | Expr::Box { expr } => { - f(*expr); - } - Expr::Tuple { exprs } => { - for expr in exprs { - f(*expr); - } - } - Expr::Array(a) => match a { - Array::ElementList(exprs) => { - for expr in exprs { - f(*expr); - } - } - Array::Repeat { initializer, repeat } => { - f(*initializer); - f(*repeat) - } - }, - Expr::Literal(_) => {} - } - } -} - -/// Explicit binding annotations given in the HIR for a binding. Note -/// that this is not the final binding *mode* that we infer after type -/// inference. -#[derive(Clone, PartialEq, Eq, Debug, Copy)] -pub enum BindingAnnotation { - /// No binding annotation given: this means that the final binding mode - /// will depend on whether we have skipped through a `&` reference - /// when matching. For example, the `x` in `Some(x)` will have binding - /// mode `None`; if you do `let Some(x) = &Some(22)`, it will - /// ultimately be inferred to be by-reference. - Unannotated, - - /// Annotated with `mut x` -- could be either ref or not, similar to `None`. - Mutable, - - /// Annotated as `ref`, like `ref x` - Ref, - - /// Annotated as `ref mut x`. - RefMut, -} - -impl BindingAnnotation { - fn new(is_mutable: bool, is_ref: bool) -> Self { - match (is_mutable, is_ref) { - (true, true) => BindingAnnotation::RefMut, - (false, true) => BindingAnnotation::Ref, - (true, false) => BindingAnnotation::Mutable, - (false, false) => BindingAnnotation::Unannotated, - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct RecordFieldPat { - pub(crate) name: Name, - pub(crate) pat: PatId, -} - -/// Close relative to rustc's hir::PatKind -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Pat { - Missing, - Wild, - Tuple(Vec), - Record { - path: Option, - args: Vec, - // FIXME: 'ellipsis' option - }, - Range { - start: ExprId, - end: ExprId, - }, - Slice { - prefix: Vec, - rest: Option, - suffix: Vec, - }, - Path(Path), - Lit(ExprId), - Bind { - mode: BindingAnnotation, - name: Name, - subpat: Option, - }, - TupleStruct { - path: Option, - args: Vec, - }, - Ref { - pat: PatId, - mutability: Mutability, - }, -} - -impl Pat { - pub fn walk_child_pats(&self, mut f: impl FnMut(PatId)) { - match self { - Pat::Range { .. } | Pat::Lit(..) | Pat::Path(..) | Pat::Wild | Pat::Missing => {} - Pat::Bind { subpat, .. } => { - subpat.iter().copied().for_each(f); - } - Pat::Tuple(args) | Pat::TupleStruct { args, .. } => { - args.iter().copied().for_each(f); - } - Pat::Ref { pat, .. } => f(*pat), - Pat::Slice { prefix, rest, suffix } => { - let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); - total_iter.copied().for_each(f); - } - Pat::Record { args, .. } => { - args.iter().map(|f| f.pat).for_each(f); - } - } - } -} diff --git a/crates/ra_hir/src/expr/lower.rs b/crates/ra_hir/src/expr/lower.rs index 6463dd65e..7b0bfd919 100644 --- a/crates/ra_hir/src/expr/lower.rs +++ b/crates/ra_hir/src/expr/lower.rs @@ -1,6 +1,10 @@ //! FIXME: write short doc here -use hir_def::{path::GenericArgs, type_ref::TypeRef}; +use hir_def::{ + builtin_type::{BuiltinFloat, BuiltinInt}, + path::GenericArgs, + type_ref::TypeRef, +}; use hir_expand::{ hygiene::Hygiene, name::{self, AsName, Name}, @@ -16,15 +20,13 @@ use ra_syntax::{ use test_utils::tested_by; use crate::{ - db::HirDatabase, - ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, - AstId, DefWithBody, Either, HirFileId, MacroCallLoc, MacroFileKind, Mutability, Path, Resolver, - Source, + db::HirDatabase, AstId, DefWithBody, Either, HirFileId, MacroCallLoc, MacroFileKind, + Mutability, Path, Resolver, Source, }; use super::{ - ArithOp, Array, BinaryOp, BindingAnnotation, Body, BodySourceMap, CmpOp, Expr, ExprId, Literal, - LogicOp, MatchArm, Ordering, Pat, PatId, PatPtr, RecordFieldPat, RecordLitField, Statement, + Array, BinaryOp, BindingAnnotation, Body, BodySourceMap, Expr, ExprId, Literal, MatchArm, Pat, + PatId, PatPtr, RecordFieldPat, RecordLitField, Statement, }; pub(super) fn lower( @@ -46,7 +48,7 @@ pub(super) fn lower( exprs: Arena::default(), pats: Arena::default(), params: Vec::new(), - body_expr: ExprId((!0).into()), + body_expr: ExprId::dummy(), }, } .collect(params, body) @@ -423,28 +425,18 @@ where ast::Expr::Literal(e) => { let lit = match e.kind() { LiteralKind::IntNumber { suffix } => { - let known_name = suffix - .and_then(|it| IntTy::from_suffix(&it).map(UncertainIntTy::Known)); + let known_name = suffix.and_then(|it| BuiltinInt::from_suffix(&it)); - Literal::Int( - Default::default(), - known_name.unwrap_or(UncertainIntTy::Unknown), - ) + Literal::Int(Default::default(), known_name) } LiteralKind::FloatNumber { suffix } => { - let known_name = suffix - .and_then(|it| FloatTy::from_suffix(&it).map(UncertainFloatTy::Known)); + let known_name = suffix.and_then(|it| BuiltinFloat::from_suffix(&it)); - Literal::Float( - Default::default(), - known_name.unwrap_or(UncertainFloatTy::Unknown), - ) + Literal::Float(Default::default(), known_name) } LiteralKind::ByteString => Literal::ByteString(Default::default()), LiteralKind::String => Literal::String(Default::default()), - LiteralKind::Byte => { - Literal::Int(Default::default(), UncertainIntTy::Known(IntTy::u8())) - } + LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), LiteralKind::Bool => Literal::Bool(Default::default()), LiteralKind::Char => Literal::Char(Default::default()), }; @@ -601,47 +593,3 @@ where Path::from_src(path, &hygiene) } } - -impl From for BinaryOp { - fn from(ast_op: ast::BinOp) -> Self { - match ast_op { - ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or), - ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And), - ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: false }), - ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: true }), - ast::BinOp::LesserEqualTest => { - BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: false }) - } - ast::BinOp::GreaterEqualTest => { - BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: false }) - } - ast::BinOp::LesserTest => { - BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: true }) - } - ast::BinOp::GreaterTest => { - BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: true }) - } - ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add), - ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul), - ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub), - ast::BinOp::Division => BinaryOp::ArithOp(ArithOp::Div), - ast::BinOp::Remainder => BinaryOp::ArithOp(ArithOp::Rem), - ast::BinOp::LeftShift => BinaryOp::ArithOp(ArithOp::Shl), - ast::BinOp::RightShift => BinaryOp::ArithOp(ArithOp::Shr), - ast::BinOp::BitwiseXor => BinaryOp::ArithOp(ArithOp::BitXor), - ast::BinOp::BitwiseOr => BinaryOp::ArithOp(ArithOp::BitOr), - ast::BinOp::BitwiseAnd => BinaryOp::ArithOp(ArithOp::BitAnd), - ast::BinOp::Assignment => BinaryOp::Assignment { op: None }, - ast::BinOp::AddAssign => BinaryOp::Assignment { op: Some(ArithOp::Add) }, - ast::BinOp::DivAssign => BinaryOp::Assignment { op: Some(ArithOp::Div) }, - ast::BinOp::MulAssign => BinaryOp::Assignment { op: Some(ArithOp::Mul) }, - ast::BinOp::RemAssign => BinaryOp::Assignment { op: Some(ArithOp::Rem) }, - ast::BinOp::ShlAssign => BinaryOp::Assignment { op: Some(ArithOp::Shl) }, - ast::BinOp::ShrAssign => BinaryOp::Assignment { op: Some(ArithOp::Shr) }, - ast::BinOp::SubAssign => BinaryOp::Assignment { op: Some(ArithOp::Sub) }, - ast::BinOp::BitOrAssign => BinaryOp::Assignment { op: Some(ArithOp::BitOr) }, - ast::BinOp::BitAndAssign => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) }, - ast::BinOp::BitXorAssign => BinaryOp::Assignment { op: Some(ArithOp::BitXor) }, - } - } -} diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 4af1d65ee..6d9792391 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -452,8 +452,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Ty::apply_one(TypeCtor::Ref(Mutability::Shared), slice_type) } Literal::Char(..) => Ty::simple(TypeCtor::Char), - Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int(*ty)), - Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float(*ty)), + Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int((*ty).into())), + Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float((*ty).into())), }, }; // use a new type variable if we got Ty::Unknown here diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 52d24e24d..1832fcf50 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -25,7 +25,7 @@ use crate::{ generics::{GenericDef, WherePredicate}, resolve::{Resolver, TypeNs}, ty::{ - primitive::{FloatTy, IntTy}, + primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, Adt, }, util::make_mut_slice, @@ -657,13 +657,41 @@ fn type_for_builtin(def: BuiltinType) -> Ty { BuiltinType::Char => TypeCtor::Char, BuiltinType::Bool => TypeCtor::Bool, BuiltinType::Str => TypeCtor::Str, - BuiltinType::Int(BuiltinInt { signedness, bitness }) => { - TypeCtor::Int(IntTy { signedness, bitness }.into()) - } - BuiltinType::Float(BuiltinFloat { bitness }) => TypeCtor::Float(FloatTy { bitness }.into()), + BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), + BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), }) } +impl From for IntTy { + fn from(t: BuiltinInt) -> Self { + IntTy { signedness: t.signedness, bitness: t.bitness } + } +} + +impl From for FloatTy { + fn from(t: BuiltinFloat) -> Self { + FloatTy { bitness: t.bitness } + } +} + +impl From> for UncertainIntTy { + fn from(t: Option) -> Self { + match t { + None => UncertainIntTy::Unknown, + Some(t) => UncertainIntTy::Known(t.into()), + } + } +} + +impl From> for UncertainFloatTy { + fn from(t: Option) -> Self { + match t { + None => UncertainFloatTy::Unknown, + Some(t) => UncertainFloatTy::Known(t.into()), + } + } +} + fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { let struct_data = db.struct_data(def.id.into()); let fields = match struct_data.variant_data.fields() { diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 1749752f1..7362de4c3 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs @@ -129,24 +129,6 @@ impl IntTy { (Signedness::Unsigned, IntBitness::X128) => "u128", } } - - pub(crate) fn from_suffix(suffix: &str) -> Option { - match suffix { - "isize" => Some(IntTy::isize()), - "i8" => Some(IntTy::i8()), - "i16" => Some(IntTy::i16()), - "i32" => Some(IntTy::i32()), - "i64" => Some(IntTy::i64()), - "i128" => Some(IntTy::i128()), - "usize" => Some(IntTy::usize()), - "u8" => Some(IntTy::u8()), - "u16" => Some(IntTy::u16()), - "u32" => Some(IntTy::u32()), - "u64" => Some(IntTy::u64()), - "u128" => Some(IntTy::u128()), - _ => None, - } - } } #[derive(Copy, Clone, PartialEq, Eq, Hash)] @@ -181,12 +163,4 @@ impl FloatTy { FloatBitness::X64 => "f64", } } - - pub(crate) fn from_suffix(suffix: &str) -> Option { - match suffix { - "f32" => Some(FloatTy::f32()), - "f64" => Some(FloatTy::f64()), - _ => None, - } - } } -- cgit v1.2.3