diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-01-02 17:42:45 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-01-02 17:42:45 +0000 |
commit | a88d4f8c7216105e8bffed55fe85d9de796dc172 (patch) | |
tree | da8fe6fd5f771181ee1753907af22d9c0ce60586 /crates/mbe/src/mbe_expander/transcriber.rs | |
parent | 510abef5da1427c542e7b37dcea805c7b022984c (diff) | |
parent | 3545289603dae852fb2b99181e9be5e3117b0a2e (diff) |
Merge #7133
7133: Proper handling $crate and local_inner_macros r=jonas-schievink a=edwin0cheng
This PR introduces `HygineFrames` to store the macro definition/call site hierarchy in hyginee and when resolving `local_inner_macros` and `$crate`, we use the token to look up the corresponding frame and return the correct value.
See also: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#hygiene-and-hierarchies
fixe #6890 and #6788
r? @jonas-schievink
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/mbe/src/mbe_expander/transcriber.rs')
-rw-r--r-- | crates/mbe/src/mbe_expander/transcriber.rs | 20 |
1 files changed, 6 insertions, 14 deletions
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 | ||
121 | fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> { | 121 | fn 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(); |