Repository: rust-analyzer/rust-analyzer
Pull request #8986 (2021-05-25 11:09:02)

feat: Add go to type definition for struct fields within struct
Example:

```rust
struct A;

struct B {
    a/*<- cursor*/: A,
}
```

Go to type definition used to not work on this position. It now goes to
`A` as expected.


Patch:
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 79a7321060..eab8fac910 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -805,7 +805,7 @@ impl<'a> InferenceContext<'a> {
                     None => self.table.new_float_var(),
                 },
             },
-            Expr::MacroStmts { tail } => self.infer_expr_inner(*tail, expected),
+            Expr::MacroStmts { tail } => self.infer_expr(*tail, expected),
         };
         // use a new type variable if we got unknown here
         let ty = self.insert_type_vars_shallow(ty);
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs
index f3284bb96a..004d9cb688 100644
--- a/crates/ide/src/goto_type_definition.rs
+++ b/crates/ide/src/goto_type_definition.rs
@@ -1,3 +1,4 @@
+use ide_db::base_db::Upcast;
 use ide_db::RootDatabase;
 use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T};
 
@@ -31,6 +32,7 @@ pub(crate) fn goto_type_definition(
                 ast::Pat(it) => sema.type_of_pat(&it)?,
                 ast::SelfParam(it) => sema.type_of_self(&it)?,
                 ast::Type(it) => sema.resolve_type(&it)?,
+                ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?,
                 _ => return None,
             }
         };
@@ -161,4 +163,34 @@ impl Foo$0 {}
 "#,
         )
     }
+
+    #[test]
+    fn goto_def_for_struct_field() {
+        check(
+            r#"
+struct Bar;
+     //^^^
+
+struct Foo {
+    bar$0: Bar,
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn goto_def_for_enum_struct_field() {
+        check(
+            r#"
+struct Bar;
+     //^^^
+
+enum Foo {
+    Bar {
+        bar$0: Bar
+    },
+}
+"#,
+        );
+    }
 }


Test patch:
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index 7e9fc8735b..bb568ea372 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -912,47 +912,3 @@ fn test() -> i32 {
         "#,
     )
 }
-
-#[test]
-fn panic_macro() {
-    check_infer_with_mismatches(
-        r#"
-mod panic {
-    #[macro_export]
-    pub macro panic_2015 {
-        () => (
-            $crate::panicking::panic("explicit panic")
-        ),
-    }
-}
-
-mod panicking {
-    pub fn panic() -> ! { loop {} }
-}
-
-#[rustc_builtin_macro = "core_panic"]
-macro_rules! panic {
-    // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
-    // depending on the edition of the caller.
-    ($($arg:tt)*) => {
-        /* compiler built-in */
-    };
-}
-
-fn main() {
-    panic!("internal error: entered unreachable code")
-}
-        "#,
-        expect![[r#"
-            190..201 '{ loop {} }': !
-            192..199 'loop {}': !
-            197..199 '{}': ()
-            !0..24 '$crate...:panic': fn panic() -> !
-            !0..42 '$crate...anic")': !
-            !0..42 '$crate...anic")': !
-            !0..70 '$crate...code")': !
-            !25..41 '"expli...panic"': &str
-            470..528 '{     ...de") }': ()
-        "#]],
-    );
-}