aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-16 15:11:19 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-16 15:11:19 +0000
commit454cc313589fb17de92d6f3dbf576a5ea5f4adf2 (patch)
treee67129e4e514e140463d8f0f7bd7556793cac484 /crates/ra_hir/src
parentd75a0368f5048243d6561e42e77835f6f574b321 (diff)
parent0aedd4fb2f28ec24902d26c7d8a24d6146263d2f (diff)
Merge #524
524: Implement array inference r=flodiebold a=h-michael related #394 Co-authored-by: Hirokazu Hata <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs10
-rw-r--r--crates/ra_hir/src/ty.rs26
-rw-r--r--crates/ra_hir/src/ty/tests.rs26
-rw-r--r--crates/ra_hir/src/ty/tests/data/array.txt52
4 files changed, 107 insertions, 7 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 663338844..6e98ebc69 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -197,6 +197,9 @@ pub enum Expr {
197 Tuple { 197 Tuple {
198 exprs: Vec<ExprId>, 198 exprs: Vec<ExprId>,
199 }, 199 },
200 Array {
201 exprs: Vec<ExprId>,
202 },
200 Literal(Literal), 203 Literal(Literal),
201} 204}
202 205
@@ -312,7 +315,7 @@ impl Expr {
312 | Expr::UnaryOp { expr, .. } => { 315 | Expr::UnaryOp { expr, .. } => {
313 f(*expr); 316 f(*expr);
314 } 317 }
315 Expr::Tuple { exprs } => { 318 Expr::Tuple { exprs } | Expr::Array { exprs } => {
316 for expr in exprs { 319 for expr in exprs {
317 f(*expr); 320 f(*expr);
318 } 321 }
@@ -649,6 +652,10 @@ impl ExprCollector {
649 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); 652 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
650 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) 653 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
651 } 654 }
655 ast::ExprKind::ArrayExpr(e) => {
656 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
657 self.alloc_expr(Expr::Array { exprs }, syntax_ptr)
658 }
652 ast::ExprKind::Literal(e) => { 659 ast::ExprKind::Literal(e) => {
653 let child = if let Some(child) = e.literal_expr() { 660 let child = if let Some(child) = e.literal_expr() {
654 child 661 child
@@ -691,7 +698,6 @@ impl ExprCollector {
691 // TODO implement HIR for these: 698 // TODO implement HIR for these:
692 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 699 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
693 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 700 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
694 ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
695 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 701 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
696 } 702 }
697 } 703 }
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 85d4dc05c..c7c063601 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -181,11 +181,12 @@ pub enum Ty {
181 /// The pointee of a string slice. Written as `str`. 181 /// The pointee of a string slice. Written as `str`.
182 Str, 182 Str,
183 183
184 // An array with the given length. Written as `[T; n]`.
185 // Array(Ty, ty::Const),
186 /// The pointee of an array slice. Written as `[T]`. 184 /// The pointee of an array slice. Written as `[T]`.
187 Slice(Arc<Ty>), 185 Slice(Arc<Ty>),
188 186
187 // An array with the given length. Written as `[T; n]`.
188 Array(Arc<Ty>),
189
189 /// A raw pointer. Written as `*mut T` or `*const T` 190 /// A raw pointer. Written as `*mut T` or `*const T`
190 RawPtr(Arc<Ty>, Mutability), 191 RawPtr(Arc<Ty>, Mutability),
191 192
@@ -276,7 +277,10 @@ impl Ty {
276 let inner_ty = Ty::from_hir(db, module, impl_block, inner); 277 let inner_ty = Ty::from_hir(db, module, impl_block, inner);
277 Ty::RawPtr(Arc::new(inner_ty), *mutability) 278 Ty::RawPtr(Arc::new(inner_ty), *mutability)
278 } 279 }
279 TypeRef::Array(_inner) => Ty::Unknown, // TODO 280 TypeRef::Array(inner) => {
281 let inner_ty = Ty::from_hir(db, module, impl_block, inner);
282 Ty::Array(Arc::new(inner_ty))
283 }
280 TypeRef::Slice(inner) => { 284 TypeRef::Slice(inner) => {
281 let inner_ty = Ty::from_hir(db, module, impl_block, inner); 285 let inner_ty = Ty::from_hir(db, module, impl_block, inner);
282 Ty::Slice(Arc::new(inner_ty)) 286 Ty::Slice(Arc::new(inner_ty))
@@ -352,7 +356,7 @@ impl Ty {
352 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 356 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
353 f(self); 357 f(self);
354 match self { 358 match self {
355 Ty::Slice(t) => Arc::make_mut(t).walk_mut(f), 359 Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f),
356 Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f), 360 Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f),
357 Ty::Ref(t, _) => Arc::make_mut(t).walk_mut(f), 361 Ty::Ref(t, _) => Arc::make_mut(t).walk_mut(f),
358 Ty::Tuple(ts) => { 362 Ty::Tuple(ts) => {
@@ -400,7 +404,7 @@ impl fmt::Display for Ty {
400 Ty::Int(t) => write!(f, "{}", t.ty_to_string()), 404 Ty::Int(t) => write!(f, "{}", t.ty_to_string()),
401 Ty::Float(t) => write!(f, "{}", t.ty_to_string()), 405 Ty::Float(t) => write!(f, "{}", t.ty_to_string()),
402 Ty::Str => write!(f, "str"), 406 Ty::Str => write!(f, "str"),
403 Ty::Slice(t) => write!(f, "[{}]", t), 407 Ty::Slice(t) | Ty::Array(t) => write!(f, "[{}]", t),
404 Ty::RawPtr(t, m) => write!(f, "*{}{}", m.as_keyword_for_ptr(), t), 408 Ty::RawPtr(t, m) => write!(f, "*{}{}", m.as_keyword_for_ptr(), t),
405 Ty::Ref(t, m) => write!(f, "&{}{}", m.as_keyword_for_ref(), t), 409 Ty::Ref(t, m) => write!(f, "&{}{}", m.as_keyword_for_ref(), t),
406 Ty::Never => write!(f, "!"), 410 Ty::Never => write!(f, "!"),
@@ -1102,6 +1106,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1102 1106
1103 Ty::Tuple(Arc::from(ty_vec)) 1107 Ty::Tuple(Arc::from(ty_vec))
1104 } 1108 }
1109 Expr::Array { exprs } => {
1110 let elem_ty = match &expected.ty {
1111 Ty::Slice(inner) | Ty::Array(inner) => Ty::clone(&inner),
1112 _ => self.new_type_var(),
1113 };
1114
1115 for expr in exprs.iter() {
1116 self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
1117 }
1118
1119 Ty::Array(Arc::new(elem_ty))
1120 }
1105 Expr::Literal(lit) => match lit { 1121 Expr::Literal(lit) => match lit {
1106 Literal::Bool(..) => Ty::Bool, 1122 Literal::Bool(..) => Ty::Bool,
1107 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared), 1123 Literal::String(..) => Ty::Ref(Arc::new(Ty::Str), Mutability::Shared),
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 5d7bc25cc..affd63a85 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -334,6 +334,32 @@ fn test(x: &str, y: isize) {
334 ); 334 );
335} 335}
336 336
337#[test]
338fn infer_array() {
339 check_inference(
340 r#"
341fn test(x: &str, y: isize) {
342 let a = [x];
343 let b = [a, a];
344 let c = [b, b];
345
346 let d = [y, 1, 2, 3];
347 let d = [1, y, 2, 3];
348 let e = [y];
349 let f = [d, d];
350 let g = [e, e];
351
352 let h = [1, 2];
353 let i = ["a", "b"];
354
355 let b = [a, ["b"]];
356 let x: [u8; 0] = [];
357}
358"#,
359 "array.txt",
360 );
361}
362
337fn infer(content: &str) -> String { 363fn infer(content: &str) -> String {
338 let (db, _, file_id) = MockDatabase::with_single_file(content); 364 let (db, _, file_id) = MockDatabase::with_single_file(content);
339 let source_file = db.source_file(file_id); 365 let source_file = db.source_file(file_id);
diff --git a/crates/ra_hir/src/ty/tests/data/array.txt b/crates/ra_hir/src/ty/tests/data/array.txt
new file mode 100644
index 000000000..acdf74ba4
--- /dev/null
+++ b/crates/ra_hir/src/ty/tests/data/array.txt
@@ -0,0 +1,52 @@
1[9; 10) 'x': &str
2[18; 19) 'y': isize
3[28; 293) '{ ... []; }': ()
4[38; 39) 'a': [&str]
5[42; 45) '[x]': [&str]
6[43; 44) 'x': &str
7[55; 56) 'b': [[&str]]
8[59; 65) '[a, a]': [[&str]]
9[60; 61) 'a': [&str]
10[63; 64) 'a': [&str]
11[75; 76) 'c': [[[&str]]]
12[79; 85) '[b, b]': [[[&str]]]
13[80; 81) 'b': [[&str]]
14[83; 84) 'b': [[&str]]
15[96; 97) 'd': [isize]
16[100; 112) '[y, 1, 2, 3]': [isize]
17[101; 102) 'y': isize
18[104; 105) '1': isize
19[107; 108) '2': isize
20[110; 111) '3': isize
21[122; 123) 'd': [isize]
22[126; 138) '[1, y, 2, 3]': [isize]
23[127; 128) '1': isize
24[130; 131) 'y': isize
25[133; 134) '2': isize
26[136; 137) '3': isize
27[148; 149) 'e': [isize]
28[152; 155) '[y]': [isize]
29[153; 154) 'y': isize
30[165; 166) 'f': [[isize]]
31[169; 175) '[d, d]': [[isize]]
32[170; 171) 'd': [isize]
33[173; 174) 'd': [isize]
34[185; 186) 'g': [[isize]]
35[189; 195) '[e, e]': [[isize]]
36[190; 191) 'e': [isize]
37[193; 194) 'e': [isize]
38[206; 207) 'h': [i32]
39[210; 216) '[1, 2]': [i32]
40[211; 212) '1': i32
41[214; 215) '2': i32
42[226; 227) 'i': [&str]
43[230; 240) '["a", "b"]': [&str]
44[231; 234) '"a"': &str
45[236; 239) '"b"': &str
46[251; 252) 'b': [[&str]]
47[255; 265) '[a, ["b"]]': [[&str]]
48[256; 257) 'a': [&str]
49[259; 264) '["b"]': [&str]
50[260; 263) '"b"': &str
51[275; 276) 'x': [u8]
52[288; 290) '[]': [u8]