mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Resolve derive attributes even when shadowed
This commit is contained in:
parent
401daa5f77
commit
aa9d093488
3 changed files with 23 additions and 7 deletions
|
@ -24,7 +24,7 @@ use syntax::{
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
||||||
source_analyzer::{resolve_hir_path, SourceAnalyzer},
|
source_analyzer::{resolve_hir_path, resolve_hir_path_as_macro, SourceAnalyzer},
|
||||||
Access, AssocItem, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
|
Access, AssocItem, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
|
||||||
InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait,
|
InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait,
|
||||||
Type, TypeAlias, TypeParam, VariantDef,
|
Type, TypeAlias, TypeParam, VariantDef,
|
||||||
|
@ -1134,4 +1134,14 @@ impl<'a> SemanticsScope<'a> {
|
||||||
let path = Path::from_src(path.clone(), &ctx)?;
|
let path = Path::from_src(path.clone(), &ctx)?;
|
||||||
resolve_hir_path(self.db, &self.resolver, &path)
|
resolve_hir_path(self.db, &self.resolver, &path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve a path as-if it was written at the given scope. This is
|
||||||
|
/// necessary a heuristic, as it doesn't take hygiene into account.
|
||||||
|
// FIXME: This special casing solely exists for attributes for now
|
||||||
|
// ideally we should have a path resolution infra that properly knows about overlapping namespaces
|
||||||
|
pub fn speculative_resolve_as_mac(&self, path: &ast::Path) -> Option<MacroDef> {
|
||||||
|
let ctx = body::LowerCtx::new(self.db.upcast(), self.file_id);
|
||||||
|
let path = Path::from_src(path.clone(), &ctx)?;
|
||||||
|
resolve_hir_path_as_macro(self.db, &self.resolver, &path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -502,6 +502,15 @@ pub(crate) fn resolve_hir_path(
|
||||||
resolve_hir_path_(db, resolver, path, false)
|
resolve_hir_path_(db, resolver, path, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn resolve_hir_path_as_macro(
|
||||||
|
db: &dyn HirDatabase,
|
||||||
|
resolver: &Resolver,
|
||||||
|
path: &Path,
|
||||||
|
) -> Option<MacroDef> {
|
||||||
|
resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_hir_path_(
|
fn resolve_hir_path_(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
|
|
|
@ -53,12 +53,9 @@ pub fn try_resolve_derive_input_at(
|
||||||
.take_while(|tok| tok.kind() != T!['('] && tok.kind() != T![,])
|
.take_while(|tok| tok.kind() != T!['('] && tok.kind() != T![,])
|
||||||
.collect();
|
.collect();
|
||||||
let path = ast::Path::parse(&tokens.into_iter().rev().join("")).ok()?;
|
let path = ast::Path::parse(&tokens.into_iter().rev().join("")).ok()?;
|
||||||
match sema.scope(tt.syntax()).speculative_resolve(&path) {
|
sema.scope(tt.syntax())
|
||||||
Some(hir::PathResolution::Macro(makro)) if makro.kind() == hir::MacroKind::Derive => {
|
.speculative_resolve_as_mac(&path)
|
||||||
Some(makro)
|
.filter(|mac| mac.kind() == hir::MacroKind::Derive)
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Picks the token with the highest rank returned by the passed in function.
|
/// Picks the token with the highest rank returned by the passed in function.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue