diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2018-04-18 19:36:48 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2018-04-18 19:36:48 -0700 |
| commit | e9348738fca8c88dca6e343702eaa12ffc8df34c (patch) | |
| tree | e778a2aabb658e2ef5754798bf0f4d4f63560422 /src/libsyntax/tokenstream.rs | |
| parent | ac3c2288f9f9d977acb46406ba60033d65165a7b (diff) | |
| download | rust-e9348738fca8c88dca6e343702eaa12ffc8df34c.tar.gz rust-e9348738fca8c88dca6e343702eaa12ffc8df34c.zip | |
proc_macro: Stay on the "use the cache" path more
Discovered in #50061 we're falling off the "happy path" of using a stringified token stream more often than we should. This was due to the fact that a user-written token like `0xf` is equality-different from the stringified token of `15` (despite being semantically equivalent). This patch updates the call to `eq_unspanned` with an even more awful solution, `probably_equal_for_proc_macro`, which ignores the value of each token and basically only compares the structure of the token stream, assuming that the AST doesn't change just one token at a time. While this is a step towards fixing #50061 there is still one regression from #49154 which needs to be fixed.
Diffstat (limited to 'src/libsyntax/tokenstream.rs')
| -rw-r--r-- | src/libsyntax/tokenstream.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 6ac04b3cdf6..e2b5c4e1adf 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -124,6 +124,24 @@ impl TokenTree { } } + // See comments in `interpolated_to_tokenstream` for why we care about + // *probably* equal here rather than actual equality + // + // This is otherwise the same as `eq_unspanned`, only recursing with a + // different method. + pub fn probably_equal_for_proc_macro(&self, other: &TokenTree) -> bool { + match (self, other) { + (&TokenTree::Token(_, ref tk), &TokenTree::Token(_, ref tk2)) => { + tk.probably_equal_for_proc_macro(tk2) + } + (&TokenTree::Delimited(_, ref dl), &TokenTree::Delimited(_, ref dl2)) => { + dl.delim == dl2.delim && + dl.stream().probably_equal_for_proc_macro(&dl2.stream()) + } + (_, _) => false, + } + } + /// Retrieve the TokenTree's span. pub fn span(&self) -> Span { match *self { @@ -250,6 +268,22 @@ impl TokenStream { t1.next().is_none() && t2.next().is_none() } + // See comments in `interpolated_to_tokenstream` for why we care about + // *probably* equal here rather than actual equality + // + // This is otherwise the same as `eq_unspanned`, only recursing with a + // different method. + pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool { + let mut t1 = self.trees(); + let mut t2 = other.trees(); + for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { + if !t1.probably_equal_for_proc_macro(&t2) { + return false; + } + } + t1.next().is_none() && t2.next().is_none() + } + /// Precondition: `self` consists of a single token tree. /// Returns true if the token tree is a joint operation w.r.t. `proc_macro::TokenNode`. pub fn as_tree(self) -> (TokenTree, bool /* joint? */) { |
