2406: Add hygiene information to SourceAnalyzer r=matklad a=edwin0cheng

This should fix https://github.com/rust-analyzer/rust-analyzer/pull/2392#issuecomment-557964686

Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
bors[bot] 2019-11-26 13:18:03 +00:00 committed by GitHub
commit 4822d26540
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 13 deletions

View file

@ -18,12 +18,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
// Find the calling expression and it's NameRef
let calling_node = FnCallNode::with_node(&syntax, position.offset)?;
let name_ref = calling_node.name_ref()?;
let name_ref = hir::Source::new(position.file_id.into(), name_ref.syntax());
let analyzer = hir::SourceAnalyzer::new(
db,
hir::Source::new(position.file_id.into(), name_ref.syntax()),
None,
);
let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
let (mut call_info, has_self) = match &calling_node {
FnCallNode::CallExpr(expr) => {
//FIXME: Type::as_callable is broken
@ -44,7 +41,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
(CallInfo::with_fn(db, function), function.has_self_param(db))
}
FnCallNode::MacroCallExpr(expr) => {
let macro_def = analyzer.resolve_macro_call(db, &expr)?;
let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?;
(CallInfo::with_macro(db, macro_def)?, false)
}
};

View file

@ -269,4 +269,27 @@ fn some_thing() -> u32 {
assert_eq!(res.name, "foo");
assert_snapshot!(res.expansion, @r###"bar!()"###);
}
#[test]
fn macro_expand_with_dollar_crate() {
let res = check_expand_macro(
r#"
//- /lib.rs
#[macro_export]
macro_rules! bar {
() => {0};
}
macro_rules! foo {
() => {$crate::bar!()};
}
fn main() {
let res = fo<|>o!();
}
"#,
);
assert_eq!(res.name, "foo");
assert_snapshot!(res.expansion, @r###"0"###);
}
}

View file

@ -152,7 +152,7 @@ pub(crate) fn classify_name_ref(
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
tested_by!(goto_definition_works_for_macros);
if let Some(macro_def) = analyzer.resolve_macro_call(db, &macro_call) {
if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(&macro_call)) {
let kind = NameKind::Macro(macro_def);
return Some(NameDefinition { kind, container, visibility });
}