about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs69
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs78
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs42
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs4
24 files changed, 201 insertions, 149 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index e810467b994..f0989d9de91 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -90,11 +90,26 @@ pub struct HirFormatter<'a> {
     show_container_bounds: bool,
     omit_verbose_types: bool,
     closure_style: ClosureStyle,
+    display_lifetimes: DisplayLifetime,
     display_kind: DisplayKind,
     display_target: DisplayTarget,
     bounds_formatting_ctx: BoundsFormattingCtx,
 }
 
+// FIXME: To consider, ref and dyn trait lifetimes can be omitted if they are `'_`, path args should
+// not be when in signatures
+// So this enum does not encode this well enough
+// Also 'static can be omitted for ref and dyn trait lifetimes in static/const item types
+// FIXME: Also named lifetimes may be rendered in places where their name is not in scope?
+#[derive(Copy, Clone)]
+pub enum DisplayLifetime {
+    Always,
+    OnlyStatic,
+    OnlyNamed,
+    OnlyNamedOrStatic,
+    Never,
+}
+
 #[derive(Default)]
 enum BoundsFormattingCtx {
     Entered {
@@ -155,6 +170,21 @@ impl HirFormatter<'_> {
             }
         }
     }
+
+    fn render_lifetime(&self, lifetime: &Lifetime) -> bool {
+        match self.display_lifetimes {
+            DisplayLifetime::Always => true,
+            DisplayLifetime::OnlyStatic => matches!(***lifetime.interned(), LifetimeData::Static),
+            DisplayLifetime::OnlyNamed => {
+                matches!(***lifetime.interned(), LifetimeData::Placeholder(_))
+            }
+            DisplayLifetime::OnlyNamedOrStatic => matches!(
+                ***lifetime.interned(),
+                LifetimeData::Static | LifetimeData::Placeholder(_)
+            ),
+            DisplayLifetime::Never => false,
+        }
+    }
 }
 
 pub trait HirDisplay {
@@ -189,6 +219,7 @@ pub trait HirDisplay {
             display_kind,
             closure_style,
             show_container_bounds,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -212,6 +243,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -236,6 +268,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -260,6 +293,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 
@@ -284,6 +318,7 @@ pub trait HirDisplay {
             display_target: DisplayTarget::from_crate(db, module_id.krate()),
             display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
             bounds_formatting_ctx: Default::default(),
         }) {
             Ok(()) => {}
@@ -312,6 +347,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Test,
             show_container_bounds: false,
+            display_lifetimes: DisplayLifetime::Always,
         }
     }
 
@@ -336,6 +372,7 @@ pub trait HirDisplay {
             display_target,
             display_kind: DisplayKind::Diagnostics,
             show_container_bounds,
+            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
         }
     }
 }
@@ -480,6 +517,7 @@ pub struct HirDisplayWrapper<'a, T> {
     display_kind: DisplayKind,
     display_target: DisplayTarget,
     show_container_bounds: bool,
+    display_lifetimes: DisplayLifetime,
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -502,7 +540,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
         self.t.hir_fmt(&mut HirFormatter {
             db: self.db,
             fmt: f,
-            buf: String::with_capacity(20),
+            buf: String::with_capacity(self.max_size.unwrap_or(20)),
             curr_size: 0,
             max_size: self.max_size,
             entity_limit: self.limited_size,
@@ -511,6 +549,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
             display_target: self.display_target,
             closure_style: self.closure_style,
             show_container_bounds: self.show_container_bounds,
+            display_lifetimes: self.display_lifetimes,
             bounds_formatting_ctx: Default::default(),
         })
     }
@@ -519,6 +558,11 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
         self.closure_style = c;
         self
     }
+
+    pub fn with_lifetime_display(mut self, l: DisplayLifetime) -> Self {
+        self.display_lifetimes = l;
+        self
+    }
 }
 
 impl<T> fmt::Display for HirDisplayWrapper<'_, T>
