feat: Add binding mode inlay hints

This commit is contained in:
Lukas Wirth 2022-05-14 14:26:08 +02:00
parent 06448c5548
commit 6b696fced8
12 changed files with 201 additions and 41 deletions

View file

@ -3332,6 +3332,12 @@ impl Callable {
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum BindingMode {
Move,
Ref(Mutability),
}
/// For IDE only
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ScopeDef {

View file

@ -30,9 +30,9 @@ use crate::{
db::HirDatabase,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer},
Access, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path, ScopeDef,
ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
Access, BindingMode, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path,
ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -336,6 +336,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.type_of_self(param)
}
pub fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
self.imp.pattern_adjustments(pat)
}
pub fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
self.imp.binding_mode_of_pat(pat)
}
pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
self.imp.resolve_method_call(call).map(Function::from)
}
@ -951,6 +959,16 @@ impl<'db> SemanticsImpl<'db> {
self.analyze(param.syntax())?.type_of_self(self.db, param)
}
fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
self.analyze(pat.syntax())
.and_then(|it| it.pattern_adjustments(self.db, pat))
.unwrap_or_default()
}
fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
self.analyze(pat.syntax())?.binding_mode_of_pat(self.db, pat)
}
fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> {
self.analyze(call.syntax())?.resolve_method_call(self.db, call).map(|(id, _)| id)
}

View file

@ -34,15 +34,16 @@ use hir_ty::{
Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution, TyExt,
TyLoweringContext,
};
use smallvec::SmallVec;
use syntax::{
ast::{self, AstNode},
SyntaxKind, SyntaxNode, TextRange, TextSize,
};
use crate::{
db::HirDatabase, semantics::PathResolution, Adt, AssocItem, BuiltinAttr, BuiltinType, Const,
Field, Function, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias,
Variant,
db::HirDatabase, semantics::PathResolution, Adt, AssocItem, BindingMode, BuiltinAttr,
BuiltinType, Const, Field, Function, Local, Macro, ModuleDef, Static, Struct, ToolModule,
Trait, Type, TypeAlias, Variant,
};
/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
@ -182,7 +183,7 @@ impl SourceAnalyzer {
let coerced = infer
.pat_adjustments
.get(&pat_id)
.and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.clone()));
.and_then(|adjusts| adjusts.last().map(|adjust| adjust.clone()));
let ty = infer[pat_id].clone();
let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
Some((mk_ty(ty), coerced.map(mk_ty)))
@ -199,6 +200,38 @@ impl SourceAnalyzer {
Some(Type::new_with_resolver(db, &self.resolver, ty))
}
pub(crate) fn binding_mode_of_pat(
&self,
_db: &dyn HirDatabase,
pat: &ast::IdentPat,
) -> Option<BindingMode> {
let pat_id = self.pat_id(&pat.clone().into())?;
let infer = self.infer.as_ref()?;
infer.pat_binding_modes.get(&pat_id).map(|bm| match bm {
hir_ty::BindingMode::Move => BindingMode::Move,
hir_ty::BindingMode::Ref(hir_ty::Mutability::Mut) => BindingMode::Ref(Mutability::Mut),
hir_ty::BindingMode::Ref(hir_ty::Mutability::Not) => {
BindingMode::Ref(Mutability::Shared)
}
})
}
pub(crate) fn pattern_adjustments(
&self,
db: &dyn HirDatabase,
pat: &ast::Pat,
) -> Option<SmallVec<[Type; 1]>> {
let pat_id = self.pat_id(&pat)?;
let infer = self.infer.as_ref()?;
Some(
infer
.pat_adjustments
.get(&pat_id)?
.iter()
.map(|ty| Type::new_with_resolver(db, &self.resolver, ty.clone()))
.collect(),
)
}
pub(crate) fn resolve_method_call(
&self,
db: &dyn HirDatabase,