Auto merge of #127636 - nnethercote:fix-Parser-look_ahead, r=oli-obk · rust-lang/rust@62c068f (original) (raw)

`@@ -1376,6 +1376,127 @@ fn ttdelim_span() {

`

1376

1376

`});

`

1377

1377

`}

`

1378

1378

``

``

1379

`+

// Uses a macro rather than a function so that failure messages mention the

`

``

1380

`+

// correct line in the test function.

`

``

1381

`+

macro_rules! look {

`

``

1382

`+

($p:ident, dist:literal,dist:literal, dist:literal,kind:expr) => {

`

``

1383

`+

p.lookahead(p.look_ahead(p.lookahead(dist, |tok| assert_eq!($kind, tok.kind));

`

``

1384

`+

};

`

``

1385

`+

}

`

``

1386

+

``

1387

`+

#[test]

`

``

1388

`+

fn look_ahead() {

`

``

1389

`+

create_default_session_globals_then(|| {

`

``

1390

`+

let sym_f = Symbol::intern("f");

`

``

1391

`+

let sym_x = Symbol::intern("x");

`

``

1392

`+

#[allow(non_snake_case)]

`

``

1393

`+

let sym_S = Symbol::intern("S");

`

``

1394

`+

let raw_no = IdentIsRaw::No;

`

``

1395

+

``

1396

`+

let psess = psess();

`

``

1397

`+

let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string());

`

``

1398

+

``

1399

`` +

// Current position is the fn.

``

``

1400

`+

look!(p, 0, token::Ident(kw::Fn, raw_no));

`

``

1401

`+

look!(p, 1, token::Ident(sym_f, raw_no));

`

``

1402

`+

look!(p, 2, token::OpenDelim(Delimiter::Parenthesis));

`

``

1403

`+

look!(p, 3, token::Ident(sym_x, raw_no));

`

``

1404

`+

look!(p, 4, token::Colon);

`

``

1405

`+

look!(p, 5, token::Ident(sym::u32, raw_no));

`

``

1406

`+

look!(p, 6, token::CloseDelim(Delimiter::Parenthesis));

`

``

1407

`+

look!(p, 7, token::OpenDelim(Delimiter::Brace));

`

``

1408

`+

look!(p, 8, token::Ident(sym_x, raw_no));

`

``

1409

`+

look!(p, 9, token::CloseDelim(Delimiter::Brace));

`

``

1410

`+

look!(p, 10, token::Ident(kw::Struct, raw_no));

`

``

1411

`+

look!(p, 11, token::Ident(sym_S, raw_no));

`

``

1412

`+

look!(p, 12, token::Semi);

`

``

1413

`` +

// Any lookahead past the end of the token stream returns Eof.

``

``

1414

`+

look!(p, 13, token::Eof);

`

``

1415

`+

look!(p, 14, token::Eof);

`

``

1416

`+

look!(p, 15, token::Eof);

`

``

1417

`+

look!(p, 100, token::Eof);

`

``

1418

+

``

1419

`` +

// Move forward to the first x.

``

``

1420

`+

for _ in 0..3 {

`

``

1421

`+

p.bump();

`

``

1422

`+

}

`

``

1423

`+

look!(p, 0, token::Ident(sym_x, raw_no));

`

``

1424

`+

look!(p, 1, token::Colon);

`

``

1425

`+

look!(p, 2, token::Ident(sym::u32, raw_no));

`

``

1426

`+

look!(p, 3, token::CloseDelim(Delimiter::Parenthesis));

`

``

1427

`+

look!(p, 4, token::OpenDelim(Delimiter::Brace));

`

``

1428

`+

look!(p, 5, token::Ident(sym_x, raw_no));

`

``

1429

`+

look!(p, 6, token::CloseDelim(Delimiter::Brace));

`

``

1430

`+

look!(p, 7, token::Ident(kw::Struct, raw_no));

`

``

1431

`+

look!(p, 8, token::Ident(sym_S, raw_no));

`

``

1432

`+

look!(p, 9, token::Semi);

`

``

1433

`+

look!(p, 10, token::Eof);

`

``

1434

`+

look!(p, 11, token::Eof);

`

``

1435

`+

look!(p, 100, token::Eof);

`

``

1436

+

``

1437

`` +

// Move forward to the ;.

``

``

1438

`+

for _ in 0..9 {

`

``

1439

`+

p.bump();

`

``

1440

`+

}

`

``

1441

`+

look!(p, 0, token::Semi);

`

``

1442

`` +

// Any lookahead past the end of the token stream returns Eof.

``

``

1443

`+

look!(p, 1, token::Eof);

`

``

1444

`+

look!(p, 100, token::Eof);

`

``

1445

+

``

1446

`` +

// Move one past the ;, i.e. past the end of the token stream.

``

``

1447

`+

p.bump();

`

``

1448

`+

look!(p, 0, token::Eof);

`

``

1449

`+

look!(p, 1, token::Eof);

`

``

1450

`+

look!(p, 100, token::Eof);

`

``

1451

+

``

1452

`+

// Bumping after Eof is idempotent.

`

``

1453

`+

p.bump();

`

``

1454

`+

look!(p, 0, token::Eof);

`

``

1455

`+

look!(p, 1, token::Eof);

`

``

1456

`+

look!(p, 100, token::Eof);

`

``

1457

`+

});

`

``

1458

`+

}

`

``

1459

+

``

1460

`` +

/// There used to be some buggy behaviour when using look_ahead not within

``

``

1461

`+

/// the outermost token stream, which this test covers.

`

``

1462

`+

#[test]

`

``

1463

`+

fn look_ahead_non_outermost_stream() {

`

``

1464

`+

create_default_session_globals_then(|| {

`

``

1465

`+

let sym_f = Symbol::intern("f");

`

``

1466

`+

let sym_x = Symbol::intern("x");

`

``

1467

`+

#[allow(non_snake_case)]

`

``

1468

`+

let sym_S = Symbol::intern("S");

`

``

1469

`+

let raw_no = IdentIsRaw::No;

`

``

1470

+

``

1471

`+

let psess = psess();

`

``

1472

`+

let mut p = string_to_parser(&psess, "mod m { fn f(x: u32) { x } struct S; }".to_string());

`

``

1473

+

``

1474

`` +

// Move forward to the fn, which is not within the outermost token

``

``

1475

`` +

// stream (because it's inside the mod { ... }).

``

``

1476

`+

for _ in 0..3 {

`

``

1477

`+

p.bump();

`

``

1478

`+

}

`

``

1479

`+

look!(p, 0, token::Ident(kw::Fn, raw_no));

`

``

1480

`+

look!(p, 1, token::Ident(sym_f, raw_no));

`

``

1481

`+

look!(p, 2, token::OpenDelim(Delimiter::Parenthesis));

`

``

1482

`+

look!(p, 3, token::Ident(sym_x, raw_no));

`

``

1483

`+

look!(p, 4, token::Colon);

`

``

1484

`+

look!(p, 5, token::Ident(sym::u32, raw_no));

`

``

1485

`+

look!(p, 6, token::CloseDelim(Delimiter::Parenthesis));

`

``

1486

`+

look!(p, 7, token::OpenDelim(Delimiter::Brace));

`

``

1487

`+

look!(p, 8, token::Ident(sym_x, raw_no));

`

``

1488

`+

look!(p, 9, token::CloseDelim(Delimiter::Brace));

`

``

1489

`+

look!(p, 10, token::Ident(kw::Struct, raw_no));

`

``

1490

`+

look!(p, 11, token::Ident(sym_S, raw_no));

`

``

1491

`+

look!(p, 12, token::Semi);

`

``

1492

`+

look!(p, 13, token::CloseDelim(Delimiter::Brace));

`

``

1493

`` +

// Any lookahead past the end of the token stream returns Eof.

``

``

1494

`+

look!(p, 14, token::Eof);

`

``

1495

`+

look!(p, 15, token::Eof);

`

``

1496

`+

look!(p, 100, token::Eof);

`

``

1497

`+

});

`

``

1498

`+

}

`

``

1499

+

1379

1500

`// This tests that when parsing a string (rather than a file) we don't try

`

1380

1501

`// and read in a file for a module declaration and just parse a stub.

`

1381

1502

`` // See recurse_into_file_modules in the parser.

``