Render places in capture inlay hints

This commit is contained in:
Lukas Wirth 2023-05-07 09:42:50 +02:00
parent abcdb4bc7d
commit 4c5fd19ee5
5 changed files with 21 additions and 31 deletions

View File

@ -304,7 +304,6 @@ pub struct HirDisplayWrapper<'a, T> {
pub enum ClosureStyle {
/// `impl FnX(i32, i32) -> i32`, where `FnX` is the most special trait between `Fn`, `FnMut`, `FnOnce` that the
/// closure implements. This is the default.
// FIXME: Allow rendering non capturing closures as plain function pointers?
ImplFn,
/// `|i32, i32| -> i32`
RANotation,

View File

@ -170,23 +170,7 @@ impl CapturedItem {
self.kind
}
pub fn display_kind(&self) -> &'static str {
match self.kind {
CaptureKind::ByRef(k) => match k {
BorrowKind::Shared => "immutable borrow",
BorrowKind::Shallow => {
never!("shallow borrow should not happen in closure captures");
"shallow borrow"
},
BorrowKind::Unique => "unique immutable borrow ([read more](https://doc.rust-lang.org/stable/reference/types/closure.html#unique-immutable-borrows-in-captures))",
BorrowKind::Mut { .. } => "mutable borrow",
},
CaptureKind::ByValue => "move",
}
}
pub fn display_place(&self, owner: ClosureId, db: &dyn HirDatabase) -> String {
let owner = db.lookup_intern_closure(owner.into()).0;
pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
let body = db.body(owner);
let mut result = body[self.place.local].name.to_string();
let mut field_need_paren = false;

View File

@ -3214,7 +3214,11 @@ impl Closure {
let owner = db.lookup_intern_closure((self.id).into()).0;
let infer = &db.infer(owner);
let info = infer.closure_info(&self.id);
info.0.iter().cloned().map(|capture| ClosureCapture { owner, capture }).collect()
info.0
.iter()
.cloned()
.map(|capture| ClosureCapture { owner, closure: self.id, capture })
.collect()
}
pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait {
@ -3228,6 +3232,7 @@ impl Closure {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClosureCapture {
owner: DefWithBodyId,
closure: ClosureId,
capture: hir_ty::CapturedItem,
}
@ -3251,12 +3256,8 @@ impl ClosureCapture {
}
}
pub fn display_kind(&self) -> &'static str {
self.capture.display_kind()
}
pub fn display_place(&self, owner: ClosureId, db: &dyn HirDatabase) -> String {
self.capture.display_place(owner, db)
pub fn display_place(&self, db: &dyn HirDatabase) -> String {
self.capture.display_place(self.owner, db)
}
}

View File

@ -3,7 +3,8 @@ use std::fmt::Display;
use either::Either;
use hir::{
Adt, AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo,
Adt, AsAssocItem, AttributeTemplate, CaptureKind, HasAttrs, HasSource, HirDisplay, Semantics,
TypeInfo,
};
use ide_db::{
base_db::SourceDatabase,
@ -54,8 +55,14 @@ pub(super) fn closure_expr(
let mut captures = c
.captured_items(sema.db)
.into_iter()
.map(|x| {
format!("* `{}` by {}", x.display_place(c.clone().into(), sema.db), x.display_kind())
.map(|it| {
let borrow_kind= match it.kind() {
CaptureKind::SharedRef => "immutable borrow",
CaptureKind::UniqueSharedRef => "unique immutable borrow ([read more](https://doc.rust-lang.org/stable/reference/types/closure.html#unique-immutable-borrows-in-captures))",
CaptureKind::MutableRef => "mutable borrow",
CaptureKind::Move => "move",
};
format!("* `{}` by {}", it.display_place(sema.db), borrow_kind)
})
.join("\n");
if captures.trim().is_empty() {

View File

@ -65,7 +65,7 @@ pub(super) fn hints(
hir::CaptureKind::MutableRef => "&mut ",
hir::CaptureKind::Move => "",
},
local.name(sema.db)
capture.display_place(sema.db)
),
None,
source.name().and_then(|name| sema.original_range_opt(name.syntax())),
@ -156,13 +156,12 @@ fn main() {
// ^ )
&mut baz;
};
// FIXME: &mut qux should be &unique qux
|| {
// ^ move
// ^ (
// ^ &mut baz
// ^ , $
// ^ &mut qux
// ^ &mut *qux
// ^ )
baz = NonCopy;
*qux = NonCopy;