Skip to content

Commit 437329d

Browse files
Merge #3429
3429: Fix panic on eager expansion r=matklad a=edwin0cheng When lazy expanding inside an eager macro, its *parent* file of that lazy macro call must be already exists such that a panic is occurred because that parent file is the eager macro we are processing. This PR fix this bug by store the argument syntax node as another eager macro id for that purpose. Personally I don't know if it is a good answer for this bug. Co-authored-by: Edwin Cheng <[email protected]>
2 parents ce69561 + 5ea83fe commit 437329d

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

crates/ra_hir_expand/src/eager.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,25 @@ pub fn expand_eager_macro(
3737
) -> Option<EagerMacroId> {
3838
let args = macro_call.value.token_tree()?;
3939
let parsed_args = mbe::ast_to_token_tree(&args)?.0;
40-
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, FragmentKind::Expr).ok()?.0;
41-
let result = eager_macro_recur(db, macro_call.with_value(parsed_args.syntax_node()), resolver)?;
4240

41+
// Note:
42+
// When `lazy_expand` is called, its *parent* file must be already exists.
43+
// Here we store an eager macro id for the argument expanded subtree here
44+
// for that purpose.
45+
let arg_id: MacroCallId = db
46+
.intern_eager_expansion({
47+
EagerCallLoc {
48+
def,
49+
fragment: FragmentKind::Expr,
50+
subtree: Arc::new(parsed_args.clone()),
51+
file_id: macro_call.file_id,
52+
}
53+
})
54+
.into();
55+
56+
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, FragmentKind::Expr).ok()?.0;
57+
let result =
58+
eager_macro_recur(db, InFile::new(arg_id.as_file(), parsed_args.syntax_node()), resolver)?;
4359
let subtree = to_subtree(&result)?;
4460

4561
if let MacroDefKind::BuiltInEager(eager) = def.kind {

crates/ra_hir_ty/src/tests/macros.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,27 @@ fn main() {
438438
);
439439
}
440440

441+
#[test]
442+
fn infer_builtin_macros_concat_with_lazy() {
443+
assert_snapshot!(
444+
infer(r#"
445+
macro_rules! hello {() => {"hello"}}
446+
447+
#[rustc_builtin_macro]
448+
macro_rules! concat {() => {}}
449+
450+
fn main() {
451+
let x = concat!(hello!(), concat!("world", "!"));
452+
}
453+
"#),
454+
@r###"
455+
![0; 13) '"helloworld!"': &str
456+
[104; 161) '{ ...")); }': ()
457+
[114; 115) 'x': &str
458+
"###
459+
);
460+
}
461+
441462
#[test]
442463
fn infer_derive_clone_simple() {
443464
let (db, pos) = TestDB::with_position(

0 commit comments

Comments
 (0)