diff options
| author | bors <bors@rust-lang.org> | 2018-04-20 05:34:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-20 05:34:17 +0000 |
| commit | 257d43d0d580dc5e92a4aa4bebbd2bf5f04bbcae (patch) | |
| tree | ee6b6445d219acb464dccabf95db51fb66526f50 /src/libsyntax/tokenstream.rs | |
| parent | f4a3df1f76509b9dd7380db7ce60bd67bc5d5e7e (diff) | |
| parent | e9348738fca8c88dca6e343702eaa12ffc8df34c (diff) | |
| download | rust-257d43d0d580dc5e92a4aa4bebbd2bf5f04bbcae.tar.gz rust-257d43d0d580dc5e92a4aa4bebbd2bf5f04bbcae.zip | |
Auto merge of #50069 - alexcrichton:fix-proc-macro, r=nrc
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? */) { |
