From bd3a26493f101039fb6fe97561a15bcfffea82f0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 8 Sep 2018 10:13:32 +0300 Subject: [PATCH] fix stuck parser --- .../src/grammar/expressions/atom.rs | 9 +- .../libsyntax2/src/grammar/expressions/mod.rs | 4 + .../tests/data/parser/err/0022_bad_exprs.rs | 3 + .../tests/data/parser/err/0022_bad_exprs.txt | 189 +++++++++++++ .../tests/data/parser/ok/0034_macro_2.0.rs | 16 ++ .../tests/data/parser/ok/0034_macro_2.0.txt | 250 ++++++++++++++++++ .../tests/data/parser/ok/0034_macro_stuck.txt | 250 ++++++++++++++++++ 7 files changed, 719 insertions(+), 2 deletions(-) create mode 100644 crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.rs create mode 100644 crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.txt create mode 100644 crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.rs create mode 100644 crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.txt create mode 100644 crates/libsyntax2/tests/data/parser/ok/0034_macro_stuck.txt diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index f8b50b3558..2536bac800 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs @@ -140,9 +140,14 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { } while !p.at(EOF) && !p.at(R_BRACK) { p.expect(COMMA); - if !p.at(R_BRACK) { - expr(p); + if p.at(R_BRACK) { + break; } + if !EXPR_FIRST.contains(p.current()) { + p.error("expected expression"); + break; + } + expr(p); } p.expect(R_BRACK); m.complete(p, ARRAY_EXPR) diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index 9379ed9385..f7b9f7086e 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs @@ -376,6 +376,10 @@ fn arg_list(p: &mut Parser) { let m = p.start(); p.bump(); while !p.at(R_PAREN) && !p.at(EOF) { + if !EXPR_FIRST.contains(p.current()) { + p.error("expected expression"); + break; + } expr(p); if !p.at(R_PAREN) && !p.expect(COMMA) { break; diff --git a/crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.rs b/crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.rs new file mode 100644 index 0000000000..cd2d493a10 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.rs @@ -0,0 +1,3 @@ +fn a() { [1, 2, @, struct, let] } +fn b() { foo(1, 2, @, impl, let) } +fn c() { foo.bar(1, 2, @, ], trait, let) } diff --git a/crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.txt b/crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.txt new file mode 100644 index 0000000000..287e56ac43 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0022_bad_exprs.txt @@ -0,0 +1,189 @@ +ROOT@[0; 112) + FN_DEF@[0; 33) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 4) + IDENT@[3; 4) "a" + PARAM_LIST@[4; 6) + L_PAREN@[4; 5) + R_PAREN@[5; 6) + WHITESPACE@[6; 7) + BLOCK@[7; 33) + L_CURLY@[7; 8) + WHITESPACE@[8; 9) + EXPR_STMT@[9; 15) + ARRAY_EXPR@[9; 15) + L_BRACK@[9; 10) + LITERAL@[10; 11) + INT_NUMBER@[10; 11) "1" + COMMA@[11; 12) + WHITESPACE@[12; 13) + LITERAL@[13; 14) + INT_NUMBER@[13; 14) "2" + COMMA@[14; 15) + err: `expected expression` + err: `expected R_BRACK` + err: `expected SEMI` + WHITESPACE@[15; 16) + err: `expected expression` + EXPR_STMT@[16; 17) + ERROR@[16; 17) + AT@[16; 17) + err: `expected SEMI` + err: `expected expression` + EXPR_STMT@[17; 18) + ERROR@[17; 18) + COMMA@[17; 18) + err: `expected SEMI` + WHITESPACE@[18; 19) + STRUCT_DEF@[19; 26) + STRUCT_KW@[19; 25) + err: `expected a name` + ERROR@[25; 26) + COMMA@[25; 26) + err: `expected `;`, `{`, or `(`` + WHITESPACE@[26; 27) + LET_STMT@[27; 31) + LET_KW@[27; 30) + err: `expected pattern` + ERROR@[30; 31) + R_BRACK@[30; 31) + err: `expected SEMI` + WHITESPACE@[31; 32) + R_CURLY@[32; 33) + WHITESPACE@[33; 34) + FN_DEF@[34; 68) + FN_KW@[34; 36) + WHITESPACE@[36; 37) + NAME@[37; 38) + IDENT@[37; 38) "b" + PARAM_LIST@[38; 40) + L_PAREN@[38; 39) + R_PAREN@[39; 40) + WHITESPACE@[40; 41) + BLOCK@[41; 68) + L_CURLY@[41; 42) + WHITESPACE@[42; 43) + EXPR_STMT@[43; 52) + CALL_EXPR@[43; 52) + PATH_EXPR@[43; 46) + PATH@[43; 46) + PATH_SEGMENT@[43; 46) + NAME_REF@[43; 46) + IDENT@[43; 46) "foo" + ARG_LIST@[46; 52) + L_PAREN@[46; 47) + LITERAL@[47; 48) + INT_NUMBER@[47; 48) "1" + COMMA@[48; 49) + WHITESPACE@[49; 50) + LITERAL@[50; 51) + INT_NUMBER@[50; 51) "2" + COMMA@[51; 52) + err: `expected expression` + err: `expected SEMI` + WHITESPACE@[52; 53) + err: `expected expression` + EXPR_STMT@[53; 54) + ERROR@[53; 54) + AT@[53; 54) + err: `expected SEMI` + err: `expected expression` + EXPR_STMT@[54; 55) + ERROR@[54; 55) + COMMA@[54; 55) + err: `expected SEMI` + WHITESPACE@[55; 56) + IMPL_ITEM@[56; 60) + IMPL_KW@[56; 60) + err: `expected type` + err: `expected `{`` + err: `expected expression` + EXPR_STMT@[60; 61) + ERROR@[60; 61) + COMMA@[60; 61) + err: `expected SEMI` + WHITESPACE@[61; 62) + LET_STMT@[62; 65) + LET_KW@[62; 65) + err: `expected pattern` + err: `expected SEMI` + err: `expected expression` + ERROR@[65; 66) + R_PAREN@[65; 66) + WHITESPACE@[66; 67) + R_CURLY@[67; 68) + WHITESPACE@[68; 69) + FN_DEF@[69; 111) + FN_KW@[69; 71) + WHITESPACE@[71; 72) + NAME@[72; 73) + IDENT@[72; 73) "c" + PARAM_LIST@[73; 75) + L_PAREN@[73; 74) + R_PAREN@[74; 75) + WHITESPACE@[75; 76) + BLOCK@[76; 111) + L_CURLY@[76; 77) + WHITESPACE@[77; 78) + EXPR_STMT@[78; 91) + METHOD_CALL_EXPR@[78; 91) + PATH_EXPR@[78; 81) + PATH@[78; 81) + PATH_SEGMENT@[78; 81) + NAME_REF@[78; 81) + IDENT@[78; 81) "foo" + DOT@[81; 82) + NAME_REF@[82; 85) + IDENT@[82; 85) "bar" + ARG_LIST@[85; 91) + L_PAREN@[85; 86) + LITERAL@[86; 87) + INT_NUMBER@[86; 87) "1" + COMMA@[87; 88) + WHITESPACE@[88; 89) + LITERAL@[89; 90) + INT_NUMBER@[89; 90) "2" + COMMA@[90; 91) + err: `expected expression` + err: `expected SEMI` + WHITESPACE@[91; 92) + err: `expected expression` + EXPR_STMT@[92; 93) + ERROR@[92; 93) + AT@[92; 93) + err: `expected SEMI` + err: `expected expression` + EXPR_STMT@[93; 94) + ERROR@[93; 94) + COMMA@[93; 94) + err: `expected SEMI` + WHITESPACE@[94; 95) + err: `expected expression` + EXPR_STMT@[95; 96) + ERROR@[95; 96) + R_BRACK@[95; 96) + err: `expected SEMI` + err: `expected expression` + EXPR_STMT@[96; 97) + ERROR@[96; 97) + COMMA@[96; 97) + err: `expected SEMI` + WHITESPACE@[97; 98) + TRAIT_DEF@[98; 104) + TRAIT_KW@[98; 103) + err: `expected a name` + ERROR@[103; 104) + COMMA@[103; 104) + err: `expected `{`` + WHITESPACE@[104; 105) + LET_STMT@[105; 108) + LET_KW@[105; 108) + err: `expected pattern` + err: `expected SEMI` + err: `expected expression` + ERROR@[108; 109) + R_PAREN@[108; 109) + WHITESPACE@[109; 110) + R_CURLY@[110; 111) + WHITESPACE@[111; 112) diff --git a/crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.rs b/crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.rs new file mode 100644 index 0000000000..2a70ee83a4 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.rs @@ -0,0 +1,16 @@ +macro parse_use_trees($($s:expr),* $(,)*) { + vec![ + $(parse_use_tree($s),)* + ] +} + +#[test] +fn test_use_tree_merge() { + macro test_merge([$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) { + assert_eq!( + merge_use_trees(parse_use_trees!($($input,)*)), + parse_use_trees!($($output,)*), + ); + } +} + diff --git a/crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.txt b/crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.txt new file mode 100644 index 0000000000..1a8ca761dd --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/ok/0034_macro_2.0.txt @@ -0,0 +1,250 @@ +ROOT@[0; 350) + MACRO_CALL@[0; 41) + PATH@[0; 5) + PATH_SEGMENT@[0; 5) + NAME_REF@[0; 5) + IDENT@[0; 5) "macro" + err: `expected EXCL` + WHITESPACE@[5; 6) + IDENT@[6; 21) "parse_use_trees" + TOKEN_TREE@[21; 41) + L_PAREN@[21; 22) + DOLLAR@[22; 23) + TOKEN_TREE@[23; 32) + L_PAREN@[23; 24) + DOLLAR@[24; 25) + IDENT@[25; 26) "s" + COLON@[26; 27) + IDENT@[27; 31) "expr" + R_PAREN@[31; 32) + COMMA@[32; 33) + STAR@[33; 34) + WHITESPACE@[34; 35) + DOLLAR@[35; 36) + TOKEN_TREE@[36; 39) + L_PAREN@[36; 37) + COMMA@[37; 38) + R_PAREN@[38; 39) + STAR@[39; 40) + R_PAREN@[40; 41) + err: `expected SEMI` + WHITESPACE@[41; 42) + err: `expected an item` + ERROR@[42; 93) + L_CURLY@[42; 43) + WHITESPACE@[43; 48) + IDENT@[48; 51) "vec" + EXCL@[51; 52) + L_BRACK@[52; 53) + WHITESPACE@[53; 62) + DOLLAR@[62; 63) + L_PAREN@[63; 64) + IDENT@[64; 78) "parse_use_tree" + L_PAREN@[78; 79) + DOLLAR@[79; 80) + IDENT@[80; 81) "s" + R_PAREN@[81; 82) + COMMA@[82; 83) + R_PAREN@[83; 84) + STAR@[84; 85) + WHITESPACE@[85; 90) + R_BRACK@[90; 91) + WHITESPACE@[91; 92) + R_CURLY@[92; 93) + WHITESPACE@[93; 95) + FN_DEF@[95; 348) + ATTR@[95; 102) + POUND@[95; 96) + TOKEN_TREE@[96; 102) + L_BRACK@[96; 97) + IDENT@[97; 101) "test" + R_BRACK@[101; 102) + WHITESPACE@[102; 103) + FN_KW@[103; 105) + WHITESPACE@[105; 106) + NAME@[106; 125) + IDENT@[106; 125) "test_use_tree_merge" + PARAM_LIST@[125; 127) + L_PAREN@[125; 126) + R_PAREN@[126; 127) + WHITESPACE@[127; 128) + BLOCK@[128; 348) + L_CURLY@[128; 129) + WHITESPACE@[129; 134) + EXPR_STMT@[134; 139) + PATH_EXPR@[134; 139) + PATH@[134; 139) + PATH_SEGMENT@[134; 139) + NAME_REF@[134; 139) + IDENT@[134; 139) "macro" + err: `expected SEMI` + WHITESPACE@[139; 140) + EXPR_STMT@[140; 203) + CALL_EXPR@[140; 203) + PATH_EXPR@[140; 150) + PATH@[140; 150) + PATH_SEGMENT@[140; 150) + NAME_REF@[140; 150) + IDENT@[140; 150) "test_merge" + ARG_LIST@[150; 203) + L_PAREN@[150; 151) + ARRAY_EXPR@[151; 202) + L_BRACK@[151; 152) + err: `expected expression` + ERROR@[152; 153) + DOLLAR@[152; 153) + err: `expected COMMA` + TUPLE_EXPR@[153; 166) + L_PAREN@[153; 154) + err: `expected expression` + ERROR@[154; 155) + DOLLAR@[154; 155) + err: `expected COMMA` + PATH_EXPR@[155; 160) + PATH@[155; 160) + PATH_SEGMENT@[155; 160) + NAME_REF@[155; 160) + IDENT@[155; 160) "input" + err: `expected COMMA` + err: `expected expression` + ERROR@[160; 161) + COLON@[160; 161) + err: `expected COMMA` + PATH_EXPR@[161; 165) + PATH@[161; 165) + PATH_SEGMENT@[161; 165) + NAME_REF@[161; 165) + IDENT@[161; 165) "expr" + R_PAREN@[165; 166) + COMMA@[166; 167) + PREFIX_EXPR@[167; 170) + STAR@[167; 168) + WHITESPACE@[168; 169) + err: `expected expression` + ERROR@[169; 170) + DOLLAR@[169; 170) + err: `expected COMMA` + BIN_EXPR@[170; 175) + PAREN_EXPR@[170; 173) + L_PAREN@[170; 171) + err: `expected expression` + ERROR@[171; 172) + COMMA@[171; 172) + R_PAREN@[172; 173) + STAR@[173; 174) + err: `expected expression` + ERROR@[174; 175) + R_BRACK@[174; 175) + COMMA@[175; 176) + WHITESPACE@[176; 177) + ARRAY_EXPR@[177; 202) + L_BRACK@[177; 178) + err: `expected expression` + ERROR@[178; 179) + DOLLAR@[178; 179) + err: `expected COMMA` + TUPLE_EXPR@[179; 193) + L_PAREN@[179; 180) + err: `expected expression` + ERROR@[180; 181) + DOLLAR@[180; 181) + err: `expected COMMA` + PATH_EXPR@[181; 187) + PATH@[181; 187) + PATH_SEGMENT@[181; 187) + NAME_REF@[181; 187) + IDENT@[181; 187) "output" + err: `expected COMMA` + err: `expected expression` + ERROR@[187; 188) + COLON@[187; 188) + err: `expected COMMA` + PATH_EXPR@[188; 192) + PATH@[188; 192) + PATH_SEGMENT@[188; 192) + NAME_REF@[188; 192) + IDENT@[188; 192) "expr" + R_PAREN@[192; 193) + COMMA@[193; 194) + PREFIX_EXPR@[194; 197) + STAR@[194; 195) + WHITESPACE@[195; 196) + err: `expected expression` + ERROR@[196; 197) + DOLLAR@[196; 197) + err: `expected COMMA` + BIN_EXPR@[197; 202) + PAREN_EXPR@[197; 200) + L_PAREN@[197; 198) + err: `expected expression` + ERROR@[198; 199) + COMMA@[198; 199) + R_PAREN@[199; 200) + STAR@[200; 201) + err: `expected expression` + ERROR@[201; 202) + R_BRACK@[201; 202) + err: `expected COMMA` + err: `expected expression` + err: `expected R_BRACK` + err: `expected COMMA` + err: `expected expression` + err: `expected R_BRACK` + R_PAREN@[202; 203) + err: `expected SEMI` + WHITESPACE@[203; 204) + BLOCK_EXPR@[204; 346) + BLOCK@[204; 346) + L_CURLY@[204; 205) + WHITESPACE@[205; 214) + EXPR_STMT@[214; 340) + MACRO_CALL@[214; 339) + PATH@[214; 223) + PATH_SEGMENT@[214; 223) + NAME_REF@[214; 223) + IDENT@[214; 223) "assert_eq" + EXCL@[223; 224) + TOKEN_TREE@[224; 339) + L_PAREN@[224; 225) + WHITESPACE@[225; 238) + IDENT@[238; 253) "merge_use_trees" + TOKEN_TREE@[253; 284) + L_PAREN@[253; 254) + IDENT@[254; 269) "parse_use_trees" + EXCL@[269; 270) + TOKEN_TREE@[270; 283) + L_PAREN@[270; 271) + DOLLAR@[271; 272) + TOKEN_TREE@[272; 281) + L_PAREN@[272; 273) + DOLLAR@[273; 274) + IDENT@[274; 279) "input" + COMMA@[279; 280) + R_PAREN@[280; 281) + STAR@[281; 282) + R_PAREN@[282; 283) + R_PAREN@[283; 284) + COMMA@[284; 285) + WHITESPACE@[285; 298) + IDENT@[298; 313) "parse_use_trees" + EXCL@[313; 314) + TOKEN_TREE@[314; 328) + L_PAREN@[314; 315) + DOLLAR@[315; 316) + TOKEN_TREE@[316; 326) + L_PAREN@[316; 317) + DOLLAR@[317; 318) + IDENT@[318; 324) "output" + COMMA@[324; 325) + R_PAREN@[325; 326) + STAR@[326; 327) + R_PAREN@[327; 328) + COMMA@[328; 329) + WHITESPACE@[329; 338) + R_PAREN@[338; 339) + SEMI@[339; 340) + WHITESPACE@[340; 345) + R_CURLY@[345; 346) + WHITESPACE@[346; 347) + R_CURLY@[347; 348) + WHITESPACE@[348; 350) diff --git a/crates/libsyntax2/tests/data/parser/ok/0034_macro_stuck.txt b/crates/libsyntax2/tests/data/parser/ok/0034_macro_stuck.txt new file mode 100644 index 0000000000..1a8ca761dd --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/ok/0034_macro_stuck.txt @@ -0,0 +1,250 @@ +ROOT@[0; 350) + MACRO_CALL@[0; 41) + PATH@[0; 5) + PATH_SEGMENT@[0; 5) + NAME_REF@[0; 5) + IDENT@[0; 5) "macro" + err: `expected EXCL` + WHITESPACE@[5; 6) + IDENT@[6; 21) "parse_use_trees" + TOKEN_TREE@[21; 41) + L_PAREN@[21; 22) + DOLLAR@[22; 23) + TOKEN_TREE@[23; 32) + L_PAREN@[23; 24) + DOLLAR@[24; 25) + IDENT@[25; 26) "s" + COLON@[26; 27) + IDENT@[27; 31) "expr" + R_PAREN@[31; 32) + COMMA@[32; 33) + STAR@[33; 34) + WHITESPACE@[34; 35) + DOLLAR@[35; 36) + TOKEN_TREE@[36; 39) + L_PAREN@[36; 37) + COMMA@[37; 38) + R_PAREN@[38; 39) + STAR@[39; 40) + R_PAREN@[40; 41) + err: `expected SEMI` + WHITESPACE@[41; 42) + err: `expected an item` + ERROR@[42; 93) + L_CURLY@[42; 43) + WHITESPACE@[43; 48) + IDENT@[48; 51) "vec" + EXCL@[51; 52) + L_BRACK@[52; 53) + WHITESPACE@[53; 62) + DOLLAR@[62; 63) + L_PAREN@[63; 64) + IDENT@[64; 78) "parse_use_tree" + L_PAREN@[78; 79) + DOLLAR@[79; 80) + IDENT@[80; 81) "s" + R_PAREN@[81; 82) + COMMA@[82; 83) + R_PAREN@[83; 84) + STAR@[84; 85) + WHITESPACE@[85; 90) + R_BRACK@[90; 91) + WHITESPACE@[91; 92) + R_CURLY@[92; 93) + WHITESPACE@[93; 95) + FN_DEF@[95; 348) + ATTR@[95; 102) + POUND@[95; 96) + TOKEN_TREE@[96; 102) + L_BRACK@[96; 97) + IDENT@[97; 101) "test" + R_BRACK@[101; 102) + WHITESPACE@[102; 103) + FN_KW@[103; 105) + WHITESPACE@[105; 106) + NAME@[106; 125) + IDENT@[106; 125) "test_use_tree_merge" + PARAM_LIST@[125; 127) + L_PAREN@[125; 126) + R_PAREN@[126; 127) + WHITESPACE@[127; 128) + BLOCK@[128; 348) + L_CURLY@[128; 129) + WHITESPACE@[129; 134) + EXPR_STMT@[134; 139) + PATH_EXPR@[134; 139) + PATH@[134; 139) + PATH_SEGMENT@[134; 139) + NAME_REF@[134; 139) + IDENT@[134; 139) "macro" + err: `expected SEMI` + WHITESPACE@[139; 140) + EXPR_STMT@[140; 203) + CALL_EXPR@[140; 203) + PATH_EXPR@[140; 150) + PATH@[140; 150) + PATH_SEGMENT@[140; 150) + NAME_REF@[140; 150) + IDENT@[140; 150) "test_merge" + ARG_LIST@[150; 203) + L_PAREN@[150; 151) + ARRAY_EXPR@[151; 202) + L_BRACK@[151; 152) + err: `expected expression` + ERROR@[152; 153) + DOLLAR@[152; 153) + err: `expected COMMA` + TUPLE_EXPR@[153; 166) + L_PAREN@[153; 154) + err: `expected expression` + ERROR@[154; 155) + DOLLAR@[154; 155) + err: `expected COMMA` + PATH_EXPR@[155; 160) + PATH@[155; 160) + PATH_SEGMENT@[155; 160) + NAME_REF@[155; 160) + IDENT@[155; 160) "input" + err: `expected COMMA` + err: `expected expression` + ERROR@[160; 161) + COLON@[160; 161) + err: `expected COMMA` + PATH_EXPR@[161; 165) + PATH@[161; 165) + PATH_SEGMENT@[161; 165) + NAME_REF@[161; 165) + IDENT@[161; 165) "expr" + R_PAREN@[165; 166) + COMMA@[166; 167) + PREFIX_EXPR@[167; 170) + STAR@[167; 168) + WHITESPACE@[168; 169) + err: `expected expression` + ERROR@[169; 170) + DOLLAR@[169; 170) + err: `expected COMMA` + BIN_EXPR@[170; 175) + PAREN_EXPR@[170; 173) + L_PAREN@[170; 171) + err: `expected expression` + ERROR@[171; 172) + COMMA@[171; 172) + R_PAREN@[172; 173) + STAR@[173; 174) + err: `expected expression` + ERROR@[174; 175) + R_BRACK@[174; 175) + COMMA@[175; 176) + WHITESPACE@[176; 177) + ARRAY_EXPR@[177; 202) + L_BRACK@[177; 178) + err: `expected expression` + ERROR@[178; 179) + DOLLAR@[178; 179) + err: `expected COMMA` + TUPLE_EXPR@[179; 193) + L_PAREN@[179; 180) + err: `expected expression` + ERROR@[180; 181) + DOLLAR@[180; 181) + err: `expected COMMA` + PATH_EXPR@[181; 187) + PATH@[181; 187) + PATH_SEGMENT@[181; 187) + NAME_REF@[181; 187) + IDENT@[181; 187) "output" + err: `expected COMMA` + err: `expected expression` + ERROR@[187; 188) + COLON@[187; 188) + err: `expected COMMA` + PATH_EXPR@[188; 192) + PATH@[188; 192) + PATH_SEGMENT@[188; 192) + NAME_REF@[188; 192) + IDENT@[188; 192) "expr" + R_PAREN@[192; 193) + COMMA@[193; 194) + PREFIX_EXPR@[194; 197) + STAR@[194; 195) + WHITESPACE@[195; 196) + err: `expected expression` + ERROR@[196; 197) + DOLLAR@[196; 197) + err: `expected COMMA` + BIN_EXPR@[197; 202) + PAREN_EXPR@[197; 200) + L_PAREN@[197; 198) + err: `expected expression` + ERROR@[198; 199) + COMMA@[198; 199) + R_PAREN@[199; 200) + STAR@[200; 201) + err: `expected expression` + ERROR@[201; 202) + R_BRACK@[201; 202) + err: `expected COMMA` + err: `expected expression` + err: `expected R_BRACK` + err: `expected COMMA` + err: `expected expression` + err: `expected R_BRACK` + R_PAREN@[202; 203) + err: `expected SEMI` + WHITESPACE@[203; 204) + BLOCK_EXPR@[204; 346) + BLOCK@[204; 346) + L_CURLY@[204; 205) + WHITESPACE@[205; 214) + EXPR_STMT@[214; 340) + MACRO_CALL@[214; 339) + PATH@[214; 223) + PATH_SEGMENT@[214; 223) + NAME_REF@[214; 223) + IDENT@[214; 223) "assert_eq" + EXCL@[223; 224) + TOKEN_TREE@[224; 339) + L_PAREN@[224; 225) + WHITESPACE@[225; 238) + IDENT@[238; 253) "merge_use_trees" + TOKEN_TREE@[253; 284) + L_PAREN@[253; 254) + IDENT@[254; 269) "parse_use_trees" + EXCL@[269; 270) + TOKEN_TREE@[270; 283) + L_PAREN@[270; 271) + DOLLAR@[271; 272) + TOKEN_TREE@[272; 281) + L_PAREN@[272; 273) + DOLLAR@[273; 274) + IDENT@[274; 279) "input" + COMMA@[279; 280) + R_PAREN@[280; 281) + STAR@[281; 282) + R_PAREN@[282; 283) + R_PAREN@[283; 284) + COMMA@[284; 285) + WHITESPACE@[285; 298) + IDENT@[298; 313) "parse_use_trees" + EXCL@[313; 314) + TOKEN_TREE@[314; 328) + L_PAREN@[314; 315) + DOLLAR@[315; 316) + TOKEN_TREE@[316; 326) + L_PAREN@[316; 317) + DOLLAR@[317; 318) + IDENT@[318; 324) "output" + COMMA@[324; 325) + R_PAREN@[325; 326) + STAR@[326; 327) + R_PAREN@[327; 328) + COMMA@[328; 329) + WHITESPACE@[329; 338) + R_PAREN@[338; 339) + SEMI@[339; 340) + WHITESPACE@[340; 345) + R_CURLY@[345; 346) + WHITESPACE@[346; 347) + R_CURLY@[347; 348) + WHITESPACE@[348; 350)