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:
Ville Penttinen 2019-02-27 17:22:53 +02:00
parent 2e2a6dd2fb
commit bb4521be1c
2 changed files with 45 additions and 0 deletions

View file

@ -74,6 +74,30 @@ pub(crate) fn reference_definition(
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
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]
fn goto_definition_works_when_used_on_definition_name_itself() {
check_goto(

View file

@ -2,6 +2,7 @@ test_utils::marks!(
inserts_parens_for_function_calls
goto_definition_works_for_methods
goto_definition_works_for_fields
goto_definition_works_for_named_fields
call_info_bad_offset
dont_complete_current_use
);