@@ -182,16 +182,18 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<Hov
182
182
} )
183
183
}
184
184
185
- match def {
186
- Definition :: ModuleDef ( it) => match it {
187
- ModuleDef :: Adt ( Adt :: Struct ( it) ) => Some ( to_action ( it. try_to_nav ( db) ?) ) ,
188
- ModuleDef :: Adt ( Adt :: Union ( it) ) => Some ( to_action ( it. try_to_nav ( db) ?) ) ,
189
- ModuleDef :: Adt ( Adt :: Enum ( it) ) => Some ( to_action ( it. try_to_nav ( db) ?) ) ,
190
- ModuleDef :: Trait ( it) => Some ( to_action ( it. try_to_nav ( db) ?) ) ,
191
- _ => None ,
192
- } ,
185
+ let adt = match def {
186
+ Definition :: ModuleDef ( ModuleDef :: Trait ( it) ) => return it. try_to_nav ( db) . map ( to_action) ,
187
+ Definition :: ModuleDef ( ModuleDef :: Adt ( it) ) => Some ( it) ,
188
+ Definition :: SelfType ( it) => it. target_ty ( db) . as_adt ( ) ,
193
189
_ => None ,
190
+ } ?;
191
+ match adt {
192
+ Adt :: Struct ( it) => it. try_to_nav ( db) ,
193
+ Adt :: Union ( it) => it. try_to_nav ( db) ,
194
+ Adt :: Enum ( it) => it. try_to_nav ( db) ,
194
195
}
196
+ . map ( to_action)
195
197
}
196
198
197
199
fn runnable_action (
@@ -226,45 +228,46 @@ fn runnable_action(
226
228
}
227
229
228
230
fn goto_type_action ( db : & RootDatabase , def : Definition ) -> Option < HoverAction > {
229
- match def {
230
- Definition :: Local ( it) => {
231
- let mut targets: Vec < ModuleDef > = Vec :: new ( ) ;
232
- let mut push_new_def = |item : ModuleDef | {
233
- if !targets. contains ( & item) {
234
- targets. push ( item) ;
235
- }
236
- } ;
237
-
238
- it. ty ( db) . walk ( db, |t| {
239
- if let Some ( adt) = t. as_adt ( ) {
240
- push_new_def ( adt. into ( ) ) ;
241
- } else if let Some ( trait_) = t. as_dyn_trait ( ) {
242
- push_new_def ( trait_. into ( ) ) ;
243
- } else if let Some ( traits) = t. as_impl_traits ( db) {
244
- traits. into_iter ( ) . for_each ( |it| push_new_def ( it. into ( ) ) ) ;
245
- } else if let Some ( trait_) = t. as_associated_type_parent_trait ( db) {
246
- push_new_def ( trait_. into ( ) ) ;
247
- }
248
- } ) ;
249
-
250
- let targets = targets
251
- . into_iter ( )
252
- . filter_map ( |it| {
253
- Some ( HoverGotoTypeData {
254
- mod_path : render_path (
255
- db,
256
- it. module ( db) ?,
257
- it. name ( db) . map ( |name| name. to_string ( ) ) ,
258
- ) ,
259
- nav : it. try_to_nav ( db) ?,
260
- } )
261
- } )
262
- . collect ( ) ;
263
-
264
- Some ( HoverAction :: GoToType ( targets) )
231
+ let mut targets: Vec < ModuleDef > = Vec :: new ( ) ;
232
+ let mut push_new_def = |item : ModuleDef | {
233
+ if !targets. contains ( & item) {
234
+ targets. push ( item) ;
265
235
}
266
- _ => None ,
236
+ } ;
237
+
238
+ if let Definition :: TypeParam ( it) = def {
239
+ it. trait_bounds ( db) . into_iter ( ) . for_each ( |it| push_new_def ( it. into ( ) ) ) ;
240
+ } else {
241
+ let ty = match def {
242
+ Definition :: Local ( it) => it. ty ( db) ,
243
+ Definition :: ConstParam ( it) => it. ty ( db) ,
244
+ _ => return None ,
245
+ } ;
246
+
247
+ ty. walk ( db, |t| {
248
+ if let Some ( adt) = t. as_adt ( ) {
249
+ push_new_def ( adt. into ( ) ) ;
250
+ } else if let Some ( trait_) = t. as_dyn_trait ( ) {
251
+ push_new_def ( trait_. into ( ) ) ;
252
+ } else if let Some ( traits) = t. as_impl_traits ( db) {
253
+ traits. into_iter ( ) . for_each ( |it| push_new_def ( it. into ( ) ) ) ;
254
+ } else if let Some ( trait_) = t. as_associated_type_parent_trait ( db) {
255
+ push_new_def ( trait_. into ( ) ) ;
256
+ }
257
+ } ) ;
267
258
}
259
+
260
+ let targets = targets
261
+ . into_iter ( )
262
+ . filter_map ( |it| {
263
+ Some ( HoverGotoTypeData {
264
+ mod_path : render_path ( db, it. module ( db) ?, it. name ( db) . map ( |name| name. to_string ( ) ) ) ,
265
+ nav : it. try_to_nav ( db) ?,
266
+ } )
267
+ } )
268
+ . collect ( ) ;
269
+
270
+ Some ( HoverAction :: GoToType ( targets) )
268
271
}
269
272
270
273
fn hover_markup (
@@ -2174,6 +2177,25 @@ fn foo() { let bar = Bar; bar.fo<|>o(); }
2174
2177
) ;
2175
2178
}
2176
2179
2180
+ #[ test]
2181
+ fn test_hover_self_has_impl_action ( ) {
2182
+ check_actions (
2183
+ r#"struct foo where Self<|>:;"# ,
2184
+ expect ! [ [ r#"
2185
+ [
2186
+ Implementation(
2187
+ FilePosition {
2188
+ file_id: FileId(
2189
+ 0,
2190
+ ),
2191
+ offset: 7,
2192
+ },
2193
+ ),
2194
+ ]
2195
+ "# ] ] ,
2196
+ ) ;
2197
+ }
2198
+
2177
2199
#[ test]
2178
2200
fn test_hover_test_has_action ( ) {
2179
2201
check_actions (
@@ -3062,6 +3084,71 @@ fn main() { let s<|>t = test().get(); }
3062
3084
) ;
3063
3085
}
3064
3086
3087
+ #[ test]
3088
+ fn test_hover_const_param_has_goto_type_action ( ) {
3089
+ check_actions (
3090
+ r#"
3091
+ struct Bar;
3092
+ struct Foo<const BAR: Bar>;
3093
+
3094
+ impl<const BAR: Bar> Foo<BAR<|>> {}
3095
+ "# ,
3096
+ expect ! [ [ r#"
3097
+ [
3098
+ GoToType(
3099
+ [
3100
+ HoverGotoTypeData {
3101
+ mod_path: "test::Bar",
3102
+ nav: NavigationTarget {
3103
+ file_id: FileId(
3104
+ 0,
3105
+ ),
3106
+ full_range: 0..11,
3107
+ focus_range: 7..10,
3108
+ name: "Bar",
3109
+ kind: Struct,
3110
+ description: "struct Bar",
3111
+ },
3112
+ },
3113
+ ],
3114
+ ),
3115
+ ]
3116
+ "# ] ] ,
3117
+ ) ;
3118
+ }
3119
+
3120
+ #[ test]
3121
+ fn test_hover_type_param_has_goto_type_action ( ) {
3122
+ check_actions (
3123
+ r#"
3124
+ trait Foo {}
3125
+
3126
+ fn foo<T: Foo>(t: T<|>){}
3127
+ "# ,
3128
+ expect ! [ [ r#"
3129
+ [
3130
+ GoToType(
3131
+ [
3132
+ HoverGotoTypeData {
3133
+ mod_path: "test::Foo",
3134
+ nav: NavigationTarget {
3135
+ file_id: FileId(
3136
+ 0,
3137
+ ),
3138
+ full_range: 0..12,
3139
+ focus_range: 6..9,
3140
+ name: "Foo",
3141
+ kind: Trait,
3142
+ description: "trait Foo",
3143
+ },
3144
+ },
3145
+ ],
3146
+ ),
3147
+ ]
3148
+ "# ] ] ,
3149
+ ) ;
3150
+ }
3151
+
3065
3152
#[ test]
3066
3153
fn hover_displays_normalized_crate_names ( ) {
3067
3154
check (
0 commit comments