@@ -681,7 +681,7 @@ pub struct IdentRenamer<'a> {
681
681
682
682
impl < ' a > Folder for IdentRenamer < ' a > {
683
683
fn fold_ident ( & mut self , id : Ident ) -> Ident {
684
- Ident :: new ( id . name , mtwt:: apply_renames ( self . renames , id. ctxt ) )
684
+ mtwt:: apply_renames ( self . renames , id)
685
685
}
686
686
fn fold_mac ( & mut self , mac : ast:: Mac ) -> ast:: Mac {
687
687
fold:: noop_fold_mac ( mac, self )
@@ -705,8 +705,7 @@ impl<'a> Folder for PatIdentRenamer<'a> {
705
705
706
706
pat. map ( |ast:: Pat { id, node, span} | match node {
707
707
PatKind :: Ident ( binding_mode, Spanned { span : sp, node : ident} , sub) => {
708
- let new_ident = Ident :: new ( ident. name ,
709
- mtwt:: apply_renames ( self . renames , ident. ctxt ) ) ;
708
+ let new_ident = mtwt:: apply_renames ( self . renames , ident) ;
710
709
let new_node =
711
710
PatKind :: Ident ( binding_mode,
712
711
Spanned { span : sp, node : new_ident} ,
@@ -1266,7 +1265,7 @@ mod tests {
1266
1265
use ext:: mtwt;
1267
1266
use fold:: Folder ;
1268
1267
use parse;
1269
- use parse:: token:: { self , keywords } ;
1268
+ use parse:: token;
1270
1269
use util:: parser_testing:: { string_to_parser} ;
1271
1270
use util:: parser_testing:: { string_to_pat, string_to_crate, strs_to_idents} ;
1272
1271
use visit;
@@ -1396,267 +1395,10 @@ mod tests {
1396
1395
) ;
1397
1396
}
1398
1397
1399
- // renaming tests expand a crate and then check that the bindings match
1400
- // the right varrefs. The specification of the test case includes the
1401
- // text of the crate, and also an array of arrays. Each element in the
1402
- // outer array corresponds to a binding in the traversal of the AST
1403
- // induced by visit. Each of these arrays contains a list of indexes,
1404
- // interpreted as the varrefs in the varref traversal that this binding
1405
- // should match. So, for instance, in a program with two bindings and
1406
- // three varrefs, the array [[1, 2], [0]] would indicate that the first
1407
- // binding should match the second two varrefs, and the second binding
1408
- // should match the first varref.
1409
- //
1410
- // Put differently; this is a sparse representation of a boolean matrix
1411
- // indicating which bindings capture which identifiers.
1412
- //
1413
- // Note also that this matrix is dependent on the implicit ordering of
1414
- // the bindings and the varrefs discovered by the name-finder and the path-finder.
1415
- //
1416
- // The comparisons are done post-mtwt-resolve, so we're comparing renamed
1417
- // names; differences in marks don't matter any more.
1418
- //
1419
- // oog... I also want tests that check "bound-identifier-=?". That is,
1420
- // not just "do these have the same name", but "do they have the same
1421
- // name *and* the same marks"? Understanding this is really pretty painful.
1422
- // in principle, you might want to control this boolean on a per-varref basis,
1423
- // but that would make things even harder to understand, and might not be
1424
- // necessary for thorough testing.
1425
- type RenamingTest = ( & ' static str , Vec < Vec < usize > > , bool ) ;
1426
-
1427
- #[ test]
1428
- fn automatic_renaming ( ) {
1429
- let tests: Vec < RenamingTest > =
1430
- vec ! ( // b & c should get new names throughout, in the expr too:
1431
- ( "fn a() -> i32 { let b = 13; let c = b; b+c }" ,
1432
- vec!( vec!( 0 , 1 ) , vec!( 2 ) ) , false ) ,
1433
- // both x's should be renamed (how is this causing a bug?)
1434
- ( "fn main () {let x: i32 = 13;x;}" ,
1435
- vec!( vec!( 0 ) ) , false ) ,
1436
- // the use of b after the + should be renamed, the other one not:
1437
- ( "macro_rules! f (($x:ident) => (b + $x)); fn a() -> i32 { let b = 13; f!(b)}" ,
1438
- vec!( vec!( 1 ) ) , false ) ,
1439
- // the b before the plus should not be renamed (requires marks)
1440
- ( "macro_rules! f (($x:ident) => ({let b=9; ($x + b)})); fn a() -> i32 { f!(b)}" ,
1441
- vec!( vec!( 1 ) ) , false ) ,
1442
- // the marks going in and out of letty should cancel, allowing that $x to
1443
- // capture the one following the semicolon.
1444
- // this was an awesome test case, and caught a *lot* of bugs.
1445
- ( "macro_rules! letty(($x:ident) => (let $x = 15;));
1446
- macro_rules! user(($x:ident) => ({letty!($x); $x}));
1447
- fn main() -> i32 {user!(z)}" ,
1448
- vec!( vec!( 0 ) ) , false )
1449
- ) ;
1450
- for ( idx, s) in tests. iter ( ) . enumerate ( ) {
1451
- run_renaming_test ( s, idx) ;
1452
- }
1453
- }
1454
-
1455
- // no longer a fixme #8062: this test exposes a *potential* bug; our system does
1456
- // not behave exactly like MTWT, but a conversation with Matthew Flatt
1457
- // suggests that this can only occur in the presence of local-expand, which
1458
- // we have no plans to support. ... unless it's needed for item hygiene....
1459
- #[ ignore]
1460
- #[ test]
1461
- fn issue_8062 ( ) {
1462
- run_renaming_test (
1463
- & ( "fn main() {let hrcoo = 19; macro_rules! getx(()=>(hrcoo)); getx!();}" ,
1464
- vec ! ( vec!( 0 ) ) , true ) , 0 )
1465
- }
1466
-
1467
- // FIXME #6994:
1468
- // the z flows into and out of two macros (g & f) along one path, and one
1469
- // (just g) along the other, so the result of the whole thing should
1470
- // be "let z_123 = 3; z_123"
1471
- #[ ignore]
1472
- #[ test]
1473
- fn issue_6994 ( ) {
1474
- run_renaming_test (
1475
- & ( "macro_rules! g (($x:ident) =>
1476
- ({macro_rules! f(($y:ident)=>({let $y=3;$x}));f!($x)}));
1477
- fn a(){g!(z)}" ,
1478
- vec ! ( vec!( 0 ) ) , false ) ,
1479
- 0 )
1480
- }
1481
-
1482
- // match variable hygiene. Should expand into
1483
- // fn z() {match 8 {x_1 => {match 9 {x_2 | x_2 if x_2 == x_1 => x_2 + x_1}}}}
1484
- #[ test]
1485
- fn issue_9384 ( ) {
1486
- run_renaming_test (
1487
- & ( "macro_rules! bad_macro (($ex:expr) => ({match 9 {x | x if x == $ex => x + $ex}}));
1488
- fn z() {match 8 {x => bad_macro!(x)}}" ,
1489
- // NB: the third "binding" is the repeat of the second one.
1490
- vec ! ( vec!( 1 , 3 ) , vec!( 0 , 2 ) , vec!( 0 , 2 ) ) ,
1491
- true ) ,
1492
- 0 )
1493
- }
1494
-
1495
- // interpolated nodes weren't getting labeled.
1496
- // should expand into
1497
- // fn main(){let g1_1 = 13; g1_1}}
1498
- #[ test]
1499
- fn pat_expand_issue_15221 ( ) {
1500
- run_renaming_test (
1501
- & ( "macro_rules! inner ( ($e:pat ) => ($e));
1502
- macro_rules! outer ( ($e:pat ) => (inner!($e)));
1503
- fn main() { let outer!(g) = 13; g;}" ,
1504
- vec ! ( vec!( 0 ) ) ,
1505
- true ) ,
1506
- 0 )
1507
- }
1508
-
1509
1398
// create a really evil test case where a $x appears inside a binding of $x
1510
1399
// but *shouldn't* bind because it was inserted by a different macro....
1511
1400
// can't write this test case until we have macro-generating macros.
1512
1401
1513
- // method arg hygiene
1514
- // method expands to fn get_x(&self_0, x_1: i32) {self_0 + self_2 + x_3 + x_1}
1515
- #[ test]
1516
- fn method_arg_hygiene ( ) {
1517
- run_renaming_test (
1518
- & ( "macro_rules! inject_x (()=>(x));
1519
- macro_rules! inject_self (()=>(self));
1520
- struct A;
1521
- impl A{fn get_x(&self, x: i32) {self + inject_self!() + inject_x!() + x;} }" ,
1522
- vec ! ( vec!( 0 ) , vec!( 3 ) ) ,
1523
- true ) ,
1524
- 0 )
1525
- }
1526
-
1527
- // ooh, got another bite?
1528
- // expands to struct A; impl A {fn thingy(&self_1) {self_1;}}
1529
- #[ test]
1530
- fn method_arg_hygiene_2 ( ) {
1531
- run_renaming_test (
1532
- & ( "struct A;
1533
- macro_rules! add_method (($T:ty) =>
1534
- (impl $T { fn thingy(&self) {self;} }));
1535
- add_method!(A);" ,
1536
- vec ! ( vec!( 0 ) ) ,
1537
- true ) ,
1538
- 0 )
1539
- }
1540
-
1541
- // item fn hygiene
1542
- // expands to fn q(x_1: i32){fn g(x_2: i32){x_2 + x_1};}
1543
- #[ test]
1544
- fn issue_9383 ( ) {
1545
- run_renaming_test (
1546
- & ( "macro_rules! bad_macro (($ex:expr) => (fn g(x: i32){ x + $ex }));
1547
- fn q(x: i32) { bad_macro!(x); }" ,
1548
- vec ! ( vec!( 1 ) , vec!( 0 ) ) , true ) ,
1549
- 0 )
1550
- }
1551
-
1552
- // closure arg hygiene (ExprKind::Closure)
1553
- // expands to fn f(){(|x_1 : i32| {(x_2 + x_1)})(3);}
1554
- #[ test]
1555
- fn closure_arg_hygiene ( ) {
1556
- run_renaming_test (
1557
- & ( "macro_rules! inject_x (()=>(x));
1558
- fn f(){(|x : i32| {(inject_x!() + x)})(3);}" ,
1559
- vec ! ( vec!( 1 ) ) ,
1560
- true ) ,
1561
- 0 )
1562
- }
1563
-
1564
- // macro_rules in method position. Sadly, unimplemented.
1565
- #[ test]
1566
- fn macro_in_method_posn ( ) {
1567
- expand_crate_str (
1568
- "macro_rules! my_method (() => (fn thirteen(&self) -> i32 {13}));
1569
- struct A;
1570
- impl A{ my_method!(); }
1571
- fn f(){A.thirteen;}" . to_string ( ) ) ;
1572
- }
1573
-
1574
- // another nested macro
1575
- // expands to impl Entries {fn size_hint(&self_1) {self_1;}
1576
- #[ test]
1577
- fn item_macro_workaround ( ) {
1578
- run_renaming_test (
1579
- & ( "macro_rules! item { ($i:item) => {$i}}
1580
- struct Entries;
1581
- macro_rules! iterator_impl {
1582
- () => { item!( impl Entries { fn size_hint(&self) { self;}});}}
1583
- iterator_impl! { }" ,
1584
- vec ! ( vec!( 0 ) ) , true ) ,
1585
- 0 )
1586
- }
1587
-
1588
- // run one of the renaming tests
1589
- fn run_renaming_test ( t : & RenamingTest , test_idx : usize ) {
1590
- let invalid_name = keywords:: Invalid . name ( ) ;
1591
- let ( teststr, bound_connections, bound_ident_check) = match * t {
1592
- ( ref str, ref conns, bic) => ( str. to_string ( ) , conns. clone ( ) , bic)
1593
- } ;
1594
- let cr = expand_crate_str ( teststr. to_string ( ) ) ;
1595
- let bindings = crate_bindings ( & cr) ;
1596
- let varrefs = crate_varrefs ( & cr) ;
1597
-
1598
- // must be one check clause for each binding:
1599
- assert_eq ! ( bindings. len( ) , bound_connections. len( ) ) ;
1600
- for ( binding_idx, shouldmatch) in bound_connections. iter ( ) . enumerate ( ) {
1601
- let binding_name = mtwt:: resolve ( bindings[ binding_idx] ) ;
1602
- let binding_marks = mtwt:: marksof ( bindings[ binding_idx] . ctxt , invalid_name) ;
1603
- // shouldmatch can't name varrefs that don't exist:
1604
- assert ! ( ( shouldmatch. is_empty( ) ) ||
1605
- ( varrefs. len( ) > * shouldmatch. iter( ) . max( ) . unwrap( ) ) ) ;
1606
- for ( idx, varref) in varrefs. iter ( ) . enumerate ( ) {
1607
- let print_hygiene_debug_info = || {
1608
- // good lord, you can't make a path with 0 segments, can you?
1609
- let final_varref_ident = match varref. segments . last ( ) {
1610
- Some ( pathsegment) => pathsegment. identifier ,
1611
- None => panic ! ( "varref with 0 path segments?" )
1612
- } ;
1613
- let varref_name = mtwt:: resolve ( final_varref_ident) ;
1614
- let varref_idents : Vec < ast:: Ident >
1615
- = varref. segments . iter ( ) . map ( |s| s. identifier )
1616
- . collect ( ) ;
1617
- println ! ( "varref #{}: {:?}, resolves to {}" , idx, varref_idents, varref_name) ;
1618
- println ! ( "varref's first segment's string: \" {}\" " , final_varref_ident) ;
1619
- println ! ( "binding #{}: {}, resolves to {}" ,
1620
- binding_idx, bindings[ binding_idx] , binding_name) ;
1621
- mtwt:: with_sctable ( |x| mtwt:: display_sctable ( x) ) ;
1622
- } ;
1623
- if shouldmatch. contains ( & idx) {
1624
- // it should be a path of length 1, and it should
1625
- // be free-identifier=? or bound-identifier=? to the given binding
1626
- assert_eq ! ( varref. segments. len( ) , 1 ) ;
1627
- let varref_name = mtwt:: resolve ( varref. segments [ 0 ] . identifier ) ;
1628
- let varref_marks = mtwt:: marksof ( varref. segments [ 0 ]
1629
- . identifier
1630
- . ctxt ,
1631
- invalid_name) ;
1632
- if !( varref_name==binding_name) {
1633
- println ! ( "uh oh, should match but doesn't:" ) ;
1634
- print_hygiene_debug_info ( ) ;
1635
- }
1636
- assert_eq ! ( varref_name, binding_name) ;
1637
- if bound_ident_check {
1638
- // we're checking bound-identifier=?, and the marks
1639
- // should be the same, too:
1640
- assert_eq ! ( varref_marks, binding_marks. clone( ) ) ;
1641
- }
1642
- } else {
1643
- let varref_name = mtwt:: resolve ( varref. segments [ 0 ] . identifier ) ;
1644
- let fail = ( varref. segments . len ( ) == 1 )
1645
- && ( varref_name == binding_name) ;
1646
- // temp debugging:
1647
- if fail {
1648
- println ! ( "failure on test {}" , test_idx) ;
1649
- println ! ( "text of test case: \" {}\" " , teststr) ;
1650
- println ! ( "" ) ;
1651
- println ! ( "uh oh, matches but shouldn't:" ) ;
1652
- print_hygiene_debug_info ( ) ;
1653
- }
1654
- assert ! ( !fail) ;
1655
- }
1656
- }
1657
- }
1658
- }
1659
-
1660
1402
#[ test]
1661
1403
fn fmt_in_macro_used_inside_module_macro ( ) {
1662
1404
let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string()));
0 commit comments