8201: Fix recursive macro statements expansion r=edwin0cheng a=edwin0cheng

This PR attempts to properly handle macro statement expansion by implementing the following:

1.  Merge macro expanded statements to parent scope statements.
2.  Add a new hir `Expr::MacroStmts` for handle tail expression infer.

PS : The scope of macro expanded statements are so strange that it took more time than I thought to understand and implement it :(

Fixes  #8171



Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
bors[bot] 2021-03-27 02:57:02 +00:00 committed by GitHub
commit c8066ebd17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 70 deletions

View file

@ -767,6 +767,7 @@ impl<'a> InferenceContext<'a> {
None => self.table.new_float_var(),
},
},
Expr::MacroStmts { tail } => self.infer_expr(*tail, expected),
};
// use a new type variable if we got unknown here
let ty = self.insert_type_vars_shallow(ty);

View file

@ -226,11 +226,48 @@ fn expr_macro_expanded_in_stmts() {
"#,
expect![[r#"
!0..8 'leta=();': ()
!0..8 'leta=();': ()
!3..4 'a': ()
!5..7 '()': ()
57..84 '{ ...); } }': ()
"#]],
);
}
#[test]
fn recurisve_macro_expanded_in_stmts() {
check_infer(
r#"
macro_rules! ng {
([$($tts:tt)*]) => {
$($tts)*;
};
([$($tts:tt)*] $head:tt $($rest:tt)*) => {
ng! {
[$($tts)* $head] $($rest)*
}
};
}
fn foo() {
ng!([] let a = 3);
let b = a;
}
"#,
expect![[r#"
!0..7 'leta=3;': {unknown}
!0..7 'leta=3;': {unknown}
!0..13 'ng!{[leta=3]}': {unknown}
!0..13 'ng!{[leta=]3}': {unknown}
!0..13 'ng!{[leta]=3}': {unknown}
!3..4 'a': i32
!5..6 '3': i32
196..237 '{ ...= a; }': ()
229..230 'b': i32
233..234 'a': i32
"#]],
);
}
#[test]
fn recursive_inner_item_macro_rules() {
check_infer(
@ -246,7 +283,8 @@ fn recursive_inner_item_macro_rules() {
"#,
expect![[r#"
!0..1 '1': i32
!0..7 'mac!($)': {unknown}
!0..26 'macro_...>{1};}': {unknown}
!0..26 'macro_...>{1};}': {unknown}
107..143 '{ ...!(); }': ()
129..130 'a': i32
"#]],