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 <edwin0cheng@gmail.com>
This commit is contained in:
bors[bot] 2020-03-04 00:05:10 +00:00 committed by GitHub
commit 437329d3f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 2 deletions

View file

@ -37,9 +37,25 @@ pub fn expand_eager_macro(
) -> Option<EagerMacroId> { ) -> Option<EagerMacroId> {
let args = macro_call.value.token_tree()?; let args = macro_call.value.token_tree()?;
let parsed_args = mbe::ast_to_token_tree(&args)?.0; let parsed_args = mbe::ast_to_token_tree(&args)?.0;
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, FragmentKind::Expr).ok()?.0;
let result = eager_macro_recur(db, macro_call.with_value(parsed_args.syntax_node()), resolver)?;
// Note:
// When `lazy_expand` is called, its *parent* file must be already exists.
// Here we store an eager macro id for the argument expanded subtree here
// for that purpose.
let arg_id: MacroCallId = db
.intern_eager_expansion({
EagerCallLoc {
def,
fragment: FragmentKind::Expr,
subtree: Arc::new(parsed_args.clone()),
file_id: macro_call.file_id,
}
})
.into();
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, FragmentKind::Expr).ok()?.0;
let result =
eager_macro_recur(db, InFile::new(arg_id.as_file(), parsed_args.syntax_node()), resolver)?;
let subtree = to_subtree(&result)?; let subtree = to_subtree(&result)?;
if let MacroDefKind::BuiltInEager(eager) = def.kind { if let MacroDefKind::BuiltInEager(eager) = def.kind {

View file

@ -438,6 +438,27 @@ fn main() {
); );
} }
#[test]
fn infer_builtin_macros_concat_with_lazy() {
assert_snapshot!(
infer(r#"
macro_rules! hello {() => {"hello"}}
#[rustc_builtin_macro]
macro_rules! concat {() => {}}
fn main() {
let x = concat!(hello!(), concat!("world", "!"));
}
"#),
@r###"
![0; 13) '"helloworld!"': &str
[104; 161) '{ ...")); }': ()
[114; 115) 'x': &str
"###
);
}
#[test] #[test]
fn infer_derive_clone_simple() { fn infer_derive_clone_simple() {
let (db, pos) = TestDB::with_position( let (db, pos) = TestDB::with_position(