From 91a89efcf29d2281a55cc5723784d0c93f39c01c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 20 Dec 2022 19:33:27 +0000 Subject: [PATCH] Save source & target types in `hir`'s `expr_adjustments` --- crates/hir/src/lib.rs | 7 ++++ crates/hir/src/semantics.rs | 52 ++++++++++++++++-------- crates/ide/src/inlay_hints/adjustment.rs | 2 +- 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 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> { + pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option> { self.imp.expr_adjustments(expr) } @@ -1067,26 +1067,42 @@ impl<'db> SemanticsImpl<'db> { } } - fn expr_adjustments(&self, expr: &ast::Expr) -> Option> { + fn expr_adjustments(&self, expr: &ast::Expr) -> Option> { 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 => { "" }