|  | 
| 1 | 1 | use crate::ast::NodeId; | 
| 2 |  | -use crate::early_buffered_lints::BufferedEarlyLintId; | 
| 3 | 2 | use crate::ext::tt::macro_parser; | 
| 4 | 3 | use crate::feature_gate::Features; | 
| 5 | 4 | use crate::parse::{token, ParseSess}; | 
| @@ -291,16 +290,7 @@ where | 
| 291 | 290 |                     macro_node_id, | 
| 292 | 291 |                 ); | 
| 293 | 292 |                 // Get the Kleene operator and optional separator | 
| 294 |  | -                let (separator, op) = | 
| 295 |  | -                    parse_sep_and_kleene_op( | 
| 296 |  | -                        trees, | 
| 297 |  | -                        span.entire(), | 
| 298 |  | -                        sess, | 
| 299 |  | -                        features, | 
| 300 |  | -                        attrs, | 
| 301 |  | -                        edition, | 
| 302 |  | -                        macro_node_id, | 
| 303 |  | -                    ); | 
|  | 293 | +                let (separator, op) = parse_sep_and_kleene_op(trees, span.entire(), sess); | 
| 304 | 294 |                 // Count the number of captured "names" (i.e., named metavars) | 
| 305 | 295 |                 let name_captures = macro_parser::count_names(&sequence); | 
| 306 | 296 |                 TokenTree::Sequence( | 
| @@ -411,164 +401,11 @@ where | 
| 411 | 401 | /// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene | 
| 412 | 402 | /// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an | 
| 413 | 403 | /// error with the appropriate span is emitted to `sess` and a dummy value is returned. | 
| 414 |  | -/// | 
| 415 |  | -/// N.B., in the 2015 edition, `*` and `+` are the only Kleene operators, and `?` is a separator. | 
| 416 |  | -/// In the 2018 edition however, `?` is a Kleene operator, and not a separator. | 
| 417 |  | -fn parse_sep_and_kleene_op<I>( | 
| 418 |  | -    input: &mut Peekable<I>, | 
| 419 |  | -    span: Span, | 
| 420 |  | -    sess: &ParseSess, | 
| 421 |  | -    features: &Features, | 
| 422 |  | -    attrs: &[ast::Attribute], | 
| 423 |  | -    edition: Edition, | 
| 424 |  | -    macro_node_id: NodeId, | 
| 425 |  | -) -> (Option<token::Token>, KleeneOp) | 
| 426 |  | -where | 
| 427 |  | -    I: Iterator<Item = tokenstream::TokenTree>, | 
| 428 |  | -{ | 
| 429 |  | -    match edition { | 
| 430 |  | -        Edition::Edition2015 => parse_sep_and_kleene_op_2015( | 
| 431 |  | -            input, | 
| 432 |  | -            span, | 
| 433 |  | -            sess, | 
| 434 |  | -            features, | 
| 435 |  | -            attrs, | 
| 436 |  | -            macro_node_id, | 
| 437 |  | -        ), | 
| 438 |  | -        Edition::Edition2018 => parse_sep_and_kleene_op_2018(input, span, sess, features, attrs), | 
| 439 |  | -    } | 
| 440 |  | -} | 
| 441 |  | - | 
| 442 |  | -// `?` is a separator (with a migration warning) and never a KleeneOp. | 
| 443 |  | -fn parse_sep_and_kleene_op_2015<I>( | 
| 444 |  | -    input: &mut Peekable<I>, | 
| 445 |  | -    span: Span, | 
| 446 |  | -    sess: &ParseSess, | 
| 447 |  | -    _features: &Features, | 
| 448 |  | -    _attrs: &[ast::Attribute], | 
| 449 |  | -    macro_node_id: NodeId, | 
| 450 |  | -) -> (Option<token::Token>, KleeneOp) | 
| 451 |  | -where | 
| 452 |  | -    I: Iterator<Item = tokenstream::TokenTree>, | 
| 453 |  | -{ | 
| 454 |  | -    // We basically look at two token trees here, denoted as #1 and #2 below | 
| 455 |  | -    let span = match parse_kleene_op(input, span) { | 
| 456 |  | -        // #1 is a `+` or `*` KleeneOp | 
| 457 |  | -        // | 
| 458 |  | -        // `?` is ambiguous: it could be a separator (warning) or a Kleene::ZeroOrOne (error), so | 
| 459 |  | -        // we need to look ahead one more token to be sure. | 
| 460 |  | -        Ok(Ok((op, _))) if op != KleeneOp::ZeroOrOne => return (None, op), | 
| 461 |  | - | 
| 462 |  | -        // #1 is `?` token, but it could be a Kleene::ZeroOrOne (error in 2015) without a separator | 
| 463 |  | -        // or it could be a `?` separator followed by any Kleene operator. We need to look ahead 1 | 
| 464 |  | -        // token to find out which. | 
| 465 |  | -        Ok(Ok((op, op1_span))) => { | 
| 466 |  | -            assert_eq!(op, KleeneOp::ZeroOrOne); | 
| 467 |  | - | 
| 468 |  | -            // Lookahead at #2. If it is a KleenOp, then #1 is a separator. | 
| 469 |  | -            let is_1_sep = if let Some(&tokenstream::TokenTree::Token(_, ref tok2)) = input.peek() { | 
| 470 |  | -                kleene_op(tok2).is_some() | 
| 471 |  | -            } else { | 
| 472 |  | -                false | 
| 473 |  | -            }; | 
| 474 |  | - | 
| 475 |  | -            if is_1_sep { | 
| 476 |  | -                // #1 is a separator and #2 should be a KleepeOp. | 
| 477 |  | -                // (N.B. We need to advance the input iterator.) | 
| 478 |  | -                match parse_kleene_op(input, span) { | 
| 479 |  | -                    // #2 is `?`, which is not allowed as a Kleene op in 2015 edition, | 
| 480 |  | -                    // but is allowed in the 2018 edition. | 
| 481 |  | -                    Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => { | 
| 482 |  | -                        sess.span_diagnostic | 
| 483 |  | -                            .struct_span_err(op2_span, "expected `*` or `+`") | 
| 484 |  | -                            .note("`?` is not a macro repetition operator in the 2015 edition, \ | 
| 485 |  | -                                 but is accepted in the 2018 edition") | 
| 486 |  | -                            .emit(); | 
| 487 |  | - | 
| 488 |  | -                        // Return a dummy | 
| 489 |  | -                        return (None, KleeneOp::ZeroOrMore); | 
| 490 |  | -                    } | 
| 491 |  | - | 
| 492 |  | -                    // #2 is a Kleene op, which is the only valid option | 
| 493 |  | -                    Ok(Ok((op, _))) => { | 
| 494 |  | -                        // Warn that `?` as a separator will be deprecated | 
| 495 |  | -                        sess.buffer_lint( | 
| 496 |  | -                            BufferedEarlyLintId::QuestionMarkMacroSep, | 
| 497 |  | -                            op1_span, | 
| 498 |  | -                            macro_node_id, | 
| 499 |  | -                            "using `?` as a separator is deprecated and will be \ | 
| 500 |  | -                             a hard error in an upcoming edition", | 
| 501 |  | -                        ); | 
| 502 |  | - | 
| 503 |  | -                        return (Some(token::Question), op); | 
| 504 |  | -                    } | 
| 505 |  | - | 
| 506 |  | -                    // #2 is a random token (this is an error) :( | 
| 507 |  | -                    Ok(Err((_, _))) => op1_span, | 
| 508 |  | - | 
| 509 |  | -                    // #2 is not even a token at all :( | 
| 510 |  | -                    Err(_) => op1_span, | 
| 511 |  | -                } | 
| 512 |  | -            } else { | 
| 513 |  | -                // `?` is not allowed as a Kleene op in 2015, | 
| 514 |  | -                // but is allowed in the 2018 edition | 
| 515 |  | -                sess.span_diagnostic | 
| 516 |  | -                    .struct_span_err(op1_span, "expected `*` or `+`") | 
| 517 |  | -                    .note("`?` is not a macro repetition operator in the 2015 edition, \ | 
| 518 |  | -                         but is accepted in the 2018 edition") | 
| 519 |  | -                    .emit(); | 
| 520 |  | - | 
| 521 |  | -                // Return a dummy | 
| 522 |  | -                return (None, KleeneOp::ZeroOrMore); | 
| 523 |  | -            } | 
| 524 |  | -        } | 
| 525 |  | - | 
| 526 |  | -        // #1 is a separator followed by #2, a KleeneOp | 
| 527 |  | -        Ok(Err((tok, span))) => match parse_kleene_op(input, span) { | 
| 528 |  | -            // #2 is a `?`, which is not allowed as a Kleene op in 2015 edition, | 
| 529 |  | -            // but is allowed in the 2018 edition | 
| 530 |  | -            Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => { | 
| 531 |  | -                sess.span_diagnostic | 
| 532 |  | -                    .struct_span_err(op2_span, "expected `*` or `+`") | 
| 533 |  | -                    .note("`?` is not a macro repetition operator in the 2015 edition, \ | 
| 534 |  | -                        but is accepted in the 2018 edition") | 
| 535 |  | -                    .emit(); | 
| 536 |  | - | 
| 537 |  | -                // Return a dummy | 
| 538 |  | -                return (None, KleeneOp::ZeroOrMore); | 
| 539 |  | -            } | 
| 540 |  | - | 
| 541 |  | -            // #2 is a KleeneOp :D | 
| 542 |  | -            Ok(Ok((op, _))) => return (Some(tok), op), | 
| 543 |  | - | 
| 544 |  | -            // #2 is a random token :( | 
| 545 |  | -            Ok(Err((_, span))) => span, | 
| 546 |  | - | 
| 547 |  | -            // #2 is not a token at all :( | 
| 548 |  | -            Err(span) => span, | 
| 549 |  | -        }, | 
| 550 |  | - | 
| 551 |  | -        // #1 is not a token | 
| 552 |  | -        Err(span) => span, | 
| 553 |  | -    }; | 
| 554 |  | - | 
| 555 |  | -    sess.span_diagnostic.span_err(span, "expected `*` or `+`"); | 
| 556 |  | - | 
| 557 |  | -    // Return a dummy | 
| 558 |  | -    (None, KleeneOp::ZeroOrMore) | 
| 559 |  | -} | 
| 560 |  | - | 
| 561 |  | -// `?` is a Kleene op, not a separator | 
| 562 |  | -fn parse_sep_and_kleene_op_2018<I>( | 
| 563 |  | -    input: &mut Peekable<I>, | 
|  | 404 | +fn parse_sep_and_kleene_op( | 
|  | 405 | +    input: &mut Peekable<impl Iterator<Item = tokenstream::TokenTree>>, | 
| 564 | 406 |     span: Span, | 
| 565 | 407 |     sess: &ParseSess, | 
| 566 |  | -    _features: &Features, | 
| 567 |  | -    _attrs: &[ast::Attribute], | 
| 568 |  | -) -> (Option<token::Token>, KleeneOp) | 
| 569 |  | -where | 
| 570 |  | -    I: Iterator<Item = tokenstream::TokenTree>, | 
| 571 |  | -{ | 
|  | 408 | +) -> (Option<token::Token>, KleeneOp) { | 
| 572 | 409 |     // We basically look at two token trees here, denoted as #1 and #2 below | 
| 573 | 410 |     let span = match parse_kleene_op(input, span) { | 
| 574 | 411 |         // #1 is a `?` (needs feature gate) | 
|  | 
0 commit comments