From ca40ca93a55ffa08d3e699fc877e7e189b526c66 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 5 Apr 2019 22:34:45 +0200 Subject: Parse and infer tuple indices --- crates/ra_hir/src/expr.rs | 5 +++- crates/ra_hir/src/name.rs | 9 +++++++ crates/ra_hir/src/ty/tests.rs | 59 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir') 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 { } ast::ExprKind::FieldExpr(e) => { let expr = self.collect_expr_opt(e.expr()); - let name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); + let name = match e.field_access() { + Some(kind) => kind.as_name(), + _ => Name::missing(), + }; self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) } 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 { } } +impl<'a> AsName for ast::FieldKind<'a> { + fn as_name(&self) -> Name { + match self { + ast::FieldKind::Name(nr) => nr.as_name(), + ast::FieldKind::Index(idx) => Name::new(idx.text().clone()), + } + } +} + impl AsName for ra_db::Dependency { fn as_name(&self) -> Name { 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 }; ); } +#[test] +fn tuple_struct_fields() { + assert_snapshot_matches!( + infer(r#" +struct S(i32, u64); +fn test() -> u64 { + let a = S(4, 6); + let b = a.0; + a.1 +} +"#), + @r###" +[38; 87) '{ ... a.1 }': u64 +[48; 49) 'a': S +[52; 53) 'S': S(i32, u64) -> S +[52; 59) 'S(4, 6)': S +[54; 55) '4': i32 +[57; 58) '6': u64 +[69; 70) 'b': i32 +[73; 74) 'a': S +[73; 76) 'a.0': i32 +[82; 83) 'a': S +[82; 85) 'a.1': u64"### + ); +} + +#[test] +fn tuple_struct_with_fn() { + assert_snapshot_matches!( + infer(r#" +struct S(fn(u32) -> u64); +fn test() -> u64 { + let a = S(|i| 2*i); + let b = a.0(4); + a.0(2) +} +"#), + @r###" +[44; 102) '{ ...0(2) }': u64 +[54; 55) 'a': S +[58; 59) 'S': S(fn(u32) -> u64) -> S +[58; 68) 'S(|i| 2*i)': S +[60; 67) '|i| 2*i': fn(u32) -> u64 +[61; 62) 'i': i32 +[64; 65) '2': i32 +[64; 67) '2*i': i32 +[66; 67) 'i': i32 +[78; 79) 'b': u64 +[82; 83) 'a': S +[82; 85) 'a.0': fn(u32) -> u64 +[82; 88) 'a.0(4)': u64 +[86; 87) '4': u32 +[94; 95) 'a': S +[94; 97) 'a.0': fn(u32) -> u64 +[94; 100) 'a.0(2)': u64 +[98; 99) '2': u32"### + ); +} + fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { let func = source_binder::function_from_position(db, pos).unwrap(); let body_source_map = func.body_source_map(db); -- cgit v1.2.3