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.
This commit is contained in:
parent
ac3c2288f9
commit
e9348738fc
3 changed files with 127 additions and 9 deletions
|
@ -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? */) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue