diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-03-04 00:05:10 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-04 00:05:10 +0000 |
commit | 437329d3f5b7bb5b703b93c75a97d349eb77d6c7 (patch) | |
tree | a8f700a32ff4bb980c0eab738c04c00ba07ab69c | |
parent | ce69561be32421868e0f1ddb537f6f0a596d5610 (diff) | |
parent | 5ea83fee010a26e86e962cfb8270fd2a565277b3 (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.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 21 |
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] |
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 | |||
462 | #[test] | ||
442 | fn infer_derive_clone_simple() { | 463 | fn infer_derive_clone_simple() { |
443 | let (db, pos) = TestDB::with_position( | 464 | let (db, pos) = TestDB::with_position( |
444 | r#" | 465 | r#" |