Skip to content

Commit 3d716b4

Browse files
committed
Render more lifetimes
1 parent 21351d9 commit 3d716b4

23 files changed

+199
-147
lines changed

Diff for: crates/hir-ty/src/display.rs

+61-8
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,26 @@ pub struct HirFormatter<'a> {
9191
show_container_bounds: bool,
9292
omit_verbose_types: bool,
9393
closure_style: ClosureStyle,
94+
display_lifetimes: DisplayLifetime,
9495
display_kind: DisplayKind,
9596
display_target: DisplayTarget,
9697
bounds_formatting_ctx: BoundsFormattingCtx,
9798
}
9899

100+
// FIXME: To consider, ref and dyn trait lifetimes can be omitted if they are `'_`, path args should
101+
// not be when in signatures
102+
// So this enum does not encode this well enough
103+
// Also 'static can be omitted for ref and dyn trait lifetimes in static/const item types
104+
// FIXME: Also named lifetimes may be rendered in places where their name is not in scope?
105+
#[derive(Copy, Clone)]
106+
pub enum DisplayLifetime {
107+
Always,
108+
OnlyStatic,
109+
OnlyNamed,
110+
OnlyNamedOrStatic,
111+
Never,
112+
}
113+
99114
#[derive(Default)]
100115
enum BoundsFormattingCtx {
101116
Entered {
@@ -156,6 +171,21 @@ impl HirFormatter<'_> {
156171
}
157172
}
158173
}
174+
175+
fn render_lifetime(&self, lifetime: &Lifetime) -> bool {
176+
match self.display_lifetimes {
177+
DisplayLifetime::Always => true,
178+
DisplayLifetime::OnlyStatic => matches!(***lifetime.interned(), LifetimeData::Static),
179+
DisplayLifetime::OnlyNamed => {
180+
matches!(***lifetime.interned(), LifetimeData::Placeholder(_))
181+
}
182+
DisplayLifetime::OnlyNamedOrStatic => matches!(
183+
***lifetime.interned(),
184+
LifetimeData::Static | LifetimeData::Placeholder(_)
185+
),
186+
DisplayLifetime::Never => false,
187+
}
188+
}
159189
}
160190

161191
pub trait HirDisplay {
@@ -190,6 +220,7 @@ pub trait HirDisplay {
190220
display_kind,
191221
closure_style,
192222
show_container_bounds,
223+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
193224
}
194225
}
195226

@@ -213,6 +244,7 @@ pub trait HirDisplay {
213244
display_target,
214245
display_kind: DisplayKind::Diagnostics,
215246
show_container_bounds: false,
247+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
216248
}
217249
}
218250

@@ -237,6 +269,7 @@ pub trait HirDisplay {
237269
display_target,
238270
display_kind: DisplayKind::Diagnostics,
239271
show_container_bounds: false,
272+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
240273
}
241274
}
242275

@@ -261,6 +294,7 @@ pub trait HirDisplay {
261294
display_target,
262295
display_kind: DisplayKind::Diagnostics,
263296
show_container_bounds: false,
297+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
264298
}
265299
}
266300

@@ -285,6 +319,7 @@ pub trait HirDisplay {
285319
display_target: DisplayTarget::from_crate(db, module_id.krate()),
286320
display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
287321
show_container_bounds: false,
322+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
288323
bounds_formatting_ctx: Default::default(),
289324
}) {
290325
Ok(()) => {}
@@ -313,6 +348,7 @@ pub trait HirDisplay {
313348
display_target,
314349
display_kind: DisplayKind::Test,
315350
show_container_bounds: false,
351+
display_lifetimes: DisplayLifetime::Always,
316352
}
317353
}
318354

@@ -337,6 +373,7 @@ pub trait HirDisplay {
337373
display_target,
338374
display_kind: DisplayKind::Diagnostics,
339375
show_container_bounds,
376+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
340377
}
341378
}
342379
}
@@ -481,6 +518,7 @@ pub struct HirDisplayWrapper<'a, T> {
481518
display_kind: DisplayKind,
482519
display_target: DisplayTarget,
483520
show_container_bounds: bool,
521+
display_lifetimes: DisplayLifetime,
484522
}
485523

486524
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -503,7 +541,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
503541
self.t.hir_fmt(&mut HirFormatter {
504542
db: self.db,
505543
fmt: f,
506-
buf: String::with_capacity(20),
544+
buf: String::with_capacity(self.max_size.unwrap_or(20)),
507545
curr_size: 0,
508546
max_size: self.max_size,
509547
entity_limit: self.limited_size,
@@ -512,6 +550,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
512550
display_target: self.display_target,
513551
closure_style: self.closure_style,
514552
show_container_bounds: self.show_container_bounds,
553+
display_lifetimes: self.display_lifetimes,
515554
bounds_formatting_ctx: Default::default(),
516555
})
517556
}
@@ -520,6 +559,11 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
520559
self.closure_style = c;
521560
self
522561
}
562+
563+
pub fn with_lifetime_display(mut self, l: DisplayLifetime) -> Self {
564+
self.display_lifetimes = l;
565+
self
566+
}
523567
}
524568

