7205: Fix bug for $crate in LHS of mbe r=edwin0cheng a=edwin0cheng

We treated `$crate` as meta variable in LHS of mbe, which should be an `ident`. 

Fixes #7204

Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
bors[bot] 2021-01-08 06:03:54 +00:00 committed by GitHub
commit be02ac981d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 5 deletions

View file

@ -119,11 +119,10 @@ fn expand_subtree(
}
fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> {
if v == "crate" {
// We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path.
let tt = tt::Leaf::from(tt::Ident { text: "$crate".into(), id }).into();
ExpandResult::ok(Fragment::Tokens(tt))
} else if !ctx.bindings.contains(v) {
// We already handle $crate case in mbe parser
debug_assert!(v != "crate");
if !ctx.bindings.contains(v) {
// Note that it is possible to have a `$var` inside a macro which is not bound.
// For example:
// ```

View file

@ -109,6 +109,10 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
let id = punct.id;
Op::Var { name, kind, id }
}
tt::Leaf::Ident(ident) if ident.text == "crate" => {
// We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path.
Op::Leaf(tt::Leaf::from(tt::Ident { text: "$crate".into(), id: ident.id }))
}
tt::Leaf::Ident(ident) => {
let name = ident.text.clone();
let kind = eat_fragment_kind(src, mode)?;

View file

@ -1079,6 +1079,19 @@ fn test_vertical_bar_with_pat() {
.assert_expand_items(r#"foo! { | x | }"#, r#"0"#);
}
#[test]
fn test_dollar_crate_lhs_is_not_meta() {
parse_macro(
r#"
macro_rules! foo {
($crate) => {};
() => {0};
}
"#,
)
.assert_expand_items(r#"foo!{}"#, r#"0"#);
}
#[test]
fn test_lifetime() {
parse_macro(