@@ -681,7 +681,7 @@ pub struct IdentRenamer<'a> {
681681
682682impl < ' a > Folder for IdentRenamer < ' a > {
683683 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)
685685 }
686686 fn fold_mac ( & mut self , mac : ast:: Mac ) -> ast:: Mac {
687687 fold:: noop_fold_mac ( mac, self )
@@ -705,8 +705,7 @@ impl<'a> Folder for PatIdentRenamer<'a> {
705705
706706 pat. map ( |ast:: Pat { id, node, span} | match node {
707707 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) ;
710709 let new_node =
711710 PatKind :: Ident ( binding_mode,
712711 Spanned { span : sp, node : new_ident} ,
@@ -1266,7 +1265,7 @@ mod tests {
12661265 use ext:: mtwt;
12671266 use fold:: Folder ;
12681267 use parse;
1269- use parse:: token:: { self , keywords } ;
1268+ use parse:: token;
12701269 use util:: parser_testing:: { string_to_parser} ;
12711270 use util:: parser_testing:: { string_to_pat, string_to_crate, strs_to_idents} ;
12721271 use visit;
@@ -1396,267 +1395,10 @@ mod tests {
13961395 ) ;
13971396 }
13981397
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-
15091398 // create a really evil test case where a $x appears inside a binding of $x
15101399 // but *shouldn't* bind because it was inserted by a different macro....
15111400 // can't write this test case until we have macro-generating macros.
15121401
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-
16601402 #[ test]
16611403 fn fmt_in_macro_used_inside_module_macro ( ) {
16621404 let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string()));
0 commit comments