Skip to content

Commit 4822d26

Browse files
Merge #2406
2406: Add hygiene information to SourceAnalyzer r=matklad a=edwin0cheng This should fix #2392 (comment) Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
2 parents 36dca8d + 0623164 commit 4822d26

File tree

5 files changed

+34
-13
lines changed

5 files changed

+34
-13
lines changed

crates/ra_hir/src/source_binder.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use hir_def::{
1414
DefWithBodyId,
1515
};
1616
use hir_expand::{
17-
name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source,
17+
hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind,
18+
Source,
1819
};
1920
use ra_syntax::{
2021
ast::{self, AstNode},
@@ -240,10 +241,10 @@ impl SourceAnalyzer {
240241
pub fn resolve_macro_call(
241242
&self,
242243
db: &impl HirDatabase,
243-
macro_call: &ast::MacroCall,
244+
macro_call: Source<&ast::MacroCall>,
244245
) -> Option<MacroDef> {
245-
// This must be a normal source file rather than macro file.
246-
let path = macro_call.path().and_then(Path::from_ast)?;
246+
let hygiene = Hygiene::new(db, macro_call.file_id);
247+
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?;
247248
self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into())
248249
}
249250

@@ -445,7 +446,7 @@ impl SourceAnalyzer {
445446
db: &impl HirDatabase,
446447
macro_call: Source<&ast::MacroCall>,
447448
) -> Option<Expansion> {
448-
let def = self.resolve_macro_call(db, macro_call.value)?.id;
449+
let def = self.resolve_macro_call(db, macro_call)?.id;
449450
let ast_id = AstId::new(
450451
macro_call.file_id,
451452
db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),

crates/ra_hir_def/src/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl Path {
9797

9898
/// Converts an `ast::Path` to `Path`. Works with use trees.
9999
/// It correctly handles `$crate` based path from macro call.
100-
pub(crate) fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
100+
pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
101101
let mut kind = PathKind::Plain;
102102
let mut segments = Vec::new();
103103
loop {

crates/ra_ide_api/src/call_info.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
1818
// Find the calling expression and it's NameRef
1919
let calling_node = FnCallNode::with_node(&syntax, position.offset)?;
2020
let name_ref = calling_node.name_ref()?;
21+
let name_ref = hir::Source::new(position.file_id.into(), name_ref.syntax());
2122

22-
let analyzer = hir::SourceAnalyzer::new(
23-
db,
24-
hir::Source::new(position.file_id.into(), name_ref.syntax()),
25-
None,
26-
);
23+
let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
2724
let (mut call_info, has_self) = match &calling_node {
2825
FnCallNode::CallExpr(expr) => {
2926
//FIXME: Type::as_callable is broken
@@ -44,7 +41,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
4441
(CallInfo::with_fn(db, function), function.has_self_param(db))
4542
}
4643
FnCallNode::MacroCallExpr(expr) => {
47-
let macro_def = analyzer.resolve_macro_call(db, &expr)?;
44+
let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?;
4845
(CallInfo::with_macro(db, macro_def)?, false)
4946
}
5047
};

crates/ra_ide_api/src/expand_macro.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,27 @@ fn some_thing() -> u32 {
269269
assert_eq!(res.name, "foo");
270270
assert_snapshot!(res.expansion, @r###"bar!()"###);
271271
}
272+
273+
#[test]
274+
fn macro_expand_with_dollar_crate() {
275+
let res = check_expand_macro(
276+
r#"
277+
//- /lib.rs
278+
#[macro_export]
279+
macro_rules! bar {
280+
() => {0};
281+
}
282+
macro_rules! foo {
283+
() => {$crate::bar!()};
284+
}
285+
286+
fn main() {
287+
let res = fo<|>o!();
288+
}
289+
"#,
290+
);
291+
292+
assert_eq!(res.name, "foo");
293+
assert_snapshot!(res.expansion, @r###"0"###);
294+
}
272295
}

crates/ra_ide_api/src/references/classify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub(crate) fn classify_name_ref(
152152

153153
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
154154
tested_by!(goto_definition_works_for_macros);
155-
if let Some(macro_def) = analyzer.resolve_macro_call(db, &macro_call) {
155+
if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(&macro_call)) {
156156
let kind = NameKind::Macro(macro_def);
157157
return Some(NameDefinition { kind, container, visibility });
158158
}

0 commit comments

Comments
 (0)