Skip to content

Commit 26419c0

Browse files
committed
Fix proc-macro attributes being shadowed by their functions in IDE layer
1 parent c5c11b8 commit 26419c0

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

crates/hir/src/semantics.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
329329
self.imp.resolve_path(path)
330330
}
331331

332+
pub fn resolve_path_as_macro(&self, path: &ast::Path) -> Option<MacroDef> {
333+
self.imp.resolve_path_as_macro(path)
334+
}
335+
332336
pub fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option<Crate> {
333337
self.imp.resolve_extern_crate(extern_crate)
334338
}
@@ -845,6 +849,12 @@ impl<'db> SemanticsImpl<'db> {
845849
self.analyze(path.syntax()).resolve_path(self.db, path)
846850
}
847851

852+
// FIXME: This shouldn't exist, but is currently required to always resolve attribute paths in
853+
// the IDE layer due to namespace collisions
854+
fn resolve_path_as_macro(&self, path: &ast::Path) -> Option<MacroDef> {
855+
self.analyze(path.syntax()).resolve_path_as_macro(self.db, path)
856+
}
857+
848858
fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option<Crate> {
849859
let krate = self.scope(extern_crate.syntax()).krate()?;
850860
krate.dependencies(self.db).into_iter().find_map(|dep| {

crates/hir/src/source_analyzer.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,18 @@ impl SourceAnalyzer {
246246
}
247247
}
248248

249+
pub(crate) fn resolve_path_as_macro(
250+
&self,
251+
db: &dyn HirDatabase,
252+
path: &ast::Path,
253+
) -> Option<MacroDef> {
254+
// This must be a normal source file rather than macro file.
255+
let hygiene = Hygiene::new(db.upcast(), self.file_id);
256+
let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene);
257+
let hir_path = Path::from_src(path.clone(), &ctx)?;
258+
resolve_hir_path_as_macro(db, &self.resolver, &hir_path)
259+
}
260+
249261
pub(crate) fn resolve_path(
250262
&self,
251263
db: &dyn HirDatabase,

crates/ide/src/syntax_highlighting/test_data/highlighting.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="brace">}</span><span class="semicolon">;</span>
4444
<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span>
4545

46-
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="module attribute">proc_macros</span><span class="operator attribute">::</span><span class="builtin_attr attribute">identity</span><span class="attribute attribute">]</span>
46+
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="module attribute">proc_macros</span><span class="operator attribute">::</span><span class="macro attribute">identity</span><span class="attribute attribute">]</span>
4747
<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration public">ops</span> <span class="brace">{</span>
4848
<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute attribute">]</span>
4949
<span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration public">FnOnce</span><span class="angle">&lt;</span><span class="type_param declaration">Args</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>

crates/ide_db/src/defs.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -433,20 +433,20 @@ impl NameRefClass {
433433
.find_map(ast::Attr::cast)
434434
.map(|attr| attr.path().as_ref() == Some(&top_path));
435435
return match is_attribute_path {
436-
Some(true) => sema.resolve_path(&path).and_then(|resolved| {
437-
match resolved {
438-
// Don't wanna collide with builtin attributes here like `test` hence guard
439-
// so only resolve to modules that aren't the last segment
440-
PathResolution::Def(module @ ModuleDef::Module(_)) if path != top_path => {
441-
cov_mark::hit!(name_ref_classify_attr_path_qualifier);
442-
Some(NameRefClass::Definition(Definition::ModuleDef(module)))
443-
}
444-
PathResolution::Macro(mac) if mac.kind() == hir::MacroKind::Attr => {
445-
Some(NameRefClass::Definition(Definition::Macro(mac)))
446-
}
447-
_ => None,
436+
Some(true) if path == top_path => sema
437+
.resolve_path_as_macro(&path)
438+
.filter(|mac| mac.kind() == hir::MacroKind::Attr)
439+
.map(Definition::Macro)
440+
.map(NameRefClass::Definition),
441+
// in case of the path being a qualifier, don't resolve to anything but a module
442+
Some(true) => match sema.resolve_path(&path)? {
443+
PathResolution::Def(module @ ModuleDef::Module(_)) => {
444+
cov_mark::hit!(name_ref_classify_attr_path_qualifier);
445+
Some(NameRefClass::Definition(Definition::ModuleDef(module)))
448446
}
449-
}),
447+
_ => None,
448+
},
449+
// inside attribute, but our path isn't part of the attribute's path(might be in its expression only)
450450
Some(false) => None,
451451
None => sema.resolve_path(&path).map(Into::into).map(NameRefClass::Definition),
452452
};

0 commit comments

Comments
 (0)