@@ -8,6 +8,7 @@ use std::{
8
8
} ;
9
9
10
10
use base_db:: Crate ;
11
+ use bitflags:: bitflags;
11
12
use chalk_ir:: { BoundVar , Safety , TyKind } ;
12
13
use either:: Either ;
13
14
use hir_def:: {
@@ -91,11 +92,26 @@ pub struct HirFormatter<'a> {
91
92
show_container_bounds : bool ,
92
93
omit_verbose_types : bool ,
93
94
closure_style : ClosureStyle ,
95
+ display_lifetimes : DisplayLifetime ,
94
96
display_kind : DisplayKind ,
95
97
display_target : DisplayTarget ,
96
98
bounds_formatting_ctx : BoundsFormattingCtx ,
97
99
}
98
100
101
+ // FIXME: To consider, ref and dyn trait lifetimes can be omitted if they are `'_`, path args should
102
+ // not be when in signatures
103
+ // So this enum does not encode this well enough
104
+ // Also 'static can be omitted for ref and dyn trait lifetimes in static/const item types
105
+ // FIXME: Also named lifetimes may be rendered in places where their name is not in scope?
106
+ #[ derive( Copy , Clone ) ]
107
+ pub enum DisplayLifetime {
108
+ Always ,
109
+ OnlyStatic ,
110
+ OnlyNamed ,
111
+ OnlyNamedOrStatic ,
112
+ Never ,
113
+ }
114
+
99
115
#[ derive( Default ) ]
100
116
enum BoundsFormattingCtx {
101
117
Entered {
@@ -156,6 +172,21 @@ impl HirFormatter<'_> {
156
172
}
157
173
}
158
174
}
175
+
176
+ fn render_lifetime ( & self , lifetime : & Lifetime ) -> bool {
177
+ match self . display_lifetimes {
178
+ DisplayLifetime :: Always => true ,
179
+ DisplayLifetime :: OnlyStatic => matches ! ( * * * lifetime. interned( ) , LifetimeData :: Static ) ,
180
+ DisplayLifetime :: OnlyNamed => {
181
+ matches ! ( * * * lifetime. interned( ) , LifetimeData :: Placeholder ( _) )
182
+ }
183
+ DisplayLifetime :: OnlyNamedOrStatic => matches ! (
184
+ * * * lifetime. interned( ) ,
185
+ LifetimeData :: Static | LifetimeData :: Placeholder ( _)
186
+ ) ,
187
+ DisplayLifetime :: Never => false ,
188
+ }
189
+ }
159
190
}
160
191
161
192
pub trait HirDisplay {
@@ -190,6 +221,7 @@ pub trait HirDisplay {
190
221
display_kind,
191
222
closure_style,
192
223
show_container_bounds,
224
+ display_lifetimes : DisplayLifetime :: OnlyNamedOrStatic ,
193
225
}
194
226
}
195
227
@@ -213,6 +245,7 @@ pub trait HirDisplay {
213
245
display_target,
214
246
display_kind : DisplayKind :: Diagnostics ,
215
247
show_container_bounds : false ,
248
+ display_lifetimes : DisplayLifetime :: OnlyNamedOrStatic ,
216
249
}
217
250
}
218
251
@@ -237,6 +270,7 @@ pub trait HirDisplay {
237
270
display_target,
238
271
display_kind : DisplayKind :: Diagnostics ,
239
272
show_container_bounds : false ,
273
+ display_lifetimes : DisplayLifetime :: OnlyNamedOrStatic ,
240
274
}
241
275
}
242
276
@@ -261,6 +295,7 @@ pub trait HirDisplay {
261
295
display_target,
262
296
display_kind : DisplayKind :: Diagnostics ,
263
297
show_container_bounds : false ,
298
+ display_lifetimes : DisplayLifetime :: OnlyNamedOrStatic ,
264
299
}
265
300
}
266
301
@@ -285,6 +320,7 @@ pub trait HirDisplay {
285
320
display_target : DisplayTarget :: from_crate ( db, module_id. krate ( ) ) ,
286
321
display_kind : DisplayKind :: SourceCode { target_module_id : module_id, allow_opaque } ,
287
322
show_container_bounds : false ,
323
+ display_lifetimes : DisplayLifetime :: OnlyNamedOrStatic ,
288
324
bounds_formatting_ctx : Default :: default ( ) ,
289
325
} ) {
290
326
Ok ( ( ) ) => { }
@@ -313,6 +349,7 @@ pub trait HirDisplay {
313
349
display_target,
314
350
display_kind : DisplayKind :: Test ,
315
351
show_container_bounds : false ,
352
+ display_lifetimes : DisplayLifetime :: Always ,
316
353
}
317
354
}
318
355
@@ -337,6 +374,7 @@ pub trait HirDisplay {
337
374
display_target,
338
375
display_kind : DisplayKind :: Diagnostics ,
339
376
show_container_bounds,
377
+ display_lifetimes : DisplayLifetime :: OnlyNamedOrStatic ,
340
378
}
341
379
}
342
380
}
@@ -481,6 +519,7 @@ pub struct HirDisplayWrapper<'a, T> {
481
519
display_kind : DisplayKind ,
482
520
display_target : DisplayTarget ,
483
521
show_container_bounds : bool ,
522
+ display_lifetimes : DisplayLifetime ,
484
523
}
485
524
486
525
#[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
@@ -503,7 +542,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
503
542
self . t . hir_fmt ( & mut HirFormatter {
504
543
db : self . db ,
505
544
fmt : f,
506
- buf : String :: with_capacity ( 20 ) ,
545
+ buf : String :: with_capacity ( self . max_size . unwrap_or ( 20 ) ) ,
507
546
curr_size : 0 ,
508
547
max_size : self . max_size ,
509
548
entity_limit : self . limited_size ,
@@ -512,6 +551,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
512
551
display_target : self . display_target ,
513
552
closure_style : self . closure_style ,
514
553
show_container_bounds : self . show_container_bounds ,
554
+ display_lifetimes : self . display_lifetimes ,
515
555
bounds_formatting_ctx : Default :: default ( ) ,
516
556
} )
517
557
}
@@ -520,6 +560,11 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
520
560
self . closure_style = c;
521
561
self
522
562
}
563
+
564
+ pub fn with_lifetime_display ( mut self , l : DisplayLifetime ) -> Self {
565
+ self . display_lifetimes = l;
566
+ self
567
+ }
523
568
}
524
569
525
570
impl < T > fmt:: Display for HirDisplayWrapper < ' _ , T >
@@ -1024,9 +1069,7 @@ impl HirDisplay for Ty {
1024
1069
kind @ ( TyKind :: Raw ( m, t) | TyKind :: Ref ( m, _, t) ) => {
1025
1070
if let TyKind :: Ref ( _, l, _) = kind {
1026
1071
f. write_char ( '&' ) ?;
1027
- if cfg ! ( test) {
1028
- // rendering these unconditionally is probably too much (at least for inlay
1029
- // hints) so we gate it to testing only for the time being
1072
+ if f. render_lifetime ( l) {
1030
1073
l. hir_fmt ( f) ?;
1031
1074
f. write_char ( ' ' ) ?;
1032
1075
}
@@ -1057,9 +1100,10 @@ impl HirDisplay for Ty {
1057
1100
} )
1058
1101
} ;
1059
1102
let ( preds_to_print, has_impl_fn_pred) = match t. kind ( Interner ) {
1060
- TyKind :: Dyn ( dyn_ty) if dyn_ty . bounds . skip_binders ( ) . interned ( ) . len ( ) > 1 => {
1103
+ TyKind :: Dyn ( dyn_ty) => {
1061
1104
let bounds = dyn_ty. bounds . skip_binders ( ) . interned ( ) ;
1062
- ( bounds. len ( ) , contains_impl_fn ( bounds) )
1105
+ let render_lifetime = f. render_lifetime ( & dyn_ty. lifetime ) ;
1106
+ ( bounds. len ( ) + render_lifetime as usize , contains_impl_fn ( bounds) )
1063
1107
}
1064
1108
TyKind :: Alias ( AliasTy :: Opaque ( OpaqueTy {
1065
1109
opaque_ty_id,
@@ -1479,7 +1523,7 @@ impl HirDisplay for Ty {
1479
1523
TyKind :: BoundVar ( idx) => idx. hir_fmt ( f) ?,
1480
1524
TyKind :: Dyn ( dyn_ty) => {
1481
1525
// Reorder bounds to satisfy `write_bounds_like_dyn_trait()`'s expectation.
1482
- // FIXME: `Iterator::partition_in_place()` or `Vec::drain_filter ()` may make it
1526
+ // FIXME: `Iterator::partition_in_place()` or `Vec::extract_if ()` may make it
1483
1527
// more efficient when either of them hits stable.
1484
1528
let mut bounds: SmallVec < [ _ ; 4 ] > =
1485
1529
dyn_ty. bounds . skip_binders ( ) . iter ( Interner ) . cloned ( ) . collect ( ) ;
@@ -1488,6 +1532,17 @@ impl HirDisplay for Ty {
1488
1532
bounds. extend ( others) ;
1489
1533
bounds. extend ( auto_traits) ;
1490
1534
1535
+ if f. render_lifetime ( & dyn_ty. lifetime ) {
1536
+ // we skip the binders in `write_bounds_like_dyn_trait_with_prefix`
1537
+ bounds. push ( Binders :: empty (
1538
+ Interner ,
1539
+ chalk_ir:: WhereClause :: TypeOutlives ( chalk_ir:: TypeOutlives {
1540
+ ty : self . clone ( ) ,
1541
+ lifetime : dyn_ty. lifetime . clone ( ) ,
1542
+ } ) ,
1543
+ ) ) ;
1544
+ }
1545
+
1491
1546
write_bounds_like_dyn_trait_with_prefix (
1492
1547
f,
1493
1548
"dyn" ,
@@ -1991,7 +2046,6 @@ impl HirDisplay for LifetimeData {
1991
2046
write ! ( f, "{}" , param_data. name. display( f. db, f. edition( ) ) ) ?;
1992
2047
Ok ( ( ) )
1993
2048
}
1994
- _ if f. display_kind . is_source_code ( ) => write ! ( f, "'_" ) ,
1995
2049
LifetimeData :: BoundVar ( idx) => idx. hir_fmt ( f) ,
1996
2050
LifetimeData :: InferenceVar ( _) => write ! ( f, "_" ) ,
1997
2051
LifetimeData :: Static => write ! ( f, "'static" ) ,
0 commit comments