aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-30 20:51:47 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-30 20:51:47 +0000
commit28fdb8d03caf1ab8b40ed0fcbe8e47451fe030d9 (patch)
treea795362bb8cd25edb87e8da3f9786d68e029c22b /crates
parentdb17e06c2eec892ab807fd191bc11b15d8da42e2 (diff)
parent13cb4a1b370038dee51ae739a42d6b98acaef385 (diff)
Merge #701
701: Minor type inference tweaks r=flodiebold a=marcusklaas Pass down expectation for reference expressions and type the guard in match expressions. I wasn't able to add a test for the former addition because the type variable previously introduced would always resolve to the right type in the things I tried! Co-authored-by: Marcus Klaas de Vries <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/expr.rs8
-rw-r--r--crates/ra_hir/src/ty.rs16
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap23
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_array.snap14
-rw-r--r--crates/ra_hir/src/ty/tests.rs4
-rw-r--r--crates/ra_syntax/src/ast/generated.rs6
-rw-r--r--crates/ra_syntax/src/grammar.ron2
-rw-r--r--crates/ra_syntax/src/grammar/expressions/atom.rs18
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0066_match_arm.txt83
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.txt47
11 files changed, 163 insertions, 63 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 83e913e4a..37aa24677 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -219,7 +219,7 @@ pub use ra_syntax::ast::BinOp as BinaryOp;
219#[derive(Debug, Clone, Eq, PartialEq)] 219#[derive(Debug, Clone, Eq, PartialEq)]
220pub struct MatchArm { 220pub struct MatchArm {
221 pub pats: Vec<PatId>, 221 pub pats: Vec<PatId>,
222 // guard: Option<ExprId>, // TODO 222 pub guard: Option<ExprId>,
223 pub expr: ExprId, 223 pub expr: ExprId,
224} 224}
225 225
@@ -515,10 +515,12 @@ impl ExprCollector {
515 MatchArm { 515 MatchArm {
516 pats: vec![pat], 516 pats: vec![pat],
517 expr: then_branch, 517 expr: then_branch,
518 guard: None,
518 }, 519 },
519 MatchArm { 520 MatchArm {
520 pats: vec![placeholder_pat], 521 pats: vec![placeholder_pat],
521 expr: else_branch, 522 expr: else_branch,
523 guard: None,
522 }, 524 },
523 ]; 525 ];
524 self.alloc_expr( 526 self.alloc_expr(
@@ -617,6 +619,10 @@ impl ExprCollector {
617 .map(|arm| MatchArm { 619 .map(|arm| MatchArm {
618 pats: arm.pats().map(|p| self.collect_pat(p)).collect(), 620 pats: arm.pats().map(|p| self.collect_pat(p)).collect(),
619 expr: self.collect_expr_opt(arm.expr()), 621 expr: self.collect_expr_opt(arm.expr()),
622 guard: arm
623 .guard()
624 .and_then(|guard| guard.expr())
625 .map(|e| self.collect_expr(e)),
620 }) 626 })
621 .collect() 627 .collect()
622 } else { 628 } else {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 0472414a6..60c231e82 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -1488,7 +1488,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1488 for &pat in &arm.pats { 1488 for &pat in &arm.pats {
1489 let _pat_ty = self.infer_pat(pat, &input_ty); 1489 let _pat_ty = self.infer_pat(pat, &input_ty);
1490 } 1490 }
1491 // TODO type the guard 1491 if let Some(guard_expr) = arm.guard {
1492 self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool));
1493 }
1492 self.infer_expr(arm.expr, &expected); 1494 self.infer_expr(arm.expr, &expected);
1493 } 1495 }
1494 1496
@@ -1561,9 +1563,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1561 cast_ty 1563 cast_ty
1562 } 1564 }
1563 Expr::Ref { expr, mutability } => { 1565 Expr::Ref { expr, mutability } => {
1564 // TODO pass the expectation down 1566 let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty {
1565 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 1567 if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared {
1568 // TODO: throw type error - expected mut reference but found shared ref,
1569 // which cannot be coerced
1570 }
1571 Expectation::has_type((**subty).clone())
1572 } else {
1573 Expectation::none()
1574 };
1566 // TODO reference coercions etc. 1575 // TODO reference coercions etc.
1576 let inner_ty = self.infer_expr(*expr, &expectation);
1567 Ty::Ref(Arc::new(inner_ty), *mutability) 1577 Ty::Ref(Arc::new(inner_ty), *mutability)
1568 } 1578 }
1569 Expr::UnaryOp { expr, op } => { 1579 Expr::UnaryOp { expr, op } => {
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
index 2719f592e..48c83cbb2 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_adt_pattern.snap
@@ -1,10 +1,10 @@
1--- 1---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-28T21:58:55.559331849+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[68; 262) '{ ... d; }': () 7[68; 289) '{ ... d; }': ()
8[78; 79) 'e': E 8[78; 79) 'e': E
9[82; 95) 'E::A { x: 3 }': E 9[82; 95) 'E::A { x: 3 }': E
10[92; 93) '3': usize 10[92; 93) '3': usize
@@ -15,15 +15,18 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
15[129; 148) 'E::A {..._var }': E 15[129; 148) 'E::A {..._var }': E
16[139; 146) 'new_var': usize 16[139; 146) 'new_var': usize
17[151; 152) 'e': E 17[151; 152) 'e': E
18[159; 218) 'match ... }': usize 18[159; 245) 'match ... }': usize
19[165; 166) 'e': E 19[165; 166) 'e': E
20[177; 187) 'E::A { x }': E 20[177; 187) 'E::A { x }': E
21[184; 185) 'x': usize 21[184; 185) 'x': usize
22[191; 192) 'x': usize 22[191; 192) 'x': usize
23[202; 206) 'E::B': E 23[202; 206) 'E::B': E
24[210; 211) '1': usize 24[210; 213) 'foo': bool
25[229; 248) 'ref d ...{ .. }': &E 25[217; 218) '1': usize
26[237; 248) 'E::A { .. }': E 26[228; 232) 'E::B': E
27[251; 252) 'e': E 27[236; 238) '10': usize
28[258; 259) 'd': &E 28[256; 275) 'ref d ...{ .. }': &E
29[264; 275) 'E::A { .. }': E
30[278; 279) 'e': E
31[285; 286) 'd': &E
29 32
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap
index 3f2faa598..042248c35 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_array.snap
@@ -1,12 +1,12 @@
1--- 1---
2created: "2019-01-22T14:44:59.880187500+00:00" 2created: "2019-01-30T20:08:05.185312835+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: "&result" 4expression: "&result"
5source: "crates\\ra_hir\\src\\ty\\tests.rs" 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[9; 10) 'x': &str 7[9; 10) 'x': &str
8[18; 19) 'y': isize 8[18; 19) 'y': isize
9[28; 293) '{ ... []; }': () 9[28; 324) '{ ... 3]; }': ()
10[38; 39) 'a': [&str] 10[38; 39) 'a': [&str]
11[42; 45) '[x]': [&str] 11[42; 45) '[x]': [&str]
12[43; 44) 'x': &str 12[43; 44) 'x': &str
@@ -56,4 +56,10 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
56[260; 263) '"b"': &str 56[260; 263) '"b"': &str
57[275; 276) 'x': [u8] 57[275; 276) 'x': [u8]
58[288; 290) '[]': [u8] 58[288; 290) '[]': [u8]
59[300; 301) 'z': &[u8]
60[311; 321) '&[1, 2, 3]': &[u8]
61[312; 321) '[1, 2, 3]': [u8]
62[313; 314) '1': u8
63[316; 317) '2': u8
64[319; 320) '3': u8
59 65
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index b36e6ec47..cb8d6351d 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -371,6 +371,7 @@ fn test(x: &str, y: isize) {
371 371
372 let b = [a, ["b"]]; 372 let b = [a, ["b"]];
373 let x: [u8; 0] = []; 373 let x: [u8; 0] = [];
374 let z: &[u8] = &[1, 2, 3];
374} 375}
375"#, 376"#,
376 ); 377 );
@@ -426,7 +427,8 @@ fn test() {
426 427
427 match e { 428 match e {
428 E::A { x } => x, 429 E::A { x } => x,
429 E::B => 1, 430 E::B if foo => 1,
431 E::B => 10,
430 }; 432 };
431 433
432 let ref d @ E::A { .. } = e; 434 let ref d @ E::A { .. } = e;
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 3ace6533c..4f5a96014 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1981,7 +1981,11 @@ impl ToOwned for MatchGuard {
1981} 1981}
1982 1982
1983 1983
1984impl MatchGuard {} 1984impl MatchGuard {
1985 pub fn expr(&self) -> Option<&Expr> {
1986 super::child_opt(self)
1987 }
1988}
1985 1989
1986// MethodCallExpr 1990// MethodCallExpr
1987#[derive(Debug, PartialEq, Eq, Hash)] 1991#[derive(Debug, PartialEq, Eq, Hash)]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 85fc79038..e4cad4eb3 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -418,7 +418,7 @@ Grammar(
418 ], 418 ],
419 collections: [ [ "pats", "Pat" ] ] 419 collections: [ [ "pats", "Pat" ] ]
420 ), 420 ),
421 "MatchGuard": (), 421 "MatchGuard": (options: ["Expr"]),
422 "StructLit": (options: ["Path", "NamedFieldList", ["spread", "Expr"]]), 422 "StructLit": (options: ["Path", "NamedFieldList", ["spread", "Expr"]]),
423 "NamedFieldList": (collections: [ ["fields", "NamedField"] ]), 423 "NamedFieldList": (collections: [ ["fields", "NamedField"] ]),
424 "NamedField": (options: ["NameRef", "Expr"]), 424 "NamedField": (options: ["NameRef", "Expr"]),
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs
index 6d6d89f70..600774afd 100644
--- a/crates/ra_syntax/src/grammar/expressions/atom.rs
+++ b/crates/ra_syntax/src/grammar/expressions/atom.rs
@@ -360,8 +360,8 @@ fn match_arm(p: &mut Parser) -> BlockLike {
360 while p.eat(PIPE) { 360 while p.eat(PIPE) {
361 patterns::pattern(p); 361 patterns::pattern(p);
362 } 362 }
363 if p.eat(IF_KW) { 363 if p.at(IF_KW) {
364 expr(p); 364 match_guard(p);
365 } 365 }
366 p.expect(FAT_ARROW); 366 p.expect(FAT_ARROW);
367 let ret = expr_stmt(p); 367 let ret = expr_stmt(p);
@@ -369,6 +369,20 @@ fn match_arm(p: &mut Parser) -> BlockLike {
369 ret 369 ret
370} 370}
371 371
372// test match_guard
373// fn foo() {
374// match () {
375// _ if foo => (),
376// }
377// }
378fn match_guard(p: &mut Parser) -> CompletedMarker {
379 assert!(p.at(IF_KW));
380 let m = p.start();
381 p.bump();
382 expr(p);
383 m.complete(p, MATCH_GUARD)
384}
385
372// test block_expr 386// test block_expr
373// fn foo() { 387// fn foo() {
374// {}; 388// {};
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0066_match_arm.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0066_match_arm.txt
index 98e7535a3..b44e61879 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0066_match_arm.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0066_match_arm.txt
@@ -37,32 +37,33 @@ SOURCE_FILE@[0; 167)
37 PLACEHOLDER_PAT@[51; 52) 37 PLACEHOLDER_PAT@[51; 52)
38 UNDERSCORE@[51; 52) 38 UNDERSCORE@[51; 52)
39 WHITESPACE@[52; 53) 39 WHITESPACE@[52; 53)
40 IF_KW@[53; 55) 40 MATCH_GUARD@[53; 77)
41 WHITESPACE@[55; 56) 41 IF_KW@[53; 55)
42 BIN_EXPR@[56; 77) 42 WHITESPACE@[55; 56)
43 PATH_EXPR@[56; 60) 43 BIN_EXPR@[56; 77)
44 PATH@[56; 60) 44 PATH_EXPR@[56; 60)
45 PATH_SEGMENT@[56; 60) 45 PATH@[56; 60)
46 NAME_REF@[56; 60) 46 PATH_SEGMENT@[56; 60)
47 IDENT@[56; 60) "Test" 47 NAME_REF@[56; 60)
48 WHITESPACE@[60; 61) 48 IDENT@[56; 60) "Test"
49 R_ANGLE@[61; 62) 49 WHITESPACE@[60; 61)
50 WHITESPACE@[62; 63) 50 R_ANGLE@[61; 62)
51 STRUCT_LIT@[63; 77) 51 WHITESPACE@[62; 63)
52 PATH@[63; 67) 52 STRUCT_LIT@[63; 77)
53 PATH_SEGMENT@[63; 67) 53 PATH@[63; 67)
54 NAME_REF@[63; 67) 54 PATH_SEGMENT@[63; 67)
55 IDENT@[63; 67) "Test" 55 NAME_REF@[63; 67)
56 NAMED_FIELD_LIST@[67; 77) 56 IDENT@[63; 67) "Test"
57 L_CURLY@[67; 68) 57 NAMED_FIELD_LIST@[67; 77)
58 NAMED_FIELD@[68; 76) 58 L_CURLY@[67; 68)
59 NAME_REF@[68; 73) 59 NAMED_FIELD@[68; 76)
60 IDENT@[68; 73) "field" 60 NAME_REF@[68; 73)
61 COLON@[73; 74) 61 IDENT@[68; 73) "field"
62 WHITESPACE@[74; 75) 62 COLON@[73; 74)
63 LITERAL@[75; 76) 63 WHITESPACE@[74; 75)
64 INT_NUMBER@[75; 76) "0" 64 LITERAL@[75; 76)
65 R_CURLY@[76; 77) 65 INT_NUMBER@[75; 76) "0"
66 R_CURLY@[76; 77)
66 WHITESPACE@[77; 78) 67 WHITESPACE@[77; 78)
67 FAT_ARROW@[78; 80) 68 FAT_ARROW@[78; 80)
68 WHITESPACE@[80; 81) 69 WHITESPACE@[80; 81)
@@ -82,13 +83,14 @@ SOURCE_FILE@[0; 167)
82 NAME@[97; 98) 83 NAME@[97; 98)
83 IDENT@[97; 98) "Y" 84 IDENT@[97; 98) "Y"
84 WHITESPACE@[98; 99) 85 WHITESPACE@[98; 99)
85 IF_KW@[99; 101) 86 MATCH_GUARD@[99; 103)
86 WHITESPACE@[101; 102) 87 IF_KW@[99; 101)
87 PATH_EXPR@[102; 103) 88 WHITESPACE@[101; 102)
88 PATH@[102; 103) 89 PATH_EXPR@[102; 103)
89 PATH_SEGMENT@[102; 103) 90 PATH@[102; 103)
90 NAME_REF@[102; 103) 91 PATH_SEGMENT@[102; 103)
91 IDENT@[102; 103) "Z" 92 NAME_REF@[102; 103)
93 IDENT@[102; 103) "Z"
92 WHITESPACE@[103; 104) 94 WHITESPACE@[103; 104)
93 FAT_ARROW@[104; 106) 95 FAT_ARROW@[104; 106)
94 WHITESPACE@[106; 107) 96 WHITESPACE@[106; 107)
@@ -110,13 +112,14 @@ SOURCE_FILE@[0; 167)
110 NAME@[125; 126) 112 NAME@[125; 126)
111 IDENT@[125; 126) "Y" 113 IDENT@[125; 126) "Y"
112 WHITESPACE@[126; 127) 114 WHITESPACE@[126; 127)
113 IF_KW@[127; 129) 115 MATCH_GUARD@[127; 131)
114 WHITESPACE@[129; 130) 116 IF_KW@[127; 129)
115 PATH_EXPR@[130; 131) 117 WHITESPACE@[129; 130)
116 PATH@[130; 131) 118 PATH_EXPR@[130; 131)
117 PATH_SEGMENT@[130; 131) 119 PATH@[130; 131)
118 NAME_REF@[130; 131) 120 PATH_SEGMENT@[130; 131)
119 IDENT@[130; 131) "Z" 121 NAME_REF@[130; 131)
122 IDENT@[130; 131) "Z"
120 WHITESPACE@[131; 132) 123 WHITESPACE@[131; 132)
121 FAT_ARROW@[132; 134) 124 FAT_ARROW@[132; 134)
122 WHITESPACE@[134; 135) 125 WHITESPACE@[134; 135)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.rs
new file mode 100644
index 000000000..f1bd72fc4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 match () {
3 _ if foo => (),
4 }
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.txt
new file mode 100644
index 000000000..27553882d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0118_match_guard.txt
@@ -0,0 +1,47 @@
1SOURCE_FILE@[0; 58)
2 FN_DEF@[0; 57)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 57)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 MATCH_EXPR@[15; 55)
15 MATCH_KW@[15; 20)
16 WHITESPACE@[20; 21)
17 TUPLE_EXPR@[21; 23)
18 L_PAREN@[21; 22)
19 R_PAREN@[22; 23)
20 WHITESPACE@[23; 24)
21 MATCH_ARM_LIST@[24; 55)
22 L_CURLY@[24; 25)
23 WHITESPACE@[25; 34)
24 MATCH_ARM@[34; 48)
25 PLACEHOLDER_PAT@[34; 35)
26 UNDERSCORE@[34; 35)
27 WHITESPACE@[35; 36)
28 MATCH_GUARD@[36; 42)
29 IF_KW@[36; 38)
30 WHITESPACE@[38; 39)
31 PATH_EXPR@[39; 42)
32 PATH@[39; 42)
33 PATH_SEGMENT@[39; 42)
34 NAME_REF@[39; 42)
35 IDENT@[39; 42) "foo"
36 WHITESPACE@[42; 43)
37 FAT_ARROW@[43; 45)
38 WHITESPACE@[45; 46)
39 TUPLE_EXPR@[46; 48)
40 L_PAREN@[46; 47)
41 R_PAREN@[47; 48)
42 COMMA@[48; 49)
43 WHITESPACE@[49; 54)
44 R_CURLY@[54; 55)
45 WHITESPACE@[55; 56)
46 R_CURLY@[56; 57)
47 WHITESPACE@[57; 58)