diff options
author | robojumper <[email protected]> | 2019-04-05 21:34:45 +0100 |
---|---|---|
committer | robojumper <[email protected]> | 2019-04-06 00:07:35 +0100 |
commit | ca40ca93a55ffa08d3e699fc877e7e189b526c66 (patch) | |
tree | 8b56a9250db5c713da3fc14758c0583bbb029638 /crates/ra_hir | |
parent | 0372eca5b2e6dade5132a08db46992ca73a25188 (diff) |
Parse and infer tuple indices
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 59 |
3 files changed, 72 insertions, 1 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index b2a237ece..cfa824458 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -671,7 +671,10 @@ impl ExprCollector { | |||
671 | } | 671 | } |
672 | ast::ExprKind::FieldExpr(e) => { | 672 | ast::ExprKind::FieldExpr(e) => { |
673 | let expr = self.collect_expr_opt(e.expr()); | 673 | let expr = self.collect_expr_opt(e.expr()); |
674 | let name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 674 | let name = match e.field_access() { |
675 | Some(kind) => kind.as_name(), | ||
676 | _ => Name::missing(), | ||
677 | }; | ||
675 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) | 678 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) |
676 | } | 679 | } |
677 | ast::ExprKind::TryExpr(e) => { | 680 | ast::ExprKind::TryExpr(e) => { |
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 | ||
93 | impl<'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 | |||
93 | impl AsName for ra_db::Dependency { | 102 | impl 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/tests.rs b/crates/ra_hir/src/ty/tests.rs index 0b7c841df..f0164f7ea 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2242,6 +2242,65 @@ static B: u64 = { let x = 1; x }; | |||
2242 | ); | 2242 | ); |
2243 | } | 2243 | } |
2244 | 2244 | ||
2245 | #[test] | ||
2246 | fn tuple_struct_fields() { | ||
2247 | assert_snapshot_matches!( | ||
2248 | infer(r#" | ||
2249 | struct S(i32, u64); | ||
2250 | fn 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] | ||
2272 | fn tuple_struct_with_fn() { | ||
2273 | assert_snapshot_matches!( | ||
2274 | infer(r#" | ||
2275 | struct S(fn(u32) -> u64); | ||
2276 | fn 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 | |||
2245 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2304 | fn 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); |