@@ -57,7 +57,7 @@ pub(crate) fn goto_definition(
57
57
} ,
58
58
ast:: Name ( name) => {
59
59
let def = NameClass :: classify( & sema, & name) ?. referenced_or_defined( sema. db) ;
60
- try_find_trait_fn_definition ( & sema. db, & def)
60
+ try_find_trait_item_definition ( & sema. db, & def)
61
61
. or_else( || def. try_to_nav( sema. db) )
62
62
} ,
63
63
ast:: Lifetime ( lt) => if let Some ( name_class) = NameClass :: classify_lifetime( & sema, & lt) {
@@ -100,30 +100,32 @@ fn try_lookup_include_path(
100
100
} )
101
101
}
102
102
103
- /// finds the trait definition of an impl'd function
103
+ /// finds the trait definition of an impl'd item
104
104
/// e.g.
105
105
/// ```rust
106
106
/// trait A { fn a(); }
107
107
/// struct S;
108
108
/// impl A for S { fn a(); } // <-- on this function, will get the location of a() in the trait
109
109
/// ```
110
- fn try_find_trait_fn_definition ( db : & RootDatabase , def : & Definition ) -> Option < NavigationTarget > {
111
- match def {
112
- Definition :: ModuleDef ( ModuleDef :: Function ( f) ) => {
113
- let name = def. name ( db) ?;
114
- let assoc = f. as_assoc_item ( db) ?;
115
- let imp = match assoc. container ( db) {
116
- hir:: AssocItemContainer :: Impl ( imp) => imp,
117
- _ => return None ,
118
- } ;
119
- let trait_ = imp. trait_ ( db) ?;
120
- trait_
121
- . items ( db)
122
- . iter ( )
123
- . find_map ( |itm| ( itm. name ( db) ? == name) . then ( || itm. try_to_nav ( db) ) . flatten ( ) )
124
- }
110
+ fn try_find_trait_item_definition ( db : & RootDatabase , def : & Definition ) -> Option < NavigationTarget > {
111
+ let name = def. name ( db) ?;
112
+ let assoc = match def {
113
+ Definition :: ModuleDef ( ModuleDef :: Function ( f) ) => f. as_assoc_item ( db) ,
114
+ Definition :: ModuleDef ( ModuleDef :: Const ( c) ) => c. as_assoc_item ( db) ,
115
+ Definition :: ModuleDef ( ModuleDef :: TypeAlias ( ty) ) => ty. as_assoc_item ( db) ,
125
116
_ => None ,
126
- }
117
+ } ?;
118
+
119
+ let imp = match assoc. container ( db) {
120
+ hir:: AssocItemContainer :: Impl ( imp) => imp,
121
+ _ => return None ,
122
+ } ;
123
+
124
+ let trait_ = imp. trait_ ( db) ?;
125
+ trait_
126
+ . items ( db)
127
+ . iter ( )
128
+ . find_map ( |itm| ( itm. name ( db) ? == name) . then ( || itm. try_to_nav ( db) ) . flatten ( ) )
127
129
}
128
130
129
131
fn pick_best ( tokens : TokenAtOffset < SyntaxToken > ) -> Option < SyntaxToken > {
@@ -1304,6 +1306,42 @@ struct Stwuct;
1304
1306
impl Twait for Stwuct {
1305
1307
fn a$0();
1306
1308
}
1309
+ "# ,
1310
+ ) ;
1311
+ }
1312
+
1313
+ #[ test]
1314
+ fn goto_def_of_trait_impl_const ( ) {
1315
+ check (
1316
+ r#"
1317
+ trait Twait {
1318
+ const NOMS: bool;
1319
+ // ^^^^
1320
+ }
1321
+
1322
+ struct Stwuct;
1323
+
1324
+ impl Twait for Stwuct {
1325
+ const NOMS$0: bool = true;
1326
+ }
1327
+ "# ,
1328
+ ) ;
1329
+ }
1330
+
1331
+ #[ test]
1332
+ fn goto_def_of_trait_impl_type_alias ( ) {
1333
+ check (
1334
+ r#"
1335
+ trait Twait {
1336
+ type IsBad;
1337
+ // ^^^^^
1338
+ }
1339
+
1340
+ struct Stwuct;
1341
+
1342
+ impl Twait for Stwuct {
1343
+ type IsBad$0 = !;
1344
+ }
1307
1345
"# ,
1308
1346
) ;
1309
1347
}
0 commit comments