about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2021-12-26 17:58:33 +0300
committerAleksey Kladov <aleksey.kladov@gmail.com>2021-12-26 17:58:33 +0300
commit0f74758fea243941f2555a056136a37c4e41c3dc (patch)
tree225531c952e0db9931e8945011cb52dd5ba3421a
parentf4cb0ff9bea204e7cd1744dea28ec447298a9df7 (diff)
downloadrust-0f74758fea243941f2555a056136a37c4e41c3dc.tar.gz
rust-0f74758fea243941f2555a056136a37c4e41c3dc.zip
internal: move outlined parser tests
-rw-r--r--crates/parser/src/tests.rs59
-rw-r--r--crates/parser/test_data/parser/err/0000_struct_field_missing_comma.rast (renamed from crates/syntax/test_data/parser/err/0000_struct_field_missing_comma.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0000_struct_field_missing_comma.rs (renamed from crates/syntax/test_data/parser/err/0000_struct_field_missing_comma.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0000_struct_field_missing_comma.txt34
-rw-r--r--crates/parser/test_data/parser/err/0001_item_recovery_in_file.rast (renamed from crates/syntax/test_data/parser/err/0001_item_recovery_in_file.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0001_item_recovery_in_file.rs (renamed from crates/syntax/test_data/parser/err/0001_item_recovery_in_file.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0001_item_recovery_in_file.txt18
-rw-r--r--crates/parser/test_data/parser/err/0002_duplicate_shebang.rast (renamed from crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0002_duplicate_shebang.rs (renamed from crates/syntax/test_data/parser/err/0002_duplicate_shebang.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0002_duplicate_shebang.txt45
-rw-r--r--crates/parser/test_data/parser/err/0003_C++_semicolon.rast (renamed from crates/syntax/test_data/parser/err/0003_C++_semicolon.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0003_C++_semicolon.rs (renamed from crates/syntax/test_data/parser/err/0003_C++_semicolon.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0003_C++_semicolon.txt39
-rw-r--r--crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast (renamed from crates/syntax/test_data/parser/err/0004_use_path_bad_segment.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0004_use_path_bad_segment.rs (renamed from crates/syntax/test_data/parser/err/0004_use_path_bad_segment.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0004_use_path_bad_segment.txt15
-rw-r--r--crates/parser/test_data/parser/err/0005_attribute_recover.rast (renamed from crates/syntax/test_data/parser/err/0005_attribute_recover.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0005_attribute_recover.rs (renamed from crates/syntax/test_data/parser/err/0005_attribute_recover.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0005_attribute_recover.txt62
-rw-r--r--crates/parser/test_data/parser/err/0006_named_field_recovery.rast (renamed from crates/syntax/test_data/parser/err/0006_named_field_recovery.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0006_named_field_recovery.rs (renamed from crates/syntax/test_data/parser/err/0006_named_field_recovery.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0006_named_field_recovery.txt74
-rw-r--r--crates/parser/test_data/parser/err/0007_stray_curly_in_file.rast (renamed from crates/syntax/test_data/parser/err/0007_stray_curly_in_file.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0007_stray_curly_in_file.rs (renamed from crates/syntax/test_data/parser/err/0007_stray_curly_in_file.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0007_stray_curly_in_file.txt33
-rw-r--r--crates/parser/test_data/parser/err/0008_item_block_recovery.rast (renamed from crates/syntax/test_data/parser/err/0008_item_block_recovery.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0008_item_block_recovery.rs (renamed from crates/syntax/test_data/parser/err/0008_item_block_recovery.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0008_item_block_recovery.txt81
-rw-r--r--crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.rast (renamed from crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.rs (renamed from crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.txt56
-rw-r--r--crates/parser/test_data/parser/err/0010_unsafe_lambda_block.rast (renamed from crates/syntax/test_data/parser/err/0010_unsafe_lambda_block.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0010_unsafe_lambda_block.rs (renamed from crates/syntax/test_data/parser/err/0010_unsafe_lambda_block.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0010_unsafe_lambda_block.txt45
-rw-r--r--crates/parser/test_data/parser/err/0011_extern_struct.rast (renamed from crates/syntax/test_data/parser/err/0011_extern_struct.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0011_extern_struct.rs (renamed from crates/syntax/test_data/parser/err/0011_extern_struct.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0011_extern_struct.txt13
-rw-r--r--crates/parser/test_data/parser/err/0012_broken_lambda.rast (renamed from crates/syntax/test_data/parser/err/0012_broken_lambda.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0013_invalid_type.rast (renamed from crates/syntax/test_data/parser/err/0013_invalid_type.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0013_invalid_type.rs (renamed from crates/syntax/test_data/parser/err/0013_invalid_type.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0013_invalid_type.txt89
-rw-r--r--crates/parser/test_data/parser/err/0014_where_no_bounds.rast (renamed from crates/syntax/test_data/parser/err/0014_where_no_bounds.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0014_where_no_bounds.rs (renamed from crates/syntax/test_data/parser/err/0014_where_no_bounds.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0014_where_no_bounds.txt32
-rw-r--r--crates/parser/test_data/parser/err/0015_curly_in_params.rast (renamed from crates/syntax/test_data/parser/err/0015_curly_in_params.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0015_curly_in_params.rs (renamed from crates/syntax/test_data/parser/err/0015_curly_in_params.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0015_curly_in_params.txt24
-rw-r--r--crates/parser/test_data/parser/err/0016_missing_semi.rast (renamed from crates/syntax/test_data/parser/err/0016_missing_semi.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0016_missing_semi.rs (renamed from crates/syntax/test_data/parser/err/0016_missing_semi.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0016_missing_semi.txt44
-rw-r--r--crates/parser/test_data/parser/err/0017_incomplete_binexpr.rast (renamed from crates/syntax/test_data/parser/err/0017_incomplete_binexpr.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0017_incomplete_binexpr.rs (renamed from crates/syntax/test_data/parser/err/0017_incomplete_binexpr.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0017_incomplete_binexpr.txt47
-rw-r--r--crates/parser/test_data/parser/err/0018_incomplete_fn.rast (renamed from crates/syntax/test_data/parser/err/0018_incomplete_fn.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0018_incomplete_fn.rs (renamed from crates/syntax/test_data/parser/err/0018_incomplete_fn.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0018_incomplete_fn.txt133
-rw-r--r--crates/parser/test_data/parser/err/0019_let_recover.rast (renamed from crates/syntax/test_data/parser/err/0019_let_recover.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0019_let_recover.rs (renamed from crates/syntax/test_data/parser/err/0019_let_recover.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0019_let_recover.txt107
-rw-r--r--crates/parser/test_data/parser/err/0020_fn_recover.rast (renamed from crates/syntax/test_data/parser/err/0020_fn_recover.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0020_fn_recover.rs (renamed from crates/syntax/test_data/parser/err/0020_fn_recover.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0020_fn_recover.txt21
-rw-r--r--crates/parser/test_data/parser/err/0021_incomplete_param.rast (renamed from crates/syntax/test_data/parser/err/0021_incomplete_param.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0021_incomplete_param.rs (renamed from crates/syntax/test_data/parser/err/0021_incomplete_param.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0021_incomplete_param.txt34
-rw-r--r--crates/parser/test_data/parser/err/0022_bad_exprs.rast (renamed from crates/syntax/test_data/parser/err/0022_bad_exprs.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0022_bad_exprs.rs (renamed from crates/syntax/test_data/parser/err/0022_bad_exprs.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0022_bad_exprs.txt171
-rw-r--r--crates/parser/test_data/parser/err/0023_mismatched_paren.rast (renamed from crates/syntax/test_data/parser/err/0023_mismatched_paren.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0023_mismatched_paren.rs (renamed from crates/syntax/test_data/parser/err/0023_mismatched_paren.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0023_mismatched_paren.txt44
-rw-r--r--crates/parser/test_data/parser/err/0024_many_type_parens.rast (renamed from crates/syntax/test_data/parser/err/0024_many_type_parens.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0024_many_type_parens.rs (renamed from crates/syntax/test_data/parser/err/0024_many_type_parens.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0024_many_type_parens.txt321
-rw-r--r--crates/parser/test_data/parser/err/0025_nope.rast (renamed from crates/syntax/test_data/parser/err/0025_nope.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0025_nope.rs (renamed from crates/syntax/test_data/parser/err/0025_nope.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0025_nope.txt204
-rw-r--r--crates/parser/test_data/parser/err/0026_imp_recovery.rast (renamed from crates/syntax/test_data/parser/err/0026_imp_recovery.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0026_imp_recovery.rs (renamed from crates/syntax/test_data/parser/err/0026_imp_recovery.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0026_imp_recovery.txt49
-rw-r--r--crates/parser/test_data/parser/err/0027_incomplere_where_for.rast (renamed from crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0027_incomplere_where_for.rs (renamed from crates/syntax/test_data/parser/err/0027_incomplere_where_for.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0027_incomplere_where_for.txt29
-rw-r--r--crates/parser/test_data/parser/err/0029_field_completion.rast (renamed from crates/syntax/test_data/parser/err/0029_field_completion.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0029_field_completion.rs (renamed from crates/syntax/test_data/parser/err/0029_field_completion.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0029_field_completion.txt36
-rw-r--r--crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast (renamed from crates/syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rs (renamed from crates/syntax/test_data/parser/err/0032_match_arms_inner_attrs.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.txt205
-rw-r--r--crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast (renamed from crates/syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rs (renamed from crates/syntax/test_data/parser/err/0033_match_arms_outer_attrs.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.txt68
-rw-r--r--crates/parser/test_data/parser/err/0034_bad_box_pattern.rast (renamed from crates/syntax/test_data/parser/err/0034_bad_box_pattern.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0034_bad_box_pattern.rs (renamed from crates/syntax/test_data/parser/err/0034_bad_box_pattern.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0034_bad_box_pattern.txt96
-rw-r--r--crates/parser/test_data/parser/err/0035_use_recover.rast (renamed from crates/syntax/test_data/parser/err/0035_use_recover.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0035_use_recover.rs (renamed from crates/syntax/test_data/parser/err/0035_use_recover.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0035_use_recover.txt55
-rw-r--r--crates/parser/test_data/parser/err/0036_partial_use.rast (renamed from crates/syntax/test_data/parser/err/0036_partial_use.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0036_partial_use.rs (renamed from crates/syntax/test_data/parser/err/0036_partial_use.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0036_partial_use.txt51
-rw-r--r--crates/parser/test_data/parser/err/0039_lambda_recovery.rast (renamed from crates/syntax/test_data/parser/err/0039_lambda_recovery.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0039_lambda_recovery.rs (renamed from crates/syntax/test_data/parser/err/0039_lambda_recovery.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0039_lambda_recovery.txt83
-rw-r--r--crates/parser/test_data/parser/err/0042_weird_blocks.rast (renamed from crates/syntax/test_data/parser/err/0042_weird_blocks.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0042_weird_blocks.rs (renamed from crates/syntax/test_data/parser/err/0042_weird_blocks.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0042_weird_blocks.txt75
-rw-r--r--crates/parser/test_data/parser/err/0043_unexpected_for_type.rast (renamed from crates/syntax/test_data/parser/err/0043_unexpected_for_type.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0043_unexpected_for_type.rs (renamed from crates/syntax/test_data/parser/err/0043_unexpected_for_type.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0043_unexpected_for_type.txt256
-rw-r--r--crates/parser/test_data/parser/err/0044_item_modifiers.rast (renamed from crates/syntax/test_data/parser/err/0044_item_modifiers.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0044_item_modifiers.rs (renamed from crates/syntax/test_data/parser/err/0044_item_modifiers.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0044_item_modifiers.txt48
-rw-r--r--crates/parser/test_data/parser/err/0047_repated_extern_modifier.rast (renamed from crates/syntax/test_data/parser/err/0047_repated_extern_modifier.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0047_repated_extern_modifier.rs (renamed from crates/syntax/test_data/parser/err/0047_repated_extern_modifier.rs)2
-rw-r--r--crates/parser/test_data/parser/err/0047_repated_extern_modifier.txt15
-rw-r--r--crates/parser/test_data/parser/err/0048_double_fish.rast (renamed from crates/syntax/test_data/parser/err/0048_double_fish.rast)0
-rw-r--r--crates/parser/test_data/parser/err/0048_double_fish.rs (renamed from crates/syntax/test_data/parser/err/0048_double_fish.rs)0
-rw-r--r--crates/parser/test_data/parser/err/0048_double_fish.txt123
-rw-r--r--crates/parser/test_data/parser/ok/0000_empty.rast (renamed from crates/syntax/test_data/parser/ok/0000_empty.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0000_empty.rs (renamed from crates/syntax/test_data/parser/ok/0000_empty.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0000_empty.txt1
-rw-r--r--crates/parser/test_data/parser/ok/0001_struct_item.rast (renamed from crates/syntax/test_data/parser/ok/0001_struct_item.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0001_struct_item.rs (renamed from crates/syntax/test_data/parser/ok/0001_struct_item.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0001_struct_item.txt39
-rw-r--r--crates/parser/test_data/parser/ok/0002_struct_item_field.rast (renamed from crates/syntax/test_data/parser/ok/0002_struct_item_field.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0002_struct_item_field.rs (renamed from crates/syntax/test_data/parser/ok/0002_struct_item_field.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0002_struct_item_field.txt22
-rw-r--r--crates/parser/test_data/parser/ok/0004_file_shebang.rast (renamed from crates/syntax/test_data/parser/ok/0004_file_shebang.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0004_file_shebang.rs (renamed from crates/syntax/test_data/parser/ok/0004_file_shebang.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0004_file_shebang.txt2
-rw-r--r--crates/parser/test_data/parser/ok/0005_fn_item.rast (renamed from crates/syntax/test_data/parser/ok/0005_fn_item.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0005_fn_item.rs (renamed from crates/syntax/test_data/parser/ok/0005_fn_item.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0005_fn_item.txt16
-rw-r--r--crates/parser/test_data/parser/ok/0006_inner_attributes.rast (renamed from crates/syntax/test_data/parser/ok/0006_inner_attributes.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0006_inner_attributes.rs (renamed from crates/syntax/test_data/parser/ok/0006_inner_attributes.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0006_inner_attributes.txt194
-rw-r--r--crates/parser/test_data/parser/ok/0007_extern_crate.rast (renamed from crates/syntax/test_data/parser/ok/0007_extern_crate.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0007_extern_crate.rs (renamed from crates/syntax/test_data/parser/ok/0007_extern_crate.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0007_extern_crate.txt40
-rw-r--r--crates/parser/test_data/parser/ok/0008_mod_item.rast (renamed from crates/syntax/test_data/parser/ok/0008_mod_item.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0008_mod_item.rs (renamed from crates/syntax/test_data/parser/ok/0008_mod_item.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0008_mod_item.txt77
-rw-r--r--crates/parser/test_data/parser/ok/0009_use_item.rast (renamed from crates/syntax/test_data/parser/ok/0009_use_item.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0009_use_item.rs (renamed from crates/syntax/test_data/parser/ok/0009_use_item.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0009_use_item.txt21
-rw-r--r--crates/parser/test_data/parser/ok/0010_use_path_segments.rast (renamed from crates/syntax/test_data/parser/ok/0010_use_path_segments.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0010_use_path_segments.rs (renamed from crates/syntax/test_data/parser/ok/0010_use_path_segments.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0010_use_path_segments.txt42
-rw-r--r--crates/parser/test_data/parser/ok/0011_outer_attribute.rast (renamed from crates/syntax/test_data/parser/ok/0011_outer_attribute.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0011_outer_attribute.rs (renamed from crates/syntax/test_data/parser/ok/0011_outer_attribute.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0011_outer_attribute.txt61
-rw-r--r--crates/parser/test_data/parser/ok/0012_visibility.rast (renamed from crates/syntax/test_data/parser/ok/0012_visibility.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0012_visibility.rs (renamed from crates/syntax/test_data/parser/ok/0012_visibility.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0012_visibility.txt133
-rw-r--r--crates/parser/test_data/parser/ok/0013_use_path_self_super.rast (renamed from crates/syntax/test_data/parser/ok/0013_use_path_self_super.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0013_use_path_self_super.rs (renamed from crates/syntax/test_data/parser/ok/0013_use_path_self_super.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0013_use_path_self_super.txt36
-rw-r--r--crates/parser/test_data/parser/ok/0014_use_tree.rast (renamed from crates/syntax/test_data/parser/ok/0014_use_tree.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0014_use_tree.rs (renamed from crates/syntax/test_data/parser/ok/0014_use_tree.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0014_use_tree.txt95
-rw-r--r--crates/parser/test_data/parser/ok/0015_use_tree.rast (renamed from crates/syntax/test_data/parser/ok/0015_use_tree.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0015_use_tree.rs (renamed from crates/syntax/test_data/parser/ok/0015_use_tree.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0015_use_tree.txt65
-rw-r--r--crates/parser/test_data/parser/ok/0016_struct_flavors.rast (renamed from crates/syntax/test_data/parser/ok/0016_struct_flavors.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0016_struct_flavors.rs (renamed from crates/syntax/test_data/parser/ok/0016_struct_flavors.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0016_struct_flavors.txt93
-rw-r--r--crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast (renamed from crates/syntax/test_data/parser/ok/0017_attr_trailing_comma.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rs (renamed from crates/syntax/test_data/parser/ok/0017_attr_trailing_comma.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0017_attr_trailing_comma.txt30
-rw-r--r--crates/parser/test_data/parser/ok/0018_struct_type_params.rast (renamed from crates/syntax/test_data/parser/ok/0018_struct_type_params.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0018_struct_type_params.rs (renamed from crates/syntax/test_data/parser/ok/0018_struct_type_params.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0018_struct_type_params.txt274
-rw-r--r--crates/parser/test_data/parser/ok/0019_enums.rast (renamed from crates/syntax/test_data/parser/ok/0019_enums.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0019_enums.rs (renamed from crates/syntax/test_data/parser/ok/0019_enums.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0019_enums.txt155
-rw-r--r--crates/parser/test_data/parser/ok/0020_type_param_bounds.rast (renamed from crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0020_type_param_bounds.rs (renamed from crates/syntax/test_data/parser/ok/0020_type_param_bounds.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0020_type_param_bounds.txt283
-rw-r--r--crates/parser/test_data/parser/ok/0022_empty_extern_block.rast (renamed from crates/syntax/test_data/parser/ok/0022_empty_extern_block.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0022_empty_extern_block.rs (renamed from crates/syntax/test_data/parser/ok/0022_empty_extern_block.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0022_empty_extern_block.txt21
-rw-r--r--crates/parser/test_data/parser/ok/0023_static_items.rast (renamed from crates/syntax/test_data/parser/ok/0023_static_items.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0023_static_items.rs (renamed from crates/syntax/test_data/parser/ok/0023_static_items.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0023_static_items.txt41
-rw-r--r--crates/parser/test_data/parser/ok/0024_const_item.rast (renamed from crates/syntax/test_data/parser/ok/0024_const_item.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0024_const_item.rs (renamed from crates/syntax/test_data/parser/ok/0024_const_item.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0024_const_item.txt1
-rw-r--r--crates/parser/test_data/parser/ok/0025_extern_fn_in_block.rast (renamed from crates/syntax/test_data/parser/ok/0025_extern_fn_in_block.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0025_extern_fn_in_block.rs (renamed from crates/syntax/test_data/parser/ok/0025_extern_fn_in_block.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0025_extern_fn_in_block.txt33
-rw-r--r--crates/parser/test_data/parser/ok/0026_const_fn_in_block.rast (renamed from crates/syntax/test_data/parser/ok/0026_const_fn_in_block.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0026_const_fn_in_block.rs (renamed from crates/syntax/test_data/parser/ok/0026_const_fn_in_block.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0026_const_fn_in_block.txt32
-rw-r--r--crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.rast (renamed from crates/syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.rs (renamed from crates/syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.txt43
-rw-r--r--crates/parser/test_data/parser/ok/0028_operator_binding_power.rast (renamed from crates/syntax/test_data/parser/ok/0028_operator_binding_power.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0028_operator_binding_power.rs (renamed from crates/syntax/test_data/parser/ok/0028_operator_binding_power.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0028_operator_binding_power.txt186
-rw-r--r--crates/parser/test_data/parser/ok/0029_range_forms.rast (renamed from crates/syntax/test_data/parser/ok/0029_range_forms.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0029_range_forms.rs (renamed from crates/syntax/test_data/parser/ok/0029_range_forms.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0029_range_forms.txt152
-rw-r--r--crates/parser/test_data/parser/ok/0030_string_suffixes.rast (renamed from crates/syntax/test_data/parser/ok/0030_string_suffixes.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0030_string_suffixes.rs (renamed from crates/syntax/test_data/parser/ok/0030_string_suffixes.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0030_string_suffixes.txt64
-rw-r--r--crates/parser/test_data/parser/ok/0030_traits.rast (renamed from crates/syntax/test_data/parser/ok/0030_traits.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0030_traits.rs (renamed from crates/syntax/test_data/parser/ok/0030_traits.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0030_traits.txt61
-rw-r--r--crates/parser/test_data/parser/ok/0031_extern.rast (renamed from crates/syntax/test_data/parser/ok/0031_extern.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0031_extern.rs (renamed from crates/syntax/test_data/parser/ok/0031_extern.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0031_extern.txt973
-rw-r--r--crates/parser/test_data/parser/ok/0032_where_for.rast (renamed from crates/syntax/test_data/parser/ok/0032_where_for.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0032_where_for.rs (renamed from crates/syntax/test_data/parser/ok/0032_where_for.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0032_where_for.txt93
-rw-r--r--crates/parser/test_data/parser/ok/0033_label_break.rast (renamed from crates/syntax/test_data/parser/ok/0033_label_break.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0033_label_break.rs (renamed from crates/syntax/test_data/parser/ok/0033_label_break.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0033_label_break.txt227
-rw-r--r--crates/parser/test_data/parser/ok/0034_crate_path_in_call.rast (renamed from crates/syntax/test_data/parser/ok/0034_crate_path_in_call.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0034_crate_path_in_call.rs (renamed from crates/syntax/test_data/parser/ok/0034_crate_path_in_call.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0034_crate_path_in_call.txt43
-rw-r--r--crates/parser/test_data/parser/ok/0035_weird_exprs.rast (renamed from crates/syntax/test_data/parser/ok/0035_weird_exprs.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0035_weird_exprs.rs (renamed from crates/syntax/test_data/parser/ok/0035_weird_exprs.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0035_weird_exprs.txt2337
-rw-r--r--crates/parser/test_data/parser/ok/0036_fully_qualified.rast (renamed from crates/syntax/test_data/parser/ok/0036_fully_qualified.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0036_fully_qualified.rs (renamed from crates/syntax/test_data/parser/ok/0036_fully_qualified.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0036_fully_qualified.txt93
-rw-r--r--crates/parser/test_data/parser/ok/0037_mod.rast (renamed from crates/syntax/test_data/parser/ok/0037_mod.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0037_mod.rs (renamed from crates/syntax/test_data/parser/ok/0037_mod.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0037_mod.txt16
-rw-r--r--crates/parser/test_data/parser/ok/0038_where_pred_type.rast (renamed from crates/syntax/test_data/parser/ok/0038_where_pred_type.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0038_where_pred_type.rs (renamed from crates/syntax/test_data/parser/ok/0038_where_pred_type.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0038_where_pred_type.txt43
-rw-r--r--crates/parser/test_data/parser/ok/0039_raw_fn_item.rast (renamed from crates/syntax/test_data/parser/ok/0039_raw_fn_item.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0039_raw_fn_item.rs (renamed from crates/syntax/test_data/parser/ok/0039_raw_fn_item.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0039_raw_fn_item.txt16
-rw-r--r--crates/parser/test_data/parser/ok/0040_raw_struct_item_field.rast (renamed from crates/syntax/test_data/parser/ok/0040_raw_struct_item_field.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0040_raw_struct_item_field.rs (renamed from crates/syntax/test_data/parser/ok/0040_raw_struct_item_field.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0040_raw_struct_item_field.txt22
-rw-r--r--crates/parser/test_data/parser/ok/0041_raw_keywords.rast (renamed from crates/syntax/test_data/parser/ok/0041_raw_keywords.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0041_raw_keywords.rs (renamed from crates/syntax/test_data/parser/ok/0041_raw_keywords.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0041_raw_keywords.txt50
-rw-r--r--crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast (renamed from crates/syntax/test_data/parser/ok/0042_ufcs_call_list.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0042_ufcs_call_list.rs (renamed from crates/syntax/test_data/parser/ok/0042_ufcs_call_list.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0042_ufcs_call_list.txt126
-rw-r--r--crates/parser/test_data/parser/ok/0043_complex_assignment.rast (renamed from crates/syntax/test_data/parser/ok/0043_complex_assignment.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0043_complex_assignment.rs (renamed from crates/syntax/test_data/parser/ok/0043_complex_assignment.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0043_complex_assignment.txt110
-rw-r--r--crates/parser/test_data/parser/ok/0044_let_attrs.rast (renamed from crates/syntax/test_data/parser/ok/0044_let_attrs.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0044_let_attrs.rs (renamed from crates/syntax/test_data/parser/ok/0044_let_attrs.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0044_let_attrs.txt77
-rw-r--r--crates/parser/test_data/parser/ok/0045_block_attrs.rast (renamed from crates/syntax/test_data/parser/ok/0045_block_attrs.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0045_block_attrs.rs (renamed from crates/syntax/test_data/parser/ok/0045_block_attrs.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0045_block_attrs.txt230
-rw-r--r--crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast (renamed from crates/syntax/test_data/parser/ok/0046_extern_inner_attributes.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rs (renamed from crates/syntax/test_data/parser/ok/0046_extern_inner_attributes.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0046_extern_inner_attributes.txt29
-rw-r--r--crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.rast (renamed from crates/syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.rs (renamed from crates/syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.txt323
-rw-r--r--crates/parser/test_data/parser/ok/0048_compound_assignment.rast (renamed from crates/syntax/test_data/parser/ok/0048_compound_assignment.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0048_compound_assignment.rs (renamed from crates/syntax/test_data/parser/ok/0048_compound_assignment.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0048_compound_assignment.txt201
-rw-r--r--crates/parser/test_data/parser/ok/0049_async_block.rast (renamed from crates/syntax/test_data/parser/ok/0049_async_block.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0049_async_block.rs (renamed from crates/syntax/test_data/parser/ok/0049_async_block.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0049_async_block.txt36
-rw-r--r--crates/parser/test_data/parser/ok/0050_async_block_as_argument.rast (renamed from crates/syntax/test_data/parser/ok/0050_async_block_as_argument.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0050_async_block_as_argument.rs (renamed from crates/syntax/test_data/parser/ok/0050_async_block_as_argument.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0050_async_block_as_argument.txt92
-rw-r--r--crates/parser/test_data/parser/ok/0051_parameter_attrs.rast (renamed from crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0051_parameter_attrs.rs (renamed from crates/syntax/test_data/parser/ok/0051_parameter_attrs.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0051_parameter_attrs.txt548
-rw-r--r--crates/parser/test_data/parser/ok/0052_for_range_block.rast (renamed from crates/syntax/test_data/parser/ok/0052_for_range_block.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0052_for_range_block.rs (renamed from crates/syntax/test_data/parser/ok/0052_for_range_block.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0052_for_range_block.txt81
-rw-r--r--crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast (renamed from crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rs (renamed from crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt37
-rw-r--r--crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast (renamed from crates/syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rs (renamed from crates/syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.txt126
-rw-r--r--crates/parser/test_data/parser/ok/0055_dot_dot_dot.rast (renamed from crates/syntax/test_data/parser/ok/0055_dot_dot_dot.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs (renamed from crates/syntax/test_data/parser/ok/0055_dot_dot_dot.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0055_dot_dot_dot.txt50
-rw-r--r--crates/parser/test_data/parser/ok/0056_neq_in_type.rast (renamed from crates/syntax/test_data/parser/ok/0056_neq_in_type.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0056_neq_in_type.rs (renamed from crates/syntax/test_data/parser/ok/0056_neq_in_type.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0056_neq_in_type.txt66
-rw-r--r--crates/parser/test_data/parser/ok/0057_loop_in_call.rast (renamed from crates/syntax/test_data/parser/ok/0057_loop_in_call.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0057_loop_in_call.rs (renamed from crates/syntax/test_data/parser/ok/0057_loop_in_call.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0057_loop_in_call.txt59
-rw-r--r--crates/parser/test_data/parser/ok/0058_unary_expr_precedence.rast (renamed from crates/syntax/test_data/parser/ok/0058_unary_expr_precedence.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0058_unary_expr_precedence.rs (renamed from crates/syntax/test_data/parser/ok/0058_unary_expr_precedence.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0058_unary_expr_precedence.txt97
-rw-r--r--crates/parser/test_data/parser/ok/0059_loops_in_parens.rast (renamed from crates/syntax/test_data/parser/ok/0059_loops_in_parens.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0059_loops_in_parens.rs (renamed from crates/syntax/test_data/parser/ok/0059_loops_in_parens.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0059_loops_in_parens.txt101
-rw-r--r--crates/parser/test_data/parser/ok/0060_as_range.rast (renamed from crates/syntax/test_data/parser/ok/0060_as_range.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0060_as_range.rs (renamed from crates/syntax/test_data/parser/ok/0060_as_range.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0060_as_range.txt56
-rw-r--r--crates/parser/test_data/parser/ok/0061_match_full_range.rast (renamed from crates/syntax/test_data/parser/ok/0061_match_full_range.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0061_match_full_range.rs (renamed from crates/syntax/test_data/parser/ok/0061_match_full_range.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0061_match_full_range.txt27
-rw-r--r--crates/parser/test_data/parser/ok/0062_macro_2.0.rast (renamed from crates/syntax/test_data/parser/ok/0062_macro_2.0.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0062_macro_2.0.rs (renamed from crates/syntax/test_data/parser/ok/0062_macro_2.0.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0062_macro_2.0.txt177
-rw-r--r--crates/parser/test_data/parser/ok/0063_trait_fn_patterns.rast (renamed from crates/syntax/test_data/parser/ok/0063_trait_fn_patterns.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0063_trait_fn_patterns.rs (renamed from crates/syntax/test_data/parser/ok/0063_trait_fn_patterns.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0063_trait_fn_patterns.txt198
-rw-r--r--crates/parser/test_data/parser/ok/0063_variadic_fun.rast (renamed from crates/syntax/test_data/parser/ok/0063_variadic_fun.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0063_variadic_fun.rs (renamed from crates/syntax/test_data/parser/ok/0063_variadic_fun.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0063_variadic_fun.txt134
-rw-r--r--crates/parser/test_data/parser/ok/0064_impl_fn_params.rast (renamed from crates/syntax/test_data/parser/ok/0064_impl_fn_params.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0064_impl_fn_params.rs (renamed from crates/syntax/test_data/parser/ok/0064_impl_fn_params.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0064_impl_fn_params.txt166
-rw-r--r--crates/parser/test_data/parser/ok/0065_comment_newline.rast (renamed from crates/syntax/test_data/parser/ok/0065_comment_newline.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0065_comment_newline.rs (renamed from crates/syntax/test_data/parser/ok/0065_comment_newline.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0065_comment_newline.txt17
-rw-r--r--crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast (renamed from crates/syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rs (renamed from crates/syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.txt61
-rw-r--r--crates/parser/test_data/parser/ok/0066_default_modifier.rast (renamed from crates/syntax/test_data/parser/ok/0066_default_modifier.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0066_default_modifier.rs (renamed from crates/syntax/test_data/parser/ok/0066_default_modifier.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0066_default_modifier.txt222
-rw-r--r--crates/parser/test_data/parser/ok/0067_where_for_pred.rast (renamed from crates/syntax/test_data/parser/ok/0067_where_for_pred.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0067_where_for_pred.rs (renamed from crates/syntax/test_data/parser/ok/0067_where_for_pred.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0067_where_for_pred.txt413
-rw-r--r--crates/parser/test_data/parser/ok/0068_item_modifiers.rast (renamed from crates/syntax/test_data/parser/ok/0068_item_modifiers.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0068_item_modifiers.rs (renamed from crates/syntax/test_data/parser/ok/0068_item_modifiers.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0068_item_modifiers.txt238
-rw-r--r--crates/parser/test_data/parser/ok/0069_multi_trait_object.rast (renamed from crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0069_multi_trait_object.rs (renamed from crates/syntax/test_data/parser/ok/0069_multi_trait_object.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0069_multi_trait_object.txt204
-rw-r--r--crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast (renamed from crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0070_expr_attr_placement.rs (renamed from crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0070_expr_attr_placement.txt59
-rw-r--r--crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast (renamed from crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rast)0
-rw-r--r--crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rs (renamed from crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rs)0
-rw-r--r--crates/parser/test_data/parser/ok/0071_stmt_attr_placement.txt71
-rw-r--r--crates/syntax/src/tests.rs19
-rw-r--r--crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast (renamed from crates/syntax/test_data/parser/err/0031_block_inner_attrs.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs (renamed from crates/syntax/test_data/parser/err/0031_block_inner_attrs.rs)0
-rw-r--r--crates/syntax/test_data/parser/validation/0037_visibility_in_traits.rast (renamed from crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0037_visibility_in_traits.rs (renamed from crates/syntax/test_data/parser/err/0037_visibility_in_traits.rs)0
-rw-r--r--crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rast (renamed from crates/syntax/test_data/parser/err/0038_endless_inclusive_range.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rs (renamed from crates/syntax/test_data/parser/err/0038_endless_inclusive_range.rs)0
-rw-r--r--crates/syntax/test_data/parser/validation/0040_illegal_crate_kw_location.rast (renamed from crates/syntax/test_data/parser/err/0040_illegal_crate_kw_location.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0040_illegal_crate_kw_location.rs (renamed from crates/syntax/test_data/parser/err/0040_illegal_crate_kw_location.rs)0
-rw-r--r--crates/syntax/test_data/parser/validation/0041_illegal_self_keyword_location.rast (renamed from crates/syntax/test_data/parser/err/0041_illegal_self_keyword_location.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0041_illegal_self_keyword_location.rs (renamed from crates/syntax/test_data/parser/err/0041_illegal_self_keyword_location.rs)0
-rw-r--r--crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rast (renamed from crates/syntax/test_data/parser/err/0045_ambiguous_trait_object.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs (renamed from crates/syntax/test_data/parser/err/0045_ambiguous_trait_object.rs)0
-rw-r--r--crates/syntax/test_data/parser/validation/0046_mutable_const_item.rast (renamed from crates/syntax/test_data/parser/err/0046_mutable_const_item.rast)0
-rw-r--r--crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs (renamed from crates/syntax/test_data/parser/err/0046_mutable_const_item.rs)0
353 files changed, 13703 insertions, 10 deletions
diff --git a/crates/parser/src/tests.rs b/crates/parser/src/tests.rs
index ebba9925618..f6f8742725f 100644
--- a/crates/parser/src/tests.rs
+++ b/crates/parser/src/tests.rs
@@ -9,7 +9,7 @@ use expect_test::expect_file;
 use crate::LexedStr;
 
 #[test]
-fn valid_lexes_input() {
+fn lex_valid() {
     for case in TestCase::list("lexer/ok") {
         let actual = lex(&case.text);
         expect_file![case.txt].assert_eq(&actual)
@@ -17,7 +17,7 @@ fn valid_lexes_input() {
 }
 
 #[test]
-fn invalid_lexes_input() {
+fn lex_invalid() {
     for case in TestCase::list("lexer/err") {
         let actual = lex(&case.text);
         expect_file![case.txt].assert_eq(&actual)
@@ -39,6 +39,61 @@ fn lex(text: &str) -> String {
     res
 }
 
+#[test]
+fn parse_valid() {
+    for case in TestCase::list("parser/ok") {
+        let (actual, errors) = parse(&case.text);
+        assert!(!errors, "errors in an OK file {}:\n{}", case.rs.display(), actual);
+        expect_file![case.txt].assert_eq(&actual);
+    }
+}
+
+#[test]
+fn parse_invalid() {
+    for case in TestCase::list("parser/err") {
+        let (actual, errors) = parse(&case.text);
+        assert!(errors, "no errors in an ERR file {}:\n{}", case.rs.display(), actual);
+        expect_file![case.txt].assert_eq(&actual)
+    }
+}
+
+fn parse(text: &str) -> (String, bool) {
+    let lexed = LexedStr::new(text);
+    let input = lexed.to_input();
+    let output = crate::parse_source_file(&input);
+
+    let mut buf = String::new();
+    let mut errors = Vec::new();
+    let mut indent = String::new();
+    lexed.intersperse_trivia(&output, false, &mut |step| match step {
+        crate::StrStep::Token { kind, text } => {
+            write!(buf, "{}", indent).unwrap();
+            write!(buf, "{:?} {:?}\n", kind, text).unwrap();
+        }
+        crate::StrStep::Enter { kind } => {
+            write!(buf, "{}", indent).unwrap();
+            write!(buf, "{:?}\n", kind).unwrap();
+            indent.push_str("  ");
+        }
+        crate::StrStep::Exit => {
+            indent.pop();
+            indent.pop();
+        }
+        crate::StrStep::Error { msg, pos } => errors.push(format!("error {}: {}\n", pos, msg)),
+    });
+
+    for (token, msg) in lexed.errors() {
+        let pos = lexed.text_start(token);
+        errors.push(format!("error {}: {}\n", pos, msg));
+    }
+
+    let has_errors = !errors.is_empty();
+    for e in errors {
+        buf.push_str(&e);
+    }
+    (buf, has_errors)
+}
+
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 struct TestCase {
     rs: PathBuf,
diff --git a/crates/syntax/test_data/parser/err/0000_struct_field_missing_comma.rast b/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.rast
index bbbf496c82d..bbbf496c82d 100644
--- a/crates/syntax/test_data/parser/err/0000_struct_field_missing_comma.rast
+++ b/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.rast
diff --git a/crates/syntax/test_data/parser/err/0000_struct_field_missing_comma.rs b/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.rs
index fe5030d893f..fe5030d893f 100644
--- a/crates/syntax/test_data/parser/err/0000_struct_field_missing_comma.rs
+++ b/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.rs
diff --git a/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.txt b/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.txt
new file mode 100644
index 00000000000..b30328c8270
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0000_struct_field_missing_comma.txt
@@ -0,0 +1,34 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "a"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "b"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE "\n"
+      R_CURLY "}"
+error 21: expected COMMA
diff --git a/crates/syntax/test_data/parser/err/0001_item_recovery_in_file.rast b/crates/parser/test_data/parser/err/0001_item_recovery_in_file.rast
index 6dc73bfdbae..6dc73bfdbae 100644
--- a/crates/syntax/test_data/parser/err/0001_item_recovery_in_file.rast
+++ b/crates/parser/test_data/parser/err/0001_item_recovery_in_file.rast
diff --git a/crates/syntax/test_data/parser/err/0001_item_recovery_in_file.rs b/crates/parser/test_data/parser/err/0001_item_recovery_in_file.rs
index 98f23de1f22..98f23de1f22 100644
--- a/crates/syntax/test_data/parser/err/0001_item_recovery_in_file.rs
+++ b/crates/parser/test_data/parser/err/0001_item_recovery_in_file.rs
diff --git a/crates/parser/test_data/parser/err/0001_item_recovery_in_file.txt b/crates/parser/test_data/parser/err/0001_item_recovery_in_file.txt
new file mode 100644
index 00000000000..959b87ebbc5
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0001_item_recovery_in_file.txt
@@ -0,0 +1,18 @@
+SOURCE_FILE
+  ERROR
+    IF_KW "if"
+  WHITESPACE " "
+  ERROR
+    MATCH_KW "match"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+error 0: expected an item
+error 3: expected an item
diff --git a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast b/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast
index 9ad5b12b8b8..9ad5b12b8b8 100644
--- a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast
+++ b/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast
diff --git a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rs b/crates/parser/test_data/parser/err/0002_duplicate_shebang.rs
index 48a3a3980ba..48a3a3980ba 100644
--- a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rs
+++ b/crates/parser/test_data/parser/err/0002_duplicate_shebang.rs
diff --git a/crates/parser/test_data/parser/err/0002_duplicate_shebang.txt b/crates/parser/test_data/parser/err/0002_duplicate_shebang.txt
new file mode 100644
index 00000000000..ec6c3151005
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0002_duplicate_shebang.txt
@@ -0,0 +1,45 @@
+SOURCE_FILE
+  SHEBANG "#!/use/bin/env rusti"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+  ERROR
+    SLASH "/"
+  USE
+    USE_KW "use"
+    ERROR
+      SLASH "/"
+  MACRO_CALL
+    PATH
+      PATH_SEGMENT
+        NAME_REF
+          IDENT "bin"
+  ERROR
+    SLASH "/"
+  MACRO_CALL
+    PATH
+      PATH_SEGMENT
+        NAME_REF
+          IDENT "env"
+  WHITESPACE " "
+  MACRO_CALL
+    PATH
+      PATH_SEGMENT
+        NAME_REF
+          IDENT "rusti"
+  WHITESPACE "\n"
+error 23: expected `[`
+error 23: expected an item
+error 27: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 28: expected SEMICOLON
+error 31: expected BANG
+error 31: expected `{`, `[`, `(`
+error 31: expected SEMICOLON
+error 31: expected an item
+error 35: expected BANG
+error 35: expected `{`, `[`, `(`
+error 35: expected SEMICOLON
+error 41: expected BANG
+error 41: expected `{`, `[`, `(`
+error 41: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0003_C++_semicolon.rast b/crates/parser/test_data/parser/err/0003_C++_semicolon.rast
index 7763fad840b..7763fad840b 100644
--- a/crates/syntax/test_data/parser/err/0003_C++_semicolon.rast
+++ b/crates/parser/test_data/parser/err/0003_C++_semicolon.rast
diff --git a/crates/syntax/test_data/parser/err/0003_C++_semicolon.rs b/crates/parser/test_data/parser/err/0003_C++_semicolon.rs
index 009312270fe..009312270fe 100644
--- a/crates/syntax/test_data/parser/err/0003_C++_semicolon.rs
+++ b/crates/parser/test_data/parser/err/0003_C++_semicolon.rs
diff --git a/crates/parser/test_data/parser/err/0003_C++_semicolon.txt b/crates/parser/test_data/parser/err/0003_C++_semicolon.txt
new file mode 100644
index 00000000000..00131bea51d
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0003_C++_semicolon.txt
@@ -0,0 +1,39 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "a"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "i32"
+      COMMA ","
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "b"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "String"
+      COMMA ","
+      WHITESPACE "\n"
+      R_CURLY "}"
+  ERROR
+    SEMICOLON ";"
+error 39: expected item, found `;`
+consider removing this semicolon
diff --git a/crates/syntax/test_data/parser/err/0004_use_path_bad_segment.rast b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
index 9a0f4665efc..9a0f4665efc 100644
--- a/crates/syntax/test_data/parser/err/0004_use_path_bad_segment.rast
+++ b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
diff --git a/crates/syntax/test_data/parser/err/0004_use_path_bad_segment.rs b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rs
index 060e65d06d2..060e65d06d2 100644
--- a/crates/syntax/test_data/parser/err/0004_use_path_bad_segment.rs
+++ b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rs
diff --git a/crates/parser/test_data/parser/err/0004_use_path_bad_segment.txt b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.txt
new file mode 100644
index 00000000000..44e192a5fcb
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.txt
@@ -0,0 +1,15 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "foo"
+        COLON2 "::"
+        ERROR
+          INT_NUMBER "92"
+    SEMICOLON ";"
+error 9: expected identifier
diff --git a/crates/syntax/test_data/parser/err/0005_attribute_recover.rast b/crates/parser/test_data/parser/err/0005_attribute_recover.rast
index 44dcc58a926..44dcc58a926 100644
--- a/crates/syntax/test_data/parser/err/0005_attribute_recover.rast
+++ b/crates/parser/test_data/parser/err/0005_attribute_recover.rast
diff --git a/crates/syntax/test_data/parser/err/0005_attribute_recover.rs b/crates/parser/test_data/parser/err/0005_attribute_recover.rs
index de7f8162839..de7f8162839 100644
--- a/crates/syntax/test_data/parser/err/0005_attribute_recover.rs
+++ b/crates/parser/test_data/parser/err/0005_attribute_recover.rs
diff --git a/crates/parser/test_data/parser/err/0005_attribute_recover.txt b/crates/parser/test_data/parser/err/0005_attribute_recover.txt
new file mode 100644
index 00000000000..6ff072e207c
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0005_attribute_recover.txt
@@ -0,0 +1,62 @@
+SOURCE_FILE
+  FN
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "foo"
+        TOKEN_TREE
+          L_PAREN "("
+          IDENT "foo"
+          COMMA ","
+          WHITESPACE " "
+          PLUS "+"
+          COMMA ","
+          WHITESPACE " "
+          INT_NUMBER "92"
+          R_PAREN ")"
+      R_BRACK "]"
+    WHITESPACE "\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n\n"
+  ATTR
+    POUND "#"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+      TOKEN_TREE
+        L_PAREN "("
+        WHITESPACE "\n"
+        FN_KW "fn"
+        WHITESPACE " "
+        IDENT "foo"
+        TOKEN_TREE
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        TOKEN_TREE
+          L_CURLY "{"
+          WHITESPACE "\n"
+          R_CURLY "}"
+  WHITESPACE "\n"
+error 53: expected R_PAREN
+error 53: expected `]`
+error 53: expected an item
diff --git a/crates/syntax/test_data/parser/err/0006_named_field_recovery.rast b/crates/parser/test_data/parser/err/0006_named_field_recovery.rast
index 5f85c3943ab..5f85c3943ab 100644
--- a/crates/syntax/test_data/parser/err/0006_named_field_recovery.rast
+++ b/crates/parser/test_data/parser/err/0006_named_field_recovery.rast
diff --git a/crates/syntax/test_data/parser/err/0006_named_field_recovery.rs b/crates/parser/test_data/parser/err/0006_named_field_recovery.rs
index 8069c111b4b..8069c111b4b 100644
--- a/crates/syntax/test_data/parser/err/0006_named_field_recovery.rs
+++ b/crates/parser/test_data/parser/err/0006_named_field_recovery.rs
diff --git a/crates/parser/test_data/parser/err/0006_named_field_recovery.txt b/crates/parser/test_data/parser/err/0006_named_field_recovery.txt
new file mode 100644
index 00000000000..7a4aa93b246
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0006_named_field_recovery.txt
@@ -0,0 +1,74 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "f"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      COMMA ","
+      WHITESPACE "\n    "
+      VISIBILITY
+        PUB_KW "pub"
+      WHITESPACE " "
+      ERROR
+        INT_NUMBER "92"
+      WHITESPACE "\n    "
+      ERROR
+        PLUS "+"
+      WHITESPACE " "
+      ERROR
+        MINUS "-"
+      WHITESPACE " "
+      ERROR
+        STAR "*"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        NAME
+          IDENT "x"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      COMMA ","
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "z"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "f64"
+      COMMA ","
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
+error 31: expected field declaration
+error 33: expected COMMA
+error 38: expected field declaration
+error 39: expected COMMA
+error 40: expected field declaration
+error 41: expected COMMA
+error 42: expected field declaration
+error 43: expected COMMA
diff --git a/crates/syntax/test_data/parser/err/0007_stray_curly_in_file.rast b/crates/parser/test_data/parser/err/0007_stray_curly_in_file.rast
index c57ea77364e..c57ea77364e 100644
--- a/crates/syntax/test_data/parser/err/0007_stray_curly_in_file.rast
+++ b/crates/parser/test_data/parser/err/0007_stray_curly_in_file.rast
diff --git a/crates/syntax/test_data/parser/err/0007_stray_curly_in_file.rs b/crates/parser/test_data/parser/err/0007_stray_curly_in_file.rs
index dc869fb785e..dc869fb785e 100644
--- a/crates/syntax/test_data/parser/err/0007_stray_curly_in_file.rs
+++ b/crates/parser/test_data/parser/err/0007_stray_curly_in_file.rs
diff --git a/crates/parser/test_data/parser/err/0007_stray_curly_in_file.txt b/crates/parser/test_data/parser/err/0007_stray_curly_in_file.txt
new file mode 100644
index 00000000000..5d87ff866b2
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0007_stray_curly_in_file.txt
@@ -0,0 +1,33 @@
+SOURCE_FILE
+  ERROR
+    R_CURLY "}"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+  ERROR
+    R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  ERROR
+    R_CURLY "}"
+  WHITESPACE "\n"
+error 0: unmatched `}`
+error 14: unmatched `}`
+error 29: unmatched `}`
diff --git a/crates/syntax/test_data/parser/err/0008_item_block_recovery.rast b/crates/parser/test_data/parser/err/0008_item_block_recovery.rast
index 99ec2faed00..99ec2faed00 100644
--- a/crates/syntax/test_data/parser/err/0008_item_block_recovery.rast
+++ b/crates/parser/test_data/parser/err/0008_item_block_recovery.rast
diff --git a/crates/syntax/test_data/parser/err/0008_item_block_recovery.rs b/crates/parser/test_data/parser/err/0008_item_block_recovery.rs
index 9fcac19b5ce..9fcac19b5ce 100644
--- a/crates/syntax/test_data/parser/err/0008_item_block_recovery.rs
+++ b/crates/parser/test_data/parser/err/0008_item_block_recovery.rs
diff --git a/crates/parser/test_data/parser/err/0008_item_block_recovery.txt b/crates/parser/test_data/parser/err/0008_item_block_recovery.txt
new file mode 100644
index 00000000000..6dd70e7cd9b
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0008_item_block_recovery.txt
@@ -0,0 +1,81 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  MACRO_CALL
+    PATH
+      PATH_SEGMENT
+        NAME_REF
+          IDENT "bar"
+    TOKEN_TREE
+      L_PAREN "("
+      R_PAREN ")"
+  WHITESPACE " "
+  ERROR
+    L_CURLY "{"
+    WHITESPACE "\n    "
+    IF_EXPR
+      IF_KW "if"
+      WHITESPACE " "
+      CONDITION
+        LITERAL
+          TRUE_KW "true"
+      WHITESPACE " "
+      BLOCK_EXPR
+        STMT_LIST
+          L_CURLY "{"
+          WHITESPACE "\n        "
+          LITERAL
+            INT_NUMBER "1"
+          WHITESPACE "\n    "
+          R_CURLY "}"
+      WHITESPACE " "
+      ELSE_KW "else"
+      WHITESPACE " "
+      BLOCK_EXPR
+        STMT_LIST
+          L_CURLY "{"
+          WHITESPACE "\n        "
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "2"
+            WHITESPACE " "
+            PLUS "+"
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "3"
+          WHITESPACE "\n    "
+          R_CURLY "}"
+    WHITESPACE "\n"
+    R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "baz"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 17: expected BANG
+error 19: expected SEMICOLON
+error 20: expected an item
diff --git a/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast b/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.rast
index 2d4c689c7c6..2d4c689c7c6 100644
--- a/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast
+++ b/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.rast
diff --git a/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rs b/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.rs
index 0dd30d0bd68..0dd30d0bd68 100644
--- a/crates/syntax/test_data/parser/err/0009_broken_struct_type_parameter.rs
+++ b/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.rs
diff --git a/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.txt b/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.txt
new file mode 100644
index 00000000000..a0154321718
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0009_broken_struct_type_parameter.txt
@@ -0,0 +1,56 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      ERROR
+        INT_NUMBER "90"
+  WHITESPACE " "
+  ERROR
+    PLUS "+"
+  WHITESPACE " "
+  ERROR
+    INT_NUMBER "2"
+  ERROR
+    R_ANGLE ">"
+  WHITESPACE " "
+  ERROR
+    L_CURLY "{"
+    WHITESPACE "\n    "
+    EXPR_STMT
+      PATH_EXPR
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "f"
+    ERROR
+      COLON ":"
+    WHITESPACE " "
+    PATH_EXPR
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "u32"
+    WHITESPACE "\n"
+    R_CURLY "}"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+error 9: expected type parameter
+error 11: expected COMMA
+error 11: expected R_ANGLE
+error 11: expected `;`, `{`, or `(`
+error 12: expected an item
+error 14: expected an item
+error 15: expected an item
+error 17: expected an item
+error 24: expected SEMICOLON
+error 24: expected expression
diff --git a/crates/syntax/test_data/parser/err/0010_unsafe_lambda_block.rast b/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.rast
index 586acc73296..586acc73296 100644
--- a/crates/syntax/test_data/parser/err/0010_unsafe_lambda_block.rast
+++ b/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.rast
diff --git a/crates/syntax/test_data/parser/err/0010_unsafe_lambda_block.rs b/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.rs
index 9857752824a..9857752824a 100644
--- a/crates/syntax/test_data/parser/err/0010_unsafe_lambda_block.rs
+++ b/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.rs
diff --git a/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.txt b/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.txt
new file mode 100644
index 00000000000..9427ee5c0e5
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0010_unsafe_lambda_block.txt
@@ -0,0 +1,45 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CLOSURE_EXPR
+            PARAM_LIST
+              PIPE "|"
+              PIPE "|"
+            WHITESPACE " "
+            RET_TYPE
+              THIN_ARROW "->"
+              WHITESPACE " "
+              TUPLE_TYPE
+                L_PAREN "("
+                R_PAREN ")"
+        WHITESPACE " "
+        EXPR_STMT
+          BLOCK_EXPR
+            UNSAFE_KW "unsafe"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              TUPLE_EXPR
+                L_PAREN "("
+                R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 24: expected a block
+error 24: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0011_extern_struct.rast b/crates/parser/test_data/parser/err/0011_extern_struct.rast
index b02d390af9b..b02d390af9b 100644
--- a/crates/syntax/test_data/parser/err/0011_extern_struct.rast
+++ b/crates/parser/test_data/parser/err/0011_extern_struct.rast
diff --git a/crates/syntax/test_data/parser/err/0011_extern_struct.rs b/crates/parser/test_data/parser/err/0011_extern_struct.rs
index c1bd0a2d1be..c1bd0a2d1be 100644
--- a/crates/syntax/test_data/parser/err/0011_extern_struct.rs
+++ b/crates/parser/test_data/parser/err/0011_extern_struct.rs
diff --git a/crates/parser/test_data/parser/err/0011_extern_struct.txt b/crates/parser/test_data/parser/err/0011_extern_struct.txt
new file mode 100644
index 00000000000..bd5ec4b7c29
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0011_extern_struct.txt
@@ -0,0 +1,13 @@
+SOURCE_FILE
+  ERROR
+    ABI
+      EXTERN_KW "extern"
+  WHITESPACE " "
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "Foo"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+error 6: expected existential, fn, trait or impl
diff --git a/crates/syntax/test_data/parser/err/0012_broken_lambda.rast b/crates/parser/test_data/parser/err/0012_broken_lambda.rast
index f31c2763398..f31c2763398 100644
--- a/crates/syntax/test_data/parser/err/0012_broken_lambda.rast
+++ b/crates/parser/test_data/parser/err/0012_broken_lambda.rast
diff --git a/crates/syntax/test_data/parser/err/0013_invalid_type.rast b/crates/parser/test_data/parser/err/0013_invalid_type.rast
index f48ab6e7124..f48ab6e7124 100644
--- a/crates/syntax/test_data/parser/err/0013_invalid_type.rast
+++ b/crates/parser/test_data/parser/err/0013_invalid_type.rast
diff --git a/crates/syntax/test_data/parser/err/0013_invalid_type.rs b/crates/parser/test_data/parser/err/0013_invalid_type.rs
index 20dde3bc30f..20dde3bc30f 100644
--- a/crates/syntax/test_data/parser/err/0013_invalid_type.rs
+++ b/crates/parser/test_data/parser/err/0013_invalid_type.rs
diff --git a/crates/parser/test_data/parser/err/0013_invalid_type.txt b/crates/parser/test_data/parser/err/0013_invalid_type.txt
new file mode 100644
index 00000000000..eec84a0c67d
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0013_invalid_type.txt
@@ -0,0 +1,89 @@
+SOURCE_FILE
+  STRUCT
+    VISIBILITY
+      PUB_KW "pub"
+    WHITESPACE " "
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "Cache"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      WHITESPACE "\n    "
+      TUPLE_FIELD
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "RefCell"
+              GENERIC_ARG_LIST
+                L_ANGLE "<"
+                TYPE_ARG
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "HashMap"
+                        GENERIC_ARG_LIST
+                          L_ANGLE "<"
+                          WHITESPACE "\n        "
+                          TYPE_ARG
+                            PATH_TYPE
+                              PATH
+                                PATH_SEGMENT
+                                  NAME_REF
+                                    IDENT "TypeId"
+                          COMMA ","
+                          WHITESPACE "\n        "
+                          TYPE_ARG
+                            PATH_TYPE
+                              PATH
+                                PATH_SEGMENT
+                                  NAME_REF
+                                    IDENT "Box"
+                                  GENERIC_ARG_LIST
+                                    L_ANGLE "<"
+                                    TYPE_ARG
+                                      ERROR
+                                        AT "@"
+      WHITESPACE " "
+      TUPLE_FIELD
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Any"
+      ERROR
+  ERROR
+    R_ANGLE ">"
+  ERROR
+    COMMA ","
+  WHITESPACE "\n    "
+  ERROR
+    R_ANGLE ">"
+  ERROR
+    R_ANGLE ">"
+  WHITESPACE "\n"
+  ERROR
+    R_PAREN ")"
+  ERROR
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+error 67: expected type
+error 68: expected COMMA
+error 68: expected R_ANGLE
+error 68: expected COMMA
+error 68: expected R_ANGLE
+error 68: expected COMMA
+error 68: expected R_ANGLE
+error 68: expected COMMA
+error 72: expected COMMA
+error 72: expected a type
+error 72: expected R_PAREN
+error 72: expected SEMICOLON
+error 72: expected an item
+error 73: expected an item
+error 79: expected an item
+error 80: expected an item
+error 82: expected an item
+error 83: expected an item
diff --git a/crates/syntax/test_data/parser/err/0014_where_no_bounds.rast b/crates/parser/test_data/parser/err/0014_where_no_bounds.rast
index 9178cf3b7f1..9178cf3b7f1 100644
--- a/crates/syntax/test_data/parser/err/0014_where_no_bounds.rast
+++ b/crates/parser/test_data/parser/err/0014_where_no_bounds.rast
diff --git a/crates/syntax/test_data/parser/err/0014_where_no_bounds.rs b/crates/parser/test_data/parser/err/0014_where_no_bounds.rs
index 75c1d2f9861..75c1d2f9861 100644
--- a/crates/syntax/test_data/parser/err/0014_where_no_bounds.rs
+++ b/crates/parser/test_data/parser/err/0014_where_no_bounds.rs
diff --git a/crates/parser/test_data/parser/err/0014_where_no_bounds.txt b/crates/parser/test_data/parser/err/0014_where_no_bounds.txt
new file mode 100644
index 00000000000..fd2f9ada33d
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0014_where_no_bounds.txt
@@ -0,0 +1,32 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE " "
+      WHERE_PRED
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "T"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 19: expected colon
diff --git a/crates/syntax/test_data/parser/err/0015_curly_in_params.rast b/crates/parser/test_data/parser/err/0015_curly_in_params.rast
index a3c25b450a9..a3c25b450a9 100644
--- a/crates/syntax/test_data/parser/err/0015_curly_in_params.rast
+++ b/crates/parser/test_data/parser/err/0015_curly_in_params.rast
diff --git a/crates/syntax/test_data/parser/err/0015_curly_in_params.rs b/crates/parser/test_data/parser/err/0015_curly_in_params.rs
index 156e70251a1..156e70251a1 100644
--- a/crates/syntax/test_data/parser/err/0015_curly_in_params.rs
+++ b/crates/parser/test_data/parser/err/0015_curly_in_params.rs
diff --git a/crates/parser/test_data/parser/err/0015_curly_in_params.txt b/crates/parser/test_data/parser/err/0015_curly_in_params.txt
new file mode 100644
index 00000000000..8e169320d95
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0015_curly_in_params.txt
@@ -0,0 +1,24 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+  ERROR
+    R_CURLY "}"
+  ERROR
+    R_PAREN ")"
+  WHITESPACE " "
+  ERROR
+    L_CURLY "{"
+    WHITESPACE "\n"
+    R_CURLY "}"
+  WHITESPACE "\n"
+error 7: expected value parameter
+error 7: expected R_PAREN
+error 7: expected a block
+error 7: unmatched `}`
+error 8: expected an item
+error 10: expected an item
diff --git a/crates/syntax/test_data/parser/err/0016_missing_semi.rast b/crates/parser/test_data/parser/err/0016_missing_semi.rast
index 30e76de8340..30e76de8340 100644
--- a/crates/syntax/test_data/parser/err/0016_missing_semi.rast
+++ b/crates/parser/test_data/parser/err/0016_missing_semi.rast
diff --git a/crates/syntax/test_data/parser/err/0016_missing_semi.rs b/crates/parser/test_data/parser/err/0016_missing_semi.rs
index 9ae85768619..9ae85768619 100644
--- a/crates/syntax/test_data/parser/err/0016_missing_semi.rs
+++ b/crates/parser/test_data/parser/err/0016_missing_semi.rs
diff --git a/crates/parser/test_data/parser/err/0016_missing_semi.txt b/crates/parser/test_data/parser/err/0016_missing_semi.txt
new file mode 100644
index 00000000000..c48c35bf822
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0016_missing_semi.txt
@@ -0,0 +1,44 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "foo"
+            ARG_LIST
+              L_PAREN "("
+              WHITESPACE "\n        "
+              LITERAL
+                INT_NUMBER "1"
+              COMMA ","
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE "\n    "
+              R_PAREN ")"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RETURN_EXPR
+            RETURN_KW "return"
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "92"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 38: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0017_incomplete_binexpr.rast b/crates/parser/test_data/parser/err/0017_incomplete_binexpr.rast
index 9d2c7c69482..9d2c7c69482 100644
--- a/crates/syntax/test_data/parser/err/0017_incomplete_binexpr.rast
+++ b/crates/parser/test_data/parser/err/0017_incomplete_binexpr.rast
diff --git a/crates/syntax/test_data/parser/err/0017_incomplete_binexpr.rs b/crates/parser/test_data/parser/err/0017_incomplete_binexpr.rs
index 17bd4977777..17bd4977777 100644
--- a/crates/syntax/test_data/parser/err/0017_incomplete_binexpr.rs
+++ b/crates/parser/test_data/parser/err/0017_incomplete_binexpr.rs
diff --git a/crates/parser/test_data/parser/err/0017_incomplete_binexpr.txt b/crates/parser/test_data/parser/err/0017_incomplete_binexpr.txt
new file mode 100644
index 00000000000..80735646290
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0017_incomplete_binexpr.txt
@@ -0,0 +1,47 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "foo"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "i32"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "bar"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "92"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        BIN_EXPR
+          LITERAL
+            INT_NUMBER "1"
+          WHITESPACE " "
+          PLUS "+"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 44: expected expression
diff --git a/crates/syntax/test_data/parser/err/0018_incomplete_fn.rast b/crates/parser/test_data/parser/err/0018_incomplete_fn.rast
index 55ac5bc62ad..55ac5bc62ad 100644
--- a/crates/syntax/test_data/parser/err/0018_incomplete_fn.rast
+++ b/crates/parser/test_data/parser/err/0018_incomplete_fn.rast
diff --git a/crates/syntax/test_data/parser/err/0018_incomplete_fn.rs b/crates/parser/test_data/parser/err/0018_incomplete_fn.rs
index fe604006c9e..fe604006c9e 100644
--- a/crates/syntax/test_data/parser/err/0018_incomplete_fn.rs
+++ b/crates/parser/test_data/parser/err/0018_incomplete_fn.rs
diff --git a/crates/parser/test_data/parser/err/0018_incomplete_fn.txt b/crates/parser/test_data/parser/err/0018_incomplete_fn.txt
new file mode 100644
index 00000000000..799720b5574
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0018_incomplete_fn.txt
@@ -0,0 +1,133 @@
+SOURCE_FILE
+  IMPL
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "FnScopes"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "new_scope"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            REF_PAT
+              AMP "&"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "ScopeId"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            LET_STMT
+              LET_KW "let"
+              WHITESPACE " "
+              IDENT_PAT
+                NAME
+                  IDENT "res"
+              WHITESPACE " "
+              EQ "="
+              WHITESPACE " "
+              METHOD_CALL_EXPR
+                FIELD_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          SELF_KW "self"
+                  DOT "."
+                  NAME_REF
+                    IDENT "scopes"
+                DOT "."
+                NAME_REF
+                  IDENT "len"
+                ARG_LIST
+                  L_PAREN "("
+                  R_PAREN ")"
+              SEMICOLON ";"
+            WHITESPACE "\n        "
+            METHOD_CALL_EXPR
+              FIELD_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        SELF_KW "self"
+                DOT "."
+                NAME_REF
+                  IDENT "scopes"
+              DOT "."
+              NAME_REF
+                IDENT "push"
+              ARG_LIST
+                L_PAREN "("
+                RECORD_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "ScopeData"
+                  WHITESPACE " "
+                  RECORD_EXPR_FIELD_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    RECORD_EXPR_FIELD
+                      NAME_REF
+                        IDENT "parent"
+                      COLON ":"
+                      WHITESPACE " "
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "None"
+                    COMMA ","
+                    WHITESPACE " "
+                    RECORD_EXPR_FIELD
+                      NAME_REF
+                        IDENT "entries"
+                      COLON ":"
+                      WHITESPACE " "
+                      MACRO_CALL
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "vec"
+                        BANG "!"
+                        TOKEN_TREE
+                          L_BRACK "["
+                          R_BRACK "]"
+                    WHITESPACE " "
+                    R_CURLY "}"
+                R_PAREN ")"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+      WHITESPACE "\n\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "set_parent"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
+error 34: expected pattern
+error 34: missing type for function parameter
+error 180: expected function arguments
+error 180: expected a block
diff --git a/crates/syntax/test_data/parser/err/0019_let_recover.rast b/crates/parser/test_data/parser/err/0019_let_recover.rast
index 919ce545b76..919ce545b76 100644
--- a/crates/syntax/test_data/parser/err/0019_let_recover.rast
+++ b/crates/parser/test_data/parser/err/0019_let_recover.rast
diff --git a/crates/syntax/test_data/parser/err/0019_let_recover.rs b/crates/parser/test_data/parser/err/0019_let_recover.rs
index 48bf3d68bd3..48bf3d68bd3 100644
--- a/crates/syntax/test_data/parser/err/0019_let_recover.rs
+++ b/crates/parser/test_data/parser/err/0019_let_recover.rs
diff --git a/crates/parser/test_data/parser/err/0019_let_recover.txt b/crates/parser/test_data/parser/err/0019_let_recover.txt
new file mode 100644
index 00000000000..25722b13558
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0019_let_recover.txt
@@ -0,0 +1,107 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "foo"
+          WHITESPACE " "
+          EQ "="
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "bar"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "baz"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "92"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          IF_EXPR
+            IF_KW "if"
+            WHITESPACE " "
+            CONDITION
+              LITERAL
+                TRUE_KW "true"
+            WHITESPACE " "
+            BLOCK_EXPR
+              STMT_LIST
+                L_CURLY "{"
+                R_CURLY "}"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          WHILE_EXPR
+            WHILE_KW "while"
+            WHITESPACE " "
+            CONDITION
+              LITERAL
+                TRUE_KW "true"
+            WHITESPACE " "
+            BLOCK_EXPR
+              STMT_LIST
+                L_CURLY "{"
+                R_CURLY "}"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+        WHITESPACE "\n    "
+        LOOP_EXPR
+          LOOP_KW "loop"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 24: expected expression
+error 24: expected SEMICOLON
+error 49: expected pattern
+error 49: expected SEMICOLON
+error 75: expected pattern
+error 75: expected SEMICOLON
+error 98: expected pattern
+error 98: expected SEMICOLON
+error 124: expected pattern
+error 124: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0020_fn_recover.rast b/crates/parser/test_data/parser/err/0020_fn_recover.rast
index 9ed2b14745c..9ed2b14745c 100644
--- a/crates/syntax/test_data/parser/err/0020_fn_recover.rast
+++ b/crates/parser/test_data/parser/err/0020_fn_recover.rast
diff --git a/crates/syntax/test_data/parser/err/0020_fn_recover.rs b/crates/parser/test_data/parser/err/0020_fn_recover.rs
index 3393b668b41..3393b668b41 100644
--- a/crates/syntax/test_data/parser/err/0020_fn_recover.rs
+++ b/crates/parser/test_data/parser/err/0020_fn_recover.rs
diff --git a/crates/parser/test_data/parser/err/0020_fn_recover.txt b/crates/parser/test_data/parser/err/0020_fn_recover.txt
new file mode 100644
index 00000000000..56d124cb95b
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0020_fn_recover.txt
@@ -0,0 +1,21 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 2: expected a name
+error 2: expected function arguments
+error 2: expected a block
diff --git a/crates/syntax/test_data/parser/err/0021_incomplete_param.rast b/crates/parser/test_data/parser/err/0021_incomplete_param.rast
index e2b6a3fd7e4..e2b6a3fd7e4 100644
--- a/crates/syntax/test_data/parser/err/0021_incomplete_param.rast
+++ b/crates/parser/test_data/parser/err/0021_incomplete_param.rast
diff --git a/crates/syntax/test_data/parser/err/0021_incomplete_param.rs b/crates/parser/test_data/parser/err/0021_incomplete_param.rs
index 7a6c264f6d7..7a6c264f6d7 100644
--- a/crates/syntax/test_data/parser/err/0021_incomplete_param.rs
+++ b/crates/parser/test_data/parser/err/0021_incomplete_param.rs
diff --git a/crates/parser/test_data/parser/err/0021_incomplete_param.txt b/crates/parser/test_data/parser/err/0021_incomplete_param.txt
new file mode 100644
index 00000000000..762840aa2a9
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0021_incomplete_param.txt
@@ -0,0 +1,34 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "x"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "i32"
+      COMMA ","
+      WHITESPACE " "
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "y"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 16: missing type for function parameter
diff --git a/crates/syntax/test_data/parser/err/0022_bad_exprs.rast b/crates/parser/test_data/parser/err/0022_bad_exprs.rast
index d4341371a71..d4341371a71 100644
--- a/crates/syntax/test_data/parser/err/0022_bad_exprs.rast
+++ b/crates/parser/test_data/parser/err/0022_bad_exprs.rast
diff --git a/crates/syntax/test_data/parser/err/0022_bad_exprs.rs b/crates/parser/test_data/parser/err/0022_bad_exprs.rs
index cd2d493a10c..cd2d493a10c 100644
--- a/crates/syntax/test_data/parser/err/0022_bad_exprs.rs
+++ b/crates/parser/test_data/parser/err/0022_bad_exprs.rs
diff --git a/crates/parser/test_data/parser/err/0022_bad_exprs.txt b/crates/parser/test_data/parser/err/0022_bad_exprs.txt
new file mode 100644
index 00000000000..900394bd960
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0022_bad_exprs.txt
@@ -0,0 +1,171 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "a"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        EXPR_STMT
+          ARRAY_EXPR
+            L_BRACK "["
+            LITERAL
+              INT_NUMBER "1"
+            COMMA ","
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "2"
+            COMMA ","
+            WHITESPACE " "
+            ERROR
+              AT "@"
+        ERROR
+          COMMA ","
+        WHITESPACE " "
+        STRUCT
+          STRUCT_KW "struct"
+          ERROR
+            COMMA ","
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+          ERROR
+            R_BRACK "]"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "b"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "foo"
+            ARG_LIST
+              L_PAREN "("
+              LITERAL
+                INT_NUMBER "1"
+              COMMA ","
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "2"
+              COMMA ","
+              WHITESPACE " "
+              ERROR
+                AT "@"
+        ERROR
+          COMMA ","
+        WHITESPACE " "
+        IMPL
+          IMPL_KW "impl"
+        ERROR
+          COMMA ","
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+        ERROR
+          R_PAREN ")"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "c"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        EXPR_STMT
+          METHOD_CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "foo"
+            DOT "."
+            NAME_REF
+              IDENT "bar"
+            ARG_LIST
+              L_PAREN "("
+              LITERAL
+                INT_NUMBER "1"
+              COMMA ","
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "2"
+              COMMA ","
+              WHITESPACE " "
+              ERROR
+                AT "@"
+        ERROR
+          COMMA ","
+        WHITESPACE " "
+        ERROR
+          R_BRACK "]"
+        ERROR
+          COMMA ","
+        WHITESPACE " "
+        TRAIT
+          TRAIT_KW "trait"
+          ERROR
+            COMMA ","
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+        ERROR
+          R_PAREN ")"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 16: expected expression
+error 17: expected R_BRACK
+error 17: expected SEMICOLON
+error 17: expected expression
+error 25: expected a name
+error 26: expected `;`, `{`, or `(`
+error 30: expected pattern
+error 31: expected SEMICOLON
+error 53: expected expression
+error 54: expected SEMICOLON
+error 54: expected expression
+error 60: expected type
+error 60: expected `{`
+error 60: expected expression
+error 65: expected pattern
+error 65: expected SEMICOLON
+error 65: expected expression
+error 92: expected expression
+error 93: expected SEMICOLON
+error 93: expected expression
+error 95: expected expression
+error 96: expected expression
+error 103: expected a name
+error 104: expected `{`
+error 108: expected pattern
+error 108: expected SEMICOLON
+error 108: expected expression
diff --git a/crates/syntax/test_data/parser/err/0023_mismatched_paren.rast b/crates/parser/test_data/parser/err/0023_mismatched_paren.rast
index 671566e3837..671566e3837 100644
--- a/crates/syntax/test_data/parser/err/0023_mismatched_paren.rast
+++ b/crates/parser/test_data/parser/err/0023_mismatched_paren.rast
diff --git a/crates/syntax/test_data/parser/err/0023_mismatched_paren.rs b/crates/parser/test_data/parser/err/0023_mismatched_paren.rs
index 0206d563ea7..0206d563ea7 100644
--- a/crates/syntax/test_data/parser/err/0023_mismatched_paren.rs
+++ b/crates/parser/test_data/parser/err/0023_mismatched_paren.rs
diff --git a/crates/parser/test_data/parser/err/0023_mismatched_paren.txt b/crates/parser/test_data/parser/err/0023_mismatched_paren.txt
new file mode 100644
index 00000000000..1176400634c
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0023_mismatched_paren.txt
@@ -0,0 +1,44 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        MACRO_CALL
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "foo"
+          BANG "!"
+          WHITESPACE " "
+          TOKEN_TREE
+            L_PAREN "("
+            WHITESPACE "\n        "
+            IDENT "bar"
+            COMMA ","
+            WHITESPACE " "
+            STRING "\"baz\""
+            COMMA ","
+            WHITESPACE " "
+            INT_NUMBER "1"
+            COMMA ","
+            WHITESPACE " "
+            FLOAT_NUMBER "2.0"
+        WHITESPACE "\n    "
+        R_CURLY "}"
+  WHITESPACE " "
+  COMMENT "//~ ERROR incorrect close delimiter"
+  WHITESPACE "\n"
+  ERROR
+    R_CURLY "}"
+  WHITESPACE "\n"
+error 49: unmatched `}`
+error 92: unmatched `}`
diff --git a/crates/syntax/test_data/parser/err/0024_many_type_parens.rast b/crates/parser/test_data/parser/err/0024_many_type_parens.rast
index 39a317137f3..39a317137f3 100644
--- a/crates/syntax/test_data/parser/err/0024_many_type_parens.rast
+++ b/crates/parser/test_data/parser/err/0024_many_type_parens.rast
diff --git a/crates/syntax/test_data/parser/err/0024_many_type_parens.rs b/crates/parser/test_data/parser/err/0024_many_type_parens.rs
index 6c2e95c0296..6c2e95c0296 100644
--- a/crates/syntax/test_data/parser/err/0024_many_type_parens.rs
+++ b/crates/parser/test_data/parser/err/0024_many_type_parens.rs
diff --git a/crates/parser/test_data/parser/err/0024_many_type_parens.txt b/crates/parser/test_data/parser/err/0024_many_type_parens.txt
new file mode 100644
index 00000000000..446e1a82338
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0024_many_type_parens.txt
@@ -0,0 +1,321 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "f"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            L_PAREN "("
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Copy"
+            R_PAREN ")"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            L_PAREN "("
+            QUESTION "?"
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Sized"
+            R_PAREN ")"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            L_PAREN "("
+            FOR_TYPE
+              FOR_KW "for"
+              GENERIC_PARAM_LIST
+                L_ANGLE "<"
+                LIFETIME_PARAM
+                  LIFETIME
+                    LIFETIME_IDENT "'a"
+                R_ANGLE ">"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Trait"
+                    GENERIC_ARG_LIST
+                      L_ANGLE "<"
+                      LIFETIME_ARG
+                        LIFETIME
+                          LIFETIME_IDENT "'a"
+                      R_ANGLE ">"
+            R_PAREN ")"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          COLON ":"
+          WHITESPACE " "
+          DYN_TRAIT_TYPE
+            TYPE_BOUND_LIST
+              TYPE_BOUND
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Box"
+                      GENERIC_ARG_LIST
+                        L_ANGLE "<"
+                        TYPE_ARG
+                          PAREN_TYPE
+                            L_PAREN "("
+                            PATH_TYPE
+                              PATH
+                                PATH_SEGMENT
+                                  NAME_REF
+                                    IDENT "Copy"
+                            R_PAREN ")"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              TYPE_BOUND
+                L_PAREN "("
+                QUESTION "?"
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Sized"
+                R_PAREN ")"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              TYPE_BOUND
+                L_PAREN "("
+                FOR_TYPE
+                  FOR_KW "for"
+                  GENERIC_PARAM_LIST
+                    L_ANGLE "<"
+                    LIFETIME_PARAM
+                      LIFETIME
+                        LIFETIME_IDENT "'a"
+                    R_ANGLE ">"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "Trait"
+                        GENERIC_ARG_LIST
+                          L_ANGLE "<"
+                          LIFETIME_ARG
+                            LIFETIME
+                              LIFETIME_IDENT "'a"
+                          R_ANGLE ">"
+                R_PAREN ")"
+        ERROR
+          R_ANGLE ">"
+        SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          COLON ":"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "Box"
+                GENERIC_ARG_LIST
+                  L_ANGLE "<"
+                  TYPE_ARG
+                    PAREN_TYPE
+                      L_PAREN "("
+                      ERROR
+                        QUESTION "?"
+        EXPR_STMT
+          PATH_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "Sized"
+        ERROR
+          R_PAREN ")"
+        WHITESPACE " "
+        ERROR
+          PLUS "+"
+        WHITESPACE " "
+        EXPR_STMT
+          TUPLE_EXPR
+            L_PAREN "("
+            FOR_EXPR
+              FOR_KW "for"
+              PATH_PAT
+                PATH
+                  PATH_SEGMENT
+                    L_ANGLE "<"
+                    ERROR
+                      LIFETIME_IDENT "'a"
+                    R_ANGLE ">"
+              WHITESPACE " "
+              BIN_EXPR
+                BIN_EXPR
+                  BIN_EXPR
+                    BIN_EXPR
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Trait"
+                      L_ANGLE "<"
+                      ERROR
+                        LIFETIME_IDENT "'a"
+                    R_ANGLE ">"
+                    ERROR
+                      R_PAREN ")"
+                  WHITESPACE " "
+                  PLUS "+"
+                  WHITESPACE " "
+                  PAREN_EXPR
+                    L_PAREN "("
+                    PATH_EXPR
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "Copy"
+                    R_PAREN ")"
+                R_ANGLE ">"
+                ERROR
+                  SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          COLON ":"
+          WHITESPACE " "
+          DYN_TRAIT_TYPE
+            TYPE_BOUND_LIST
+              TYPE_BOUND
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Box"
+                      GENERIC_ARG_LIST
+                        L_ANGLE "<"
+                        TYPE_ARG
+                          PAREN_TYPE
+                            L_PAREN "("
+                            FOR_TYPE
+                              FOR_KW "for"
+                              GENERIC_PARAM_LIST
+                                L_ANGLE "<"
+                                LIFETIME_PARAM
+                                  LIFETIME
+                                    LIFETIME_IDENT "'a"
+                                R_ANGLE ">"
+                              WHITESPACE " "
+                              PATH_TYPE
+                                PATH
+                                  PATH_SEGMENT
+                                    NAME_REF
+                                      IDENT "Trait"
+                                    GENERIC_ARG_LIST
+                                      L_ANGLE "<"
+                                      LIFETIME_ARG
+                                        LIFETIME
+                                          LIFETIME_IDENT "'a"
+                                      R_ANGLE ">"
+                            R_PAREN ")"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              TYPE_BOUND
+                L_PAREN "("
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Copy"
+                R_PAREN ")"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              TYPE_BOUND
+                L_PAREN "("
+                QUESTION "?"
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Sized"
+                R_PAREN ")"
+        ERROR
+          R_ANGLE ">"
+        SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 88: expected COMMA
+error 88: expected R_ANGLE
+error 121: expected SEMICOLON
+error 121: expected expression
+error 140: expected type
+error 141: expected R_PAREN
+error 141: expected COMMA
+error 141: expected R_ANGLE
+error 141: expected SEMICOLON
+error 146: expected SEMICOLON
+error 146: expected expression
+error 148: expected expression
+error 155: expected type
+error 158: expected IN_KW
+error 165: expected expression
+error 168: expected expression
+error 179: expected expression
+error 180: expected a block
+error 180: expected COMMA
+error 180: expected expression
+error 180: expected R_PAREN
+error 180: expected SEMICOLON
+error 215: expected COMMA
+error 215: expected R_ANGLE
+error 235: expected SEMICOLON
+error 235: expected expression
diff --git a/crates/syntax/test_data/parser/err/0025_nope.rast b/crates/parser/test_data/parser/err/0025_nope.rast
index b48b4aed8dd..b48b4aed8dd 100644
--- a/crates/syntax/test_data/parser/err/0025_nope.rast
+++ b/crates/parser/test_data/parser/err/0025_nope.rast
diff --git a/crates/syntax/test_data/parser/err/0025_nope.rs b/crates/parser/test_data/parser/err/0025_nope.rs
index 28726ed5138..28726ed5138 100644
--- a/crates/syntax/test_data/parser/err/0025_nope.rs
+++ b/crates/parser/test_data/parser/err/0025_nope.rs
diff --git a/crates/parser/test_data/parser/err/0025_nope.txt b/crates/parser/test_data/parser/err/0025_nope.txt
new file mode 100644
index 00000000000..aca57faf96e
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0025_nope.txt
@@ -0,0 +1,204 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        ENUM
+          ENUM_KW "enum"
+          WHITESPACE " "
+          NAME
+            IDENT "Test"
+          WHITESPACE " "
+          VARIANT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            VARIANT
+              NAME
+                IDENT "Var1"
+            COMMA ","
+            WHITESPACE "\n        "
+            VARIANT
+              NAME
+                IDENT "Var2"
+              TUPLE_FIELD_LIST
+                L_PAREN "("
+                TUPLE_FIELD
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "String"
+                R_PAREN ")"
+            COMMA ","
+            WHITESPACE "\n        "
+            VARIANT
+              NAME
+                IDENT "Var3"
+              WHITESPACE " "
+              RECORD_FIELD_LIST
+                L_CURLY "{"
+                WHITESPACE "\n            "
+                RECORD_FIELD
+                  NAME
+                    IDENT "abc"
+                  COLON ":"
+                WHITESPACE " "
+                ERROR
+                  L_CURLY "{"
+                  R_CURLY "}"
+                ERROR
+                  COMMA ","
+                WHITESPACE " "
+                COMMENT "//~ ERROR: expected type, found `{`"
+                WHITESPACE "\n        "
+                R_CURLY "}"
+            COMMA ","
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n\n    "
+        COMMENT "// recover..."
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "a"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        ENUM
+          ENUM_KW "enum"
+          WHITESPACE " "
+          NAME
+            IDENT "Test2"
+          WHITESPACE " "
+          VARIANT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            VARIANT
+              NAME
+                IDENT "Fine"
+            COMMA ","
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n\n    "
+        ENUM
+          ENUM_KW "enum"
+          WHITESPACE " "
+          NAME
+            IDENT "Test3"
+          WHITESPACE " "
+          VARIANT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            VARIANT
+              NAME
+                IDENT "StillFine"
+              WHITESPACE " "
+              RECORD_FIELD_LIST
+                L_CURLY "{"
+                WHITESPACE "\n            "
+                RECORD_FIELD
+                  NAME
+                    IDENT "def"
+                  COLON ":"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "i32"
+                COMMA ","
+                WHITESPACE "\n        "
+                R_CURLY "}"
+            COMMA ","
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              ENUM
+                COMMENT "// fail again"
+                WHITESPACE "\n        "
+                ENUM_KW "enum"
+                WHITESPACE " "
+                NAME
+                  IDENT "Test4"
+                WHITESPACE " "
+                VARIANT_LIST
+                  L_CURLY "{"
+                  WHITESPACE "\n            "
+                  VARIANT
+                    NAME
+                      IDENT "Nope"
+                    TUPLE_FIELD_LIST
+                      L_PAREN "("
+                      TUPLE_FIELD
+                        PATH_TYPE
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "i32"
+                      WHITESPACE " "
+                      ERROR
+                  ERROR
+                    L_CURLY "{"
+                    R_CURLY "}"
+                  ERROR
+                    R_PAREN ")"
+                  WHITESPACE " "
+                  COMMENT "//~ ERROR: found `{`"
+                  WHITESPACE "\n                         "
+                  COMMENT "//~^ ERROR: found `{`"
+                  WHITESPACE "\n        "
+                  R_CURLY "}"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        COMMENT "// still recover later"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "bad_syntax"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          ERROR
+            UNDERSCORE "_"
+          SEMICOLON ";"
+        WHITESPACE " "
+        COMMENT "//~ ERROR: expected expression, found reserved identifier `_`"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 95: expected type
+error 95: expected COMMA
+error 96: expected field
+error 98: expected field declaration
+error 371: expected COMMA
+error 372: expected a type
+error 372: expected R_PAREN
+error 372: expected COMMA
+error 372: expected enum variant
+error 374: expected enum variant
+error 508: expected expression
diff --git a/crates/syntax/test_data/parser/err/0026_imp_recovery.rast b/crates/parser/test_data/parser/err/0026_imp_recovery.rast
index 1b08c834eb8..1b08c834eb8 100644
--- a/crates/syntax/test_data/parser/err/0026_imp_recovery.rast
+++ b/crates/parser/test_data/parser/err/0026_imp_recovery.rast
diff --git a/crates/syntax/test_data/parser/err/0026_imp_recovery.rs b/crates/parser/test_data/parser/err/0026_imp_recovery.rs
index 829ca1c4be9..829ca1c4be9 100644
--- a/crates/syntax/test_data/parser/err/0026_imp_recovery.rs
+++ b/crates/parser/test_data/parser/err/0026_imp_recovery.rs
diff --git a/crates/parser/test_data/parser/err/0026_imp_recovery.txt b/crates/parser/test_data/parser/err/0026_imp_recovery.txt
new file mode 100644
index 00000000000..1068418e0d8
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0026_imp_recovery.txt
@@ -0,0 +1,49 @@
+SOURCE_FILE
+  IMPL
+    IMPL_KW "impl"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Clone"
+      R_ANGLE ">"
+  WHITESPACE "\n"
+  IMPL
+    IMPL_KW "impl"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "OnceCell"
+          GENERIC_ARG_LIST
+            L_ANGLE "<"
+            TYPE_ARG
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "T"
+            R_ANGLE ">"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+error 14: expected trait or type
+error 14: expected `{`
diff --git a/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast b/crates/parser/test_data/parser/err/0027_incomplere_where_for.rast
index ec585a42356..ec585a42356 100644
--- a/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast
+++ b/crates/parser/test_data/parser/err/0027_incomplere_where_for.rast
diff --git a/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rs b/crates/parser/test_data/parser/err/0027_incomplere_where_for.rs
index 2792c20843a..2792c20843a 100644
--- a/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rs
+++ b/crates/parser/test_data/parser/err/0027_incomplere_where_for.rs
diff --git a/crates/parser/test_data/parser/err/0027_incomplere_where_for.txt b/crates/parser/test_data/parser/err/0027_incomplere_where_for.txt
new file mode 100644
index 00000000000..674c8d536ca
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0027_incomplere_where_for.txt
@@ -0,0 +1,29 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n    "
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE " "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 26: expected type
+error 26: expected colon
diff --git a/crates/syntax/test_data/parser/err/0029_field_completion.rast b/crates/parser/test_data/parser/err/0029_field_completion.rast
index 183cf32030b..183cf32030b 100644
--- a/crates/syntax/test_data/parser/err/0029_field_completion.rast
+++ b/crates/parser/test_data/parser/err/0029_field_completion.rast
diff --git a/crates/syntax/test_data/parser/err/0029_field_completion.rs b/crates/parser/test_data/parser/err/0029_field_completion.rs
index a7cdc17bb11..a7cdc17bb11 100644
--- a/crates/syntax/test_data/parser/err/0029_field_completion.rs
+++ b/crates/parser/test_data/parser/err/0029_field_completion.rs
diff --git a/crates/parser/test_data/parser/err/0029_field_completion.txt b/crates/parser/test_data/parser/err/0029_field_completion.txt
new file mode 100644
index 00000000000..fb037112fa3
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0029_field_completion.txt
@@ -0,0 +1,36 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "a"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "A"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FIELD_EXPR
+          PATH_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "a"
+          DOT "."
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 21: expected field name or number
diff --git a/crates/syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast
index 2438b104bf4..2438b104bf4 100644
--- a/crates/syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast
+++ b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast
diff --git a/crates/syntax/test_data/parser/err/0032_match_arms_inner_attrs.rs b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rs
index 06aa4777043..06aa4777043 100644
--- a/crates/syntax/test_data/parser/err/0032_match_arms_inner_attrs.rs
+++ b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rs
diff --git a/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.txt b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.txt
new file mode 100644
index 00000000000..327bf94a49e
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.txt
@@ -0,0 +1,205 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                ATTR
+                  POUND "#"
+                ERROR
+                  BANG "!"
+                ARRAY_EXPR
+                  L_BRACK "["
+                  CALL_EXPR
+                    PATH_EXPR
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "doc"
+                    ARG_LIST
+                      L_PAREN "("
+                      LITERAL
+                        STRING "\"Not allowed here\""
+                      R_PAREN ")"
+                  R_BRACK "]"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                ATTR
+                  POUND "#"
+                ERROR
+                  BANG "!"
+                ARRAY_EXPR
+                  L_BRACK "["
+                  CALL_EXPR
+                    PATH_EXPR
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "doc"
+                    ARG_LIST
+                      L_PAREN "("
+                      LITERAL
+                        STRING "\"Nor here\""
+                      R_PAREN ")"
+                  R_BRACK "]"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        MATCH_EXPR
+          MATCH_KW "match"
+          WHITESPACE " "
+          TUPLE_EXPR
+            L_PAREN "("
+            R_PAREN ")"
+          WHITESPACE " "
+          MATCH_ARM_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            MATCH_ARM
+              ATTR
+                POUND "#"
+                L_BRACK "["
+                META
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "cfg"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    IDENT "test"
+                    R_PAREN ")"
+                R_BRACK "]"
+              WHITESPACE "\n        "
+              ATTR
+                POUND "#"
+              ERROR
+                BANG "!"
+              ARRAY_EXPR
+                L_BRACK "["
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "doc"
+                  ARG_LIST
+                    L_PAREN "("
+                    LITERAL
+                      STRING "\"Nor here\""
+                    R_PAREN ")"
+                R_BRACK "]"
+            WHITESPACE "\n        "
+            MATCH_ARM
+              WILDCARD_PAT
+                UNDERSCORE "_"
+              WHITESPACE " "
+              FAT_ARROW "=>"
+              WHITESPACE " "
+              TUPLE_EXPR
+                L_PAREN "("
+                R_PAREN ")"
+              COMMA ","
+            WHITESPACE "\n        "
+            MATCH_ARM
+              WILDCARD_PAT
+                UNDERSCORE "_"
+              WHITESPACE " "
+              FAT_ARROW "=>"
+              WHITESPACE " "
+              TUPLE_EXPR
+                L_PAREN "("
+                R_PAREN ")"
+              COMMA ","
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 52: expected `[`
+error 52: expected pattern
+error 53: expected FAT_ARROW
+error 78: expected `,`
+error 161: expected `[`
+error 161: expected pattern
+error 162: expected FAT_ARROW
+error 232: expected `[`
+error 232: expected pattern
+error 233: expected FAT_ARROW
+error 250: expected `,`
diff --git a/crates/syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast
index 66fc2ccbd20..66fc2ccbd20 100644
--- a/crates/syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast
+++ b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast
diff --git a/crates/syntax/test_data/parser/err/0033_match_arms_outer_attrs.rs b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rs
index 4635222da28..4635222da28 100644
--- a/crates/syntax/test_data/parser/err/0033_match_arms_outer_attrs.rs
+++ b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rs
diff --git a/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.txt b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.txt
new file mode 100644
index 00000000000..b5bc3d84df0
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.txt
@@ -0,0 +1,68 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        MATCH_EXPR
+          MATCH_KW "match"
+          WHITESPACE " "
+          TUPLE_EXPR
+            L_PAREN "("
+            R_PAREN ")"
+          WHITESPACE " "
+          MATCH_ARM_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            MATCH_ARM
+              WILDCARD_PAT
+                UNDERSCORE "_"
+              WHITESPACE " "
+              FAT_ARROW "=>"
+              WHITESPACE " "
+              TUPLE_EXPR
+                L_PAREN "("
+                R_PAREN ")"
+              COMMA ","
+            WHITESPACE "\n        "
+            MATCH_ARM
+              WILDCARD_PAT
+                UNDERSCORE "_"
+              WHITESPACE " "
+              FAT_ARROW "=>"
+              WHITESPACE " "
+              TUPLE_EXPR
+                L_PAREN "("
+                R_PAREN ")"
+              COMMA ","
+            WHITESPACE "\n        "
+            MATCH_ARM
+              ATTR
+                POUND "#"
+                L_BRACK "["
+                META
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "cfg"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    IDENT "test"
+                    R_PAREN ")"
+                R_BRACK "]"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 80: expected pattern
+error 80: expected FAT_ARROW
+error 80: expected expression
diff --git a/crates/syntax/test_data/parser/err/0034_bad_box_pattern.rast b/crates/parser/test_data/parser/err/0034_bad_box_pattern.rast
index 583e62c77a3..583e62c77a3 100644
--- a/crates/syntax/test_data/parser/err/0034_bad_box_pattern.rast
+++ b/crates/parser/test_data/parser/err/0034_bad_box_pattern.rast
diff --git a/crates/syntax/test_data/parser/err/0034_bad_box_pattern.rs b/crates/parser/test_data/parser/err/0034_bad_box_pattern.rs
index d3fa2e468cc..d3fa2e468cc 100644
--- a/crates/syntax/test_data/parser/err/0034_bad_box_pattern.rs
+++ b/crates/parser/test_data/parser/err/0034_bad_box_pattern.rs
diff --git a/crates/parser/test_data/parser/err/0034_bad_box_pattern.txt b/crates/parser/test_data/parser/err/0034_bad_box_pattern.txt
new file mode 100644
index 00000000000..7a2ae9103fd
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0034_bad_box_pattern.txt
@@ -0,0 +1,96 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            REF_KW "ref"
+            WHITESPACE " "
+            ERROR
+              BOX_KW "box"
+        WHITESPACE " "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            MUT_KW "mut"
+            WHITESPACE " "
+            ERROR
+              BOX_KW "box"
+        WHITESPACE " "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            REF_KW "ref"
+            WHITESPACE " "
+            MUT_KW "mut"
+            WHITESPACE " "
+            ERROR
+              BOX_KW "box"
+        WHITESPACE " "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+error 24: expected a name
+error 27: expected SEMICOLON
+error 48: expected a name
+error 51: expected SEMICOLON
+error 76: expected a name
+error 79: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0035_use_recover.rast b/crates/parser/test_data/parser/err/0035_use_recover.rast
index 14eaf9e9b02..14eaf9e9b02 100644
--- a/crates/syntax/test_data/parser/err/0035_use_recover.rast
+++ b/crates/parser/test_data/parser/err/0035_use_recover.rast
diff --git a/crates/syntax/test_data/parser/err/0035_use_recover.rs b/crates/parser/test_data/parser/err/0035_use_recover.rs
index 4a266812628..4a266812628 100644
--- a/crates/syntax/test_data/parser/err/0035_use_recover.rs
+++ b/crates/parser/test_data/parser/err/0035_use_recover.rs
diff --git a/crates/parser/test_data/parser/err/0035_use_recover.txt b/crates/parser/test_data/parser/err/0035_use_recover.txt
new file mode 100644
index 00000000000..f9287d42e20
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0035_use_recover.txt
@@ -0,0 +1,55 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "foo"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "bar"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              CRATE_KW "crate"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "baz"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "f"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 17: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 17: expected SEMICOLON
+error 37: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 37: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0036_partial_use.rast b/crates/parser/test_data/parser/err/0036_partial_use.rast
index ef6172f8a1a..ef6172f8a1a 100644
--- a/crates/syntax/test_data/parser/err/0036_partial_use.rast
+++ b/crates/parser/test_data/parser/err/0036_partial_use.rast
diff --git a/crates/syntax/test_data/parser/err/0036_partial_use.rs b/crates/parser/test_data/parser/err/0036_partial_use.rs
index d521a5bb2de..d521a5bb2de 100644
--- a/crates/syntax/test_data/parser/err/0036_partial_use.rs
+++ b/crates/parser/test_data/parser/err/0036_partial_use.rs
diff --git a/crates/parser/test_data/parser/err/0036_partial_use.txt b/crates/parser/test_data/parser/err/0036_partial_use.txt
new file mode 100644
index 00000000000..13e76e68307
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0036_partial_use.txt
@@ -0,0 +1,51 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "std"
+      COLON2 "::"
+      USE_TREE_LIST
+        L_CURLY "{"
+        USE_TREE
+          PATH
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "error"
+            COLON2 "::"
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Error"
+        ERROR
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        ERROR
+          USE_KW "use"
+        WHITESPACE " "
+        USE_TREE
+          PATH
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "std"
+            COLON2 "::"
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "io"
+        ERROR
+          SEMICOLON ";"
+  WHITESPACE "\n"
+error 22: expected COMMA
+error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 23: expected COMMA
+error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 27: expected COMMA
+error 35: expected COMMA
+error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 36: expected COMMA
+error 36: expected R_CURLY
+error 36: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/err/0039_lambda_recovery.rast b/crates/parser/test_data/parser/err/0039_lambda_recovery.rast
index b9b9f2e4b1b..b9b9f2e4b1b 100644
--- a/crates/syntax/test_data/parser/err/0039_lambda_recovery.rast
+++ b/crates/parser/test_data/parser/err/0039_lambda_recovery.rast
diff --git a/crates/syntax/test_data/parser/err/0039_lambda_recovery.rs b/crates/parser/test_data/parser/err/0039_lambda_recovery.rs
index a2f74bd879a..a2f74bd879a 100644
--- a/crates/syntax/test_data/parser/err/0039_lambda_recovery.rs
+++ b/crates/parser/test_data/parser/err/0039_lambda_recovery.rs
diff --git a/crates/parser/test_data/parser/err/0039_lambda_recovery.txt b/crates/parser/test_data/parser/err/0039_lambda_recovery.txt
new file mode 100644
index 00000000000..8ca16060153
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0039_lambda_recovery.txt
@@ -0,0 +1,83 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      PATH_TYPE
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "i32"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          METHOD_CALL_EXPR
+            METHOD_CALL_EXPR
+              METHOD_CALL_EXPR
+                ARRAY_EXPR
+                  L_BRACK "["
+                  LITERAL
+                    INT_NUMBER "1"
+                  COMMA ","
+                  WHITESPACE " "
+                  LITERAL
+                    INT_NUMBER "2"
+                  COMMA ","
+                  WHITESPACE " "
+                  LITERAL
+                    INT_NUMBER "3"
+                  R_BRACK "]"
+                DOT "."
+                NAME_REF
+                  IDENT "iter"
+                ARG_LIST
+                  L_PAREN "("
+                  R_PAREN ")"
+              WHITESPACE "\n        "
+              DOT "."
+              NAME_REF
+                IDENT "map"
+              ARG_LIST
+                L_PAREN "("
+                CLOSURE_EXPR
+                  PARAM_LIST
+                    PIPE "|"
+                    PARAM
+                      IDENT_PAT
+                        NAME
+                          IDENT "it"
+                    PIPE "|"
+                R_PAREN ")"
+            WHITESPACE "\n        "
+            DOT "."
+            NAME_REF
+              IDENT "max"
+            GENERIC_ARG_LIST
+              COLON2 "::"
+              L_ANGLE "<"
+              TYPE_ARG
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "i32"
+              R_ANGLE ">"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 56: expected expression
diff --git a/crates/syntax/test_data/parser/err/0042_weird_blocks.rast b/crates/parser/test_data/parser/err/0042_weird_blocks.rast
index 25910cb4052..25910cb4052 100644
--- a/crates/syntax/test_data/parser/err/0042_weird_blocks.rast
+++ b/crates/parser/test_data/parser/err/0042_weird_blocks.rast
diff --git a/crates/syntax/test_data/parser/err/0042_weird_blocks.rs b/crates/parser/test_data/parser/err/0042_weird_blocks.rs
index 8fa324c1a14..8fa324c1a14 100644
--- a/crates/syntax/test_data/parser/err/0042_weird_blocks.rs
+++ b/crates/parser/test_data/parser/err/0042_weird_blocks.rs
diff --git a/crates/parser/test_data/parser/err/0042_weird_blocks.txt b/crates/parser/test_data/parser/err/0042_weird_blocks.txt
new file mode 100644
index 00000000000..9cea337ce9c
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0042_weird_blocks.txt
@@ -0,0 +1,75 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              ERROR
+                UNSAFE_KW "unsafe"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "92"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              ERROR
+                ASYNC_KW "async"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "92"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              EXPR_STMT
+                BLOCK_EXPR
+                  TRY_KW "try"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "92"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE " "
+            ERROR
+              LABEL
+                LIFETIME
+                  LIFETIME_IDENT "'label"
+                COLON ":"
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "92"
+            WHITESPACE " "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 24: expected existential, fn, trait or impl
+error 41: expected existential, fn, trait or impl
+error 56: expected a block
+error 75: expected a loop
diff --git a/crates/syntax/test_data/parser/err/0043_unexpected_for_type.rast b/crates/parser/test_data/parser/err/0043_unexpected_for_type.rast
index d4e4bf102ed..d4e4bf102ed 100644
--- a/crates/syntax/test_data/parser/err/0043_unexpected_for_type.rast
+++ b/crates/parser/test_data/parser/err/0043_unexpected_for_type.rast
diff --git a/crates/syntax/test_data/parser/err/0043_unexpected_for_type.rs b/crates/parser/test_data/parser/err/0043_unexpected_for_type.rs
index 0e9f8ccb4f8..0e9f8ccb4f8 100644
--- a/crates/syntax/test_data/parser/err/0043_unexpected_for_type.rs
+++ b/crates/parser/test_data/parser/err/0043_unexpected_for_type.rs
diff --git a/crates/parser/test_data/parser/err/0043_unexpected_for_type.txt b/crates/parser/test_data/parser/err/0043_unexpected_for_type.txt
new file mode 100644
index 00000000000..cb4fb1642d9
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0043_unexpected_for_type.txt
@@ -0,0 +1,256 @@
+SOURCE_FILE
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "ForRef"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    FOR_TYPE
+      FOR_KW "for"
+      GENERIC_PARAM_LIST
+        L_ANGLE "<"
+        LIFETIME_PARAM
+          LIFETIME
+            LIFETIME_IDENT "'a"
+        R_ANGLE ">"
+      WHITESPACE " "
+      REF_TYPE
+        AMP "&"
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "ForTup"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    FOR_TYPE
+      FOR_KW "for"
+      GENERIC_PARAM_LIST
+        L_ANGLE "<"
+        LIFETIME_PARAM
+          LIFETIME
+            LIFETIME_IDENT "'a"
+        R_ANGLE ">"
+      WHITESPACE " "
+      TUPLE_TYPE
+        L_PAREN "("
+        REF_TYPE
+          AMP "&"
+          LIFETIME
+            LIFETIME_IDENT "'a"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "u32"
+        COMMA ","
+        R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "ForSlice"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    FOR_TYPE
+      FOR_KW "for"
+      GENERIC_PARAM_LIST
+        L_ANGLE "<"
+        LIFETIME_PARAM
+          LIFETIME
+            LIFETIME_IDENT "'a"
+        R_ANGLE ">"
+      WHITESPACE " "
+      SLICE_TYPE
+        L_BRACK "["
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+        R_BRACK "]"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "ForForFn"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    FOR_TYPE
+      FOR_KW "for"
+      GENERIC_PARAM_LIST
+        L_ANGLE "<"
+        LIFETIME_PARAM
+          LIFETIME
+            LIFETIME_IDENT "'a"
+        R_ANGLE ">"
+      WHITESPACE " "
+      FOR_TYPE
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'b"
+          R_ANGLE ">"
+        WHITESPACE " "
+        FN_PTR_TYPE
+          FN_KW "fn"
+          PARAM_LIST
+            L_PAREN "("
+            PARAM
+              REF_TYPE
+                AMP "&"
+                LIFETIME
+                  LIFETIME_IDENT "'a"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "i32"
+            COMMA ","
+            WHITESPACE " "
+            PARAM
+              REF_TYPE
+                AMP "&"
+                LIFETIME
+                  LIFETIME_IDENT "'b"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "i32"
+            R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_for_for"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        FOR_TYPE
+          FOR_KW "for"
+          GENERIC_PARAM_LIST
+            L_ANGLE "<"
+            LIFETIME_PARAM
+              LIFETIME
+                LIFETIME_IDENT "'b"
+            R_ANGLE ">"
+          WHITESPACE " "
+          FOR_TYPE
+            FOR_KW "for"
+            GENERIC_PARAM_LIST
+              L_ANGLE "<"
+              LIFETIME_PARAM
+                LIFETIME
+                  LIFETIME_IDENT "'c"
+              R_ANGLE ">"
+            WHITESPACE " "
+            FN_PTR_TYPE
+              FN_KW "fn"
+              PARAM_LIST
+                L_PAREN "("
+                PARAM
+                  REF_TYPE
+                    AMP "&"
+                    LIFETIME
+                      LIFETIME_IDENT "'a"
+                    WHITESPACE " "
+                    PATH_TYPE
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "T"
+                COMMA ","
+                WHITESPACE " "
+                PARAM
+                  REF_TYPE
+                    AMP "&"
+                    LIFETIME
+                      LIFETIME_IDENT "'b"
+                    WHITESPACE " "
+                    PATH_TYPE
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "T"
+                COMMA ","
+                WHITESPACE " "
+                PARAM
+                  REF_TYPE
+                    AMP "&"
+                    LIFETIME
+                      LIFETIME_IDENT "'c"
+                    WHITESPACE " "
+                    PATH_TYPE
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "T"
+                R_PAREN ")"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Copy"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 21: expected a function pointer or path
+error 52: expected a function pointer or path
+error 88: expected a function pointer or path
+error 119: expected a function pointer or path
+error 195: expected a function pointer or path
diff --git a/crates/syntax/test_data/parser/err/0044_item_modifiers.rast b/crates/parser/test_data/parser/err/0044_item_modifiers.rast
index b4ff1a14a7c..b4ff1a14a7c 100644
--- a/crates/syntax/test_data/parser/err/0044_item_modifiers.rast
+++ b/crates/parser/test_data/parser/err/0044_item_modifiers.rast
diff --git a/crates/syntax/test_data/parser/err/0044_item_modifiers.rs b/crates/parser/test_data/parser/err/0044_item_modifiers.rs
index 731e58013bd..731e58013bd 100644
--- a/crates/syntax/test_data/parser/err/0044_item_modifiers.rs
+++ b/crates/parser/test_data/parser/err/0044_item_modifiers.rs
diff --git a/crates/parser/test_data/parser/err/0044_item_modifiers.txt b/crates/parser/test_data/parser/err/0044_item_modifiers.txt
new file mode 100644
index 00000000000..96e471a69a7
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0044_item_modifiers.txt
@@ -0,0 +1,48 @@
+SOURCE_FILE
+  ERROR
+    UNSAFE_KW "unsafe"
+  WHITESPACE " "
+  FN
+    ASYNC_KW "async"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  CONST
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    CONST_KW "const"
+    WHITESPACE " "
+    ERROR
+      FN_KW "fn"
+  WHITESPACE " "
+  MACRO_CALL
+    PATH
+      PATH_SEGMENT
+        NAME_REF
+          IDENT "bar"
+    TOKEN_TREE
+      L_PAREN "("
+      R_PAREN ")"
+  WHITESPACE " "
+  ERROR
+    L_CURLY "{"
+    R_CURLY "}"
+  WHITESPACE "\n"
+error 6: expected existential, fn, trait or impl
+error 38: expected a name
+error 40: missing type for `const` or `static`
+error 40: expected SEMICOLON
+error 44: expected BANG
+error 46: expected SEMICOLON
+error 47: expected an item
diff --git a/crates/syntax/test_data/parser/err/0047_repated_extern_modifier.rast b/crates/parser/test_data/parser/err/0047_repated_extern_modifier.rast
index 85e10ca36db..85e10ca36db 100644
--- a/crates/syntax/test_data/parser/err/0047_repated_extern_modifier.rast
+++ b/crates/parser/test_data/parser/err/0047_repated_extern_modifier.rast
diff --git a/crates/syntax/test_data/parser/err/0047_repated_extern_modifier.rs b/crates/parser/test_data/parser/err/0047_repated_extern_modifier.rs
index 1fb18eaf1bc..db32b98dfb0 100644
--- a/crates/syntax/test_data/parser/err/0047_repated_extern_modifier.rs
+++ b/crates/parser/test_data/parser/err/0047_repated_extern_modifier.rs
@@ -1 +1 @@
-extern "C" extern "C"

+extern "C" extern "C"
diff --git a/crates/parser/test_data/parser/err/0047_repated_extern_modifier.txt b/crates/parser/test_data/parser/err/0047_repated_extern_modifier.txt
new file mode 100644
index 00000000000..884ac50f8bb
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0047_repated_extern_modifier.txt
@@ -0,0 +1,15 @@
+SOURCE_FILE
+  ERROR
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+  WHITESPACE " "
+  ERROR
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+  WHITESPACE "\r\n"
+error 10: expected existential, fn, trait or impl
+error 21: expected existential, fn, trait or impl
diff --git a/crates/syntax/test_data/parser/err/0048_double_fish.rast b/crates/parser/test_data/parser/err/0048_double_fish.rast
index ca52166fbc4..ca52166fbc4 100644
--- a/crates/syntax/test_data/parser/err/0048_double_fish.rast
+++ b/crates/parser/test_data/parser/err/0048_double_fish.rast
diff --git a/crates/syntax/test_data/parser/err/0048_double_fish.rs b/crates/parser/test_data/parser/err/0048_double_fish.rs
index 31c12bfff9f..31c12bfff9f 100644
--- a/crates/syntax/test_data/parser/err/0048_double_fish.rs
+++ b/crates/parser/test_data/parser/err/0048_double_fish.rs
diff --git a/crates/parser/test_data/parser/err/0048_double_fish.txt b/crates/parser/test_data/parser/err/0048_double_fish.txt
new file mode 100644
index 00000000000..3a05bfee1ee
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0048_double_fish.txt
@@ -0,0 +1,123 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "f"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          PATH_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+                GENERIC_ARG_LIST
+                  COLON2 "::"
+                  L_ANGLE "<"
+                  TYPE_ARG
+                    PATH_TYPE
+                      PATH
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Item"
+                            GENERIC_ARG_LIST
+                              COLON2 "::"
+                              L_ANGLE "<"
+                              TYPE_ARG
+                                PATH_TYPE
+                                  PATH
+                                    PATH_SEGMENT
+                                      NAME_REF
+                                        IDENT "lol"
+                              R_ANGLE ">"
+                        COLON2 "::"
+                        ERROR
+                          L_ANGLE "<"
+        BIN_EXPR
+          PATH_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "nope"
+          SHR ">>"
+          ERROR
+            SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "g"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          COLON ":"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Item"
+                  GENERIC_ARG_LIST
+                    COLON2 "::"
+                    L_ANGLE "<"
+                    TYPE_ARG
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "lol"
+                    R_ANGLE ">"
+              COLON2 "::"
+              ERROR
+                L_ANGLE "<"
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "nope"
+            R_ANGLE ">"
+            WHITESPACE " "
+            ERROR
+              EQ "="
+        WHITESPACE " "
+        EXPR_STMT
+          TUPLE_EXPR
+            L_PAREN "("
+            R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 30: expected identifier
+error 31: expected COMMA
+error 31: expected R_ANGLE
+error 31: expected SEMICOLON
+error 37: expected expression
+error 75: expected identifier
+error 76: expected SEMICOLON
+error 82: expected expression
+error 83: expected SEMICOLON
diff --git a/crates/syntax/test_data/parser/ok/0000_empty.rast b/crates/parser/test_data/parser/ok/0000_empty.rast
index 6b234b0b241..6b234b0b241 100644
--- a/crates/syntax/test_data/parser/ok/0000_empty.rast
+++ b/crates/parser/test_data/parser/ok/0000_empty.rast
diff --git a/crates/syntax/test_data/parser/ok/0000_empty.rs b/crates/parser/test_data/parser/ok/0000_empty.rs
index e69de29bb2d..e69de29bb2d 100644
--- a/crates/syntax/test_data/parser/ok/0000_empty.rs
+++ b/crates/parser/test_data/parser/ok/0000_empty.rs
diff --git a/crates/parser/test_data/parser/ok/0000_empty.txt b/crates/parser/test_data/parser/ok/0000_empty.txt
new file mode 100644
index 00000000000..40b9ef804c2
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0000_empty.txt
@@ -0,0 +1 @@
+SOURCE_FILE
diff --git a/crates/syntax/test_data/parser/ok/0001_struct_item.rast b/crates/parser/test_data/parser/ok/0001_struct_item.rast
index a171fe7a86d..a171fe7a86d 100644
--- a/crates/syntax/test_data/parser/ok/0001_struct_item.rast
+++ b/crates/parser/test_data/parser/ok/0001_struct_item.rast
diff --git a/crates/syntax/test_data/parser/ok/0001_struct_item.rs b/crates/parser/test_data/parser/ok/0001_struct_item.rs
index 512aeb3e7a0..512aeb3e7a0 100644
--- a/crates/syntax/test_data/parser/ok/0001_struct_item.rs
+++ b/crates/parser/test_data/parser/ok/0001_struct_item.rs
diff --git a/crates/parser/test_data/parser/ok/0001_struct_item.txt b/crates/parser/test_data/parser/ok/0001_struct_item.txt
new file mode 100644
index 00000000000..0e9639f23db
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0001_struct_item.txt
@@ -0,0 +1,39 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Copy"
+      R_ANGLE ">"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "f"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "T"
+      COMMA ","
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0002_struct_item_field.rast b/crates/parser/test_data/parser/ok/0002_struct_item_field.rast
index 362892b91f1..362892b91f1 100644
--- a/crates/syntax/test_data/parser/ok/0002_struct_item_field.rast
+++ b/crates/parser/test_data/parser/ok/0002_struct_item_field.rast
diff --git a/crates/syntax/test_data/parser/ok/0002_struct_item_field.rs b/crates/parser/test_data/parser/ok/0002_struct_item_field.rs
index cc3866d2511..cc3866d2511 100644
--- a/crates/syntax/test_data/parser/ok/0002_struct_item_field.rs
+++ b/crates/parser/test_data/parser/ok/0002_struct_item_field.rs
diff --git a/crates/parser/test_data/parser/ok/0002_struct_item_field.txt b/crates/parser/test_data/parser/ok/0002_struct_item_field.txt
new file mode 100644
index 00000000000..dd52e5850e5
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0002_struct_item_field.txt
@@ -0,0 +1,22 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "foo"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE "\n"
+      R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0004_file_shebang.rast b/crates/parser/test_data/parser/ok/0004_file_shebang.rast
index 67e21df13a1..67e21df13a1 100644
--- a/crates/syntax/test_data/parser/ok/0004_file_shebang.rast
+++ b/crates/parser/test_data/parser/ok/0004_file_shebang.rast
diff --git a/crates/syntax/test_data/parser/ok/0004_file_shebang.rs b/crates/parser/test_data/parser/ok/0004_file_shebang.rs
index 53dc9e61733..53dc9e61733 100644
--- a/crates/syntax/test_data/parser/ok/0004_file_shebang.rs
+++ b/crates/parser/test_data/parser/ok/0004_file_shebang.rs
diff --git a/crates/parser/test_data/parser/ok/0004_file_shebang.txt b/crates/parser/test_data/parser/ok/0004_file_shebang.txt
new file mode 100644
index 00000000000..698957189fe
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0004_file_shebang.txt
@@ -0,0 +1,2 @@
+SOURCE_FILE
+  SHEBANG "#!/use/bin/env rusti"
diff --git a/crates/syntax/test_data/parser/ok/0005_fn_item.rast b/crates/parser/test_data/parser/ok/0005_fn_item.rast
index 845f9a6f357..845f9a6f357 100644
--- a/crates/syntax/test_data/parser/ok/0005_fn_item.rast
+++ b/crates/parser/test_data/parser/ok/0005_fn_item.rast
diff --git a/crates/syntax/test_data/parser/ok/0005_fn_item.rs b/crates/parser/test_data/parser/ok/0005_fn_item.rs
index 03210551cb1..03210551cb1 100644
--- a/crates/syntax/test_data/parser/ok/0005_fn_item.rs
+++ b/crates/parser/test_data/parser/ok/0005_fn_item.rs
diff --git a/crates/parser/test_data/parser/ok/0005_fn_item.txt b/crates/parser/test_data/parser/ok/0005_fn_item.txt
new file mode 100644
index 00000000000..756d20e4d6d
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0005_fn_item.txt
@@ -0,0 +1,16 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0006_inner_attributes.rast b/crates/parser/test_data/parser/ok/0006_inner_attributes.rast
index be2d1dc123e..be2d1dc123e 100644
--- a/crates/syntax/test_data/parser/ok/0006_inner_attributes.rast
+++ b/crates/parser/test_data/parser/ok/0006_inner_attributes.rast
diff --git a/crates/syntax/test_data/parser/ok/0006_inner_attributes.rs b/crates/parser/test_data/parser/ok/0006_inner_attributes.rs
index e81f8b1e84f..e81f8b1e84f 100644
--- a/crates/syntax/test_data/parser/ok/0006_inner_attributes.rs
+++ b/crates/parser/test_data/parser/ok/0006_inner_attributes.rs
diff --git a/crates/parser/test_data/parser/ok/0006_inner_attributes.txt b/crates/parser/test_data/parser/ok/0006_inner_attributes.txt
new file mode 100644
index 00000000000..cb63ba80e77
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0006_inner_attributes.txt
@@ -0,0 +1,194 @@
+SOURCE_FILE
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+      TOKEN_TREE
+        L_PAREN "("
+        TRUE_KW "true"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "ident"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "ident"
+        COMMA ","
+        WHITESPACE " "
+        INT_NUMBER "100"
+        COMMA ","
+        WHITESPACE " "
+        TRUE_KW "true"
+        COMMA ","
+        WHITESPACE " "
+        STRING "\"true\""
+        COMMA ","
+        WHITESPACE " "
+        IDENT "ident"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        INT_NUMBER "100"
+        COMMA ","
+        WHITESPACE " "
+        IDENT "ident"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        STRING "\"hello\""
+        COMMA ","
+        WHITESPACE " "
+        IDENT "ident"
+        TOKEN_TREE
+          L_PAREN "("
+          INT_NUMBER "100"
+          R_PAREN ")"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+      TOKEN_TREE
+        L_PAREN "("
+        INT_NUMBER "100"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "enabled"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        TRUE_KW "true"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "enabled"
+      TOKEN_TREE
+        L_PAREN "("
+        TRUE_KW "true"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "attr"
+      TOKEN_TREE
+        L_PAREN "("
+        STRING "\"hello\""
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "repr"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "C"
+        COMMA ","
+        WHITESPACE " "
+        IDENT "align"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        INT_NUMBER "4"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "repr"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "C"
+        COMMA ","
+        WHITESPACE " "
+        IDENT "align"
+        TOKEN_TREE
+          L_PAREN "("
+          INT_NUMBER "4"
+          R_PAREN ")"
+        R_PAREN ")"
+    R_BRACK "]"
diff --git a/crates/syntax/test_data/parser/ok/0007_extern_crate.rast b/crates/parser/test_data/parser/ok/0007_extern_crate.rast
index 4babdba9279..4babdba9279 100644
--- a/crates/syntax/test_data/parser/ok/0007_extern_crate.rast
+++ b/crates/parser/test_data/parser/ok/0007_extern_crate.rast
diff --git a/crates/syntax/test_data/parser/ok/0007_extern_crate.rs b/crates/parser/test_data/parser/ok/0007_extern_crate.rs
index ab81a608cb5..ab81a608cb5 100644
--- a/crates/syntax/test_data/parser/ok/0007_extern_crate.rs
+++ b/crates/parser/test_data/parser/ok/0007_extern_crate.rs
diff --git a/crates/parser/test_data/parser/ok/0007_extern_crate.txt b/crates/parser/test_data/parser/ok/0007_extern_crate.txt
new file mode 100644
index 00000000000..8b9259fd6b9
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0007_extern_crate.txt
@@ -0,0 +1,40 @@
+SOURCE_FILE
+  EXTERN_CRATE
+    EXTERN_KW "extern"
+    WHITESPACE " "
+    CRATE_KW "crate"
+    WHITESPACE " "
+    NAME_REF
+      IDENT "foo"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  EXTERN_CRATE
+    EXTERN_KW "extern"
+    WHITESPACE " "
+    CRATE_KW "crate"
+    WHITESPACE " "
+    NAME_REF
+      IDENT "foo"
+    WHITESPACE " "
+    RENAME
+      AS_KW "as"
+      WHITESPACE " "
+      NAME
+        IDENT "bar"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  EXTERN_CRATE
+    EXTERN_KW "extern"
+    WHITESPACE " "
+    CRATE_KW "crate"
+    WHITESPACE " "
+    NAME_REF
+      SELF_KW "self"
+    WHITESPACE " "
+    RENAME
+      AS_KW "as"
+      WHITESPACE " "
+      NAME
+        IDENT "baz"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0008_mod_item.rast b/crates/parser/test_data/parser/ok/0008_mod_item.rast
index e864641834f..e864641834f 100644
--- a/crates/syntax/test_data/parser/ok/0008_mod_item.rast
+++ b/crates/parser/test_data/parser/ok/0008_mod_item.rast
diff --git a/crates/syntax/test_data/parser/ok/0008_mod_item.rs b/crates/parser/test_data/parser/ok/0008_mod_item.rs
index 4ff0d9795c7..4ff0d9795c7 100644
--- a/crates/syntax/test_data/parser/ok/0008_mod_item.rs
+++ b/crates/parser/test_data/parser/ok/0008_mod_item.rs
diff --git a/crates/parser/test_data/parser/ok/0008_mod_item.txt b/crates/parser/test_data/parser/ok/0008_mod_item.txt
new file mode 100644
index 00000000000..adee67181b1
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0008_mod_item.txt
@@ -0,0 +1,77 @@
+SOURCE_FILE
+  MODULE
+    MOD_KW "mod"
+    WHITESPACE " "
+    NAME
+      IDENT "c"
+    WHITESPACE " "
+    ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "foo"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      STRUCT
+        STRUCT_KW "struct"
+        WHITESPACE " "
+        NAME
+          IDENT "S"
+        WHITESPACE " "
+        RECORD_FIELD_LIST
+          L_CURLY "{"
+          R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  MODULE
+    MOD_KW "mod"
+    WHITESPACE " "
+    NAME
+      IDENT "d"
+    WHITESPACE " "
+    ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      ATTR
+        POUND "#"
+        BANG "!"
+        L_BRACK "["
+        META
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "attr"
+        R_BRACK "]"
+      WHITESPACE "\n    "
+      MODULE
+        MOD_KW "mod"
+        WHITESPACE " "
+        NAME
+          IDENT "e"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      MODULE
+        MOD_KW "mod"
+        WHITESPACE " "
+        NAME
+          IDENT "f"
+        WHITESPACE " "
+        ITEM_LIST
+          L_CURLY "{"
+          WHITESPACE "\n    "
+          R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0009_use_item.rast b/crates/parser/test_data/parser/ok/0009_use_item.rast
index 6be1cf9fc83..6be1cf9fc83 100644
--- a/crates/syntax/test_data/parser/ok/0009_use_item.rast
+++ b/crates/parser/test_data/parser/ok/0009_use_item.rast
diff --git a/crates/syntax/test_data/parser/ok/0009_use_item.rs b/crates/parser/test_data/parser/ok/0009_use_item.rs
index 05a6aff83fc..05a6aff83fc 100644
--- a/crates/syntax/test_data/parser/ok/0009_use_item.rs
+++ b/crates/parser/test_data/parser/ok/0009_use_item.rs
diff --git a/crates/parser/test_data/parser/ok/0009_use_item.txt b/crates/parser/test_data/parser/ok/0009_use_item.txt
new file mode 100644
index 00000000000..04a44ef7e4b
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0009_use_item.txt
@@ -0,0 +1,21 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          COLON2 "::"
+          NAME_REF
+            IDENT "bar"
+    SEMICOLON ";"
diff --git a/crates/syntax/test_data/parser/ok/0010_use_path_segments.rast b/crates/parser/test_data/parser/ok/0010_use_path_segments.rast
index 4d49e793374..4d49e793374 100644
--- a/crates/syntax/test_data/parser/ok/0010_use_path_segments.rast
+++ b/crates/parser/test_data/parser/ok/0010_use_path_segments.rast
diff --git a/crates/syntax/test_data/parser/ok/0010_use_path_segments.rs b/crates/parser/test_data/parser/ok/0010_use_path_segments.rs
index 1e71b7a6c5d..1e71b7a6c5d 100644
--- a/crates/syntax/test_data/parser/ok/0010_use_path_segments.rs
+++ b/crates/parser/test_data/parser/ok/0010_use_path_segments.rs
diff --git a/crates/parser/test_data/parser/ok/0010_use_path_segments.txt b/crates/parser/test_data/parser/ok/0010_use_path_segments.txt
new file mode 100644
index 00000000000..ddadec817b8
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0010_use_path_segments.txt
@@ -0,0 +1,42 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH
+            PATH_SEGMENT
+              COLON2 "::"
+              NAME_REF
+                IDENT "foo"
+          COLON2 "::"
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "bar"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "baz"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "foo"
+          COLON2 "::"
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "bar"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "baz"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0011_outer_attribute.rast b/crates/parser/test_data/parser/ok/0011_outer_attribute.rast
index bb35b40f4e7..bb35b40f4e7 100644
--- a/crates/syntax/test_data/parser/ok/0011_outer_attribute.rast
+++ b/crates/parser/test_data/parser/ok/0011_outer_attribute.rast
diff --git a/crates/syntax/test_data/parser/ok/0011_outer_attribute.rs b/crates/parser/test_data/parser/ok/0011_outer_attribute.rs
index 6f04cb1717f..6f04cb1717f 100644
--- a/crates/syntax/test_data/parser/ok/0011_outer_attribute.rs
+++ b/crates/parser/test_data/parser/ok/0011_outer_attribute.rs
diff --git a/crates/parser/test_data/parser/ok/0011_outer_attribute.txt b/crates/parser/test_data/parser/ok/0011_outer_attribute.txt
new file mode 100644
index 00000000000..dbb9bc54da8
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0011_outer_attribute.txt
@@ -0,0 +1,61 @@
+SOURCE_FILE
+  FN
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "cfg"
+        TOKEN_TREE
+          L_PAREN "("
+          IDENT "test"
+          R_PAREN ")"
+      R_BRACK "]"
+    WHITESPACE "\n"
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "Ignore"
+      R_BRACK "]"
+    WHITESPACE "\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  MODULE
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "path"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        LITERAL
+          STRING "\"a.rs\""
+      R_BRACK "]"
+    WHITESPACE "\n"
+    MOD_KW "mod"
+    WHITESPACE " "
+    NAME
+      IDENT "b"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0012_visibility.rast b/crates/parser/test_data/parser/ok/0012_visibility.rast
index e046b0bb1c8..e046b0bb1c8 100644
--- a/crates/syntax/test_data/parser/ok/0012_visibility.rast
+++ b/crates/parser/test_data/parser/ok/0012_visibility.rast
diff --git a/crates/syntax/test_data/parser/ok/0012_visibility.rs b/crates/parser/test_data/parser/ok/0012_visibility.rs
index 129d486fae2..129d486fae2 100644
--- a/crates/syntax/test_data/parser/ok/0012_visibility.rs
+++ b/crates/parser/test_data/parser/ok/0012_visibility.rs
diff --git a/crates/parser/test_data/parser/ok/0012_visibility.txt b/crates/parser/test_data/parser/ok/0012_visibility.txt
new file mode 100644
index 00000000000..a95bc23016b
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0012_visibility.txt
@@ -0,0 +1,133 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "a"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    VISIBILITY
+      PUB_KW "pub"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "b"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  MACRO_DEF
+    VISIBILITY
+      PUB_KW "pub"
+    WHITESPACE " "
+    MACRO_KW "macro"
+    WHITESPACE " "
+    NAME
+      IDENT "m"
+    TOKEN_TREE
+      TOKEN_TREE
+        L_PAREN "("
+        DOLLAR "$"
+        COLON ":"
+        IDENT "ident"
+        R_PAREN ")"
+      WHITESPACE " "
+      TOKEN_TREE
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    VISIBILITY
+      PUB_KW "pub"
+      L_PAREN "("
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            CRATE_KW "crate"
+      R_PAREN ")"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "c"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    VISIBILITY
+      PUB_KW "pub"
+      L_PAREN "("
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            SUPER_KW "super"
+      R_PAREN ")"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "d"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    VISIBILITY
+      PUB_KW "pub"
+      L_PAREN "("
+      IN_KW "in"
+      WHITESPACE " "
+      PATH
+        PATH
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "foo"
+          COLON2 "::"
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "bar"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "baz"
+      R_PAREN ")"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "e"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0013_use_path_self_super.rast b/crates/parser/test_data/parser/ok/0013_use_path_self_super.rast
index dba74e222eb..dba74e222eb 100644
--- a/crates/syntax/test_data/parser/ok/0013_use_path_self_super.rast
+++ b/crates/parser/test_data/parser/ok/0013_use_path_self_super.rast
diff --git a/crates/syntax/test_data/parser/ok/0013_use_path_self_super.rs b/crates/parser/test_data/parser/ok/0013_use_path_self_super.rs
index 9d9eb99175b..9d9eb99175b 100644
--- a/crates/syntax/test_data/parser/ok/0013_use_path_self_super.rs
+++ b/crates/parser/test_data/parser/ok/0013_use_path_self_super.rs
diff --git a/crates/parser/test_data/parser/ok/0013_use_path_self_super.txt b/crates/parser/test_data/parser/ok/0013_use_path_self_super.txt
new file mode 100644
index 00000000000..8a0149caca1
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0013_use_path_self_super.txt
@@ -0,0 +1,36 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              SELF_KW "self"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                SUPER_KW "super"
+          COLON2 "::"
+          PATH_SEGMENT
+            NAME_REF
+              SUPER_KW "super"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "bar"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0014_use_tree.rast b/crates/parser/test_data/parser/ok/0014_use_tree.rast
index 4389d2d4bce..4389d2d4bce 100644
--- a/crates/syntax/test_data/parser/ok/0014_use_tree.rast
+++ b/crates/parser/test_data/parser/ok/0014_use_tree.rast
diff --git a/crates/syntax/test_data/parser/ok/0014_use_tree.rs b/crates/parser/test_data/parser/ok/0014_use_tree.rs
index 5e4aa3a3321..5e4aa3a3321 100644
--- a/crates/syntax/test_data/parser/ok/0014_use_tree.rs
+++ b/crates/parser/test_data/parser/ok/0014_use_tree.rs
diff --git a/crates/parser/test_data/parser/ok/0014_use_tree.txt b/crates/parser/test_data/parser/ok/0014_use_tree.txt
new file mode 100644
index 00000000000..b37edc365b4
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0014_use_tree.txt
@@ -0,0 +1,95 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      STAR "*"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      COLON2 "::"
+      STAR "*"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      COLON2 "::"
+      USE_TREE_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      USE_TREE_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+      COLON2 "::"
+      STAR "*"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+      COLON2 "::"
+      USE_TREE_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          COLON2 "::"
+          NAME_REF
+            IDENT "foo"
+      COLON2 "::"
+      USE_TREE_LIST
+        L_CURLY "{"
+        USE_TREE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "a"
+        COMMA ","
+        WHITESPACE " "
+        USE_TREE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "b"
+        COMMA ","
+        WHITESPACE " "
+        USE_TREE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "c"
+        R_CURLY "}"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0015_use_tree.rast b/crates/parser/test_data/parser/ok/0015_use_tree.rast
index d7e93f7eb75..d7e93f7eb75 100644
--- a/crates/syntax/test_data/parser/ok/0015_use_tree.rast
+++ b/crates/parser/test_data/parser/ok/0015_use_tree.rast
diff --git a/crates/syntax/test_data/parser/ok/0015_use_tree.rs b/crates/parser/test_data/parser/ok/0015_use_tree.rs
index 46a0783a2bd..46a0783a2bd 100644
--- a/crates/syntax/test_data/parser/ok/0015_use_tree.rs
+++ b/crates/parser/test_data/parser/ok/0015_use_tree.rs
diff --git a/crates/parser/test_data/parser/ok/0015_use_tree.txt b/crates/parser/test_data/parser/ok/0015_use_tree.txt
new file mode 100644
index 00000000000..ddf8aad6fcd
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0015_use_tree.txt
@@ -0,0 +1,65 @@
+SOURCE_FILE
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+      WHITESPACE " "
+      RENAME
+        AS_KW "as"
+        WHITESPACE " "
+        NAME
+          IDENT "bar"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "foo"
+      COLON2 "::"
+      USE_TREE_LIST
+        L_CURLY "{"
+        USE_TREE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "a"
+          WHITESPACE " "
+          RENAME
+            AS_KW "as"
+            WHITESPACE " "
+            NAME
+              IDENT "b"
+        COMMA ","
+        WHITESPACE " "
+        USE_TREE
+          STAR "*"
+        COMMA ","
+        WHITESPACE " "
+        USE_TREE
+          COLON2 "::"
+          STAR "*"
+        COMMA ","
+        WHITESPACE " "
+        USE_TREE
+          PATH
+            PATH_SEGMENT
+              COLON2 "::"
+              NAME_REF
+                IDENT "foo"
+          WHITESPACE " "
+          RENAME
+            AS_KW "as"
+            WHITESPACE " "
+            NAME
+              IDENT "x"
+        R_CURLY "}"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0016_struct_flavors.rast b/crates/parser/test_data/parser/ok/0016_struct_flavors.rast
index b15f41dd7e9..b15f41dd7e9 100644
--- a/crates/syntax/test_data/parser/ok/0016_struct_flavors.rast
+++ b/crates/parser/test_data/parser/ok/0016_struct_flavors.rast
diff --git a/crates/syntax/test_data/parser/ok/0016_struct_flavors.rs b/crates/parser/test_data/parser/ok/0016_struct_flavors.rs
index 69638350c46..69638350c46 100644
--- a/crates/syntax/test_data/parser/ok/0016_struct_flavors.rs
+++ b/crates/parser/test_data/parser/ok/0016_struct_flavors.rs
diff --git a/crates/parser/test_data/parser/ok/0016_struct_flavors.txt b/crates/parser/test_data/parser/ok/0016_struct_flavors.txt
new file mode 100644
index 00000000000..eb2724e2f36
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0016_struct_flavors.txt
@@ -0,0 +1,93 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "A"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "B"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "C"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "D"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "a"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      COMMA ","
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        NAME
+          IDENT "b"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "E"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      TUPLE_FIELD
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "x"
+      COMMA ","
+      WHITESPACE " "
+      TUPLE_FIELD
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "y"
+      COMMA ","
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0017_attr_trailing_comma.rast b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast
index 938a3f17b68..938a3f17b68 100644
--- a/crates/syntax/test_data/parser/ok/0017_attr_trailing_comma.rast
+++ b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast
diff --git a/crates/syntax/test_data/parser/ok/0017_attr_trailing_comma.rs b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rs
index fe0a7bb97e3..fe0a7bb97e3 100644
--- a/crates/syntax/test_data/parser/ok/0017_attr_trailing_comma.rs
+++ b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rs
diff --git a/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.txt b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.txt
new file mode 100644
index 00000000000..7c914e2542e
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.txt
@@ -0,0 +1,30 @@
+SOURCE_FILE
+  FN
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "foo"
+        TOKEN_TREE
+          L_PAREN "("
+          IDENT "a"
+          COMMA ","
+          R_PAREN ")"
+      R_BRACK "]"
+    WHITESPACE "\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0018_struct_type_params.rast b/crates/parser/test_data/parser/ok/0018_struct_type_params.rast
index f845d5cffa8..f845d5cffa8 100644
--- a/crates/syntax/test_data/parser/ok/0018_struct_type_params.rast
+++ b/crates/parser/test_data/parser/ok/0018_struct_type_params.rast
diff --git a/crates/syntax/test_data/parser/ok/0018_struct_type_params.rs b/crates/parser/test_data/parser/ok/0018_struct_type_params.rs
index 88c544923b5..88c544923b5 100644
--- a/crates/syntax/test_data/parser/ok/0018_struct_type_params.rs
+++ b/crates/parser/test_data/parser/ok/0018_struct_type_params.rs
diff --git a/crates/parser/test_data/parser/ok/0018_struct_type_params.txt b/crates/parser/test_data/parser/ok/0018_struct_type_params.txt
new file mode 100644
index 00000000000..11ebc7efb9f
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0018_struct_type_params.txt
@@ -0,0 +1,274 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S1"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S2"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      TUPLE_FIELD
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S3"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE " "
+      RECORD_FIELD
+        NAME
+          IDENT "u"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE " "
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S4"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S5"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S6"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        COLON ":"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S7"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'b"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S8"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'b"
+        WHITESPACE " "
+        PLUS "+"
+      WHITESPACE " "
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S9"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'b"
+        WHITESPACE " "
+        PLUS "+"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'c"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S10"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+      COMMA ","
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S11"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+      COMMA ","
+      WHITESPACE " "
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'b"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S12"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'b"
+        PLUS "+"
+      COMMA ","
+      WHITESPACE " "
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'b"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'c"
+      COMMA ","
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S13"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S14"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "U"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S15"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "U"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0019_enums.rast b/crates/parser/test_data/parser/ok/0019_enums.rast
index c3df008146d..c3df008146d 100644
--- a/crates/syntax/test_data/parser/ok/0019_enums.rast
+++ b/crates/parser/test_data/parser/ok/0019_enums.rast
diff --git a/crates/syntax/test_data/parser/ok/0019_enums.rs b/crates/parser/test_data/parser/ok/0019_enums.rs
index 7a1afa0e62f..7a1afa0e62f 100644
--- a/crates/syntax/test_data/parser/ok/0019_enums.rs
+++ b/crates/parser/test_data/parser/ok/0019_enums.rs
diff --git a/crates/parser/test_data/parser/ok/0019_enums.txt b/crates/parser/test_data/parser/ok/0019_enums.txt
new file mode 100644
index 00000000000..dd47e3aa47a
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0019_enums.txt
@@ -0,0 +1,155 @@
+SOURCE_FILE
+  ENUM
+    ENUM_KW "enum"
+    WHITESPACE " "
+    NAME
+      IDENT "E1"
+    WHITESPACE " "
+    VARIANT_LIST
+      L_CURLY "{"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  ENUM
+    ENUM_KW "enum"
+    WHITESPACE " "
+    NAME
+      IDENT "E2"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    WHITESPACE " "
+    VARIANT_LIST
+      L_CURLY "{"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  ENUM
+    ENUM_KW "enum"
+    WHITESPACE " "
+    NAME
+      IDENT "E3"
+    WHITESPACE " "
+    VARIANT_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "X"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  ENUM
+    ENUM_KW "enum"
+    WHITESPACE " "
+    NAME
+      IDENT "E4"
+    WHITESPACE " "
+    VARIANT_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "X"
+      COMMA ","
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  ENUM
+    ENUM_KW "enum"
+    WHITESPACE " "
+    NAME
+      IDENT "E5"
+    WHITESPACE " "
+    VARIANT_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "A"
+      COMMA ","
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "B"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        LITERAL
+          INT_NUMBER "92"
+      COMMA ","
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "C"
+        WHITESPACE " "
+        RECORD_FIELD_LIST
+          L_CURLY "{"
+          WHITESPACE "\n        "
+          RECORD_FIELD
+            NAME
+              IDENT "a"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "u32"
+          COMMA ","
+          WHITESPACE "\n        "
+          RECORD_FIELD
+            VISIBILITY
+              PUB_KW "pub"
+            WHITESPACE " "
+            NAME
+              IDENT "b"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "f64"
+          COMMA ","
+          WHITESPACE "\n    "
+          R_CURLY "}"
+      COMMA ","
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "F"
+        WHITESPACE " "
+        RECORD_FIELD_LIST
+          L_CURLY "{"
+          R_CURLY "}"
+      COMMA ","
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "D"
+        TUPLE_FIELD_LIST
+          L_PAREN "("
+          TUPLE_FIELD
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "u32"
+          COMMA ","
+          R_PAREN ")"
+      COMMA ","
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "E"
+        TUPLE_FIELD_LIST
+          L_PAREN "("
+          R_PAREN ")"
+      COMMA ","
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast b/crates/parser/test_data/parser/ok/0020_type_param_bounds.rast
index 9d4b001aed9..9d4b001aed9 100644
--- a/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast
+++ b/crates/parser/test_data/parser/ok/0020_type_param_bounds.rast
diff --git a/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rs b/crates/parser/test_data/parser/ok/0020_type_param_bounds.rs
index 7128989789a..7128989789a 100644
--- a/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rs
+++ b/crates/parser/test_data/parser/ok/0020_type_param_bounds.rs
diff --git a/crates/parser/test_data/parser/ok/0020_type_param_bounds.txt b/crates/parser/test_data/parser/ok/0020_type_param_bounds.txt
new file mode 100644
index 00000000000..043a966ff97
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0020_type_param_bounds.txt
@@ -0,0 +1,283 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "A"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "B"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        TYPE_BOUND_LIST
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "C"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'a"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "D"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          WHITESPACE " "
+          PLUS "+"
+      WHITESPACE " "
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "E"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'d"
+      WHITESPACE " "
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "F"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'d"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Clone"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "G"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Clone"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Copy"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "H"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "Foo"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      SELF_KW "self"
+                COLON2 "::"
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Bar"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'a"
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "I"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        TYPE_BOUND_LIST
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "U"
+        COLON ":"
+        TYPE_BOUND_LIST
+      COMMA ","
+      R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "K"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'d"
+      COMMA ","
+      WHITESPACE " "
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'d"
+        COLON ":"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'a"
+        WHITESPACE " "
+        PLUS "+"
+        WHITESPACE " "
+        LIFETIME
+          LIFETIME_IDENT "'b"
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            LIFETIME
+              LIFETIME_IDENT "'d"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Clone"
+      R_ANGLE ">"
+    SEMICOLON ";"
diff --git a/crates/syntax/test_data/parser/ok/0022_empty_extern_block.rast b/crates/parser/test_data/parser/ok/0022_empty_extern_block.rast
index 26abae3b29d..26abae3b29d 100644
--- a/crates/syntax/test_data/parser/ok/0022_empty_extern_block.rast
+++ b/crates/parser/test_data/parser/ok/0022_empty_extern_block.rast
diff --git a/crates/syntax/test_data/parser/ok/0022_empty_extern_block.rs b/crates/parser/test_data/parser/ok/0022_empty_extern_block.rs
index f5fe0e6ef30..f5fe0e6ef30 100644
--- a/crates/syntax/test_data/parser/ok/0022_empty_extern_block.rs
+++ b/crates/parser/test_data/parser/ok/0022_empty_extern_block.rs
diff --git a/crates/parser/test_data/parser/ok/0022_empty_extern_block.txt b/crates/parser/test_data/parser/ok/0022_empty_extern_block.txt
new file mode 100644
index 00000000000..ef2fb66dd52
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0022_empty_extern_block.txt
@@ -0,0 +1,21 @@
+SOURCE_FILE
+  EXTERN_BLOCK
+    ABI
+      EXTERN_KW "extern"
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  EXTERN_BLOCK
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0023_static_items.rast b/crates/parser/test_data/parser/ok/0023_static_items.rast
index 9374cf5e965..9374cf5e965 100644
--- a/crates/syntax/test_data/parser/ok/0023_static_items.rast
+++ b/crates/parser/test_data/parser/ok/0023_static_items.rast
diff --git a/crates/syntax/test_data/parser/ok/0023_static_items.rs b/crates/parser/test_data/parser/ok/0023_static_items.rs
index 5fb92ce33f0..5fb92ce33f0 100644
--- a/crates/syntax/test_data/parser/ok/0023_static_items.rs
+++ b/crates/parser/test_data/parser/ok/0023_static_items.rs
diff --git a/crates/parser/test_data/parser/ok/0023_static_items.txt b/crates/parser/test_data/parser/ok/0023_static_items.txt
new file mode 100644
index 00000000000..b164e828e30
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0023_static_items.txt
@@ -0,0 +1,41 @@
+SOURCE_FILE
+  STATIC
+    STATIC_KW "static"
+    WHITESPACE " "
+    NAME
+      IDENT "FOO"
+    COLON ":"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "u32"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    LITERAL
+      INT_NUMBER "1"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STATIC
+    STATIC_KW "static"
+    WHITESPACE " "
+    MUT_KW "mut"
+    WHITESPACE " "
+    NAME
+      IDENT "BAR"
+    COLON ":"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "i32"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    LITERAL
+      INT_NUMBER "92"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0024_const_item.rast b/crates/parser/test_data/parser/ok/0024_const_item.rast
index 6b234b0b241..6b234b0b241 100644
--- a/crates/syntax/test_data/parser/ok/0024_const_item.rast
+++ b/crates/parser/test_data/parser/ok/0024_const_item.rast
diff --git a/crates/syntax/test_data/parser/ok/0024_const_item.rs b/crates/parser/test_data/parser/ok/0024_const_item.rs
index e69de29bb2d..e69de29bb2d 100644
--- a/crates/syntax/test_data/parser/ok/0024_const_item.rs
+++ b/crates/parser/test_data/parser/ok/0024_const_item.rs
diff --git a/crates/parser/test_data/parser/ok/0024_const_item.txt b/crates/parser/test_data/parser/ok/0024_const_item.txt
new file mode 100644
index 00000000000..40b9ef804c2
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0024_const_item.txt
@@ -0,0 +1 @@
+SOURCE_FILE
diff --git a/crates/syntax/test_data/parser/ok/0025_extern_fn_in_block.rast b/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.rast
index 21ed8ebfa48..21ed8ebfa48 100644
--- a/crates/syntax/test_data/parser/ok/0025_extern_fn_in_block.rast
+++ b/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.rast
diff --git a/crates/syntax/test_data/parser/ok/0025_extern_fn_in_block.rs b/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.rs
index 289809809a6..289809809a6 100644
--- a/crates/syntax/test_data/parser/ok/0025_extern_fn_in_block.rs
+++ b/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.rs
diff --git a/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.txt b/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.txt
new file mode 100644
index 00000000000..9c5f5ac64e9
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0025_extern_fn_in_block.txt
@@ -0,0 +1,33 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FN
+          ABI
+            EXTERN_KW "extern"
+          WHITESPACE " "
+          FN_KW "fn"
+          WHITESPACE " "
+          NAME
+            IDENT "f"
+          PARAM_LIST
+            L_PAREN "("
+            R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0026_const_fn_in_block.rast b/crates/parser/test_data/parser/ok/0026_const_fn_in_block.rast
index ad4cd31cb65..ad4cd31cb65 100644
--- a/crates/syntax/test_data/parser/ok/0026_const_fn_in_block.rast
+++ b/crates/parser/test_data/parser/ok/0026_const_fn_in_block.rast
diff --git a/crates/syntax/test_data/parser/ok/0026_const_fn_in_block.rs b/crates/parser/test_data/parser/ok/0026_const_fn_in_block.rs
index 7641a3d28e6..7641a3d28e6 100644
--- a/crates/syntax/test_data/parser/ok/0026_const_fn_in_block.rs
+++ b/crates/parser/test_data/parser/ok/0026_const_fn_in_block.rs
diff --git a/crates/parser/test_data/parser/ok/0026_const_fn_in_block.txt b/crates/parser/test_data/parser/ok/0026_const_fn_in_block.txt
new file mode 100644
index 00000000000..ca9a3df86f6
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0026_const_fn_in_block.txt
@@ -0,0 +1,32 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FN
+          CONST_KW "const"
+          WHITESPACE " "
+          FN_KW "fn"
+          WHITESPACE " "
+          NAME
+            IDENT "f"
+          PARAM_LIST
+            L_PAREN "("
+            R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast b/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.rast
index eb1fa2819c0..eb1fa2819c0 100644
--- a/crates/syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast
+++ b/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.rast
diff --git a/crates/syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rs b/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.rs
index f3c5ff93863..f3c5ff93863 100644
--- a/crates/syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rs
+++ b/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.rs
diff --git a/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.txt b/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.txt
new file mode 100644
index 00000000000..88ebd109520
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0027_unsafe_fn_in_block.txt
@@ -0,0 +1,43 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FN
+          UNSAFE_KW "unsafe"
+          WHITESPACE " "
+          FN_KW "fn"
+          WHITESPACE " "
+          NAME
+            IDENT "f"
+          PARAM_LIST
+            L_PAREN "("
+            R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        BLOCK_EXPR
+          UNSAFE_KW "unsafe"
+          WHITESPACE " "
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "92"
+            WHITESPACE " "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0028_operator_binding_power.rast b/crates/parser/test_data/parser/ok/0028_operator_binding_power.rast
index 96c75052fa8..96c75052fa8 100644
--- a/crates/syntax/test_data/parser/ok/0028_operator_binding_power.rast
+++ b/crates/parser/test_data/parser/ok/0028_operator_binding_power.rast
diff --git a/crates/syntax/test_data/parser/ok/0028_operator_binding_power.rs b/crates/parser/test_data/parser/ok/0028_operator_binding_power.rs
index cc9598470d8..cc9598470d8 100644
--- a/crates/syntax/test_data/parser/ok/0028_operator_binding_power.rs
+++ b/crates/parser/test_data/parser/ok/0028_operator_binding_power.rs
diff --git a/crates/parser/test_data/parser/ok/0028_operator_binding_power.txt b/crates/parser/test_data/parser/ok/0028_operator_binding_power.txt
new file mode 100644
index 00000000000..ae08c0756aa
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0028_operator_binding_power.txt
@@ -0,0 +1,186 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "binding_power"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "x"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BIN_EXPR
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "1"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              BIN_EXPR
+                BIN_EXPR
+                  LITERAL
+                    INT_NUMBER "2"
+                  WHITESPACE " "
+                  STAR "*"
+                  WHITESPACE " "
+                  LITERAL
+                    INT_NUMBER "3"
+                WHITESPACE " "
+                PERCENT "%"
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "4"
+            WHITESPACE " "
+            MINUS "-"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "5"
+              WHITESPACE " "
+              SLASH "/"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "6"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            PLUS "+"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              STAR "*"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            SHL "<<"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            AMP "&"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              SHR ">>"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            CARET "^"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              AMP "&"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            PIPE "|"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              CARET "^"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            EQ2 "=="
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              PIPE "|"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            WHITESPACE " "
+            AMP2 "&&"
+            WHITESPACE " "
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "2"
+              WHITESPACE " "
+              EQ2 "=="
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        COMMENT "//1 || 2 && 2;"
+        WHITESPACE "\n    "
+        COMMENT "//1 .. 2 || 3;"
+        WHITESPACE "\n    "
+        COMMENT "//1 = 2 .. 3;"
+        WHITESPACE "\n    "
+        COMMENT "//---&*1 - --2 * 9;"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0029_range_forms.rast b/crates/parser/test_data/parser/ok/0029_range_forms.rast
index 486bab8df10..486bab8df10 100644
--- a/crates/syntax/test_data/parser/ok/0029_range_forms.rast
+++ b/crates/parser/test_data/parser/ok/0029_range_forms.rast
diff --git a/crates/syntax/test_data/parser/ok/0029_range_forms.rs b/crates/parser/test_data/parser/ok/0029_range_forms.rs
index f9ff444d400..f9ff444d400 100644
--- a/crates/syntax/test_data/parser/ok/0029_range_forms.rs
+++ b/crates/parser/test_data/parser/ok/0029_range_forms.rs
diff --git a/crates/parser/test_data/parser/ok/0029_range_forms.txt b/crates/parser/test_data/parser/ok/0029_range_forms.txt
new file mode 100644
index 00000000000..5acc54e713e
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0029_range_forms.txt
@@ -0,0 +1,152 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RANGE_EXPR
+            DOT2 ".."
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "1"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            RANGE_EXPR
+              DOT2 ".."
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "z"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "2"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "x"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            RANGE_EXPR
+              LITERAL
+                FALSE_KW "false"
+              DOT2 ".."
+              BIN_EXPR
+                LITERAL
+                  INT_NUMBER "1"
+                WHITESPACE " "
+                EQ2 "=="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "x"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          RANGE_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            DOT2 ".."
+          SEMICOLON ";"
+        WHITESPACE "\n    \n    "
+        EXPR_STMT
+          RANGE_EXPR
+            DOT2EQ "..="
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "1"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            RANGE_EXPR
+              DOT2EQ "..="
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "z"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "2"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "x"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            RANGE_EXPR
+              LITERAL
+                FALSE_KW "false"
+              DOT2EQ "..="
+              BIN_EXPR
+                LITERAL
+                  INT_NUMBER "1"
+                WHITESPACE " "
+                EQ2 "=="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "x"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          RANGE_EXPR
+            LITERAL
+              INT_NUMBER "1"
+            DOT2 ".."
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0030_string_suffixes.rast b/crates/parser/test_data/parser/ok/0030_string_suffixes.rast
index 9f59c0ecb69..9f59c0ecb69 100644
--- a/crates/syntax/test_data/parser/ok/0030_string_suffixes.rast
+++ b/crates/parser/test_data/parser/ok/0030_string_suffixes.rast
diff --git a/crates/syntax/test_data/parser/ok/0030_string_suffixes.rs b/crates/parser/test_data/parser/ok/0030_string_suffixes.rs
index 261aad1fb6b..261aad1fb6b 100644
--- a/crates/syntax/test_data/parser/ok/0030_string_suffixes.rs
+++ b/crates/parser/test_data/parser/ok/0030_string_suffixes.rs
diff --git a/crates/parser/test_data/parser/ok/0030_string_suffixes.txt b/crates/parser/test_data/parser/ok/0030_string_suffixes.txt
new file mode 100644
index 00000000000..44211c7c420
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0030_string_suffixes.txt
@@ -0,0 +1,64 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            CHAR "'c'u32"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            STRING "\"string\"invalid"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            BYTE "b'b'_suff"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            BYTE_STRING "b\"bs\"invalid"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0030_traits.rast b/crates/parser/test_data/parser/ok/0030_traits.rast
index d07c6683a3d..d07c6683a3d 100644
--- a/crates/syntax/test_data/parser/ok/0030_traits.rast
+++ b/crates/parser/test_data/parser/ok/0030_traits.rast
diff --git a/crates/syntax/test_data/parser/ok/0030_traits.rs b/crates/parser/test_data/parser/ok/0030_traits.rs
index ac30843eff6..ac30843eff6 100644
--- a/crates/syntax/test_data/parser/ok/0030_traits.rs
+++ b/crates/parser/test_data/parser/ok/0030_traits.rs
diff --git a/crates/parser/test_data/parser/ok/0030_traits.txt b/crates/parser/test_data/parser/ok/0030_traits.txt
new file mode 100644
index 00000000000..44423581e6a
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0030_traits.txt
@@ -0,0 +1,61 @@
+SOURCE_FILE
+  TRAIT
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "Runnable"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "handler"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  TRAIT
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "TraitWithExpr"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "fn_with_expr"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "x"
+            COLON ":"
+            WHITESPACE " "
+            ARRAY_TYPE
+              L_BRACK "["
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "i32"
+              SEMICOLON ";"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "1"
+              R_BRACK "]"
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0031_extern.rast b/crates/parser/test_data/parser/ok/0031_extern.rast
index 8150d445f37..8150d445f37 100644
--- a/crates/syntax/test_data/parser/ok/0031_extern.rast
+++ b/crates/parser/test_data/parser/ok/0031_extern.rast
diff --git a/crates/syntax/test_data/parser/ok/0031_extern.rs b/crates/parser/test_data/parser/ok/0031_extern.rs
index b33ac273ca6..b33ac273ca6 100644
--- a/crates/syntax/test_data/parser/ok/0031_extern.rs
+++ b/crates/parser/test_data/parser/ok/0031_extern.rs
diff --git a/crates/parser/test_data/parser/ok/0031_extern.txt b/crates/parser/test_data/parser/ok/0031_extern.txt
new file mode 100644
index 00000000000..70b52780862
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0031_extern.txt
@@ -0,0 +1,973 @@
+SOURCE_FILE
+  EXTERN_BLOCK
+    ABI
+      EXTERN_KW "extern"
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "socket"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "domain"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "ty"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "protocol"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "bind"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "fd"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "addr"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "sockaddr"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "connect"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "address"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "sockaddr"
+          COMMA ","
+          WHITESPACE "\n                   "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "listen"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "backlog"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "getsockname"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "address"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "sockaddr"
+          COMMA ","
+          WHITESPACE "\n                       "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "address_len"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "getsockopt"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "sockfd"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE "\n                      "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "level"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE "\n                      "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "optname"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE "\n                      "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "optval"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "c_void"
+          COMMA ","
+          WHITESPACE "\n                      "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "optlen"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "setsockopt"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "level"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "name"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE "\n                      "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "value"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "c_void"
+          COMMA ","
+          WHITESPACE "\n                      "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "option_len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "getpeername"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "address"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "sockaddr"
+          COMMA ","
+          WHITESPACE "\n                       "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "address_len"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "c_int"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "sendto"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "buf"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "c_void"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "size_t"
+          COMMA ","
+          WHITESPACE "\n                  "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "flags"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "addr"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "sockaddr"
+          COMMA ","
+          WHITESPACE "\n                  "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "addrlen"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "ssize_t"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "send"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "buf"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "c_void"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "size_t"
+          COMMA ","
+          WHITESPACE "\n                "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "flags"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "ssize_t"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "recvfrom"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "buf"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "c_void"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "size_t"
+          COMMA ","
+          WHITESPACE "\n                    "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "flags"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "addr"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "sockaddr"
+          COMMA ","
+          WHITESPACE "\n                    "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "addrlen"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "socklen_t"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "ssize_t"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "recv"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "socket"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "buf"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    COLON2 "::"
+                    NAME_REF
+                      IDENT "c_void"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "len"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "size_t"
+          COMMA ","
+          WHITESPACE "\n                "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "flags"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  COLON2 "::"
+                  NAME_REF
+                    IDENT "c_int"
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "ssize_t"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0032_where_for.rast b/crates/parser/test_data/parser/ok/0032_where_for.rast
index ee66eab5300..ee66eab5300 100644
--- a/crates/syntax/test_data/parser/ok/0032_where_for.rast
+++ b/crates/parser/test_data/parser/ok/0032_where_for.rast
diff --git a/crates/syntax/test_data/parser/ok/0032_where_for.rs b/crates/parser/test_data/parser/ok/0032_where_for.rs
index 588170fbef5..588170fbef5 100644
--- a/crates/syntax/test_data/parser/ok/0032_where_for.rs
+++ b/crates/parser/test_data/parser/ok/0032_where_for.rs
diff --git a/crates/parser/test_data/parser/ok/0032_where_for.txt b/crates/parser/test_data/parser/ok/0032_where_for.txt
new file mode 100644
index 00000000000..86f6af97c73
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0032_where_for.txt
@@ -0,0 +1,93 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "test_serialization"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "SER"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "SER"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Serialize"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            FOR_TYPE
+              FOR_KW "for"
+              GENERIC_PARAM_LIST
+                L_ANGLE "<"
+                LIFETIME_PARAM
+                  LIFETIME
+                    LIFETIME_IDENT "'de"
+                R_ANGLE ">"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Deserialize"
+                    GENERIC_ARG_LIST
+                      L_ANGLE "<"
+                      LIFETIME_ARG
+                        LIFETIME
+                          LIFETIME_IDENT "'de"
+                      R_ANGLE ">"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "PartialEq"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "std"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "fmt"
+                COLON2 "::"
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Debug"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0033_label_break.rast b/crates/parser/test_data/parser/ok/0033_label_break.rast
index fbda85797e1..fbda85797e1 100644
--- a/crates/syntax/test_data/parser/ok/0033_label_break.rast
+++ b/crates/parser/test_data/parser/ok/0033_label_break.rast
diff --git a/crates/syntax/test_data/parser/ok/0033_label_break.rs b/crates/parser/test_data/parser/ok/0033_label_break.rs
index 728d78137c9..728d78137c9 100644
--- a/crates/syntax/test_data/parser/ok/0033_label_break.rs
+++ b/crates/parser/test_data/parser/ok/0033_label_break.rs
diff --git a/crates/parser/test_data/parser/ok/0033_label_break.txt b/crates/parser/test_data/parser/ok/0033_label_break.txt
new file mode 100644
index 00000000000..9807bf0d9a6
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0033_label_break.txt
@@ -0,0 +1,227 @@
+SOURCE_FILE
+  FN
+    COMMENT "// format with label break value."
+    WHITESPACE "\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            LABEL
+              LIFETIME
+                LIFETIME_IDENT "'empty_block"
+              COLON ":"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            LABEL
+              LIFETIME
+                LIFETIME_IDENT "'block"
+              COLON ":"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "do_thing"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                SEMICOLON ";"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                IF_EXPR
+                  IF_KW "if"
+                  WHITESPACE " "
+                  CONDITION
+                    CALL_EXPR
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "condition_not_met"
+                      ARG_LIST
+                        L_PAREN "("
+                        R_PAREN ")"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE "\n            "
+                      EXPR_STMT
+                        BREAK_EXPR
+                          BREAK_KW "break"
+                          WHITESPACE " "
+                          LIFETIME
+                            LIFETIME_IDENT "'block"
+                        SEMICOLON ";"
+                      WHITESPACE "\n        "
+                      R_CURLY "}"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "do_next_thing"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                SEMICOLON ";"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                IF_EXPR
+                  IF_KW "if"
+                  WHITESPACE " "
+                  CONDITION
+                    CALL_EXPR
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "condition_not_met"
+                      ARG_LIST
+                        L_PAREN "("
+                        R_PAREN ")"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE "\n            "
+                      EXPR_STMT
+                        BREAK_EXPR
+                          BREAK_KW "break"
+                          WHITESPACE " "
+                          LIFETIME
+                            LIFETIME_IDENT "'block"
+                        SEMICOLON ";"
+                      WHITESPACE "\n        "
+                      R_CURLY "}"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "do_last_thing"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                SEMICOLON ";"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "result"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BLOCK_EXPR
+            LABEL
+              LIFETIME
+                LIFETIME_IDENT "'block"
+              COLON ":"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                IF_EXPR
+                  IF_KW "if"
+                  WHITESPACE " "
+                  CONDITION
+                    CALL_EXPR
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "foo"
+                      ARG_LIST
+                        L_PAREN "("
+                        R_PAREN ")"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE "\n            "
+                      COMMENT "// comment"
+                      WHITESPACE "\n            "
+                      EXPR_STMT
+                        BREAK_EXPR
+                          BREAK_KW "break"
+                          WHITESPACE " "
+                          LIFETIME
+                            LIFETIME_IDENT "'block"
+                          WHITESPACE " "
+                          LITERAL
+                            INT_NUMBER "1"
+                        SEMICOLON ";"
+                      WHITESPACE "\n        "
+                      R_CURLY "}"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                IF_EXPR
+                  IF_KW "if"
+                  WHITESPACE " "
+                  CONDITION
+                    CALL_EXPR
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "bar"
+                      ARG_LIST
+                        L_PAREN "("
+                        R_PAREN ")"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE "\n            "
+                      COMMENT "/* comment */"
+                      WHITESPACE "\n            "
+                      EXPR_STMT
+                        BREAK_EXPR
+                          BREAK_KW "break"
+                          WHITESPACE " "
+                          LIFETIME
+                            LIFETIME_IDENT "'block"
+                          WHITESPACE " "
+                          LITERAL
+                            INT_NUMBER "2"
+                        SEMICOLON ";"
+                      WHITESPACE "\n        "
+                      R_CURLY "}"
+              WHITESPACE "\n        "
+              LITERAL
+                INT_NUMBER "3"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0034_crate_path_in_call.rast b/crates/parser/test_data/parser/ok/0034_crate_path_in_call.rast
index 9a6010d3622..9a6010d3622 100644
--- a/crates/syntax/test_data/parser/ok/0034_crate_path_in_call.rast
+++ b/crates/parser/test_data/parser/ok/0034_crate_path_in_call.rast
diff --git a/crates/syntax/test_data/parser/ok/0034_crate_path_in_call.rs b/crates/parser/test_data/parser/ok/0034_crate_path_in_call.rs
index f1ed30220ae..f1ed30220ae 100644
--- a/crates/syntax/test_data/parser/ok/0034_crate_path_in_call.rs
+++ b/crates/parser/test_data/parser/ok/0034_crate_path_in_call.rs
diff --git a/crates/parser/test_data/parser/ok/0034_crate_path_in_call.txt b/crates/parser/test_data/parser/ok/0034_crate_path_in_call.txt
new file mode 100644
index 00000000000..2b3b86ebf2d
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0034_crate_path_in_call.txt
@@ -0,0 +1,43 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "make_query"
+            ARG_LIST
+              L_PAREN "("
+              PATH_EXPR
+                PATH
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          CRATE_KW "crate"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "module_map"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "module_tree"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0035_weird_exprs.rast b/crates/parser/test_data/parser/ok/0035_weird_exprs.rast
index 672a12d0878..672a12d0878 100644
--- a/crates/syntax/test_data/parser/ok/0035_weird_exprs.rast
+++ b/crates/parser/test_data/parser/ok/0035_weird_exprs.rast
diff --git a/crates/syntax/test_data/parser/ok/0035_weird_exprs.rs b/crates/parser/test_data/parser/ok/0035_weird_exprs.rs
index 8c13231631c..8c13231631c 100644
--- a/crates/syntax/test_data/parser/ok/0035_weird_exprs.rs
+++ b/crates/parser/test_data/parser/ok/0035_weird_exprs.rs
diff --git a/crates/parser/test_data/parser/ok/0035_weird_exprs.txt b/crates/parser/test_data/parser/ok/0035_weird_exprs.txt
new file mode 100644
index 00000000000..5f62748c479
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0035_weird_exprs.txt
@@ -0,0 +1,2337 @@
+SOURCE_FILE
+  COMMENT "//! Adapted from a `rustc` test, which can be found at "
+  WHITESPACE "\n"
+  COMMENT "//! https://github.com/rust-lang/rust/blob/6d34ec18c7d7e574553f6347ecf08e1e1c45c13d/src/test/run-pass/weird-exprs.rs."
+  WHITESPACE "\n"
+  COMMENT "//! "
+  WHITESPACE "\n"
+  COMMENT "//! Reported to rust-analyzer in https://github.com/rust-analyzer/rust-analyzer/issues/290"
+  WHITESPACE "\n\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "allow"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "non_camel_case_types"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "allow"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "dead_code"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "allow"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "unreachable_code"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "allow"
+      TOKEN_TREE
+        L_PAREN "("
+        IDENT "unused_parens"
+        R_PAREN ")"
+    R_BRACK "]"
+  WHITESPACE "\n\n"
+  ATTR
+    POUND "#"
+    BANG "!"
+    L_BRACK "["
+    META
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "recursion_limit"
+      WHITESPACE " "
+      EQ "="
+      WHITESPACE " "
+      LITERAL
+        STRING "\"128\""
+    R_BRACK "]"
+  WHITESPACE "\n\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "std"
+          COLON2 "::"
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "cell"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Cell"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  USE
+    USE_KW "use"
+    WHITESPACE " "
+    USE_TREE
+      PATH
+        PATH
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "std"
+          COLON2 "::"
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "mem"
+        COLON2 "::"
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "swap"
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+  COMMENT "// Just a grab bag of stuff that you wouldn't want to actually write."
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "strange"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      PATH_TYPE
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "bool"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_x"
+          COLON ":"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "bool"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          RETURN_EXPR
+            RETURN_KW "return"
+            WHITESPACE " "
+            LITERAL
+              TRUE_KW "true"
+          SEMICOLON ";"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "funny"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FN
+          FN_KW "fn"
+          WHITESPACE " "
+          NAME
+            IDENT "f"
+          PARAM_LIST
+            L_PAREN "("
+            PARAM
+              IDENT_PAT
+                NAME
+                  IDENT "_x"
+              COLON ":"
+              WHITESPACE " "
+              TUPLE_TYPE
+                L_PAREN "("
+                R_PAREN ")"
+            R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "f"
+            ARG_LIST
+              L_PAREN "("
+              RETURN_EXPR
+                RETURN_KW "return"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "what"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FN
+          FN_KW "fn"
+          WHITESPACE " "
+          NAME
+            IDENT "the"
+          PARAM_LIST
+            L_PAREN "("
+            PARAM
+              IDENT_PAT
+                NAME
+                  IDENT "x"
+              COLON ":"
+              WHITESPACE " "
+              REF_TYPE
+                AMP "&"
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Cell"
+                      GENERIC_ARG_LIST
+                        L_ANGLE "<"
+                        TYPE_ARG
+                          PATH_TYPE
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "bool"
+                        R_ANGLE ">"
+            R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                RETURN_EXPR
+                  RETURN_KW "return"
+                  WHITESPACE " "
+                  WHILE_EXPR
+                    WHILE_KW "while"
+                    WHITESPACE " "
+                    CONDITION
+                      PREFIX_EXPR
+                        BANG "!"
+                        METHOD_CALL_EXPR
+                          PATH_EXPR
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "x"
+                          DOT "."
+                          NAME_REF
+                            IDENT "get"
+                          ARG_LIST
+                            L_PAREN "("
+                            R_PAREN ")"
+                    WHITESPACE " "
+                    BLOCK_EXPR
+                      STMT_LIST
+                        L_CURLY "{"
+                        WHITESPACE " "
+                        EXPR_STMT
+                          METHOD_CALL_EXPR
+                            PATH_EXPR
+                              PATH
+                                PATH_SEGMENT
+                                  NAME_REF
+                                    IDENT "x"
+                            DOT "."
+                            NAME_REF
+                              IDENT "set"
+                            ARG_LIST
+                              L_PAREN "("
+                              LITERAL
+                                TRUE_KW "true"
+                              R_PAREN ")"
+                          SEMICOLON ";"
+                        WHITESPACE " "
+                        R_CURLY "}"
+                SEMICOLON ";"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "i"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          REF_EXPR
+            AMP "&"
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Cell"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "new"
+              ARG_LIST
+                L_PAREN "("
+                LITERAL
+                  FALSE_KW "false"
+                R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "dont"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              CLOSURE_EXPR
+                PARAM_LIST
+                  PIPE "|"
+                  PIPE "|"
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "the"
+                  ARG_LIST
+                    L_PAREN "("
+                    PATH_EXPR
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "i"
+                    R_PAREN ")"
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "dont"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          MACRO_CALL
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "assert"
+            BANG "!"
+            TOKEN_TREE
+              L_PAREN "("
+              TOKEN_TREE
+                L_PAREN "("
+                IDENT "i"
+                DOT "."
+                IDENT "get"
+                TOKEN_TREE
+                  L_PAREN "("
+                  R_PAREN ")"
+                R_PAREN ")"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "zombiejesus"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LOOP_EXPR
+          LOOP_KW "loop"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                WHILE_EXPR
+                  WHILE_KW "while"
+                  WHITESPACE " "
+                  CONDITION
+                    PAREN_EXPR
+                      L_PAREN "("
+                      RETURN_EXPR
+                        RETURN_KW "return"
+                      R_PAREN ")"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE "\n            "
+                      IF_EXPR
+                        IF_KW "if"
+                        WHITESPACE " "
+                        CONDITION
+                          PAREN_EXPR
+                            L_PAREN "("
+                            RETURN_EXPR
+                              RETURN_KW "return"
+                            R_PAREN ")"
+                        WHITESPACE " "
+                        BLOCK_EXPR
+                          STMT_LIST
+                            L_CURLY "{"
+                            WHITESPACE "\n                "
+                            EXPR_STMT
+                              MATCH_EXPR
+                                MATCH_KW "match"
+                                WHITESPACE " "
+                                PAREN_EXPR
+                                  L_PAREN "("
+                                  RETURN_EXPR
+                                    RETURN_KW "return"
+                                  R_PAREN ")"
+                                WHITESPACE " "
+                                MATCH_ARM_LIST
+                                  L_CURLY "{"
+                                  WHITESPACE "\n                    "
+                                  MATCH_ARM
+                                    LITERAL_PAT
+                                      LITERAL
+                                        INT_NUMBER "1"
+                                    WHITESPACE " "
+                                    FAT_ARROW "=>"
+                                    WHITESPACE " "
+                                    BLOCK_EXPR
+                                      STMT_LIST
+                                        L_CURLY "{"
+                                        WHITESPACE "\n                        "
+                                        IF_EXPR
+                                          IF_KW "if"
+                                          WHITESPACE " "
+                                          CONDITION
+                                            PAREN_EXPR
+                                              L_PAREN "("
+                                              RETURN_EXPR
+                                                RETURN_KW "return"
+                                              R_PAREN ")"
+                                          WHITESPACE " "
+                                          BLOCK_EXPR
+                                            STMT_LIST
+                                              L_CURLY "{"
+                                              WHITESPACE "\n                            "
+                                              RETURN_EXPR
+                                                RETURN_KW "return"
+                                              WHITESPACE "\n                        "
+                                              R_CURLY "}"
+                                          WHITESPACE " "
+                                          ELSE_KW "else"
+                                          WHITESPACE " "
+                                          BLOCK_EXPR
+                                            STMT_LIST
+                                              L_CURLY "{"
+                                              WHITESPACE "\n                            "
+                                              RETURN_EXPR
+                                                RETURN_KW "return"
+                                              WHITESPACE "\n                        "
+                                              R_CURLY "}"
+                                        WHITESPACE "\n                    "
+                                        R_CURLY "}"
+                                  WHITESPACE "\n                    "
+                                  MATCH_ARM
+                                    WILDCARD_PAT
+                                      UNDERSCORE "_"
+                                    WHITESPACE " "
+                                    FAT_ARROW "=>"
+                                    WHITESPACE " "
+                                    BLOCK_EXPR
+                                      STMT_LIST
+                                        L_CURLY "{"
+                                        WHITESPACE " "
+                                        RETURN_EXPR
+                                          RETURN_KW "return"
+                                        WHITESPACE " "
+                                        R_CURLY "}"
+                                  WHITESPACE "\n                "
+                                  R_CURLY "}"
+                              SEMICOLON ";"
+                            WHITESPACE "\n            "
+                            R_CURLY "}"
+                        WHITESPACE " "
+                        ELSE_KW "else"
+                        WHITESPACE " "
+                        IF_EXPR
+                          IF_KW "if"
+                          WHITESPACE " "
+                          CONDITION
+                            PAREN_EXPR
+                              L_PAREN "("
+                              RETURN_EXPR
+                                RETURN_KW "return"
+                              R_PAREN ")"
+                          WHITESPACE " "
+                          BLOCK_EXPR
+                            STMT_LIST
+                              L_CURLY "{"
+                              WHITESPACE "\n                "
+                              EXPR_STMT
+                                RETURN_EXPR
+                                  RETURN_KW "return"
+                                SEMICOLON ";"
+                              WHITESPACE "\n            "
+                              R_CURLY "}"
+                      WHITESPACE "\n        "
+                      R_CURLY "}"
+              WHITESPACE "\n        "
+              IF_EXPR
+                IF_KW "if"
+                WHITESPACE " "
+                CONDITION
+                  PAREN_EXPR
+                    L_PAREN "("
+                    RETURN_EXPR
+                      RETURN_KW "return"
+                    R_PAREN ")"
+                WHITESPACE " "
+                BLOCK_EXPR
+                  STMT_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    EXPR_STMT
+                      BREAK_EXPR
+                        BREAK_KW "break"
+                      SEMICOLON ";"
+                    WHITESPACE " "
+                    R_CURLY "}"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "notsure"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              IDENT "_x"
+          COLON ":"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "isize"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              IDENT "_y"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BIN_EXPR
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "_x"
+                WHITESPACE " "
+                EQ "="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "0"
+              R_PAREN ")"
+            WHITESPACE " "
+            EQ2 "=="
+            WHITESPACE " "
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "_x"
+                WHITESPACE " "
+                EQ "="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "0"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              IDENT "_z"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BIN_EXPR
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "_x"
+                WHITESPACE " "
+                EQ "="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "0"
+              R_PAREN ")"
+            WHITESPACE " "
+            L_ANGLE "<"
+            WHITESPACE " "
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "_x"
+                WHITESPACE " "
+                EQ "="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "0"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_a"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BIN_EXPR
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "_x"
+                WHITESPACE " "
+                PLUSEQ "+="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "0"
+              R_PAREN ")"
+            WHITESPACE " "
+            EQ2 "=="
+            WHITESPACE " "
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "_x"
+                WHITESPACE " "
+                EQ "="
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "0"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_b"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BIN_EXPR
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "swap"
+              ARG_LIST
+                L_PAREN "("
+                REF_EXPR
+                  AMP "&"
+                  MUT_KW "mut"
+                  WHITESPACE " "
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "_y"
+                COMMA ","
+                WHITESPACE " "
+                REF_EXPR
+                  AMP "&"
+                  MUT_KW "mut"
+                  WHITESPACE " "
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "_z"
+                R_PAREN ")"
+            WHITESPACE " "
+            EQ2 "=="
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "swap"
+              ARG_LIST
+                L_PAREN "("
+                REF_EXPR
+                  AMP "&"
+                  MUT_KW "mut"
+                  WHITESPACE " "
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "_y"
+                COMMA ","
+                WHITESPACE " "
+                REF_EXPR
+                  AMP "&"
+                  MUT_KW "mut"
+                  WHITESPACE " "
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "_z"
+                R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "canttouchthis"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      PATH_TYPE
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "usize"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        FN
+          FN_KW "fn"
+          WHITESPACE " "
+          NAME
+            IDENT "p"
+          PARAM_LIST
+            L_PAREN "("
+            R_PAREN ")"
+          WHITESPACE " "
+          RET_TYPE
+            THIN_ARROW "->"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "bool"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              LITERAL
+                TRUE_KW "true"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_a"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          PAREN_EXPR
+            L_PAREN "("
+            BIN_EXPR
+              MACRO_CALL
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "assert"
+                BANG "!"
+                TOKEN_TREE
+                  L_PAREN "("
+                  TOKEN_TREE
+                    L_PAREN "("
+                    TRUE_KW "true"
+                    R_PAREN ")"
+                  R_PAREN ")"
+              WHITESPACE " "
+              EQ2 "=="
+              WHITESPACE " "
+              PAREN_EXPR
+                L_PAREN "("
+                MACRO_CALL
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "assert"
+                  BANG "!"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    IDENT "p"
+                    TOKEN_TREE
+                      L_PAREN "("
+                      R_PAREN ")"
+                    R_PAREN ")"
+                R_PAREN ")"
+            R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_c"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          PAREN_EXPR
+            L_PAREN "("
+            BIN_EXPR
+              MACRO_CALL
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "assert"
+                BANG "!"
+                TOKEN_TREE
+                  L_PAREN "("
+                  TOKEN_TREE
+                    L_PAREN "("
+                    IDENT "p"
+                    TOKEN_TREE
+                      L_PAREN "("
+                      R_PAREN ")"
+                    R_PAREN ")"
+                  R_PAREN ")"
+              WHITESPACE " "
+              EQ2 "=="
+              WHITESPACE " "
+              TUPLE_EXPR
+                L_PAREN "("
+                R_PAREN ")"
+            R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_b"
+          COLON ":"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "bool"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          PAREN_EXPR
+            L_PAREN "("
+            BIN_EXPR
+              MACRO_CALL
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "println"
+                BANG "!"
+                TOKEN_TREE
+                  L_PAREN "("
+                  STRING "\"{}\""
+                  COMMA ","
+                  WHITESPACE " "
+                  INT_NUMBER "0"
+                  R_PAREN ")"
+              WHITESPACE " "
+              EQ2 "=="
+              WHITESPACE " "
+              PAREN_EXPR
+                L_PAREN "("
+                RETURN_EXPR
+                  RETURN_KW "return"
+                  WHITESPACE " "
+                  LITERAL
+                    INT_NUMBER "0"
+                R_PAREN ")"
+            R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "angrydome"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          LOOP_EXPR
+            LOOP_KW "loop"
+            WHITESPACE " "
+            BLOCK_EXPR
+              STMT_LIST
+                L_CURLY "{"
+                WHITESPACE " "
+                IF_EXPR
+                  IF_KW "if"
+                  WHITESPACE " "
+                  CONDITION
+                    BREAK_EXPR
+                      BREAK_KW "break"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE " "
+                      R_CURLY "}"
+                WHITESPACE " "
+                R_CURLY "}"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              IDENT "i"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "0"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        LOOP_EXPR
+          LOOP_KW "loop"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              EXPR_STMT
+                BIN_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "i"
+                  WHITESPACE " "
+                  PLUSEQ "+="
+                  WHITESPACE " "
+                  LITERAL
+                    INT_NUMBER "1"
+                SEMICOLON ";"
+              WHITESPACE " "
+              EXPR_STMT
+                IF_EXPR
+                  IF_KW "if"
+                  WHITESPACE " "
+                  CONDITION
+                    BIN_EXPR
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "i"
+                      WHITESPACE " "
+                      EQ2 "=="
+                      WHITESPACE " "
+                      LITERAL
+                        INT_NUMBER "1"
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      WHITESPACE " "
+                      MATCH_EXPR
+                        MATCH_KW "match"
+                        WHITESPACE " "
+                        PAREN_EXPR
+                          L_PAREN "("
+                          CONTINUE_EXPR
+                            CONTINUE_KW "continue"
+                          R_PAREN ")"
+                        WHITESPACE " "
+                        MATCH_ARM_LIST
+                          L_CURLY "{"
+                          WHITESPACE " "
+                          MATCH_ARM
+                            LITERAL_PAT
+                              LITERAL
+                                INT_NUMBER "1"
+                            WHITESPACE " "
+                            FAT_ARROW "=>"
+                            WHITESPACE " "
+                            BLOCK_EXPR
+                              STMT_LIST
+                                L_CURLY "{"
+                                WHITESPACE " "
+                                R_CURLY "}"
+                            COMMA ","
+                          WHITESPACE " "
+                          MATCH_ARM
+                            WILDCARD_PAT
+                              UNDERSCORE "_"
+                            WHITESPACE " "
+                            FAT_ARROW "=>"
+                            WHITESPACE " "
+                            MACRO_CALL
+                              PATH
+                                PATH_SEGMENT
+                                  NAME_REF
+                                    IDENT "panic"
+                              BANG "!"
+                              TOKEN_TREE
+                                L_PAREN "("
+                                STRING "\"wat\""
+                                R_PAREN ")"
+                          WHITESPACE " "
+                          R_CURLY "}"
+                      WHITESPACE " "
+                      R_CURLY "}"
+              WHITESPACE "\n      "
+              EXPR_STMT
+                BREAK_EXPR
+                  BREAK_KW "break"
+                SEMICOLON ";"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "evil_lincoln"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_evil"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          MACRO_CALL
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "println"
+            BANG "!"
+            TOKEN_TREE
+              L_PAREN "("
+              STRING "\"lincoln\""
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "dots"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          MACRO_CALL
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "assert_eq"
+            BANG "!"
+            TOKEN_TREE
+              L_PAREN "("
+              IDENT "String"
+              COLON ":"
+              COLON ":"
+              IDENT "from"
+              TOKEN_TREE
+                L_PAREN "("
+                STRING "\"..................................................\""
+                R_PAREN ")"
+              COMMA ","
+              WHITESPACE "\n               "
+              IDENT "format"
+              BANG "!"
+              TOKEN_TREE
+                L_PAREN "("
+                STRING "\"{:?}\""
+                COMMA ","
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE "\n                               "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                WHITESPACE " "
+                DOT "."
+                DOT "."
+                R_PAREN ")"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "u8"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "u8"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u8"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        IF_EXPR
+          IF_KW "if"
+          WHITESPACE " "
+          CONDITION
+            BIN_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "u8"
+              WHITESPACE " "
+              NEQ "!="
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "0u8"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              EXPR_STMT
+                MACRO_CALL
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "assert_eq"
+                  BANG "!"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    INT_NUMBER "8u8"
+                    COMMA ","
+                    WHITESPACE " "
+                    TOKEN_TREE
+                      L_CURLY "{"
+                      WHITESPACE "\n            "
+                      IDENT "macro_rules"
+                      BANG "!"
+                      WHITESPACE " "
+                      IDENT "u8"
+                      WHITESPACE " "
+                      TOKEN_TREE
+                        L_CURLY "{"
+                        WHITESPACE "\n                "
+                        TOKEN_TREE
+                          L_PAREN "("
+                          IDENT "u8"
+                          R_PAREN ")"
+                        WHITESPACE " "
+                        EQ "="
+                        R_ANGLE ">"
+                        WHITESPACE " "
+                        TOKEN_TREE
+                          L_CURLY "{"
+                          WHITESPACE "\n                    "
+                          MOD_KW "mod"
+                          WHITESPACE " "
+                          IDENT "u8"
+                          WHITESPACE " "
+                          TOKEN_TREE
+                            L_CURLY "{"
+                            WHITESPACE "\n                        "
+                            PUB_KW "pub"
+                            WHITESPACE " "
+                            FN_KW "fn"
+                            WHITESPACE " "
+                            IDENT "u8"
+                            L_ANGLE "<"
+                            LIFETIME_IDENT "'u8"
+                            COLON ":"
+                            WHITESPACE " "
+                            LIFETIME_IDENT "'u8"
+                            WHITESPACE " "
+                            PLUS "+"
+                            WHITESPACE " "
+                            LIFETIME_IDENT "'u8"
+                            R_ANGLE ">"
+                            TOKEN_TREE
+                              L_PAREN "("
+                              IDENT "u8"
+                              COLON ":"
+                              WHITESPACE " "
+                              AMP "&"
+                              LIFETIME_IDENT "'u8"
+                              WHITESPACE " "
+                              IDENT "u8"
+                              R_PAREN ")"
+                            WHITESPACE " "
+                            MINUS "-"
+                            R_ANGLE ">"
+                            WHITESPACE " "
+                            AMP "&"
+                            LIFETIME_IDENT "'u8"
+                            WHITESPACE " "
+                            IDENT "u8"
+                            WHITESPACE " "
+                            TOKEN_TREE
+                              L_CURLY "{"
+                              WHITESPACE "\n                            "
+                              STRING "\"u8\""
+                              SEMICOLON ";"
+                              WHITESPACE "\n                            "
+                              IDENT "u8"
+                              WHITESPACE "\n                        "
+                              R_CURLY "}"
+                            WHITESPACE "\n                    "
+                            R_CURLY "}"
+                          WHITESPACE "\n                "
+                          R_CURLY "}"
+                        SEMICOLON ";"
+                        WHITESPACE "\n            "
+                        R_CURLY "}"
+                      WHITESPACE "\n\n            "
+                      IDENT "u8"
+                      BANG "!"
+                      TOKEN_TREE
+                        L_PAREN "("
+                        IDENT "u8"
+                        R_PAREN ")"
+                      SEMICOLON ";"
+                      WHITESPACE "\n            "
+                      LET_KW "let"
+                      WHITESPACE " "
+                      AMP "&"
+                      IDENT "u8"
+                      COLON ":"
+                      WHITESPACE " "
+                      AMP "&"
+                      IDENT "u8"
+                      WHITESPACE " "
+                      EQ "="
+                      WHITESPACE " "
+                      IDENT "u8"
+                      COLON ":"
+                      COLON ":"
+                      IDENT "u8"
+                      TOKEN_TREE
+                        L_PAREN "("
+                        AMP "&"
+                        INT_NUMBER "8u8"
+                        R_PAREN ")"
+                      SEMICOLON ";"
+                      WHITESPACE "\n            "
+                      CRATE_KW "crate"
+                      COLON ":"
+                      COLON ":"
+                      IDENT "u8"
+                      TOKEN_TREE
+                        L_PAREN "("
+                        INT_NUMBER "0u8"
+                        R_PAREN ")"
+                      SEMICOLON ";"
+                      WHITESPACE "\n            "
+                      IDENT "u8"
+                      WHITESPACE "\n        "
+                      R_CURLY "}"
+                    R_PAREN ")"
+                SEMICOLON ";"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "fishy"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          MACRO_CALL
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "assert_eq"
+            BANG "!"
+            TOKEN_TREE
+              L_PAREN "("
+              IDENT "String"
+              COLON ":"
+              COLON ":"
+              IDENT "from"
+              TOKEN_TREE
+                L_PAREN "("
+                STRING "\"><>\""
+                R_PAREN ")"
+              COMMA ","
+              WHITESPACE "\n               "
+              IDENT "String"
+              COLON ":"
+              COLON ":"
+              L_ANGLE "<"
+              R_ANGLE ">"
+              COLON ":"
+              COLON ":"
+              IDENT "from"
+              COLON ":"
+              COLON ":"
+              L_ANGLE "<"
+              R_ANGLE ">"
+              TOKEN_TREE
+                L_PAREN "("
+                STRING "\"><>\""
+                R_PAREN ")"
+              DOT "."
+              IDENT "chars"
+              COLON ":"
+              COLON ":"
+              L_ANGLE "<"
+              R_ANGLE ">"
+              TOKEN_TREE
+                L_PAREN "("
+                R_PAREN ")"
+              DOT "."
+              IDENT "rev"
+              COLON ":"
+              COLON ":"
+              L_ANGLE "<"
+              R_ANGLE ">"
+              TOKEN_TREE
+                L_PAREN "("
+                R_PAREN ")"
+              DOT "."
+              IDENT "collect"
+              COLON ":"
+              COLON ":"
+              L_ANGLE "<"
+              IDENT "String"
+              R_ANGLE ">"
+              TOKEN_TREE
+                L_PAREN "("
+                R_PAREN ")"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "union"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        UNION
+          UNION_KW "union"
+          WHITESPACE " "
+          NAME
+            IDENT "union"
+          GENERIC_PARAM_LIST
+            L_ANGLE "<"
+            LIFETIME_PARAM
+              LIFETIME
+                LIFETIME_IDENT "'union"
+            R_ANGLE ">"
+          WHITESPACE " "
+          RECORD_FIELD_LIST
+            L_CURLY "{"
+            WHITESPACE " "
+            RECORD_FIELD
+              NAME
+                IDENT "union"
+              COLON ":"
+              WHITESPACE " "
+              REF_TYPE
+                AMP "&"
+                LIFETIME
+                  LIFETIME_IDENT "'union"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "union"
+                      GENERIC_ARG_LIST
+                        L_ANGLE "<"
+                        LIFETIME_ARG
+                          LIFETIME
+                            LIFETIME_IDENT "'union"
+                        R_ANGLE ">"
+            COMMA ","
+            WHITESPACE " "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "special_characters"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "val"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          PREFIX_EXPR
+            BANG "!"
+            PAREN_EXPR
+              L_PAREN "("
+              BIN_EXPR
+                CALL_EXPR
+                  PAREN_EXPR
+                    L_PAREN "("
+                    CLOSURE_EXPR
+                      PARAM_LIST
+                        PIPE "|"
+                        PARAM
+                          TUPLE_PAT
+                            L_PAREN "("
+                            REST_PAT
+                              DOT2 ".."
+                            R_PAREN ")"
+                          COLON ":"
+                          TUPLE_TYPE
+                            L_PAREN "("
+                            INFER_TYPE
+                              UNDERSCORE "_"
+                            COMMA ","
+                            INFER_TYPE
+                              UNDERSCORE "_"
+                            R_PAREN ")"
+                        COMMA ","
+                        PARAM
+                          IDENT_PAT
+                            NAME
+                              IDENT "__"
+                            AT "@"
+                            WILDCARD_PAT
+                              UNDERSCORE "_"
+                        PIPE "|"
+                      PATH_EXPR
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "__"
+                    R_PAREN ")"
+                  ARG_LIST
+                    L_PAREN "("
+                    TUPLE_EXPR
+                      L_PAREN "("
+                      REF_EXPR
+                        AMP "&"
+                        PREFIX_EXPR
+                          STAR "*"
+                          LITERAL
+                            STRING "\"\\\\\""
+                      COMMA ","
+                      LITERAL
+                        CHAR "'🤔'"
+                      R_PAREN ")"
+                    COMMENT "/**/"
+                    COMMA ","
+                    BLOCK_EXPR
+                      STMT_LIST
+                        L_CURLY "{"
+                        R_CURLY "}"
+                    R_PAREN ")"
+                EQ2 "=="
+                BLOCK_EXPR
+                  STMT_LIST
+                    L_CURLY "{"
+                    EXPR_STMT
+                      REF_EXPR
+                        AMP "&"
+                        INDEX_EXPR
+                          ARRAY_EXPR
+                            L_BRACK "["
+                            RANGE_EXPR
+                              DOT2EQ "..="
+                              RANGE_EXPR
+                                DOT2 ".."
+                            R_BRACK "]"
+                          L_BRACK "["
+                          RANGE_EXPR
+                            DOT2 ".."
+                          R_BRACK "]"
+                      SEMICOLON ";"
+                    R_CURLY "}"
+              R_PAREN ")"
+          COMMENT "//"
+          WHITESPACE "\n    "
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          MACRO_CALL
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "assert"
+            BANG "!"
+            TOKEN_TREE
+              L_PAREN "("
+              BANG "!"
+              IDENT "val"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "punch_card"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      IMPL_TRAIT_TYPE
+        IMPL_KW "impl"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "std"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "fmt"
+                COLON2 "::"
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Debug"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        RANGE_EXPR
+          DOT2EQ "..="
+          RANGE_EXPR
+            DOT2EQ "..="
+            RANGE_EXPR
+              DOT2 ".."
+              WHITESPACE " "
+              RANGE_EXPR
+                DOT2 ".."
+                WHITESPACE "    "
+                RANGE_EXPR
+                  DOT2 ".."
+                  WHITESPACE " "
+                  RANGE_EXPR
+                    DOT2 ".."
+                    WHITESPACE " "
+                    RANGE_EXPR
+                      DOT2 ".."
+                      WHITESPACE " "
+                      RANGE_EXPR
+                        DOT2 ".."
+                        WHITESPACE "    "
+                        RANGE_EXPR
+                          DOT2 ".."
+                          WHITESPACE " "
+                          RANGE_EXPR
+                            DOT2 ".."
+                            WHITESPACE " "
+                            RANGE_EXPR
+                              DOT2 ".."
+                              WHITESPACE " "
+                              RANGE_EXPR
+                                DOT2 ".."
+                                WHITESPACE "    "
+                                RANGE_EXPR
+                                  DOT2 ".."
+                                  WHITESPACE " "
+                                  RANGE_EXPR
+                                    DOT2EQ "..="
+                                    RANGE_EXPR
+                                      DOT2 ".."
+                                      WHITESPACE " "
+                                      RANGE_EXPR
+                                        DOT2 ".."
+                                        WHITESPACE "\n    "
+                                        RANGE_EXPR
+                                          DOT2EQ "..="
+                                          RANGE_EXPR
+                                            DOT2 ".."
+                                            WHITESPACE " "
+                                            RANGE_EXPR
+                                              DOT2EQ "..="
+                                              RANGE_EXPR
+                                                DOT2 ".."
+                                                WHITESPACE "    "
+                                                RANGE_EXPR
+                                                  DOT2 ".."
+                                                  WHITESPACE " "
+                                                  RANGE_EXPR
+                                                    DOT2 ".."
+                                                    WHITESPACE " "
+                                                    RANGE_EXPR
+                                                      DOT2 ".."
+                                                      WHITESPACE " "
+                                                      RANGE_EXPR
+                                                        DOT2 ".."
+                                                        WHITESPACE "    "
+                                                        RANGE_EXPR
+                                                          DOT2 ".."
+                                                          WHITESPACE " "
+                                                          RANGE_EXPR
+                                                            DOT2 ".."
+                                                            WHITESPACE " "
+                                                            RANGE_EXPR
+                                                              DOT2 ".."
+                                                              WHITESPACE " "
+                                                              RANGE_EXPR
+                                                                DOT2 ".."
+                                                                WHITESPACE "    "
+                                                                RANGE_EXPR
+                                                                  DOT2EQ "..="
+                                                                  RANGE_EXPR
+                                                                    DOT2EQ "..="
+                                                                    RANGE_EXPR
+                                                                      DOT2EQ "..="
+                                                                      RANGE_EXPR
+                                                                        DOT2 ".."
+                                                                        WHITESPACE "\n    "
+                                                                        RANGE_EXPR
+                                                                          DOT2EQ "..="
+                                                                          RANGE_EXPR
+                                                                            DOT2 ".."
+                                                                            WHITESPACE " "
+                                                                            RANGE_EXPR
+                                                                              DOT2EQ "..="
+                                                                              RANGE_EXPR
+                                                                                DOT2 ".."
+                                                                                WHITESPACE "    "
+                                                                                RANGE_EXPR
+                                                                                  DOT2EQ "..="
+                                                                                  RANGE_EXPR
+                                                                                    DOT2 ".."
+                                                                                    WHITESPACE " "
+                                                                                    RANGE_EXPR
+                                                                                      DOT2EQ "..="
+                                                                                      RANGE_EXPR
+                                                                                        DOT2 ".."
+                                                                                        WHITESPACE "    "
+                                                                                        RANGE_EXPR
+                                                                                          DOT2 ".."
+                                                                                          WHITESPACE " "
+                                                                                          RANGE_EXPR
+                                                                                            DOT2EQ "..="
+                                                                                            RANGE_EXPR
+                                                                                              DOT2EQ "..="
+                                                                                              RANGE_EXPR
+                                                                                                DOT2 ".."
+                                                                                                WHITESPACE "    "
+                                                                                                RANGE_EXPR
+                                                                                                  DOT2 ".."
+                                                                                                  WHITESPACE " "
+                                                                                                  RANGE_EXPR
+                                                                                                    DOT2EQ "..="
+                                                                                                    RANGE_EXPR
+                                                                                                      DOT2 ".."
+                                                                                                      WHITESPACE " "
+                                                                                                      RANGE_EXPR
+                                                                                                        DOT2 ".."
+                                                                                                        WHITESPACE "\n    "
+                                                                                                        RANGE_EXPR
+                                                                                                          DOT2EQ "..="
+                                                                                                          RANGE_EXPR
+                                                                                                            DOT2EQ "..="
+                                                                                                            RANGE_EXPR
+                                                                                                              DOT2 ".."
+                                                                                                              WHITESPACE " "
+                                                                                                              RANGE_EXPR
+                                                                                                                DOT2 ".."
+                                                                                                                WHITESPACE "    "
+                                                                                                                RANGE_EXPR
+                                                                                                                  DOT2EQ "..="
+                                                                                                                  RANGE_EXPR
+                                                                                                                    DOT2 ".."
+                                                                                                                    WHITESPACE " "
+                                                                                                                    RANGE_EXPR
+                                                                                                                      DOT2EQ "..="
+                                                                                                                      RANGE_EXPR
+                                                                                                                        DOT2 ".."
+                                                                                                                        WHITESPACE "    "
+                                                                                                                        RANGE_EXPR
+                                                                                                                          DOT2EQ "..="
+                                                                                                                          RANGE_EXPR
+                                                                                                                            DOT2 ".."
+                                                                                                                            WHITESPACE " "
+                                                                                                                            RANGE_EXPR
+                                                                                                                              DOT2 ".."
+                                                                                                                              WHITESPACE " "
+                                                                                                                              RANGE_EXPR
+                                                                                                                                DOT2 ".."
+                                                                                                                                WHITESPACE "    "
+                                                                                                                                RANGE_EXPR
+                                                                                                                                  DOT2 ".."
+                                                                                                                                  WHITESPACE " "
+                                                                                                                                  RANGE_EXPR
+                                                                                                                                    DOT2EQ "..="
+                                                                                                                                    RANGE_EXPR
+                                                                                                                                      DOT2 ".."
+                                                                                                                                      WHITESPACE " "
+                                                                                                                                      RANGE_EXPR
+                                                                                                                                        DOT2 ".."
+                                                                                                                                        WHITESPACE "\n    "
+                                                                                                                                        RANGE_EXPR
+                                                                                                                                          DOT2EQ "..="
+                                                                                                                                          RANGE_EXPR
+                                                                                                                                            DOT2 ".."
+                                                                                                                                            WHITESPACE " "
+                                                                                                                                            RANGE_EXPR
+                                                                                                                                              DOT2EQ "..="
+                                                                                                                                              RANGE_EXPR
+                                                                                                                                                DOT2 ".."
+                                                                                                                                                WHITESPACE "    "
+                                                                                                                                                RANGE_EXPR
+                                                                                                                                                  DOT2EQ "..="
+                                                                                                                                                  RANGE_EXPR
+                                                                                                                                                    DOT2 ".."
+                                                                                                                                                    WHITESPACE " "
+                                                                                                                                                    RANGE_EXPR
+                                                                                                                                                      DOT2EQ "..="
+                                                                                                                                                      RANGE_EXPR
+                                                                                                                                                        DOT2 ".."
+                                                                                                                                                        WHITESPACE "    "
+                                                                                                                                                        RANGE_EXPR
+                                                                                                                                                          DOT2 ".."
+                                                                                                                                                          WHITESPACE " "
+                                                                                                                                                          RANGE_EXPR
+                                                                                                                                                            DOT2EQ "..="
+                                                                                                                                                            RANGE_EXPR
+                                                                                                                                                              DOT2 ".."
+                                                                                                                                                              WHITESPACE " "
+                                                                                                                                                              RANGE_EXPR
+                                                                                                                                                                DOT2 ".."
+                                                                                                                                                                WHITESPACE "    "
+                                                                                                                                                                RANGE_EXPR
+                                                                                                                                                                  DOT2 ".."
+                                                                                                                                                                  WHITESPACE " "
+                                                                                                                                                                  RANGE_EXPR
+                                                                                                                                                                    DOT2EQ "..="
+                                                                                                                                                                    RANGE_EXPR
+                                                                                                                                                                      DOT2 ".."
+                                                                                                                                                                      WHITESPACE " "
+                                                                                                                                                                      RANGE_EXPR
+                                                                                                                                                                        DOT2 ".."
+                                                                                                                                                                        WHITESPACE "\n    "
+                                                                                                                                                                        RANGE_EXPR
+                                                                                                                                                                          DOT2EQ "..="
+                                                                                                                                                                          RANGE_EXPR
+                                                                                                                                                                            DOT2 ".."
+                                                                                                                                                                            WHITESPACE " "
+                                                                                                                                                                            RANGE_EXPR
+                                                                                                                                                                              DOT2EQ "..="
+                                                                                                                                                                              RANGE_EXPR
+                                                                                                                                                                                DOT2 ".."
+                                                                                                                                                                                WHITESPACE "    "
+                                                                                                                                                                                RANGE_EXPR
+                                                                                                                                                                                  DOT2EQ "..="
+                                                                                                                                                                                  RANGE_EXPR
+                                                                                                                                                                                    DOT2 ".."
+                                                                                                                                                                                    WHITESPACE " "
+                                                                                                                                                                                    RANGE_EXPR
+                                                                                                                                                                                      DOT2EQ "..="
+                                                                                                                                                                                      RANGE_EXPR
+                                                                                                                                                                                        DOT2 ".."
+                                                                                                                                                                                        WHITESPACE "    "
+                                                                                                                                                                                        RANGE_EXPR
+                                                                                                                                                                                          DOT2 ".."
+                                                                                                                                                                                          WHITESPACE " "
+                                                                                                                                                                                          RANGE_EXPR
+                                                                                                                                                                                            DOT2 ".."
+                                                                                                                                                                                            WHITESPACE " "
+                                                                                                                                                                                            RANGE_EXPR
+                                                                                                                                                                                              DOT2EQ "..="
+                                                                                                                                                                                              RANGE_EXPR
+                                                                                                                                                                                                DOT2 ".."
+                                                                                                                                                                                                WHITESPACE "    "
+                                                                                                                                                                                                RANGE_EXPR
+                                                                                                                                                                                                  DOT2 ".."
+                                                                                                                                                                                                  WHITESPACE " "
+                                                                                                                                                                                                  RANGE_EXPR
+                                                                                                                                                                                                    DOT2EQ "..="
+                                                                                                                                                                                                    RANGE_EXPR
+                                                                                                                                                                                                      DOT2 ".."
+                                                                                                                                                                                                      WHITESPACE " "
+                                                                                                                                                                                                      RANGE_EXPR
+                                                                                                                                                                                                        DOT2 ".."
+                                                                                                                                                                                                        WHITESPACE "\n    "
+                                                                                                                                                                                                        RANGE_EXPR
+                                                                                                                                                                                                          DOT2EQ "..="
+                                                                                                                                                                                                          RANGE_EXPR
+                                                                                                                                                                                                            DOT2 ".."
+                                                                                                                                                                                                            WHITESPACE " "
+                                                                                                                                                                                                            RANGE_EXPR
+                                                                                                                                                                                                              DOT2EQ "..="
+                                                                                                                                                                                                              RANGE_EXPR
+                                                                                                                                                                                                                DOT2 ".."
+                                                                                                                                                                                                                WHITESPACE "    "
+                                                                                                                                                                                                                RANGE_EXPR
+                                                                                                                                                                                                                  DOT2 ".."
+                                                                                                                                                                                                                  WHITESPACE " "
+                                                                                                                                                                                                                  RANGE_EXPR
+                                                                                                                                                                                                                    DOT2EQ "..="
+                                                                                                                                                                                                                    RANGE_EXPR
+                                                                                                                                                                                                                      DOT2EQ "..="
+                                                                                                                                                                                                                      RANGE_EXPR
+                                                                                                                                                                                                                        DOT2 ".."
+                                                                                                                                                                                                                        WHITESPACE "    "
+                                                                                                                                                                                                                        RANGE_EXPR
+                                                                                                                                                                                                                          DOT2EQ "..="
+                                                                                                                                                                                                                          RANGE_EXPR
+                                                                                                                                                                                                                            DOT2EQ "..="
+                                                                                                                                                                                                                            RANGE_EXPR
+                                                                                                                                                                                                                              DOT2 ".."
+                                                                                                                                                                                                                              WHITESPACE " "
+                                                                                                                                                                                                                              RANGE_EXPR
+                                                                                                                                                                                                                                DOT2 ".."
+                                                                                                                                                                                                                                WHITESPACE "    "
+                                                                                                                                                                                                                                RANGE_EXPR
+                                                                                                                                                                                                                                  DOT2 ".."
+                                                                                                                                                                                                                                  WHITESPACE " "
+                                                                                                                                                                                                                                  RANGE_EXPR
+                                                                                                                                                                                                                                    DOT2EQ "..="
+                                                                                                                                                                                                                                    RANGE_EXPR
+                                                                                                                                                                                                                                      DOT2 ".."
+                                                                                                                                                                                                                                      WHITESPACE " "
+                                                                                                                                                                                                                                      RANGE_EXPR
+                                                                                                                                                                                                                                        DOT2 ".."
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "ktulhu"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        EXPR_STMT
+          TUPLE_EXPR
+            L_PAREN "("
+            R_PAREN ")"
+          SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        SEMICOLON ";"
+        TUPLE_EXPR
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    VISIBILITY
+      PUB_KW "pub"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "strange"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "funny"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "what"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "zombiejesus"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "notsure"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "canttouchthis"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "angrydome"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "evil_lincoln"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "dots"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "u8"
+            ARG_LIST
+              L_PAREN "("
+              LITERAL
+                INT_NUMBER "8u8"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "fishy"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "union"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "special_characters"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "punch_card"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "ktulhu"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0036_fully_qualified.rast b/crates/parser/test_data/parser/ok/0036_fully_qualified.rast
index 2aa7fffd1c5..2aa7fffd1c5 100644
--- a/crates/syntax/test_data/parser/ok/0036_fully_qualified.rast
+++ b/crates/parser/test_data/parser/ok/0036_fully_qualified.rast
diff --git a/crates/syntax/test_data/parser/ok/0036_fully_qualified.rs b/crates/parser/test_data/parser/ok/0036_fully_qualified.rs
index 6da27933ece..6da27933ece 100644
--- a/crates/syntax/test_data/parser/ok/0036_fully_qualified.rs
+++ b/crates/parser/test_data/parser/ok/0036_fully_qualified.rs
diff --git a/crates/parser/test_data/parser/ok/0036_fully_qualified.txt b/crates/parser/test_data/parser/ok/0036_fully_qualified.txt
new file mode 100644
index 00000000000..6137b38aba3
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0036_fully_qualified.txt
@@ -0,0 +1,93 @@
+SOURCE_FILE
+  COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/311"
+  WHITESPACE "\n\n"
+  FN
+    VISIBILITY
+      PUB_KW "pub"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "S"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Iterator"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      PATH_TYPE
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "String"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        PATH_TYPE
+          PATH
+            PATH
+              PATH_SEGMENT
+                L_ANGLE "<"
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                WHITESPACE " "
+                AS_KW "as"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Iterator"
+                R_ANGLE ">"
+            COLON2 "::"
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Item"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Eq"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        METHOD_CALL_EXPR
+          LITERAL
+            STRING "\"\""
+          DOT "."
+          NAME_REF
+            IDENT "to_owned"
+          ARG_LIST
+            L_PAREN "("
+            R_PAREN ")"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0037_mod.rast b/crates/parser/test_data/parser/ok/0037_mod.rast
index 35577272e56..35577272e56 100644
--- a/crates/syntax/test_data/parser/ok/0037_mod.rast
+++ b/crates/parser/test_data/parser/ok/0037_mod.rast
diff --git a/crates/syntax/test_data/parser/ok/0037_mod.rs b/crates/parser/test_data/parser/ok/0037_mod.rs
index 7e5a1b8358c..7e5a1b8358c 100644
--- a/crates/syntax/test_data/parser/ok/0037_mod.rs
+++ b/crates/parser/test_data/parser/ok/0037_mod.rs
diff --git a/crates/parser/test_data/parser/ok/0037_mod.txt b/crates/parser/test_data/parser/ok/0037_mod.txt
new file mode 100644
index 00000000000..fb6565f3a48
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0037_mod.txt
@@ -0,0 +1,16 @@
+SOURCE_FILE
+  COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/357"
+  WHITESPACE "\n\n"
+  COMMENT "//! docs"
+  WHITESPACE "\n"
+  MODULE
+    COMMENT "// non-docs"
+    WHITESPACE "\n"
+    MOD_KW "mod"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    WHITESPACE " "
+    ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0038_where_pred_type.rast b/crates/parser/test_data/parser/ok/0038_where_pred_type.rast
index 09aa2e60d97..09aa2e60d97 100644
--- a/crates/syntax/test_data/parser/ok/0038_where_pred_type.rast
+++ b/crates/parser/test_data/parser/ok/0038_where_pred_type.rast
diff --git a/crates/syntax/test_data/parser/ok/0038_where_pred_type.rs b/crates/parser/test_data/parser/ok/0038_where_pred_type.rs
index 8bfc341a50a..8bfc341a50a 100644
--- a/crates/syntax/test_data/parser/ok/0038_where_pred_type.rs
+++ b/crates/parser/test_data/parser/ok/0038_where_pred_type.rs
diff --git a/crates/parser/test_data/parser/ok/0038_where_pred_type.txt b/crates/parser/test_data/parser/ok/0038_where_pred_type.txt
new file mode 100644
index 00000000000..e8976304202
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0038_where_pred_type.txt
@@ -0,0 +1,43 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "test"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE " "
+      WHERE_PRED
+        TUPLE_TYPE
+          L_PAREN "("
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "u64"
+          COMMA ","
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "u64"
+          R_PAREN ")"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Foo"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0039_raw_fn_item.rast b/crates/parser/test_data/parser/ok/0039_raw_fn_item.rast
index 186dea82d4d..186dea82d4d 100644
--- a/crates/syntax/test_data/parser/ok/0039_raw_fn_item.rast
+++ b/crates/parser/test_data/parser/ok/0039_raw_fn_item.rast
diff --git a/crates/syntax/test_data/parser/ok/0039_raw_fn_item.rs b/crates/parser/test_data/parser/ok/0039_raw_fn_item.rs
index 8380d1e79bc..8380d1e79bc 100644
--- a/crates/syntax/test_data/parser/ok/0039_raw_fn_item.rs
+++ b/crates/parser/test_data/parser/ok/0039_raw_fn_item.rs
diff --git a/crates/parser/test_data/parser/ok/0039_raw_fn_item.txt b/crates/parser/test_data/parser/ok/0039_raw_fn_item.txt
new file mode 100644
index 00000000000..2eeed781c1a
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0039_raw_fn_item.txt
@@ -0,0 +1,16 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "r#foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0040_raw_struct_item_field.rast b/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.rast
index 8cfc14f491c..8cfc14f491c 100644
--- a/crates/syntax/test_data/parser/ok/0040_raw_struct_item_field.rast
+++ b/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.rast
diff --git a/crates/syntax/test_data/parser/ok/0040_raw_struct_item_field.rs b/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.rs
index 098a60a72bf..098a60a72bf 100644
--- a/crates/syntax/test_data/parser/ok/0040_raw_struct_item_field.rs
+++ b/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.rs
diff --git a/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.txt b/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.txt
new file mode 100644
index 00000000000..ceb918420f5
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0040_raw_struct_item_field.txt
@@ -0,0 +1,22 @@
+SOURCE_FILE
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      RECORD_FIELD
+        NAME
+          IDENT "r#foo"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE "\n"
+      R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0041_raw_keywords.rast b/crates/parser/test_data/parser/ok/0041_raw_keywords.rast
index a8971b466e6..a8971b466e6 100644
--- a/crates/syntax/test_data/parser/ok/0041_raw_keywords.rast
+++ b/crates/parser/test_data/parser/ok/0041_raw_keywords.rast
diff --git a/crates/syntax/test_data/parser/ok/0041_raw_keywords.rs b/crates/parser/test_data/parser/ok/0041_raw_keywords.rs
index d59a6d3476b..d59a6d3476b 100644
--- a/crates/syntax/test_data/parser/ok/0041_raw_keywords.rs
+++ b/crates/parser/test_data/parser/ok/0041_raw_keywords.rs
diff --git a/crates/parser/test_data/parser/ok/0041_raw_keywords.txt b/crates/parser/test_data/parser/ok/0041_raw_keywords.txt
new file mode 100644
index 00000000000..dacf0ce7426
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0041_raw_keywords.txt
@@ -0,0 +1,50 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "r#struct"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "92"
+          SEMICOLON ";"
+        WHITESPACE " "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "r#trait"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "r#struct"
+            WHITESPACE " "
+            STAR "*"
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "2"
+          SEMICOLON ";"
+        WHITESPACE " "
+        R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0042_ufcs_call_list.rast b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast
index aa7a4dc7456..aa7a4dc7456 100644
--- a/crates/syntax/test_data/parser/ok/0042_ufcs_call_list.rast
+++ b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast
diff --git a/crates/syntax/test_data/parser/ok/0042_ufcs_call_list.rs b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rs
index 6c02e65ed7d..6c02e65ed7d 100644
--- a/crates/syntax/test_data/parser/ok/0042_ufcs_call_list.rs
+++ b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rs
diff --git a/crates/parser/test_data/parser/ok/0042_ufcs_call_list.txt b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.txt
new file mode 100644
index 00000000000..ff2121a58a6
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.txt
@@ -0,0 +1,126 @@
+SOURCE_FILE
+  COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/596"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "Foo"
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+  IMPL
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Foo"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "bar"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "bool"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            MACRO_CALL
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "unimplemented"
+              BANG "!"
+              TOKEN_TREE
+                L_PAREN "("
+                R_PAREN ")"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "baz"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        WILDCARD_PAT
+          UNDERSCORE "_"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "bool"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        CALL_EXPR
+          PATH_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "baz"
+          ARG_LIST
+            L_PAREN "("
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      L_ANGLE "<"
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Foo"
+                      R_ANGLE ">"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "bar"
+              ARG_LIST
+                L_PAREN "("
+                R_PAREN ")"
+            R_PAREN ")"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0043_complex_assignment.rast b/crates/parser/test_data/parser/ok/0043_complex_assignment.rast
index 12d776c7bf9..12d776c7bf9 100644
--- a/crates/syntax/test_data/parser/ok/0043_complex_assignment.rast
+++ b/crates/parser/test_data/parser/ok/0043_complex_assignment.rast
diff --git a/crates/syntax/test_data/parser/ok/0043_complex_assignment.rs b/crates/parser/test_data/parser/ok/0043_complex_assignment.rs
index 7e4a28bf74c..7e4a28bf74c 100644
--- a/crates/syntax/test_data/parser/ok/0043_complex_assignment.rs
+++ b/crates/parser/test_data/parser/ok/0043_complex_assignment.rs
diff --git a/crates/parser/test_data/parser/ok/0043_complex_assignment.txt b/crates/parser/test_data/parser/ok/0043_complex_assignment.txt
new file mode 100644
index 00000000000..f9e5a51ae22
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0043_complex_assignment.txt
@@ -0,0 +1,110 @@
+SOURCE_FILE
+  COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/674"
+  WHITESPACE "\n\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "Repr"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE " "
+      RECORD_FIELD
+        NAME
+          IDENT "raw"
+        COLON ":"
+        WHITESPACE " "
+        ARRAY_TYPE
+          L_BRACK "["
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "u8"
+          SEMICOLON ";"
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "1"
+          R_BRACK "]"
+      WHITESPACE " "
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "abc"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            INDEX_EXPR
+              FIELD_EXPR
+                RECORD_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Repr"
+                  WHITESPACE " "
+                  RECORD_EXPR_FIELD_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    RECORD_EXPR_FIELD
+                      NAME_REF
+                        IDENT "raw"
+                      COLON ":"
+                      WHITESPACE " "
+                      ARRAY_EXPR
+                        L_BRACK "["
+                        LITERAL
+                          INT_NUMBER "0"
+                        R_BRACK "]"
+                    WHITESPACE " "
+                    R_CURLY "}"
+                DOT "."
+                NAME_REF
+                  IDENT "raw"
+              L_BRACK "["
+              LITERAL
+                INT_NUMBER "0"
+              R_BRACK "]"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "0"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            RECORD_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Repr"
+              RECORD_EXPR_FIELD_LIST
+                L_CURLY "{"
+                RECORD_EXPR_FIELD
+                  NAME_REF
+                    IDENT "raw"
+                  COLON ":"
+                  ARRAY_EXPR
+                    L_BRACK "["
+                    LITERAL
+                      INT_NUMBER "0"
+                    R_BRACK "]"
+                R_CURLY "}"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0044_let_attrs.rast b/crates/parser/test_data/parser/ok/0044_let_attrs.rast
index 80c1d6b87af..80c1d6b87af 100644
--- a/crates/syntax/test_data/parser/ok/0044_let_attrs.rast
+++ b/crates/parser/test_data/parser/ok/0044_let_attrs.rast
diff --git a/crates/syntax/test_data/parser/ok/0044_let_attrs.rs b/crates/parser/test_data/parser/ok/0044_let_attrs.rs
index 325a97aebdc..325a97aebdc 100644
--- a/crates/syntax/test_data/parser/ok/0044_let_attrs.rs
+++ b/crates/parser/test_data/parser/ok/0044_let_attrs.rs
diff --git a/crates/parser/test_data/parser/ok/0044_let_attrs.txt b/crates/parser/test_data/parser/ok/0044_let_attrs.txt
new file mode 100644
index 00000000000..6c637bac428
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0044_let_attrs.txt
@@ -0,0 +1,77 @@
+SOURCE_FILE
+  FN
+    COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/677"
+    WHITESPACE "\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          ATTR
+            POUND "#"
+            L_BRACK "["
+            META
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "cfg"
+              TOKEN_TREE
+                L_PAREN "("
+                IDENT "feature"
+                WHITESPACE " "
+                EQ "="
+                WHITESPACE " "
+                STRING "\"backtrace\""
+                R_PAREN ")"
+            R_BRACK "]"
+          WHITESPACE "\n    "
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "exit_code"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "panic"
+                COLON2 "::"
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "catch_unwind"
+            ARG_LIST
+              L_PAREN "("
+              CLOSURE_EXPR
+                MOVE_KW "move"
+                WHITESPACE " "
+                PARAM_LIST
+                  PIPE "|"
+                  PIPE "|"
+                WHITESPACE " "
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "main"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0045_block_attrs.rast b/crates/parser/test_data/parser/ok/0045_block_attrs.rast
index a45f88def1e..a45f88def1e 100644
--- a/crates/syntax/test_data/parser/ok/0045_block_attrs.rast
+++ b/crates/parser/test_data/parser/ok/0045_block_attrs.rast
diff --git a/crates/syntax/test_data/parser/ok/0045_block_attrs.rs b/crates/parser/test_data/parser/ok/0045_block_attrs.rs
index ed4593759ac..ed4593759ac 100644
--- a/crates/syntax/test_data/parser/ok/0045_block_attrs.rs
+++ b/crates/parser/test_data/parser/ok/0045_block_attrs.rs
diff --git a/crates/parser/test_data/parser/ok/0045_block_attrs.txt b/crates/parser/test_data/parser/ok/0045_block_attrs.txt
new file mode 100644
index 00000000000..6b6f3bfe3e9
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0045_block_attrs.txt
@@ -0,0 +1,230 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "inner"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        ATTR
+          POUND "#"
+          BANG "!"
+          L_BRACK "["
+          META
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "doc"
+            TOKEN_TREE
+              L_PAREN "("
+              STRING "\"Inner attributes allowed here\""
+              R_PAREN ")"
+          R_BRACK "]"
+        WHITESPACE "\n    "
+        COMMENT "//! As are ModuleDoc style comments"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              ATTR
+                POUND "#"
+                BANG "!"
+                L_BRACK "["
+                META
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "doc"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    STRING "\"Inner attributes are allowed in blocks used as statements\""
+                    R_PAREN ")"
+                R_BRACK "]"
+              WHITESPACE "\n        "
+              ATTR
+                POUND "#"
+                BANG "!"
+                L_BRACK "["
+                META
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "doc"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    STRING "\"Being validated is not affected by duplcates\""
+                    R_PAREN ")"
+                R_BRACK "]"
+              WHITESPACE "\n        "
+              COMMENT "//! As are ModuleDoc style comments"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            ATTR
+              POUND "#"
+              BANG "!"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "doc"
+                TOKEN_TREE
+                  L_PAREN "("
+                  STRING "\"Inner attributes are allowed in blocks when they are the last statement of another block\""
+                  R_PAREN ")"
+              R_BRACK "]"
+            WHITESPACE "\n        "
+            COMMENT "//! As are ModuleDoc style comments"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "outer"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          WILDCARD_PAT
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          BLOCK_EXPR
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "doc"
+                TOKEN_TREE
+                  L_PAREN "("
+                  STRING "\"Outer attributes are always allowed\""
+                  R_PAREN ")"
+              R_BRACK "]"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  IMPL
+    COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/689"
+    WHITESPACE "\n"
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Whatever"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "salsa_event"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            AMP "&"
+            NAME
+              SELF_KW "self"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "event_fn"
+            COLON ":"
+            WHITESPACE " "
+            IMPL_TRAIT_TYPE
+              IMPL_KW "impl"
+              WHITESPACE " "
+              TYPE_BOUND_LIST
+                TYPE_BOUND
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "Fn"
+                        PARAM_LIST
+                          L_PAREN "("
+                          R_PAREN ")"
+                        WHITESPACE " "
+                        RET_TYPE
+                          THIN_ARROW "->"
+                          WHITESPACE " "
+                          PATH_TYPE
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "Event"
+                                GENERIC_ARG_LIST
+                                  L_ANGLE "<"
+                                  TYPE_ARG
+                                    PATH_TYPE
+                                      PATH
+                                        PATH_SEGMENT
+                                          NAME_REF
+                                            IDENT "Self"
+                                  R_ANGLE ">"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            WHITESPACE "\n        "
+            ATTR
+              POUND "#"
+              BANG "!"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "allow"
+                TOKEN_TREE
+                  L_PAREN "("
+                  IDENT "unused_variables"
+                  R_PAREN ")"
+              R_BRACK "]"
+            WHITESPACE " "
+            COMMENT "// this is  `inner_attr` of the block"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0046_extern_inner_attributes.rast b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast
index 854ff9d5633..854ff9d5633 100644
--- a/crates/syntax/test_data/parser/ok/0046_extern_inner_attributes.rast
+++ b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast
diff --git a/crates/syntax/test_data/parser/ok/0046_extern_inner_attributes.rs b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rs
index fe67e2df43c..fe67e2df43c 100644
--- a/crates/syntax/test_data/parser/ok/0046_extern_inner_attributes.rs
+++ b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rs
diff --git a/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.txt b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.txt
new file mode 100644
index 00000000000..4eb51cfdf09
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.txt
@@ -0,0 +1,29 @@
+SOURCE_FILE
+  EXTERN_BLOCK
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      COMMENT "//! This is a doc comment"
+      WHITESPACE "\n    "
+      ATTR
+        POUND "#"
+        BANG "!"
+        L_BRACK "["
+        META
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "doc"
+          TOKEN_TREE
+            L_PAREN "("
+            STRING "\"This is also a doc comment\""
+            R_PAREN ")"
+        R_BRACK "]"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast b/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.rast
index 9b6101edb17..9b6101edb17 100644
--- a/crates/syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast
+++ b/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.rast
diff --git a/crates/syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rs b/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.rs
index bbd6b0f6e7c..bbd6b0f6e7c 100644
--- a/crates/syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rs
+++ b/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.rs
diff --git a/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.txt b/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.txt
new file mode 100644
index 00000000000..ac23e7d1d96
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0047_minus_in_inner_pattern.txt
@@ -0,0 +1,323 @@
+SOURCE_FILE
+  COMMENT "// https://github.com/rust-analyzer/rust-analyzer/issues/972"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Some"
+              ARG_LIST
+                L_PAREN "("
+                PREFIX_EXPR
+                  MINUS "-"
+                  LITERAL
+                    INT_NUMBER "1"
+                R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                TUPLE_STRUCT_PAT
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Some"
+                  L_PAREN "("
+                  LITERAL_PAT
+                    MINUS "-"
+                    LITERAL
+                      INT_NUMBER "1"
+                  R_PAREN ")"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Some"
+              ARG_LIST
+                L_PAREN "("
+                TUPLE_EXPR
+                  L_PAREN "("
+                  PREFIX_EXPR
+                    MINUS "-"
+                    LITERAL
+                      INT_NUMBER "1"
+                  COMMA ","
+                  WHITESPACE " "
+                  PREFIX_EXPR
+                    MINUS "-"
+                    LITERAL
+                      INT_NUMBER "1"
+                  R_PAREN ")"
+                R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                TUPLE_STRUCT_PAT
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Some"
+                  L_PAREN "("
+                  TUPLE_PAT
+                    L_PAREN "("
+                    LITERAL_PAT
+                      MINUS "-"
+                      LITERAL
+                        INT_NUMBER "1"
+                    COMMA ","
+                    WHITESPACE " "
+                    LITERAL_PAT
+                      MINUS "-"
+                      LITERAL
+                        INT_NUMBER "1"
+                    R_PAREN ")"
+                  R_PAREN ")"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "A"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "B"
+              ARG_LIST
+                L_PAREN "("
+                PREFIX_EXPR
+                  MINUS "-"
+                  LITERAL
+                    INT_NUMBER "1"
+                COMMA ","
+                WHITESPACE " "
+                PREFIX_EXPR
+                  MINUS "-"
+                  LITERAL
+                    INT_NUMBER "1"
+                R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                TUPLE_STRUCT_PAT
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "A"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "B"
+                  L_PAREN "("
+                  LITERAL_PAT
+                    MINUS "-"
+                    LITERAL
+                      INT_NUMBER "1"
+                  COMMA ","
+                  WHITESPACE " "
+                  LITERAL_PAT
+                    MINUS "-"
+                    LITERAL
+                      INT_NUMBER "1"
+                  R_PAREN ")"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        IF_EXPR
+          IF_KW "if"
+          WHITESPACE " "
+          CONDITION
+            LET_KW "let"
+            WHITESPACE " "
+            TUPLE_STRUCT_PAT
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Some"
+              L_PAREN "("
+              LITERAL_PAT
+                MINUS "-"
+                LITERAL
+                  INT_NUMBER "1"
+              R_PAREN ")"
+            WHITESPACE " "
+            EQ "="
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Some"
+              ARG_LIST
+                L_PAREN "("
+                PREFIX_EXPR
+                  MINUS "-"
+                  LITERAL
+                    INT_NUMBER "1"
+                R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  ENUM
+    ENUM_KW "enum"
+    WHITESPACE " "
+    NAME
+      IDENT "A"
+    WHITESPACE " "
+    VARIANT_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      VARIANT
+        NAME
+          IDENT "B"
+        TUPLE_FIELD_LIST
+          L_PAREN "("
+          TUPLE_FIELD
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i8"
+          COMMA ","
+          WHITESPACE " "
+          TUPLE_FIELD
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i8"
+          R_PAREN ")"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        RANGE_PAT
+          LITERAL_PAT
+            MINUS "-"
+            LITERAL
+              INT_NUMBER "128"
+          DOT2EQ "..="
+          LITERAL_PAT
+            LITERAL
+              INT_NUMBER "127"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "i8"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0048_compound_assignment.rast b/crates/parser/test_data/parser/ok/0048_compound_assignment.rast
index b19a0b5f8bb..b19a0b5f8bb 100644
--- a/crates/syntax/test_data/parser/ok/0048_compound_assignment.rast
+++ b/crates/parser/test_data/parser/ok/0048_compound_assignment.rast
diff --git a/crates/syntax/test_data/parser/ok/0048_compound_assignment.rs b/crates/parser/test_data/parser/ok/0048_compound_assignment.rs
index 871720a49a6..871720a49a6 100644
--- a/crates/syntax/test_data/parser/ok/0048_compound_assignment.rs
+++ b/crates/parser/test_data/parser/ok/0048_compound_assignment.rs
diff --git a/crates/parser/test_data/parser/ok/0048_compound_assignment.txt b/crates/parser/test_data/parser/ok/0048_compound_assignment.txt
new file mode 100644
index 00000000000..eca5e7aa810
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0048_compound_assignment.txt
@@ -0,0 +1,201 @@
+SOURCE_FILE
+  COMMENT "// https://github.com/rust-analyzer/rust-analyzer/pull/983"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "compound_assignment"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              IDENT "a"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "0"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            PLUSEQ "+="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "1"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            MINUSEQ "-="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "2"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            STAREQ "*="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            PERCENTEQ "%="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "4"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            SLASHEQ "/="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "5"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            PIPEEQ "|="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "6"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            AMPEQ "&="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "7"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            CARETEQ "^="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "8"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            LTEQ "<="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "9"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            GTEQ ">="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "10"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            SHREQ ">>="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "11"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "a"
+            WHITESPACE " "
+            SHLEQ "<<="
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "12"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0049_async_block.rast b/crates/parser/test_data/parser/ok/0049_async_block.rast
index a254214595a..a254214595a 100644
--- a/crates/syntax/test_data/parser/ok/0049_async_block.rast
+++ b/crates/parser/test_data/parser/ok/0049_async_block.rast
diff --git a/crates/syntax/test_data/parser/ok/0049_async_block.rs b/crates/parser/test_data/parser/ok/0049_async_block.rs
index 4781b322549..4781b322549 100644
--- a/crates/syntax/test_data/parser/ok/0049_async_block.rs
+++ b/crates/parser/test_data/parser/ok/0049_async_block.rs
diff --git a/crates/parser/test_data/parser/ok/0049_async_block.txt b/crates/parser/test_data/parser/ok/0049_async_block.txt
new file mode 100644
index 00000000000..f376821e285
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0049_async_block.txt
@@ -0,0 +1,36 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            ASYNC_KW "async"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            ASYNC_KW "async"
+            WHITESPACE " "
+            MOVE_KW "move"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
diff --git a/crates/syntax/test_data/parser/ok/0050_async_block_as_argument.rast b/crates/parser/test_data/parser/ok/0050_async_block_as_argument.rast
index f54c0c16642..f54c0c16642 100644
--- a/crates/syntax/test_data/parser/ok/0050_async_block_as_argument.rast
+++ b/crates/parser/test_data/parser/ok/0050_async_block_as_argument.rast
diff --git a/crates/syntax/test_data/parser/ok/0050_async_block_as_argument.rs b/crates/parser/test_data/parser/ok/0050_async_block_as_argument.rs
index ec4612cff27..ec4612cff27 100644
--- a/crates/syntax/test_data/parser/ok/0050_async_block_as_argument.rs
+++ b/crates/parser/test_data/parser/ok/0050_async_block_as_argument.rs
diff --git a/crates/parser/test_data/parser/ok/0050_async_block_as_argument.txt b/crates/parser/test_data/parser/ok/0050_async_block_as_argument.txt
new file mode 100644
index 00000000000..53ddf35ccb4
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0050_async_block_as_argument.txt
@@ -0,0 +1,92 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "x"
+        COLON ":"
+        WHITESPACE " "
+        IMPL_TRAIT_TYPE
+          IMPL_KW "impl"
+          WHITESPACE " "
+          TYPE_BOUND_LIST
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "std"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "future"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Future"
+                    GENERIC_ARG_LIST
+                      L_ANGLE "<"
+                      ASSOC_TYPE_ARG
+                        NAME_REF
+                          IDENT "Output"
+                        WHITESPACE " "
+                        EQ "="
+                        WHITESPACE " "
+                        PATH_TYPE
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "i32"
+                      R_ANGLE ">"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        CALL_EXPR
+          PATH_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "foo"
+          ARG_LIST
+            L_PAREN "("
+            BLOCK_EXPR
+              ASYNC_KW "async"
+              WHITESPACE " "
+              MOVE_KW "move"
+              WHITESPACE " "
+              STMT_LIST
+                L_CURLY "{"
+                WHITESPACE " "
+                LITERAL
+                  INT_NUMBER "12"
+                WHITESPACE " "
+                R_CURLY "}"
+            R_PAREN ")"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast
index e4e76645ce0..e4e76645ce0 100644
--- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
+++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast
diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rs b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs
index de350d8587a..de350d8587a 100644
--- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rs
+++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs
diff --git a/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt b/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt
new file mode 100644
index 00000000000..e1ebf5a38cb
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt
@@ -0,0 +1,548 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "g1"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        ATTR
+          POUND "#"
+          L_BRACK "["
+          META
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "attr1"
+          R_BRACK "]"
+        WHITESPACE " "
+        ATTR
+          POUND "#"
+          L_BRACK "["
+          META
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "attr2"
+          R_BRACK "]"
+        WHITESPACE " "
+        IDENT_PAT
+          NAME
+            IDENT "pat"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Type"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "g2"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        ATTR
+          POUND "#"
+          L_BRACK "["
+          META
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "attr1"
+          R_BRACK "]"
+        WHITESPACE " "
+        IDENT_PAT
+          NAME
+            IDENT "x"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u8"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  EXTERN_BLOCK
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE " "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "printf"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            IDENT_PAT
+              NAME
+                IDENT "format"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              CONST_KW "const"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "i8"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            DOT3 "..."
+          R_PAREN ")"
+        WHITESPACE " "
+        RET_TYPE
+          THIN_ARROW "->"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "i32"
+        SEMICOLON ";"
+      WHITESPACE " "
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "F"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "FnMut"
+                  PARAM_LIST
+                    L_PAREN "("
+                    PARAM
+                      ATTR
+                        POUND "#"
+                        L_BRACK "["
+                        META
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "attr"
+                        R_BRACK "]"
+                      WHITESPACE " "
+                      REF_TYPE
+                        AMP "&"
+                        MUT_KW "mut"
+                        WHITESPACE " "
+                        PATH_TYPE
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "Foo"
+                              GENERIC_ARG_LIST
+                                L_ANGLE "<"
+                                LIFETIME_ARG
+                                  LIFETIME
+                                    LIFETIME_IDENT "'a"
+                                R_ANGLE ">"
+                    R_PAREN ")"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  TRAIT
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "Foo"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "bar"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            WILDCARD_PAT
+              UNDERSCORE "_"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "u64"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            ATTR
+              POUND "#"
+              WHITESPACE " "
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            IDENT_PAT
+              MUT_KW "mut"
+              WHITESPACE " "
+              NAME
+                IDENT "x"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i32"
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  IMPL
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "S"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "must_use"
+              R_BRACK "]"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "g1"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "g2"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            AMP "&"
+            NAME
+              SELF_KW "self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "g3"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            AMP "&"
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "g4"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            AMP "&"
+            LIFETIME
+              LIFETIME_IDENT "'a"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "g5"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            AMP "&"
+            LIFETIME
+              LIFETIME_IDENT "'a"
+            WHITESPACE " "
+            MUT_KW "mut"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "c"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Self"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n     "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "d"
+        PARAM_LIST
+          L_PAREN "("
+          SELF_PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "attr"
+              R_BRACK "]"
+            WHITESPACE " "
+            NAME
+              SELF_KW "self"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Rc"
+                  GENERIC_ARG_LIST
+                    L_ANGLE "<"
+                    TYPE_ARG
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Self"
+                    R_ANGLE ">"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0052_for_range_block.rast b/crates/parser/test_data/parser/ok/0052_for_range_block.rast
index 949ddc3797e..949ddc3797e 100644
--- a/crates/syntax/test_data/parser/ok/0052_for_range_block.rast
+++ b/crates/parser/test_data/parser/ok/0052_for_range_block.rast
diff --git a/crates/syntax/test_data/parser/ok/0052_for_range_block.rs b/crates/parser/test_data/parser/ok/0052_for_range_block.rs
index b51b1963008..b51b1963008 100644
--- a/crates/syntax/test_data/parser/ok/0052_for_range_block.rs
+++ b/crates/parser/test_data/parser/ok/0052_for_range_block.rs
diff --git a/crates/parser/test_data/parser/ok/0052_for_range_block.txt b/crates/parser/test_data/parser/ok/0052_for_range_block.txt
new file mode 100644
index 00000000000..0c9dd432fb4
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0052_for_range_block.txt
@@ -0,0 +1,81 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n   "
+        FOR_EXPR
+          FOR_KW "for"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "_x"
+          WHITESPACE " "
+          IN_KW "in"
+          WHITESPACE " "
+          RANGE_EXPR
+            LITERAL
+              INT_NUMBER "0"
+            WHITESPACE " "
+            DOT2 ".."
+            WHITESPACE " "
+            METHOD_CALL_EXPR
+              PAREN_EXPR
+                L_PAREN "("
+                RANGE_EXPR
+                  LITERAL
+                    INT_NUMBER "0"
+                  WHITESPACE " "
+                  DOT2 ".."
+                  WHITESPACE " "
+                  BLOCK_EXPR
+                    STMT_LIST
+                      L_CURLY "{"
+                      BIN_EXPR
+                        LITERAL
+                          INT_NUMBER "1"
+                        WHITESPACE " "
+                        PLUS "+"
+                        WHITESPACE " "
+                        LITERAL
+                          INT_NUMBER "2"
+                      R_CURLY "}"
+                R_PAREN ")"
+              DOT "."
+              NAME_REF
+                IDENT "sum"
+              GENERIC_ARG_LIST
+                COLON2 "::"
+                L_ANGLE "<"
+                TYPE_ARG
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "u32"
+                R_ANGLE ">"
+              ARG_LIST
+                L_PAREN "("
+                R_PAREN ")"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE "\n       "
+              EXPR_STMT
+                BREAK_EXPR
+                  BREAK_KW "break"
+                SEMICOLON ";"
+              WHITESPACE "\n   "
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast
index 97416f16acc..97416f16acc 100644
--- a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast
+++ b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast
diff --git a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rs b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rs
index b59c23c56a9..b59c23c56a9 100644
--- a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rs
+++ b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rs
diff --git a/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt
new file mode 100644
index 00000000000..b94d43beb3c
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt
@@ -0,0 +1,37 @@
+SOURCE_FILE
+  MACRO_RULES
+    COMMENT "/// Some docs"
+    WHITESPACE "\n"
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "macro_export"
+      R_BRACK "]"
+    WHITESPACE "\n"
+    MACRO_RULES_KW "macro_rules"
+    BANG "!"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    WHITESPACE " "
+    TOKEN_TREE
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      TOKEN_TREE
+        L_PAREN "("
+        R_PAREN ")"
+      WHITESPACE " "
+      EQ "="
+      R_ANGLE ">"
+      WHITESPACE " "
+      TOKEN_TREE
+        L_CURLY "{"
+        R_CURLY "}"
+      SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast
index e85cb15961e..e85cb15961e 100644
--- a/crates/syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast
+++ b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast
diff --git a/crates/syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rs b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rs
index 0d3f5722a5a..0d3f5722a5a 100644
--- a/crates/syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rs
+++ b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rs
diff --git a/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.txt b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.txt
new file mode 100644
index 00000000000..4e1e31f3767
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.txt
@@ -0,0 +1,126 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "a"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      PATH_TYPE
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "Foo"
+            GENERIC_ARG_LIST
+              L_ANGLE "<"
+              TYPE_ARG
+                PATH_TYPE
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "bar"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Baz"
+              R_ANGLE ">"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "b"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        WILDCARD_PAT
+          UNDERSCORE "_"
+        COLON ":"
+        WHITESPACE " "
+        IMPL_TRAIT_TYPE
+          IMPL_KW "impl"
+          WHITESPACE " "
+          TYPE_BOUND_LIST
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "FnMut"
+                    PARAM_LIST
+                      L_PAREN "("
+                      PARAM
+                        PATH_TYPE
+                          PATH
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "x"
+                            COLON2 "::"
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "Y"
+                      R_PAREN ")"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "c"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        WILDCARD_PAT
+          UNDERSCORE "_"
+        COLON ":"
+        WHITESPACE " "
+        IMPL_TRAIT_TYPE
+          IMPL_KW "impl"
+          WHITESPACE " "
+          TYPE_BOUND_LIST
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "FnMut"
+                    PARAM_LIST
+                      L_PAREN "("
+                      PARAM
+                        REF_TYPE
+                          AMP "&"
+                          PATH_TYPE
+                            PATH
+                              PATH
+                                PATH_SEGMENT
+                                  NAME_REF
+                                    IDENT "x"
+                              COLON2 "::"
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "Y"
+                      R_PAREN ")"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0055_dot_dot_dot.rast b/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rast
index b43c38b9e04..b43c38b9e04 100644
--- a/crates/syntax/test_data/parser/ok/0055_dot_dot_dot.rast
+++ b/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rast
diff --git a/crates/syntax/test_data/parser/ok/0055_dot_dot_dot.rs b/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs
index cd204f65ed9..cd204f65ed9 100644
--- a/crates/syntax/test_data/parser/ok/0055_dot_dot_dot.rs
+++ b/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs
diff --git a/crates/parser/test_data/parser/ok/0055_dot_dot_dot.txt b/crates/parser/test_data/parser/ok/0055_dot_dot_dot.txt
new file mode 100644
index 00000000000..684f499df5c
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0055_dot_dot_dot.txt
@@ -0,0 +1,50 @@
+SOURCE_FILE
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "X"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    TUPLE_TYPE
+      L_PAREN "("
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          TUPLE_PAT
+            L_PAREN "("
+            R_PAREN ")"
+          COLON ":"
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                COLON2 "::"
+                NAME_REF
+                  IDENT "X"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          TUPLE_EXPR
+            L_PAREN "("
+            R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0056_neq_in_type.rast b/crates/parser/test_data/parser/ok/0056_neq_in_type.rast
index 7393f1df83a..7393f1df83a 100644
--- a/crates/syntax/test_data/parser/ok/0056_neq_in_type.rast
+++ b/crates/parser/test_data/parser/ok/0056_neq_in_type.rast
diff --git a/crates/syntax/test_data/parser/ok/0056_neq_in_type.rs b/crates/parser/test_data/parser/ok/0056_neq_in_type.rs
index 6210683cea3..6210683cea3 100644
--- a/crates/syntax/test_data/parser/ok/0056_neq_in_type.rs
+++ b/crates/parser/test_data/parser/ok/0056_neq_in_type.rs
diff --git a/crates/parser/test_data/parser/ok/0056_neq_in_type.txt b/crates/parser/test_data/parser/ok/0056_neq_in_type.txt
new file mode 100644
index 00000000000..2d78eaffc52
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0056_neq_in_type.txt
@@ -0,0 +1,66 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        IF_EXPR
+          IF_KW "if"
+          WHITESPACE " "
+          CONDITION
+            BIN_EXPR
+              CAST_EXPR
+                METHOD_CALL_EXPR
+                  LITERAL
+                    FLOAT_NUMBER "1.0f32"
+                  DOT "."
+                  NAME_REF
+                    IDENT "floor"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                WHITESPACE " "
+                AS_KW "as"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "i64"
+              WHITESPACE " "
+              NEQ "!="
+              WHITESPACE " "
+              CAST_EXPR
+                METHOD_CALL_EXPR
+                  LITERAL
+                    FLOAT_NUMBER "1.0f32"
+                  DOT "."
+                  NAME_REF
+                    IDENT "floor"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                WHITESPACE " "
+                AS_KW "as"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "i64"
+          WHITESPACE " "
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0057_loop_in_call.rast b/crates/parser/test_data/parser/ok/0057_loop_in_call.rast
index f8efd8ea4ca..f8efd8ea4ca 100644
--- a/crates/syntax/test_data/parser/ok/0057_loop_in_call.rast
+++ b/crates/parser/test_data/parser/ok/0057_loop_in_call.rast
diff --git a/crates/syntax/test_data/parser/ok/0057_loop_in_call.rs b/crates/parser/test_data/parser/ok/0057_loop_in_call.rs
index 31c12522ffc..31c12522ffc 100644
--- a/crates/syntax/test_data/parser/ok/0057_loop_in_call.rs
+++ b/crates/parser/test_data/parser/ok/0057_loop_in_call.rs
diff --git a/crates/parser/test_data/parser/ok/0057_loop_in_call.txt b/crates/parser/test_data/parser/ok/0057_loop_in_call.txt
new file mode 100644
index 00000000000..67837e4750c
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0057_loop_in_call.txt
@@ -0,0 +1,59 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "x"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "i32"
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "foo"
+            ARG_LIST
+              L_PAREN "("
+              LOOP_EXPR
+                LOOP_KW "loop"
+                WHITESPACE " "
+                BLOCK_EXPR
+                  STMT_LIST
+                    L_CURLY "{"
+                    R_CURLY "}"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
diff --git a/crates/syntax/test_data/parser/ok/0058_unary_expr_precedence.rast b/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.rast
index 476a19307ab..476a19307ab 100644
--- a/crates/syntax/test_data/parser/ok/0058_unary_expr_precedence.rast
+++ b/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.rast
diff --git a/crates/syntax/test_data/parser/ok/0058_unary_expr_precedence.rs b/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.rs
index 100fccc641c..100fccc641c 100644
--- a/crates/syntax/test_data/parser/ok/0058_unary_expr_precedence.rs
+++ b/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.rs
diff --git a/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.txt b/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.txt
new file mode 100644
index 00000000000..683d5070aee
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0058_unary_expr_precedence.txt
@@ -0,0 +1,97 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BIN_EXPR
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "1"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              PREFIX_EXPR
+                STAR "*"
+                REF_EXPR
+                  AMP "&"
+                  LITERAL
+                    INT_NUMBER "2"
+            WHITESPACE " "
+            PLUS "+"
+            WHITESPACE " "
+            LITERAL
+              INT_NUMBER "3"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CAST_EXPR
+            PREFIX_EXPR
+              STAR "*"
+              REF_EXPR
+                AMP "&"
+                LITERAL
+                  INT_NUMBER "1"
+            WHITESPACE " "
+            AS_KW "as"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "u64"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          PREFIX_EXPR
+            STAR "*"
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "x"
+              ARG_LIST
+                L_PAREN "("
+                LITERAL
+                  INT_NUMBER "1"
+                R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          REF_EXPR
+            AMP "&"
+            INDEX_EXPR
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "x"
+              L_BRACK "["
+              LITERAL
+                INT_NUMBER "1"
+              R_BRACK "]"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RANGE_EXPR
+            PREFIX_EXPR
+              MINUS "-"
+              LITERAL
+                INT_NUMBER "1"
+            DOT2 ".."
+            LITERAL
+              INT_NUMBER "2"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0059_loops_in_parens.rast b/crates/parser/test_data/parser/ok/0059_loops_in_parens.rast
index 0cb1ccf044a..0cb1ccf044a 100644
--- a/crates/syntax/test_data/parser/ok/0059_loops_in_parens.rast
+++ b/crates/parser/test_data/parser/ok/0059_loops_in_parens.rast
diff --git a/crates/syntax/test_data/parser/ok/0059_loops_in_parens.rs b/crates/parser/test_data/parser/ok/0059_loops_in_parens.rs
index 6e8b718aaf9..6e8b718aaf9 100644
--- a/crates/syntax/test_data/parser/ok/0059_loops_in_parens.rs
+++ b/crates/parser/test_data/parser/ok/0059_loops_in_parens.rs
diff --git a/crates/parser/test_data/parser/ok/0059_loops_in_parens.txt b/crates/parser/test_data/parser/ok/0059_loops_in_parens.txt
new file mode 100644
index 00000000000..1eeb6c957f7
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0059_loops_in_parens.txt
@@ -0,0 +1,101 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Some"
+            ARG_LIST
+              L_PAREN "("
+              FOR_EXPR
+                FOR_KW "for"
+                WHITESPACE " "
+                WILDCARD_PAT
+                  UNDERSCORE "_"
+                WHITESPACE " "
+                IN_KW "in"
+                WHITESPACE " "
+                METHOD_CALL_EXPR
+                  ARRAY_EXPR
+                    L_BRACK "["
+                    LITERAL
+                      INT_NUMBER "1"
+                    R_BRACK "]"
+                  DOT "."
+                  NAME_REF
+                    IDENT "into_iter"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                WHITESPACE " "
+                BLOCK_EXPR
+                  STMT_LIST
+                    L_CURLY "{"
+                    R_CURLY "}"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Some"
+            ARG_LIST
+              L_PAREN "("
+              LOOP_EXPR
+                LOOP_KW "loop"
+                WHITESPACE " "
+                BLOCK_EXPR
+                  STMT_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    EXPR_STMT
+                      BREAK_EXPR
+                        BREAK_KW "break"
+                      SEMICOLON ";"
+                    WHITESPACE " "
+                    R_CURLY "}"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Some"
+            ARG_LIST
+              L_PAREN "("
+              WHILE_EXPR
+                WHILE_KW "while"
+                WHITESPACE " "
+                CONDITION
+                  LITERAL
+                    TRUE_KW "true"
+                WHITESPACE " "
+                BLOCK_EXPR
+                  STMT_LIST
+                    L_CURLY "{"
+                    R_CURLY "}"
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0060_as_range.rast b/crates/parser/test_data/parser/ok/0060_as_range.rast
index f6921085059..f6921085059 100644
--- a/crates/syntax/test_data/parser/ok/0060_as_range.rast
+++ b/crates/parser/test_data/parser/ok/0060_as_range.rast
diff --git a/crates/syntax/test_data/parser/ok/0060_as_range.rs b/crates/parser/test_data/parser/ok/0060_as_range.rs
index f063ffadb3d..f063ffadb3d 100644
--- a/crates/syntax/test_data/parser/ok/0060_as_range.rs
+++ b/crates/parser/test_data/parser/ok/0060_as_range.rs
diff --git a/crates/parser/test_data/parser/ok/0060_as_range.txt b/crates/parser/test_data/parser/ok/0060_as_range.txt
new file mode 100644
index 00000000000..81fc02b6f4a
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0060_as_range.txt
@@ -0,0 +1,56 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RANGE_EXPR
+            CAST_EXPR
+              LITERAL
+                INT_NUMBER "0"
+              WHITESPACE " "
+              AS_KW "as"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "usize"
+            WHITESPACE " "
+            DOT2 ".."
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RANGE_EXPR
+            BIN_EXPR
+              LITERAL
+                INT_NUMBER "1"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              CAST_EXPR
+                LITERAL
+                  INT_NUMBER "2"
+                WHITESPACE " "
+                AS_KW "as"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "usize"
+            WHITESPACE " "
+            DOT2 ".."
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0061_match_full_range.rast b/crates/parser/test_data/parser/ok/0061_match_full_range.rast
index bcc8732c973..bcc8732c973 100644
--- a/crates/syntax/test_data/parser/ok/0061_match_full_range.rast
+++ b/crates/parser/test_data/parser/ok/0061_match_full_range.rast
diff --git a/crates/syntax/test_data/parser/ok/0061_match_full_range.rs b/crates/parser/test_data/parser/ok/0061_match_full_range.rs
index 2c4ed11e1e5..2c4ed11e1e5 100644
--- a/crates/syntax/test_data/parser/ok/0061_match_full_range.rs
+++ b/crates/parser/test_data/parser/ok/0061_match_full_range.rs
diff --git a/crates/parser/test_data/parser/ok/0061_match_full_range.txt b/crates/parser/test_data/parser/ok/0061_match_full_range.txt
new file mode 100644
index 00000000000..2f56e9041ea
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0061_match_full_range.txt
@@ -0,0 +1,27 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        MATCH_EXPR
+          MATCH_KW "match"
+          WHITESPACE " "
+          RANGE_EXPR
+            DOT2 ".."
+          WHITESPACE " "
+          MATCH_ARM_LIST
+            L_CURLY "{"
+            WHITESPACE "\n    "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0062_macro_2.0.rast b/crates/parser/test_data/parser/ok/0062_macro_2.0.rast
index 80f331bec37..80f331bec37 100644
--- a/crates/syntax/test_data/parser/ok/0062_macro_2.0.rast
+++ b/crates/parser/test_data/parser/ok/0062_macro_2.0.rast
diff --git a/crates/syntax/test_data/parser/ok/0062_macro_2.0.rs b/crates/parser/test_data/parser/ok/0062_macro_2.0.rs
index 781047ba19a..781047ba19a 100644
--- a/crates/syntax/test_data/parser/ok/0062_macro_2.0.rs
+++ b/crates/parser/test_data/parser/ok/0062_macro_2.0.rs
diff --git a/crates/parser/test_data/parser/ok/0062_macro_2.0.txt b/crates/parser/test_data/parser/ok/0062_macro_2.0.txt
new file mode 100644
index 00000000000..3915ed75064
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0062_macro_2.0.txt
@@ -0,0 +1,177 @@
+SOURCE_FILE
+  MACRO_DEF
+    MACRO_KW "macro"
+    WHITESPACE " "
+    NAME
+      IDENT "parse_use_trees"
+    TOKEN_TREE
+      TOKEN_TREE
+        L_PAREN "("
+        DOLLAR "$"
+        TOKEN_TREE
+          L_PAREN "("
+          DOLLAR "$"
+          IDENT "s"
+          COLON ":"
+          IDENT "expr"
+          R_PAREN ")"
+        COMMA ","
+        STAR "*"
+        WHITESPACE " "
+        DOLLAR "$"
+        TOKEN_TREE
+          L_PAREN "("
+          COMMA ","
+          R_PAREN ")"
+        STAR "*"
+        R_PAREN ")"
+      WHITESPACE " "
+      TOKEN_TREE
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        IDENT "vec"
+        BANG "!"
+        TOKEN_TREE
+          L_BRACK "["
+          WHITESPACE "\n        "
+          DOLLAR "$"
+          TOKEN_TREE
+            L_PAREN "("
+            IDENT "parse_use_tree"
+            TOKEN_TREE
+              L_PAREN "("
+              DOLLAR "$"
+              IDENT "s"
+              R_PAREN ")"
+            COMMA ","
+            R_PAREN ")"
+          STAR "*"
+          WHITESPACE "\n    "
+          R_BRACK "]"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  FN
+    ATTR
+      POUND "#"
+      L_BRACK "["
+      META
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "test"
+      R_BRACK "]"
+    WHITESPACE "\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "test_use_tree_merge"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        MACRO_DEF
+          MACRO_KW "macro"
+          WHITESPACE " "
+          NAME
+            IDENT "test_merge"
+          TOKEN_TREE
+            TOKEN_TREE
+              L_PAREN "("
+              TOKEN_TREE
+                L_BRACK "["
+                DOLLAR "$"
+                TOKEN_TREE
+                  L_PAREN "("
+                  DOLLAR "$"
+                  IDENT "input"
+                  COLON ":"
+                  IDENT "expr"
+                  R_PAREN ")"
+                COMMA ","
+                STAR "*"
+                WHITESPACE " "
+                DOLLAR "$"
+                TOKEN_TREE
+                  L_PAREN "("
+                  COMMA ","
+                  R_PAREN ")"
+                STAR "*"
+                R_BRACK "]"
+              COMMA ","
+              WHITESPACE " "
+              TOKEN_TREE
+                L_BRACK "["
+                DOLLAR "$"
+                TOKEN_TREE
+                  L_PAREN "("
+                  DOLLAR "$"
+                  IDENT "output"
+                  COLON ":"
+                  IDENT "expr"
+                  R_PAREN ")"
+                COMMA ","
+                STAR "*"
+                WHITESPACE " "
+                DOLLAR "$"
+                TOKEN_TREE
+                  L_PAREN "("
+                  COMMA ","
+                  R_PAREN ")"
+                STAR "*"
+                R_BRACK "]"
+              R_PAREN ")"
+            WHITESPACE " "
+            TOKEN_TREE
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              IDENT "assert_eq"
+              BANG "!"
+              TOKEN_TREE
+                L_PAREN "("
+                WHITESPACE "\n            "
+                IDENT "merge_use_trees"
+                TOKEN_TREE
+                  L_PAREN "("
+                  IDENT "parse_use_trees"
+                  BANG "!"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    DOLLAR "$"
+                    TOKEN_TREE
+                      L_PAREN "("
+                      DOLLAR "$"
+                      IDENT "input"
+                      COMMA ","
+                      R_PAREN ")"
+                    STAR "*"
+                    R_PAREN ")"
+                  R_PAREN ")"
+                COMMA ","
+                WHITESPACE "\n            "
+                IDENT "parse_use_trees"
+                BANG "!"
+                TOKEN_TREE
+                  L_PAREN "("
+                  DOLLAR "$"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    DOLLAR "$"
+                    IDENT "output"
+                    COMMA ","
+                    R_PAREN ")"
+                  STAR "*"
+                  R_PAREN ")"
+                COMMA ","
+                WHITESPACE "\n        "
+                R_PAREN ")"
+              SEMICOLON ";"
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0063_trait_fn_patterns.rast b/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.rast
index 979058d032f..979058d032f 100644
--- a/crates/syntax/test_data/parser/ok/0063_trait_fn_patterns.rast
+++ b/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.rast
diff --git a/crates/syntax/test_data/parser/ok/0063_trait_fn_patterns.rs b/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.rs
index 3b666af8eed..3b666af8eed 100644
--- a/crates/syntax/test_data/parser/ok/0063_trait_fn_patterns.rs
+++ b/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.rs
diff --git a/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.txt b/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.txt
new file mode 100644
index 00000000000..a86b21d27cd
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0063_trait_fn_patterns.txt
@@ -0,0 +1,198 @@
+SOURCE_FILE
+  TRAIT
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f1"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            TUPLE_PAT
+              L_PAREN "("
+              IDENT_PAT
+                NAME
+                  IDENT "a"
+              COMMA ","
+              WHITESPACE " "
+              IDENT_PAT
+                NAME
+                  IDENT "b"
+              R_PAREN ")"
+            COLON ":"
+            WHITESPACE " "
+            TUPLE_TYPE
+              L_PAREN "("
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "usize"
+              COMMA ","
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "usize"
+              R_PAREN ")"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f2"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            RECORD_PAT
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "S"
+              WHITESPACE " "
+              RECORD_PAT_FIELD_LIST
+                L_CURLY "{"
+                WHITESPACE " "
+                RECORD_PAT_FIELD
+                  IDENT_PAT
+                    NAME
+                      IDENT "a"
+                COMMA ","
+                WHITESPACE " "
+                RECORD_PAT_FIELD
+                  IDENT_PAT
+                    NAME
+                      IDENT "b"
+                WHITESPACE " "
+                R_CURLY "}"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "S"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f3"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            TUPLE_STRUCT_PAT
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "NewType"
+              L_PAREN "("
+              IDENT_PAT
+                NAME
+                  IDENT "a"
+              R_PAREN ")"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "NewType"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f4"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            REF_PAT
+              AMP "&"
+              REF_PAT
+                AMP "&"
+                IDENT_PAT
+                  NAME
+                    IDENT "a"
+            COLON ":"
+            WHITESPACE " "
+            REF_TYPE
+              AMP "&"
+              REF_TYPE
+                AMP "&"
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "usize"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "bar"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            WILDCARD_PAT
+              UNDERSCORE "_"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "u64"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            IDENT_PAT
+              MUT_KW "mut"
+              WHITESPACE " "
+              NAME
+                IDENT "x"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i32"
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0063_variadic_fun.rast b/crates/parser/test_data/parser/ok/0063_variadic_fun.rast
index dcc4105c917..dcc4105c917 100644
--- a/crates/syntax/test_data/parser/ok/0063_variadic_fun.rast
+++ b/crates/parser/test_data/parser/ok/0063_variadic_fun.rast
diff --git a/crates/syntax/test_data/parser/ok/0063_variadic_fun.rs b/crates/parser/test_data/parser/ok/0063_variadic_fun.rs
index a16afbaf386..a16afbaf386 100644
--- a/crates/syntax/test_data/parser/ok/0063_variadic_fun.rs
+++ b/crates/parser/test_data/parser/ok/0063_variadic_fun.rs
diff --git a/crates/parser/test_data/parser/ok/0063_variadic_fun.txt b/crates/parser/test_data/parser/ok/0063_variadic_fun.txt
new file mode 100644
index 00000000000..e36399123bc
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0063_variadic_fun.txt
@@ -0,0 +1,134 @@
+SOURCE_FILE
+  EXTERN_BLOCK
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "a"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            WILDCARD_PAT
+              UNDERSCORE "_"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "u8"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            DOT3 "..."
+          COMMA ","
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "b"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            WILDCARD_PAT
+              UNDERSCORE "_"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "u8"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            WILDCARD_PAT
+              UNDERSCORE "_"
+            COLON ":"
+            WHITESPACE " "
+            DOT3 "..."
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "c"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            WILDCARD_PAT
+              UNDERSCORE "_"
+            COLON ":"
+            WHITESPACE " "
+            PTR_TYPE
+              STAR "*"
+              MUT_KW "mut"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "u8"
+          COMMA ","
+          WHITESPACE " "
+          PARAM
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "cfg"
+                TOKEN_TREE
+                  L_PAREN "("
+                  IDENT "never"
+                  R_PAREN ")"
+              R_BRACK "]"
+            WHITESPACE " "
+            SLICE_PAT
+              L_BRACK "["
+              IDENT_PAT
+                NAME
+                  IDENT "w"
+              COMMA ","
+              WHITESPACE " "
+              IDENT_PAT
+                NAME
+                  IDENT "t"
+              COMMA ","
+              WHITESPACE " "
+              IDENT_PAT
+                NAME
+                  IDENT "f"
+              R_BRACK "]"
+            COLON ":"
+            WHITESPACE " "
+            DOT3 "..."
+          COMMA ","
+          R_PAREN ")"
+        SEMICOLON ";"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0064_impl_fn_params.rast b/crates/parser/test_data/parser/ok/0064_impl_fn_params.rast
index dbfc2f92607..dbfc2f92607 100644
--- a/crates/syntax/test_data/parser/ok/0064_impl_fn_params.rast
+++ b/crates/parser/test_data/parser/ok/0064_impl_fn_params.rast
diff --git a/crates/syntax/test_data/parser/ok/0064_impl_fn_params.rs b/crates/parser/test_data/parser/ok/0064_impl_fn_params.rs
index b49e872d79d..b49e872d79d 100644
--- a/crates/syntax/test_data/parser/ok/0064_impl_fn_params.rs
+++ b/crates/parser/test_data/parser/ok/0064_impl_fn_params.rs
diff --git a/crates/parser/test_data/parser/ok/0064_impl_fn_params.txt b/crates/parser/test_data/parser/ok/0064_impl_fn_params.txt
new file mode 100644
index 00000000000..18cecc8108d
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0064_impl_fn_params.txt
@@ -0,0 +1,166 @@
+SOURCE_FILE
+  IMPL
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "U"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f1"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            TUPLE_PAT
+              L_PAREN "("
+              IDENT_PAT
+                NAME
+                  IDENT "a"
+              COMMA ","
+              WHITESPACE " "
+              IDENT_PAT
+                NAME
+                  IDENT "b"
+              R_PAREN ")"
+            COLON ":"
+            WHITESPACE " "
+            TUPLE_TYPE
+              L_PAREN "("
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "usize"
+              COMMA ","
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "usize"
+              R_PAREN ")"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f2"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            RECORD_PAT
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "S"
+              WHITESPACE " "
+              RECORD_PAT_FIELD_LIST
+                L_CURLY "{"
+                WHITESPACE " "
+                RECORD_PAT_FIELD
+                  IDENT_PAT
+                    NAME
+                      IDENT "a"
+                COMMA ","
+                WHITESPACE " "
+                RECORD_PAT_FIELD
+                  IDENT_PAT
+                    NAME
+                      IDENT "b"
+                WHITESPACE " "
+                R_CURLY "}"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "S"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f3"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            TUPLE_STRUCT_PAT
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "NewType"
+              L_PAREN "("
+              IDENT_PAT
+                NAME
+                  IDENT "a"
+              R_PAREN ")"
+            COLON ":"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "NewType"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n    "
+      FN
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "f4"
+        PARAM_LIST
+          L_PAREN "("
+          PARAM
+            REF_PAT
+              AMP "&"
+              REF_PAT
+                AMP "&"
+                IDENT_PAT
+                  NAME
+                    IDENT "a"
+            COLON ":"
+            WHITESPACE " "
+            REF_TYPE
+              AMP "&"
+              REF_TYPE
+                AMP "&"
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "usize"
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0065_comment_newline.rast b/crates/parser/test_data/parser/ok/0065_comment_newline.rast
index 162830d95f3..162830d95f3 100644
--- a/crates/syntax/test_data/parser/ok/0065_comment_newline.rast
+++ b/crates/parser/test_data/parser/ok/0065_comment_newline.rast
diff --git a/crates/syntax/test_data/parser/ok/0065_comment_newline.rs b/crates/parser/test_data/parser/ok/0065_comment_newline.rs
index 1fafe216b6e..1fafe216b6e 100644
--- a/crates/syntax/test_data/parser/ok/0065_comment_newline.rs
+++ b/crates/parser/test_data/parser/ok/0065_comment_newline.rs
diff --git a/crates/parser/test_data/parser/ok/0065_comment_newline.txt b/crates/parser/test_data/parser/ok/0065_comment_newline.txt
new file mode 100644
index 00000000000..3ffcb48f5e4
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0065_comment_newline.txt
@@ -0,0 +1,17 @@
+SOURCE_FILE
+  FN
+    COMMENT "/// Example"
+    WHITESPACE "\n\n"
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "test"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast
index 9efa6ec0b6a..9efa6ec0b6a 100644
--- a/crates/syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast
+++ b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast
diff --git a/crates/syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rs b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rs
index 29f3655e013..29f3655e013 100644
--- a/crates/syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rs
+++ b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rs
diff --git a/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.txt b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.txt
new file mode 100644
index 00000000000..ba7b6042a9e
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.txt
@@ -0,0 +1,61 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "f"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE " "
+      WHERE_PRED
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Fn"
+                  PARAM_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+                  WHITESPACE " "
+                  RET_TYPE
+                    THIN_ARROW "->"
+                    WHITESPACE " "
+                    PATH_TYPE
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "u8"
+          WHITESPACE " "
+          PLUS "+"
+          WHITESPACE " "
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Send"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0066_default_modifier.rast b/crates/parser/test_data/parser/ok/0066_default_modifier.rast
index 0479c5f60f5..0479c5f60f5 100644
--- a/crates/syntax/test_data/parser/ok/0066_default_modifier.rast
+++ b/crates/parser/test_data/parser/ok/0066_default_modifier.rast
diff --git a/crates/syntax/test_data/parser/ok/0066_default_modifier.rs b/crates/parser/test_data/parser/ok/0066_default_modifier.rs
index e443e3495e3..e443e3495e3 100644
--- a/crates/syntax/test_data/parser/ok/0066_default_modifier.rs
+++ b/crates/parser/test_data/parser/ok/0066_default_modifier.rs
diff --git a/crates/parser/test_data/parser/ok/0066_default_modifier.txt b/crates/parser/test_data/parser/ok/0066_default_modifier.txt
new file mode 100644
index 00000000000..a4303098a28
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0066_default_modifier.txt
@@ -0,0 +1,222 @@
+SOURCE_FILE
+  TRAIT
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n  "
+      TYPE_ALIAS
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        TYPE_KW "type"
+        WHITESPACE " "
+        NAME
+          IDENT "T"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Bar"
+        SEMICOLON ";"
+      WHITESPACE "\n  "
+      CONST
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        CONST_KW "const"
+        WHITESPACE " "
+        NAME
+          IDENT "f"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u8"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        LITERAL
+          INT_NUMBER "0"
+        SEMICOLON ";"
+      WHITESPACE "\n  "
+      FN
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "foo"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n  "
+      FN
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        UNSAFE_KW "unsafe"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "bar"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  IMPL
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "T"
+    WHITESPACE " "
+    FOR_KW "for"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Foo"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      WHITESPACE "\n  "
+      TYPE_ALIAS
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        TYPE_KW "type"
+        WHITESPACE " "
+        NAME
+          IDENT "T"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Bar"
+        SEMICOLON ";"
+      WHITESPACE "\n  "
+      CONST
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        CONST_KW "const"
+        WHITESPACE " "
+        NAME
+          IDENT "f"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u8"
+        WHITESPACE " "
+        EQ "="
+        WHITESPACE " "
+        LITERAL
+          INT_NUMBER "0"
+        SEMICOLON ";"
+      WHITESPACE "\n  "
+      FN
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "foo"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n  "
+      FN
+        DEFAULT_KW "default"
+        WHITESPACE " "
+        UNSAFE_KW "unsafe"
+        WHITESPACE " "
+        FN_KW "fn"
+        WHITESPACE " "
+        NAME
+          IDENT "bar"
+        PARAM_LIST
+          L_PAREN "("
+          R_PAREN ")"
+        WHITESPACE " "
+        BLOCK_EXPR
+          STMT_LIST
+            L_CURLY "{"
+            R_CURLY "}"
+      WHITESPACE "\n"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  IMPL
+    DEFAULT_KW "default"
+    WHITESPACE " "
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "T"
+    WHITESPACE " "
+    FOR_KW "for"
+    WHITESPACE " "
+    TUPLE_TYPE
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+  IMPL
+    DEFAULT_KW "default"
+    WHITESPACE " "
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "T"
+    WHITESPACE " "
+    FOR_KW "for"
+    WHITESPACE " "
+    TUPLE_TYPE
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0067_where_for_pred.rast b/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
index d1bf63d507b..d1bf63d507b 100644
--- a/crates/syntax/test_data/parser/ok/0067_where_for_pred.rast
+++ b/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
diff --git a/crates/syntax/test_data/parser/ok/0067_where_for_pred.rs b/crates/parser/test_data/parser/ok/0067_where_for_pred.rs
index 9058c46190c..9058c46190c 100644
--- a/crates/syntax/test_data/parser/ok/0067_where_for_pred.rs
+++ b/crates/parser/test_data/parser/ok/0067_where_for_pred.rs
diff --git a/crates/parser/test_data/parser/ok/0067_where_for_pred.txt b/crates/parser/test_data/parser/ok/0067_where_for_pred.txt
new file mode 100644
index 00000000000..136fce93d7e
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0067_where_for_pred.txt
@@ -0,0 +1,413 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_trait"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "F"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "F"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Fn"
+                  PARAM_LIST
+                    L_PAREN "("
+                    PARAM
+                      REF_TYPE
+                        AMP "&"
+                        LIFETIME
+                          LIFETIME_IDENT "'a"
+                        WHITESPACE " "
+                        PATH_TYPE
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "str"
+                    R_PAREN ")"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_ref"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "F"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        REF_TYPE
+          AMP "&"
+          LIFETIME
+            LIFETIME_IDENT "'a"
+          WHITESPACE " "
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "F"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Debug"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_parens"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "F"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        PAREN_TYPE
+          L_PAREN "("
+          REF_TYPE
+            AMP "&"
+            LIFETIME
+              LIFETIME_IDENT "'a"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "F"
+          R_PAREN ")"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Fn"
+                  PARAM_LIST
+                    L_PAREN "("
+                    PARAM
+                      REF_TYPE
+                        AMP "&"
+                        LIFETIME
+                          LIFETIME_IDENT "'a"
+                        WHITESPACE " "
+                        PATH_TYPE
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "str"
+                    R_PAREN ")"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_slice"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "F"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        SLICE_TYPE
+          L_BRACK "["
+          REF_TYPE
+            AMP "&"
+            LIFETIME
+              LIFETIME_IDENT "'a"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "F"
+          R_BRACK "]"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Eq"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_qpath"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      PARAM
+        IDENT_PAT
+          NAME
+            IDENT "_t"
+        COLON ":"
+        WHITESPACE " "
+        REF_TYPE
+          AMP "&"
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "T"
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH
+              PATH_SEGMENT
+                L_ANGLE "<"
+                REF_TYPE
+                  AMP "&"
+                  LIFETIME
+                    LIFETIME_IDENT "'a"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "T"
+                WHITESPACE " "
+                AS_KW "as"
+                WHITESPACE " "
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Baz"
+                R_ANGLE ">"
+            COLON2 "::"
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "Foo"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Iterator"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "for_for_fn"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE "\n"
+    WHERE_CLAUSE
+      WHERE_KW "where"
+      WHITESPACE "\n    "
+      WHERE_PRED
+        FOR_KW "for"
+        GENERIC_PARAM_LIST
+          L_ANGLE "<"
+          LIFETIME_PARAM
+            LIFETIME
+              LIFETIME_IDENT "'a"
+          R_ANGLE ">"
+        WHITESPACE " "
+        FOR_TYPE
+          FOR_KW "for"
+          GENERIC_PARAM_LIST
+            L_ANGLE "<"
+            LIFETIME_PARAM
+              LIFETIME
+                LIFETIME_IDENT "'b"
+            R_ANGLE ">"
+          WHITESPACE " "
+          FN_PTR_TYPE
+            FN_KW "fn"
+            PARAM_LIST
+              L_PAREN "("
+              PARAM
+                REF_TYPE
+                  AMP "&"
+                  LIFETIME
+                    LIFETIME_IDENT "'a"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "T"
+              COMMA ","
+              WHITESPACE " "
+              PARAM
+                REF_TYPE
+                  AMP "&"
+                  LIFETIME
+                    LIFETIME_IDENT "'b"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "T"
+              R_PAREN ")"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "Copy"
+      COMMA ","
+    WHITESPACE "\n"
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rast b/crates/parser/test_data/parser/ok/0068_item_modifiers.rast
index 8b635d0a037..8b635d0a037 100644
--- a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rast
+++ b/crates/parser/test_data/parser/ok/0068_item_modifiers.rast
diff --git a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rs b/crates/parser/test_data/parser/ok/0068_item_modifiers.rs
index 6d27a082cb3..6d27a082cb3 100644
--- a/crates/syntax/test_data/parser/ok/0068_item_modifiers.rs
+++ b/crates/parser/test_data/parser/ok/0068_item_modifiers.rs
diff --git a/crates/parser/test_data/parser/ok/0068_item_modifiers.txt b/crates/parser/test_data/parser/ok/0068_item_modifiers.txt
new file mode 100644
index 00000000000..41fc5691ad7
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0068_item_modifiers.txt
@@ -0,0 +1,238 @@
+SOURCE_FILE
+  FN
+    ASYNC_KW "async"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    ABI
+      EXTERN_KW "extern"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    CONST_KW "const"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    CONST_KW "const"
+    WHITESPACE " "
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C\""
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    ASYNC_KW "async"
+    WHITESPACE " "
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+  FN
+    CONST_KW "const"
+    WHITESPACE " "
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "bar"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n\n"
+  TRAIT
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+  TRAIT
+    AUTO_KW "auto"
+    WHITESPACE " "
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+  TRAIT
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    AUTO_KW "auto"
+    WHITESPACE " "
+    TRAIT_KW "trait"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  IMPL
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Foo"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+  IMPL
+    DEFAULT_KW "default"
+    WHITESPACE " "
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Foo"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
+  IMPL
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    DEFAULT_KW "default"
+    WHITESPACE " "
+    IMPL_KW "impl"
+    WHITESPACE " "
+    PATH_TYPE
+      PATH
+        PATH_SEGMENT
+          NAME_REF
+            IDENT "Foo"
+    WHITESPACE " "
+    ASSOC_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n\n"
+  EXTERN_BLOCK
+    UNSAFE_KW "unsafe"
+    WHITESPACE " "
+    ABI
+      EXTERN_KW "extern"
+      WHITESPACE " "
+      STRING "\"C++\""
+    WHITESPACE " "
+    EXTERN_ITEM_LIST
+      L_CURLY "{"
+      R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast b/crates/parser/test_data/parser/ok/0069_multi_trait_object.rast
index 7967b88f200..7967b88f200 100644
--- a/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast
+++ b/crates/parser/test_data/parser/ok/0069_multi_trait_object.rast
diff --git a/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rs b/crates/parser/test_data/parser/ok/0069_multi_trait_object.rs
index 97eb79c486f..97eb79c486f 100644
--- a/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rs
+++ b/crates/parser/test_data/parser/ok/0069_multi_trait_object.rs
diff --git a/crates/parser/test_data/parser/ok/0069_multi_trait_object.txt b/crates/parser/test_data/parser/ok/0069_multi_trait_object.txt
new file mode 100644
index 00000000000..9e8f4e19740
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0069_multi_trait_object.txt
@@ -0,0 +1,204 @@
+SOURCE_FILE
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "Foo"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      LIFETIME_PARAM
+        LIFETIME
+          LIFETIME_IDENT "'a"
+      R_ANGLE ">"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    REF_TYPE
+      AMP "&"
+      LIFETIME
+        LIFETIME_IDENT "'a"
+      WHITESPACE " "
+      PAREN_TYPE
+        L_PAREN "("
+        DYN_TRAIT_TYPE
+          DYN_KW "dyn"
+          WHITESPACE " "
+          TYPE_BOUND_LIST
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Send"
+            WHITESPACE " "
+            PLUS "+"
+            WHITESPACE " "
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Sync"
+        R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "Foo"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    PTR_TYPE
+      STAR "*"
+      CONST_KW "const"
+      WHITESPACE " "
+      PAREN_TYPE
+        L_PAREN "("
+        DYN_TRAIT_TYPE
+          DYN_KW "dyn"
+          WHITESPACE " "
+          TYPE_BOUND_LIST
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Send"
+            WHITESPACE " "
+            PLUS "+"
+            WHITESPACE " "
+            TYPE_BOUND
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "Sync"
+        R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "Foo"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    FN_PTR_TYPE
+      FN_KW "fn"
+      PARAM_LIST
+        L_PAREN "("
+        R_PAREN ")"
+      WHITESPACE " "
+      RET_TYPE
+        THIN_ARROW "->"
+        WHITESPACE " "
+        PAREN_TYPE
+          L_PAREN "("
+          DYN_TRAIT_TYPE
+            DYN_KW "dyn"
+            WHITESPACE " "
+            TYPE_BOUND_LIST
+              TYPE_BOUND
+                PATH_TYPE
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "Send"
+              WHITESPACE " "
+              PLUS "+"
+              WHITESPACE " "
+              TYPE_BOUND
+                LIFETIME
+                  LIFETIME_IDENT "'static"
+          R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "b"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          CAST_EXPR
+            PAREN_EXPR
+              L_PAREN "("
+              REF_EXPR
+                AMP "&"
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "a"
+              R_PAREN ")"
+            WHITESPACE " "
+            AS_KW "as"
+            WHITESPACE " "
+            REF_TYPE
+              AMP "&"
+              PAREN_TYPE
+                L_PAREN "("
+                DYN_TRAIT_TYPE
+                  DYN_KW "dyn"
+                  WHITESPACE " "
+                  TYPE_BOUND_LIST
+                    TYPE_BOUND
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Add"
+                            GENERIC_ARG_LIST
+                              L_ANGLE "<"
+                              TYPE_ARG
+                                PATH_TYPE
+                                  PATH
+                                    PATH_SEGMENT
+                                      NAME_REF
+                                        IDENT "Other"
+                              COMMA ","
+                              WHITESPACE " "
+                              ASSOC_TYPE_ARG
+                                NAME_REF
+                                  IDENT "Output"
+                                WHITESPACE " "
+                                EQ "="
+                                WHITESPACE " "
+                                PATH_TYPE
+                                  PATH
+                                    PATH_SEGMENT
+                                      NAME_REF
+                                        IDENT "Addable"
+                              R_ANGLE ">"
+                    WHITESPACE " "
+                    PLUS "+"
+                    WHITESPACE " "
+                    TYPE_BOUND
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Other"
+                R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rast b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast
index b52161a401e..b52161a401e 100644
--- a/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rast
+++ b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast
diff --git a/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rs b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rs
index d8b7a3832a9..d8b7a3832a9 100644
--- a/crates/syntax/test_data/parser/ok/0070_expr_attr_placement.rs
+++ b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rs
diff --git a/crates/parser/test_data/parser/ok/0070_expr_attr_placement.txt b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.txt
new file mode 100644
index 00000000000..3d00b27ab8d
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.txt
@@ -0,0 +1,59 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "f"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        PAREN_EXPR
+          L_PAREN "("
+          BIN_EXPR
+            TRY_EXPR
+              ATTR
+                POUND "#"
+                L_BRACK "["
+                META
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "a"
+                R_BRACK "]"
+              WHITESPACE " "
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "lhs"
+              QUESTION "?"
+            WHITESPACE " "
+            PLUS "+"
+            WHITESPACE " "
+            AWAIT_EXPR
+              ATTR
+                POUND "#"
+                L_BRACK "["
+                META
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "b"
+                R_BRACK "]"
+              WHITESPACE " "
+              PATH_EXPR
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "rhs"
+              DOT "."
+              AWAIT_KW "await"
+          R_PAREN ")"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rast b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast
index 075d15f249c..075d15f249c 100644
--- a/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rast
+++ b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast
diff --git a/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rs b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rs
index b4d5204bc0d..b4d5204bc0d 100644
--- a/crates/syntax/test_data/parser/ok/0071_stmt_attr_placement.rs
+++ b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rs
diff --git a/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.txt b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.txt
new file mode 100644
index 00000000000..81797c35ba1
--- /dev/null
+++ b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.txt
@@ -0,0 +1,71 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          BLOCK_EXPR
+            ATTR
+              POUND "#"
+              L_BRACK "["
+              META
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "A"
+              R_BRACK "]"
+            WHITESPACE " "
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              TRY_EXPR
+                ATTR
+                  POUND "#"
+                  L_BRACK "["
+                  META
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "B"
+                  R_BRACK "]"
+                WHITESPACE " "
+                MACRO_CALL
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "bar"
+                  BANG "!"
+                  TOKEN_TREE
+                    L_PAREN "("
+                    R_PAREN ")"
+                QUESTION "?"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
+        REF_EXPR
+          ATTR
+            POUND "#"
+            L_BRACK "["
+            META
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "C"
+            R_BRACK "]"
+          WHITESPACE " "
+          AMP "&"
+          TUPLE_EXPR
+            L_PAREN "("
+            R_PAREN ")"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs
index 69c5b1cd35a..65fcaee9a8d 100644
--- a/crates/syntax/src/tests.rs
+++ b/crates/syntax/src/tests.rs
@@ -52,18 +52,23 @@ fn benchmark_parser() {
 
 #[test]
 fn parser_tests() {
-    dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], "rast", |text, path| {
+    dir_tests(&test_data_dir(), &["parser/inline/ok"], "rast", |text, path| {
         let parse = SourceFile::parse(text);
         let errors = parse.errors();
         assert_errors_are_absent(errors, path);
         parse.debug_dump()
     });
-    dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], "rast", |text, path| {
-        let parse = SourceFile::parse(text);
-        let errors = parse.errors();
-        assert_errors_are_present(errors, path);
-        parse.debug_dump()
-    });
+    dir_tests(
+        &test_data_dir(),
+        &["parser/inline/err", "parser/validation"],
+        "rast",
+        |text, path| {
+            let parse = SourceFile::parse(text);
+            let errors = parse.errors();
+            assert_errors_are_present(errors, path);
+            parse.debug_dump()
+        },
+    );
 }
 
 #[test]
diff --git a/crates/syntax/test_data/parser/err/0031_block_inner_attrs.rast b/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast
index d4963979c86..d4963979c86 100644
--- a/crates/syntax/test_data/parser/err/0031_block_inner_attrs.rast
+++ b/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast
diff --git a/crates/syntax/test_data/parser/err/0031_block_inner_attrs.rs b/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs
index 6a04f2d0aae..6a04f2d0aae 100644
--- a/crates/syntax/test_data/parser/err/0031_block_inner_attrs.rs
+++ b/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs
diff --git a/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast b/crates/syntax/test_data/parser/validation/0037_visibility_in_traits.rast
index 90c258cd1a6..90c258cd1a6 100644
--- a/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rast
+++ b/crates/syntax/test_data/parser/validation/0037_visibility_in_traits.rast
diff --git a/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rs b/crates/syntax/test_data/parser/validation/0037_visibility_in_traits.rs
index a43e7ef10c1..a43e7ef10c1 100644
--- a/crates/syntax/test_data/parser/err/0037_visibility_in_traits.rs
+++ b/crates/syntax/test_data/parser/validation/0037_visibility_in_traits.rs
diff --git a/crates/syntax/test_data/parser/err/0038_endless_inclusive_range.rast b/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rast
index fd302fb4d55..fd302fb4d55 100644
--- a/crates/syntax/test_data/parser/err/0038_endless_inclusive_range.rast
+++ b/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rast
diff --git a/crates/syntax/test_data/parser/err/0038_endless_inclusive_range.rs b/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rs
index 0b4ed7a2bc2..0b4ed7a2bc2 100644
--- a/crates/syntax/test_data/parser/err/0038_endless_inclusive_range.rs
+++ b/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rs
diff --git a/crates/syntax/test_data/parser/err/0040_illegal_crate_kw_location.rast b/crates/syntax/test_data/parser/validation/0040_illegal_crate_kw_location.rast
index 7449b5ddfc5..7449b5ddfc5 100644
--- a/crates/syntax/test_data/parser/err/0040_illegal_crate_kw_location.rast
+++ b/crates/syntax/test_data/parser/validation/0040_illegal_crate_kw_location.rast
diff --git a/crates/syntax/test_data/parser/err/0040_illegal_crate_kw_location.rs b/crates/syntax/test_data/parser/validation/0040_illegal_crate_kw_location.rs
index 508def2c7ef..508def2c7ef 100644
--- a/crates/syntax/test_data/parser/err/0040_illegal_crate_kw_location.rs
+++ b/crates/syntax/test_data/parser/validation/0040_illegal_crate_kw_location.rs
diff --git a/crates/syntax/test_data/parser/err/0041_illegal_self_keyword_location.rast b/crates/syntax/test_data/parser/validation/0041_illegal_self_keyword_location.rast
index 01f60109144..01f60109144 100644
--- a/crates/syntax/test_data/parser/err/0041_illegal_self_keyword_location.rast
+++ b/crates/syntax/test_data/parser/validation/0041_illegal_self_keyword_location.rast
diff --git a/crates/syntax/test_data/parser/err/0041_illegal_self_keyword_location.rs b/crates/syntax/test_data/parser/validation/0041_illegal_self_keyword_location.rs
index b9e1d7d8be2..b9e1d7d8be2 100644
--- a/crates/syntax/test_data/parser/err/0041_illegal_self_keyword_location.rs
+++ b/crates/syntax/test_data/parser/validation/0041_illegal_self_keyword_location.rs
diff --git a/crates/syntax/test_data/parser/err/0045_ambiguous_trait_object.rast b/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rast
index d94daacdc1d..d94daacdc1d 100644
--- a/crates/syntax/test_data/parser/err/0045_ambiguous_trait_object.rast
+++ b/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rast
diff --git a/crates/syntax/test_data/parser/err/0045_ambiguous_trait_object.rs b/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs
index 3a73d81bb5d..3a73d81bb5d 100644
--- a/crates/syntax/test_data/parser/err/0045_ambiguous_trait_object.rs
+++ b/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs
diff --git a/crates/syntax/test_data/parser/err/0046_mutable_const_item.rast b/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rast
index c7eb312c92c..c7eb312c92c 100644
--- a/crates/syntax/test_data/parser/err/0046_mutable_const_item.rast
+++ b/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rast
diff --git a/crates/syntax/test_data/parser/err/0046_mutable_const_item.rs b/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs
index b34336f3f15..b34336f3f15 100644
--- a/crates/syntax/test_data/parser/err/0046_mutable_const_item.rs
+++ b/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs