diff options
-rw-r--r-- | crates/ra_hir/src/expr.rs | 49 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 30 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 4 | ||||
-rw-r--r-- | 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; | |||
6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | SyntaxNodePtr, AstPtr, AstNode, | 8 | SyntaxNodePtr, AstPtr, AstNode, |
9 | ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind, TypeAscriptionOwner} | 9 | ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner} |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
@@ -238,15 +238,17 @@ pub enum Expr { | |||
238 | Tuple { | 238 | Tuple { |
239 | exprs: Vec<ExprId>, | 239 | exprs: Vec<ExprId>, |
240 | }, | 240 | }, |
241 | Array { | 241 | Array(Array), |
242 | exprs: Vec<ExprId>, | ||
243 | repeat: Option<ExprId>, | ||
244 | }, | ||
245 | Literal(Literal), | 242 | Literal(Literal), |
246 | } | 243 | } |
247 | 244 | ||
248 | pub use ra_syntax::ast::PrefixOp as UnaryOp; | 245 | pub use ra_syntax::ast::PrefixOp as UnaryOp; |
249 | pub use ra_syntax::ast::BinOp as BinaryOp; | 246 | pub use ra_syntax::ast::BinOp as BinaryOp; |
247 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
248 | pub enum Array { | ||
249 | ElementList(Vec<ExprId>), | ||
250 | Repeat { initializer: ExprId, repeat: ExprId }, | ||
251 | } | ||
250 | 252 | ||
251 | #[derive(Debug, Clone, Eq, PartialEq)] | 253 | #[derive(Debug, Clone, Eq, PartialEq)] |
252 | pub struct MatchArm { | 254 | pub struct MatchArm { |
@@ -354,15 +356,17 @@ impl Expr { | |||
354 | f(*expr); | 356 | f(*expr); |
355 | } | 357 | } |
356 | } | 358 | } |
357 | Expr::Array { exprs, repeat } => { | 359 | Expr::Array(a) => match a { |
358 | for expr in exprs { | 360 | Array::ElementList(exprs) => { |
359 | f(*expr); | 361 | for expr in exprs { |
362 | f(*expr); | ||
363 | } | ||
360 | } | 364 | } |
361 | 365 | Array::Repeat { initializer, repeat } => { | |
362 | if let Some(expr) = repeat { | 366 | f(*initializer); |
363 | f(*expr) | 367 | f(*repeat) |
364 | } | 368 | } |
365 | } | 369 | }, |
366 | Expr::Literal(_) => {} | 370 | Expr::Literal(_) => {} |
367 | } | 371 | } |
368 | } | 372 | } |
@@ -733,11 +737,26 @@ impl ExprCollector { | |||
733 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 737 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
734 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 738 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
735 | } | 739 | } |
740 | |||
736 | ast::ExprKind::ArrayExpr(e) => { | 741 | ast::ExprKind::ArrayExpr(e) => { |
737 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 742 | let kind = e.kind(); |
738 | let repeat = e.repeat().map(|e| self.collect_expr(e)); | 743 | |
739 | self.alloc_expr(Expr::Array { exprs, repeat }, syntax_ptr) | 744 | match kind { |
745 | ArrayExprKind::ElementList(e) => { | ||
746 | let exprs = e.map(|expr| self.collect_expr(expr)).collect(); | ||
747 | self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr) | ||
748 | } | ||
749 | ArrayExprKind::Repeat { initializer, repeat } => { | ||
750 | let initializer = self.collect_expr_opt(initializer); | ||
751 | let repeat = self.collect_expr_opt(repeat); | ||
752 | self.alloc_expr( | ||
753 | Expr::Array(Array::Repeat { initializer, repeat }), | ||
754 | syntax_ptr, | ||
755 | ) | ||
756 | } | ||
757 | } | ||
740 | } | 758 | } |
759 | |||
741 | ast::ExprKind::Literal(e) => { | 760 | ast::ExprKind::Literal(e) => { |
742 | let lit = match e.kind() { | 761 | let lit = match e.kind() { |
743 | LiteralKind::IntNumber { suffix } => { | 762 | 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 { | |||
359 | } | 359 | } |
360 | TypeCtor::Array => { | 360 | TypeCtor::Array => { |
361 | let t = self.parameters.as_single(); | 361 | let t = self.parameters.as_single(); |
362 | write!(f, "[{};usize]", t.display(f.db))?; | 362 | write!(f, "[{};_]", t.display(f.db))?; |
363 | } | 363 | } |
364 | TypeCtor::RawPtr(m) => { | 364 | TypeCtor::RawPtr(m) => { |
365 | let t = self.parameters.as_single(); | 365 | 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::{ | |||
32 | DefWithBody, | 32 | DefWithBody, |
33 | ImplItem, | 33 | ImplItem, |
34 | type_ref::{TypeRef, Mutability}, | 34 | type_ref::{TypeRef, Mutability}, |
35 | expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, | 35 | expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat,Array, self}, |
36 | generics::GenericParams, | 36 | generics::GenericParams, |
37 | path::{GenericArgs, GenericArg}, | 37 | path::{GenericArgs, GenericArg}, |
38 | adt::VariantDef, | 38 | adt::VariantDef, |
@@ -1074,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1074 | 1074 | ||
1075 | Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) | 1075 | Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) |
1076 | } | 1076 | } |
1077 | Expr::Array { exprs, repeat } => { | 1077 | Expr::Array(array) => { |
1078 | let elem_ty = match &expected.ty { | 1078 | let elem_ty = match &expected.ty { |
1079 | Ty::Apply(a_ty) => match a_ty.ctor { | 1079 | Ty::Apply(a_ty) => match a_ty.ctor { |
1080 | TypeCtor::Slice | TypeCtor::Array => { | 1080 | TypeCtor::Slice | TypeCtor::Array => { |
@@ -1085,17 +1085,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1085 | _ => self.new_type_var(), | 1085 | _ => self.new_type_var(), |
1086 | }; | 1086 | }; |
1087 | 1087 | ||
1088 | for expr in exprs.iter() { | 1088 | match array { |
1089 | self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); | 1089 | Array::ElementList(items) => { |
1090 | } | 1090 | for expr in items.iter() { |
1091 | 1091 | self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); | |
1092 | if let Some(expr) = repeat { | 1092 | } |
1093 | self.infer_expr( | 1093 | } |
1094 | *expr, | 1094 | Array::Repeat { initializer, repeat } => { |
1095 | &Expectation::has_type(Ty::simple(TypeCtor::Int( | 1095 | self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone())); |
1096 | primitive::UncertainIntTy::Known(primitive::IntTy::usize()), | 1096 | self.infer_expr( |
1097 | ))), | 1097 | *repeat, |
1098 | ); | 1098 | &Expectation::has_type(Ty::simple(TypeCtor::Int( |
1099 | primitive::UncertainIntTy::Known(primitive::IntTy::usize()), | ||
1100 | ))), | ||
1101 | ); | ||
1102 | } | ||
1099 | } | 1103 | } |
1100 | 1104 | ||
1101 | Ty::apply_one(TypeCtor::Array, elem_ty) | 1105 | 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::{ | |||
17 | generated::*, | 17 | generated::*, |
18 | traits::*, | 18 | traits::*, |
19 | tokens::*, | 19 | tokens::*, |
20 | extensions::{PathSegmentKind, StructKind, FieldKind, SelfParamKind}, | 20 | extensions::{PathSegmentKind, StructKind, SelfParamKind}, |
21 | expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind}, | 21 | expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind,ArrayExprKind}, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | /// The main trait to go from untyped `SyntaxNode` to a typed ast. The | 24 | /// 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 { | |||
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | pub enum ArrayExprKind<'a> { | ||
197 | Repeat { initializer: Option<&'a ast::Expr>, repeat: Option<&'a ast::Expr> }, | ||
198 | ElementList(AstChildren<'a, ast::Expr>), | ||
199 | } | ||
200 | |||
201 | impl ast::ArrayExpr { | ||
202 | pub fn kind(&self) -> ArrayExprKind { | ||
203 | if self.is_repeat() { | ||
204 | ArrayExprKind::Repeat { | ||
205 | initializer: children(self).nth(0), | ||
206 | repeat: children(self).nth(2), | ||
207 | } | ||
208 | } else { | ||
209 | ArrayExprKind::ElementList(children(self)) | ||
210 | } | ||
211 | } | ||
212 | |||
213 | fn is_repeat(&self) -> bool { | ||
214 | self.syntax().children_with_tokens().any(|it| it.kind() == SEMI) | ||
215 | } | ||
216 | } | ||
217 | |||
196 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 218 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
197 | pub enum LiteralKind { | 219 | pub enum LiteralKind { |
198 | String, | 220 | String, |