mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 01:38:13 +00:00
Auto merge of #13806 - WaffleLapkin:typed_blåhaj, r=Veykril
fix: Skip adjustment hints if the adjustment is identity (`T` -> `T`) Supersedes https://github.com/rust-lang/rust-analyzer/pull/13765
This commit is contained in:
commit
761b127c47
3 changed files with 62 additions and 19 deletions
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
|
|
|
@ -59,8 +59,12 @@ pub(super) fn hints(
|
|||
});
|
||||
}
|
||||
for adjustment in adjustments.into_iter().rev() {
|
||||
if adjustment.source == adjustment.target {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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>"
|
||||
}
|
||||
|
@ -213,4 +217,20 @@ impl Trait for Struct {}
|
|||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn never_to_never_is_never_shown() {
|
||||
check_with_config(
|
||||
InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
|
||||
r#"
|
||||
fn never() -> ! {
|
||||
return loop {};
|
||||
}
|
||||
|
||||
fn or_else() {
|
||||
let () = () else { return };
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue