Added ArrayExprKind,

changed the  display for fixed array types,
Added Array Enum to ra_hir/expr
This commit is contained in:
Lenard Pratt 2019-04-04 23:29:21 +01:00
parent 2d73c909fe
commit e175921932
5 changed files with 76 additions and 31 deletions

View file

@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
use ra_syntax::{ use ra_syntax::{
SyntaxNodePtr, AstPtr, AstNode, SyntaxNodePtr, AstPtr, AstNode,
ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind, TypeAscriptionOwner} ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner}
}; };
use crate::{ use crate::{
@ -238,15 +238,17 @@ pub enum Expr {
Tuple { Tuple {
exprs: Vec<ExprId>, exprs: Vec<ExprId>,
}, },
Array { Array(Array),
exprs: Vec<ExprId>,
repeat: Option<ExprId>,
},
Literal(Literal), Literal(Literal),
} }
pub use ra_syntax::ast::PrefixOp as UnaryOp; pub use ra_syntax::ast::PrefixOp as UnaryOp;
pub use ra_syntax::ast::BinOp as BinaryOp; pub use ra_syntax::ast::BinOp as BinaryOp;
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Array {
ElementList(Vec<ExprId>),
Repeat { initializer: ExprId, repeat: ExprId },
}
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub struct MatchArm { pub struct MatchArm {
@ -354,15 +356,17 @@ impl Expr {
f(*expr); f(*expr);
} }
} }
Expr::Array { exprs, repeat } => { Expr::Array(a) => match a {
for expr in exprs { Array::ElementList(exprs) => {
f(*expr); for expr in exprs {
f(*expr);
}
} }
Array::Repeat { initializer, repeat } => {
if let Some(expr) = repeat { f(*initializer);
f(*expr) f(*repeat)
} }
} },
Expr::Literal(_) => {} Expr::Literal(_) => {}
} }
} }
@ -733,11 +737,26 @@ impl ExprCollector {
let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
} }
ast::ExprKind::ArrayExpr(e) => { ast::ExprKind::ArrayExpr(e) => {
let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); let kind = e.kind();
let repeat = e.repeat().map(|e| self.collect_expr(e));
self.alloc_expr(Expr::Array { exprs, repeat }, syntax_ptr) 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) => { ast::ExprKind::Literal(e) => {
let lit = match e.kind() { let lit = match e.kind() {
LiteralKind::IntNumber { suffix } => { LiteralKind::IntNumber { suffix } => {

View file

@ -359,7 +359,7 @@ impl HirDisplay for ApplicationTy {
} }
TypeCtor::Array => { TypeCtor::Array => {
let t = self.parameters.as_single(); let t = self.parameters.as_single();
write!(f, "[{};usize]", t.display(f.db))?; write!(f, "[{};_]", t.display(f.db))?;
} }
TypeCtor::RawPtr(m) => { TypeCtor::RawPtr(m) => {
let t = self.parameters.as_single(); let t = self.parameters.as_single();

View file

@ -32,7 +32,7 @@ use crate::{
DefWithBody, DefWithBody,
ImplItem, ImplItem,
type_ref::{TypeRef, Mutability}, 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, generics::GenericParams,
path::{GenericArgs, GenericArg}, path::{GenericArgs, GenericArg},
adt::VariantDef, adt::VariantDef,
@ -1074,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into()))
} }
Expr::Array { exprs, repeat } => { Expr::Array(array) => {
let elem_ty = match &expected.ty { let elem_ty = match &expected.ty {
Ty::Apply(a_ty) => match a_ty.ctor { Ty::Apply(a_ty) => match a_ty.ctor {
TypeCtor::Slice | TypeCtor::Array => { TypeCtor::Slice | TypeCtor::Array => {
@ -1085,17 +1085,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
_ => self.new_type_var(), _ => self.new_type_var(),
}; };
for expr in exprs.iter() { match array {
self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); Array::ElementList(items) => {
} for expr in items.iter() {
self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
if let Some(expr) = repeat { }
self.infer_expr( }
*expr, Array::Repeat { initializer, repeat } => {
&Expectation::has_type(Ty::simple(TypeCtor::Int( self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone()));
primitive::UncertainIntTy::Known(primitive::IntTy::usize()), self.infer_expr(
))), *repeat,
); &Expectation::has_type(Ty::simple(TypeCtor::Int(
primitive::UncertainIntTy::Known(primitive::IntTy::usize()),
))),
);
}
} }
Ty::apply_one(TypeCtor::Array, elem_ty) Ty::apply_one(TypeCtor::Array, elem_ty)

View file

@ -17,8 +17,8 @@ pub use self::{
generated::*, generated::*,
traits::*, traits::*,
tokens::*, tokens::*,
extensions::{PathSegmentKind, StructKind, FieldKind, SelfParamKind}, extensions::{PathSegmentKind, StructKind, SelfParamKind},
expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind}, expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind,ArrayExprKind},
}; };
/// The main trait to go from untyped `SyntaxNode` to a typed ast. The /// The main trait to go from untyped `SyntaxNode` to a typed ast. The

View file

@ -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)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum LiteralKind { pub enum LiteralKind {
String, String,