Repository: rust-lang/rust-analyzer
Pull request #17595 (2024-07-15 02:47:37)

Implement lifetime inferring

bors: :umbrella: The latest upstream changes (presumably #17620) made this pull request unmergeable. Please [resolve the merge conflicts](https://rustc-dev-guide.rust-lang.org/git.html#rebasing-and-conflicts).
bors: :umbrella: The latest upstream changes (presumably #17907) made this pull request unmergeable. Please [resolve the merge conflicts](https://rustc-dev-guide.rust-lang.org/git.html#rebasing-and-conflicts).

Patch:
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 42d73d105c..8defeee5e8 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -55,7 +55,7 @@ use triomphe::Arc;
 
 use crate::{
     db::HirDatabase,
-    error_lifetime, fold_tys,
+    fold_tys,
     generics::Generics,
     infer::{coerce::CoerceMany, unify::InferenceTable},
     lower::ImplTraitLoweringMode,
@@ -327,13 +327,13 @@ pub struct Adjustment {
 }
 
 impl Adjustment {
-    pub fn borrow(m: Mutability, ty: Ty) -> Self {
-        let ty = TyKind::Ref(m, error_lifetime(), ty).intern(Interner);
-        Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty }
+    pub fn borrow(m: Mutability, ty: Ty, lt: Lifetime) -> Self {
+        let ty = TyKind::Ref(m, lt.clone(), ty).intern(Interner);
+        Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(lt, m)), target: ty }
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum Adjust {
     /// Go from ! to any type.
     NeverToAny,
@@ -353,18 +353,18 @@ pub enum Adjust {
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct OverloadedDeref(pub Option<Mutability>);
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum AutoBorrow {
     /// Converts from T to &T.
-    Ref(Mutability),
+    Ref(Lifetime, Mutability),
     /// Converts from T to *T.
     RawPtr(Mutability),
 }
 
 impl AutoBorrow {
-    fn mutability(self) -> Mutability {
-        let (AutoBorrow::Ref(m) | AutoBorrow::RawPtr(m)) = self;
-        m
+    fn mutability(&self) -> Mutability {
+        let (AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) = self;
+        *m
     }
 }
 
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 034ed2d691..edaa1091fe 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -474,7 +474,7 @@ impl InferenceContext<'_> {
 
     fn walk_expr_with_adjust(&mut self, tgt_expr: ExprId, adjustment: &[Adjustment]) {
         if let Some((last, rest)) = adjustment.split_last() {
-            match last.kind {
+            match &last.kind {
                 Adjust::NeverToAny | Adjust::Deref(None) | Adjust::Pointer(_) => {
                     self.walk_expr_with_adjust(tgt_expr, rest)
                 }
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index 6f85a4a424..7e758c0b51 100644
--- a/crates/hir-ty/src/infer/coerce.rs
+++ b/crates/hir-ty/src/infer/coerce.rs
@@ -18,14 +18,13 @@ use triomphe::Arc;
 use crate::{
     autoderef::{Autoderef, AutoderefKind},
     db::HirDatabase,
-    error_lifetime,
     infer::{
         Adjust, Adjustment, AutoBorrow, InferOk, InferenceContext, OverloadedDeref, PointerCast,
         TypeError, TypeMismatch,
     },
     utils::ClosureSubst,
-    Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
-    Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
+    Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Lifetime,
+    Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
 };
 
 use super::unify::InferenceTable;
@@ -301,7 +300,7 @@ impl InferenceTable<'_> {
         // Examine the supertype and consider auto-borrowing.
         match to_ty.kind(Interner) {
             TyKind::Raw(mt, _) => return self.coerce_ptr(from_ty, to_ty, *mt),
-            TyKind::Ref(mt, _, _) => return self.coerce_ref(from_ty, to_ty, *mt),
+            TyKind::Ref(mt, lt, _) => return self.coerce_ref(from_ty, to_ty, *mt, lt),
             _ => {}
         }
 
@@ -377,11 +376,17 @@ impl InferenceTable<'_> {
     /// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
     /// To match `A` with `B`, autoderef will be performed,
     /// calling `deref`/`deref_mut` where necessary.
-    fn coerce_ref(&mut self, from_ty: Ty, to_ty: &Ty, to_mt: Mutability) -> CoerceResult {
-        let from_mt = match from_ty.kind(Interner) {
-            &TyKind::Ref(mt, _, _) => {
-                coerce_mutabilities(mt, to_mt)?;
-                mt
+    fn coerce_ref(
+        &mut self,
+        from_ty: Ty,
+        to_ty: &Ty,
+        to_mt: Mutability,
+        to_lt: &Lifetime,
+    ) -> CoerceResult {
+        let (_from_lt, from_mt) = match from_ty.kind(Interner) {
+            TyKind::Ref(mt, lt, _) => {
+                coerce_mutabilities(*mt, to_mt)?;
+                (lt.clone(), *mt) // clone is probably not good?
             }
             _ => return self.unify_and(&from_ty, to_ty, identity),
         };
@@ -427,8 +432,8 @@ impl InferenceTable<'_> {
             // compare those. Note that this means we use the target
             // mutability [1], since it may be that we are coercing
             // from `&mut T` to `&U`.
-            let lt = error_lifetime(); // FIXME: handle lifetimes correctly, see rustc
-            let derefd_from_ty = TyKind::Ref(to_mt, lt, referent_ty).intern(Interner);
+            let lt = to_lt; // FIXME: Involve rustc LUB and SUB flag checks
+            let derefd_from_ty = TyKind::Ref(to_mt, lt.clone(), referent_ty).intern(Interner);
             match autoderef.table.try_unify(&derefd_from_ty, to_ty) {
                 Ok(result) => {
                     found = Some(result.map(|()| derefd_from_ty));
@@ -472,8 +477,10 @@ impl InferenceTable<'_> {
         }
 
         let mut adjustments = auto_deref_adjust_steps(&autoderef);
-        adjustments
-            .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(to_mt)), target: ty.clone() });
+        adjustments.push(Adjustment {
+            kind: Adjust::Borrow(AutoBorrow::Ref(to_lt.clone(), to_mt)),
+            target: ty.clone(),
+        });
 
         success(adjustments, ty, goals)
     }
@@ -621,11 +628,11 @@ impl InferenceTable<'_> {
             (TyKind::Ref(from_mt, _, from_inner), &TyKind::Ref(to_mt, _, _)) => {
                 coerce_mutabilities(*from_mt, to_mt)?;
 
-                let lt = error_lifetime();
+                let lt = self.new_lifetime_var();
                 Some((
                     Adjustment { kind: Adjust::Deref(None), target: from_inner.clone() },
                     Adjustment {
-                        kind: Adjust::Borrow(AutoBorrow::Ref(to_mt)),
+                        kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), to_mt)),
                         target: TyKind::Ref(to_mt, lt, from_inner.clone()).intern(Interner),
                     },
                 ))
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index e40c6a63f6..89d92ea9af 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -635,7 +635,10 @@ impl InferenceContext<'_> {
                 let inner_ty = self.infer_expr_inner(*expr, &expectation);
                 match rawness {
                     Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
-                    Rawness::Ref => TyKind::Ref(mutability, error_lifetime(), inner_ty),
+                    Rawness::Ref => {
+                        let lt = self.table.new_lifetime_var();
+                        TyKind::Ref(mutability, lt, inner_ty)
+                    }
                 }
                 .intern(Interner)
             }
@@ -786,7 +789,11 @@ impl InferenceContext<'_> {
                             adj.apply(&mut self.table, base_ty)
                         });
                     // mutability will be fixed up in `InferenceContext::infer_mut`;
-                    adj.push(Adjustment::borrow(Mutability::Not, self_ty.clone()));
+                    adj.push(Adjustment::borrow(
+                        Mutability::Not,
+                        self_ty.clone(),
+                        self.table.new_lifetime_var(),
+                    ));
                     self.write_expr_adj(*base, adj);
                     if let Some(func) = self
                         .db
@@ -991,7 +998,7 @@ impl InferenceContext<'_> {
         match fn_x {
             FnTrait::FnOnce => (),
             FnTrait::FnMut => {
-                if let TyKind::Ref(Mutability::Mut, _, inner) = derefed_callee.kind(Interner) {
+                if let TyKind::Ref(Mutability::Mut, lt, inner) = derefed_callee.kind(Interner) {
                     if adjustments
                         .last()
                         .map(|it| matches!(it.kind, Adjust::Borrow(_)))
@@ -1000,15 +1007,27 @@ impl InferenceContext<'_> {
                         // prefer reborrow to move
                         adjustments
                             .push(Adjustment { kind: Adjust::Deref(None), target: inner.clone() });
-                        adjustments.push(Adjustment::borrow(Mutability::Mut, inner.clone()))
+                        adjustments.push(Adjustment::borrow(
+                            Mutability::Mut,
+                            inner.clone(),
+                            lt.clone(),
+                        ))
                     }
                 } else {
-                    adjustments.push(Adjustment::borrow(Mutability::Mut, derefed_callee.clone()));
+                    adjustments.push(Adjustment::borrow(
+                        Mutability::Mut,
+                        derefed_callee.clone(),
+                        self.table.new_lifetime_var(),
+                    ));
                 }
             }
             FnTrait::Fn => {
                 if !matches!(derefed_callee.kind(Interner), TyKind::Ref(Mutability::Not, _, _)) {
-                    adjustments.push(Adjustment::borrow(Mutability::Not, derefed_callee.clone()));
+                    adjustments.push(Adjustment::borrow(
+                        Mutability::Not,
+                        derefed_callee.clone(),
+                        self.table.new_lifetime_var(),
+                    ));
                 }
             }
         }
@@ -1313,11 +1332,11 @@ impl InferenceContext<'_> {
             Some(sig) => {
                 let p_left = &sig.params()[0];
                 if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. }) {
-                    if let &TyKind::Ref(mtbl, _, _) = p_left.kind(Interner) {
+                    if let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner) {
                         self.write_expr_adj(
                             lhs,
                             vec![Adjustment {
-                                kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
+                                kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
                                 target: p_left.clone(),
                             }],
                         );
@@ -1325,11 +1344,11 @@ impl InferenceContext<'_> {
                 }
                 let p_right = &sig.params()[1];
                 if matches!(op, BinaryOp::CmpOp(..)) {
-                    if let &TyKind::Ref(mtbl, _, _) = p_right.kind(Interner) {
+                    if let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner) {
                         self.write_expr_adj(
                             rhs,
                             vec![Adjustment {
-                                kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
+                                kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
                                 target: p_right.clone(),
                             }],
                         );
diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs
index 66267e08db..7fed5f0203 100644
--- a/crates/hir-ty/src/infer/mutability.rs
+++ b/crates/hir-ty/src/infer/mutability.rs
@@ -28,7 +28,7 @@ impl InferenceContext<'_> {
                     Adjust::NeverToAny | Adjust::Deref(None) | Adjust::Pointer(_) => (),
                     Adjust::Deref(Some(d)) => *d = OverloadedDeref(Some(mutability)),
                     Adjust::Borrow(b) => match b {
-                        AutoBorrow::Ref(m) | AutoBorrow::RawPtr(m) => mutability = *m,
+                        AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m) => mutability = *m,
                     },
                 }
             }
@@ -125,7 +125,7 @@ impl InferenceContext<'_> {
                                     .get_mut(&base)
                                     .and_then(|it| it.last_mut());
                                 if let Some(Adjustment {
-                                    kind: Adjust::Borrow(AutoBorrow::Ref(mutability)),
+                                    kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
                                     target,
                                 }) = base_adjustments
                                 {
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index f3c6f13a08..50542b2acd 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -12,7 +12,6 @@ use stdx::TupleExt;
 
 use crate::{
     consteval::{try_const_usize, usize_const},
-    error_lifetime,
     infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
     lower::lower_to_chalk_mutability,
     primitive::UintTy,
@@ -394,19 +393,20 @@ impl InferenceContext<'_> {
         expected: &Ty,
         default_bm: BindingMode,
     ) -> Ty {
-        let expectation = match expected.as_reference() {
-            Some((inner_ty, _lifetime, _exp_mut)) => inner_ty.clone(),
+        let (expectation_type, expectation_lt) = match expected.as_reference() {
+            Some((inner_ty, lifetime, _exp_mut)) => (inner_ty.clone(), lifetime.clone()),
             None => {
                 let inner_ty = self.table.new_type_var();
+                let inner_lt = self.table.new_lifetime_var();
                 let ref_ty =
-                    TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner);
+                    TyKind::Ref(mutability, inner_lt.clone(), inner_ty.clone()).intern(Interner);
                 // Unification failure will be reported by the caller.
                 self.unify(&ref_ty, expected);
-                inner_ty
+                (inner_ty, inner_lt)
             }
         };
-        let subty = self.infer_pat(inner_pat, &expectation, default_bm);
-        TyKind::Ref(mutability, error_lifetime(), subty).intern(Interner)
+        let subty = self.infer_pat(inner_pat, &expectation_type, default_bm);
+        TyKind::Ref(mutability, expectation_lt, subty).intern(Interner)
     }
 
     fn infer_bind_pat(
@@ -433,7 +433,8 @@ impl InferenceContext<'_> {
 
         let bound_ty = match mode {
             BindingMode::Ref(mutability) => {
-                TyKind::Ref(mutability, error_lifetime(), inner_ty.clone()).intern(Interner)
+                let inner_lt = self.table.new_lifetime_var();
+                TyKind::Ref(mutability, inner_lt, inner_ty.clone()).intern(Interner)
             }
             BindingMode::Move => inner_ty.clone(),
         };
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index 3e3578b9f9..c0f5ddddcb 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -17,12 +17,12 @@ use triomphe::Arc;
 
 use super::{InferOk, InferResult, InferenceContext, TypeError};
 use crate::{
-    consteval::unknown_const, db::HirDatabase, error_lifetime, fold_generic_args,
-    fold_tys_and_consts, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical,
-    Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData,
-    Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy,
-    ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
-    TyKind, VariableKind, WhereClause,
+    consteval::unknown_const, db::HirDatabase, fold_generic_args, fold_tys_and_consts,
+    to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue,
+    DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData, Guidance, InEnvironment,
+    InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy, ProjectionTyExt, Scalar,
+    Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
+    WhereClause,
 };
 
 impl InferenceContext<'_> {
@@ -105,7 +105,7 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
                 VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(Interner),
                 // Chalk can sometimes return new lifetime variables. We just replace them by errors
                 // for now.
-                VariableKind::Lifetime => error_lifetime().cast(Interner),
+                VariableKind::Lifetime => ctx.new_lifetime_var().cast(Interner),
                 VariableKind::Const(ty) => ctx.new_const_var(ty.clone()).cast(Interner),
             }),
         );
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 8ba8071d36..3ddfea13ab 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -542,7 +542,8 @@ impl ReceiverAdjustments {
             }
         }
         if let Some(m) = self.autoref {
-            let a = Adjustment::borrow(m, ty);
+            let lt = table.new_lifetime_var();
+            let a = Adjustment::borrow(m, ty, lt);
             ty = a.target.clone();
             adjust.push(a);
         }
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 9aa2eeebc1..b1db9b24f7 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -337,7 +337,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
                     Ok(Some(current))
                 }
-                Adjust::Borrow(AutoBorrow::Ref(m) | AutoBorrow::RawPtr(m)) => {
+                Adjust::Borrow(AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) => {
                     let Some((p, current)) =
                         self.lower_expr_as_place_with_adjust(current, expr_id, true, rest)?
                     else {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index a377163162..d086aee428 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -1179,7 +1179,8 @@ impl<'db> SemanticsImpl<'db> {
                         hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
                             Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
                         }
-                        hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
+                        hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(_, m)) => {
+                            // FIXME: Handle lifetimes here
                             Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
                         }
                         hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),


Test patch:
diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs
index eded786a64..efd8546216 100644
--- a/crates/hir-ty/src/tests.rs
+++ b/crates/hir-ty/src/tests.rs
@@ -26,6 +26,7 @@ use hir_def::{
     AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId,
 };
 use hir_expand::{db::ExpandDatabase, FileRange, InFile};
+use itertools::Itertools;
 use rustc_hash::FxHashMap;
 use stdx::format_to;
 use syntax::{
@@ -94,7 +95,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
     let mut had_annotations = false;
     let mut mismatches = FxHashMap::default();
     let mut types = FxHashMap::default();
-    let mut adjustments = FxHashMap::<_, Vec<_>>::default();
+    let mut adjustments = FxHashMap::default();
     for (file_id, annotations) in db.extract_annotations() {
         for (range, expected) in annotations {
             let file_range = FileRange { file_id, range };
@@ -107,13 +108,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
             } else if expected.starts_with("adjustments:") {
                 adjustments.insert(
                     file_range,
-                    expected
-                        .trim_start_matches("adjustments:")
-                        .trim()
-                        .split(',')
-                        .map(|it| it.trim().to_owned())
-                        .filter(|it| !it.is_empty())
-                        .collect(),
+                    expected.trim_start_matches("adjustments:").trim().to_owned(),
                 );
             } else {
                 panic!("unexpected annotation: {expected}");
@@ -200,7 +195,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                     adjustments
                         .iter()
                         .map(|Adjustment { kind, .. }| format!("{kind:?}"))
-                        .collect::<Vec<_>>()
+                        .join(", ")
                 );
             }
         }
diff --git a/crates/hir-ty/src/tests/coercion.rs b/crates/hir-ty/src/tests/coercion.rs
index 526db2af6d..908bbc248c 100644
--- a/crates/hir-ty/src/tests/coercion.rs
+++ b/crates/hir-ty/src/tests/coercion.rs
@@ -49,7 +49,7 @@ fn let_stmt_coerce() {
 //- minicore: coerce_unsized
 fn test() {
     let x: &[isize] = &[1];
-                   // ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
+                   // ^^^^ adjustments: Deref(None), Borrow(Ref('?3, Not)), Pointer(Unsize)
     let x: *const [isize] = &[1];
                          // ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
 }
@@ -96,7 +96,7 @@ fn foo<T>(x: &[T]) -> &[T] { x }
 fn test() {
     let x = if true {
         foo(&[1])
-         // ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
+         // ^^^^ adjustments: Deref(None), Borrow(Ref('?8, Not)), Pointer(Unsize)
     } else {
         &[1]
     };
@@ -148,7 +148,7 @@ fn foo<T>(x: &[T]) -> &[T] { x }
 fn test(i: i32) {
     let x = match i {
         2 => foo(&[2]),
-              // ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
+              // ^^^^ adjustments: Deref(None), Borrow(Ref('?10, Not)), Pointer(Unsize)
         1 => &[1],
         _ => &[3],
     };
@@ -267,7 +267,7 @@ fn takes_ref_str(x: &str) {}
 fn returns_string() -> String { loop {} }
 fn test() {
     takes_ref_str(&{ returns_string() });
-               // ^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(None), Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref(Not))
+               // ^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(None), Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref('{error}, Not))
 }
 "#,
     );
@@ -849,8 +849,8 @@ impl core::cmp::PartialEq for Struct {
 }
 fn test() {
     Struct == Struct;
- // ^^^^^^ adjustments: Borrow(Ref(Not))
-           // ^^^^^^ adjustments: Borrow(Ref(Not))
+ // ^^^^^^ adjustments: Borrow(Ref('{error}, Not))
+           // ^^^^^^ adjustments: Borrow(Ref('{error}, Not))
 }",
     );
 }
@@ -866,7 +866,7 @@ impl core::ops::AddAssign for Struct {
 }
 fn test() {
     Struct += Struct;
- // ^^^^^^ adjustments: Borrow(Ref(Mut))
+ // ^^^^^^ adjustments: Borrow(Ref('{error}, Mut))
            // ^^^^^^ adjustments:
 }",
     );
@@ -880,7 +880,7 @@ fn adjust_index() {
 fn test() {
     let x = [1, 2, 3];
     x[2] = 6;
- // ^ adjustments: Borrow(Ref(Mut))
+ // ^ adjustments: Borrow(Ref('?8, Mut))
 }
     ",
     );
@@ -905,11 +905,11 @@ impl core::ops::IndexMut for StructMut {
 }
 fn test() {
     Struct[0];
- // ^^^^^^ adjustments: Borrow(Ref(Not))
+ // ^^^^^^ adjustments: Borrow(Ref('?2, Not))
     StructMut[0];
- // ^^^^^^^^^ adjustments: Borrow(Ref(Not))
+ // ^^^^^^^^^ adjustments: Borrow(Ref('?5, Not))
     &mut StructMut[0];
-      // ^^^^^^^^^ adjustments: Borrow(Ref(Mut))
+      // ^^^^^^^^^ adjustments: Borrow(Ref('?8, Mut))
 }",
     );
 }
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index 14e2e74653..610fc9b6b4 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -1186,11 +1186,11 @@ fn test() {
             89..109 '{     ...     }': bool
             99..103 'true': bool
             123..167 '{     ...o(); }': ()
-            133..134 's': &'? S
+            133..134 's': &'static S
             137..151 'unsafe { f() }': &'static S
             146..147 'f': fn f() -> &'static S
             146..149 'f()': &'static S
-            157..158 's': &'? S
+            157..158 's': &'static S
             157..164 's.foo()': bool
         "#]],
     );
