From e175921932615cb97eaa5cfd11d940cbd1473cac Mon Sep 17 00:00:00 2001 From: Lenard Pratt Date: Thu, 4 Apr 2019 23:29:21 +0100 Subject: Added ArrayExprKind, changed the display for fixed array types, Added Array Enum to ra_hir/expr --- crates/ra_hir/src/expr.rs | 49 ++++++++++++++++++++--------- crates/ra_hir/src/ty.rs | 2 +- crates/ra_hir/src/ty/infer.rs | 30 ++++++++++-------- crates/ra_syntax/src/ast.rs | 4 +-- crates/ra_syntax/src/ast/expr_extensions.rs | 22 +++++++++++++ 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 3e6578651..589a9b2db 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -6,7 +6,7 @@ use rustc_hash::FxHashMap; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; use ra_syntax::{ SyntaxNodePtr, AstPtr, AstNode, - ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind, TypeAscriptionOwner} + ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner} }; use crate::{ @@ -238,15 +238,17 @@ pub enum Expr { Tuple { exprs: Vec, }, - Array { - exprs: Vec, - repeat: Option, - }, + Array(Array), Literal(Literal), } pub use ra_syntax::ast::PrefixOp as UnaryOp; pub use ra_syntax::ast::BinOp as BinaryOp; +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum Array { + ElementList(Vec), + Repeat { initializer: ExprId, repeat: ExprId }, +} #[derive(Debug, Clone, Eq, PartialEq)] pub struct MatchArm { @@ -354,15 +356,17 @@ impl Expr { f(*expr); } } - Expr::Array { exprs, repeat } => { - for expr in exprs { - f(*expr); + Expr::Array(a) => match a { + Array::ElementList(exprs) => { + for expr in exprs { + f(*expr); + } } - - if let Some(expr) = repeat { - f(*expr) + Array::Repeat { initializer, repeat } => { + f(*initializer); + f(*repeat) } - } + }, Expr::Literal(_) => {} } } @@ -733,11 +737,26 @@ impl ExprCollector { let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) } + ast::ExprKind::ArrayExpr(e) => { - let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); - let repeat = e.repeat().map(|e| self.collect_expr(e)); - self.alloc_expr(Expr::Array { exprs, repeat }, syntax_ptr) + let kind = e.kind(); + + match kind { + ArrayExprKind::ElementList(e) => { + let exprs = e.map(|expr| self.collect_expr(expr)).collect(); + self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr) + } + ArrayExprKind::Repeat { initializer, repeat } => { + let initializer = self.collect_expr_opt(initializer); + let repeat = self.collect_expr_opt(repeat); + self.alloc_expr( + Expr::Array(Array::Repeat { initializer, repeat }), + syntax_ptr, + ) + } + } } + ast::ExprKind::Literal(e) => { let lit = match e.kind() { LiteralKind::IntNumber { suffix } => { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 77690309a..20e55d92d 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -359,7 +359,7 @@ impl HirDisplay for ApplicationTy { } TypeCtor::Array => { let t = self.parameters.as_single(); - write!(f, "[{};usize]", t.display(f.db))?; + write!(f, "[{};_]", t.display(f.db))?; } TypeCtor::RawPtr(m) => { let t = self.parameters.as_single(); diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index d8f4ce9f8..9ace6b13a 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -32,7 +32,7 @@ use crate::{ DefWithBody, ImplItem, type_ref::{TypeRef, Mutability}, - expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, + expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat,Array, self}, generics::GenericParams, path::{GenericArgs, GenericArg}, adt::VariantDef, @@ -1074,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) } - Expr::Array { exprs, repeat } => { + Expr::Array(array) => { let elem_ty = match &expected.ty { Ty::Apply(a_ty) => match a_ty.ctor { TypeCtor::Slice | TypeCtor::Array => { @@ -1085,17 +1085,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { _ => self.new_type_var(), }; - for expr in exprs.iter() { - self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); - } - - if let Some(expr) = repeat { - self.infer_expr( - *expr, - &Expectation::has_type(Ty::simple(TypeCtor::Int( - primitive::UncertainIntTy::Known(primitive::IntTy::usize()), - ))), - ); + match array { + Array::ElementList(items) => { + for expr in items.iter() { + self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); + } + } + Array::Repeat { initializer, repeat } => { + self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone())); + self.infer_expr( + *repeat, + &Expectation::has_type(Ty::simple(TypeCtor::Int( + primitive::UncertainIntTy::Known(primitive::IntTy::usize()), + ))), + ); + } } Ty::apply_one(TypeCtor::Array, elem_ty) diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index a06a6375d..970b89825 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -17,8 +17,8 @@ pub use self::{ generated::*, traits::*, tokens::*, - extensions::{PathSegmentKind, StructKind, FieldKind, SelfParamKind}, - expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind}, + extensions::{PathSegmentKind, StructKind, SelfParamKind}, + expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind,ArrayExprKind}, }; /// The main trait to go from untyped `SyntaxNode` to a typed ast. The diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index 1d8313810..d21ec80c3 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs @@ -193,6 +193,28 @@ impl ast::BinExpr { } } +pub enum ArrayExprKind<'a> { + Repeat { initializer: Option<&'a ast::Expr>, repeat: Option<&'a ast::Expr> }, + ElementList(AstChildren<'a, ast::Expr>), +} + +impl ast::ArrayExpr { + pub fn kind(&self) -> ArrayExprKind { + if self.is_repeat() { + ArrayExprKind::Repeat { + initializer: children(self).nth(0), + repeat: children(self).nth(2), + } + } else { + ArrayExprKind::ElementList(children(self)) + } + } + + fn is_repeat(&self) -> bool { + self.syntax().children_with_tokens().any(|it| it.kind() == SEMI) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum LiteralKind { String, -- cgit v1.2.3