@@ -1022,9 +1066,7 @@ impl HirDisplay for Ty {
             kind @ (TyKind::Raw(m, t) | TyKind::Ref(m, _, t)) => {
                 if let TyKind::Ref(_, l, _) = kind {
                     f.write_char('&')?;
-                    if cfg!(test) {
-                        // rendering these unconditionally is probably too much (at least for inlay
-                        // hints) so we gate it to testing only for the time being
+                    if f.render_lifetime(l) {
                         l.hir_fmt(f)?;
                         f.write_char(' ')?;
                     }
@@ -1055,9 +1097,10 @@ impl HirDisplay for Ty {
                     })
                 };
                 let (preds_to_print, has_impl_fn_pred) = match t.kind(Interner) {
-                    TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
+                    TyKind::Dyn(dyn_ty) => {
                         let bounds = dyn_ty.bounds.skip_binders().interned();
-                        (bounds.len(), contains_impl_fn(bounds))
+                        let render_lifetime = f.render_lifetime(&dyn_ty.lifetime);
+                        (bounds.len() + render_lifetime as usize, contains_impl_fn(bounds))
                     }
                     TyKind::Alias(AliasTy::Opaque(OpaqueTy {
                         opaque_ty_id,
@@ -1479,7 +1522,7 @@ impl HirDisplay for Ty {
             TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
             TyKind::Dyn(dyn_ty) => {
                 // Reorder bounds to satisfy `write_bounds_like_dyn_trait()`'s expectation.
-                // FIXME: `Iterator::partition_in_place()` or `Vec::drain_filter()` may make it
+                // FIXME: `Iterator::partition_in_place()` or `Vec::extract_if()` may make it
                 // more efficient when either of them hits stable.
                 let mut bounds: SmallVec<[_; 4]> =
                     dyn_ty.bounds.skip_binders().iter(Interner).cloned().collect();
@@ -1488,6 +1531,17 @@ impl HirDisplay for Ty {
                 bounds.extend(others);
                 bounds.extend(auto_traits);
 
+                if f.render_lifetime(&dyn_ty.lifetime) {
+                    // we skip the binders in `write_bounds_like_dyn_trait_with_prefix`
+                    bounds.push(Binders::empty(
+                        Interner,
+                        chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives {
+                            ty: self.clone(),
+                            lifetime: dyn_ty.lifetime.clone(),
+                        }),
+                    ));
+                }
+
                 write_bounds_like_dyn_trait_with_prefix(
                     f,
                     "dyn",
@@ -1989,7 +2043,6 @@ impl HirDisplay for LifetimeData {
                 write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
                 Ok(())
             }
-            _ if f.display_kind.is_source_code() => write!(f, "'_"),
             LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
             LifetimeData::InferenceVar(_) => write!(f, "_"),
             LifetimeData::Static => write!(f, "'static"),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
index eeaacbf12ea..ddc5b715194 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
@@ -561,7 +561,7 @@ trait Foo {}
 fn test(f: impl Foo, g: &(impl Foo + ?Sized)) {
     let _: &dyn Foo = &f;
     let _: &dyn Foo = g;
-                    //^ expected &'? dyn Foo, got &'? impl Foo + ?Sized
+                    //^ expected &'? (dyn Foo + 'static), got &'? impl Foo + ?Sized
 }
         "#,
     );
@@ -827,11 +827,11 @@ struct V<T> { t: T }
 fn main() {
     let a: V<&dyn Tr>;
     (a,) = V { t: &S };
-  //^^^^expected V<&'? S>, got (V<&'? dyn Tr>,)
+  //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
 
     let mut a: V<&dyn Tr> = V { t: &S };
     (a,) = V { t: &S };
-  //^^^^expected V<&'? S>, got (V<&'? dyn Tr>,)
+  //^^^^expected V<&'? S>, got (V<&'? (dyn Tr + '?)>,)
 }
         "#,
     );
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
index 60c03b52246..a986b54a7b0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
@@ -65,13 +65,13 @@ trait A {
 }
 trait B: A {}
 
-fn test(
+fn test<'a>(
     _: &(dyn A<Assoc = ()> + Send),
-  //^ &'_ (dyn A<Assoc = ()> + Send)
-    _: &(dyn Send + A<Assoc = ()>),
-  //^ &'_ (dyn A<Assoc = ()> + Send)
+  //^ &(dyn A<Assoc = ()> + Send + 'static)
+    _: &'a (dyn Send + A<Assoc = ()>),
+  //^ &'a (dyn A<Assoc = ()> + Send + 'static)
     _: &dyn B<Assoc = ()>,
-  //^ &'_ (dyn B<Assoc = ()>)
+  //^ &(dyn B<Assoc = ()> + 'static)
 ) {}
         "#,
     );
@@ -85,7 +85,7 @@ fn render_dyn_for_ty() {
 trait Foo<'a> {}
 
 fn foo(foo: &dyn for<'a> Foo<'a>) {}
-    // ^^^ &'_ dyn Foo<'_>
+    // ^^^ &(dyn Foo<'?> + 'static)
 "#,
     );
 }
@@ -111,11 +111,11 @@ fn test(
     b;
   //^ impl Foo
     c;
-  //^ &'_ impl Foo + ?Sized
+  //^ &impl Foo + ?Sized
     d;
   //^ S<impl Foo>
     ref_any;
-  //^^^^^^^ &'_ impl ?Sized
+  //^^^^^^^ &impl ?Sized
     empty;
 } //^^^^^ impl Sized
 "#,
@@ -192,7 +192,7 @@ fn test(
     b;
   //^ fn(impl Foo) -> impl Foo
     c;
-} //^ fn(&'_ impl Foo + ?Sized) -> &'_ impl Foo + ?Sized
+} //^ fn(&impl Foo + ?Sized) -> &impl Foo + ?Sized
 "#,
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
index 3a258ecad10..1f8b06fcc56 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
@@ -1153,9 +1153,9 @@ fn dyn_trait_super_trait_not_in_scope() {
             51..55 'self': &'? Self
             64..69 '{ 0 }': u32
             66..67 '0': u32
-            176..177 'd': &'? dyn Trait
+            176..177 'd': &'? (dyn Trait + 'static)
             191..207 '{     ...o(); }': ()
-            197..198 'd': &'? dyn Trait
+            197..198 'd': &'? (dyn Trait + 'static)
             197..204 'd.foo()': u32
         "#]],
     );
@@ -2019,10 +2019,10 @@ impl dyn Error + Send {
     /// Attempts to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
         let err: Box<dyn Error> = self;
-                               // ^^^^ expected Box<dyn Error>, got Box<dyn Error + Send>
+                               // ^^^^ expected Box<dyn Error + 'static>, got Box<dyn Error + Send + 'static>
                                // FIXME, type mismatch should not occur
         <dyn Error>::downcast(err).map_err(|_| loop {})
-      //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error>) -> Result<Box<{unknown}>, Box<dyn Error>>
+      //^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + 'static>>
     }
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
index 638306054a9..644b0d392bc 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -629,7 +629,7 @@ fn issue_4053_diesel_where_clauses() {
             488..522 '{     ...     }': ()
             498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
             498..508 'self.order': O
-            498..515 'self.o...into()': dyn QueryFragment<DB>
+            498..515 'self.o...into()': dyn QueryFragment<DB> + 'static
         "#]],
     );
 }
@@ -773,7 +773,7 @@ fn issue_4800() {
         "#,
         expect![[r#"
             379..383 'self': &'? mut PeerSet<D>
-            401..424 '{     ...     }': dyn Future<Output = ()>
+            401..424 '{     ...     }': dyn Future<Output = ()> + 'static
             411..418 'loop {}': !
             416..418 '{}': ()
             575..579 'self': &'? mut Self
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
index 0f5e44151de..eeebe38f182 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
@@ -2741,11 +2741,11 @@ impl B for Astruct {}
             715..744 '#[rust...1i32])': Box<[i32; 1], Global>
             737..743 '[1i32]': [i32; 1]
             738..742 '1i32': i32
-            755..756 'v': Vec<Box<dyn B, Global>, Global>
-            776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
-            776..850 '<[_]> ...ct)]))': Vec<Box<dyn B, Global>, Global>
-            794..849 '#[rust...uct)])': Box<[Box<dyn B, Global>; 1], Global>
-            816..848 '[#[rus...ruct)]': [Box<dyn B, Global>; 1]
+            755..756 'v': Vec<Box<dyn B + 'static, Global>, Global>
+            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>
+            776..850 '<[_]> ...ct)]))': Vec<Box<dyn B + 'static, Global>, Global>
+            794..849 '#[rust...uct)])': Box<[Box<dyn B + 'static, Global>; 1], Global>
+            816..848 '[#[rus...ruct)]': [Box<dyn B + 'static, Global>; 1]
             817..847 '#[rust...truct)': Box<Astruct, Global>
             839..846 'Astruct': Astruct
         "#]],
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
index 2fb51acea87..14137605c9f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -1475,26 +1475,26 @@ fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) {
         expect![[r#"
             29..33 'self': &'? Self
             54..58 'self': &'? Self
-            198..200 '{}': Box<dyn Trait<u64>>
-            210..211 'x': Box<dyn Trait<u64>>
-            234..235 'y': &'? dyn Trait<u64>
+            198..200 '{}': Box<dyn Trait<u64> + 'static>
+            210..211 'x': Box<dyn Trait<u64> + 'static>
+            234..235 'y': &'? (dyn Trait<u64> + 'static)
             254..371 '{     ...2(); }': ()
-            260..261 'x': Box<dyn Trait<u64>>
-            267..268 'y': &'? dyn Trait<u64>
-            278..279 'z': Box<dyn Trait<u64>>
-            282..285 'bar': fn bar() -> Box<dyn Trait<u64>>
-            282..287 'bar()': Box<dyn Trait<u64>>
-            293..294 'x': Box<dyn Trait<u64>>
+            260..261 'x': Box<dyn Trait<u64> + 'static>
+            267..268 'y': &'? (dyn Trait<u64> + 'static)
+            278..279 'z': Box<dyn Trait<u64> + 'static>
+            282..285 'bar': fn bar() -> Box<dyn Trait<u64> + 'static>
+            282..287 'bar()': Box<dyn Trait<u64> + 'static>
+            293..294 'x': Box<dyn Trait<u64> + 'static>
             293..300 'x.foo()': u64
-            306..307 'y': &'? dyn Trait<u64>
+            306..307 'y': &'? (dyn Trait<u64> + 'static)
             306..313 'y.foo()': u64
-            319..320 'z': Box<dyn Trait<u64>>
+            319..320 'z': Box<dyn Trait<u64> + 'static>
             319..326 'z.foo()': u64
-            332..333 'x': Box<dyn Trait<u64>>
+            332..333 'x': Box<dyn Trait<u64> + 'static>
             332..340 'x.foo2()': i64
-            346..347 'y': &'? dyn Trait<u64>
+            346..347 'y': &'? (dyn Trait<u64> + 'static)
             346..354 'y.foo2()': i64
-            360..361 'z': Box<dyn Trait<u64>>
+            360..361 'z': Box<dyn Trait<u64> + 'static>
             360..368 'z.foo2()': i64
         "#]],
     );
@@ -1523,14 +1523,14 @@ fn test(s: S<u32, i32>) {
         expect![[r#"
             32..36 'self': &'? Self
             102..106 'self': &'? S<T, U>
-            128..139 '{ loop {} }': &'? dyn Trait<T, U>
+            128..139 '{ loop {} }': &'? (dyn Trait<T, U> + 'static)
             130..137 'loop {}': !
             135..137 '{}': ()
             175..179 'self': &'? Self
             251..252 's': S<u32, i32>
             267..289 '{     ...z(); }': ()
             273..274 's': S<u32, i32>
-            273..280 's.bar()': &'? dyn Trait<u32, i32>
+            273..280 's.bar()': &'? (dyn Trait<u32, i32> + 'static)
             273..286 's.bar().baz()': (u32, i32)
         "#]],
     );
@@ -1556,20 +1556,20 @@ fn test(x: Trait, y: &Trait) -> u64 {
 }"#,
         expect![[r#"
             26..30 'self': &'? Self
-            60..62 '{}': dyn Trait
-            72..73 'x': dyn Trait
-            82..83 'y': &'? dyn Trait
+            60..62 '{}': dyn Trait + 'static
+            72..73 'x': dyn Trait + 'static
+            82..83 'y': &'? (dyn Trait + 'static)
             100..175 '{     ...o(); }': u64
-            106..107 'x': dyn Trait
-            113..114 'y': &'? dyn Trait
-            124..125 'z': dyn Trait
-            128..131 'bar': fn bar() -> dyn Trait
-            128..133 'bar()': dyn Trait
-            139..140 'x': dyn Trait
+            106..107 'x': dyn Trait + 'static
+            113..114 'y': &'? (dyn Trait + 'static)
+            124..125 'z': dyn Trait + 'static
+            128..131 'bar': fn bar() -> dyn Trait + 'static
+            128..133 'bar()': dyn Trait + 'static
+            139..140 'x': dyn Trait + 'static
             139..146 'x.foo()': u64
-            152..153 'y': &'? dyn Trait
+            152..153 'y': &'? (dyn Trait + 'static)
             152..159 'y.foo()': u64
-            165..166 'z': dyn Trait
+            165..166 'z': dyn Trait + 'static
             165..172 'z.foo()': u64
         "#]],
     );
@@ -1589,10 +1589,10 @@ fn main() {
         expect![[r#"
             31..35 'self': &'? S
             37..39 '{}': ()
-            47..48 '_': &'? dyn Fn(S)
+            47..48 '_': &'? (dyn Fn(S) + 'static)
             58..60 '{}': ()
             71..105 '{     ...()); }': ()
-            77..78 'f': fn f(&'? dyn Fn(S))
+            77..78 'f': fn f(&'? (dyn Fn(S) + 'static))
             77..102 'f(&|nu...foo())': ()
             79..101 '&|numb....foo()': &'? impl Fn(S)
             80..101 '|numbe....foo()': impl Fn(S)
@@ -2927,13 +2927,13 @@ fn test(x: &dyn Foo) {
     foo(x);
 }"#,
         expect![[r#"
-            21..22 'x': &'? dyn Foo
+            21..22 'x': &'? (dyn Foo + 'static)
             34..36 '{}': ()
-            46..47 'x': &'? dyn Foo
+            46..47 'x': &'? (dyn Foo + 'static)
             59..74 '{     foo(x); }': ()
-            65..68 'foo': fn foo(&'? dyn Foo)
+            65..68 'foo': fn foo(&'? (dyn Foo + 'static))
             65..71 'foo(x)': ()
-            69..70 'x': &'? dyn Foo
+            69..70 'x': &'? (dyn Foo + 'static)
         "#]],
     );
 }