@@ -1847,9 +1847,9 @@ impl Foo {
 }
 fn test() {
     Foo.foo();
-  //^^^ adjustments: Borrow(Ref(Not))
+  //^^^ adjustments: Borrow(Ref('?1, Not))
     (&Foo).foo();
-  // ^^^^ adjustments: Deref(None), Borrow(Ref(Not))
+  // ^^^^ adjustments: Deref(None), Borrow(Ref('?3, Not))
 }
 "#,
     );
@@ -1863,7 +1863,7 @@ fn receiver_adjustment_unsize_array() {
 fn test() {
     let a = [1, 2, 3];
     a.len();
-} //^ adjustments: Borrow(Ref(Not)), Pointer(Unsize)
+} //^ adjustments: Borrow(Ref('?7, Not)), Pointer(Unsize)
 "#,
     );
 }
@@ -2076,7 +2076,7 @@ impl Foo {
 }
 fn test() {
     Box::new(Foo).foo();
-  //^^^^^^^^^^^^^ adjustments: Deref(None), Borrow(Ref(Not))
+  //^^^^^^^^^^^^^ adjustments: Deref(None), Borrow(Ref('?3, Not))
 }
 "#,
     );
@@ -2094,7 +2094,7 @@ impl Foo {
 use core::mem::ManuallyDrop;
 fn test() {
     ManuallyDrop::new(Foo).foo();
-  //^^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref(Not))
+  //^^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref('?4, Not))
 }
 "#,
     );
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index a15670b3c8..1c6fa62e30 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -1201,8 +1201,8 @@ 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]
+            225..226 'i': [&'static str; 2]
+            229..239 '["a", "b"]': [&'static str; 2]
             230..233 '"a"': &'static str
             235..238 '"b"': &'static str
             250..251 'b': [[&'? str; 1]; 2]