525569
impl<T> fmt::Display for HirDisplayWrapper<'_, T>
@@ -1024,9 +1068,7 @@ impl HirDisplay for Ty {
10241068
kind @ (TyKind::Raw(m, t) | TyKind::Ref(m, _, t)) => {
10251069
if let TyKind::Ref(_, l, _) = kind {
10261070
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
1071+
if f.render_lifetime(l) {
10301072
l.hir_fmt(f)?;
10311073
f.write_char(' ')?;
10321074
}
@@ -1057,9 +1099,10 @@ impl HirDisplay for Ty {
10571099
})
10581100
};
10591101
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 => {
1102+
TyKind::Dyn(dyn_ty) => {
10611103
let bounds = dyn_ty.bounds.skip_binders().interned();
1062-
(bounds.len(), contains_impl_fn(bounds))
1104+
let render_lifetime = f.render_lifetime(&dyn_ty.lifetime);
1105+
(bounds.len() + render_lifetime as usize, contains_impl_fn(bounds))
10631106
}
10641107
TyKind::Alias(AliasTy::Opaque(OpaqueTy {
10651108
opaque_ty_id,
@@ -1479,7 +1522,7 @@ impl HirDisplay for Ty {
14791522
TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
14801523
TyKind::Dyn(dyn_ty) => {
14811524
// Reorder bounds to satisfy `write_bounds_like_dyn_trait()`'s expectation.
1482-
// FIXME: `Iterator::partition_in_place()` or `Vec::drain_filter()` may make it
1525+
// FIXME: `Iterator::partition_in_place()` or `Vec::extract_if()` may make it
14831526
// more efficient when either of them hits stable.
14841527
let mut bounds: SmallVec<[_; 4]> =
14851528
dyn_ty.bounds.skip_binders().iter(Interner).cloned().collect();
@@ -1488,6 +1531,17 @@ impl HirDisplay for Ty {
14881531
bounds.extend(others);
14891532
bounds.extend(auto_traits);
14901533

1534+
if f.render_lifetime(&dyn_ty.lifetime) {
1535+
// we skip the binders in `write_bounds_like_dyn_trait_with_prefix`
1536+
bounds.push(Binders::empty(
1537+
Interner,
1538+
chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives {
1539+
ty: self.clone(),
1540+
lifetime: dyn_ty.lifetime.clone(),
1541+
}),
1542+
));
1543+
}
1544+
14911545
write_bounds_like_dyn_trait_with_prefix(
14921546
f,
14931547
"dyn",
@@ -1991,7 +2045,6 @@ impl HirDisplay for LifetimeData {
19912045
write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
19922046
Ok(())
19932047
}
1994-
_ if f.display_kind.is_source_code() => write!(f, "'_"),
19952048
LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
19962049
LifetimeData::InferenceVar(_) => write!(f, "_"),
19972050
LifetimeData::Static => write!(f, "'static"),

Diff for: crates/hir-ty/src/tests/coercion.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ trait Foo {}
561561
fn test(f: impl Foo, g: &(impl Foo + ?Sized)) {
562562
let _: &dyn Foo = &f;
563563
let _: &dyn Foo = g;
564-
//^ expected &'? dyn Foo, got &'? impl Foo + ?Sized
564+
//^ expected &'? (dyn Foo + 'static), got &'? impl Foo + ?Sized
565565
}
566566
"#,
567567
);
@@ -827,11 +827,11 @@ struct V<T> { t: T }
827827
fn main() {
828828
let a: V<&dyn Tr>;
829829
(a,) = V { t: &S };
830-
//^^^^expected V<&'? S>, got (V<&'? dyn Tr>,)
830+
//^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
831831
832832
let mut a: V<&dyn Tr> = V { t: &S };
833833
(a,) = V { t: &S };
834-
//^^^^expected V<&'? S>, got (V<&'? dyn Tr>,)
834+
//^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
835835
}
836836
"#,
837837
);

Diff for: crates/hir-ty/src/tests/display_source_code.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ trait A {
6565
}
6666
trait B: A {}
6767
68-
fn test(
68+
fn test<'a>(
6969
_: &(dyn A<Assoc = ()> + Send),
70-
//^ &'_ (dyn A<Assoc = ()> + Send)
71-
_: &(dyn Send + A<Assoc = ()>),
72-
//^ &'_ (dyn A<Assoc = ()> + Send)
70+
//^ &(dyn A<Assoc = ()> + Send + '_)
71+
_: &'a (dyn Send + A<Assoc = ()>),
72+
//^ &'a (dyn A<Assoc = ()> + Send + '_)
7373
_: &dyn B<Assoc = ()>,
74-
//^ &'_ (dyn B<Assoc = ()>)
74+
//^ &(dyn B<Assoc = ()> + '_)
7575
) {}
7676
"#,
7777
);
@@ -85,7 +85,7 @@ fn render_dyn_for_ty() {
8585
trait Foo<'a> {}
8686
8787
fn foo(foo: &dyn for<'a> Foo<'a>) {}
88-
// ^^^ &'_ dyn Foo<'_>
88+
// ^^^ &(dyn Foo<'_> + '_)
8989
"#,
9090
);
9191
}
@@ -111,11 +111,11 @@ fn test(
111111
b;
112112
//^ impl Foo
113113
c;
114-
//^ &'_ impl Foo + ?Sized
114+
//^ &impl Foo + ?Sized
115115
d;
116116
//^ S<impl Foo>
117117
ref_any;
118-
//^^^^^^^ &'_ impl ?Sized
118+
//^^^^^^^ &impl ?Sized
119119
empty;
120120
} //^^^^^ impl Sized
121121
"#,
@@ -192,7 +192,7 @@ fn test(
192192
b;
193193
//^ fn(impl Foo) -> impl Foo
194194
c;
195-
} //^ fn(&'_ impl Foo + ?Sized) -> &'_ impl Foo + ?Sized
195+
} //^ fn(&impl Foo + ?Sized) -> &impl Foo + ?Sized
196196
"#,
197197
);
198198
}

Diff for: crates/hir-ty/src/tests/method_resolution.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1153,9 +1153,9 @@ fn dyn_trait_super_trait_not_in_scope() {
11531153
51..55 'self': &'? Self
11541154
64..69 '{ 0 }': u32
11551155
66..67 '0': u32
1156-
176..177 'd': &'? dyn Trait
1156+
176..177 'd': &'? (dyn Trait + 'static)
11571157
191..207 '{ ...o(); }': ()
1158-
197..198 'd': &'? dyn Trait
1158+
197..198 'd': &'? (dyn Trait + 'static)
11591159
197..204 'd.foo()': u32
11601160
"#]],
11611161
);
@@ -2019,10 +2019,10 @@ impl dyn Error + Send {
20192019
/// Attempts to downcast the box to a concrete type.
20202020
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
20212021
let err: Box<dyn Error> = self;
2022-
// ^^^^ expected Box<dyn Error>, got Box<dyn Error + Send>
2022+
// ^^^^ expected Box<dyn Error + 'static>, got Box<dyn Error + Send + 'static>
20232023
// FIXME, type mismatch should not occur
20242024
<dyn Error>::downcast(err).map_err(|_| loop {})
2025-
//^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error>) -> Result<Box<{unknown}>, Box<dyn Error>>
2025+
//^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + 'static>>
20262026
}
20272027
}
20282028
"#,

