7942: Show whether a binding is mutable or not on hover r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-03-09 16:23:51 +00:00 committed by GitHub
commit c45ac6effe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 33 deletions

View file

@ -1296,13 +1296,7 @@ impl Local {
pub fn is_mut(self, db: &dyn HirDatabase) -> bool { pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
let body = db.body(self.parent.into()); let body = db.body(self.parent.into());
match &body[self.pat_id] { matches!(&body[self.pat_id], Pat::Bind { mode: BindingAnnotation::Mutable, .. })
Pat::Bind { mode, .. } => match mode {
BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
_ => false,
},
_ => false,
}
} }
pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody {

View file

@ -71,11 +71,7 @@ impl ShortLabel for ast::TypeAlias {
impl ShortLabel for ast::Const { impl ShortLabel for ast::Const {
fn short_label(&self) -> Option<String> { fn short_label(&self) -> Option<String> {
let mut new_buf = short_label_from_ty(self, self.ty(), "const ")?; short_label_from_ty(self, self.ty(), "const ")
if let Some(expr) = self.body() {
format_to!(new_buf, " = {}", expr.syntax());
}
Some(new_buf)
} }
} }

View file

@ -1,3 +1,4 @@
use either::Either;
use hir::{ use hir::{
Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource,
HirDisplay, Module, ModuleDef, ModuleSource, Semantics, HirDisplay, Module, ModuleDef, ModuleSource, Semantics,
@ -366,7 +367,7 @@ fn hover_for_definition(
.and_then(|fd| hover_for_builtin(fd, it)) .and_then(|fd| hover_for_builtin(fd, it))
.or_else(|| Some(Markup::fenced_block(&it.name()))), .or_else(|| Some(Markup::fenced_block(&it.name()))),
}, },
Definition::Local(it) => Some(Markup::fenced_block(&it.ty(db).display(db))), Definition::Local(it) => hover_for_local(it, db),
Definition::SelfType(impl_def) => { Definition::SelfType(impl_def) => {
impl_def.target_ty(db).as_adt().and_then(|adt| match adt { impl_def.target_ty(db).as_adt().and_then(|adt| match adt {
Adt::Struct(it) => from_def_source(db, it, mod_path), Adt::Struct(it) => from_def_source(db, it, mod_path),
@ -405,6 +406,29 @@ fn hover_for_definition(
} }
} }
fn hover_for_local(it: hir::Local, db: &RootDatabase) -> Option<Markup> {
let ty = it.ty(db);
let ty = ty.display(db);
let is_mut = if it.is_mut(db) { "mut " } else { "" };
let desc = match it.source(db).value {
Either::Left(ident) => {
let name = it.name(db).unwrap();
let let_kw = if ident
.syntax()
.parent()
.map_or(false, |p| p.kind() == LET_STMT || p.kind() == CONDITION)
{
"let "
} else {
""
};
format!("{}{}{}: {}", let_kw, is_mut, name, ty)
}
Either::Right(_) => format!("{}self: {}", is_mut, ty),
};
hover_markup(None, Some(desc), None)
}
fn hover_for_keyword( fn hover_for_keyword(
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
links_in_hover: bool, links_in_hover: bool,
@ -574,7 +598,7 @@ fn main() {
*iter* *iter*
```rust ```rust
Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>> let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>>
``` ```
"#]], "#]],
); );
@ -798,7 +822,7 @@ fn main() {
``` ```
```rust ```rust
const foo: u32 = 123 const foo: u32
``` ```
"#]], "#]],
); );
@ -831,7 +855,7 @@ fn main() {
*zz* *zz*
```rust ```rust
Test<i32, u8> let zz: Test<i32, u8>
``` ```
"#]], "#]],
); );
@ -870,7 +894,7 @@ fn main() { let b$0ar = Some(12); }
*bar* *bar*
```rust ```rust
Option<i32> let bar: Option<i32>
``` ```
"#]], "#]],
); );
@ -938,7 +962,7 @@ fn main() {
*foo* *foo*
```rust ```rust
i32 foo: i32
``` ```
"#]], "#]],
) )
@ -952,7 +976,7 @@ fn main() {
*foo* *foo*
```rust ```rust
i32 foo: i32
``` ```
"#]], "#]],
) )
@ -966,7 +990,7 @@ fn main() {
*foo* *foo*
```rust ```rust
i32 foo: i32
``` ```
"#]], "#]],
) )
@ -980,7 +1004,7 @@ fn main() {
*foo* *foo*
```rust ```rust
i32 foo: i32
``` ```
"#]], "#]],
) )
@ -1000,7 +1024,7 @@ fn main() {
*_x* *_x*
```rust ```rust
impl Deref<Target = u8> + DerefMut<Target = u8> _x: impl Deref<Target = u8> + DerefMut<Target = u8>
``` ```
"#]], "#]],
) )
@ -1022,7 +1046,7 @@ fn main() { let foo_$0test = Thing::new(); }
*foo_test* *foo_test*
```rust ```rust
Thing let foo_test: Thing
``` ```
"#]], "#]],
) )
@ -1081,7 +1105,7 @@ fn main() {
``` ```
```rust ```rust
const C: u32 = 1 const C: u32
``` ```
"#]], "#]],
) )
@ -1182,7 +1206,7 @@ fn y() {
*x* *x*
```rust ```rust
i32 let x: i32
``` ```
"#]], "#]],
) )
@ -1259,7 +1283,7 @@ fn foo(bar:u32) { let a = id!(ba$0r); }
*bar* *bar*
```rust ```rust
u32 bar: u32
``` ```
"#]], "#]],
); );
@ -1277,7 +1301,7 @@ fn foo(bar:u32) { let a = id!(ba$0r); }
*bar* *bar*
```rust ```rust
u32 bar: u32
``` ```
"#]], "#]],
); );
@ -3302,7 +3326,7 @@ fn main() {
*f* *f*
```rust ```rust
&i32 f: &i32
``` ```
"#]], "#]],
); );
@ -3321,7 +3345,7 @@ impl Foo {
*self* *self*
```rust ```rust
&Foo self: &Foo
``` ```
"#]], "#]],
); );
@ -3341,7 +3365,7 @@ impl Foo {
*self* *self*
```rust ```rust
Arc<Foo> self: Arc<Foo>
``` ```
"#]], "#]],
); );
@ -3537,7 +3561,7 @@ fn foo() {
``` ```
```rust ```rust
const FOO: usize = 3 const FOO: usize
``` ```
--- ---

View file

@ -330,10 +330,11 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
HlTag::Symbol(SymbolKind::Local) HlTag::Symbol(SymbolKind::Local)
}; };
let mut h = Highlight::new(tag); let mut h = Highlight::new(tag);
if local.is_mut(db) || local.ty(db).is_mutable_reference() { let ty = local.ty(db);
if local.is_mut(db) || ty.is_mutable_reference() {
h |= HlMod::Mutable; h |= HlMod::Mutable;
} }
if local.ty(db).as_callable(db).is_some() || local.ty(db).impls_fnonce(db) { if ty.as_callable(db).is_some() || ty.impls_fnonce(db) {
h |= HlMod::Callable; h |= HlMod::Callable;
} }
return h; return h;