Skip to content

Commit 03d509d

Browse files
committed
Render more lifetimes
1 parent 21351d9 commit 03d509d

24 files changed

+202
-149
lines changed

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

+62-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::{
88
};
99

1010
use base_db::Crate;
11+
use bitflags::bitflags;
1112
use chalk_ir::{BoundVar, Safety, TyKind};
1213
use either::Either;
1314
use hir_def::{
@@ -91,11 +92,26 @@ pub struct HirFormatter<'a> {
9192
show_container_bounds: bool,
9293
omit_verbose_types: bool,
9394
closure_style: ClosureStyle,
95+
display_lifetimes: DisplayLifetime,
9496
display_kind: DisplayKind,
9597
display_target: DisplayTarget,
9698
bounds_formatting_ctx: BoundsFormattingCtx,
9799
}
98100

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+
99115
#[derive(Default)]
100116
enum BoundsFormattingCtx {
101117
Entered {
@@ -156,6 +172,21 @@ impl HirFormatter<'_> {
156172
}
157173
}
158174
}
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+
}
159190
}
160191

161192
pub trait HirDisplay {
@@ -190,6 +221,7 @@ pub trait HirDisplay {
190221
display_kind,
191222
closure_style,
192223
show_container_bounds,
224+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
193225
}
194226
}
195227

@@ -213,6 +245,7 @@ pub trait HirDisplay {
213245
display_target,
214246
display_kind: DisplayKind::Diagnostics,
215247
show_container_bounds: false,
248+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
216249
}
217250
}
218251

@@ -237,6 +270,7 @@ pub trait HirDisplay {
237270
display_target,
238271
display_kind: DisplayKind::Diagnostics,
239272
show_container_bounds: false,
273+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
240274
}
241275
}
242276

@@ -261,6 +295,7 @@ pub trait HirDisplay {
261295
display_target,
262296
display_kind: DisplayKind::Diagnostics,
263297
show_container_bounds: false,
298+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
264299
}
265300
}
266301

@@ -285,6 +320,7 @@ pub trait HirDisplay {
285320
display_target: DisplayTarget::from_crate(db, module_id.krate()),
286321
display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
287322
show_container_bounds: false,
323+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
288324
bounds_formatting_ctx: Default::default(),
289325
}) {
290326
Ok(()) => {}
@@ -313,6 +349,7 @@ pub trait HirDisplay {
313349
display_target,
314350
display_kind: DisplayKind::Test,
315351
show_container_bounds: false,
352+
display_lifetimes: DisplayLifetime::Always,
316353
}
317354
}
318355

@@ -337,6 +374,7 @@ pub trait HirDisplay {
337374
display_target,
338375
display_kind: DisplayKind::Diagnostics,
339376
show_container_bounds,
377+
display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
340378
}
341379
}
342380
}
@@ -481,6 +519,7 @@ pub struct HirDisplayWrapper<'a, T> {
481519
display_kind: DisplayKind,
482520
display_target: DisplayTarget,
483521
show_container_bounds: bool,
522+
display_lifetimes: DisplayLifetime,
484523
}
485524

486525
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -503,7 +542,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
503542
self.t.hir_fmt(&mut HirFormatter {
504543
db: self.db,
505544
fmt: f,
506-
buf: String::with_capacity(20),
545+
buf: String::with_capacity(self.max_size.unwrap_or(20)),
507546
curr_size: 0,
508547
max_size: self.max_size,
509548
entity_limit: self.limited_size,
@@ -512,6 +551,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
512551
display_target: self.display_target,
513552
closure_style: self.closure_style,
514553
show_container_bounds: self.show_container_bounds,
554+
display_lifetimes: self.display_lifetimes,
515555
bounds_formatting_ctx: Default::default(),
516556
})
517557
}
@@ -520,6 +560,11 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
520560
self.closure_style = c;
521561
self
522562
}
563+
564+
pub fn with_lifetime_display(mut self, l: DisplayLifetime) -> Self {
565+
self.display_lifetimes = l;
566+
self
567+
}
523568
}
524569

525570
impl<T> fmt::Display for HirDisplayWrapper<'_, T>
@@ -1024,9 +1069,7 @@ impl HirDisplay for Ty {
10241069
kind @ (TyKind::Raw(m, t) | TyKind::Ref(m, _, t)) => {
10251070
if let TyKind::Ref(_, l, _) = kind {
10261071
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) {
10301073
l.hir_fmt(f)?;
10311074
f.write_char(' ')?;
10321075
}
@@ -1057,9 +1100,10 @@ impl HirDisplay for Ty {
10571100
})
10581101
};
10591102
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) => {
10611104
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))
10631107
}
10641108
TyKind::Alias(AliasTy::Opaque(OpaqueTy {
10651109
opaque_ty_id,
@@ -1479,7 +1523,7 @@ impl HirDisplay for Ty {
14791523
TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
14801524
TyKind::Dyn(dyn_ty) => {
14811525
// 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
14831527
// more efficient when either of them hits stable.
14841528
let mut bounds: SmallVec<[_; 4]> =
14851529
dyn_ty.bounds.skip_binders().iter(Interner).cloned().collect();
@@ -1488,6 +1532,17 @@ impl HirDisplay for Ty {
14881532
bounds.extend(others);
14891533
bounds.extend(auto_traits);
14901534

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+
14911546
write_bounds_like_dyn_trait_with_prefix(
14921547
f,
14931548
"dyn",
@@ -1991,7 +2046,6 @@ impl HirDisplay for LifetimeData {
19912046
write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
19922047
Ok(())
19932048
}
1994-
_ if f.display_kind.is_source_code() => write!(f, "'_"),
19952049
LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
19962050
LifetimeData::InferenceVar(_) => write!(f, "_"),
19972051
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)