about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-12-20 19:33:27 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-12-20 19:33:27 +0000
commit91a89efcf29d2281a55cc5723784d0c93f39c01c (patch)
treeda15347ae513494cbe1f8176df5ffb41f95819f3
parent927d56a67d10299a751b3b571c841d1c6b6af106 (diff)
downloadrust-91a89efcf29d2281a55cc5723784d0c93f39c01c.tar.gz
rust-91a89efcf29d2281a55cc5723784d0c93f39c01c.zip
Save source & target types in `hir`'s `expr_adjustments`
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/hir/src/semantics.rs52
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs2
3 files changed, 42 insertions, 19 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 316f3938c6c..b841e580b6c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -3691,6 +3691,13 @@ impl From<ItemInNs> for ScopeDef {
     }
 }
 
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Adjustment {
+    pub source: Type,
+    pub target: Type,
+    pub kind: Adjust,
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub enum Adjust {
     /// Go from ! to any type.
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index f887c759849..2ed62372ae2 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -2,7 +2,7 @@
 
 mod source_to_def;
 
-use std::{cell::RefCell, fmt, iter, ops};
+use std::{cell::RefCell, fmt, iter, mem, ops};
 
 use base_db::{FileId, FileRange};
 use hir_def::{
@@ -29,7 +29,7 @@ use crate::{
     db::HirDatabase,
     semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
-    Access, Adjust, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
+    Access, Adjust, Adjustment, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
     DeriveHelper, Field, Function, HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local,
     Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, ToolModule, Trait, Type,
     TypeAlias, TypeParam, VariantDef,
@@ -334,7 +334,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.resolve_trait(trait_)
     }
 
-    pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
+    pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
         self.imp.expr_adjustments(expr)
     }
 
@@ -1067,26 +1067,42 @@ impl<'db> SemanticsImpl<'db> {
         }
     }
 
-    fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
+    fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
         let mutability = |m| match m {
             hir_ty::Mutability::Not => Mutability::Shared,
             hir_ty::Mutability::Mut => Mutability::Mut,
         };
-        self.analyze(expr.syntax())?.expr_adjustments(self.db, expr).map(|it| {
+
+        let analyzer = self.analyze(expr.syntax())?;
+
+        let (mut source_ty, _) = analyzer.type_of_expr(self.db, expr)?;
+
+        analyzer.expr_adjustments(self.db, expr).map(|it| {
             it.iter()
-                .map(|adjust| match adjust.kind {
-                    hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
-                    hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
-                        Adjust::Deref(Some(OverloadedDeref(mutability(m))))
-                    }
-                    hir_ty::Adjust::Deref(None) => Adjust::Deref(None),
-                    hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
-                        Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
-                    }
-                    hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
-                        Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
-                    }
-                    hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),
+                .map(|adjust| {
+                    let target =
+                        Type::new_with_resolver(self.db, &analyzer.resolver, adjust.target.clone());
+                    let kind = match adjust.kind {
+                        hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
+                        hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
+                            Adjust::Deref(Some(OverloadedDeref(mutability(m))))
+                        }
+                        hir_ty::Adjust::Deref(None) => Adjust::Deref(None),
+                        hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
+                            Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
+                        }
+                        hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
+                            Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
+                        }
+                        hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),
+                    };
+
+                    // Update `source_ty` for the next adjustment
+                    let source = mem::replace(&mut source_ty, target.clone());
+
+                    let adjustment = Adjustment { source, target, kind };
+
+                    adjustment
                 })
                 .collect()
         })
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index 983aa1dfd56..52cfa452b97 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -60,7 +60,7 @@ pub(super) fn hints(
     }
     for adjustment in adjustments.into_iter().rev() {
         // FIXME: Add some nicer tooltips to each of these
-        let text = match adjustment {
+        let text = match adjustment.kind {
             Adjust::NeverToAny if config.adjustment_hints == AdjustmentHints::Always => {
                 "<never-to-any>"
             }