mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Make goto definition/hover resolve constructors
This commit is contained in:
parent
dc8bcc1e42
commit
49da9a3e81
3 changed files with 87 additions and 7 deletions
|
@ -47,9 +47,10 @@ pub(crate) fn reference_definition(
|
|||
name_ref: &ast::NameRef,
|
||||
) -> ReferenceResult {
|
||||
use self::ReferenceResult::*;
|
||||
if let Some(function) =
|
||||
hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())
|
||||
{
|
||||
|
||||
let function = hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax());
|
||||
|
||||
if let Some(function) = function {
|
||||
// Check if it is a method
|
||||
if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) {
|
||||
tested_by!(goto_definition_works_for_methods);
|
||||
|
@ -122,9 +123,29 @@ pub(crate) fn reference_definition(
|
|||
Some(Resolution::SelfType(_impl_block)) => {
|
||||
// TODO: go to the implemented type
|
||||
}
|
||||
None => {}
|
||||
None => {
|
||||
// If we failed to resolve then check associated items
|
||||
if let Some(function) = function {
|
||||
// Should we do this above and then grab path from the PathExpr?
|
||||
if let Some(path_expr) =
|
||||
name_ref.syntax().ancestors().find_map(ast::PathExpr::cast)
|
||||
{
|
||||
let infer_result = function.infer(db);
|
||||
let syntax_mapping = function.body_syntax_mapping(db);
|
||||
let expr = ast::Expr::cast(path_expr.syntax()).unwrap();
|
||||
|
||||
if let Some(func) = syntax_mapping
|
||||
.node_expr(expr)
|
||||
.and_then(|it| infer_result.assoc_fn_resolutions(it))
|
||||
{
|
||||
return Exact(NavigationTarget::from_function(db, func));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If that fails try the index based approach.
|
||||
let navs = crate::symbol_index::index_resolve(db, name_ref)
|
||||
.into_iter()
|
||||
|
|
|
@ -512,4 +512,26 @@ mod tests {
|
|||
let hover = analysis.hover(position).unwrap().unwrap();
|
||||
assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_infer_associated_method_exact() {
|
||||
let (analysis, position) = single_file_with_position(
|
||||
"
|
||||
struct Thing { x: u32 }
|
||||
|
||||
impl Thing {
|
||||
fn new() -> Thing {
|
||||
Thing { x: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo_test = Thing::new<|>();
|
||||
}
|
||||
",
|
||||
);
|
||||
let hover = analysis.hover(position).unwrap().unwrap();
|
||||
assert_eq!(hover.info.first(), Some("```rust\nfn new() -> Thing\n```"));
|
||||
assert_eq!(hover.info.is_exact(), true);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue