diff options
Diffstat (limited to 'crates/mbe')
-rw-r--r-- | crates/mbe/src/mbe_expander/transcriber.rs | 9 | ||||
-rw-r--r-- | crates/mbe/src/parser.rs | 4 | ||||
-rw-r--r-- | crates/mbe/src/tests.rs | 13 |
3 files changed, 21 insertions, 5 deletions
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs index 57f3f104d..27b2ac777 100644 --- a/crates/mbe/src/mbe_expander/transcriber.rs +++ b/crates/mbe/src/mbe_expander/transcriber.rs | |||
@@ -119,11 +119,10 @@ fn expand_subtree( | |||
119 | } | 119 | } |
120 | 120 | ||
121 | fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> { | 121 | fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> { |
122 | if v == "crate" { | 122 | // We already handle $crate case in mbe parser |
123 | // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. | 123 | debug_assert!(v != "crate"); |
124 | let tt = tt::Leaf::from(tt::Ident { text: "$crate".into(), id }).into(); | 124 | |
125 | ExpandResult::ok(Fragment::Tokens(tt)) | 125 | if !ctx.bindings.contains(v) { |
126 | } else if !ctx.bindings.contains(v) { | ||
127 | // Note that it is possible to have a `$var` inside a macro which is not bound. | 126 | // Note that it is possible to have a `$var` inside a macro which is not bound. |
128 | // For example: | 127 | // For example: |
129 | // ``` | 128 | // ``` |
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 77cc739b6..f3047972d 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs | |||
@@ -109,6 +109,10 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
109 | let id = punct.id; | 109 | let id = punct.id; |
110 | Op::Var { name, kind, id } | 110 | Op::Var { name, kind, id } |
111 | } | 111 | } |
112 | tt::Leaf::Ident(ident) if ident.text == "crate" => { | ||
113 | // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. | ||
114 | Op::Leaf(tt::Leaf::from(tt::Ident { text: "$crate".into(), id: ident.id })) | ||
115 | } | ||
112 | tt::Leaf::Ident(ident) => { | 116 | tt::Leaf::Ident(ident) => { |
113 | let name = ident.text.clone(); | 117 | let name = ident.text.clone(); |
114 | let kind = eat_fragment_kind(src, mode)?; | 118 | let kind = eat_fragment_kind(src, mode)?; |
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs index 1d9afb4fb..d854985c5 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs | |||
@@ -1080,6 +1080,19 @@ fn test_vertical_bar_with_pat() { | |||
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | #[test] | 1082 | #[test] |
1083 | fn test_dollar_crate_lhs_is_not_meta() { | ||
1084 | parse_macro( | ||
1085 | r#" | ||
1086 | macro_rules! foo { | ||
1087 | ($crate) => {}; | ||
1088 | () => {0}; | ||
1089 | } | ||
1090 | "#, | ||
1091 | ) | ||
1092 | .assert_expand_items(r#"foo!{}"#, r#"0"#); | ||
1093 | } | ||
1094 | |||
1095 | #[test] | ||
1083 | fn test_lifetime() { | 1096 | fn test_lifetime() { |
1084 | parse_macro( | 1097 | parse_macro( |
1085 | r#" | 1098 | r#" |