@@ -4,7 +4,9 @@ use std::{
4
4
} ;
5
5
6
6
use either:: Either ;
7
- use hir:: { known, HasVisibility , HirDisplay , HirWrite , ModuleDef , ModuleDefId , Semantics } ;
7
+ use hir:: {
8
+ known, HasVisibility , HirDisplay , HirDisplayError , HirWrite , ModuleDef , ModuleDefId , Semantics ,
9
+ } ;
8
10
use ide_db:: { base_db:: FileRange , famous_defs:: FamousDefs , RootDatabase } ;
9
11
use itertools:: Itertools ;
10
12
use smallvec:: { smallvec, SmallVec } ;
@@ -297,24 +299,35 @@ fn label_of_ty(
297
299
mut max_length : Option < usize > ,
298
300
ty : hir:: Type ,
299
301
label_builder : & mut InlayHintLabelBuilder < ' _ > ,
300
- ) {
302
+ ) -> Result < ( ) , HirDisplayError > {
301
303
let iter_item_type = hint_iterator ( sema, famous_defs, & ty) ;
302
304
match iter_item_type {
303
- Some ( ty) => {
304
- const LABEL_START : & str = "impl Iterator<Item = " ;
305
+ Some ( ( iter_trait, ty) ) => {
306
+ const LABEL_START : & str = "impl " ;
307
+ const LABEL_ITERATOR : & str = "Iterator" ;
308
+ const LABEL_MIDDLE : & str = "<Item = " ;
305
309
const LABEL_END : & str = ">" ;
306
310
307
- max_length =
308
- max_length. map ( |len| len. saturating_sub ( LABEL_START . len ( ) + LABEL_END . len ( ) ) ) ;
309
-
310
- label_builder. write_str ( LABEL_START ) . unwrap ( ) ;
311
- rec ( sema, famous_defs, max_length, ty, label_builder) ;
312
- label_builder. write_str ( LABEL_END ) . unwrap ( ) ;
313
- }
314
- None => {
315
- let _ = ty. display_truncated ( sema. db , max_length) . write_to ( label_builder) ;
311
+ max_length = max_length. map ( |len| {
312
+ len. saturating_sub (
313
+ LABEL_START . len ( )
314
+ + LABEL_ITERATOR . len ( )
315
+ + LABEL_MIDDLE . len ( )
316
+ + LABEL_END . len ( ) ,
317
+ )
318
+ } ) ;
319
+
320
+ label_builder. write_str ( LABEL_START ) ?;
321
+ label_builder. start_location_link ( ModuleDef :: from ( iter_trait) . into ( ) ) ;
322
+ label_builder. write_str ( LABEL_ITERATOR ) ?;
323
+ label_builder. end_location_link ( ) ;
324
+ label_builder. write_str ( LABEL_MIDDLE ) ?;
325
+ rec ( sema, famous_defs, max_length, ty, label_builder) ?;
326
+ label_builder. write_str ( LABEL_END ) ?;
327
+ Ok ( ( ) )
316
328
}
317
- } ;
329
+ None => ty. display_truncated ( sema. db , max_length) . write_to ( label_builder) ,
330
+ }
318
331
}
319
332
320
333
let mut label_builder = InlayHintLabelBuilder {
@@ -324,7 +337,7 @@ fn label_of_ty(
324
337
location_link_enabled : config. location_links ,
325
338
result : InlayHintLabel :: default ( ) ,
326
339
} ;
327
- rec ( sema, famous_defs, config. max_length , ty, & mut label_builder) ;
340
+ let _ = rec ( sema, famous_defs, config. max_length , ty, & mut label_builder) ;
328
341
let r = label_builder. finish ( ) ;
329
342
Some ( r)
330
343
}
@@ -430,12 +443,12 @@ fn hints(
430
443
} ;
431
444
}
432
445
433
- /// Checks if the type is an Iterator from std::iter and returns its item type.
446
+ /// Checks if the type is an Iterator from std::iter and returns the iterator trait and the item type of the concrete iterator .
434
447
fn hint_iterator (
435
448
sema : & Semantics < ' _ , RootDatabase > ,
436
449
famous_defs : & FamousDefs < ' _ , ' _ > ,
437
450
ty : & hir:: Type ,
438
- ) -> Option < hir:: Type > {
451
+ ) -> Option < ( hir:: Trait , hir :: Type ) > {
439
452
let db = sema. db ;
440
453
let strukt = ty. strip_references ( ) . as_adt ( ) ?;
441
454
let krate = strukt. module ( db) . krate ( ) ;
@@ -458,7 +471,7 @@ fn hint_iterator(
458
471
_ => None ,
459
472
} ) ?;
460
473
if let Some ( ty) = ty. normalize_trait_assoc_type ( db, & [ ] , assoc_type_item) {
461
- return Some ( ty ) ;
474
+ return Some ( ( iter_trait , ty ) ) ;
462
475
}
463
476
}
464
477
0 commit comments