aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs49
-rw-r--r--crates/ra_hir/src/name.rs9
-rw-r--r--crates/ra_hir/src/ty.rs6
-rw-r--r--crates/ra_hir/src/ty/infer.rs25
-rw-r--r--crates/ra_hir/src/ty/tests.rs141
5 files changed, 174 insertions, 56 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index b2a237ece..589a9b2db 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
7use ra_syntax::{ 7use 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
12use crate::{ 12use crate::{
@@ -238,14 +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 },
244 Literal(Literal), 242 Literal(Literal),
245} 243}
246 244
247pub use ra_syntax::ast::PrefixOp as UnaryOp; 245pub use ra_syntax::ast::PrefixOp as UnaryOp;
248pub use ra_syntax::ast::BinOp as BinaryOp; 246pub use ra_syntax::ast::BinOp as BinaryOp;
247#[derive(Debug, Clone, Eq, PartialEq)]
248pub enum Array {
249 ElementList(Vec<ExprId>),
250 Repeat { initializer: ExprId, repeat: ExprId },
251}
249 252
250#[derive(Debug, Clone, Eq, PartialEq)] 253#[derive(Debug, Clone, Eq, PartialEq)]
251pub struct MatchArm { 254pub struct MatchArm {
@@ -348,11 +351,22 @@ impl Expr {
348 | Expr::UnaryOp { expr, .. } => { 351 | Expr::UnaryOp { expr, .. } => {
349 f(*expr); 352 f(*expr);
350 } 353 }
351 Expr::Tuple { exprs } | Expr::Array { exprs } => { 354 Expr::Tuple { exprs } => {
352 for expr in exprs { 355 for expr in exprs {
353 f(*expr); 356 f(*expr);
354 } 357 }
355 } 358 }
359 Expr::Array(a) => match a {
360 Array::ElementList(exprs) => {
361 for expr in exprs {
362 f(*expr);
363 }
364 }
365 Array::Repeat { initializer, repeat } => {
366 f(*initializer);
367 f(*repeat)
368 }
369 },
356 Expr::Literal(_) => {} 370 Expr::Literal(_) => {}
357 } 371 }
358 } 372 }
@@ -671,7 +685,10 @@ impl ExprCollector {
671 } 685 }
672 ast::ExprKind::FieldExpr(e) => { 686 ast::ExprKind::FieldExpr(e) => {
673 let expr = self.collect_expr_opt(e.expr()); 687 let expr = self.collect_expr_opt(e.expr());
674 let name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 688 let name = match e.field_access() {
689 Some(kind) => kind.as_name(),
690 _ => Name::missing(),
691 };
675 self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) 692 self.alloc_expr(Expr::Field { expr, name }, syntax_ptr)
676 } 693 }
677 ast::ExprKind::TryExpr(e) => { 694 ast::ExprKind::TryExpr(e) => {
@@ -720,10 +737,26 @@ impl ExprCollector {
720 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); 737 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
721 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) 738 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
722 } 739 }
740
723 ast::ExprKind::ArrayExpr(e) => { 741 ast::ExprKind::ArrayExpr(e) => {
724 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); 742 let kind = e.kind();
725 self.alloc_expr(Expr::Array { exprs }, syntax_ptr) 743
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 }
726 } 758 }
759
727 ast::ExprKind::Literal(e) => { 760 ast::ExprKind::Literal(e) => {
728 let lit = match e.kind() { 761 let lit = match e.kind() {
729 LiteralKind::IntNumber { suffix } => { 762 LiteralKind::IntNumber { suffix } => {
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 677d18efc..283f37845 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -90,6 +90,15 @@ impl AsName for ast::Name {
90 } 90 }
91} 91}
92 92
93impl<'a> AsName for ast::FieldKind<'a> {
94 fn as_name(&self) -> Name {
95 match self {
96 ast::FieldKind::Name(nr) => nr.as_name(),
97 ast::FieldKind::Index(idx) => Name::new(idx.text().clone()),
98 }
99 }
100}
101
93impl AsName for ra_db::Dependency { 102impl AsName for ra_db::Dependency {
94 fn as_name(&self) -> Name { 103 fn as_name(&self) -> Name {
95 Name::new(self.name.clone()) 104 Name::new(self.name.clone())
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index d42c61e9d..20e55d92d 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -353,10 +353,14 @@ impl HirDisplay for ApplicationTy {
353 TypeCtor::Int(t) => write!(f, "{}", t)?, 353 TypeCtor::Int(t) => write!(f, "{}", t)?,
354 TypeCtor::Float(t) => write!(f, "{}", t)?, 354 TypeCtor::Float(t) => write!(f, "{}", t)?,
355 TypeCtor::Str => write!(f, "str")?, 355 TypeCtor::Str => write!(f, "str")?,
356 TypeCtor::Slice | TypeCtor::Array => { 356 TypeCtor::Slice => {
357 let t = self.parameters.as_single(); 357 let t = self.parameters.as_single();
358 write!(f, "[{}]", t.display(f.db))?; 358 write!(f, "[{}]", t.display(f.db))?;
359 } 359 }
360 TypeCtor::Array => {
361 let t = self.parameters.as_single();
362 write!(f, "[{};_]", t.display(f.db))?;
363 }
360 TypeCtor::RawPtr(m) => { 364 TypeCtor::RawPtr(m) => {
361 let t = self.parameters.as_single(); 365 let t = self.parameters.as_single();
362 write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?; 366 write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 887153484..28947be51 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,
@@ -489,8 +489,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
489 Some(ty) 489 Some(ty)
490 } 490 }
491 Resolution::LocalBinding(pat) => { 491 Resolution::LocalBinding(pat) => {
492 let ty = self.type_of_pat.get(pat)?; 492 let ty = self.type_of_pat.get(pat)?.clone();
493 let ty = self.resolve_ty_as_possible(&mut vec![], ty.clone()); 493 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
494 Some(ty) 494 Some(ty)
495 } 495 }
496 Resolution::GenericParam(..) => { 496 Resolution::GenericParam(..) => {
@@ -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 } => { 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,8 +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 for expr in items.iter() {
1091 self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
1092 }
1093 }
1094 Array::Repeat { initializer, repeat } => {
1095 self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone()));
1096 self.infer_expr(
1097 *repeat,
1098 &Expectation::has_type(Ty::simple(TypeCtor::Int(
1099 primitive::UncertainIntTy::Known(primitive::IntTy::usize()),
1100 ))),
1101 );
1102 }
1090 } 1103 }
1091 1104
1092 Ty::apply_one(TypeCtor::Array, elem_ty) 1105 Ty::apply_one(TypeCtor::Array, elem_ty)
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 0b7c841df..f6a325033 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -697,58 +697,58 @@ fn test(x: &str, y: isize) {
697[9; 10) 'x': &str 697[9; 10) 'x': &str
698[18; 19) 'y': isize 698[18; 19) 'y': isize
699[28; 324) '{ ... 3]; }': () 699[28; 324) '{ ... 3]; }': ()
700[38; 39) 'a': [&str] 700[38; 39) 'a': [&str;_]
701[42; 45) '[x]': [&str] 701[42; 45) '[x]': [&str;_]
702[43; 44) 'x': &str 702[43; 44) 'x': &str
703[55; 56) 'b': [[&str]] 703[55; 56) 'b': [[&str;_];_]
704[59; 65) '[a, a]': [[&str]] 704[59; 65) '[a, a]': [[&str;_];_]
705[60; 61) 'a': [&str] 705[60; 61) 'a': [&str;_]
706[63; 64) 'a': [&str] 706[63; 64) 'a': [&str;_]
707[75; 76) 'c': [[[&str]]] 707[75; 76) 'c': [[[&str;_];_];_]
708[79; 85) '[b, b]': [[[&str]]] 708[79; 85) '[b, b]': [[[&str;_];_];_]
709[80; 81) 'b': [[&str]] 709[80; 81) 'b': [[&str;_];_]
710[83; 84) 'b': [[&str]] 710[83; 84) 'b': [[&str;_];_]
711[96; 97) 'd': [isize] 711[96; 97) 'd': [isize;_]
712[100; 112) '[y, 1, 2, 3]': [isize] 712[100; 112) '[y, 1, 2, 3]': [isize;_]
713[101; 102) 'y': isize 713[101; 102) 'y': isize
714[104; 105) '1': isize 714[104; 105) '1': isize
715[107; 108) '2': isize 715[107; 108) '2': isize
716[110; 111) '3': isize 716[110; 111) '3': isize
717[122; 123) 'd': [isize] 717[122; 123) 'd': [isize;_]
718[126; 138) '[1, y, 2, 3]': [isize] 718[126; 138) '[1, y, 2, 3]': [isize;_]
719[127; 128) '1': isize 719[127; 128) '1': isize
720[130; 131) 'y': isize 720[130; 131) 'y': isize
721[133; 134) '2': isize 721[133; 134) '2': isize
722[136; 137) '3': isize 722[136; 137) '3': isize
723[148; 149) 'e': [isize] 723[148; 149) 'e': [isize;_]
724[152; 155) '[y]': [isize] 724[152; 155) '[y]': [isize;_]
725[153; 154) 'y': isize 725[153; 154) 'y': isize
726[165; 166) 'f': [[isize]] 726[165; 166) 'f': [[isize;_];_]
727[169; 175) '[d, d]': [[isize]] 727[169; 175) '[d, d]': [[isize;_];_]
728[170; 171) 'd': [isize] 728[170; 171) 'd': [isize;_]
729[173; 174) 'd': [isize] 729[173; 174) 'd': [isize;_]
730[185; 186) 'g': [[isize]] 730[185; 186) 'g': [[isize;_];_]
731[189; 195) '[e, e]': [[isize]] 731[189; 195) '[e, e]': [[isize;_];_]
732[190; 191) 'e': [isize] 732[190; 191) 'e': [isize;_]
733[193; 194) 'e': [isize] 733[193; 194) 'e': [isize;_]
734[206; 207) 'h': [i32] 734[206; 207) 'h': [i32;_]
735[210; 216) '[1, 2]': [i32] 735[210; 216) '[1, 2]': [i32;_]
736[211; 212) '1': i32 736[211; 212) '1': i32
737[214; 215) '2': i32 737[214; 215) '2': i32
738[226; 227) 'i': [&str] 738[226; 227) 'i': [&str;_]
739[230; 240) '["a", "b"]': [&str] 739[230; 240) '["a", "b"]': [&str;_]
740[231; 234) '"a"': &str 740[231; 234) '"a"': &str
741[236; 239) '"b"': &str 741[236; 239) '"b"': &str
742[251; 252) 'b': [[&str]] 742[251; 252) 'b': [[&str;_];_]
743[255; 265) '[a, ["b"]]': [[&str]] 743[255; 265) '[a, ["b"]]': [[&str;_];_]
744[256; 257) 'a': [&str] 744[256; 257) 'a': [&str;_]
745[259; 264) '["b"]': [&str] 745[259; 264) '["b"]': [&str;_]
746[260; 263) '"b"': &str 746[260; 263) '"b"': &str
747[275; 276) 'x': [u8] 747[275; 276) 'x': [u8;_]
748[288; 290) '[]': [u8] 748[288; 290) '[]': [u8;_]
749[300; 301) 'z': &[u8] 749[300; 301) 'z': &[u8;_]
750[311; 321) '&[1, 2, 3]': &[u8] 750[311; 321) '&[1, 2, 3]': &[u8;_]
751[312; 321) '[1, 2, 3]': [u8] 751[312; 321) '[1, 2, 3]': [u8;_]
752[313; 314) '1': u8 752[313; 314) '1': u8
753[316; 317) '2': u8 753[316; 317) '2': u8
754[319; 320) '3': u8"### 754[319; 320) '3': u8"###
@@ -1553,7 +1553,7 @@ fn test() {
1553[11; 48) '{ ...&y]; }': () 1553[11; 48) '{ ...&y]; }': ()
1554[21; 22) 'y': &{unknown} 1554[21; 22) 'y': &{unknown}
1555[25; 32) 'unknown': &{unknown} 1555[25; 32) 'unknown': &{unknown}
1556[38; 45) '[y, &y]': [&&{unknown}] 1556[38; 45) '[y, &y]': [&&{unknown};_]
1557[39; 40) 'y': &{unknown} 1557[39; 40) 'y': &{unknown}
1558[42; 44) '&y': &&{unknown} 1558[42; 44) '&y': &&{unknown}
1559[43; 44) 'y': &{unknown}"### 1559[43; 44) 'y': &{unknown}"###
@@ -1578,7 +1578,7 @@ fn test() {
1578[25; 32) 'unknown': &&{unknown} 1578[25; 32) 'unknown': &&{unknown}
1579[42; 43) 'y': &&{unknown} 1579[42; 43) 'y': &&{unknown}
1580[46; 53) 'unknown': &&{unknown} 1580[46; 53) 'unknown': &&{unknown}
1581[59; 77) '[(x, y..., &x)]': [(&&{unknown}, &&{unknown})] 1581[59; 77) '[(x, y..., &x)]': [(&&{unknown}, &&{unknown});_]
1582[60; 66) '(x, y)': (&&{unknown}, &&{unknown}) 1582[60; 66) '(x, y)': (&&{unknown}, &&{unknown})
1583[61; 62) 'x': &&{unknown} 1583[61; 62) 'x': &&{unknown}
1584[64; 65) 'y': &&{unknown} 1584[64; 65) 'y': &&{unknown}
@@ -1670,8 +1670,8 @@ fn test_line_buffer() {
1670"#), 1670"#),
1671 @r###" 1671 @r###"
1672[23; 53) '{ ...n']; }': () 1672[23; 53) '{ ...n']; }': ()
1673[29; 50) '&[0, b...b'\n']': &[u8] 1673[29; 50) '&[0, b...b'\n']': &[u8;_]
1674[30; 50) '[0, b'...b'\n']': [u8] 1674[30; 50) '[0, b'...b'\n']': [u8;_]
1675[31; 32) '0': u8 1675[31; 32) '0': u8
1676[34; 39) 'b'\n'': u8 1676[34; 39) 'b'\n'': u8
1677[41; 42) '1': u8 1677[41; 42) '1': u8
@@ -2242,6 +2242,65 @@ static B: u64 = { let x = 1; x };
2242 ); 2242 );
2243} 2243}
2244 2244
2245#[test]
2246fn tuple_struct_fields() {
2247 assert_snapshot_matches!(
2248 infer(r#"
2249struct S(i32, u64);
2250fn test() -> u64 {
2251 let a = S(4, 6);
2252 let b = a.0;
2253 a.1
2254}
2255"#),
2256 @r###"
2257[38; 87) '{ ... a.1 }': u64
2258[48; 49) 'a': S
2259[52; 53) 'S': S(i32, u64) -> S
2260[52; 59) 'S(4, 6)': S
2261[54; 55) '4': i32
2262[57; 58) '6': u64
2263[69; 70) 'b': i32
2264[73; 74) 'a': S
2265[73; 76) 'a.0': i32
2266[82; 83) 'a': S
2267[82; 85) 'a.1': u64"###
2268 );
2269}
2270
2271#[test]
2272fn tuple_struct_with_fn() {
2273 assert_snapshot_matches!(
2274 infer(r#"
2275struct S(fn(u32) -> u64);
2276fn test() -> u64 {
2277 let a = S(|i| 2*i);
2278 let b = a.0(4);
2279 a.0(2)
2280}
2281"#),
2282 @r###"
2283[44; 102) '{ ...0(2) }': u64
2284[54; 55) 'a': S
2285[58; 59) 'S': S(fn(u32) -> u64) -> S
2286[58; 68) 'S(|i| 2*i)': S
2287[60; 67) '|i| 2*i': fn(u32) -> u64
2288[61; 62) 'i': i32
2289[64; 65) '2': i32
2290[64; 67) '2*i': i32
2291[66; 67) 'i': i32
2292[78; 79) 'b': u64
2293[82; 83) 'a': S
2294[82; 85) 'a.0': fn(u32) -> u64
2295[82; 88) 'a.0(4)': u64
2296[86; 87) '4': u32
2297[94; 95) 'a': S
2298[94; 97) 'a.0': fn(u32) -> u64
2299[94; 100) 'a.0(2)': u64
2300[98; 99) '2': u32"###
2301 );
2302}
2303
2245fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 2304fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
2246 let func = source_binder::function_from_position(db, pos).unwrap(); 2305 let func = source_binder::function_from_position(db, pos).unwrap();
2247 let body_source_map = func.body_source_map(db); 2306 let body_source_map = func.body_source_map(db);