Skip to content

Commit 8209538

Browse files
committed
Add relaxed_delim_match parameter
1 parent ea468f4 commit 8209538

File tree

1 file changed

+53
-16
lines changed
  • compiler/rustc_parse/src

1 file changed

+53
-16
lines changed

compiler/rustc_parse/src/lib.rs

+53-16
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#![feature(or_patterns)]
88

99
use rustc_ast as ast;
10-
use rustc_ast::token::{self, Nonterminal, Token, TokenKind};
11-
use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
10+
use rustc_ast::token::{self, DelimToken, Nonterminal, Token, TokenKind};
11+
use rustc_ast::tokenstream::{self, Spacing, TokenStream, TokenTree};
1212
use rustc_ast_pretty::pprust;
1313
use rustc_data_structures::sync::Lrc;
1414
use rustc_errors::{Diagnostic, FatalError, Level, PResult};
@@ -329,9 +329,8 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
329329
// modifications, including adding/removing typically non-semantic
330330
// tokens such as extra braces and commas, don't happen.
331331
if let Some(tokens) = tokens {
332-
// If the streams match, then the AST hasn't been modified. Return the captured
333-
// `TokenStream`.
334-
if tokenstream_probably_equal_for_proc_macro(&tokens, &reparsed_tokens, sess) {
332+
// Compare with a non-relaxed delim match to start.
333+
if tokenstream_probably_equal_for_proc_macro(&tokens, &reparsed_tokens, sess, false) {
335334
return tokens;
336335
}
337336

@@ -340,23 +339,33 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
340339
// token stream to match up with inserted parenthesis in the reparsed stream.
341340
let source_with_parens = pprust::nonterminal_to_string(nt);
342341
let filename_with_parens = FileName::macro_expansion_source_code(&source_with_parens);
343-
let tokens_with_parens = parse_stream_from_source_str(
342+
let reparsed_tokens_with_parens = parse_stream_from_source_str(
344343
filename_with_parens,
345344
source_with_parens,
346345
sess,
347346
Some(span),
348347
);
349348

350-
if tokenstream_probably_equal_for_proc_macro(&tokens, &tokens_with_parens, sess) {
349+
// Compare with a relaxed delim match - we want inserted parenthesis in the
350+
// reparsed stream to match `None`-delimiters in the original stream.
351+
if tokenstream_probably_equal_for_proc_macro(
352+
&tokens,
353+
&reparsed_tokens_with_parens,
354+
sess,
355+
true,
356+
) {
351357
return tokens;
352358
}
353359

354360
info!(
355361
"cached tokens found, but they're not \"probably equal\", \
356362
going with stringified version"
357363
);
358-
info!("cached tokens: {:?}", tokens);
359-
info!("reparsed tokens: {:?}", reparsed_tokens);
364+
info!("cached tokens: {}", pprust::tts_to_string(&tokens));
365+
info!("reparsed tokens: {}", pprust::tts_to_string(&reparsed_tokens_with_parens));
366+
367+
info!("cached tokens debug: {:?}", tokens);
368+
info!("reparsed tokens debug: {:?}", reparsed_tokens_with_parens);
360369
}
361370
reparsed_tokens
362371
}
@@ -370,6 +379,7 @@ pub fn tokenstream_probably_equal_for_proc_macro(
370379
tokens: &TokenStream,
371380
reparsed_tokens: &TokenStream,
372381
sess: &ParseSess,
382+
relaxed_delim_match: bool,
373383
) -> bool {
374384
// When checking for `probably_eq`, we ignore certain tokens that aren't
375385
// preserved in the AST. Because they are not preserved, the pretty
@@ -495,7 +505,9 @@ pub fn tokenstream_probably_equal_for_proc_macro(
495505
let tokens = tokens.trees().flat_map(|t| expand_token(t, sess));
496506
let reparsed_tokens = reparsed_tokens.trees().flat_map(|t| expand_token(t, sess));
497507

498-
tokens.eq_by(reparsed_tokens, |t, rt| tokentree_probably_equal_for_proc_macro(&t, &rt, sess))
508+
tokens.eq_by(reparsed_tokens, |t, rt| {
509+
tokentree_probably_equal_for_proc_macro(&t, &rt, sess, relaxed_delim_match)
510+
})
499511
}
500512

501513
// See comments in `Nonterminal::to_tokenstream` for why we care about
@@ -507,17 +519,42 @@ pub fn tokentree_probably_equal_for_proc_macro(
507519
token: &TokenTree,
508520
reparsed_token: &TokenTree,
509521
sess: &ParseSess,
522+
relaxed_delim_match: bool,
510523
) -> bool {
511524
match (token, reparsed_token) {
512525
(TokenTree::Token(token), TokenTree::Token(reparsed_token)) => {
513526
token_probably_equal_for_proc_macro(token, reparsed_token)
514527
}
515-
(TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
516-
// `NoDelim` delimiters can appear in the captured tokenstream, but not
517-
// in the reparsed tokenstream. Allow them to match with anything, so
518-
// that we check if the two streams are structurally equivalent.
519-
(delim == delim2 || *delim == DelimToken::NoDelim || *delim2 == DelimToken::NoDelim)
520-
&& tokenstream_probably_equal_for_proc_macro(&tts, &tts2, sess)
528+
(
529+
TokenTree::Delimited(_, delim, tokens),
530+
TokenTree::Delimited(_, reparsed_delim, reparsed_tokens),
531+
) if delim == reparsed_delim => tokenstream_probably_equal_for_proc_macro(
532+
tokens,
533+
reparsed_tokens,
534+
sess,
535+
relaxed_delim_match,
536+
),
537+
(TokenTree::Delimited(_, DelimToken::NoDelim, tokens), reparsed_token) => {
538+
if relaxed_delim_match {
539+
if let TokenTree::Delimited(_, DelimToken::Paren, reparsed_tokens) = reparsed_token
540+
{
541+
if tokenstream_probably_equal_for_proc_macro(
542+
tokens,
543+
reparsed_tokens,
544+
sess,
545+
relaxed_delim_match,
546+
) {
547+
return true;
548+
}
549+
}
550+
}
551+
tokens.len() == 1
552+
&& tokentree_probably_equal_for_proc_macro(
553+
&tokens.trees().next().unwrap(),
554+
reparsed_token,
555+
sess,
556+
relaxed_delim_match,
557+
)
521558
}
522559
_ => false,
523560
}

0 commit comments

Comments
 (0)