@@ -3210,13 +3210,13 @@ fn foo() {
             218..324 '{     ...&s); }': ()
             228..229 's': Option<i32>
             232..236 'None': Option<i32>
-            246..247 'f': Box<dyn FnOnce(&'? Option<i32>)>
-            281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>)>
+            246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static>
+            281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + 'static>
             294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option<i32>)
             300..307 '|ps| {}': impl FnOnce(&'? Option<i32>)
             301..303 'ps': &'? Option<i32>
             305..307 '{}': ()
-            316..317 'f': Box<dyn FnOnce(&'? Option<i32>)>
+            316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static>
             316..321 'f(&s)': ()
             318..320 '&s': &'? Option<i32>
             319..320 's': Option<i32>
@@ -4252,9 +4252,9 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
     "#,
         expect![[r#"
             90..94 'self': &'? Self
-            127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32>)
+            127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
             164..195 '{     ...f(); }': ()
-            170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32>)
+            170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
             170..184 'v.get::<i32>()': &'? i32
             170..192 'v.get:...eref()': &'? i32
         "#]],
@@ -4735,7 +4735,7 @@ pub async fn foo_async<'a>() -> Box<dyn Trait + 'a>  {
 
 fn foo() {
     foo_async();
-  //^^^^^^^^^^^impl Future<Output = Box<dyn Trait>> + ?Sized
+  //^^^^^^^^^^^impl Future<Output = Box<dyn Trait + '?>> + ?Sized
 }
 "#,
     )
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
index 1d3a2db3352..43515de71e2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs
@@ -1066,7 +1066,7 @@ fn foo() {
             r#"
 fn foo() {
     let (mut a, b) = (0.1, "abc");
-    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) {
+    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) {
         *a = 1.2;
         let c = *b;
     }
@@ -1098,7 +1098,7 @@ fn foo() {
             r#"
 fn foo() {
     let (mut a, b) = (0.1, "abc");
-    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) {
+    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) {
         let _: &mut bool = p2;
         *a = 1.2;
         let c = *b;
@@ -1136,7 +1136,7 @@ fn foo() {
             r#"
 fn foo() {
     let (mut a, b) = (0.1, "abc");
-    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) {
+    fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&'static str) {
         let _: &mut bool = p2;
         *a = 1.2;
         let c = *b;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index 046af71a9dc..e977798c4fd 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -5033,7 +5033,7 @@ fn main() {
     fun_name(bar);
 }
 
-fn $0fun_name(bar: &str) {
+fn $0fun_name(bar: &'static str) {
     m!(bar);
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
index 3971b60f253..31e84e9adcf 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -631,7 +631,7 @@ fn main() {
 "#,
             r#"
 fn main() {
-    const $0HELLO: &str = "hello";
+    const $0HELLO: &'static str = "hello";
 }
 "#,
             "Extract into constant",
@@ -726,7 +726,7 @@ fn main() {
 "#,
             r#"
 fn main() {
-    static $0HELLO: &str = "hello";
+    static $0HELLO: &'static str = "hello";
 }
 "#,
             "Extract into static",
@@ -2528,13 +2528,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let entry = Entry($0"Hello"$0);
 }
 "#,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let $0hello = "Hello";
     let entry = Entry(hello);
@@ -2546,13 +2546,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let entry = Entry($0"Hello"$0);
 }
 "#,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     const $0HELLO: &str = "Hello";
     let entry = Entry(HELLO);
@@ -2564,13 +2564,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     let entry = Entry($0"Hello"$0);
 }
 "#,
             r#"
-struct Entry(&str);
+struct Entry<'a>(&'a str);
 fn foo() {
     static $0HELLO: &str = "Hello";
     let entry = Entry(HELLO);
@@ -2587,13 +2587,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let entry = Entry { message: $0"Hello"$0 };
 }
 "#,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let $0message = "Hello";
     let entry = Entry { message };
@@ -2605,13 +2605,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let entry = Entry { message: $0"Hello"$0 };
 }
 "#,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     const $0HELLO: &str = "Hello";
     let entry = Entry { message: HELLO };
@@ -2623,13 +2623,13 @@ fn foo() {
         check_assist_by_label(
             extract_variable,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     let entry = Entry { message: $0"Hello"$0 };
 }
 "#,
             r#"
-struct Entry { message: &str }
+struct Entry<'a> { message: &'a str }
 fn foo() {
     static $0HELLO: &str = "Hello";
     let entry = Entry { message: HELLO };
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index aac145a7215..30084d23d1f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -47,7 +47,7 @@ use crate::{
 //     bar("", baz());
 // }
 //
-// fn bar(arg: &str, baz: Baz) ${0:-> _} {
+// fn bar(arg: &'static str, baz: Baz) ${0:-> _} {
 //     todo!()
 // }
 //
@@ -1518,7 +1518,7 @@ fn foo() {
     bar("bar")
 }
 
-fn bar(arg: &str) {
+fn bar(arg: &'static str) {
     ${0:todo!()}
 }
 "#,
@@ -2135,7 +2135,7 @@ fn foo() {
     bar(baz(), baz(), "foo", "bar")
 }
 
-fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) {
+fn bar(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) {
     ${0:todo!()}
 }
 "#,
@@ -3103,7 +3103,7 @@ pub struct Foo {
     field_2: String,
 }
 impl Foo {
-    fn new(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) -> Self {
+    fn new(baz_1: Baz, baz_2: Baz, arg_1: &'static str, arg_2: &'static str) -> Self {
         ${0:Self { field_1: todo!(), field_2: todo!() }}
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 54d060cc790..01ab0be34b2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -1737,7 +1737,7 @@ fn foo() {
     bar("", baz());
 }
 
-fn bar(arg: &str, baz: Baz) ${0:-> _} {
+fn bar(arg: &'static str, baz: Baz) ${0:-> _} {
     todo!()
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
index 27d6bc7b14f..d5137949d42 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
@@ -1517,7 +1517,7 @@ fn main() {
             en Enum                      Enum
             fn function()                fn()
             fn main()                    fn()
-            lc variable                  &str
+            lc variable          &'static str
             ma helper!(…) macro_rules! helper
             ma m!(…)           macro_rules! m
             ma makro!(…)   macro_rules! makro
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
index 15518e98370..148203107c4 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs
@@ -1358,7 +1358,7 @@ pub fn foo<'x, T>(x: &'x mut T) -> u8 where T: Clone, { 0u8 }
 fn main() { fo$0 }
 "#,
         CompletionItemKind::SymbolKind(ide_db::SymbolKind::Function),
-        expect!("fn(&mut T) -> u8"),
+        expect!("fn(&'x mut T) -> u8"),
         expect!("pub fn foo<'x, T>(x: &'x mut T) -> u8 where T: Clone,"),
     );
 
@@ -1391,7 +1391,7 @@ fn main() {
 }
 "#,
         CompletionItemKind::SymbolKind(SymbolKind::Method),
-        expect!("const fn(&'foo mut self, &Foo) -> !"),
+        expect!("const fn(&'foo mut self, &'foo Foo) -> !"),
         expect!("pub const fn baz<'foo>(&'foo mut self, x: &'foo Foo) -> !"),
     );
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
index c7e2d058257..125e11e9e35 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
@@ -429,18 +429,18 @@ trait Tr<T> {
 impl Tr<$0
     "#,
         expect![[r#"
-            en Enum                    Enum
-            ma makro!(…) macro_rules! makro
+            en Enum                        Enum
+            ma makro!(…)     macro_rules! makro
             md module
-            sp Self       dyn Tr<{unknown}>
-            st Record                Record
-            st S                          S
-            st Tuple                  Tuple
-            st Unit                    Unit
+            sp Self dyn Tr<{unknown}> + 'static
+            st Record                    Record
+            st S                              S
+            st Tuple                      Tuple
+            st Unit                        Unit
             tt Tr
             tt Trait
-            un Union                  Union
-            bt u32                      u32
+            un Union                      Union
+            bt u32                          u32
             kw crate::
             kw self::
         "#]],
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs
index af25c2b2e33..a6da0fd9c5e 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/expected_function.rs
@@ -31,7 +31,7 @@ fn foo() {
     x();
  // ^^^ error: expected function, found i32
     ""();
- // ^^^^ error: expected function, found &str
+ // ^^^^ error: expected function, found &'static str
     foo();
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
index b56255b1fde..d72b21099ce 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -166,7 +166,7 @@ fn main() {
     let _ = ptr as bool;
           //^^^^^^^^^^^ error: cannot cast `*const ()` as `bool`
     let v = "hello" as bool;
-          //^^^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first
+          //^^^^^^^^^^^^^^^ error: casting `&'static str` as `bool` is invalid: needs casting through a raw pointer first
 }
 "#,
         );
@@ -956,7 +956,7 @@ fn main() {
 fn main() {
     let pointer: usize = &1_i32 as *const i32 as usize;
     let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 };
-                                          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&i32`
+                                          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&'static i32`
 }
 "#,
         );
@@ -992,7 +992,7 @@ impl Deref for Foo {
 
 fn main() {
     let _ = "foo" as bool;
-          //^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first
+          //^^^^^^^^^^^^^ error: casting `&'static str` as `bool` is invalid: needs casting through a raw pointer first
 
     let _ = Foo as bool;
           //^^^^^^^^^^^ error: non-primitive cast: `Foo` as `bool`
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
index 1db9b6d0494..500c5de791d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -306,10 +306,9 @@ fn str_ref_to_owned(
     acc: &mut Vec<Assist>,
 ) -> Option<()> {
     let expected = d.expected.display(ctx.sema.db, ctx.display_target);
-    let actual = d.actual.display(ctx.sema.db, ctx.display_target);
-
     // FIXME do this properly
-    if expected.to_string() != "String" || actual.to_string() != "&str" {
+    let is_applicable = d.actual.strip_reference().is_str() && expected.to_string() == "String";
+    if !is_applicable {
         return None;
     }
 
@@ -1176,7 +1175,7 @@ trait B {}
 
 fn test(a: &dyn A) -> &dyn B {
     a
-  //^ error: expected &dyn B, found &dyn A
+  //^ error: expected &(dyn B + 'static), found &(dyn A + 'static)
 }
 "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
index 1e7f00c2331..a933f1b4261 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs
@@ -151,7 +151,7 @@ fn main() {
 fn main() {
     let mut x = t();
     x = _;
-      //^ 💡 error: invalid `_` expression, expected type `&str`
+      //^ 💡 error: invalid `_` expression, expected type `&'static str`
     x = "";
 }
 fn t<T>() -> T { loop {} }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs
index 4422d8f8262..7f07009dc56 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs
@@ -269,7 +269,7 @@ impl<T, U> A<T, U> {
 }
 fn main() {
     let a = A {a: 0, b: ""};
-    A::<i32, &str>::foo();
+    A::<i32, &'static str>::foo();
 }
 "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index d469cd7c0cd..7b7eef9d579 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -7085,9 +7085,9 @@ fn foo() {
 }
 "#,
         expect![[r#"
-                ```rust
-                &str
-                ```"#]],
+            ```rust
+            &'static str
+            ```"#]],
     );
 }
 
@@ -8228,7 +8228,7 @@ format_args!("{aaaaa$0}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8248,7 +8248,7 @@ format_args!("{$0aaaaa}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8268,7 +8268,7 @@ format_args!(r"{$0aaaaa}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8293,7 +8293,7 @@ foo!(r"{$0aaaaa}");
             *aaaaa*
 
             ```rust
-            let aaaaa: &str
+            let aaaaa: &'static str
             ```
         "#]],
     );
@@ -8337,7 +8337,7 @@ fn main() {
         expect![[r#"
             *"🦀\u{1f980}\\\x41"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8353,7 +8353,7 @@ fn main() {
         expect![[r#"
             *r"🦀\u{1f980}\\\x41"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8375,7 +8375,7 @@ fsdghs";
 
             fsdghs"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8395,7 +8395,7 @@ fn main() {
         expect![[r#"
             *c"🦀\u{1f980}\\\x41"*
             ```rust
-            &{unknown}
+            &'static {unknown}
             ```
             ___
 
@@ -8414,7 +8414,7 @@ fn main() {
         expect![[r#"
             *r"`[^`]*`"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8429,7 +8429,7 @@ fn main() {
         expect![[r#"
             *r"`"*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8444,7 +8444,7 @@ fn main() {
         expect![[r#"
             *r"    "*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
@@ -8460,12 +8460,12 @@ fn main() {
         expect![[r#"
             *r" Hello World "*
             ```rust
-            &str
+            &'static str
             ```
             ___
 
             value of literal: `  Hello World  `
-"#]],
+        "#]],
     )
 }
 
@@ -8480,7 +8480,7 @@ fn main() {
         expect![[r#"
             *b"\xF0\x9F\xA6\x80\\"*
             ```rust
-            &[u8; 5]
+            &'static [u8; 5]
             ```
             ___
 
@@ -8496,7 +8496,7 @@ fn main() {
         expect![[r#"
             *br"\xF0\x9F\xA6\x80\\"*
             ```rust
-            &[u8; 18]
+            &'static [u8; 18]
             ```
             ___
 
@@ -9070,7 +9070,7 @@ struct Pedro$0<'a> {
 
             ```rust
             struct Pedro<'a> {
-                hola: &str,
+                hola: &'a str,
             }
             ```
 
@@ -9937,7 +9937,7 @@ fn baz() {
 
             ---
 
-            `U` = `i32`, `T` = `&str`
+            `U` = `i32`, `T` = `&'static str`
         "#]],
     );
 }
@@ -10030,7 +10030,7 @@ fn bar() {
 
             ---
 
-            `T` = `i8`, `U` = `&str`
+            `T` = `i8`, `U` = `&'static str`
         "#]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 52ea2e5ec58..36fdd90e8ae 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
@@ -380,9 +380,9 @@ fn main() {
     let foo = foo3();
      // ^^^ impl Fn(f64, f64) -> u32
     let foo = foo4();
-     // ^^^ &dyn Fn(f64, f64) -> u32
+     // ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static)
     let foo = foo5();
-     // ^^^ &dyn Fn(&dyn Fn(f64, f64) -> u32, f64) -> u32
+     // ^^^ &'static (dyn Fn(&(dyn Fn(f64, f64) -> u32 + 'static), f64) -> u32 + 'static)
     let foo = foo6();
      // ^^^ impl Fn(f64, f64) -> u32
     let foo = foo7();
@@ -413,7 +413,7 @@ fn main() {
     let foo = foo3();
      // ^^^ impl Fn(f64, f64) -> u32
     let foo = foo4();
-     // ^^^ &dyn Fn(f64, f64) -> u32
+     // ^^^ &'static (dyn Fn(f64, f64) -> u32 + 'static)
     let foo = foo5();
     let foo = foo6();
     let foo = foo7();
@@ -528,7 +528,7 @@ fn main() {
           //^^^^ i32
     let _ = 22;
     let test = "test";
-      //^^^^ &str
+      //^^^^ &'static str
     let test = InnerStruct {};
       //^^^^ InnerStruct
 
@@ -618,12 +618,12 @@ impl<T> Iterator for IntoIter<T> {
 
 fn main() {
     let mut data = Vec::new();
-          //^^^^ Vec<&str>
+          //^^^^ Vec<&'static str>
     data.push("foo");
     for i in data {
-      //^ &str
+      //^ &'static str
       let z = i;
-        //^ &str
+        //^ &'static str
     }
 }
 "#,
@@ -651,8 +651,8 @@ fn main() {
       //^^ Vec<Box<&(dyn Display + Sync)>>
     let _v = { Vec::<Box<*const (dyn Display + Sync)>>::new() };
       //^^ Vec<Box<*const (dyn Display + Sync)>>
-    let _v = { Vec::<Box<dyn Display + Sync>>::new() };
-      //^^ Vec<Box<dyn Display + Sync>>
+    let _v = { Vec::<Box<dyn Display + Sync + 'static>>::new() };
+      //^^ Vec<Box<dyn Display + Sync + 'static>>
 }
 "#,
         );
@@ -1017,7 +1017,7 @@ fn test<T>(t: T) {
 "#,
             expect![[r#"
                 fn test<T>(t: T) {
-                    let f = |a: i32, b: &str, c: T| {};
+                    let f = |a: i32, b: &'static str, c: T| {};
                     let result: () = f(42, "", t);
                 }
             "#]],
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
index de9ca8c000f..2ec85da4a42 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
@@ -194,7 +194,7 @@ impl Tr for () {
 //^ impl Tr for ()
 impl dyn Tr {
   }
-//^ impl dyn Tr
+//^ impl dyn Tr + 'static
 
 static S0: () = 0;
 static S1: () = {};
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
index 96c2ceef6ba..f6bcb5642c3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -1064,7 +1064,7 @@ fn main() {
         ),
         work_done_progress_params: Default::default(),
     });
-    assert!(res.to_string().contains("&str"));
+    assert!(res.to_string().contains("&'static str"));
 
     let res = server.send_request::<HoverRequest>(HoverParams {
         text_document_position_params: TextDocumentPositionParams::new(
@@ -1073,7 +1073,7 @@ fn main() {
         ),
         work_done_progress_params: Default::default(),
     });
-    assert!(res.to_string().contains("&str"));
+    assert!(res.to_string().contains("&'static str"));
 
     server.request::<GotoTypeDefinition>(
         GotoDefinitionParams {