Diff for: crates/hir-ty/src/tests/regression.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ fn issue_4053_diesel_where_clauses() {
629629
488..522 '{ ... }': ()
630630
498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
631631
498..508 'self.order': O
632-
498..515 'self.o...into()': dyn QueryFragment<DB>
632+
498..515 'self.o...into()': dyn QueryFragment<DB> + 'static
633633
"#]],
634634
);
635635
}
@@ -773,7 +773,7 @@ fn issue_4800() {
773773
"#,
774774
expect![[r#"
775775
379..383 'self': &'? mut PeerSet<D>
776-
401..424 '{ ... }': dyn Future<Output = ()>
776+
401..424 '{ ... }': dyn Future<Output = ()> + 'static
777777
411..418 'loop {}': !
778778
416..418 '{}': ()
779779
575..579 'self': &'? mut Self

Diff for: crates/hir-ty/src/tests/simple.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -2741,11 +2741,11 @@ impl B for Astruct {}
27412741
715..744 '#[rust...1i32])': Box<[i32; 1], Global>
27422742
737..743 '[1i32]': [i32; 1]
27432743
738..742 '1i32': i32
2744-
755..756 'v': Vec<Box<dyn B, Global>, Global>
2745-
776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
2746-
776..850 '<[_]> ...ct)]))': Vec<Box<dyn B, Global>, Global>
2747-
794..849 '#[rust...uct)])': Box<[Box<dyn B, Global>; 1], Global>
2748-
816..848 '[#[rus...ruct)]': [Box<dyn B, Global>; 1]
2744+
755..756 'v': Vec<Box<dyn B + 'static, Global>, Global>
2745+
776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B + 'static, Global>, Global>(Box<[Box<dyn B + 'static, Global>], Global>) -> Vec<Box<dyn B + 'static, Global>, Global>
2746+
776..850 '<[_]> ...ct)]))': Vec<Box<dyn B + 'static, Global>, Global>
2747+
794..849 '#[rust...uct)])': Box<[Box<dyn B + 'static, Global>; 1], Global>
2748+
816..848 '[#[rus...ruct)]': [Box<dyn B + 'static, Global>; 1]
27492749
817..847 '#[rust...truct)': Box<Astruct, Global>
27502750
839..846 'Astruct': Astruct
27512751
"#]],

0 commit comments

Comments
 (0)