aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2021-01-04 02:53:31 +0000
committerEdwin Cheng <[email protected]>2021-01-07 05:08:32 +0000
commit76f2b9d2ef797fb995f1bd2706a7e609d014a67a (patch)
treef8f81c7afd64167746a40a576e63fcd234c14b5b /crates/mbe
parentb47c63a4bcefe93be3e5fe97b2a57489f13da493 (diff)
Proper handling $crate Take 2
Diffstat (limited to 'crates/mbe')
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs2
-rw-r--r--crates/mbe/src/mbe_expander/transcriber.rs20
-rw-r--r--crates/mbe/src/parser.rs11
3 files changed, 14 insertions, 19 deletions
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index ab5f87c48..385b46601 100644
--- a/crates/mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
@@ -150,7 +150,7 @@ fn match_subtree(
150 res.add_err(err!("leftover tokens")); 150 res.add_err(err!("leftover tokens"));
151 } 151 }
152 } 152 }
153 Op::Var { name, kind } => { 153 Op::Var { name, kind, .. } => {
154 let kind = match kind { 154 let kind = match kind {
155 Some(k) => k, 155 Some(k) => k,
156 None => { 156 None => {
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs
index 720531237..57f3f104d 100644
--- a/crates/mbe/src/mbe_expander/transcriber.rs
+++ b/crates/mbe/src/mbe_expander/transcriber.rs
@@ -100,8 +100,8 @@ fn expand_subtree(
100 err = err.or(e); 100 err = err.or(e);
101 arena.push(tt.into()); 101 arena.push(tt.into());
102 } 102 }
103 Op::Var { name, .. } => { 103 Op::Var { name, id, .. } => {
104 let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name); 104 let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name, *id);
105 err = err.or(e); 105 err = err.or(e);
106 push_fragment(arena, fragment); 106 push_fragment(arena, fragment);
107 } 107 }
@@ -118,12 +118,10 @@ fn expand_subtree(
118 ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err } 118 ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err }
119} 119}
120 120
121fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> { 121fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> {
122 if v == "crate" { 122 if v == "crate" {
123 // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. 123 // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path.
124 let tt = 124 let tt = tt::Leaf::from(tt::Ident { text: "$crate".into(), id }).into();
125 tt::Leaf::from(tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() })
126 .into();
127 ExpandResult::ok(Fragment::Tokens(tt)) 125 ExpandResult::ok(Fragment::Tokens(tt))
128 } else if !ctx.bindings.contains(v) { 126 } else if !ctx.bindings.contains(v) {
129 // Note that it is possible to have a `$var` inside a macro which is not bound. 127 // Note that it is possible to have a `$var` inside a macro which is not bound.
@@ -142,14 +140,8 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
142 let tt = tt::Subtree { 140 let tt = tt::Subtree {
143 delimiter: None, 141 delimiter: None,
144 token_trees: vec![ 142 token_trees: vec![
145 tt::Leaf::from(tt::Punct { 143 tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone, id }).into(),
146 char: '$', 144 tt::Leaf::from(tt::Ident { text: v.clone(), id }).into(),
147 spacing: tt::Spacing::Alone,
148 id: tt::TokenId::unspecified(),
149 })
150 .into(),
151 tt::Leaf::from(tt::Ident { text: v.clone(), id: tt::TokenId::unspecified() })
152 .into(),
153 ], 145 ],
154 } 146 }
155 .into(); 147 .into();
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 2f3ebc831..77cc739b6 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -8,7 +8,7 @@ use crate::{tt_iter::TtIter, ExpandError, MetaTemplate};
8 8
9#[derive(Clone, Debug, PartialEq, Eq)] 9#[derive(Clone, Debug, PartialEq, Eq)]
10pub(crate) enum Op { 10pub(crate) enum Op {
11 Var { name: SmolStr, kind: Option<SmolStr> }, 11 Var { name: SmolStr, kind: Option<SmolStr>, id: tt::TokenId },
12 Repeat { subtree: MetaTemplate, kind: RepeatKind, separator: Option<Separator> }, 12 Repeat { subtree: MetaTemplate, kind: RepeatKind, separator: Option<Separator> },
13 Leaf(tt::Leaf), 13 Leaf(tt::Leaf),
14 Subtree(MetaTemplate), 14 Subtree(MetaTemplate),
@@ -106,18 +106,21 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
106 } 106 }
107 let name = UNDERSCORE.clone(); 107 let name = UNDERSCORE.clone();
108 let kind = eat_fragment_kind(src, mode)?; 108 let kind = eat_fragment_kind(src, mode)?;
109 Op::Var { name, kind } 109 let id = punct.id;
110 Op::Var { name, kind, id }
110 } 111 }
111 tt::Leaf::Ident(ident) => { 112 tt::Leaf::Ident(ident) => {
112 let name = ident.text.clone(); 113 let name = ident.text.clone();
113 let kind = eat_fragment_kind(src, mode)?; 114 let kind = eat_fragment_kind(src, mode)?;
114 Op::Var { name, kind } 115 let id = ident.id;
116 Op::Var { name, kind, id }
115 } 117 }
116 tt::Leaf::Literal(lit) => { 118 tt::Leaf::Literal(lit) => {
117 if is_boolean_literal(&lit) { 119 if is_boolean_literal(&lit) {
118 let name = lit.text.clone(); 120 let name = lit.text.clone();
119 let kind = eat_fragment_kind(src, mode)?; 121 let kind = eat_fragment_kind(src, mode)?;
120 Op::Var { name, kind } 122 let id = lit.id;
123 Op::Var { name, kind, id }
121 } else { 124 } else {
122 bail!("bad var 2"); 125 bail!("bad var 2");
123 } 126 }