mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Allow goto-definition to work for named fields in struct initializer
Now goto definition should work when done on a named field in a struct initializer.
This commit is contained in:
parent
2e2a6dd2fb
commit
bb4521be1c
2 changed files with 45 additions and 0 deletions
|
@ -74,6 +74,30 @@ pub(crate) fn reference_definition(
|
||||||
return Exact(NavigationTarget::from_field(db, field));
|
return Exact(NavigationTarget::from_field(db, field));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It could also be a named field
|
||||||
|
if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::NamedField::cast) {
|
||||||
|
tested_by!(goto_definition_works_for_named_fields);
|
||||||
|
|
||||||
|
let infer_result = function.infer(db);
|
||||||
|
let syntax_mapping = function.body_syntax_mapping(db);
|
||||||
|
|
||||||
|
let struct_lit = field_expr.syntax().ancestors().find_map(ast::StructLit::cast);
|
||||||
|
|
||||||
|
if let Some(expr) = struct_lit.and_then(|lit| syntax_mapping.node_expr(lit.into())) {
|
||||||
|
let ty = infer_result[expr].clone();
|
||||||
|
if let hir::Ty::Adt { def_id, .. } = ty {
|
||||||
|
if let hir::AdtDef::Struct(s) = def_id {
|
||||||
|
let hir_path = hir::Path::from_name_ref(name_ref);
|
||||||
|
let hir_name = hir_path.as_ident().unwrap();
|
||||||
|
|
||||||
|
if let Some(field) = s.field(db, hir_name) {
|
||||||
|
return Exact(NavigationTarget::from_field(db, field));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Try name resolution
|
// Try name resolution
|
||||||
let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax());
|
let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax());
|
||||||
|
@ -255,6 +279,26 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_definition_works_for_named_fields() {
|
||||||
|
covers!(goto_definition_works_for_named_fields);
|
||||||
|
check_goto(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
struct Foo {
|
||||||
|
spam: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() -> Foo {
|
||||||
|
Foo {
|
||||||
|
spam<|>: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"spam NAMED_FIELD_DEF FileId(1) [17; 26) [17; 21)",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_definition_works_when_used_on_definition_name_itself() {
|
fn goto_definition_works_when_used_on_definition_name_itself() {
|
||||||
check_goto(
|
check_goto(
|
||||||
|
|
|
@ -2,6 +2,7 @@ test_utils::marks!(
|
||||||
inserts_parens_for_function_calls
|
inserts_parens_for_function_calls
|
||||||
goto_definition_works_for_methods
|
goto_definition_works_for_methods
|
||||||
goto_definition_works_for_fields
|
goto_definition_works_for_fields
|
||||||
|
goto_definition_works_for_named_fields
|
||||||
call_info_bad_offset
|
call_info_bad_offset
|
||||||
dont_complete_current_use
|
dont_complete_current_use
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue