about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-25 07:36:47 +0000
committerbors <bors@rust-lang.org>2024-04-25 07:36:47 +0000
commita2259bb8a27bf0818485cc614b7e70cebd5f3c50 (patch)
treeb55fbfda5243b797617fc5dd74af671bbe323e2b /src
parentd00de3859961f60739a27cb5b6dca7d726c6209c (diff)
parent10e82da69d89f96ca31529a3b8f55d3c2436eba0 (diff)
Auto merge of #17134 - Veykril:lt-err-display, r=Veykril
internal: Don't render unknown lifetimes when rendering generic args

cc https://github.com/rust-lang/rust-analyzer/issues/17098
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs56
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/diagnostics.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs34
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs32
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs208
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs148
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs418
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs226
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs21
15 files changed, 631 insertions, 586 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 a357e850351..c010f5d22b6 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -797,8 +797,20 @@ impl HirDisplay for Ty {
                 c.hir_fmt(f)?;
                 write!(f, "]")?;
             }
-            TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => {
-                if matches!(self.kind(Interner), TyKind::Raw(..)) {
+            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
+                        l.hir_fmt(f)?;
+                        f.write_char(' ')?;
+                    }
+                    match m {
+                        Mutability::Not => (),
+                        Mutability::Mut => f.write_str("mut ")?,
+                    }
+                } else {
                     write!(
                         f,
                         "*{}",
@@ -807,15 +819,6 @@ impl HirDisplay for Ty {
                             Mutability::Mut => "mut ",
                         }
                     )?;
-                } else {
-                    write!(
-                        f,
-                        "&{}",
-                        match m {
-                            Mutability::Not => "",
-                            Mutability::Mut => "mut ",
-                        }
-                    )?;
                 }
 
                 // FIXME: all this just to decide whether to use parentheses...
@@ -1330,7 +1333,18 @@ fn hir_fmt_generics(
     }
 
     let parameters_to_write = generic_args_sans_defaults(f, generic_def, parameters);
-    if !parameters_to_write.is_empty() {
+
+    // FIXME: Remote this
+    // most of our lifetimes will be errors as we lack elision and inference
+    // so don't render them for now
+    let only_err_lifetimes = !cfg!(test)
+        && parameters_to_write.iter().all(|arg| {
+            matches!(
+                arg.data(Interner),
+                chalk_ir::GenericArgData::Lifetime(it) if *it.data(Interner) == LifetimeData::Error
+            )
+        });
+    if !parameters_to_write.is_empty() && !only_err_lifetimes {
         write!(f, "<")?;
         hir_fmt_generic_arguments(f, parameters_to_write)?;
         write!(f, ">")?;
@@ -1403,6 +1417,18 @@ fn hir_fmt_generic_arguments(
         None => (parameters, &[][..]),
     };
     for generic_arg in lifetimes.iter().chain(ty_or_const) {
+        // FIXME: Remove this
+        // most of our lifetimes will be errors as we lack elision and inference
+        // so don't render them for now
+        if !cfg!(test)
+            && matches!(
+                generic_arg.lifetime(Interner),
+                Some(l) if ***l.interned() == LifetimeData::Error
+            )
+        {
+            continue;
+        }
+
         if !first {
             write!(f, ", ")?;
         }
@@ -1728,9 +1754,9 @@ impl HirDisplay for LifetimeData {
             LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
             LifetimeData::InferenceVar(_) => write!(f, "_"),
             LifetimeData::Static => write!(f, "'static"),
-            LifetimeData::Error => write!(f, "'{{error}}"),
-            LifetimeData::Erased => Ok(()),
-            LifetimeData::Phantom(_, _) => Ok(()),
+            LifetimeData::Error => write!(f, "'?"),
+            LifetimeData::Erased => write!(f, "'<erased>"),
+            LifetimeData::Phantom(void, _) => match *void {},
         }
     }
 }
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 d56b15b9b74..526db2af6dc 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
@@ -186,7 +186,7 @@ fn test() {
     let x = match 1 {
         1 => t as *mut i32,
         2 => t as &i32,
-           //^^^^^^^^^ expected *mut i32, got &i32
+           //^^^^^^^^^ expected *mut i32, got &'? i32
         _ => t as *const i32,
           // ^^^^^^^^^^^^^^^ adjustments: Pointer(MutToConstPointer)
 
@@ -307,7 +307,7 @@ fn test() {
     let foo = Foo;
       //^^^ type: Foo<{unknown}>
     let _: &u32 = &Foo;
-                //^^^^ expected &u32, got &Foo<{unknown}>
+                //^^^^ expected &'? u32, got &'? Foo<{unknown}>
 }",
     );
 }
@@ -544,9 +544,9 @@ struct Bar<T>(Foo<T>);
 
 fn test() {
     let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
-                         //^^^^^^^^^^^^^^^^^^^^^ expected &Foo<[usize]>, got &Foo<[i32; 3]>
+                         //^^^^^^^^^^^^^^^^^^^^^ expected &'? Foo<[usize]>, got &'? Foo<[i32; 3]>
     let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
-                         //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &Bar<[usize]>, got &Bar<[i32; 3]>
+                         //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &'? Bar<[usize]>, got &'? Bar<[i32; 3]>
 }
 "#,
     );
@@ -562,7 +562,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, got &'? impl Foo + ?Sized
 }
         "#,
     );
@@ -828,11 +828,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/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/diagnostics.rs
index 119de7f050e..def06f2d59d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/diagnostics.rs
@@ -8,7 +8,7 @@ fn function_return_type_mismatch_1() {
         r#"
 fn test() -> &'static str {
     5
-  //^ expected &str, got i32
+  //^ expected &'static str, got i32
 }
 "#,
     );
@@ -21,7 +21,7 @@ fn function_return_type_mismatch_2() {
 fn test(x: bool) -> &'static str {
     if x {
         return 1;
-             //^ expected &str, got i32
+             //^ expected &'static str, got i32
     }
     "ok"
 }
@@ -38,7 +38,7 @@ fn test(x: bool) -> &'static str {
         return "ok";
     }
     1
-  //^ expected &str, got i32
+  //^ expected &'static str, got i32
 }
 "#,
     );
@@ -53,7 +53,7 @@ fn test(x: bool) -> &'static str {
         "ok"
     } else {
         1
-      //^ expected &str, got i32
+      //^ expected &'static str, got i32
     }
 }
 "#,
@@ -67,7 +67,7 @@ fn function_return_type_mismatch_5() {
 fn test(x: bool) -> &'static str {
     if x {
         1
-      //^ expected &str, got i32
+      //^ expected &'static str, got i32
     } else {
         "ok"
     }
@@ -83,10 +83,10 @@ fn non_unit_block_expr_stmt_no_semi() {
 fn test(x: bool) {
     if x {
         "notok"
-      //^^^^^^^ expected (), got &str
+      //^^^^^^^ expected (), got &'static str
     } else {
         "ok"
-      //^^^^ expected (), got &str
+      //^^^^ expected (), got &'static str
     }
     match x { true => true, false => 0 }
   //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), got bool
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 e8369caa771..60c03b52246 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
@@ -67,11 +67,11 @@ trait B: A {}
 
 fn test(
     _: &(dyn A<Assoc = ()> + Send),
-  //^ &(dyn A<Assoc = ()> + Send)
+  //^ &'_ (dyn A<Assoc = ()> + Send)
     _: &(dyn Send + A<Assoc = ()>),
-  //^ &(dyn A<Assoc = ()> + Send)
+  //^ &'_ (dyn A<Assoc = ()> + Send)
     _: &dyn B<Assoc = ()>,
-  //^ &(dyn B<Assoc = ()>)
+  //^ &'_ (dyn B<Assoc = ()>)
 ) {}
         "#,
     );
@@ -85,7 +85,7 @@ fn render_dyn_for_ty() {
 trait Foo<'a> {}
 
 fn foo(foo: &dyn for<'a> Foo<'a>) {}
-    // ^^^ &dyn Foo<'_>
+    // ^^^ &'_ dyn Foo<'_>
 "#,
     );
 }
@@ -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/macros.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
index 2f75338f994..a0899cb1d63 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs
@@ -200,8 +200,8 @@ fn expr_macro_def_expanded_in_various_places() {
             100..119 'for _ ...!() {}': IntoIterator::IntoIter<isize>
             100..119 'for _ ...!() {}': !
             100..119 'for _ ...!() {}': IntoIterator::IntoIter<isize>
-            100..119 'for _ ...!() {}': &mut IntoIterator::IntoIter<isize>
-            100..119 'for _ ...!() {}': fn next<IntoIterator::IntoIter<isize>>(&mut IntoIterator::IntoIter<isize>) -> Option<<IntoIterator::IntoIter<isize> as Iterator>::Item>
+            100..119 'for _ ...!() {}': &'? mut IntoIterator::IntoIter<isize>
+            100..119 'for _ ...!() {}': fn next<IntoIterator::IntoIter<isize>>(&'? mut IntoIterator::IntoIter<isize>) -> Option<<IntoIterator::IntoIter<isize> as Iterator>::Item>
             100..119 'for _ ...!() {}': Option<IntoIterator::Item<isize>>
             100..119 'for _ ...!() {}': ()
             100..119 'for _ ...!() {}': ()
@@ -221,7 +221,7 @@ fn expr_macro_def_expanded_in_various_places() {
             281..303 'Spam {...m!() }': {unknown}
             309..325 'spam!(...am!()]': {unknown}
             350..366 'spam!(... usize': usize
-            372..380 '&spam!()': &isize
+            372..380 '&spam!()': &'? isize
             386..394 '-spam!()': isize
             400..416 'spam!(...pam!()': {unknown}
             422..439 'spam!(...pam!()': isize
@@ -293,8 +293,8 @@ fn expr_macro_rules_expanded_in_various_places() {
             114..133 'for _ ...!() {}': IntoIterator::IntoIter<isize>
             114..133 'for _ ...!() {}': !
             114..133 'for _ ...!() {}': IntoIterator::IntoIter<isize>
-            114..133 'for _ ...!() {}': &mut IntoIterator::IntoIter<isize>
-            114..133 'for _ ...!() {}': fn next<IntoIterator::IntoIter<isize>>(&mut IntoIterator::IntoIter<isize>) -> Option<<IntoIterator::IntoIter<isize> as Iterator>::Item>
+            114..133 'for _ ...!() {}': &'? mut IntoIterator::IntoIter<isize>
+            114..133 'for _ ...!() {}': fn next<IntoIterator::IntoIter<isize>>(&'? mut IntoIterator::IntoIter<isize>) -> Option<<IntoIterator::IntoIter<isize> as Iterator>::Item>
             114..133 'for _ ...!() {}': Option<IntoIterator::Item<isize>>
             114..133 'for _ ...!() {}': ()
             114..133 'for _ ...!() {}': ()
@@ -314,7 +314,7 @@ fn expr_macro_rules_expanded_in_various_places() {
             295..317 'Spam {...m!() }': {unknown}
             323..339 'spam!(...am!()]': {unknown}
             364..380 'spam!(... usize': usize
-            386..394 '&spam!()': &isize
+            386..394 '&spam!()': &'? isize
             400..408 '-spam!()': isize
             414..430 'spam!(...pam!()': {unknown}
             436..453 'spam!(...pam!()': isize
@@ -539,7 +539,7 @@ fn test() {
     let msg = foo::Message(foo::MessageRef);
     let r = msg.deref();
     r;
-  //^ &MessageRef
+  //^ &'? MessageRef
 }
 
 //- /lib.rs crate:foo
@@ -703,9 +703,9 @@ fn infer_builtin_macros_file() {
         }
         "#,
         expect![[r#"
-            !0..2 '""': &str
+            !0..2 '""': &'static str
             63..87 '{     ...!(); }': ()
-            73..74 'x': &str
+            73..74 'x': &'static str
         "#]],
     );
 }
@@ -741,9 +741,9 @@ fn infer_builtin_macros_concat() {
         }
         "#,
         expect![[r#"
-            !0..13 '"helloworld!"': &str
+            !0..13 '"helloworld!"': &'static str
             65..121 '{     ...")); }': ()
-            75..76 'x': &str
+            75..76 'x': &'static str
         "#]],
     );
 }
@@ -820,7 +820,7 @@ macro_rules! include_str {() => {}}
 fn main() {
     let a = include_str!("foo.rs");
     a;
-} //^ &str
+} //^ &'static str
 
 //- /foo.rs
 hello
@@ -847,7 +847,7 @@ macro_rules! m {
 fn main() {
     let a = include_str!(m!(".rs"));
     a;
-} //^ &str
+} //^ &'static str
 
 //- /foo.rs
 hello
@@ -960,9 +960,9 @@ fn infer_builtin_macros_concat_with_lazy() {
         }
         "#,
         expect![[r#"
-            !0..13 '"helloworld!"': &str
+            !0..13 '"helloworld!"': &'static str
             103..160 '{     ...")); }': ()
-            113..114 'x': &str
+            113..114 'x': &'static str
         "#]],
     );
 }
@@ -977,7 +977,7 @@ fn infer_builtin_macros_env() {
 
         fn main() {
             let x = env!("foo");
-              //^ &str
+              //^ &'static str
         }
         "#,
     );
@@ -991,7 +991,7 @@ fn infer_builtin_macros_option_env() {
 //- /main.rs env:foo=bar
 fn main() {
     let x = option_env!("foo");
-      //^ Option<&str>
+      //^ Option<&'static str>
 }
         "#,
     );
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 8609ba41039..63a83d403fa 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
@@ -658,7 +658,7 @@ fn infer_call_trait_method_on_generic_param_1() {
         }
         "#,
         expect![[r#"
-            29..33 'self': &Self
+            29..33 'self': &'? Self
             63..64 't': T
             69..88 '{     ...d(); }': ()
             75..76 't': T
@@ -679,7 +679,7 @@ fn infer_call_trait_method_on_generic_param_2() {
         }
         "#,
         expect![[r#"
-            32..36 'self': &Self
+            32..36 'self': &'? Self
             70..71 't': T
             76..95 '{     ...d(); }': ()
             82..83 't': T
@@ -757,7 +757,7 @@ struct S;
 impl Clone for S {}
 impl Clone for &S {}
 fn test() { (S.clone(), (&S).clone(), (&&S).clone()); }
-          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (S, S, &S)
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (S, S, &'? S)
 "#,
     );
 }
@@ -1150,12 +1150,12 @@ fn dyn_trait_super_trait_not_in_scope() {
         }
         "#,
         expect![[r#"
-            51..55 'self': &Self
+            51..55 'self': &'? Self
             64..69 '{ 0 }': u32
             66..67 '0': u32
-            176..177 'd': &dyn Trait
+            176..177 'd': &'? dyn Trait
             191..207 '{     ...o(); }': ()
-            197..198 'd': &dyn Trait
+            197..198 'd': &'? dyn Trait
             197..204 'd.foo()': u32
         "#]],
     );
@@ -1182,15 +1182,15 @@ fn test() {
 }
 "#,
         expect![[r#"
-            75..79 'self': &S
+            75..79 'self': &'? S
             89..109 '{     ...     }': bool
             99..103 'true': bool
             123..167 '{     ...o(); }': ()
-            133..134 's': &S
-            137..151 'unsafe { f() }': &S
-            146..147 'f': fn f() -> &S
-            146..149 'f()': &S
-            157..158 's': &S
+            133..134 's': &'? S
+            137..151 'unsafe { f() }': &'static S
+            146..147 'f': fn f() -> &'static S
+            146..149 'f()': &'static S
+            157..158 's': &'? S
             157..164 's.foo()': bool
         "#]],
     );
@@ -1601,11 +1601,11 @@ use core::IntoIterator;
 fn f() {
     let v = [4].into_iter();
     v;
-  //^ &i32
+  //^ &'? i32
 
     let a = [0, 1].into_iter();
     a;
-  //^ &i32
+  //^ &'? i32
 }
 
 //- /main2021.rs crate:main2021 deps:core edition:2021
@@ -1618,7 +1618,7 @@ fn f() {
 
     let a = [0, 1].into_iter();
     a;
-  //^ &i32
+  //^ &'? i32
 }
 
 //- /core.rs crate:core
@@ -1767,7 +1767,7 @@ fn test() {
     let a2 = A(make(), 1i32);
     let _: &str = a2.thing();
     a2;
-  //^^ A<C<&str>, i32>
+  //^^ A<C<&'? str>, i32>
 }
 "#,
     );
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs
index 5d809b82392..0ccbcf63e2b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs
@@ -104,7 +104,7 @@ enum Option<T> { None, Some(T) }
 fn test() {
     let a = if true { Option::None } else { Option::Some(return) };
     a;
-  //^ Option<&str>
+  //^ Option<&'static str>
     match 42 {
         42 => a,
         _ => Option::Some("str"),
@@ -317,8 +317,8 @@ fn diverging_expression_2() {
             63..81 '{ loop...foo" }': u32
             65..72 'loop {}': !
             70..72 '{}': ()
-            74..79 '"foo"': &str
-            74..79: expected u32, got &str
+            74..79 '"foo"': &'static str
+            74..79: expected u32, got &'static str
         "#]],
     );
 }
@@ -365,8 +365,8 @@ fn diverging_expression_3_break() {
             151..172 'for a ...eak; }': {unknown}
             151..172 'for a ...eak; }': !
             151..172 'for a ...eak; }': {unknown}
-            151..172 'for a ...eak; }': &mut {unknown}
-            151..172 'for a ...eak; }': fn next<{unknown}>(&mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
+            151..172 'for a ...eak; }': &'? mut {unknown}
+            151..172 'for a ...eak; }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
             151..172 'for a ...eak; }': Option<{unknown}>
             151..172 'for a ...eak; }': ()
             151..172 'for a ...eak; }': ()
@@ -381,8 +381,8 @@ fn diverging_expression_3_break() {
             237..250 'for a in b {}': {unknown}
             237..250 'for a in b {}': !
             237..250 'for a in b {}': {unknown}
-            237..250 'for a in b {}': &mut {unknown}
-            237..250 'for a in b {}': fn next<{unknown}>(&mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
+            237..250 'for a in b {}': &'? mut {unknown}
+            237..250 'for a in b {}': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
             237..250 'for a in b {}': Option<{unknown}>
             237..250 'for a in b {}': ()
             237..250 'for a in b {}': ()
@@ -396,8 +396,8 @@ fn diverging_expression_3_break() {
             315..337 'for a ...urn; }': {unknown}
             315..337 'for a ...urn; }': !
             315..337 'for a ...urn; }': {unknown}
-            315..337 'for a ...urn; }': &mut {unknown}
-            315..337 'for a ...urn; }': fn next<{unknown}>(&mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
+            315..337 'for a ...urn; }': &'? mut {unknown}
+            315..337 'for a ...urn; }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
             315..337 'for a ...urn; }': Option<{unknown}>
             315..337 'for a ...urn; }': ()
             315..337 'for a ...urn; }': ()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
index 4355881d729..5e040a60e29 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
@@ -32,27 +32,27 @@ fn infer_pattern() {
         }
         "#,
         expect![[r#"
-            8..9 'x': &i32
+            8..9 'x': &'? i32
             17..400 '{     ...o_x; }': ()
-            27..28 'y': &i32
-            31..32 'x': &i32
-            42..44 '&z': &i32
+            27..28 'y': &'? i32
+            31..32 'x': &'? i32
+            42..44 '&z': &'? i32
             43..44 'z': i32
-            47..48 'x': &i32
+            47..48 'x': &'? i32
             58..59 'a': i32
             62..63 'z': i32
-            73..79 '(c, d)': (i32, &str)
+            73..79 '(c, d)': (i32, &'static str)
             74..75 'c': i32
-            77..78 'd': &str
-            82..94 '(1, "hello")': (i32, &str)
+            77..78 'd': &'static str
+            82..94 '(1, "hello")': (i32, &'static str)
             83..84 '1': i32
-            86..93 '"hello"': &str
+            86..93 '"hello"': &'static str
             101..151 'for (e...     }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter
             101..151 'for (e...     }': {unknown}
             101..151 'for (e...     }': !
             101..151 'for (e...     }': {unknown}
-            101..151 'for (e...     }': &mut {unknown}
-            101..151 'for (e...     }': fn next<{unknown}>(&mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
+            101..151 'for (e...     }': &'? mut {unknown}
+            101..151 'for (e...     }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
             101..151 'for (e...     }': Option<({unknown}, {unknown})>
             101..151 'for (e...     }': ()
             101..151 'for (e...     }': ()
@@ -74,10 +74,10 @@ fn infer_pattern() {
             194..197 'val': {unknown}
             210..236 'if let...rue {}': ()
             213..233 'let x ... &true': bool
-            217..225 'x @ true': &bool
+            217..225 'x @ true': &'? bool
             221..225 'true': bool
             221..225 'true': bool
-            228..233 '&true': &bool
+            228..233 '&true': &'? bool
             229..233 'true': bool
             234..236 '{}': ()
             246..252 'lambda': impl Fn(u64, u64, i32) -> i32
@@ -90,14 +90,14 @@ fn infer_pattern() {
             277..282 'a + b': u64
             281..282 'b': u64
             284..285 'c': i32
-            298..310 'ref ref_to_x': &&i32
-            313..314 'x': &i32
-            324..333 'mut mut_x': &i32
-            336..337 'x': &i32
-            347..367 'ref mu...f_to_x': &mut &i32
-            370..371 'x': &i32
-            381..382 'k': &mut &i32
-            385..397 'mut_ref_to_x': &mut &i32
+            298..310 'ref ref_to_x': &'? &'? i32
+            313..314 'x': &'? i32
+            324..333 'mut mut_x': &'? i32
+            336..337 'x': &'? i32
+            347..367 'ref mu...f_to_x': &'? mut &'? i32
+            370..371 'x': &'? i32
+            381..382 'k': &'? mut &'? i32
+            385..397 'mut_ref_to_x': &'? mut &'? i32
         "#]],
     );
 }
@@ -120,14 +120,14 @@ fn infer_literal_pattern() {
             17..28 '{ loop {} }': T
             19..26 'loop {}': !
             24..26 '{}': ()
-            37..38 'x': &i32
+            37..38 'x': &'? i32
             46..208 '{     ...) {} }': ()
             52..75 'if let...y() {}': ()
             55..72 'let "f... any()': bool
-            59..64 '"foo"': &str
-            59..64 '"foo"': &str
-            67..70 'any': fn any<&str>() -> &str
-            67..72 'any()': &str
+            59..64 '"foo"': &'static str
+            59..64 '"foo"': &'static str
+            67..70 'any': fn any<&'static str>() -> &'static str
+            67..72 'any()': &'static str
             73..75 '{}': ()
             80..99 'if let...y() {}': ()
             83..96 'let 1 = any()': bool
@@ -178,7 +178,7 @@ fn infer_range_pattern() {
         }
         "#,
         expect![[r#"
-            8..9 'x': &i32
+            8..9 'x': &'? i32
             17..75 '{     ...2 {} }': ()
             23..45 'if let...u32 {}': ()
             26..42 'let 1....= 2u32': bool
@@ -208,14 +208,14 @@ fn infer_pattern_match_ergonomics() {
         expect![[r#"
             27..78 '{     ...(1); }': ()
             37..41 'A(n)': A<i32>
-            39..40 'n': &i32
-            44..49 '&A(1)': &A<i32>
+            39..40 'n': &'? i32
+            44..49 '&A(1)': &'? A<i32>
             45..46 'A': extern "rust-call" A<i32>(i32) -> A<i32>
             45..49 'A(1)': A<i32>
             47..48 '1': i32
             59..63 'A(n)': A<i32>
-            61..62 'n': &mut i32
-            66..75 '&mut A(1)': &mut A<i32>
+            61..62 'n': &'? mut i32
+            66..75 '&mut A(1)': &'? mut A<i32>
             71..72 'A': extern "rust-call" A<i32>(i32) -> A<i32>
             71..75 'A(1)': A<i32>
             73..74 '1': i32
@@ -235,17 +235,17 @@ fn infer_pattern_match_ergonomics_ref() {
         "#,
         expect![[r#"
             10..56 '{     ...= v; }': ()
-            20..21 'v': &(i32, &i32)
-            24..32 '&(1, &2)': &(i32, &i32)
-            25..32 '(1, &2)': (i32, &i32)
+            20..21 'v': &'? (i32, &'? i32)
+            24..32 '&(1, &2)': &'? (i32, &'? i32)
+            25..32 '(1, &2)': (i32, &'? i32)
             26..27 '1': i32
-            29..31 '&2': &i32
+            29..31 '&2': &'? i32
             30..31 '2': i32
-            42..49 '(_, &w)': (i32, &i32)
+            42..49 '(_, &w)': (i32, &'? i32)
             43..44 '_': i32
-            46..48 '&w': &i32
+            46..48 '&w': &'? i32
             47..48 'w': i32
-            52..53 'v': &(i32, &i32)
+            52..53 'v': &'? (i32, &'? i32)
         "#]],
     );
 }
@@ -286,28 +286,28 @@ fn infer_pattern_match_slice() {
         "#,
         expect![[r#"
             10..209 '{     ...   } }': ()
-            20..25 'slice': &[f64]
-            36..42 '&[0.0]': &[f64; 1]
+            20..25 'slice': &'? [f64]
+            36..42 '&[0.0]': &'? [f64; 1]
             37..42 '[0.0]': [f64; 1]
             38..41 '0.0': f64
             48..207 'match ...     }': ()
-            54..59 'slice': &[f64]
-            70..73 '&[]': &[f64]
+            54..59 'slice': &'? [f64]
+            70..73 '&[]': &'? [f64]
             71..73 '[]': [f64]
             77..79 '{}': ()
-            89..93 '&[a]': &[f64]
+            89..93 '&[a]': &'? [f64]
             90..93 '[a]': [f64]
             91..92 'a': f64
             97..123 '{     ...     }': ()
             111..112 'a': f64
-            133..140 '&[b, c]': &[f64]
+            133..140 '&[b, c]': &'? [f64]
             134..140 '[b, c]': [f64]
             135..136 'b': f64
             138..139 'c': f64
             144..185 '{     ...     }': ()
             158..159 'b': f64
             173..174 'c': f64
-            194..195 '_': &[f64]
+            194..195 '_': &'? [f64]
             199..201 '{}': ()
         "#]],
     );
@@ -327,14 +327,14 @@ fn infer_pattern_match_string_literal() {
         "#,
         expect![[r#"
             10..98 '{     ...   } }': ()
-            20..21 's': &str
-            30..37 '"hello"': &str
+            20..21 's': &'? str
+            30..37 '"hello"': &'static str
             43..96 'match ...     }': ()
-            49..50 's': &str
-            61..68 '"hello"': &str
-            61..68 '"hello"': &str
+            49..50 's': &'? str
+            61..68 '"hello"': &'static str
+            61..68 '"hello"': &'static str
             72..74 '{}': ()
-            83..84 '_': &str
+            83..84 '_': &'? str
             88..90 '{}': ()
         "#]],
     );
@@ -358,27 +358,27 @@ fn infer_pattern_match_byte_string_literal() {
         }
         "#,
         expect![[r#"
-            105..109 'self': &[T; N]
+            105..109 'self': &'? [T; N]
             111..116 'index': {unknown}
-            157..180 '{     ...     }': &[u8]
+            157..180 '{     ...     }': &'? [u8]
             167..174 'loop {}': !
             172..174 '{}': ()
             191..192 'v': [u8; 3]
             203..261 '{     ...v {} }': ()
             209..233 'if let...[S] {}': ()
             212..230 'let b"... &v[S]': bool
-            216..222 'b"foo"': &[u8]
-            216..222 'b"foo"': &[u8]
-            225..230 '&v[S]': &[u8]
+            216..222 'b"foo"': &'static [u8]
+            216..222 'b"foo"': &'static [u8]
+            225..230 '&v[S]': &'? [u8]
             226..227 'v': [u8; 3]
             226..230 'v[S]': [u8]
             228..229 'S': S
             231..233 '{}': ()
             238..259 'if let... &v {}': ()
             241..256 'let b"foo" = &v': bool
-            245..251 'b"foo"': &[u8; 3]
-            245..251 'b"foo"': &[u8; 3]
-            254..256 '&v': &[u8; 3]
+            245..251 'b"foo"': &'static [u8; 3]
+            245..251 'b"foo"': &'static [u8; 3]
+            254..256 '&v': &'? [u8; 3]
             255..256 'v': [u8; 3]
             257..259 '{}': ()
         "#]],
@@ -399,17 +399,17 @@ fn infer_pattern_match_or() {
         "#,
         expect![[r#"
             10..108 '{     ...   } }': ()
-            20..21 's': &str
-            30..37 '"hello"': &str
+            20..21 's': &'? str
+            30..37 '"hello"': &'static str
             43..106 'match ...     }': ()
-            49..50 's': &str
-            61..68 '"hello"': &str
-            61..68 '"hello"': &str
-            61..78 '"hello...world"': &str
-            71..78 '"world"': &str
-            71..78 '"world"': &str
+            49..50 's': &'? str
+            61..68 '"hello"': &'static str
+            61..68 '"hello"': &'static str
+            61..78 '"hello...world"': &'? str
+            71..78 '"world"': &'static str
+            71..78 '"world"': &'static str
             82..84 '{}': ()
-            93..94 '_': &str
+            93..94 '_': &'? str
             98..100 '{}': ()
         "#]],
     );
@@ -505,10 +505,10 @@ fn infer_adt_pattern() {
             216..217 '1': usize
             227..231 'E::B': E
             235..237 '10': usize
-            255..274 'ref d ...{ .. }': &E
+            255..274 'ref d ...{ .. }': &'? E
             263..274 'E::A { .. }': E
             277..278 'e': E
-            284..285 'd': &E
+            284..285 'd': &'? E
         "#]],
     );
 }
@@ -529,14 +529,14 @@ impl Foo {
         expect![[r#"
             42..151 '{     ...     }': ()
             56..64 'Self(s,)': Foo
-            61..62 's': &usize
-            67..75 '&Foo(0,)': &Foo
+            61..62 's': &'? usize
+            67..75 '&Foo(0,)': &'? Foo
             68..71 'Foo': extern "rust-call" Foo(usize) -> Foo
             68..75 'Foo(0,)': Foo
             72..73 '0': usize
             89..97 'Self(s,)': Foo
-            94..95 's': &mut usize
-            100..112 '&mut Foo(0,)': &mut Foo
+            94..95 's': &'? mut usize
+            100..112 '&mut Foo(0,)': &'? mut Foo
             105..108 'Foo': extern "rust-call" Foo(usize) -> Foo
             105..112 'Foo(0,)': Foo
             109..110 '0': usize
@@ -669,7 +669,7 @@ fn main() {
 }
         "#,
         expect![[r#"
-            27..31 'self': &S
+            27..31 'self': &'? S
             41..50 '{ false }': bool
             43..48 'false': bool
             64..115 '{     ...   } }': ()
@@ -679,7 +679,7 @@ fn main() {
             93..94 's': S
             93..100 's.foo()': bool
             104..106 '()': ()
-    "#]],
+        "#]],
     )
 }
 
@@ -702,29 +702,29 @@ fn test() {
             51..58 'loop {}': !
             56..58 '{}': ()
             72..171 '{     ... x); }': ()
-            78..81 'foo': fn foo<&(i32, &str), i32, impl FnOnce(&(i32, &str)) -> i32>(&(i32, &str), impl FnOnce(&(i32, &str)) -> i32) -> i32
+            78..81 'foo': fn foo<&'? (i32, &'? str), i32, impl FnOnce(&'? (i32, &'? str)) -> i32>(&'? (i32, &'? str), impl FnOnce(&'? (i32, &'? str)) -> i32) -> i32
             78..105 'foo(&(...y)| x)': i32
-            82..91 '&(1, "a")': &(i32, &str)
-            83..91 '(1, "a")': (i32, &str)
+            82..91 '&(1, "a")': &'? (i32, &'static str)
+            83..91 '(1, "a")': (i32, &'static str)
             84..85 '1': i32
-            87..90 '"a"': &str
-            93..104 '|&(x, y)| x': impl FnOnce(&(i32, &str)) -> i32
-            94..101 '&(x, y)': &(i32, &str)
-            95..101 '(x, y)': (i32, &str)
+            87..90 '"a"': &'static str
+            93..104 '|&(x, y)| x': impl FnOnce(&'? (i32, &'? str)) -> i32
+            94..101 '&(x, y)': &'? (i32, &'? str)
+            95..101 '(x, y)': (i32, &'? str)
             96..97 'x': i32
-            99..100 'y': &str
+            99..100 'y': &'? str
             103..104 'x': i32
-            142..145 'foo': fn foo<&(i32, &str), &i32, impl FnOnce(&(i32, &str)) -> &i32>(&(i32, &str), impl FnOnce(&(i32, &str)) -> &i32) -> &i32
-            142..168 'foo(&(...y)| x)': &i32
-            146..155 '&(1, "a")': &(i32, &str)
-            147..155 '(1, "a")': (i32, &str)
+            142..145 'foo': fn foo<&'? (i32, &'? str), &'? i32, impl FnOnce(&'? (i32, &'? str)) -> &'? i32>(&'? (i32, &'? str), impl FnOnce(&'? (i32, &'? str)) -> &'? i32) -> &'? i32
+            142..168 'foo(&(...y)| x)': &'? i32
+            146..155 '&(1, "a")': &'? (i32, &'static str)
+            147..155 '(1, "a")': (i32, &'static str)
             148..149 '1': i32
-            151..154 '"a"': &str
-            157..167 '|(x, y)| x': impl FnOnce(&(i32, &str)) -> &i32
-            158..164 '(x, y)': (i32, &str)
-            159..160 'x': &i32
-            162..163 'y': &&str
-            166..167 'x': &i32
+            151..154 '"a"': &'static str
+            157..167 '|(x, y)| x': impl FnOnce(&'? (i32, &'? str)) -> &'? i32
+            158..164 '(x, y)': (i32, &'? str)
+            159..160 'x': &'? i32
+            162..163 'y': &'? &'? str
+            166..167 'x': &'? i32
         "#]],
     );
 }
@@ -741,13 +741,13 @@ fn slice_tail_pattern() {
         }
         "#,
         expect![[r#"
-            7..13 'params': &[i32]
+            7..13 'params': &'? [i32]
             23..92 '{     ...   } }': ()
             29..90 'match ...     }': ()
-            35..41 'params': &[i32]
+            35..41 'params': &'? [i32]
             52..69 '[head,... @ ..]': [i32]
-            53..57 'head': &i32
-            59..68 'tail @ ..': &[i32]
+            53..57 'head': &'? i32
+            59..68 'tail @ ..': &'? [i32]
             66..68 '..': [i32]
             73..84 '{         }': ()
         "#]],
@@ -1109,7 +1109,7 @@ fn var_args() {
 #[lang = "va_list"]
 pub struct VaListImpl<'f>;
 fn my_fn(foo: ...) {}
-       //^^^ VaListImpl<'{error}>
+       //^^^ VaListImpl<'?>
 "#,
     );
 }
@@ -1122,9 +1122,9 @@ fn foo() {
     let &() = &();
     let &mut () = &mut ();
     let &mut () = &();
-      //^^^^^^^ expected &(), got &mut ()
+      //^^^^^^^ expected &'? (), got &'? mut ()
     let &() = &mut ();
-      //^^^ expected &mut (), got &()
+      //^^^ expected &'? mut (), got &'? ()
 }
 "#,
     );
@@ -1148,7 +1148,7 @@ fn main() {
     };
 
     if let Wrap::<X>::A { cool, ..} = &wrapped {}
-                        //^^^^ &u32
+                        //^^^^ &'? u32
 }
 "#,
     );
@@ -1182,7 +1182,7 @@ fn main() {
     };
 
     if let Wrap::<<S as Schematic>::Props>::A { cool, ..} = &wrapped {}
-                                              //^^^^ &u32
+                                              //^^^^ &'? u32
 }
 "#,
     );
@@ -1217,7 +1217,7 @@ fn main() {
     match &6 {
         Foo::<i32>::TEST_I32_REF => (),
         Foo::<i32>::TEST_I32 => (),
-      //^^^^^^^^^^^^^^^^^^^^ expected &i32, got i32
+      //^^^^^^^^^^^^^^^^^^^^ expected &'? i32, got i32
         _ => (),
     }
 }
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 c2d2047e6f9..43fe14126e0 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
@@ -99,7 +99,7 @@ fn recursive_vars() {
             24..31 'unknown': {unknown}
             37..44 '[y, &y]': [{unknown}; 2]
             38..39 'y': {unknown}
-            41..43 '&y': &{unknown}
+            41..43 '&y': &'? {unknown}
             42..43 'y': {unknown}
         "#]],
     );
@@ -117,19 +117,19 @@ fn recursive_vars_2() {
         "#,
         expect![[r#"
             10..79 '{     ...x)]; }': ()
-            20..21 'x': &{unknown}
-            24..31 'unknown': &{unknown}
+            20..21 'x': &'? {unknown}
+            24..31 'unknown': &'? {unknown}
             41..42 'y': {unknown}
             45..52 'unknown': {unknown}
-            58..76 '[(x, y..., &x)]': [(&{unknown}, {unknown}); 2]
-            59..65 '(x, y)': (&{unknown}, {unknown})
-            60..61 'x': &{unknown}
+            58..76 '[(x, y..., &x)]': [(&'? {unknown}, {unknown}); 2]
+            59..65 '(x, y)': (&'? {unknown}, {unknown})
+            60..61 'x': &'? {unknown}
             63..64 'y': {unknown}
-            67..75 '(&y, &x)': (&{unknown}, {unknown})
-            68..70 '&y': &{unknown}
+            67..75 '(&y, &x)': (&'? {unknown}, {unknown})
+            68..70 '&y': &'? {unknown}
             69..70 'y': {unknown}
-            72..74 '&x': &&{unknown}
-            73..74 'x': &{unknown}
+            72..74 '&x': &'? &'? {unknown}
+            73..74 'x': &'? {unknown}
         "#]],
     );
 }
@@ -166,7 +166,7 @@ fn infer_std_crash_1() {
             59..136 'match ...     }': ()
             65..82 'someth...nknown': Maybe<{unknown}>
             93..123 'Maybe:...thing)': Maybe<{unknown}>
-            105..122 'ref mu...ething': &mut {unknown}
+            105..122 'ref mu...ething': &'? mut {unknown}
             127..129 '()': ()
         "#]],
     );
@@ -183,7 +183,7 @@ fn infer_std_crash_2() {
         "#,
         expect![[r#"
             22..52 '{     ...n']; }': ()
-            28..49 '&[0, b...b'\n']': &[u8; 4]
+            28..49 '&[0, b...b'\n']': &'? [u8; 4]
             29..49 '[0, b'...b'\n']': [u8; 4]
             30..31 '0': u8
             33..38 'b'\n'': u8
@@ -269,8 +269,8 @@ fn infer_std_crash_5() {
             32..320 'for co...     }': {unknown}
             32..320 'for co...     }': !
             32..320 'for co...     }': {unknown}
-            32..320 'for co...     }': &mut {unknown}
-            32..320 'for co...     }': fn next<{unknown}>(&mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
+            32..320 'for co...     }': &'? mut {unknown}
+            32..320 'for co...     }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
             32..320 'for co...     }': Option<{unknown}>
             32..320 'for co...     }': ()
             32..320 'for co...     }': ()
@@ -278,22 +278,22 @@ fn infer_std_crash_5() {
             36..43 'content': {unknown}
             47..60 'doesnt_matter': {unknown}
             61..320 '{     ...     }': ()
-            75..79 'name': &{unknown}
-            82..166 'if doe...     }': &{unknown}
+            75..79 'name': &'? {unknown}
+            82..166 'if doe...     }': &'? {unknown}
             85..98 'doesnt_matter': bool
-            99..128 '{     ...     }': &{unknown}
-            113..118 'first': &{unknown}
-            134..166 '{     ...     }': &{unknown}
-            148..156 '&content': &{unknown}
+            99..128 '{     ...     }': &'? {unknown}
+            113..118 'first': &'? {unknown}
+            134..166 '{     ...     }': &'? {unknown}
+            148..156 '&content': &'? {unknown}
             149..156 'content': {unknown}
-            181..188 'content': &{unknown}
-            191..313 'if ICE...     }': &{unknown}
+            181..188 'content': &'? {unknown}
+            191..313 'if ICE...     }': &'? {unknown}
             194..231 'ICE_RE..._VALUE': {unknown}
             194..247 'ICE_RE...&name)': bool
-            241..246 '&name': &&{unknown}
-            242..246 'name': &{unknown}
-            248..276 '{     ...     }': &{unknown}
-            262..266 'name': &{unknown}
+            241..246 '&name': &'? &'? {unknown}
+            242..246 'name': &'? {unknown}
+            248..276 '{     ...     }': &'? {unknown}
+            262..266 'name': &'? {unknown}
             282..313 '{     ...     }': {unknown}
             296..303 'content': {unknown}
         "#]],
@@ -318,7 +318,7 @@ fn infer_nested_generics_crash() {
         expect![[r#"
             91..105 'query_response': Canonical<QueryResponse<R>>
             136..166 '{     ...lue; }': ()
-            142..163 '&query....value': &QueryResponse<R>
+            142..163 '&query....value': &'? QueryResponse<R>
             143..157 'query_response': Canonical<QueryResponse<R>>
             143..163 'query_....value': QueryResponse<R>
         "#]],
@@ -465,12 +465,12 @@ fn issue_3999_slice() {
         }
         "#,
         expect![[r#"
-            7..13 'params': &[usize]
+            7..13 'params': &'? [usize]
             25..80 '{     ...   } }': ()
             31..78 'match ...     }': ()
-            37..43 'params': &[usize]
+            37..43 'params': &'? [usize]
             54..66 '[ps @ .., _]': [usize]
-            55..62 'ps @ ..': &[usize]
+            55..62 'ps @ ..': &'? [usize]
             60..62 '..': [usize]
             64..65 '_': usize
             70..72 '{}': ()
@@ -523,13 +523,13 @@ fn issue_4235_name_conflicts() {
         "#,
         expect![[r#"
             31..37 'FOO {}': FOO
-            63..67 'self': &FOO
+            63..67 'self': &'? FOO
             69..71 '{}': ()
             85..119 '{     ...o(); }': ()
-            95..96 'a': &FOO
-            99..103 '&FOO': &FOO
+            95..96 'a': &'? FOO
+            99..103 '&FOO': &'? FOO
             100..103 'FOO': FOO
-            109..110 'a': &FOO
+            109..110 'a': &'? FOO
             109..116 'a.foo()': ()
         "#]],
     );
@@ -715,12 +715,12 @@ fn issue_4885() {
         }
         "#,
         expect![[r#"
-            70..73 'key': &K
+            70..73 'key': &'? K
             132..148 '{     ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
-            138..141 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
+            138..141 'bar': fn bar<R, K>(&'? K) -> impl Future<Output = <K as Foo<R>>::Bar>
             138..146 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
-            142..145 'key': &K
-            162..165 'key': &K
+            142..145 'key': &'? K
+            162..165 'key': &'? K
             224..227 '{ }': ()
         "#]],
     );
@@ -771,11 +771,11 @@ fn issue_4800() {
         }
         "#,
         expect![[r#"
-            379..383 'self': &mut PeerSet<D>
+            379..383 'self': &'? mut PeerSet<D>
             401..424 '{     ...     }': dyn Future<Output = ()>
             411..418 'loop {}': !
             416..418 '{}': ()
-            575..579 'self': &mut Self
+            575..579 'self': &'? mut Self
         "#]],
     );
 }
@@ -815,19 +815,19 @@ fn issue_4966() {
             225..229 'iter': T
             244..246 '{}': Vec<A>
             258..402 '{     ...r(); }': ()
-            268..273 'inner': Map<impl Fn(&f64) -> f64>
-            276..300 'Map { ... 0.0 }': Map<impl Fn(&f64) -> f64>
-            285..298 '|_: &f64| 0.0': impl Fn(&f64) -> f64
-            286..287 '_': &f64
+            268..273 'inner': Map<impl Fn(&'? f64) -> f64>
+            276..300 'Map { ... 0.0 }': Map<impl Fn(&'? f64) -> f64>
+            285..298 '|_: &f64| 0.0': impl Fn(&'? f64) -> f64
+            286..287 '_': &'? f64
             295..298 '0.0': f64
-            311..317 'repeat': Repeat<Map<impl Fn(&f64) -> f64>>
-            320..345 'Repeat...nner }': Repeat<Map<impl Fn(&f64) -> f64>>
-            338..343 'inner': Map<impl Fn(&f64) -> f64>
-            356..359 'vec': Vec<IntoIterator::Item<Repeat<Map<impl Fn(&f64) -> f64>>>>
-            362..371 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<impl Fn(&f64) -> f64>>>, Repeat<Map<impl Fn(&f64) -> f64>>>(Repeat<Map<impl Fn(&f64) -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<impl Fn(&f64) -> f64>>>>
-            362..379 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<impl Fn(&f64) -> f64>>>>
-            372..378 'repeat': Repeat<Map<impl Fn(&f64) -> f64>>
-            386..389 'vec': Vec<IntoIterator::Item<Repeat<Map<impl Fn(&f64) -> f64>>>>
+            311..317 'repeat': Repeat<Map<impl Fn(&'? f64) -> f64>>
+            320..345 'Repeat...nner }': Repeat<Map<impl Fn(&'? f64) -> f64>>
+            338..343 'inner': Map<impl Fn(&'? f64) -> f64>
+            356..359 'vec': Vec<IntoIterator::Item<Repeat<Map<impl Fn(&'? f64) -> f64>>>>
+            362..371 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<impl Fn(&'? f64) -> f64>>>, Repeat<Map<impl Fn(&'? f64) -> f64>>>(Repeat<Map<impl Fn(&'? f64) -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<impl Fn(&'? f64) -> f64>>>>
+            362..379 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<impl Fn(&'? f64) -> f64>>>>
+            372..378 'repeat': Repeat<Map<impl Fn(&'? f64) -> f64>>
+            386..389 'vec': Vec<IntoIterator::Item<Repeat<Map<impl Fn(&'? f64) -> f64>>>>
             386..399 'vec.foo_bar()': {unknown}
         "#]],
     );
@@ -850,10 +850,10 @@ fn main() {
 }
 "#,
         expect![[r#"
-            40..44 'self': &S<T>
+            40..44 'self': &'? S<T>
             46..48 '_t': T
             53..55 '{}': ()
-            81..85 'self': &S<T>
+            81..85 'self': &'? S<T>
             87..89 '_f': F
             94..96 '{}': ()
             109..160 '{     ...10); }': ()
@@ -862,8 +862,8 @@ fn main() {
             123..126 'S()': S<i32>
             132..133 's': S<i32>
             132..144 's.g(|_x| {})': ()
-            136..143 '|_x| {}': impl FnOnce(&i32)
-            137..139 '_x': &i32
+            136..143 '|_x| {}': impl FnOnce(&'? i32)
+            137..139 '_x': &'? i32
             141..143 '{}': ()
             150..151 's': S<i32>
             150..157 's.f(10)': ()
@@ -895,14 +895,14 @@ fn flush(&self) {
 }
 "#,
         expect![[r#"
-            123..127 'self': &Mutex<T>
-            150..152 '{}': MutexGuard<'{error}, T>
-            234..238 'self': &{unknown}
+            123..127 'self': &'? Mutex<T>
+            150..152 '{}': MutexGuard<'?, T>
+            234..238 'self': &'? {unknown}
             240..290 '{     ...()); }': ()
-            250..251 'w': &Mutex<BufWriter>
+            250..251 'w': &'? Mutex<BufWriter>
             276..287 '*(w.lock())': BufWriter
-            278..279 'w': &Mutex<BufWriter>
-            278..286 'w.lock()': MutexGuard<'{error}, BufWriter>
+            278..279 'w': &'? Mutex<BufWriter>
+            278..286 'w.lock()': MutexGuard<'?, BufWriter>
         "#]],
     );
 }
@@ -1023,20 +1023,20 @@ fn cfg_tail() {
         expect![[r#"
             14..53 '{     ...)] 9 }': ()
             20..31 '{ "first" }': ()
-            22..29 '"first"': &str
+            22..29 '"first"': &'static str
             72..190 '{     ...] 13 }': ()
             78..88 '{ "fake" }': ()
-            80..86 '"fake"': &str
+            80..86 '"fake"': &'static str
             93..103 '{ "fake" }': ()
-            95..101 '"fake"': &str
+            95..101 '"fake"': &'static str
             108..120 '{ "second" }': ()
-            110..118 '"second"': &str
+            110..118 '"second"': &'static str
             210..273 '{     ... 15; }': ()
             216..227 '{ "third" }': ()
-            218..225 '"third"': &str
+            218..225 '"third"': &'static str
             293..357 '{     ...] 15 }': ()
-            299..311 '{ "fourth" }': &str
-            301..309 '"fourth"': &str
+            299..311 '{ "fourth" }': &'static str
+            301..309 '"fourth"': &'static str
         "#]],
     )
 }
@@ -1238,8 +1238,8 @@ fn test() {
             16..66 'for _ ...     }': IntoIterator::IntoIter<()>
             16..66 'for _ ...     }': !
             16..66 'for _ ...     }': IntoIterator::IntoIter<()>
-            16..66 'for _ ...     }': &mut IntoIterator::IntoIter<()>
-            16..66 'for _ ...     }': fn next<IntoIterator::IntoIter<()>>(&mut IntoIterator::IntoIter<()>) -> Option<<IntoIterator::IntoIter<()> as Iterator>::Item>
+            16..66 'for _ ...     }': &'? mut IntoIterator::IntoIter<()>
+            16..66 'for _ ...     }': fn next<IntoIterator::IntoIter<()>>(&'? mut IntoIterator::IntoIter<()>) -> Option<<IntoIterator::IntoIter<()> as Iterator>::Item>
             16..66 'for _ ...     }': Option<IntoIterator::Item<()>>
             16..66 'for _ ...     }': ()
             16..66 'for _ ...     }': ()
@@ -1727,7 +1727,7 @@ fn dyn_with_unresolved_trait() {
         r#"
 fn foo(a: &dyn DoesNotExist) {
     a.bar();
-  //^&{unknown}
+  //^&'? {unknown}
 }
         "#,
     );
@@ -1851,9 +1851,9 @@ fn foo() {
     match &E::A {
         b @ (x @ E::A | x) => {
             b;
-          //^ &E
+          //^ &'? E
             x;
-          //^ &E
+          //^ &'? E
         }
     }
 }",
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 a9d28ebfef5..a525a577431 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
@@ -115,15 +115,15 @@ fn test(a: u32, b: isize, c: !, d: &str) {
             8..9 'a': u32
             16..17 'b': isize
             26..27 'c': !
-            32..33 'd': &str
+            32..33 'd': &'? str
             41..120 '{     ...f32; }': ()
             47..48 'a': u32
             54..55 'b': isize
             61..62 'c': !
-            68..69 'd': &str
+            68..69 'd': &'? str
             75..81 '1usize': usize
             87..93 '1isize': isize
-            99..105 '"test"': &str
+            99..105 '"test"': &'static str
             111..117 '1.0f32': f32
         "#]],
     );
@@ -344,23 +344,23 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
 }
         "#,
         expect![[r#"
-            8..9 'a': &u32
-            17..18 'b': &mut u32
+            8..9 'a': &'? u32
+            17..18 'b': &'? mut u32
             30..31 'c': *const u32
             45..46 'd': *mut u32
             58..149 '{     ... *d; }': ()
-            64..65 'a': &u32
+            64..65 'a': &'? u32
             71..73 '*a': u32
-            72..73 'a': &u32
-            79..81 '&a': &&u32
-            80..81 'a': &u32
-            87..93 '&mut a': &mut &u32
-            92..93 'a': &u32
-            99..100 'b': &mut u32
+            72..73 'a': &'? u32
+            79..81 '&a': &'? &'? u32
+            80..81 'a': &'? u32
+            87..93 '&mut a': &'? mut &'? u32
+            92..93 'a': &'? u32
+            99..100 'b': &'? mut u32
             106..108 '*b': u32
-            107..108 'b': &mut u32
-            114..116 '&b': &&mut u32
-            115..116 'b': &mut u32
+            107..108 'b': &'? mut u32
+            114..116 '&b': &'? &'? mut u32
+            115..116 'b': &'? mut u32
             122..123 'c': *const u32
             129..131 '*c': u32
             130..131 'c': *const u32
@@ -425,22 +425,22 @@ h";
             32..36 '5i32': i32
             50..54 '5f32': f32
             68..72 '5f64': f64
-            86..93 '"hello"': &str
-            107..115 'b"bytes"': &[u8; 5]
+            86..93 '"hello"': &'static str
+            107..115 'b"bytes"': &'static [u8; 5]
             129..132 ''c'': char
             146..150 'b'b'': u8
             164..168 '3.14': f64
             182..186 '5000': i32
             200..205 'false': bool
             219..223 'true': bool
-            237..333 'r#"   ...    "#': &str
-            347..357 'br#"yolo"#': &[u8; 4]
-            375..376 'a': &[u8; 4]
-            379..403 'b"a\x2...    c"': &[u8; 4]
-            421..422 'b': &[u8; 4]
-            425..433 'br"g\ h"': &[u8; 4]
-            451..452 'c': &[u8; 6]
-            455..467 'br#"x"\"yb"#': &[u8; 6]
+            237..333 'r#"   ...    "#': &'static str
+            347..357 'br#"yolo"#': &'static [u8; 4]
+            375..376 'a': &'static [u8; 4]
+            379..403 'b"a\x2...    c"': &'static [u8; 4]
+            421..422 'b': &'static [u8; 4]
+            425..433 'br"g\ h"': &'static [u8; 4]
+            451..452 'c': &'static [u8; 6]
+            455..467 'br#"x"\"yb"#': &'static [u8; 6]
         "##]],
     );
 }
@@ -508,9 +508,9 @@ fn test(x: SomeType) {
             238..240 '!x': {unknown}
             239..240 'x': SomeType
             246..254 '-"hello"': {unknown}
-            247..254 '"hello"': &str
+            247..254 '"hello"': &'static str
             260..268 '!"hello"': {unknown}
-            261..268 '"hello"': &str
+            261..268 '"hello"': &'static str
         "#]],
     );
 }
@@ -535,7 +535,7 @@ fn test() -> &mut &f64 {
         expect![[r#"
             13..14 'x': u32
             21..23 '{}': ()
-            77..230 '{     ...t &c }': &mut &f64
+            77..230 '{     ...t &c }': &'? mut &'? f64
             87..88 'a': u32
             91..107 'unknow...nction': {unknown}
             91..109 'unknow...tion()': u32
@@ -550,8 +550,8 @@ fn test() -> &mut &f64 {
             193..194 'c': f64
             197..213 'unknow...nction': {unknown}
             197..215 'unknow...tion()': f64
-            221..228 '&mut &c': &mut &f64
-            226..228 '&c': &f64
+            221..228 '&mut &c': &'? mut &'? f64
+            226..228 '&c': &'? f64
             227..228 'c': f64
         "#]],
     );
@@ -579,12 +579,12 @@ impl S {
 }
 "#,
         expect![[r#"
-            33..37 'self': &S
+            33..37 'self': &'? S
             39..60 '{     ...     }': ()
-            49..53 'self': &S
-            74..78 'self': &S
+            49..53 'self': &'? S
+            74..78 'self': &'? S
             87..108 '{     ...     }': ()
-            97..101 'self': &S
+            97..101 'self': &'? S
             132..152 '{     ...     }': S
             142..146 'S {}': S
             176..199 '{     ...     }': S
@@ -771,35 +771,35 @@ fn test2(a1: *const A, a2: *mut A) {
             64..65 'a': A
             71..73 'a1': A
             71..75 'a1.b': B
-            85..87 'a2': &A
-            90..92 '&a': &A
+            85..87 'a2': &'? A
+            90..92 '&a': &'? A
             91..92 'a': A
-            98..100 'a2': &A
+            98..100 'a2': &'? A
             98..102 'a2.b': B
-            112..114 'a3': &mut A
-            117..123 '&mut a': &mut A
+            112..114 'a3': &'? mut A
+            117..123 '&mut a': &'? mut A
             122..123 'a': A
-            129..131 'a3': &mut A
+            129..131 'a3': &'? mut A
             129..133 'a3.b': B
-            143..145 'a4': &&&&&&&A
-            148..156 '&&&&&&&a': &&&&&&&A
-            149..156 '&&&&&&a': &&&&&&A
-            150..156 '&&&&&a': &&&&&A
-            151..156 '&&&&a': &&&&A
-            152..156 '&&&a': &&&A
-            153..156 '&&a': &&A
-            154..156 '&a': &A
+            143..145 'a4': &'? &'? &'? &'? &'? &'? &'? A
+            148..156 '&&&&&&&a': &'? &'? &'? &'? &'? &'? &'? A
+            149..156 '&&&&&&a': &'? &'? &'? &'? &'? &'? A
+            150..156 '&&&&&a': &'? &'? &'? &'? &'? A
+            151..156 '&&&&a': &'? &'? &'? &'? A
+            152..156 '&&&a': &'? &'? &'? A
+            153..156 '&&a': &'? &'? A
+            154..156 '&a': &'? A
             155..156 'a': A
-            162..164 'a4': &&&&&&&A
+            162..164 'a4': &'? &'? &'? &'? &'? &'? &'? A
             162..166 'a4.b': B
-            176..178 'a5': &mut &&mut &&mut A
-            181..199 '&mut &...&mut a': &mut &&mut &&mut A
-            186..199 '&&mut &&mut a': &&mut &&mut A
-            187..199 '&mut &&mut a': &mut &&mut A
-            192..199 '&&mut a': &&mut A
-            193..199 '&mut a': &mut A
+            176..178 'a5': &'? mut &'? &'? mut &'? &'? mut A
+            181..199 '&mut &...&mut a': &'? mut &'? &'? mut &'? &'? mut A
+            186..199 '&&mut &&mut a': &'? &'? mut &'? &'? mut A
+            187..199 '&mut &&mut a': &'? mut &'? &'? mut A
+            192..199 '&&mut a': &'? &'? mut A
+            193..199 '&mut a': &'? mut A
             198..199 'a': A
-            205..207 'a5': &mut &&mut &&mut A
+            205..207 'a5': &'? mut &'? &'? mut &'? &'? mut A
             205..209 'a5.b': B
             223..225 'a1': *const A
             237..239 'a2': *mut A
@@ -840,22 +840,22 @@ fn test() {
 }
 "#,
         expect![[r#"
-            66..70 'self': &A<T>
-            78..101 '{     ...     }': &T
-            88..95 '&self.0': &T
-            89..93 'self': &A<T>
+            66..70 'self': &'? A<T>
+            78..101 '{     ...     }': &'? T
+            88..95 '&self.0': &'? T
+            89..93 'self': &'? A<T>
             89..95 'self.0': T
-            182..186 'self': &B<T>
-            205..228 '{     ...     }': &T
-            215..222 '&self.0': &T
-            216..220 'self': &B<T>
+            182..186 'self': &'? B<T>
+            205..228 '{     ...     }': &'? T
+            215..222 '&self.0': &'? T
+            216..220 'self': &'? B<T>
             216..222 'self.0': T
             242..280 '{     ...))); }': ()
-            252..253 't': &i32
-            256..262 'A::foo': fn foo<i32>(&A<i32>) -> &i32
-            256..277 'A::foo...42))))': &i32
-            263..276 '&&B(B(A(42)))': &&B<B<A<i32>>>
-            264..276 '&B(B(A(42)))': &B<B<A<i32>>>
+            252..253 't': &'? i32
+            256..262 'A::foo': fn foo<i32>(&'? A<i32>) -> &'? i32
+            256..277 'A::foo...42))))': &'? i32
+            263..276 '&&B(B(A(42)))': &'? &'? B<B<A<i32>>>
+            264..276 '&B(B(A(42)))': &'? B<B<A<i32>>>
             265..266 'B': extern "rust-call" B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
             265..276 'B(B(A(42)))': B<B<A<i32>>>
             267..268 'B': extern "rust-call" B<A<i32>>(A<i32>) -> B<A<i32>>
@@ -895,28 +895,28 @@ fn test(a: A<i32>) {
 }
 "#,
         expect![[r#"
-            71..75 'self': &A<T>
-            77..78 'x': &A<T>
-            93..114 '{     ...     }': &T
-            103..108 '&*x.0': &T
+            71..75 'self': &'? A<T>
+            77..78 'x': &'? A<T>
+            93..114 '{     ...     }': &'? T
+            103..108 '&*x.0': &'? T
             104..108 '*x.0': T
-            105..106 'x': &A<T>
+            105..106 'x': &'? A<T>
             105..108 'x.0': *mut T
-            195..199 'self': &B<T>
-            218..241 '{     ...     }': &T
-            228..235 '&self.0': &T
-            229..233 'self': &B<T>
+            195..199 'self': &'? B<T>
+            218..241 '{     ...     }': &'? T
+            228..235 '&self.0': &'? T
+            229..233 'self': &'? B<T>
             229..235 'self.0': T
             253..254 'a': A<i32>
             264..310 '{     ...))); }': ()
-            274..275 't': &i32
+            274..275 't': &'? i32
             278..279 'A': extern "rust-call" A<i32>(*mut i32) -> A<i32>
             278..292 'A(0 as *mut _)': A<i32>
-            278..307 'A(0 as...B(a)))': &i32
+            278..307 'A(0 as...B(a)))': &'? i32
             280..281 '0': i32
             280..291 '0 as *mut _': *mut i32
-            297..306 '&&B(B(a))': &&B<B<A<i32>>>
-            298..306 '&B(B(a))': &B<B<A<i32>>>
+            297..306 '&&B(B(a))': &'? &'? B<B<A<i32>>>
+            298..306 '&B(B(a))': &'? B<B<A<i32>>>
             299..300 'B': extern "rust-call" B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
             299..306 'B(B(a))': B<B<A<i32>>>
             301..302 'B': extern "rust-call" B<A<i32>>(A<i32>) -> B<A<i32>>
@@ -1044,7 +1044,7 @@ fn infer_inherent_method() {
             31..35 'self': A
             37..38 'x': u32
             52..54 '{}': i32
-            106..110 'self': &A
+            106..110 'self': &'? A
             112..113 'x': u64
             127..129 '{}': i64
             147..148 'a': A
@@ -1053,7 +1053,7 @@ fn infer_inherent_method() {
             159..167 'a.foo(1)': i32
             165..166 '1': u32
             173..184 '(&a).bar(1)': i64
-            174..176 '&a': &A
+            174..176 '&a': &'? A
             175..176 'a': A
             182..183 '1': u64
             190..191 'a': A
@@ -1078,10 +1078,10 @@ fn test() {
 }
 "#,
         expect![[r#"
-            67..71 'self': &str
+            67..71 'self': &'? str
             80..82 '{}': i32
             96..116 '{     ...o(); }': ()
-            102..107 '"foo"': &str
+            102..107 '"foo"': &'static str
             102..113 '"foo".foo()': i32
         "#]],
     );
@@ -1101,33 +1101,33 @@ fn infer_tuple() {
         }
         "#,
         expect![[r#"
-            8..9 'x': &str
+            8..9 'x': &'? str
             17..18 'y': isize
             27..169 '{     ...d"); }': ()
-            37..38 'a': (u32, &str)
-            54..62 '(1, "a")': (u32, &str)
+            37..38 'a': (u32, &'? str)
+            54..62 '(1, "a")': (u32, &'? str)
             55..56 '1': u32
-            58..61 '"a"': &str
-            72..73 'b': ((u32, &str), &str)
-            76..82 '(a, x)': ((u32, &str), &str)
-            77..78 'a': (u32, &str)
-            80..81 'x': &str
-            92..93 'c': (isize, &str)
-            96..102 '(y, x)': (isize, &str)
+            58..61 '"a"': &'static str
+            72..73 'b': ((u32, &'? str), &'? str)
+            76..82 '(a, x)': ((u32, &'? str), &'? str)
+            77..78 'a': (u32, &'? str)
+            80..81 'x': &'? str
+            92..93 'c': (isize, &'? str)
+            96..102 '(y, x)': (isize, &'? str)
             97..98 'y': isize
-            100..101 'x': &str
-            112..113 'd': ((isize, &str), &str)
-            116..122 '(c, x)': ((isize, &str), &str)
-            117..118 'c': (isize, &str)
-            120..121 'x': &str
-            132..133 'e': (i32, &str)
-            136..144 '(1, "e")': (i32, &str)
+            100..101 'x': &'? str
+            112..113 'd': ((isize, &'? str), &'? str)
+            116..122 '(c, x)': ((isize, &'? str), &'? str)
+            117..118 'c': (isize, &'? str)
+            120..121 'x': &'? str
+            132..133 'e': (i32, &'static str)
+            136..144 '(1, "e")': (i32, &'static str)
             137..138 '1': i32
-            140..143 '"e"': &str
-            154..155 'f': ((i32, &str), &str)
-            158..166 '(e, "d")': ((i32, &str), &str)
-            159..160 'e': (i32, &str)
-            162..165 '"d"': &str
+            140..143 '"e"': &'static str
+            154..155 'f': ((i32, &'static str), &'static str)
+            158..166 '(e, "d")': ((i32, &'static str), &'static str)
+            159..160 'e': (i32, &'static str)
+            162..165 '"d"': &'static str
         "#]],
     );
 }
@@ -1156,20 +1156,20 @@ fn infer_array() {
         }
         "#,
         expect![[r#"
-            8..9 'x': &str
+            8..9 'x': &'? str
             17..18 'y': isize
             27..326 '{     ...,4]; }': ()
-            37..38 'a': [&str; 1]
-            41..44 '[x]': [&str; 1]
-            42..43 'x': &str
-            54..55 'b': [[&str; 1]; 2]
-            58..64 '[a, a]': [[&str; 1]; 2]
-            59..60 'a': [&str; 1]
-            62..63 'a': [&str; 1]
-            74..75 'c': [[[&str; 1]; 2]; 2]
-            78..84 '[b, b]': [[[&str; 1]; 2]; 2]
-            79..80 'b': [[&str; 1]; 2]
-            82..83 'b': [[&str; 1]; 2]
+            37..38 'a': [&'? str; 1]
+            41..44 '[x]': [&'? str; 1]
+            42..43 'x': &'? str
+            54..55 'b': [[&'? str; 1]; 2]
+            58..64 '[a, a]': [[&'? str; 1]; 2]
+            59..60 'a': [&'? str; 1]
+            62..63 'a': [&'? str; 1]
+            74..75 'c': [[[&'? str; 1]; 2]; 2]
+            78..84 '[b, b]': [[[&'? str; 1]; 2]; 2]
+            79..80 'b': [[&'? str; 1]; 2]
+            82..83 'b': [[&'? str; 1]; 2]
             95..96 'd': [isize; 4]
             99..111 '[y, 1, 2, 3]': [isize; 4]
             100..101 'y': isize
@@ -1197,15 +1197,15 @@ fn infer_array() {
             209..215 '[1, 2]': [i32; 2]
             210..211 '1': i32
             213..214 '2': i32
-            225..226 'i': [&str; 2]
-            229..239 '["a", "b"]': [&str; 2]
-            230..233 '"a"': &str
-            235..238 '"b"': &str
-            250..251 'b': [[&str; 1]; 2]
-            254..264 '[a, ["b"]]': [[&str; 1]; 2]
-            255..256 'a': [&str; 1]
-            258..263 '["b"]': [&str; 1]
-            259..262 '"b"': &str
+            225..226 'i': [&'? str; 2]
+            229..239 '["a", "b"]': [&'? str; 2]
+            230..233 '"a"': &'static str
+            235..238 '"b"': &'static str
+            250..251 'b': [[&'? str; 1]; 2]
+            254..264 '[a, ["b"]]': [[&'? str; 1]; 2]
+            255..256 'a': [&'? str; 1]
+            258..263 '["b"]': [&'? str; 1]
+            259..262 '"b"': &'static str
             274..275 'x': [u8; 0]
             287..289 '[]': [u8; 0]
             299..300 'y': [u8; 4]
@@ -1279,12 +1279,12 @@ fn infer_tuple_struct_generics() {
             92..93 'A': extern "rust-call" A<u128>(u128) -> A<u128>
             92..101 'A(42u128)': A<u128>
             94..100 '42u128': u128
-            107..111 'Some': extern "rust-call" Some<&str>(&str) -> Option<&str>
-            107..116 'Some("x")': Option<&str>
-            112..115 '"x"': &str
-            122..134 'Option::Some': extern "rust-call" Some<&str>(&str) -> Option<&str>
-            122..139 'Option...e("x")': Option<&str>
-            135..138 '"x"': &str
+            107..111 'Some': extern "rust-call" Some<&'static str>(&'static str) -> Option<&'static str>
+            107..116 'Some("x")': Option<&'static str>
+            112..115 '"x"': &'static str
+            122..134 'Option::Some': extern "rust-call" Some<&'static str>(&'static str) -> Option<&'static str>
+            122..139 'Option...e("x")': Option<&'static str>
+            135..138 '"x"': &'static str
             145..149 'None': Option<{unknown}>
             159..160 'x': Option<i64>
             176..180 'None': Option<i64>
@@ -1405,15 +1405,15 @@ fn infer_impl_generics_with_autoderef() {
         }
         "#,
         expect![[r#"
-            77..81 'self': &Option<T>
-            97..99 '{}': Option<&T>
+            77..81 'self': &'? Option<T>
+            97..99 '{}': Option<&'? T>
             110..111 'o': Option<u32>
             126..164 '{     ...f(); }': ()
-            132..145 '(&o).as_ref()': Option<&u32>
-            133..135 '&o': &Option<u32>
+            132..145 '(&o).as_ref()': Option<&'? u32>
+            133..135 '&o': &'? Option<u32>
             134..135 'o': Option<u32>
             151..152 'o': Option<u32>
-            151..161 'o.as_ref()': Option<&u32>
+            151..161 'o.as_ref()': Option<&'? u32>
         "#]],
     );
 }
@@ -1551,16 +1551,16 @@ fn infer_type_alias() {
         "#,
         expect![[r#"
             115..116 'x': A<u32, i128>
-            123..124 'y': A<&str, u128>
+            123..124 'y': A<&'? str, u128>
             137..138 'z': A<u8, i8>
             153..210 '{     ...z.y; }': ()
             159..160 'x': A<u32, i128>
             159..162 'x.x': u32
             168..169 'x': A<u32, i128>
             168..171 'x.y': i128
-            177..178 'y': A<&str, u128>
-            177..180 'y.x': &str
-            186..187 'y': A<&str, u128>
+            177..178 'y': A<&'? str, u128>
+            177..180 'y.x': &'? str
+            186..187 'y': A<&'? str, u128>
             186..189 'y.y': u128
             195..196 'z': A<u8, i8>
             195..198 'z.x': u8
@@ -1572,8 +1572,8 @@ fn infer_type_alias() {
             312..328 'm::Ali...Foo(0)': Enum
             326..327 '0': u8
             338..354 'm::Ali...Foo(x)': Enum
-            352..353 'x': &u8
-            357..359 '&e': &Enum
+            352..353 'x': &'? u8
+            357..359 '&e': &'? Enum
             358..359 'e': Enum
         "#]],
     )
@@ -1618,10 +1618,10 @@ fn infer_type_param() {
             9..10 'x': T
             20..29 '{     x }': T
             26..27 'x': T
-            43..44 'x': &T
+            43..44 'x': &'? T
             55..65 '{     *x }': T
             61..63 '*x': T
-            62..63 'x': &T
+            62..63 'x': &'? T
             77..157 '{     ...(1); }': ()
             87..88 'y': u32
             91..96 '10u32': u32
@@ -1629,9 +1629,9 @@ fn infer_type_param() {
             102..107 'id(y)': u32
             105..106 'y': u32
             117..118 'x': bool
-            127..132 'clone': fn clone<bool>(&bool) -> bool
+            127..132 'clone': fn clone<bool>(&'? bool) -> bool
             127..135 'clone(z)': bool
-            133..134 'z': &bool
+            133..134 'z': &'? bool
             141..151 'id::<i128>': fn id<i128>(i128) -> i128
             141..154 'id::<i128>(1)': i128
             152..153 '1': i128
@@ -1842,7 +1842,7 @@ fn foo() -> &'static str { "" }
 
 fn main() {
     foo();
-  //^^^^^ &str
+  //^^^^^ &'static str
 }"#,
     );
 }
@@ -1940,10 +1940,10 @@ fn closure_return_inferred() {
         "#,
         expect![[r#"
             16..46 '{     ..." }; }': u32
-            26..27 'x': impl Fn() -> &str
-            30..43 '|| { "test" }': impl Fn() -> &str
-            33..43 '{ "test" }': &str
-            35..41 '"test"': &str
+            26..27 'x': impl Fn() -> &'static str
+            30..43 '|| { "test" }': impl Fn() -> &'static str
+            33..43 '{ "test" }': &'static str
+            35..41 '"test"': &'static str
         "#]],
     );
 }
@@ -1975,10 +1975,10 @@ fn test() {
             70..71 'v': i64
             78..80 '{}': ()
             91..362 '{     ...   } }': ()
-            101..106 'mut g': |usize| yields i64 -> &str
-            109..218 '|r| { ...     }': |usize| yields i64 -> &str
+            101..106 'mut g': |usize| yields i64 -> &'static str
+            109..218 '|r| { ...     }': |usize| yields i64 -> &'static str
             110..111 'r': usize
-            113..218 '{     ...     }': &str
+            113..218 '{     ...     }': &'static str
             127..128 'a': usize
             131..138 'yield 0': usize
             137..138 '0': i64
@@ -1988,22 +1988,22 @@ fn test() {
             177..178 'a': usize
             181..188 'yield 2': usize
             187..188 '2': i64
-            198..212 '"return value"': &str
+            198..212 '"return value"': &'static str
             225..360 'match ...     }': ()
-            231..239 'Pin::new': fn new<&mut |usize| yields i64 -> &str>(&mut |usize| yields i64 -> &str) -> Pin<&mut |usize| yields i64 -> &str>
-            231..247 'Pin::n...mut g)': Pin<&mut |usize| yields i64 -> &str>
-            231..262 'Pin::n...usize)': CoroutineState<i64, &str>
-            240..246 '&mut g': &mut |usize| yields i64 -> &str
-            245..246 'g': |usize| yields i64 -> &str
+            231..239 'Pin::new': fn new<&'? mut |usize| yields i64 -> &'static str>(&'? mut |usize| yields i64 -> &'static str) -> Pin<&'? mut |usize| yields i64 -> &'static str>
+            231..247 'Pin::n...mut g)': Pin<&'? mut |usize| yields i64 -> &'static str>
+            231..262 'Pin::n...usize)': CoroutineState<i64, &'static str>
+            240..246 '&mut g': &'? mut |usize| yields i64 -> &'static str
+            245..246 'g': |usize| yields i64 -> &'static str
             255..261 '0usize': usize
-            273..299 'Corout...ded(y)': CoroutineState<i64, &str>
+            273..299 'Corout...ded(y)': CoroutineState<i64, &'static str>
             297..298 'y': i64
             303..312 '{ f(y); }': ()
             305..306 'f': fn f(i64)
             305..309 'f(y)': ()
             307..308 'y': i64
-            321..348 'Corout...ete(r)': CoroutineState<i64, &str>
-            346..347 'r': &str
+            321..348 'Corout...ete(r)': CoroutineState<i64, &'static str>
+            346..347 'r': &'static str
             352..354 '{}': ()
         "#]],
     );
@@ -2050,7 +2050,7 @@ fn f(x: (&&&&i32, &&&i32)) {
         _ => loop {},
     };
     f;
-  //^ (&&&&i32, &&&i32)
+  //^ (&'? &'? &'? &'? i32, &'? &'? &'? i32)
 }
         "#,
     );
@@ -2059,10 +2059,10 @@ fn f(x: (&&&&i32, &&&i32)) {
 fn f() {
     let x = &&&(&&&2, &&&&&3);
     let (y, z) = x;
-       //^ &&&&i32
+       //^ &'? &'? &'? &'? i32
     let t @ (y, z) = x;
     t;
-  //^ &&&(&&&i32, &&&&&i32)
+  //^ &'? &'? &'? (&'? &'? &'? i32, &'? &'? &'? &'? &'? i32)
 }
         "#,
     );
@@ -2071,10 +2071,10 @@ fn f() {
 fn f() {
     let x = &&&(&&&2, &&&&&3);
     let (y, z) = x;
-       //^ &&&&i32
+       //^ &'? &'? &'? &'? i32
     let t @ (y, z) = x;
     t;
-  //^ &&&(&&&i32, &&&&&i32)
+  //^ &'? &'? &'? (&'? &'? &'? i32, &'? &'? &'? &'? &'? i32)
 }
         "#,
     );
@@ -2761,23 +2761,23 @@ impl S {
 fn f() {
     let x = S;
     let c1 = || x.read();
-      //^^ impl Fn() -> &S
+      //^^ impl Fn() -> &'? S
     let c2 = || x.write();
-      //^^ impl FnMut() -> &mut S
+      //^^ impl FnMut() -> &'? mut S
     let c3 = || x.consume();
       //^^ impl FnOnce() -> S
     let c3 = || x.consume().consume().consume();
       //^^ impl FnOnce() -> S
     let c3 = || x.consume().write().read();
-      //^^ impl FnOnce() -> &S
+      //^^ impl FnOnce() -> &'? S
     let x = &mut x;
     let c1 = || x.write();
-      //^^ impl FnMut() -> &mut S
+      //^^ impl FnMut() -> &'? mut S
     let x = S;
     let c1 = || { let ref t = x; t };
-      //^^ impl Fn() -> &S
+      //^^ impl Fn() -> &'? S
     let c2 = || { let ref mut t = x; t };
-      //^^ impl FnMut() -> &mut S
+      //^^ impl FnMut() -> &'? mut S
     let c3 = || { let t = x; t };
       //^^ impl FnOnce() -> S
 }
@@ -3074,11 +3074,11 @@ fn main() {
 }
         "#,
         expect![[r#"
-            104..108 'self': &Box<T>
-            188..192 'self': &Box<Foo<T>>
-            218..220 '{}': &T
-            242..246 'self': &Box<Foo<T>>
-            275..277 '{}': &Foo<T>
+            104..108 'self': &'? Box<T>
+            188..192 'self': &'a Box<Foo<T>>
+            218..220 '{}': &'a T
+            242..246 'self': &'a Box<Foo<T>>
+            275..277 '{}': &'a Foo<T>
             297..301 'self': Box<Foo<T>>
             322..324 '{}': Foo<T>
             338..559 '{     ...r(); }': ()
@@ -3088,21 +3088,21 @@ fn main() {
             360..363 'Foo': extern "rust-call" Foo<i32>(i32) -> Foo<i32>
             360..370 'Foo(0_i32)': Foo<i32>
             364..369 '0_i32': i32
-            382..386 'bad1': &i32
+            382..386 'bad1': &'? i32
             389..394 'boxed': Box<Foo<i32>>
-            389..406 'boxed....nner()': &i32
-            416..421 'good1': &i32
-            424..438 'Foo::get_inner': fn get_inner<i32, '{error}>(&Box<Foo<i32>>) -> &i32
-            424..446 'Foo::g...boxed)': &i32
-            439..445 '&boxed': &Box<Foo<i32>>
+            389..406 'boxed....nner()': &'? i32
+            416..421 'good1': &'? i32
+            424..438 'Foo::get_inner': fn get_inner<i32, '?>(&'? Box<Foo<i32>>) -> &'? i32
+            424..446 'Foo::g...boxed)': &'? i32
+            439..445 '&boxed': &'? Box<Foo<i32>>
             440..445 'boxed': Box<Foo<i32>>
-            457..461 'bad2': &Foo<i32>
+            457..461 'bad2': &'? Foo<i32>
             464..469 'boxed': Box<Foo<i32>>
-            464..480 'boxed....self()': &Foo<i32>
-            490..495 'good2': &Foo<i32>
-            498..511 'Foo::get_self': fn get_self<i32, '{error}>(&Box<Foo<i32>>) -> &Foo<i32>
-            498..519 'Foo::g...boxed)': &Foo<i32>
-            512..518 '&boxed': &Box<Foo<i32>>
+            464..480 'boxed....self()': &'? Foo<i32>
+            490..495 'good2': &'? Foo<i32>
+            498..511 'Foo::get_self': fn get_self<i32, '?>(&'? Box<Foo<i32>>) -> &'? Foo<i32>
+            498..519 'Foo::g...boxed)': &'? Foo<i32>
+            512..518 '&boxed': &'? Box<Foo<i32>>
             513..518 'boxed': Box<Foo<i32>>
             530..535 'inner': Foo<i32>
             538..543 'boxed': Box<Foo<i32>>
@@ -3414,31 +3414,31 @@ struct TS(usize);
 fn main() {
     let x;
     [x,] = &[1,];
-  //^^^^expected &[i32; 1], got [{unknown}; _]
+  //^^^^expected &'? [i32; 1], got [{unknown}; _]
 
     let x;
     [(x,),] = &[(1,),];
-  //^^^^^^^expected &[(i32,); 1], got [{unknown}; _]
+  //^^^^^^^expected &'? [(i32,); 1], got [{unknown}; _]
 
     let x;
     ((x,),) = &((1,),);
-  //^^^^^^^expected &((i32,),), got (({unknown},),)
+  //^^^^^^^expected &'? ((i32,),), got (({unknown},),)
 
     let x;
     (x,) = &(1,);
-  //^^^^expected &(i32,), got ({unknown},)
+  //^^^^expected &'? (i32,), got ({unknown},)
 
     let x;
     (S { a: x },) = &(S { a: 42 },);
-  //^^^^^^^^^^^^^expected &(S,), got (S,)
+  //^^^^^^^^^^^^^expected &'? (S,), got (S,)
 
     let x;
     S { a: x } = &S { a: 42 };
-  //^^^^^^^^^^expected &S, got S
+  //^^^^^^^^^^expected &'? S, got S
 
     let x;
     TS(x) = &TS(42);
-  //^^^^^expected &TS, got TS
+  //^^^^^expected &'? TS, got TS
 }
         "#,
     );
@@ -3548,17 +3548,17 @@ fn f<T>(t: Ark<T>) {
 }
 "#,
         expect![[r#"
-            47..51 'self': &Ark<T>
+            47..51 'self': &'? Ark<T>
             65..88 '{     ...     }': *const T
-            75..82 '&self.0': &T
-            76..80 'self': &Ark<T>
+            75..82 '&self.0': &'? T
+            76..80 'self': &'? Ark<T>
             76..82 'self.0': T
             99..100 't': Ark<T>
             110..144 '{     ... (); }': ()
-            116..124 'Ark::foo': fn foo<T>(&Ark<T>) -> *const T
+            116..124 'Ark::foo': fn foo<T>(&'? Ark<T>) -> *const T
             116..128 'Ark::foo(&t)': *const T
             116..141 'Ark::f...nst ()': *const ()
-            125..127 '&t': &Ark<T>
+            125..127 '&t': &'? Ark<T>
             126..127 't': Ark<T>
         "#]],
     );
@@ -3632,7 +3632,7 @@ pub struct CStr;
 
 fn main() {
     c"ello";
-  //^^^^^^^ &CStr
+  //^^^^^^^ &'static CStr
 }
 "#,
     );
@@ -3659,7 +3659,7 @@ fn main() {
     let are = "are";
     let count = 10;
     builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!");
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type: Arguments<'{error}>
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type: Arguments<'?>
 }
 "#,
     );
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 dfcd322a39c..eb2c6095012 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
@@ -245,7 +245,7 @@ fn test() {
     v.push("foo");
     for x in v {
         x;
-    } //^ &str
+    } //^ &'static str
 }
 
 //- /alloc.rs crate:alloc
@@ -575,7 +575,7 @@ fn indexing_arrays() {
         "fn main() { &mut [9][2]; }",
         expect![[r#"
             10..26 '{ &mut...[2]; }': ()
-            12..23 '&mut [9][2]': &mut {unknown}
+            12..23 '&mut [9][2]': &'? mut {unknown}
             17..20 '[9]': [i32; 1]
             17..23 '[9][2]': {unknown}
             18..19 '9': i32
@@ -873,7 +873,7 @@ impl<U, T: Trait<U>> O<T> {
 
 fn test(o: O<S>) {
     o.foo();
-} //^^^^^^^ &str
+} //^^^^^^^ &'? str
 "#,
     );
 }
@@ -1016,15 +1016,15 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
     z.foo2();
 }"#,
         expect![[r#"
-            29..33 'self': &Self
-            54..58 'self': &Self
+            29..33 'self': &'? Self
+            54..58 'self': &'? Self
             77..78 'x': impl Trait<u16>
             97..99 '{}': ()
             154..155 'x': impl Trait<u64>
-            174..175 'y': &impl Trait<u32>
+            174..175 'y': &'? impl Trait<u32>
             195..323 '{     ...2(); }': ()
             201..202 'x': impl Trait<u64>
-            208..209 'y': &impl Trait<u32>
+            208..209 'y': &'? impl Trait<u32>
             219..220 'z': S<u16>
             223..224 'S': extern "rust-call" S<u16>(u16) -> S<u16>
             223..227 'S(1)': S<u16>
@@ -1034,13 +1034,13 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
             237..238 'z': S<u16>
             245..246 'x': impl Trait<u64>
             245..252 'x.foo()': u64
-            258..259 'y': &impl Trait<u32>
+            258..259 'y': &'? impl Trait<u32>
             258..265 'y.foo()': u32
             271..272 'z': S<u16>
             271..278 'z.foo()': u16
             284..285 'x': impl Trait<u64>
             284..292 'x.foo2()': i64
-            298..299 'y': &impl Trait<u32>
+            298..299 'y': &'? impl Trait<u32>
             298..306 'y.foo2()': i64
             312..313 'z': S<u16>
             312..320 'z.foo2()': i64
@@ -1204,26 +1204,26 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
     z.foo2();
 }"#,
         expect![[r#"
-            29..33 'self': &Self
-            54..58 'self': &Self
+            29..33 'self': &'? Self
+            54..58 'self': &'? Self
             98..100 '{}': ()
             110..111 'x': impl Trait<u64>
-            130..131 'y': &impl Trait<u64>
+            130..131 'y': &'? impl Trait<u64>
             151..268 '{     ...2(); }': ()
             157..158 'x': impl Trait<u64>
-            164..165 'y': &impl Trait<u64>
+            164..165 'y': &'? impl Trait<u64>
             175..176 'z': impl Trait<u64>
             179..182 'bar': fn bar() -> impl Trait<u64>
             179..184 'bar()': impl Trait<u64>
             190..191 'x': impl Trait<u64>
             190..197 'x.foo()': u64
-            203..204 'y': &impl Trait<u64>
+            203..204 'y': &'? impl Trait<u64>
             203..210 'y.foo()': u64
             216..217 'z': impl Trait<u64>
             216..223 'z.foo()': u64
             229..230 'x': impl Trait<u64>
             229..237 'x.foo2()': i64
-            243..244 'y': &impl Trait<u64>
+            243..244 'y': &'? impl Trait<u64>
             243..251 'y.foo2()': i64
             257..258 'z': impl Trait<u64>
             257..265 'z.foo2()': i64
@@ -1328,7 +1328,7 @@ fn test() {
     a.foo();
 }"#,
         expect![[r#"
-            29..33 'self': &Self
+            29..33 'self': &'? Self
             71..82 '{ loop {} }': !
             73..80 'loop {}': !
             78..80 '{}': ()
@@ -1366,8 +1366,8 @@ fn test() {
     d.foo();
 }"#,
         expect![[r#"
-            49..53 'self': &mut Self
-            101..105 'self': &Self
+            49..53 'self': &'? mut Self
+            101..105 'self': &'? Self
             184..195 '{ loop {} }': ({unknown}, {unknown})
             186..193 'loop {}': !
             191..193 '{}': ()
@@ -1414,10 +1414,10 @@ fn foo<const C: u8, T>() -> (impl FnOnce(&str, T), impl Trait<u8>) {
 }
 "#,
         expect![[r#"
-            134..165 '{     ...(C)) }': (impl FnOnce(&str, T), Bar<u8>)
-            140..163 '(|inpu...ar(C))': (impl FnOnce(&str, T), Bar<u8>)
-            141..154 '|input, t| {}': impl FnOnce(&str, T)
-            142..147 'input': &str
+            134..165 '{     ...(C)) }': (impl FnOnce(&'? str, T), Bar<u8>)
+            140..163 '(|inpu...ar(C))': (impl FnOnce(&'? str, T), Bar<u8>)
+            141..154 '|input, t| {}': impl FnOnce(&'? str, T)
+            142..147 'input': &'? str
             149..150 't': T
             152..154 '{}': ()
             156..159 'Bar': extern "rust-call" Bar<u8>(u8) -> Bar<u8>
@@ -1466,26 +1466,26 @@ fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
     z.foo2();
 }"#,
         expect![[r#"
-            29..33 'self': &Self
-            54..58 'self': &Self
+            29..33 'self': &'? Self
+            54..58 'self': &'? Self
             97..99 '{}': dyn Trait<u64>
             109..110 'x': dyn Trait<u64>
-            128..129 'y': &dyn Trait<u64>
+            128..129 'y': &'? dyn Trait<u64>
             148..265 '{     ...2(); }': ()
             154..155 'x': dyn Trait<u64>
-            161..162 'y': &dyn Trait<u64>
+            161..162 'y': &'? dyn Trait<u64>
             172..173 'z': dyn Trait<u64>
             176..179 'bar': fn bar() -> dyn Trait<u64>
             176..181 'bar()': dyn Trait<u64>
             187..188 'x': dyn Trait<u64>
             187..194 'x.foo()': u64
-            200..201 'y': &dyn Trait<u64>
+            200..201 'y': &'? dyn Trait<u64>
             200..207 'y.foo()': u64
             213..214 'z': dyn Trait<u64>
             213..220 'z.foo()': u64
             226..227 'x': dyn Trait<u64>
             226..234 'x.foo2()': i64
-            240..241 'y': &dyn Trait<u64>
+            240..241 'y': &'? dyn Trait<u64>
             240..248 'y.foo2()': i64
             254..255 'z': dyn Trait<u64>
             254..262 'z.foo2()': i64
@@ -1514,16 +1514,16 @@ fn test(s: S<u32, i32>) {
     s.bar().baz();
 }"#,
         expect![[r#"
-            32..36 'self': &Self
-            102..106 'self': &S<T, U>
-            128..139 '{ loop {} }': &dyn Trait<T, U>
+            32..36 'self': &'? Self
+            102..106 'self': &'? S<T, U>
+            128..139 '{ loop {} }': &'? dyn Trait<T, U>
             130..137 'loop {}': !
             135..137 '{}': ()
-            175..179 'self': &Self
+            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>
             273..286 's.bar().baz()': (u32, i32)
         "#]],
     );
@@ -1548,19 +1548,19 @@ fn test(x: Trait, y: &Trait) -> u64 {
     z.foo();
 }"#,
         expect![[r#"
-            26..30 'self': &Self
+            26..30 'self': &'? Self
             60..62 '{}': dyn Trait
             72..73 'x': dyn Trait
-            82..83 'y': &dyn Trait
+            82..83 'y': &'? dyn Trait
             100..175 '{     ...o(); }': u64
             106..107 'x': dyn Trait
-            113..114 'y': &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
             139..146 'x.foo()': u64
-            152..153 'y': &dyn Trait
+            152..153 'y': &'? dyn Trait
             152..159 'y.foo()': u64
             165..166 'z': dyn Trait
             165..172 'z.foo()': u64
@@ -1580,14 +1580,14 @@ fn main() {
 }
         "#,
         expect![[r#"
-            31..35 'self': &S
+            31..35 'self': &'? S
             37..39 '{}': ()
-            47..48 '_': &dyn Fn(S)
+            47..48 '_': &'? dyn Fn(S)
             58..60 '{}': ()
             71..105 '{     ...()); }': ()
-            77..78 'f': fn f(&dyn Fn(S))
+            77..78 'f': fn f(&'? dyn Fn(S))
             77..102 'f(&|nu...foo())': ()
-            79..101 '&|numb....foo()': &impl Fn(S)
+            79..101 '&|numb....foo()': &'? impl Fn(S)
             80..101 '|numbe....foo()': impl Fn(S)
             81..87 'number': S
             89..95 'number': S
@@ -1790,7 +1790,7 @@ fn test<T: Trait1, U: Trait2>(x: T, y: U) {
     y.foo();
 }"#,
         expect![[r#"
-            53..57 'self': &Self
+            53..57 'self': &'? Self
             66..68 '{}': u32
             185..186 'x': T
             191..192 'y': U
@@ -1819,11 +1819,11 @@ fn test(x: &impl Trait1) {
     x.foo();
 }"#,
         expect![[r#"
-            53..57 'self': &Self
+            53..57 'self': &'? Self
             66..68 '{}': u32
-            119..120 'x': &impl Trait1
+            119..120 'x': &'? impl Trait1
             136..152 '{     ...o(); }': ()
-            142..143 'x': &impl Trait1
+            142..143 'x': &'? impl Trait1
             142..149 'x.foo()': u32
         "#]],
     );
@@ -1934,8 +1934,8 @@ fn test() {
     opt.map(f);
 }"#,
         expect![[r#"
-            28..32 'self': &Self
-            132..136 'self': &Bar<F>
+            28..32 'self': &'? Self
+            132..136 'self': &'? Bar<F>
             149..160 '{ loop {} }': (A1, R)
             151..158 'loop {}': !
             156..158 '{}': ()
@@ -1988,7 +1988,7 @@ fn test() {
     let r2 = lazy2.foo();
 }"#,
         expect![[r#"
-            36..40 'self': &Foo
+            36..40 'self': &'? Foo
             51..53 '{}': usize
             131..132 'f': F
             151..153 '{}': Lazy<T, F>
@@ -2262,14 +2262,14 @@ impl Trait for S2 {
     fn f(&self, x: <Self>::Item) { let y = x; }
 }"#,
         expect![[r#"
-            40..44 'self': &Self
+            40..44 'self': &'? Self
             46..47 'x': Trait::Item<Self>
-            126..130 'self': &S
+            126..130 'self': &'? S
             132..133 'x': u32
             147..161 '{ let y = x; }': ()
             153..154 'y': u32
             157..158 'x': u32
-            228..232 'self': &S2
+            228..232 'self': &'? S2
             234..235 'x': i32
             251..265 '{ let y = x; }': ()
             257..258 'y': i32
@@ -2643,12 +2643,12 @@ fn main() {
             72..74 '_v': F
             117..120 '{ }': ()
             132..163 '{     ... }); }': ()
-            138..148 'f::<(), _>': fn f<(), impl FnOnce(&())>(impl FnOnce(&()))
+            138..148 'f::<(), _>': fn f<(), impl FnOnce(&'? ())>(impl FnOnce(&'? ()))
             138..160 'f::<()... z; })': ()
-            149..159 '|z| { z; }': impl FnOnce(&())
-            150..151 'z': &()
+            149..159 '|z| { z; }': impl FnOnce(&'? ())
+            150..151 'z': &'? ()
             153..159 '{ z; }': ()
-            155..156 'z': &()
+            155..156 'z': &'? ()
         "#]],
     );
 }
@@ -2897,13 +2897,13 @@ fn test(x: &dyn Foo) {
     foo(x);
 }"#,
         expect![[r#"
-            21..22 'x': &dyn Foo
+            21..22 'x': &'? dyn Foo
             34..36 '{}': ()
-            46..47 'x': &dyn Foo
+            46..47 'x': &'? dyn Foo
             59..74 '{     foo(x); }': ()
-            65..68 'foo': fn foo(&dyn Foo)
+            65..68 'foo': fn foo(&'? dyn Foo)
             65..71 'foo(x)': ()
-            69..70 'x': &dyn Foo
+            69..70 'x': &'? dyn Foo
         "#]],
     );
 }
@@ -2927,7 +2927,7 @@ fn test() {
     (IsCopy, NotCopy).test();
 }"#,
         expect![[r#"
-            78..82 'self': &Self
+            78..82 'self': &'? Self
             134..235 '{     ...t(); }': ()
             140..146 'IsCopy': IsCopy
             140..153 'IsCopy.test()': bool
@@ -2969,7 +2969,7 @@ fn test() {
             28..29 'T': {unknown}
             36..38 '{}': T
             36..38: expected T, got ()
-            113..117 'self': &Self
+            113..117 'self': &'? Self
             169..249 '{     ...t(); }': ()
             175..178 'foo': fn foo()
             175..185 'foo.test()': bool
@@ -2997,16 +2997,16 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
     f3.test();
 }"#,
         expect![[r#"
-            22..26 'self': &Self
+            22..26 'self': &'? Self
             76..78 'f1': fn()
             86..88 'f2': fn(usize) -> u8
-            107..109 'f3': fn(u8, u8) -> &u8
+            107..109 'f3': fn(u8, u8) -> &'? u8
             130..178 '{     ...t(); }': ()
             136..138 'f1': fn()
             136..145 'f1.test()': bool
             151..153 'f2': fn(usize) -> u8
             151..160 'f2.test()': bool
-            166..168 'f3': fn(u8, u8) -> &u8
+            166..168 'f3': fn(u8, u8) -> &'? u8
             166..175 'f3.test()': bool
         "#]],
     );
@@ -3027,13 +3027,13 @@ fn test() {
     (1u8, *"foo").test(); // not Sized
 }"#,
         expect![[r#"
-            22..26 'self': &Self
+            22..26 'self': &'? Self
             79..194 '{     ...ized }': ()
             85..88 '1u8': u8
             85..95 '1u8.test()': bool
             101..116 '(*"foo").test()': {unknown}
             102..108 '*"foo"': str
-            103..108 '"foo"': &str
+            103..108 '"foo"': &'static str
             135..145 '(1u8, 1u8)': (u8, u8)
             135..152 '(1u8, ...test()': bool
             136..139 '1u8': u8
@@ -3042,7 +3042,7 @@ fn test() {
             158..178 '(1u8, ...test()': {unknown}
             159..162 '1u8': u8
             164..170 '*"foo"': str
-            165..170 '"foo"': &str
+            165..170 '"foo"': &'static str
         "#]],
     );
 }
@@ -3093,7 +3093,7 @@ fn foo() {
             93..94 'x': Option<i32>
             109..111 '{}': ()
             117..124 '(&f)(s)': ()
-            118..120 '&f': &impl Fn(Option<i32>)
+            118..120 '&f': &'? impl Fn(Option<i32>)
             119..120 'f': impl Fn(Option<i32>)
             122..123 's': Option<i32>
         "#]],
@@ -3170,25 +3170,25 @@ fn foo() {
     f(&s);
 }"#,
         expect![[r#"
-            154..158 'self': &Box<T>
-            166..205 '{     ...     }': &T
-            176..199 'unsafe...nner }': &T
-            185..197 '&*self.inner': &T
+            154..158 'self': &'? Box<T>
+            166..205 '{     ...     }': &'? T
+            176..199 'unsafe...nner }': &'? T
+            185..197 '&*self.inner': &'? T
             186..197 '*self.inner': T
-            187..191 'self': &Box<T>
+            187..191 'self': &'? Box<T>
             187..197 'self.inner': *mut T
             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>)>
-            294..308 '&mut (|ps| {})': &mut impl FnOnce(&Option<i32>)
-            300..307 '|ps| {}': impl FnOnce(&Option<i32>)
-            301..303 'ps': &Option<i32>
+            246..247 'f': Box<dyn FnOnce(&'? Option<i32>)>
+            281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>)>
+            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>)>
             316..321 'f(&s)': ()
-            318..320 '&s': &Option<i32>
+            318..320 '&s': &'? Option<i32>
             319..320 's': Option<i32>
         "#]],
     );
@@ -3320,7 +3320,7 @@ fn f() {
     }
 }"#,
         expect![[r#"
-            46..50 'self': &Self
+            46..50 'self': &'? Self
             58..63 '{ 0 }': u8
             60..61 '0': u8
             115..185 '{     ...   } }': ()
@@ -3595,7 +3595,7 @@ fn take_u32(_: u32) {}
 fn minimized() {
     let v = V::default();
     let p = v.get(&0);
-      //^ &u32
+      //^ &'? u32
     take_u32(42 + p);
 }
 "#,
@@ -3625,7 +3625,7 @@ fn take_u32(_: u32) {}
 fn minimized() {
     let v = V::default();
     let p = v.get();
-      //^ &{unknown}
+      //^ &'? {unknown}
     take_u32(42 + p);
 }
 "#,
@@ -3684,11 +3684,11 @@ fn main() {
 }
 "#,
         expect![[r#"
-            44..48 'self': &Self
-            133..137 'self': &[u8; 4]
+            44..48 'self': &'? Self
+            133..137 'self': &'? [u8; 4]
             155..172 '{     ...     }': usize
             165..166 '2': usize
-            236..240 'self': &[u8; 2]
+            236..240 'self': &'? [u8; 2]
             258..275 '{     ...     }': u8
             268..269 '2': u8
             289..392 '{     ...g(); }': ()
@@ -3732,11 +3732,11 @@ fn main() {
 }
 "#,
         expect![[r#"
-            44..48 'self': &Self
-            151..155 'self': &[u8; L]
+            44..48 'self': &'? Self
+            151..155 'self': &'? [u8; L]
             173..194 '{     ...     }': [u8; L]
             183..188 '*self': [u8; L]
-            184..188 'self': &[u8; L]
+            184..188 'self': &'? [u8; L]
             208..260 '{     ...g(); }': ()
             218..219 'v': [u8; 2]
             222..230 '[0u8; 2]': [u8; 2]
@@ -4056,13 +4056,13 @@ fn g(t: &(dyn Sync + T2 + T1 + Send)) {
 }
         "#,
         expect![[r#"
-            68..69 't': &{unknown}
+            68..69 't': &'? {unknown}
             101..103 '{}': ()
-            109..110 't': &{unknown}
+            109..110 't': &'? {unknown}
             142..155 '{     f(t); }': ()
-            148..149 'f': fn f(&{unknown})
+            148..149 'f': fn f(&'? {unknown})
             148..152 'f(t)': ()
-            150..151 't': &{unknown}
+            150..151 't': &'? {unknown}
         "#]],
     );
 
@@ -4105,7 +4105,7 @@ trait Trait {
 }
 
 fn f(t: &dyn Trait<T = (), T = ()>) {}
-   //^&{unknown}
+   //^&'? {unknown}
         "#,
     );
 }
@@ -4175,27 +4175,27 @@ trait Trait {
 
 fn f<T>(v: impl Trait) {
     let a = v.get::<i32>().deref();
-      //^ &i32
+      //^ &'? i32
     let a = v.get::<T>().deref();
-      //^ &T
+      //^ &'? T
 }
 fn g<'a, T: 'a>(v: impl Trait<Assoc<T> = &'a T>) {
     let a = v.get::<T>();
-      //^ &T
+      //^ &'a T
     let a = v.get::<()>();
-      //^ Trait::Assoc<(), impl Trait<Assoc<T> = &T>>
+      //^ Trait::Assoc<(), impl Trait<Assoc<T> = &'a T>>
 }
 fn h<'a>(v: impl Trait<Assoc<i32> = &'a i32> + Trait<Assoc<i64> = &'a i64>) {
     let a = v.get::<i32>();
-      //^ &i32
+      //^ &'a i32
     let a = v.get::<i64>();
-      //^ &i64
+      //^ &'a i64
 }
 fn i<'a>(v: impl Trait<Assoc<i32> = &'a i32, Assoc<i64> = &'a i64>) {
     let a = v.get::<i32>();
-      //^ &i32
+      //^ &'a i32
     let a = v.get::<i64>();
-      //^ &i64
+      //^ &'a i64
 }
     "#,
     );
@@ -4221,12 +4221,12 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
 }
     "#,
         expect![[r#"
-            90..94 'self': &Self
-            127..128 'v': &(dyn Trait<Assoc<i32> = &i32>)
+            90..94 'self': &'? Self
+            127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32>)
             164..195 '{     ...f(); }': ()
-            170..171 'v': &(dyn Trait<Assoc<i32> = &i32>)
-            170..184 'v.get::<i32>()': &i32
-            170..192 'v.get:...eref()': &i32
+            170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32>)
+            170..184 'v.get::<i32>()': &'? i32
+            170..192 'v.get:...eref()': &'? i32
         "#]],
     );
 }
@@ -4487,19 +4487,19 @@ fn derive_macro_bounds() {
             let x = (&Copy).clone();
               //^ Copy
             let x = (&NotCopy).clone();
-              //^ &NotCopy
+              //^ &'? NotCopy
             let x = (&Generic(Copy)).clone();
               //^ Generic<Copy>
             let x = (&Generic(NotCopy)).clone();
-              //^ &Generic<NotCopy>
+              //^ &'? Generic<NotCopy>
             let x: &AssocGeneric<Copy> = &AssocGeneric(NotCopy);
             let x = x.clone();
-              //^ &AssocGeneric<Copy>
+              //^ &'? AssocGeneric<Copy>
             // let x: &AssocGeneric2<Copy> = &AssocGeneric2(NotCopy);
             // let x = x.clone();
             let x: &AssocGeneric3<Copy> = &AssocGeneric3(Generic(NotCopy));
             let x = x.clone();
-              //^ &AssocGeneric3<Copy>
+              //^ &'? AssocGeneric3<Copy>
             let x = (&R1(Vec())).clone();
               //^ R1
             let x = (&R2(R1(Vec()))).clone();
@@ -4582,7 +4582,7 @@ impl B for u16 {
 fn ttt() {
     let inp = Y;
     x::<u16>(&inp);
-           //^^^^ expected &X, got &Y
+           //^^^^ expected &'? X, got &'? Y
 }
 "#,
     );
@@ -4629,7 +4629,7 @@ fn foo() {
     let mut map = SomeMap;
     map["a"] = ();
     map;
-  //^^^ SomeMap<&str>
+  //^^^ SomeMap<&'static str>
 }
 "#,
     );
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 34326294d2e..2b8de3443b4 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
@@ -5623,7 +5623,7 @@ fn func<T: Debug>(i: Struct<'_, T>) {
     fun_name(i);
 }
 
-fn $0fun_name(i: Struct<'_, T>) {
+fn $0fun_name(i: Struct<T>) {
     foo(i);
 }
 "#,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs
index 64a32dee3d7..62eb642b3bc 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/predicate.rs
@@ -19,7 +19,7 @@ struct Foo<'lt, T, const C: usize> where $0 {}
             en Enum      Enum
             ma makro!(…) macro_rules! makro
             md module
-            st Foo<…>    Foo<'{error}, {unknown}, _>
+            st Foo<…>    Foo<{unknown}, _>
             st Record    Record
             st Tuple     Tuple
             st Unit      Unit
@@ -92,7 +92,7 @@ struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
             en Enum      Enum
             ma makro!(…) macro_rules! makro
             md module
-            st Foo<…>    Foo<'{error}, {unknown}, _>
+            st Foo<…>    Foo<{unknown}, _>
             st Record    Record
             st Tuple     Tuple
             st Unit      Unit
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 66f1bff7c1c..ff38c161087 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
@@ -20,8 +20,8 @@ struct Foo<'lt, T, const C: usize> {
             en Enum      Enum
             ma makro!(…) macro_rules! makro
             md module
-            sp Self      Foo<'{error}, {unknown}, _>
-            st Foo<…>    Foo<'{error}, {unknown}, _>
+            sp Self      Foo<{unknown}, _>
+            st Foo<…>    Foo<{unknown}, _>
             st Record    Record
             st Tuple     Tuple
             st Unit      Unit
@@ -45,8 +45,8 @@ struct Foo<'lt, T, const C: usize>(f$0);
             en Enum       Enum
             ma makro!(…)  macro_rules! makro
             md module
-            sp Self       Foo<'{error}, {unknown}, _>
-            st Foo<…>     Foo<'{error}, {unknown}, _>
+            sp Self       Foo<{unknown}, _>
+            st Foo<…>     Foo<{unknown}, _>
             st Record     Record
             st Tuple      Tuple
             st Unit       Unit
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 07b9f9cc1ff..0cb8c485b2f 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
@@ -332,6 +332,25 @@ fn main(a: SliceIter<'_, Container>) {
     }
 
     #[test]
+    fn lt_hints() {
+        check_types(
+            r#"
+struct S<'lt>;
+
+fn f<'a>() {
+    let x = S::<'static>;
+      //^ S<'static>
+    let y = S::<'_>;
+      //^ S
+    let z = S::<'a>;
+      //^ S<'a>
+
+}
+"#,
+        );
+    }
+
+    #[test]
     fn fn_hints() {
         check_types(
             r#"
@@ -341,7 +360,7 @@ fn foo1() -> impl Fn(f64) { loop {} }
 fn foo2() -> impl Fn(f64, f64) { loop {} }
 fn foo3() -> impl Fn(f64, f64) -> u32 { loop {} }
 fn foo4() -> &'static dyn Fn(f64, f64) -> u32 { loop {} }
-fn foo5() -> &'static dyn Fn(&'static dyn Fn(f64, f64) -> u32, f64) -> u32 { loop {} }
+fn foo5() -> &'static for<'a> dyn Fn(&'a dyn Fn(f64, f64) -> u32, f64) -> u32 { loop {} }
 fn foo6() -> impl Fn(f64, f64) -> u32 + Sized { loop {} }
 fn foo7() -> *const (impl Fn(f64, f64) -> u32 + Sized) { loop {} }