use hir::{
- Adt, AsAssocItem, AssocItemContainer, FieldSource, HasAttrs, HasSource, HirDisplay, Module,
- ModuleDef, ModuleSource, Semantics,
+ Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource,
+ HirDisplay, Module, ModuleDef, ModuleSource, Semantics,
};
use ide_db::base_db::SourceDatabase;
use ide_db::{
doc_links::{remove_links, rewrite_links},
markdown_remove::remove_markdown,
markup::Markup,
- runnables::{runnable, runnable_fn},
+ runnables::{runnable_fn, runnable_mod},
FileId, FilePosition, NavigationTarget, RangeInfo, Runnable,
};
return None;
}
- let node = token.ancestors().find(|n| {
- ast::Expr::can_cast(n.kind())
- || ast::Pat::can_cast(n.kind())
- || ast::SelfParam::can_cast(n.kind())
- })?;
+ let node = token
+ .ancestors()
+ .find(|n| ast::Expr::can_cast(n.kind()) || ast::Pat::can_cast(n.kind()))?;
let ty = match_ast! {
match node {
ast::Expr(it) => sema.type_of_expr(&it)?,
ast::Pat(it) => sema.type_of_pat(&it)?,
- ast::SelfParam(self_param) => sema.type_of_self(&self_param)?,
// If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
// (e.g expanding a builtin macro). So we give up here.
ast::MacroCall(_it) => return None,
Definition::SelfType(it) => it.target_ty(db).as_adt(),
_ => None,
}?;
- match adt {
- Adt::Struct(it) => it.try_to_nav(db),
- Adt::Union(it) => it.try_to_nav(db),
- Adt::Enum(it) => it.try_to_nav(db),
- }
- .map(to_action)
+ adt.try_to_nav(db).map(to_action)
}
fn runnable_action(
Definition::ModuleDef(it) => match it {
ModuleDef::Module(it) => match it.definition_source(sema.db).value {
ModuleSource::Module(it) => {
- runnable(&sema, it.syntax().clone()).map(|it| HoverAction::Runnable(it))
+ runnable_mod(&sema, it).map(|it| HoverAction::Runnable(it))
}
_ => None,
},
}
};
- if let Definition::TypeParam(it) = def {
+ if let Definition::GenericParam(GenericParam::TypeParam(it)) = def {
it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into()));
} else {
let ty = match def {
Definition::Local(it) => it.ty(db),
- Definition::ConstParam(it) => it.ty(db),
+ Definition::GenericParam(GenericParam::ConstParam(it)) => it.ty(db),
_ => return None,
};
})
}
Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))),
- Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))),
- Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))),
- Definition::ConstParam(it) => from_def_source(db, it, None),
+ Definition::GenericParam(it) => match it {
+ GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))),
+ GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))),
+ GenericParam::ConstParam(it) => from_def_source(db, it, None),
+ },
};
fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup>
return tokens.max_by_key(priority);
fn priority(n: &SyntaxToken) -> usize {
match n.kind() {
- IDENT | INT_NUMBER | LIFETIME_IDENT => 3,
+ IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 3,
T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
);
}
+ #[test]
+ fn test_hover_self_has_go_to_type() {
+ check_actions(
+ r#"
+struct Foo;
+impl Foo {
+ fn foo(&self$0) {}
+}
+"#,
+ expect![[r#"
+ [
+ GoToType(
+ [
+ HoverGotoTypeData {
+ mod_path: "test::Foo",
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 0..11,
+ focus_range: 7..10,
+ name: "Foo",
+ kind: Struct,
+ description: "struct Foo",
+ },
+ },
+ ],
+ ),
+ ]
+ "#]],
+ );
+ }
+
#[test]
fn hover_displays_normalized_crate_names() {
check(
}
"#,
expect![[r#"
- *&self*
+ *self*
+
```rust
&Foo
```
}
"#,
expect![[r#"
- *self: Arc<Foo>*
+ *self*
+
```rust
Arc<Foo>
```