Unnamed repository; edit this file 'description' to name the repository.
internal: move outlined parser tests
Aleksey Kladov 2021-12-26
parent f4cb0ff · commit 0f74758
-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 ebba992561..f6f8742725 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 bbbf496c82..bbbf496c82 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 fe5030d893..fe5030d893 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 0000000000..b30328c827
--- /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 6dc73bfdba..6dc73bfdba 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 98f23de1f2..98f23de1f2 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 0000000000..959b87ebbc
--- /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 9ad5b12b8b..9ad5b12b8b 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 48a3a3980b..48a3a3980b 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 0000000000..ec6c315100
--- /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 7763fad840..7763fad840 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 009312270f..009312270f 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 0000000000..00131bea51
--- /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 9a0f4665ef..9a0f4665ef 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 060e65d06d..060e65d06d 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 0000000000..44e192a5fc
--- /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 44dcc58a92..44dcc58a92 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 de7f816283..de7f816283 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 0000000000..6ff072e207
--- /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 5f85c3943a..5f85c3943a 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 8069c111b4..8069c111b4 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 0000000000..7a4aa93b24
--- /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 c57ea77364..c57ea77364 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 dc869fb785..dc869fb785 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 0000000000..5d87ff866b
--- /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 99ec2faed0..99ec2faed0 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 9fcac19b5c..9fcac19b5c 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 0000000000..6dd70e7cd9
--- /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 2d4c689c7c..2d4c689c7c 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 0dd30d0bd6..0dd30d0bd6 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 0000000000..a015432171
--- /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 586acc7329..586acc7329 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 9857752824..9857752824 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 0000000000..9427ee5c0e
--- /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 b02d390af9..b02d390af9 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 c1bd0a2d1b..c1bd0a2d1b 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 0000000000..bd5ec4b7c2
--- /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 f31c276339..f31c276339 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 f48ab6e712..f48ab6e712 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 20dde3bc30..20dde3bc30 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 0000000000..eec84a0c67
--- /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 9178cf3b7f..9178cf3b7f 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 75c1d2f986..75c1d2f986 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 0000000000..fd2f9ada33
--- /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 a3c25b450a..a3c25b450a 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 156e70251a..156e70251a 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 0000000000..8e169320d9
--- /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 30e76de834..30e76de834 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 9ae8576861..9ae8576861 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 0000000000..c48c35bf82
--- /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 9d2c7c6948..9d2c7c6948 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 17bd497777..17bd497777 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 0000000000..8073564629
--- /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 55ac5bc62a..55ac5bc62a 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 fe604006c9..fe604006c9 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 0000000000..799720b557
--- /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 919ce545b7..919ce545b7 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 48bf3d68bd..48bf3d68bd 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 0000000000..25722b1355
--- /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 9ed2b14745..9ed2b14745 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 3393b668b4..3393b668b4 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 0000000000..56d124cb95
--- /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 e2b6a3fd7e..e2b6a3fd7e 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 7a6c264f6d..7a6c264f6d 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 0000000000..762840aa2a
--- /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 d4341371a7..d4341371a7 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 cd2d493a10..cd2d493a10 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 0000000000..900394bd96
--- /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 671566e383..671566e383 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 0206d563ea..0206d563ea 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 0000000000..1176400634
--- /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 39a317137f..39a317137f 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 6c2e95c029..6c2e95c029 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 0000000000..446e1a8233
--- /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 b48b4aed8d..b48b4aed8d 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 28726ed513..28726ed513 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 0000000000..aca57faf96
--- /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 1b08c834eb..1b08c834eb 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 829ca1c4be..829ca1c4be 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 0000000000..1068418e0d
--- /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 ec585a4235..ec585a4235 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 2792c20843..2792c20843 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 0000000000..674c8d536c
--- /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 183cf32030..183cf32030 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 a7cdc17bb1..a7cdc17bb1 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 0000000000..fb037112fa
--- /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 2438b104bf..2438b104bf 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 06aa477704..06aa477704 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 0000000000..327bf94a49
--- /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 66fc2ccbd2..66fc2ccbd2 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 4635222da2..4635222da2 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 0000000000..b5bc3d84df
--- /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 583e62c77a..583e62c77a 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 d3fa2e468c..d3fa2e468c 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 0000000000..7a2ae9103f
--- /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 14eaf9e9b0..14eaf9e9b0 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 4a26681262..4a26681262 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 0000000000..f9287d42e2
--- /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 ef6172f8a1..ef6172f8a1 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 d521a5bb2d..d521a5bb2d 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 0000000000..13e76e6830
--- /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 b9b9f2e4b1..b9b9f2e4b1 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 a2f74bd879..a2f74bd879 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 0000000000..8ca1606015
--- /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 25910cb405..25910cb405 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 8fa324c1a1..8fa324c1a1 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 0000000000..9cea337ce9
--- /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 d4e4bf102e..d4e4bf102e 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 0e9f8ccb4f..0e9f8ccb4f 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 0000000000..cb4fb1642d
--- /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 b4ff1a14a7..b4ff1a14a7 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 731e58013b..731e58013b 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 0000000000..96e471a69a
--- /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 85e10ca36d..85e10ca36d 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 1fb18eaf1b..db32b98dfb 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 0000000000..884ac50f8b
--- /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 ca52166fbc..ca52166fbc 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 31c12bfff9..31c12bfff9 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 0000000000..3a05bfee1e
--- /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 6b234b0b24..6b234b0b24 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 e69de29bb2..e69de29bb2 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 0000000000..40b9ef804c
--- /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 a171fe7a86..a171fe7a86 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 512aeb3e7a..512aeb3e7a 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 0000000000..0e9639f23d
--- /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 362892b91f..362892b91f 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 cc3866d251..cc3866d251 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 0000000000..dd52e5850e
--- /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 67e21df13a..67e21df13a 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 53dc9e6173..53dc9e6173 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 0000000000..698957189f
--- /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 845f9a6f35..845f9a6f35 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 03210551cb..03210551cb 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 0000000000..756d20e4d6
--- /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 be2d1dc123..be2d1dc123 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 e81f8b1e84..e81f8b1e84 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 0000000000..cb63ba80e7
--- /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 4babdba927..4babdba927 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 ab81a608cb..ab81a608cb 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 0000000000..8b9259fd6b
--- /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 e864641834..e864641834 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 4ff0d9795c..4ff0d9795c 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 0000000000..adee67181b
--- /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 6be1cf9fc8..6be1cf9fc8 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 05a6aff83f..05a6aff83f 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 0000000000..04a44ef7e4
--- /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 4d49e79337..4d49e79337 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 1e71b7a6c5..1e71b7a6c5 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 0000000000..ddadec817b
--- /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 bb35b40f4e..bb35b40f4e 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 6f04cb1717..6f04cb1717 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 0000000000..dbb9bc54da
--- /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 e046b0bb1c..e046b0bb1c 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 129d486fae..129d486fae 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 0000000000..a95bc23016
--- /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 dba74e222e..dba74e222e 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 9d9eb99175..9d9eb99175 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 0000000000..8a0149caca
--- /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 4389d2d4bc..4389d2d4bc 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 5e4aa3a332..5e4aa3a332 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 0000000000..b37edc365b
--- /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 d7e93f7eb7..d7e93f7eb7 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 46a0783a2b..46a0783a2b 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 0000000000..ddf8aad6fc
--- /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 b15f41dd7e..b15f41dd7e 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 69638350c4..69638350c4 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 0000000000..eb2724e2f3
--- /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 938a3f17b6..938a3f17b6 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 fe0a7bb97e..fe0a7bb97e 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 0000000000..7c914e2542
--- /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 f845d5cffa..f845d5cffa 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 88c544923b..88c544923b 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 0000000000..11ebc7efb9
--- /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 c3df008146..c3df008146 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 7a1afa0e62..7a1afa0e62 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 0000000000..dd47e3aa47
--- /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 9d4b001aed..9d4b001aed 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 7128989789..7128989789 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 0000000000..043a966ff9
--- /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 26abae3b29..26abae3b29 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 f5fe0e6ef3..f5fe0e6ef3 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 0000000000..ef2fb66dd5
--- /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 9374cf5e96..9374cf5e96 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 5fb92ce33f..5fb92ce33f 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 0000000000..b164e828e3
--- /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 6b234b0b24..6b234b0b24 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 e69de29bb2..e69de29bb2 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 0000000000..40b9ef804c
--- /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 21ed8ebfa4..21ed8ebfa4 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 289809809a..289809809a 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 0000000000..9c5f5ac64e
--- /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 ad4cd31cb6..ad4cd31cb6 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 7641a3d28e..7641a3d28e 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 0000000000..ca9a3df86f
--- /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 eb1fa2819c..eb1fa2819c 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 f3c5ff9386..f3c5ff9386 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 0000000000..88ebd10952
--- /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 96c75052fa..96c75052fa 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 cc9598470d..cc9598470d 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 0000000000..ae08c0756a
--- /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 486bab8df1..486bab8df1 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 f9ff444d40..f9ff444d40 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 0000000000..5acc54e713
--- /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 9f59c0ecb6..9f59c0ecb6 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 261aad1fb6..261aad1fb6 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 0000000000..44211c7c42
--- /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 d07c6683a3..d07c6683a3 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 ac30843eff..ac30843eff 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 0000000000..44423581e6
--- /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 8150d445f3..8150d445f3 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 b33ac273ca..b33ac273ca 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 0000000000..70b5278086
--- /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 ee66eab530..ee66eab530 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 588170fbef..588170fbef 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 0000000000..86f6af97c7
--- /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 fbda85797e..fbda85797e 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 728d78137c..728d78137c 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 0000000000..9807bf0d9a
--- /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 9a6010d362..9a6010d362 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 f1ed30220a..f1ed30220a 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 0000000000..2b3b86ebf2
--- /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 672a12d087..672a12d087 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 8c13231631..8c13231631 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 0000000000..5f62748c47
--- /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 2aa7fffd1c..2aa7fffd1c 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 6da27933ec..6da27933ec 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 0000000000..6137b38aba
--- /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 35577272e5..35577272e5 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 7e5a1b8358..7e5a1b8358 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 0000000000..fb6565f3a4
--- /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 09aa2e60d9..09aa2e60d9 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 8bfc341a50..8bfc341a50 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 0000000000..e897630420
--- /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 186dea82d4..186dea82d4 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 8380d1e79b..8380d1e79b 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 0000000000..2eeed781c1
--- /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 8cfc14f491..8cfc14f491 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 098a60a72b..098a60a72b 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 0000000000..ceb918420f
--- /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 a8971b466e..a8971b466e 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 d59a6d3476..d59a6d3476 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 0000000000..dacf0ce742
--- /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 aa7a4dc745..aa7a4dc745 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 6c02e65ed7..6c02e65ed7 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 0000000000..ff2121a58a
--- /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 12d776c7bf..12d776c7bf 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 7e4a28bf74..7e4a28bf74 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 0000000000..f9e5a51ae2
--- /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 80c1d6b87a..80c1d6b87a 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 325a97aebd..325a97aebd 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 0000000000..6c637bac42
--- /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 a45f88def1..a45f88def1 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 ed4593759a..ed4593759a 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 0000000000..6b6f3bfe3e
--- /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 854ff9d563..854ff9d563 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 fe67e2df43..fe67e2df43 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 0000000000..4eb51cfdf0
--- /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 9b6101edb1..9b6101edb1 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 bbd6b0f6e7..bbd6b0f6e7 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 0000000000..ac23e7d1d9
--- /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 b19a0b5f8b..b19a0b5f8b 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 871720a49a..871720a49a 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 0000000000..eca5e7aa81
--- /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 a254214595..a254214595 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 4781b32254..4781b32254 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 0000000000..f376821e28
--- /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 f54c0c1664..f54c0c1664 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 ec4612cff2..ec4612cff2 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 0000000000..53ddf35ccb
--- /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 e4e76645ce..e4e76645ce 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 de350d8587..de350d8587 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 0000000000..e1ebf5a38c
--- /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 949ddc3797..949ddc3797 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 b51b196300..b51b196300 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 0000000000..0c9dd432fb
--- /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 97416f16ac..97416f16ac 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 b59c23c56a..b59c23c56a 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 0000000000..b94d43beb3
--- /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 e85cb15961..e85cb15961 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 0d3f5722a5..0d3f5722a5 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 0000000000..4e1e31f376
--- /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 b43c38b9e0..b43c38b9e0 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 cd204f65ed..cd204f65ed 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 0000000000..684f499df5
--- /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 7393f1df83..7393f1df83 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 6210683cea..6210683cea 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 0000000000..2d78eaffc5
--- /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 f8efd8ea4c..f8efd8ea4c 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 31c12522ff..31c12522ff 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 0000000000..67837e4750
--- /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 476a19307a..476a19307a 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 100fccc641..100fccc641 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 0000000000..683d5070ae
--- /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 0cb1ccf044..0cb1ccf044 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 6e8b718aaf..6e8b718aaf 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 0000000000..1eeb6c957f
--- /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 f692108505..f692108505 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 f063ffadb3..f063ffadb3 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 0000000000..81fc02b6f4
--- /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 bcc8732c97..bcc8732c97 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 2c4ed11e1e..2c4ed11e1e 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 0000000000..2f56e9041e
--- /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 80f331bec3..80f331bec3 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 781047ba19..781047ba19 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 0000000000..3915ed7506
--- /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 979058d032..979058d032 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 3b666af8ee..3b666af8ee 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 0000000000..a86b21d27c
--- /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 dcc4105c91..dcc4105c91 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 a16afbaf38..a16afbaf38 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 0000000000..e36399123b
--- /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 dbfc2f9260..dbfc2f9260 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 b49e872d79..b49e872d79 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 0000000000..18cecc8108
--- /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 162830d95f..162830d95f 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 1fafe216b6..1fafe216b6 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 0000000000..3ffcb48f5e
--- /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 9efa6ec0b6..9efa6ec0b6 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 29f3655e01..29f3655e01 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 0000000000..ba7b6042a9
--- /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 0479c5f60f..0479c5f60f 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 e443e3495e..e443e3495e 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 0000000000..a4303098a2
--- /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 d1bf63d507..d1bf63d507 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 9058c46190..9058c46190 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 0000000000..136fce93d7
--- /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 8b635d0a03..8b635d0a03 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 6d27a082cb..6d27a082cb 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 0000000000..41fc5691ad
--- /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 7967b88f20..7967b88f20 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 97eb79c486..97eb79c486 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 0000000000..9e8f4e1974
--- /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 b52161a401..b52161a401 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 d8b7a3832a..d8b7a3832a 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 0000000000..3d00b27ab8
--- /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 075d15f249..075d15f249 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 b4d5204bc0..b4d5204bc0 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 0000000000..81797c35ba
--- /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 69c5b1cd35..65fcaee9a8 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 d4963979c8..d4963979c8 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 6a04f2d0aa..6a04f2d0aa 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 90c258cd1a..90c258cd1a 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 a43e7ef10c..a43e7ef10c 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 fd302fb4d5..fd302fb4d5 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 0b4ed7a2bc..0b4ed7a2bc 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 7449b5ddfc..7449b5ddfc 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 508def2c7e..508def2c7e 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 01f6010914..01f6010914 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 b9e1d7d8be..b9e1d7d8be 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 d94daacdc1..d94daacdc1 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 3a73d81bb5..3a73d81bb5 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 c7eb312c92..c7eb312c92 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 b34336f3f1..b34336f3f1 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