Skip to content

Commit d85946b

Browse files
bors[bot]Veykril
andauthored
Merge #10585
10585: fix: Resolve derive attributes even when shadowed r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents 87d5ef8 + aa9d093 commit d85946b

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

crates/hir/src/semantics.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use syntax::{
2424
use crate::{
2525
db::HirDatabase,
2626
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
27-
source_analyzer::{resolve_hir_path, SourceAnalyzer},
27+
source_analyzer::{resolve_hir_path, resolve_hir_path_as_macro, SourceAnalyzer},
2828
Access, AssocItem, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
2929
InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait,
3030
Type, TypeAlias, TypeParam, VariantDef,
@@ -1134,4 +1134,14 @@ impl<'a> SemanticsScope<'a> {
11341134
let path = Path::from_src(path.clone(), &ctx)?;
11351135
resolve_hir_path(self.db, &self.resolver, &path)
11361136
}
1137+
1138+
/// Resolve a path as-if it was written at the given scope. This is
1139+
/// necessary a heuristic, as it doesn't take hygiene into account.
1140+
// FIXME: This special casing solely exists for attributes for now
1141+
// ideally we should have a path resolution infra that properly knows about overlapping namespaces
1142+
pub fn speculative_resolve_as_mac(&self, path: &ast::Path) -> Option<MacroDef> {
1143+
let ctx = body::LowerCtx::new(self.db.upcast(), self.file_id);
1144+
let path = Path::from_src(path.clone(), &ctx)?;
1145+
resolve_hir_path_as_macro(self.db, &self.resolver, &path)
1146+
}
11371147
}

crates/hir/src/source_analyzer.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,15 @@ pub(crate) fn resolve_hir_path(
502502
resolve_hir_path_(db, resolver, path, false)
503503
}
504504

505+
#[inline]
506+
pub(crate) fn resolve_hir_path_as_macro(
507+
db: &dyn HirDatabase,
508+
resolver: &Resolver,
509+
path: &Path,
510+
) -> Option<MacroDef> {
511+
resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(Into::into)
512+
}
513+
505514
fn resolve_hir_path_(
506515
db: &dyn HirDatabase,
507516
resolver: &Resolver,

crates/ide_db/src/helpers.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,9 @@ pub fn try_resolve_derive_input_at(
5353
.take_while(|tok| tok.kind() != T!['('] && tok.kind() != T![,])
5454
.collect();
5555
let path = ast::Path::parse(&tokens.into_iter().rev().join("")).ok()?;
56-
match sema.scope(tt.syntax()).speculative_resolve(&path) {
57-
Some(hir::PathResolution::Macro(makro)) if makro.kind() == hir::MacroKind::Derive => {
58-
Some(makro)
59-
}
60-
_ => None,
61-
}
56+
sema.scope(tt.syntax())
57+
.speculative_resolve_as_mac(&path)
58+
.filter(|mac| mac.kind() == hir::MacroKind::Derive)
6259
}
6360

6461
/// Picks the token with the highest rank returned by the passed in function.

0 commit comments

Comments
 (0)