aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-04 00:05:10 +0000
committerGitHub <[email protected]>2020-03-04 00:05:10 +0000
commit437329d3f5b7bb5b703b93c75a97d349eb77d6c7 (patch)
treea8f700a32ff4bb980c0eab738c04c00ba07ab69c
parentce69561be32421868e0f1ddb537f6f0a596d5610 (diff)
parent5ea83fee010a26e86e962cfb8270fd2a565277b3 (diff)
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]>
-rw-r--r--crates/ra_hir_expand/src/eager.rs20
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs21
2 files changed, 39 insertions, 2 deletions
diff --git a/crates/ra_hir_expand/src/eager.rs b/crates/ra_hir_expand/src/eager.rs
index 7fcdfab5a..f95f37ede 100644
--- a/crates/ra_hir_expand/src/eager.rs
+++ b/crates/ra_hir_expand/src/eager.rs
@@ -37,9 +37,25 @@ pub fn expand_eager_macro(
37) -> Option<EagerMacroId> { 37) -> Option<EagerMacroId> {
38 let args = macro_call.value.token_tree()?; 38 let args = macro_call.value.token_tree()?;
39 let parsed_args = mbe::ast_to_token_tree(&args)?.0; 39 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)?;
42 40
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)?;
43 let subtree = to_subtree(&result)?; 59 let subtree = to_subtree(&result)?;
44 60
45 if let MacroDefKind::BuiltInEager(eager) = def.kind { 61 if let MacroDefKind::BuiltInEager(eager) = def.kind {
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index 55386c030..5d0efa0f4 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -439,6 +439,27 @@ fn main() {
439} 439}
440 440
441#[test] 441#[test]
442fn infer_builtin_macros_concat_with_lazy() {
443 assert_snapshot!(
444 infer(r#"
445macro_rules! hello {() => {"hello"}}
446
447#[rustc_builtin_macro]
448macro_rules! concat {() => {}}
449
450fn 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
462#[test]
442fn infer_derive_clone_simple() { 463fn infer_derive_clone_simple() {
443 let (db, pos) = TestDB::with_position( 464 let (db, pos) = TestDB::with_position(
444 r#" 465 r#"