mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
Explicitly check for reference locals or fields in Name classification
This commit is contained in:
parent
87621de2b9
commit
c65bb7f8b9
11 changed files with 67 additions and 50 deletions
|
@ -112,8 +112,8 @@ pub(crate) fn external_docs(
|
|||
let node = token.parent()?;
|
||||
let definition = match_ast! {
|
||||
match node {
|
||||
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced())?,
|
||||
ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined())?,
|
||||
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced_field())?,
|
||||
ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.defined_or_referenced_field())?,
|
||||
_ => return None,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -25,10 +25,10 @@ pub(crate) fn goto_declaration(
|
|||
match parent {
|
||||
ast::NameRef(name_ref) => {
|
||||
let name_kind = NameRefClass::classify(&sema, &name_ref)?;
|
||||
name_kind.referenced()
|
||||
name_kind.referenced_local()
|
||||
},
|
||||
ast::Name(name) => {
|
||||
NameClass::classify(&sema, &name)?.referenced_or_defined()
|
||||
NameClass::classify(&sema, &name)?.defined_or_referenced_local()
|
||||
},
|
||||
_ => return None,
|
||||
}
|
||||
|
|
|
@ -60,12 +60,11 @@ pub(crate) fn goto_definition(
|
|||
reference_definition(&sema, Either::Right(&name_ref))
|
||||
},
|
||||
ast::Name(name) => {
|
||||
let def = NameClass::classify(&sema, &name)?.referenced_or_defined();
|
||||
try_find_trait_item_definition(sema.db, &def)
|
||||
.or_else(|| def.try_to_nav(sema.db))
|
||||
let def = NameClass::classify(&sema, &name)?.defined_or_referenced_local();
|
||||
try_find_trait_item_definition(sema.db, &def).or_else(|| def.try_to_nav(sema.db))
|
||||
},
|
||||
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) {
|
||||
let def = name_class.referenced_or_defined();
|
||||
let def = name_class.defined_or_referenced_local();
|
||||
def.try_to_nav(sema.db)
|
||||
} else {
|
||||
reference_definition(&sema, Either::Left(<))
|
||||
|
@ -140,7 +139,7 @@ pub(crate) fn reference_definition(
|
|||
|lifetime| NameRefClass::classify_lifetime(sema, lifetime),
|
||||
|name_ref| NameRefClass::classify(sema, name_ref),
|
||||
)?;
|
||||
let def = name_kind.referenced();
|
||||
let def = name_kind.referenced_local();
|
||||
def.try_to_nav(sema.db)
|
||||
}
|
||||
|
||||
|
@ -878,10 +877,11 @@ fn main() {
|
|||
r#"
|
||||
enum Foo {
|
||||
Bar { x: i32 }
|
||||
} //^
|
||||
}
|
||||
fn baz(foo: Foo) {
|
||||
match foo {
|
||||
Foo::Bar { x$0 } => x
|
||||
//^
|
||||
};
|
||||
}
|
||||
"#,
|
||||
|
|
|
@ -29,10 +29,10 @@ pub(crate) fn goto_implementation(
|
|||
let node = sema.find_node_at_offset_with_descend(&syntax, position.offset)?;
|
||||
let def = match &node {
|
||||
ast::NameLike::Name(name) => {
|
||||
NameClass::classify(&sema, name).map(|class| class.referenced_or_defined())
|
||||
NameClass::classify(&sema, name).map(|class| class.defined_or_referenced_local())
|
||||
}
|
||||
ast::NameLike::NameRef(name_ref) => {
|
||||
NameRefClass::classify(&sema, name_ref).map(|class| class.referenced())
|
||||
NameRefClass::classify(&sema, name_ref).map(|class| class.referenced_local())
|
||||
}
|
||||
ast::NameLike::Lifetime(_) => None,
|
||||
}?;
|
||||
|
|
|
@ -96,18 +96,14 @@ pub(crate) fn hover(
|
|||
match node {
|
||||
// we don't use NameClass::referenced_or_defined here as we do not want to resolve
|
||||
// field pattern shorthands to their definition
|
||||
ast::Name(name) => NameClass::classify(&sema, &name).and_then(|class| match class {
|
||||
NameClass::ConstReference(def) => Some(def),
|
||||
def => def.defined(),
|
||||
}),
|
||||
ast::Name(name) => NameClass::classify(&sema, &name).map(|class| class.defined_or_referenced_local()),
|
||||
ast::NameRef(name_ref) => {
|
||||
NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced())
|
||||
NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced_field())
|
||||
},
|
||||
ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime).map_or_else(
|
||||
|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced()),
|
||||
|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced_local()),
|
||||
|d| d.defined(),
|
||||
),
|
||||
|
||||
_ => {
|
||||
if ast::Comment::cast(token.clone()).is_some() {
|
||||
cov_mark::hit!(no_highlight_on_comment_hover);
|
||||
|
|
|
@ -58,7 +58,7 @@ pub(crate) fn find_all_refs(
|
|||
|
||||
let (def, is_literal_search) =
|
||||
if let Some(name) = get_name_of_item_declaration(&syntax, position) {
|
||||
(NameClass::classify(sema, &name)?.referenced_or_defined(), true)
|
||||
(NameClass::classify(sema, &name)?.defined_or_referenced_field(), true)
|
||||
} else {
|
||||
(find_def(sema, &syntax, position.offset)?, false)
|
||||
};
|
||||
|
@ -116,13 +116,17 @@ pub(crate) fn find_def(
|
|||
offset: TextSize,
|
||||
) -> Option<Definition> {
|
||||
let def = match sema.find_node_at_offset_with_descend(syntax, offset)? {
|
||||
ast::NameLike::NameRef(name_ref) => NameRefClass::classify(sema, &name_ref)?.referenced(),
|
||||
ast::NameLike::Name(name) => NameClass::classify(sema, &name)?.referenced_or_defined(),
|
||||
ast::NameLike::NameRef(name_ref) => {
|
||||
NameRefClass::classify(sema, &name_ref)?.referenced_local()
|
||||
}
|
||||
ast::NameLike::Name(name) => {
|
||||
NameClass::classify(sema, &name)?.defined_or_referenced_local()
|
||||
}
|
||||
ast::NameLike::Lifetime(lifetime) => NameRefClass::classify_lifetime(sema, &lifetime)
|
||||
.map(|class| class.referenced())
|
||||
.map(|class| class.referenced_local())
|
||||
.or_else(|| {
|
||||
NameClass::classify_lifetime(sema, &lifetime)
|
||||
.map(|class| class.referenced_or_defined())
|
||||
.map(|class| class.defined_or_referenced_local())
|
||||
})?,
|
||||
};
|
||||
Some(def)
|
||||
|
|
|
@ -108,11 +108,11 @@ fn find_definition(
|
|||
bail!("Renaming aliases is currently unsupported")
|
||||
}
|
||||
ast::NameLike::Name(name) => {
|
||||
NameClass::classify(sema, &name).map(|class| class.referenced_or_defined())
|
||||
NameClass::classify(sema, &name).map(|class| class.defined_or_referenced_local())
|
||||
}
|
||||
ast::NameLike::NameRef(name_ref) => {
|
||||
if let Some(def) =
|
||||
NameRefClass::classify(sema, &name_ref).map(|class| class.referenced())
|
||||
NameRefClass::classify(sema, &name_ref).map(|class| class.referenced_local())
|
||||
{
|
||||
// if the name differs from the definitions name it has to be an alias
|
||||
if def.name(sema.db).map_or(false, |it| it.to_string() != name_ref.text()) {
|
||||
|
@ -124,9 +124,10 @@ fn find_definition(
|
|||
}
|
||||
}
|
||||
ast::NameLike::Lifetime(lifetime) => NameRefClass::classify_lifetime(sema, &lifetime)
|
||||
.map(|class| class.referenced())
|
||||
.map(|class| class.referenced_local())
|
||||
.or_else(|| {
|
||||
NameClass::classify_lifetime(sema, &lifetime).map(|it| it.referenced_or_defined())
|
||||
NameClass::classify_lifetime(sema, &lifetime)
|
||||
.map(|it| it.defined_or_referenced_field())
|
||||
}),
|
||||
}
|
||||
.ok_or_else(|| format_err!("No references found at position"))?;
|
||||
|
|
|
@ -58,10 +58,8 @@ pub(super) fn element(
|
|||
Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def),
|
||||
Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
|
||||
let mut h = HlTag::Symbol(SymbolKind::Field).into();
|
||||
if let Definition::Field(field) = field_ref {
|
||||
if let hir::VariantDef::Union(_) = field.parent_def(db) {
|
||||
h |= HlMod::Unsafe;
|
||||
}
|
||||
if let hir::VariantDef::Union(_) = field_ref.parent_def(db) {
|
||||
h |= HlMod::Unsafe;
|
||||
}
|
||||
h
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue