diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_ty/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ide/src/goto_type_definition.rs | 62 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 4 |
3 files changed, 63 insertions, 5 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index a1894e8d8..74129eb21 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -20,7 +20,7 @@ rustc-hash = "1.1.0" | |||
20 | scoped-tls = "1" | 20 | scoped-tls = "1" |
21 | chalk-solve = { version = "0.68", default-features = false } | 21 | chalk-solve = { version = "0.68", default-features = false } |
22 | chalk-ir = "0.68" | 22 | chalk-ir = "0.68" |
23 | chalk-recursive = "0.68" | 23 | chalk-recursive = { version = "0.68", default-features = false } |
24 | la-arena = { version = "0.2.0", path = "../../lib/arena" } | 24 | la-arena = { version = "0.2.0", path = "../../lib/arena" } |
25 | once_cell = { version = "1.5.0" } | 25 | once_cell = { version = "1.5.0" } |
26 | 26 | ||
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index 004d9cb68..ca3c02bf6 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs | |||
@@ -25,7 +25,7 @@ pub(crate) fn goto_type_definition( | |||
25 | let token: SyntaxToken = pick_best(file.syntax().token_at_offset(position.offset))?; | 25 | let token: SyntaxToken = pick_best(file.syntax().token_at_offset(position.offset))?; |
26 | let token: SyntaxToken = sema.descend_into_macros(token); | 26 | let token: SyntaxToken = sema.descend_into_macros(token); |
27 | 27 | ||
28 | let (ty, node) = sema.token_ancestors_with_macros(token).find_map(|node| { | 28 | let (ty, node) = sema.token_ancestors_with_macros(token.clone()).find_map(|node| { |
29 | let ty = match_ast! { | 29 | let ty = match_ast! { |
30 | match node { | 30 | match node { |
31 | ast::Expr(it) => sema.type_of_expr(&it)?, | 31 | ast::Expr(it) => sema.type_of_expr(&it)?, |
@@ -33,13 +33,23 @@ pub(crate) fn goto_type_definition( | |||
33 | ast::SelfParam(it) => sema.type_of_self(&it)?, | 33 | ast::SelfParam(it) => sema.type_of_self(&it)?, |
34 | ast::Type(it) => sema.resolve_type(&it)?, | 34 | ast::Type(it) => sema.resolve_type(&it)?, |
35 | ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?, | 35 | ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?, |
36 | ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?, | ||
37 | // can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise | ||
38 | ast::NameRef(it) => { | ||
39 | if let Some(record_field) = ast::RecordExprField::for_name_ref(&it) { | ||
40 | let (_, _, ty) = sema.resolve_record_field(&record_field)?; | ||
41 | ty | ||
42 | } else { | ||
43 | let record_field = ast::RecordPatField::for_field_name_ref(&it)?; | ||
44 | sema.resolve_record_pat_field(&record_field)?.ty(db) | ||
45 | } | ||
46 | }, | ||
36 | _ => return None, | 47 | _ => return None, |
37 | } | 48 | } |
38 | }; | 49 | }; |
39 | 50 | ||
40 | Some((ty, node)) | 51 | Some((ty, node)) |
41 | })?; | 52 | })?; |
42 | |||
43 | let adt_def = ty.autoderef(db).filter_map(|ty| ty.as_adt()).last()?; | 53 | let adt_def = ty.autoderef(db).filter_map(|ty| ty.as_adt()).last()?; |
44 | 54 | ||
45 | let nav = adt_def.try_to_nav(db)?; | 55 | let nav = adt_def.try_to_nav(db)?; |
@@ -88,6 +98,54 @@ fn foo() { | |||
88 | } | 98 | } |
89 | 99 | ||
90 | #[test] | 100 | #[test] |
101 | fn goto_type_definition_record_expr_field() { | ||
102 | check( | ||
103 | r#" | ||
104 | struct Bar; | ||
105 | // ^^^ | ||
106 | struct Foo { foo: Bar } | ||
107 | fn foo() { | ||
108 | Foo { foo$0 } | ||
109 | } | ||
110 | "#, | ||
111 | ); | ||
112 | check( | ||
113 | r#" | ||
114 | struct Bar; | ||
115 | // ^^^ | ||
116 | struct Foo { foo: Bar } | ||
117 | fn foo() { | ||
118 | Foo { foo$0: Bar } | ||
119 | } | ||
120 | "#, | ||
121 | ); | ||
122 | } | ||
123 | |||
124 | #[test] | ||
125 | fn goto_type_definition_record_pat_field() { | ||
126 | check( | ||
127 | r#" | ||
128 | struct Bar; | ||
129 | // ^^^ | ||
130 | struct Foo { foo: Bar } | ||
131 | fn foo() { | ||
132 | let Foo { foo$0 }; | ||
133 | } | ||
134 | "#, | ||
135 | ); | ||
136 | check( | ||
137 | r#" | ||
138 | struct Bar; | ||
139 | // ^^^ | ||
140 | struct Foo { foo: Bar } | ||
141 | fn foo() { | ||
142 | let Foo { foo$0: bar }; | ||
143 | } | ||
144 | "#, | ||
145 | ); | ||
146 | } | ||
147 | |||
148 | #[test] | ||
91 | fn goto_type_definition_works_simple_ref() { | 149 | fn goto_type_definition_works_simple_ref() { |
92 | check( | 150 | check( |
93 | r#" | 151 | r#" |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3b20d741a..5588c15da 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -1062,8 +1062,8 @@ mod tests { | |||
1062 | let package_json_path = project_root().join("editors/code/package.json"); | 1062 | let package_json_path = project_root().join("editors/code/package.json"); |
1063 | let mut package_json = fs::read_to_string(&package_json_path).unwrap(); | 1063 | let mut package_json = fs::read_to_string(&package_json_path).unwrap(); |
1064 | 1064 | ||
1065 | let start_marker = " \"$generated-start\": false,\n"; | 1065 | let start_marker = " \"$generated-start\": {},\n"; |
1066 | let end_marker = " \"$generated-end\": false\n"; | 1066 | let end_marker = " \"$generated-end\": {}\n"; |
1067 | 1067 | ||
1068 | let start = package_json.find(start_marker).unwrap() + start_marker.len(); | 1068 | let start = package_json.find(start_marker).unwrap() + start_marker.len(); |
1069 | let end = package_json.find(end_marker).unwrap(); | 1069 | let end = package_json.find(end_marker).unwrap(); |