diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/parse/token.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax/tokenstream.rs | 8 |
2 files changed, 27 insertions, 12 deletions
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 35a745ccdee..0913ed86147 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -527,8 +527,17 @@ impl Token { // all span information. // // As a result, some AST nodes are annotated with the token - // stream they came from. Attempt to extract these lossless - // token streams before we fall back to the stringification. + // stream they came from. Here we attempt to extract these + // lossless token streams before we fall back to the + // stringification. + // + // During early phases of the compiler, though, the AST could + // get modified directly (e.g. attributes added or removed) and + // the internal cache of tokens my not be invalidated or + // updated. Consequently if the "lossless" token stream + // disagrees with our actuall stringification (which has + // historically been much more battle-tested) then we go with + // the lossy stream anyway (losing span information). let mut tokens = None; match nt.0 { @@ -555,13 +564,17 @@ impl Token { _ => {} } - tokens.unwrap_or_else(|| { - nt.1.force(|| { - // FIXME(jseyfried): Avoid this pretty-print + reparse hack - let source = pprust::token_to_string(self); - parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span)) - }) - }) + let tokens_for_real = nt.1.force(|| { + // FIXME(#43081): Avoid this pretty-print + reparse hack + let source = pprust::token_to_string(self); + parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span)) + }); + if let Some(tokens) = tokens { + if tokens.eq_unspanned(&tokens_for_real) { + return tokens + } + } + return tokens_for_real } } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 3a7a1b9a669..6ac04b3cdf6 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -118,7 +118,7 @@ impl TokenTree { (&TokenTree::Token(_, ref tk), &TokenTree::Token(_, ref tk2)) => tk == tk2, (&TokenTree::Delimited(_, ref dl), &TokenTree::Delimited(_, ref dl2)) => { dl.delim == dl2.delim && - dl.stream().trees().zip(dl2.stream().trees()).all(|(tt, tt2)| tt.eq_unspanned(&tt2)) + dl.stream().eq_unspanned(&dl2.stream()) } (_, _) => false, } @@ -240,12 +240,14 @@ impl TokenStream { /// Compares two TokenStreams, checking equality without regarding span information. pub fn eq_unspanned(&self, other: &TokenStream) -> bool { - for (t1, t2) in self.trees().zip(other.trees()) { + let mut t1 = self.trees(); + let mut t2 = other.trees(); + for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { if !t1.eq_unspanned(&t2) { return false; } } - true + t1.next().is_none() && t2.next().is_none() } /// Precondition: `self` consists of a single token tree. |
