aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-16 10:54:24 +0100
committerAleksey Kladov <[email protected]>2018-09-16 11:07:39 +0100
commitb5021411a84822cb3f1e3aeffad9550dd15bdeb6 (patch)
tree9dca564f8e51b298dced01c4ce669c756dce3142 /crates/ra_syntax
parentba0bfeee12e19da40b5eabc8d0408639af10e96f (diff)
rename all things
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/Cargo.toml17
-rw-r--r--crates/ra_syntax/fuzz/.gitignore4
-rw-r--r--crates/ra_syntax/fuzz/Cargo.toml22
-rw-r--r--crates/ra_syntax/fuzz/fuzz_targets/parser.rs9
-rw-r--r--crates/ra_syntax/src/algo/mod.rs129
-rw-r--r--crates/ra_syntax/src/algo/visit.rs110
-rw-r--r--crates/ra_syntax/src/algo/walk.rs38
-rw-r--r--crates/ra_syntax/src/ast/generated.rs2142
-rw-r--r--crates/ra_syntax/src/ast/generated.rs.tera83
-rw-r--r--crates/ra_syntax/src/ast/mod.rs206
-rw-r--r--crates/ra_syntax/src/grammar.ron538
-rw-r--r--crates/ra_syntax/src/grammar/attributes.rs31
-rw-r--r--crates/ra_syntax/src/grammar/expressions/atom.rs400
-rw-r--r--crates/ra_syntax/src/grammar/expressions/mod.rs450
-rw-r--r--crates/ra_syntax/src/grammar/items/consts.rs21
-rw-r--r--crates/ra_syntax/src/grammar/items/mod.rs393
-rw-r--r--crates/ra_syntax/src/grammar/items/nominal.rs154
-rw-r--r--crates/ra_syntax/src/grammar/items/traits.rs117
-rw-r--r--crates/ra_syntax/src/grammar/items/use_item.rs68
-rw-r--r--crates/ra_syntax/src/grammar/mod.rs188
-rw-r--r--crates/ra_syntax/src/grammar/params.rs142
-rw-r--r--crates/ra_syntax/src/grammar/paths.rs101
-rw-r--r--crates/ra_syntax/src/grammar/patterns.rs224
-rw-r--r--crates/ra_syntax/src/grammar/type_args.rs48
-rw-r--r--crates/ra_syntax/src/grammar/type_params.rs136
-rw-r--r--crates/ra_syntax/src/grammar/types.rs247
-rw-r--r--crates/ra_syntax/src/lexer/classes.rs26
-rw-r--r--crates/ra_syntax/src/lexer/comments.rs57
-rw-r--r--crates/ra_syntax/src/lexer/mod.rs209
-rw-r--r--crates/ra_syntax/src/lexer/numbers.rs67
-rw-r--r--crates/ra_syntax/src/lexer/ptr.rs166
-rw-r--r--crates/ra_syntax/src/lexer/strings.rs123
-rw-r--r--crates/ra_syntax/src/lib.rs105
-rw-r--r--crates/ra_syntax/src/parser_api.rs178
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs154
-rw-r--r--crates/ra_syntax/src/parser_impl/input.rs86
-rw-r--r--crates/ra_syntax/src/parser_impl/mod.rs194
-rw-r--r--crates/ra_syntax/src/reparsing.rs343
-rw-r--r--crates/ra_syntax/src/syntax_kinds/generated.rs562
-rw-r--r--crates/ra_syntax/src/syntax_kinds/generated.rs.tera73
-rw-r--r--crates/ra_syntax/src/syntax_kinds/mod.rs26
-rw-r--r--crates/ra_syntax/src/text_utils.rs26
-rw-r--r--crates/ra_syntax/src/token_set.rs37
-rw-r--r--crates/ra_syntax/src/utils.rs85
-rw-r--r--crates/ra_syntax/src/yellow/builder.rs64
-rw-r--r--crates/ra_syntax/src/yellow/green.rs90
-rw-r--r--crates/ra_syntax/src/yellow/mod.rs100
-rw-r--r--crates/ra_syntax/src/yellow/red.rs113
-rw-r--r--crates/ra_syntax/src/yellow/syntax.rs215
-rw-r--r--crates/ra_syntax/src/yellow/syntax_text.rs122
-rw-r--r--crates/ra_syntax/tests/data/lexer/00012_block_comment.rs4
-rw-r--r--crates/ra_syntax/tests/data/lexer/00012_block_comment.txt7
-rw-r--r--crates/ra_syntax/tests/data/lexer/0001_hello.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0001_hello.txt3
-rw-r--r--crates/ra_syntax/tests/data/lexer/0002_whitespace.rs4
-rw-r--r--crates/ra_syntax/tests/data/lexer/0002_whitespace.txt12
-rw-r--r--crates/ra_syntax/tests/data/lexer/0003_ident.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0003_ident.txt14
-rw-r--r--crates/ra_syntax/tests/data/lexer/0004_numbers.rs9
-rw-r--r--crates/ra_syntax/tests/data/lexer/0004_numbers.txt67
-rw-r--r--crates/ra_syntax/tests/data/lexer/0005_symbols.rs6
-rw-r--r--crates/ra_syntax/tests/data/lexer/0005_symbols.txt68
-rw-r--r--crates/ra_syntax/tests/data/lexer/0006_chars.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0006_chars.txt16
-rw-r--r--crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt8
-rw-r--r--crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs3
-rw-r--r--crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt22
-rw-r--r--crates/ra_syntax/tests/data/lexer/0009_strings.rs2
-rw-r--r--crates/ra_syntax/tests/data/lexer/0009_strings.txt8
-rw-r--r--crates/ra_syntax/tests/data/lexer/0010_comments.rs3
-rw-r--r--crates/ra_syntax/tests/data/lexer/0010_comments.txt6
-rw-r--r--crates/ra_syntax/tests/data/lexer/0011_keywords.rs3
-rw-r--r--crates/ra_syntax/tests/data/lexer/0011_keywords.txt62
-rw-r--r--crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt2
-rw-r--r--crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs1
-rw-r--r--crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt1
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt34
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt18
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt7
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt39
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt55
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt74
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs9
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt32
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs13
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt70
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt44
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt42
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt13
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt387
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt89
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt31
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt24
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt43
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt46
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt131
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs12
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt103
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt20
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt34
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt189
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt43
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt310
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0025_nope.rs31
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0025_nope.txt203
-rw-r--r--crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs199
-rw-r--r--crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs106
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt18
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt9
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt17
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt10
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt13
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt15
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt18
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt21
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt35
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt20
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt32
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt19
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt14
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt20
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt13
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt17
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt35
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt27
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt21
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt17
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt50
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt13
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt55
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt23
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt23
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt31
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt70
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt127
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt49
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt28
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt53
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt34
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt95
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs12
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt135
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt36
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt22
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt70
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt54
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0045_block.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0045_block.txt86
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt16
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt14
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt23
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt69
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt71
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt62
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt42
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt28
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt126
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt116
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt49
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt13
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt40
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt37
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt34
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt97
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt40
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt91
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt99
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt95
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt95
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt42
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt25
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt28
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt66
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt44
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt103
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt95
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt78
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt44
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt25
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0076_cond.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0076_cond.txt43
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt66
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt65
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt29
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt38
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt33
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt40
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt30
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt24
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt34
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt59
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt54
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs9
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt87
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt62
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt52
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt40
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt22
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt60
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt46
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt42
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt36
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt81
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt44
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt71
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt18
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt40
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt78
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt28
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt42
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt72
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt35
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt53
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0107_label.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0107_label.txt64
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt28
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt87
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt46
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0000_empty.rs0
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0000_empty.txt1
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt37
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt22
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt15
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs10
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt164
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt25
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs17
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt90
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt21
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt42
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt32
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt102
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt57
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt95
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt65
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs10
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt93
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt26
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs17
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt257
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0019_enums.rs25
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0019_enums.txt155
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs9
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt198
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt56
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt21
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt41
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt41
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt31
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt30
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt41
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs14
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt185
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt83
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0030_traits.rs11
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0030_traits.txt93
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0031_extern.rs29
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0031_extern.txt973
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt85
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs28
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt215
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs16
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt317
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt250
-rw-r--r--crates/ra_syntax/tests/test.rs151
422 files changed, 21903 insertions, 0 deletions
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
new file mode 100644
index 000000000..a0fd633e0
--- /dev/null
+++ b/crates/ra_syntax/Cargo.toml
@@ -0,0 +1,17 @@
1[package]
2name = "ra_syntax"
3version = "0.1.0"
4authors = ["Aleksey Kladov <[email protected]>"]
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8unicode-xid = "0.1.0"
9text_unit = "0.1.4"
10itertools = "0.7.8"
11drop_bomb = "0.1.4"
12parking_lot = "0.6.0"
13smol_str = "0.1.6"
14
15[dev-dependencies]
16test_utils = { path = "../test_utils" }
17walkdir = "2.2.0"
diff --git a/crates/ra_syntax/fuzz/.gitignore b/crates/ra_syntax/fuzz/.gitignore
new file mode 100644
index 000000000..572e03bdf
--- /dev/null
+++ b/crates/ra_syntax/fuzz/.gitignore
@@ -0,0 +1,4 @@
1
2target
3corpus
4artifacts
diff --git a/crates/ra_syntax/fuzz/Cargo.toml b/crates/ra_syntax/fuzz/Cargo.toml
new file mode 100644
index 000000000..65ded6a21
--- /dev/null
+++ b/crates/ra_syntax/fuzz/Cargo.toml
@@ -0,0 +1,22 @@
1
2[package]
3name = "ra_syntax-fuzz"
4version = "0.0.1"
5authors = ["Automatically generated"]
6publish = false
7
8[package.metadata]
9cargo-fuzz = true
10
11[dependencies.ra_syntax]
12path = ".."
13[dependencies.libfuzzer-sys]
14git = "https://github.com/rust-fuzz/libfuzzer-sys.git"
15
16# Prevent this from interfering with workspaces
17[workspace]
18members = ["."]
19
20[[bin]]
21name = "parser"
22path = "fuzz_targets/parser.rs"
diff --git a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs
new file mode 100644
index 000000000..396c0ecaf
--- /dev/null
+++ b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs
@@ -0,0 +1,9 @@
1#![no_main]
2#[macro_use] extern crate libfuzzer_sys;
3extern crate ra_syntax;
4
5fuzz_target!(|data: &[u8]| {
6 if let Ok(text) = std::str::from_utf8(data) {
7 ra_syntax::utils::check_fuzz_invariants(text)
8 }
9});
diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs
new file mode 100644
index 000000000..7287f5bb2
--- /dev/null
+++ b/crates/ra_syntax/src/algo/mod.rs
@@ -0,0 +1,129 @@
1pub mod walk;
2pub mod visit;
3
4use {
5 SyntaxNodeRef, TextUnit, TextRange,
6 text_utils::{contains_offset_nonstrict, is_subrange},
7};
8
9pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset {
10 let range = node.range();
11 assert!(
12 contains_offset_nonstrict(range, offset),
13 "Bad offset: range {:?} offset {:?}", range, offset
14 );
15 if range.is_empty() {
16 return LeafAtOffset::None;
17 }
18
19 if node.is_leaf() {
20 return LeafAtOffset::Single(node);
21 }
22
23 let mut children = node.children()
24 .filter(|child| {
25 let child_range = child.range();
26 !child_range.is_empty() && contains_offset_nonstrict(child_range, offset)
27 });
28
29 let left = children.next().unwrap();
30 let right = children.next();
31 assert!(children.next().is_none());
32 return if let Some(right) = right {
33 match (find_leaf_at_offset(left, offset), find_leaf_at_offset(right, offset)) {
34 (LeafAtOffset::Single(left), LeafAtOffset::Single(right)) =>
35 LeafAtOffset::Between(left, right),
36 _ => unreachable!()
37 }
38 } else {
39 find_leaf_at_offset(left, offset)
40 };
41}
42
43#[derive(Clone, Copy, Debug)]
44pub enum LeafAtOffset<'a> {
45 None,
46 Single(SyntaxNodeRef<'a>),
47 Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>)
48}
49
50impl<'a> LeafAtOffset<'a> {
51 pub fn right_biased(self) -> Option<SyntaxNodeRef<'a>> {
52 match self {
53 LeafAtOffset::None => None,
54 LeafAtOffset::Single(node) => Some(node),
55 LeafAtOffset::Between(_, right) => Some(right)
56 }
57 }
58
59 pub fn left_biased(self) -> Option<SyntaxNodeRef<'a>> {
60 match self {
61 LeafAtOffset::None => None,
62 LeafAtOffset::Single(node) => Some(node),
63 LeafAtOffset::Between(left, _) => Some(left)
64 }
65 }
66}
67
68impl<'f> Iterator for LeafAtOffset<'f> {
69 type Item = SyntaxNodeRef<'f>;
70
71 fn next(&mut self) -> Option<SyntaxNodeRef<'f>> {
72 match *self {
73 LeafAtOffset::None => None,
74 LeafAtOffset::Single(node) => { *self = LeafAtOffset::None; Some(node) }
75 LeafAtOffset::Between(left, right) => { *self = LeafAtOffset::Single(right); Some(left) }
76 }
77 }
78}
79
80pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef {
81 assert!(is_subrange(root.range(), range));
82 let (left, right) = match (
83 find_leaf_at_offset(root, range.start()).right_biased(),
84 find_leaf_at_offset(root, range.end()).left_biased()
85 ) {
86 (Some(l), Some(r)) => (l, r),
87 _ => return root
88 };
89
90 common_ancestor(left, right)
91}
92
93pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
94 generate(Some(node), |&node| node.parent())
95}
96
97#[derive(Debug)]
98pub enum Direction {
99 Forward,
100 Backward,
101}
102
103pub fn siblings<'a>(
104 node: SyntaxNodeRef<'a>,
105 direction: Direction
106) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
107 generate(Some(node), move |&node| match direction {
108 Direction::Forward => node.next_sibling(),
109 Direction::Backward => node.prev_sibling(),
110 })
111}
112
113fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
114 for p in ancestors(n1) {
115 if ancestors(n2).any(|a| a == p) {
116 return p;
117 }
118 }
119 panic!("Can't find common ancestor of {:?} and {:?}", n1, n2)
120}
121
122pub fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item=T> {
123 ::itertools::unfold(seed, move |slot| {
124 slot.take().map(|curr| {
125 *slot = step(&curr);
126 curr
127 })
128 })
129}
diff --git a/crates/ra_syntax/src/algo/visit.rs b/crates/ra_syntax/src/algo/visit.rs
new file mode 100644
index 000000000..9f1c127c7
--- /dev/null
+++ b/crates/ra_syntax/src/algo/visit.rs
@@ -0,0 +1,110 @@
1use std::marker::PhantomData;
2use {SyntaxNodeRef, AstNode};
3
4
5pub fn visitor<'a, T>() -> impl Visitor<'a, Output=T> {
6 EmptyVisitor { ph: PhantomData }
7}
8
9pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output=T, Ctx=C> {
10 EmptyVisitorCtx { ph: PhantomData, ctx }
11}
12
13pub trait Visitor<'a>: Sized {
14 type Output;
15 fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output>;
16 fn visit<N, F>(self, f: F) -> Vis<Self, N, F>
17 where N: AstNode<'a>,
18 F: FnOnce(N) -> Self::Output,
19 {
20 Vis { inner: self, f, ph: PhantomData }
21 }
22}
23
24pub trait VisitorCtx<'a>: Sized {
25 type Output;
26 type Ctx;
27 fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx>;
28 fn visit<N, F>(self, f: F) -> VisCtx<Self, N, F>
29 where N: AstNode<'a>,
30 F: FnOnce(N, Self::Ctx) -> Self::Output,
31 {
32 VisCtx { inner: self, f, ph: PhantomData }
33 }
34}
35
36#[derive(Debug)]
37struct EmptyVisitor<T> {
38 ph: PhantomData<fn() -> T>
39}
40
41impl<'a, T> Visitor<'a> for EmptyVisitor<T> {
42 type Output = T;
43
44 fn accept(self, _node: SyntaxNodeRef<'a>) -> Option<T> {
45 None
46 }
47}
48
49#[derive(Debug)]
50struct EmptyVisitorCtx<T, C> {
51 ctx: C,
52 ph: PhantomData<fn() -> T>,
53}
54
55impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx<T, C> {
56 type Output = T;
57 type Ctx = C;
58
59 fn accept(self, _node: SyntaxNodeRef<'a>) -> Result<T, C> {
60 Err(self.ctx)
61 }
62}
63
64#[derive(Debug)]
65pub struct Vis<V, N, F> {
66 inner: V,
67 f: F,
68 ph: PhantomData<fn(N)>,
69}
70
71impl<'a, V, N, F> Visitor<'a> for Vis<V, N, F>
72 where
73 V: Visitor<'a>,
74 N: AstNode<'a>,
75 F: FnOnce(N) -> <V as Visitor<'a>>::Output,
76{
77 type Output = <V as Visitor<'a>>::Output;
78
79 fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output> {
80 let Vis { inner, f, .. } = self;
81 inner.accept(node).or_else(|| N::cast(node).map(f))
82 }
83}
84
85#[derive(Debug)]
86pub struct VisCtx<V, N, F> {
87 inner: V,
88 f: F,
89 ph: PhantomData<fn(N)>,
90}
91
92impl<'a, V, N, F> VisitorCtx<'a> for VisCtx<V, N, F>
93 where
94 V: VisitorCtx<'a>,
95 N: AstNode<'a>,
96 F: FnOnce(N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output,
97{
98 type Output = <V as VisitorCtx<'a>>::Output;
99 type Ctx = <V as VisitorCtx<'a>>::Ctx;
100
101 fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx> {
102 let VisCtx { inner, f, .. } = self;
103 inner.accept(node).or_else(|ctx|
104 match N::cast(node) {
105 None => Err(ctx),
106 Some(node) => Ok(f(node, ctx))
107 }
108 )
109 }
110}
diff --git a/crates/ra_syntax/src/algo/walk.rs b/crates/ra_syntax/src/algo/walk.rs
new file mode 100644
index 000000000..536ee705f
--- /dev/null
+++ b/crates/ra_syntax/src/algo/walk.rs
@@ -0,0 +1,38 @@
1use {
2 SyntaxNodeRef,
3 algo::generate,
4};
5
6pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
7 walk(root).filter_map(|event| match event {
8 WalkEvent::Enter(node) => Some(node),
9 WalkEvent::Exit(_) => None,
10 })
11}
12
13#[derive(Debug, Copy, Clone)]
14pub enum WalkEvent<'a> {
15 Enter(SyntaxNodeRef<'a>),
16 Exit(SyntaxNodeRef<'a>),
17}
18
19pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> {
20 generate(Some(WalkEvent::Enter(root)), move |pos| {
21 let next = match *pos {
22 WalkEvent::Enter(node) => match node.first_child() {
23 Some(child) => WalkEvent::Enter(child),
24 None => WalkEvent::Exit(node),
25 },
26 WalkEvent::Exit(node) => {
27 if node == root {
28 return None;
29 }
30 match node.next_sibling() {
31 Some(sibling) => WalkEvent::Enter(sibling),
32 None => WalkEvent::Exit(node.parent().unwrap()),
33 }
34 }
35 };
36 Some(next)
37 })
38}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
new file mode 100644
index 000000000..c945c094a
--- /dev/null
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -0,0 +1,2142 @@
1use {
2 ast,
3 SyntaxNodeRef, AstNode,
4 SyntaxKind::*,
5};
6
7// ArgList
8#[derive(Debug, Clone, Copy)]
9pub struct ArgList<'a> {
10 syntax: SyntaxNodeRef<'a>,
11}
12
13impl<'a> AstNode<'a> for ArgList<'a> {
14 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
15 match syntax.kind() {
16 ARG_LIST => Some(ArgList { syntax }),
17 _ => None,
18 }
19 }
20 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
21}
22
23impl<'a> ArgList<'a> {
24 pub fn args(self) -> impl Iterator<Item = Expr<'a>> + 'a {
25 super::children(self)
26 }
27}
28
29// ArrayExpr
30#[derive(Debug, Clone, Copy)]
31pub struct ArrayExpr<'a> {
32 syntax: SyntaxNodeRef<'a>,
33}
34
35impl<'a> AstNode<'a> for ArrayExpr<'a> {
36 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
37 match syntax.kind() {
38 ARRAY_EXPR => Some(ArrayExpr { syntax }),
39 _ => None,
40 }
41 }
42 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
43}
44
45impl<'a> ArrayExpr<'a> {}
46
47// ArrayType
48#[derive(Debug, Clone, Copy)]
49pub struct ArrayType<'a> {
50 syntax: SyntaxNodeRef<'a>,
51}
52
53impl<'a> AstNode<'a> for ArrayType<'a> {
54 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
55 match syntax.kind() {
56 ARRAY_TYPE => Some(ArrayType { syntax }),
57 _ => None,
58 }
59 }
60 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
61}
62
63impl<'a> ArrayType<'a> {}
64
65// Attr
66#[derive(Debug, Clone, Copy)]
67pub struct Attr<'a> {
68 syntax: SyntaxNodeRef<'a>,
69}
70
71impl<'a> AstNode<'a> for Attr<'a> {
72 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
73 match syntax.kind() {
74 ATTR => Some(Attr { syntax }),
75 _ => None,
76 }
77 }
78 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
79}
80
81impl<'a> Attr<'a> {pub fn value(self) -> Option<TokenTree<'a>> {
82 super::child_opt(self)
83 }
84}
85
86// BinExpr
87#[derive(Debug, Clone, Copy)]
88pub struct BinExpr<'a> {
89 syntax: SyntaxNodeRef<'a>,
90}
91
92impl<'a> AstNode<'a> for BinExpr<'a> {
93 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
94 match syntax.kind() {
95 BIN_EXPR => Some(BinExpr { syntax }),
96 _ => None,
97 }
98 }
99 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
100}
101
102impl<'a> BinExpr<'a> {}
103
104// BindPat
105#[derive(Debug, Clone, Copy)]
106pub struct BindPat<'a> {
107 syntax: SyntaxNodeRef<'a>,
108}
109
110impl<'a> AstNode<'a> for BindPat<'a> {
111 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
112 match syntax.kind() {
113 BIND_PAT => Some(BindPat { syntax }),
114 _ => None,
115 }
116 }
117 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
118}
119
120impl<'a> ast::NameOwner<'a> for BindPat<'a> {}
121impl<'a> BindPat<'a> {}
122
123// Block
124#[derive(Debug, Clone, Copy)]
125pub struct Block<'a> {
126 syntax: SyntaxNodeRef<'a>,
127}
128
129impl<'a> AstNode<'a> for Block<'a> {
130 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
131 match syntax.kind() {
132 BLOCK => Some(Block { syntax }),
133 _ => None,
134 }
135 }
136 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
137}
138
139impl<'a> Block<'a> {
140 pub fn statements(self) -> impl Iterator<Item = Stmt<'a>> + 'a {
141 super::children(self)
142 }
143pub fn expr(self) -> Option<Expr<'a>> {
144 super::child_opt(self)
145 }
146}
147
148// BlockExpr
149#[derive(Debug, Clone, Copy)]
150pub struct BlockExpr<'a> {
151 syntax: SyntaxNodeRef<'a>,
152}
153
154impl<'a> AstNode<'a> for BlockExpr<'a> {
155 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
156 match syntax.kind() {
157 BLOCK_EXPR => Some(BlockExpr { syntax }),
158 _ => None,
159 }
160 }
161 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
162}
163
164impl<'a> BlockExpr<'a> {pub fn block(self) -> Option<Block<'a>> {
165 super::child_opt(self)
166 }
167}
168
169// BreakExpr
170#[derive(Debug, Clone, Copy)]
171pub struct BreakExpr<'a> {
172 syntax: SyntaxNodeRef<'a>,
173}
174
175impl<'a> AstNode<'a> for BreakExpr<'a> {
176 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
177 match syntax.kind() {
178 BREAK_EXPR => Some(BreakExpr { syntax }),
179 _ => None,
180 }
181 }
182 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
183}
184
185impl<'a> BreakExpr<'a> {}
186
187// CallExpr
188#[derive(Debug, Clone, Copy)]
189pub struct CallExpr<'a> {
190 syntax: SyntaxNodeRef<'a>,
191}
192
193impl<'a> AstNode<'a> for CallExpr<'a> {
194 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
195 match syntax.kind() {
196 CALL_EXPR => Some(CallExpr { syntax }),
197 _ => None,
198 }
199 }
200 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
201}
202
203impl<'a> ast::ArgListOwner<'a> for CallExpr<'a> {}
204impl<'a> CallExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> {
205 super::child_opt(self)
206 }
207}
208
209// CastExpr
210#[derive(Debug, Clone, Copy)]
211pub struct CastExpr<'a> {
212 syntax: SyntaxNodeRef<'a>,
213}
214
215impl<'a> AstNode<'a> for CastExpr<'a> {
216 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
217 match syntax.kind() {
218 CAST_EXPR => Some(CastExpr { syntax }),
219 _ => None,
220 }
221 }
222 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
223}
224
225impl<'a> CastExpr<'a> {}
226
227// Condition
228#[derive(Debug, Clone, Copy)]
229pub struct Condition<'a> {
230 syntax: SyntaxNodeRef<'a>,
231}
232
233impl<'a> AstNode<'a> for Condition<'a> {
234 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
235 match syntax.kind() {
236 CONDITION => Some(Condition { syntax }),
237 _ => None,
238 }
239 }
240 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
241}
242
243impl<'a> Condition<'a> {pub fn pat(self) -> Option<Pat<'a>> {
244 super::child_opt(self)
245 }
246pub fn expr(self) -> Option<Expr<'a>> {
247 super::child_opt(self)
248 }
249}
250
251// ConstDef
252#[derive(Debug, Clone, Copy)]
253pub struct ConstDef<'a> {
254 syntax: SyntaxNodeRef<'a>,
255}
256
257impl<'a> AstNode<'a> for ConstDef<'a> {
258 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
259 match syntax.kind() {
260 CONST_DEF => Some(ConstDef { syntax }),
261 _ => None,
262 }
263 }
264 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
265}
266
267impl<'a> ast::NameOwner<'a> for ConstDef<'a> {}
268impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {}
269impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {}
270impl<'a> ConstDef<'a> {}
271
272// ContinueExpr
273#[derive(Debug, Clone, Copy)]
274pub struct ContinueExpr<'a> {
275 syntax: SyntaxNodeRef<'a>,
276}
277
278impl<'a> AstNode<'a> for ContinueExpr<'a> {
279 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
280 match syntax.kind() {
281 CONTINUE_EXPR => Some(ContinueExpr { syntax }),
282 _ => None,
283 }
284 }
285 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
286}
287
288impl<'a> ContinueExpr<'a> {}
289
290// DynTraitType
291#[derive(Debug, Clone, Copy)]
292pub struct DynTraitType<'a> {
293 syntax: SyntaxNodeRef<'a>,
294}
295
296impl<'a> AstNode<'a> for DynTraitType<'a> {
297 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
298 match syntax.kind() {
299 DYN_TRAIT_TYPE => Some(DynTraitType { syntax }),
300 _ => None,
301 }
302 }
303 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
304}
305
306impl<'a> DynTraitType<'a> {}
307
308// EnumDef
309#[derive(Debug, Clone, Copy)]
310pub struct EnumDef<'a> {
311 syntax: SyntaxNodeRef<'a>,
312}
313
314impl<'a> AstNode<'a> for EnumDef<'a> {
315 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
316 match syntax.kind() {
317 ENUM_DEF => Some(EnumDef { syntax }),
318 _ => None,
319 }
320 }
321 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
322}
323
324impl<'a> ast::NameOwner<'a> for EnumDef<'a> {}
325impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {}
326impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {}
327impl<'a> EnumDef<'a> {}
328
329// Expr
330#[derive(Debug, Clone, Copy)]
331pub enum Expr<'a> {
332 TupleExpr(TupleExpr<'a>),
333 ArrayExpr(ArrayExpr<'a>),
334 ParenExpr(ParenExpr<'a>),
335 PathExpr(PathExpr<'a>),
336 LambdaExpr(LambdaExpr<'a>),
337 IfExpr(IfExpr<'a>),
338 LoopExpr(LoopExpr<'a>),
339 ForExpr(ForExpr<'a>),
340 WhileExpr(WhileExpr<'a>),
341 ContinueExpr(ContinueExpr<'a>),
342 BreakExpr(BreakExpr<'a>),
343 Label(Label<'a>),
344 BlockExpr(BlockExpr<'a>),
345 ReturnExpr(ReturnExpr<'a>),
346 MatchExpr(MatchExpr<'a>),
347 MatchArmList(MatchArmList<'a>),
348 MatchArm(MatchArm<'a>),
349 MatchGuard(MatchGuard<'a>),
350 StructLit(StructLit<'a>),
351 NamedFieldList(NamedFieldList<'a>),
352 NamedField(NamedField<'a>),
353 CallExpr(CallExpr<'a>),
354 IndexExpr(IndexExpr<'a>),
355 MethodCallExpr(MethodCallExpr<'a>),
356 FieldExpr(FieldExpr<'a>),
357 TryExpr(TryExpr<'a>),
358 CastExpr(CastExpr<'a>),
359 RefExpr(RefExpr<'a>),
360 PrefixExpr(PrefixExpr<'a>),
361 RangeExpr(RangeExpr<'a>),
362 BinExpr(BinExpr<'a>),
363 Literal(Literal<'a>),
364}
365
366impl<'a> AstNode<'a> for Expr<'a> {
367 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
368 match syntax.kind() {
369 TUPLE_EXPR => Some(Expr::TupleExpr(TupleExpr { syntax })),
370 ARRAY_EXPR => Some(Expr::ArrayExpr(ArrayExpr { syntax })),
371 PAREN_EXPR => Some(Expr::ParenExpr(ParenExpr { syntax })),
372 PATH_EXPR => Some(Expr::PathExpr(PathExpr { syntax })),
373 LAMBDA_EXPR => Some(Expr::LambdaExpr(LambdaExpr { syntax })),
374 IF_EXPR => Some(Expr::IfExpr(IfExpr { syntax })),
375 LOOP_EXPR => Some(Expr::LoopExpr(LoopExpr { syntax })),
376 FOR_EXPR => Some(Expr::ForExpr(ForExpr { syntax })),
377 WHILE_EXPR => Some(Expr::WhileExpr(WhileExpr { syntax })),
378 CONTINUE_EXPR => Some(Expr::ContinueExpr(ContinueExpr { syntax })),
379 BREAK_EXPR => Some(Expr::BreakExpr(BreakExpr { syntax })),
380 LABEL => Some(Expr::Label(Label { syntax })),
381 BLOCK_EXPR => Some(Expr::BlockExpr(BlockExpr { syntax })),
382 RETURN_EXPR => Some(Expr::ReturnExpr(ReturnExpr { syntax })),
383 MATCH_EXPR => Some(Expr::MatchExpr(MatchExpr { syntax })),
384 MATCH_ARM_LIST => Some(Expr::MatchArmList(MatchArmList { syntax })),
385 MATCH_ARM => Some(Expr::MatchArm(MatchArm { syntax })),
386 MATCH_GUARD => Some(Expr::MatchGuard(MatchGuard { syntax })),
387 STRUCT_LIT => Some(Expr::StructLit(StructLit { syntax })),
388 NAMED_FIELD_LIST => Some(Expr::NamedFieldList(NamedFieldList { syntax })),
389 NAMED_FIELD => Some(Expr::NamedField(NamedField { syntax })),
390 CALL_EXPR => Some(Expr::CallExpr(CallExpr { syntax })),
391 INDEX_EXPR => Some(Expr::IndexExpr(IndexExpr { syntax })),
392 METHOD_CALL_EXPR => Some(Expr::MethodCallExpr(MethodCallExpr { syntax })),
393 FIELD_EXPR => Some(Expr::FieldExpr(FieldExpr { syntax })),
394 TRY_EXPR => Some(Expr::TryExpr(TryExpr { syntax })),
395 CAST_EXPR => Some(Expr::CastExpr(CastExpr { syntax })),
396 REF_EXPR => Some(Expr::RefExpr(RefExpr { syntax })),
397 PREFIX_EXPR => Some(Expr::PrefixExpr(PrefixExpr { syntax })),
398 RANGE_EXPR => Some(Expr::RangeExpr(RangeExpr { syntax })),
399 BIN_EXPR => Some(Expr::BinExpr(BinExpr { syntax })),
400 LITERAL => Some(Expr::Literal(Literal { syntax })),
401 _ => None,
402 }
403 }
404 fn syntax(self) -> SyntaxNodeRef<'a> {
405 match self {
406 Expr::TupleExpr(inner) => inner.syntax(),
407 Expr::ArrayExpr(inner) => inner.syntax(),
408 Expr::ParenExpr(inner) => inner.syntax(),
409 Expr::PathExpr(inner) => inner.syntax(),
410 Expr::LambdaExpr(inner) => inner.syntax(),
411 Expr::IfExpr(inner) => inner.syntax(),
412 Expr::LoopExpr(inner) => inner.syntax(),
413 Expr::ForExpr(inner) => inner.syntax(),
414 Expr::WhileExpr(inner) => inner.syntax(),
415 Expr::ContinueExpr(inner) => inner.syntax(),
416 Expr::BreakExpr(inner) => inner.syntax(),
417 Expr::Label(inner) => inner.syntax(),
418 Expr::BlockExpr(inner) => inner.syntax(),
419 Expr::ReturnExpr(inner) => inner.syntax(),
420 Expr::MatchExpr(inner) => inner.syntax(),
421 Expr::MatchArmList(inner) => inner.syntax(),
422 Expr::MatchArm(inner) => inner.syntax(),
423 Expr::MatchGuard(inner) => inner.syntax(),
424 Expr::StructLit(inner) => inner.syntax(),
425 Expr::NamedFieldList(inner) => inner.syntax(),
426 Expr::NamedField(inner) => inner.syntax(),
427 Expr::CallExpr(inner) => inner.syntax(),
428 Expr::IndexExpr(inner) => inner.syntax(),
429 Expr::MethodCallExpr(inner) => inner.syntax(),
430 Expr::FieldExpr(inner) => inner.syntax(),
431 Expr::TryExpr(inner) => inner.syntax(),
432 Expr::CastExpr(inner) => inner.syntax(),
433 Expr::RefExpr(inner) => inner.syntax(),
434 Expr::PrefixExpr(inner) => inner.syntax(),
435 Expr::RangeExpr(inner) => inner.syntax(),
436 Expr::BinExpr(inner) => inner.syntax(),
437 Expr::Literal(inner) => inner.syntax(),
438 }
439 }
440}
441
442impl<'a> Expr<'a> {}
443
444// ExprStmt
445#[derive(Debug, Clone, Copy)]
446pub struct ExprStmt<'a> {
447 syntax: SyntaxNodeRef<'a>,
448}
449
450impl<'a> AstNode<'a> for ExprStmt<'a> {
451 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
452 match syntax.kind() {
453 EXPR_STMT => Some(ExprStmt { syntax }),
454 _ => None,
455 }
456 }
457 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
458}
459
460impl<'a> ExprStmt<'a> {pub fn expr(self) -> Option<Expr<'a>> {
461 super::child_opt(self)
462 }
463}
464
465// ExternCrateItem
466#[derive(Debug, Clone, Copy)]
467pub struct ExternCrateItem<'a> {
468 syntax: SyntaxNodeRef<'a>,
469}
470
471impl<'a> AstNode<'a> for ExternCrateItem<'a> {
472 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
473 match syntax.kind() {
474 EXTERN_CRATE_ITEM => Some(ExternCrateItem { syntax }),
475 _ => None,
476 }
477 }
478 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
479}
480
481impl<'a> ExternCrateItem<'a> {}
482
483// FieldExpr
484#[derive(Debug, Clone, Copy)]
485pub struct FieldExpr<'a> {
486 syntax: SyntaxNodeRef<'a>,
487}
488
489impl<'a> AstNode<'a> for FieldExpr<'a> {
490 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
491 match syntax.kind() {
492 FIELD_EXPR => Some(FieldExpr { syntax }),
493 _ => None,
494 }
495 }
496 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
497}
498
499impl<'a> FieldExpr<'a> {}
500
501// FieldPatList
502#[derive(Debug, Clone, Copy)]
503pub struct FieldPatList<'a> {
504 syntax: SyntaxNodeRef<'a>,
505}
506
507impl<'a> AstNode<'a> for FieldPatList<'a> {
508 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
509 match syntax.kind() {
510 FIELD_PAT_LIST => Some(FieldPatList { syntax }),
511 _ => None,
512 }
513 }
514 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
515}
516
517impl<'a> FieldPatList<'a> {}
518
519// FnDef
520#[derive(Debug, Clone, Copy)]
521pub struct FnDef<'a> {
522 syntax: SyntaxNodeRef<'a>,
523}
524
525impl<'a> AstNode<'a> for FnDef<'a> {
526 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
527 match syntax.kind() {
528 FN_DEF => Some(FnDef { syntax }),
529 _ => None,
530 }
531 }
532 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
533}
534
535impl<'a> ast::NameOwner<'a> for FnDef<'a> {}
536impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {}
537impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {}
538impl<'a> FnDef<'a> {pub fn param_list(self) -> Option<ParamList<'a>> {
539 super::child_opt(self)
540 }
541pub fn body(self) -> Option<Block<'a>> {
542 super::child_opt(self)
543 }
544pub fn ret_type(self) -> Option<RetType<'a>> {
545 super::child_opt(self)
546 }
547}
548
549// FnPointerType
550#[derive(Debug, Clone, Copy)]
551pub struct FnPointerType<'a> {
552 syntax: SyntaxNodeRef<'a>,
553}
554
555impl<'a> AstNode<'a> for FnPointerType<'a> {
556 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
557 match syntax.kind() {
558 FN_POINTER_TYPE => Some(FnPointerType { syntax }),
559 _ => None,
560 }
561 }
562 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
563}
564
565impl<'a> FnPointerType<'a> {}
566
567// ForExpr
568#[derive(Debug, Clone, Copy)]
569pub struct ForExpr<'a> {
570 syntax: SyntaxNodeRef<'a>,
571}
572
573impl<'a> AstNode<'a> for ForExpr<'a> {
574 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
575 match syntax.kind() {
576 FOR_EXPR => Some(ForExpr { syntax }),
577 _ => None,
578 }
579 }
580 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
581}
582
583impl<'a> ast::LoopBodyOwner<'a> for ForExpr<'a> {}
584impl<'a> ForExpr<'a> {pub fn pat(self) -> Option<Pat<'a>> {
585 super::child_opt(self)
586 }
587pub fn iterable(self) -> Option<Expr<'a>> {
588 super::child_opt(self)
589 }
590}
591
592// ForType
593#[derive(Debug, Clone, Copy)]
594pub struct ForType<'a> {
595 syntax: SyntaxNodeRef<'a>,
596}
597
598impl<'a> AstNode<'a> for ForType<'a> {
599 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
600 match syntax.kind() {
601 FOR_TYPE => Some(ForType { syntax }),
602 _ => None,
603 }
604 }
605 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
606}
607
608impl<'a> ForType<'a> {}
609
610// IfExpr
611#[derive(Debug, Clone, Copy)]
612pub struct IfExpr<'a> {
613 syntax: SyntaxNodeRef<'a>,
614}
615
616impl<'a> AstNode<'a> for IfExpr<'a> {
617 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
618 match syntax.kind() {
619 IF_EXPR => Some(IfExpr { syntax }),
620 _ => None,
621 }
622 }
623 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
624}
625
626impl<'a> IfExpr<'a> {pub fn condition(self) -> Option<Condition<'a>> {
627 super::child_opt(self)
628 }
629}
630
631// ImplItem
632#[derive(Debug, Clone, Copy)]
633pub struct ImplItem<'a> {
634 syntax: SyntaxNodeRef<'a>,
635}
636
637impl<'a> AstNode<'a> for ImplItem<'a> {
638 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
639 match syntax.kind() {
640 IMPL_ITEM => Some(ImplItem { syntax }),
641 _ => None,
642 }
643 }
644 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
645}
646
647impl<'a> ImplItem<'a> {}
648
649// ImplTraitType
650#[derive(Debug, Clone, Copy)]
651pub struct ImplTraitType<'a> {
652 syntax: SyntaxNodeRef<'a>,
653}
654
655impl<'a> AstNode<'a> for ImplTraitType<'a> {
656 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
657 match syntax.kind() {
658 IMPL_TRAIT_TYPE => Some(ImplTraitType { syntax }),
659 _ => None,
660 }
661 }
662 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
663}
664
665impl<'a> ImplTraitType<'a> {}
666
667// IndexExpr
668#[derive(Debug, Clone, Copy)]
669pub struct IndexExpr<'a> {
670 syntax: SyntaxNodeRef<'a>,
671}
672
673impl<'a> AstNode<'a> for IndexExpr<'a> {
674 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
675 match syntax.kind() {
676 INDEX_EXPR => Some(IndexExpr { syntax }),
677 _ => None,
678 }
679 }
680 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
681}
682
683impl<'a> IndexExpr<'a> {}
684
685// ItemList
686#[derive(Debug, Clone, Copy)]
687pub struct ItemList<'a> {
688 syntax: SyntaxNodeRef<'a>,
689}
690
691impl<'a> AstNode<'a> for ItemList<'a> {
692 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
693 match syntax.kind() {
694 ITEM_LIST => Some(ItemList { syntax }),
695 _ => None,
696 }
697 }
698 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
699}
700
701impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {}
702impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {}
703impl<'a> ItemList<'a> {}
704
705// Label
706#[derive(Debug, Clone, Copy)]
707pub struct Label<'a> {
708 syntax: SyntaxNodeRef<'a>,
709}
710
711impl<'a> AstNode<'a> for Label<'a> {
712 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
713 match syntax.kind() {
714 LABEL => Some(Label { syntax }),
715 _ => None,
716 }
717 }
718 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
719}
720
721impl<'a> Label<'a> {}
722
723// LambdaExpr
724#[derive(Debug, Clone, Copy)]
725pub struct LambdaExpr<'a> {
726 syntax: SyntaxNodeRef<'a>,
727}
728
729impl<'a> AstNode<'a> for LambdaExpr<'a> {
730 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
731 match syntax.kind() {
732 LAMBDA_EXPR => Some(LambdaExpr { syntax }),
733 _ => None,
734 }
735 }
736 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
737}
738
739impl<'a> LambdaExpr<'a> {pub fn param_list(self) -> Option<ParamList<'a>> {
740 super::child_opt(self)
741 }
742pub fn body(self) -> Option<Expr<'a>> {
743 super::child_opt(self)
744 }
745}
746
747// LetStmt
748#[derive(Debug, Clone, Copy)]
749pub struct LetStmt<'a> {
750 syntax: SyntaxNodeRef<'a>,
751}
752
753impl<'a> AstNode<'a> for LetStmt<'a> {
754 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
755 match syntax.kind() {
756 LET_STMT => Some(LetStmt { syntax }),
757 _ => None,
758 }
759 }
760 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
761}
762
763impl<'a> LetStmt<'a> {pub fn pat(self) -> Option<Pat<'a>> {
764 super::child_opt(self)
765 }
766pub fn initializer(self) -> Option<Expr<'a>> {
767 super::child_opt(self)
768 }
769}
770
771// Lifetime
772#[derive(Debug, Clone, Copy)]
773pub struct Lifetime<'a> {
774 syntax: SyntaxNodeRef<'a>,
775}
776
777impl<'a> AstNode<'a> for Lifetime<'a> {
778 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
779 match syntax.kind() {
780 LIFETIME => Some(Lifetime { syntax }),
781 _ => None,
782 }
783 }
784 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
785}
786
787impl<'a> Lifetime<'a> {}
788
789// LifetimeParam
790#[derive(Debug, Clone, Copy)]
791pub struct LifetimeParam<'a> {
792 syntax: SyntaxNodeRef<'a>,
793}
794
795impl<'a> AstNode<'a> for LifetimeParam<'a> {
796 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
797 match syntax.kind() {
798 LIFETIME_PARAM => Some(LifetimeParam { syntax }),
799 _ => None,
800 }
801 }
802 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
803}
804
805impl<'a> LifetimeParam<'a> {pub fn lifetime(self) -> Option<Lifetime<'a>> {
806 super::child_opt(self)
807 }
808}
809
810// Literal
811#[derive(Debug, Clone, Copy)]
812pub struct Literal<'a> {
813 syntax: SyntaxNodeRef<'a>,
814}
815
816impl<'a> AstNode<'a> for Literal<'a> {
817 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
818 match syntax.kind() {
819 LITERAL => Some(Literal { syntax }),
820 _ => None,
821 }
822 }
823 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
824}
825
826impl<'a> Literal<'a> {}
827
828// LoopExpr
829#[derive(Debug, Clone, Copy)]
830pub struct LoopExpr<'a> {
831 syntax: SyntaxNodeRef<'a>,
832}
833
834impl<'a> AstNode<'a> for LoopExpr<'a> {
835 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
836 match syntax.kind() {
837 LOOP_EXPR => Some(LoopExpr { syntax }),
838 _ => None,
839 }
840 }
841 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
842}
843
844impl<'a> ast::LoopBodyOwner<'a> for LoopExpr<'a> {}
845impl<'a> LoopExpr<'a> {}
846
847// MatchArm
848#[derive(Debug, Clone, Copy)]
849pub struct MatchArm<'a> {
850 syntax: SyntaxNodeRef<'a>,
851}
852
853impl<'a> AstNode<'a> for MatchArm<'a> {
854 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
855 match syntax.kind() {
856 MATCH_ARM => Some(MatchArm { syntax }),
857 _ => None,
858 }
859 }
860 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
861}
862
863impl<'a> MatchArm<'a> {
864 pub fn pats(self) -> impl Iterator<Item = Pat<'a>> + 'a {
865 super::children(self)
866 }
867pub fn guard(self) -> Option<MatchGuard<'a>> {
868 super::child_opt(self)
869 }
870pub fn expr(self) -> Option<Expr<'a>> {
871 super::child_opt(self)
872 }
873}
874
875// MatchArmList
876#[derive(Debug, Clone, Copy)]
877pub struct MatchArmList<'a> {
878 syntax: SyntaxNodeRef<'a>,
879}
880
881impl<'a> AstNode<'a> for MatchArmList<'a> {
882 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
883 match syntax.kind() {
884 MATCH_ARM_LIST => Some(MatchArmList { syntax }),
885 _ => None,
886 }
887 }
888 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
889}
890
891impl<'a> MatchArmList<'a> {
892 pub fn arms(self) -> impl Iterator<Item = MatchArm<'a>> + 'a {
893 super::children(self)
894 }
895}
896
897// MatchExpr
898#[derive(Debug, Clone, Copy)]
899pub struct MatchExpr<'a> {
900 syntax: SyntaxNodeRef<'a>,
901}
902
903impl<'a> AstNode<'a> for MatchExpr<'a> {
904 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
905 match syntax.kind() {
906 MATCH_EXPR => Some(MatchExpr { syntax }),
907 _ => None,
908 }
909 }
910 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
911}
912
913impl<'a> MatchExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> {
914 super::child_opt(self)
915 }
916pub fn match_arm_list(self) -> Option<MatchArmList<'a>> {
917 super::child_opt(self)
918 }
919}
920
921// MatchGuard
922#[derive(Debug, Clone, Copy)]
923pub struct MatchGuard<'a> {
924 syntax: SyntaxNodeRef<'a>,
925}
926
927impl<'a> AstNode<'a> for MatchGuard<'a> {
928 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
929 match syntax.kind() {
930 MATCH_GUARD => Some(MatchGuard { syntax }),
931 _ => None,
932 }
933 }
934 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
935}
936
937impl<'a> MatchGuard<'a> {}
938
939// MethodCallExpr
940#[derive(Debug, Clone, Copy)]
941pub struct MethodCallExpr<'a> {
942 syntax: SyntaxNodeRef<'a>,
943}
944
945impl<'a> AstNode<'a> for MethodCallExpr<'a> {
946 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
947 match syntax.kind() {
948 METHOD_CALL_EXPR => Some(MethodCallExpr { syntax }),
949 _ => None,
950 }
951 }
952 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
953}
954
955impl<'a> ast::ArgListOwner<'a> for MethodCallExpr<'a> {}
956impl<'a> MethodCallExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> {
957 super::child_opt(self)
958 }
959}
960
961// Module
962#[derive(Debug, Clone, Copy)]
963pub struct Module<'a> {
964 syntax: SyntaxNodeRef<'a>,
965}
966
967impl<'a> AstNode<'a> for Module<'a> {
968 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
969 match syntax.kind() {
970 MODULE => Some(Module { syntax }),
971 _ => None,
972 }
973 }
974 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
975}
976
977impl<'a> ast::NameOwner<'a> for Module<'a> {}
978impl<'a> ast::AttrsOwner<'a> for Module<'a> {}
979impl<'a> Module<'a> {pub fn item_list(self) -> Option<ItemList<'a>> {
980 super::child_opt(self)
981 }
982}
983
984// ModuleItem
985#[derive(Debug, Clone, Copy)]
986pub enum ModuleItem<'a> {
987 StructDef(StructDef<'a>),
988 EnumDef(EnumDef<'a>),
989 FnDef(FnDef<'a>),
990 TraitDef(TraitDef<'a>),
991 TypeDef(TypeDef<'a>),
992 ImplItem(ImplItem<'a>),
993 UseItem(UseItem<'a>),
994 ExternCrateItem(ExternCrateItem<'a>),
995 ConstDef(ConstDef<'a>),
996 StaticDef(StaticDef<'a>),
997 Module(Module<'a>),
998}
999
1000impl<'a> AstNode<'a> for ModuleItem<'a> {
1001 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1002 match syntax.kind() {
1003 STRUCT_DEF => Some(ModuleItem::StructDef(StructDef { syntax })),
1004 ENUM_DEF => Some(ModuleItem::EnumDef(EnumDef { syntax })),
1005 FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })),
1006 TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })),
1007 TYPE_DEF => Some(ModuleItem::TypeDef(TypeDef { syntax })),
1008 IMPL_ITEM => Some(ModuleItem::ImplItem(ImplItem { syntax })),
1009 USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })),
1010 EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })),
1011 CONST_DEF => Some(ModuleItem::ConstDef(ConstDef { syntax })),
1012 STATIC_DEF => Some(ModuleItem::StaticDef(StaticDef { syntax })),
1013 MODULE => Some(ModuleItem::Module(Module { syntax })),
1014 _ => None,
1015 }
1016 }
1017 fn syntax(self) -> SyntaxNodeRef<'a> {
1018 match self {
1019 ModuleItem::StructDef(inner) => inner.syntax(),
1020 ModuleItem::EnumDef(inner) => inner.syntax(),
1021 ModuleItem::FnDef(inner) => inner.syntax(),
1022 ModuleItem::TraitDef(inner) => inner.syntax(),
1023 ModuleItem::TypeDef(inner) => inner.syntax(),
1024 ModuleItem::ImplItem(inner) => inner.syntax(),
1025 ModuleItem::UseItem(inner) => inner.syntax(),
1026 ModuleItem::ExternCrateItem(inner) => inner.syntax(),
1027 ModuleItem::ConstDef(inner) => inner.syntax(),
1028 ModuleItem::StaticDef(inner) => inner.syntax(),
1029 ModuleItem::Module(inner) => inner.syntax(),
1030 }
1031 }
1032}
1033
1034impl<'a> ModuleItem<'a> {}
1035
1036// Name
1037#[derive(Debug, Clone, Copy)]
1038pub struct Name<'a> {
1039 syntax: SyntaxNodeRef<'a>,
1040}
1041
1042impl<'a> AstNode<'a> for Name<'a> {
1043 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1044 match syntax.kind() {
1045 NAME => Some(Name { syntax }),
1046 _ => None,
1047 }
1048 }
1049 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1050}
1051
1052impl<'a> Name<'a> {}
1053
1054// NameRef
1055#[derive(Debug, Clone, Copy)]
1056pub struct NameRef<'a> {
1057 syntax: SyntaxNodeRef<'a>,
1058}
1059
1060impl<'a> AstNode<'a> for NameRef<'a> {
1061 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1062 match syntax.kind() {
1063 NAME_REF => Some(NameRef { syntax }),
1064 _ => None,
1065 }
1066 }
1067 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1068}
1069
1070impl<'a> NameRef<'a> {}
1071
1072// NamedField
1073#[derive(Debug, Clone, Copy)]
1074pub struct NamedField<'a> {
1075 syntax: SyntaxNodeRef<'a>,
1076}
1077
1078impl<'a> AstNode<'a> for NamedField<'a> {
1079 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1080 match syntax.kind() {
1081 NAMED_FIELD => Some(NamedField { syntax }),
1082 _ => None,
1083 }
1084 }
1085 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1086}
1087
1088impl<'a> NamedField<'a> {}
1089
1090// NamedFieldDef
1091#[derive(Debug, Clone, Copy)]
1092pub struct NamedFieldDef<'a> {
1093 syntax: SyntaxNodeRef<'a>,
1094}
1095
1096impl<'a> AstNode<'a> for NamedFieldDef<'a> {
1097 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1098 match syntax.kind() {
1099 NAMED_FIELD_DEF => Some(NamedFieldDef { syntax }),
1100 _ => None,
1101 }
1102 }
1103 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1104}
1105
1106impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {}
1107impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {}
1108impl<'a> NamedFieldDef<'a> {}
1109
1110// NamedFieldList
1111#[derive(Debug, Clone, Copy)]
1112pub struct NamedFieldList<'a> {
1113 syntax: SyntaxNodeRef<'a>,
1114}
1115
1116impl<'a> AstNode<'a> for NamedFieldList<'a> {
1117 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1118 match syntax.kind() {
1119 NAMED_FIELD_LIST => Some(NamedFieldList { syntax }),
1120 _ => None,
1121 }
1122 }
1123 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1124}
1125
1126impl<'a> NamedFieldList<'a> {}
1127
1128// NeverType
1129#[derive(Debug, Clone, Copy)]
1130pub struct NeverType<'a> {
1131 syntax: SyntaxNodeRef<'a>,
1132}
1133
1134impl<'a> AstNode<'a> for NeverType<'a> {
1135 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1136 match syntax.kind() {
1137 NEVER_TYPE => Some(NeverType { syntax }),
1138 _ => None,
1139 }
1140 }
1141 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1142}
1143
1144impl<'a> NeverType<'a> {}
1145
1146// NominalDef
1147#[derive(Debug, Clone, Copy)]
1148pub enum NominalDef<'a> {
1149 StructDef(StructDef<'a>),
1150 EnumDef(EnumDef<'a>),
1151}
1152
1153impl<'a> AstNode<'a> for NominalDef<'a> {
1154 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1155 match syntax.kind() {
1156 STRUCT_DEF => Some(NominalDef::StructDef(StructDef { syntax })),
1157 ENUM_DEF => Some(NominalDef::EnumDef(EnumDef { syntax })),
1158 _ => None,
1159 }
1160 }
1161 fn syntax(self) -> SyntaxNodeRef<'a> {
1162 match self {
1163 NominalDef::StructDef(inner) => inner.syntax(),
1164 NominalDef::EnumDef(inner) => inner.syntax(),
1165 }
1166 }
1167}
1168
1169impl<'a> ast::NameOwner<'a> for NominalDef<'a> {}
1170impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {}
1171impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {}
1172impl<'a> NominalDef<'a> {}
1173
1174// Param
1175#[derive(Debug, Clone, Copy)]
1176pub struct Param<'a> {
1177 syntax: SyntaxNodeRef<'a>,
1178}
1179
1180impl<'a> AstNode<'a> for Param<'a> {
1181 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1182 match syntax.kind() {
1183 PARAM => Some(Param { syntax }),
1184 _ => None,
1185 }
1186 }
1187 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1188}
1189
1190impl<'a> Param<'a> {pub fn pat(self) -> Option<Pat<'a>> {
1191 super::child_opt(self)
1192 }
1193}
1194
1195// ParamList
1196#[derive(Debug, Clone, Copy)]
1197pub struct ParamList<'a> {
1198 syntax: SyntaxNodeRef<'a>,
1199}
1200
1201impl<'a> AstNode<'a> for ParamList<'a> {
1202 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1203 match syntax.kind() {
1204 PARAM_LIST => Some(ParamList { syntax }),
1205 _ => None,
1206 }
1207 }
1208 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1209}
1210
1211impl<'a> ParamList<'a> {
1212 pub fn params(self) -> impl Iterator<Item = Param<'a>> + 'a {
1213 super::children(self)
1214 }
1215pub fn self_param(self) -> Option<SelfParam<'a>> {
1216 super::child_opt(self)
1217 }
1218}
1219
1220// ParenExpr
1221#[derive(Debug, Clone, Copy)]
1222pub struct ParenExpr<'a> {
1223 syntax: SyntaxNodeRef<'a>,
1224}
1225
1226impl<'a> AstNode<'a> for ParenExpr<'a> {
1227 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1228 match syntax.kind() {
1229 PAREN_EXPR => Some(ParenExpr { syntax }),
1230 _ => None,
1231 }
1232 }
1233 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1234}
1235
1236impl<'a> ParenExpr<'a> {}
1237
1238// ParenType
1239#[derive(Debug, Clone, Copy)]
1240pub struct ParenType<'a> {
1241 syntax: SyntaxNodeRef<'a>,
1242}
1243
1244impl<'a> AstNode<'a> for ParenType<'a> {
1245 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1246 match syntax.kind() {
1247 PAREN_TYPE => Some(ParenType { syntax }),
1248 _ => None,
1249 }
1250 }
1251 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1252}
1253
1254impl<'a> ParenType<'a> {}
1255
1256// Pat
1257#[derive(Debug, Clone, Copy)]
1258pub enum Pat<'a> {
1259 RefPat(RefPat<'a>),
1260 BindPat(BindPat<'a>),
1261 PlaceholderPat(PlaceholderPat<'a>),
1262 PathPat(PathPat<'a>),
1263 StructPat(StructPat<'a>),
1264 FieldPatList(FieldPatList<'a>),
1265 TupleStructPat(TupleStructPat<'a>),
1266 TuplePat(TuplePat<'a>),
1267 SlicePat(SlicePat<'a>),
1268 RangePat(RangePat<'a>),
1269}
1270
1271impl<'a> AstNode<'a> for Pat<'a> {
1272 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1273 match syntax.kind() {
1274 REF_PAT => Some(Pat::RefPat(RefPat { syntax })),
1275 BIND_PAT => Some(Pat::BindPat(BindPat { syntax })),
1276 PLACEHOLDER_PAT => Some(Pat::PlaceholderPat(PlaceholderPat { syntax })),
1277 PATH_PAT => Some(Pat::PathPat(PathPat { syntax })),
1278 STRUCT_PAT => Some(Pat::StructPat(StructPat { syntax })),
1279 FIELD_PAT_LIST => Some(Pat::FieldPatList(FieldPatList { syntax })),
1280 TUPLE_STRUCT_PAT => Some(Pat::TupleStructPat(TupleStructPat { syntax })),
1281 TUPLE_PAT => Some(Pat::TuplePat(TuplePat { syntax })),
1282 SLICE_PAT => Some(Pat::SlicePat(SlicePat { syntax })),
1283 RANGE_PAT => Some(Pat::RangePat(RangePat { syntax })),
1284 _ => None,
1285 }
1286 }
1287 fn syntax(self) -> SyntaxNodeRef<'a> {
1288 match self {
1289 Pat::RefPat(inner) => inner.syntax(),
1290 Pat::BindPat(inner) => inner.syntax(),
1291 Pat::PlaceholderPat(inner) => inner.syntax(),
1292 Pat::PathPat(inner) => inner.syntax(),
1293 Pat::StructPat(inner) => inner.syntax(),
1294 Pat::FieldPatList(inner) => inner.syntax(),
1295 Pat::TupleStructPat(inner) => inner.syntax(),
1296 Pat::TuplePat(inner) => inner.syntax(),
1297 Pat::SlicePat(inner) => inner.syntax(),
1298 Pat::RangePat(inner) => inner.syntax(),
1299 }
1300 }
1301}
1302
1303impl<'a> Pat<'a> {}
1304
1305// Path
1306#[derive(Debug, Clone, Copy)]
1307pub struct Path<'a> {
1308 syntax: SyntaxNodeRef<'a>,
1309}
1310
1311impl<'a> AstNode<'a> for Path<'a> {
1312 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1313 match syntax.kind() {
1314 PATH => Some(Path { syntax }),
1315 _ => None,
1316 }
1317 }
1318 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1319}
1320
1321impl<'a> Path<'a> {pub fn segment(self) -> Option<PathSegment<'a>> {
1322 super::child_opt(self)
1323 }
1324}
1325
1326// PathExpr
1327#[derive(Debug, Clone, Copy)]
1328pub struct PathExpr<'a> {
1329 syntax: SyntaxNodeRef<'a>,
1330}
1331
1332impl<'a> AstNode<'a> for PathExpr<'a> {
1333 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1334 match syntax.kind() {
1335 PATH_EXPR => Some(PathExpr { syntax }),
1336 _ => None,
1337 }
1338 }
1339 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1340}
1341
1342impl<'a> PathExpr<'a> {}
1343
1344// PathPat
1345#[derive(Debug, Clone, Copy)]
1346pub struct PathPat<'a> {
1347 syntax: SyntaxNodeRef<'a>,
1348}
1349
1350impl<'a> AstNode<'a> for PathPat<'a> {
1351 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1352 match syntax.kind() {
1353 PATH_PAT => Some(PathPat { syntax }),
1354 _ => None,
1355 }
1356 }
1357 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1358}
1359
1360impl<'a> PathPat<'a> {}
1361
1362// PathSegment
1363#[derive(Debug, Clone, Copy)]
1364pub struct PathSegment<'a> {
1365 syntax: SyntaxNodeRef<'a>,
1366}
1367
1368impl<'a> AstNode<'a> for PathSegment<'a> {
1369 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1370 match syntax.kind() {
1371 PATH_SEGMENT => Some(PathSegment { syntax }),
1372 _ => None,
1373 }
1374 }
1375 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1376}
1377
1378impl<'a> PathSegment<'a> {pub fn name_ref(self) -> Option<NameRef<'a>> {
1379 super::child_opt(self)
1380 }
1381}
1382
1383// PathType
1384#[derive(Debug, Clone, Copy)]
1385pub struct PathType<'a> {
1386 syntax: SyntaxNodeRef<'a>,
1387}
1388
1389impl<'a> AstNode<'a> for PathType<'a> {
1390 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1391 match syntax.kind() {
1392 PATH_TYPE => Some(PathType { syntax }),
1393 _ => None,
1394 }
1395 }
1396 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1397}
1398
1399impl<'a> PathType<'a> {}
1400
1401// PlaceholderPat
1402#[derive(Debug, Clone, Copy)]
1403pub struct PlaceholderPat<'a> {
1404 syntax: SyntaxNodeRef<'a>,
1405}
1406
1407impl<'a> AstNode<'a> for PlaceholderPat<'a> {
1408 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1409 match syntax.kind() {
1410 PLACEHOLDER_PAT => Some(PlaceholderPat { syntax }),
1411 _ => None,
1412 }
1413 }
1414 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1415}
1416
1417impl<'a> PlaceholderPat<'a> {}
1418
1419// PlaceholderType
1420#[derive(Debug, Clone, Copy)]
1421pub struct PlaceholderType<'a> {
1422 syntax: SyntaxNodeRef<'a>,
1423}
1424
1425impl<'a> AstNode<'a> for PlaceholderType<'a> {
1426 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1427 match syntax.kind() {
1428 PLACEHOLDER_TYPE => Some(PlaceholderType { syntax }),
1429 _ => None,
1430 }
1431 }
1432 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1433}
1434
1435impl<'a> PlaceholderType<'a> {}
1436
1437// PointerType
1438#[derive(Debug, Clone, Copy)]
1439pub struct PointerType<'a> {
1440 syntax: SyntaxNodeRef<'a>,
1441}
1442
1443impl<'a> AstNode<'a> for PointerType<'a> {
1444 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1445 match syntax.kind() {
1446 POINTER_TYPE => Some(PointerType { syntax }),
1447 _ => None,
1448 }
1449 }
1450 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1451}
1452
1453impl<'a> PointerType<'a> {}
1454
1455// PrefixExpr
1456#[derive(Debug, Clone, Copy)]
1457pub struct PrefixExpr<'a> {
1458 syntax: SyntaxNodeRef<'a>,
1459}
1460
1461impl<'a> AstNode<'a> for PrefixExpr<'a> {
1462 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1463 match syntax.kind() {
1464 PREFIX_EXPR => Some(PrefixExpr { syntax }),
1465 _ => None,
1466 }
1467 }
1468 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1469}
1470
1471impl<'a> PrefixExpr<'a> {}
1472
1473// RangeExpr
1474#[derive(Debug, Clone, Copy)]
1475pub struct RangeExpr<'a> {
1476 syntax: SyntaxNodeRef<'a>,
1477}
1478
1479impl<'a> AstNode<'a> for RangeExpr<'a> {
1480 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1481 match syntax.kind() {
1482 RANGE_EXPR => Some(RangeExpr { syntax }),
1483 _ => None,
1484 }
1485 }
1486 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1487}
1488
1489impl<'a> RangeExpr<'a> {}
1490
1491// RangePat
1492#[derive(Debug, Clone, Copy)]
1493pub struct RangePat<'a> {
1494 syntax: SyntaxNodeRef<'a>,
1495}
1496
1497impl<'a> AstNode<'a> for RangePat<'a> {
1498 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1499 match syntax.kind() {
1500 RANGE_PAT => Some(RangePat { syntax }),
1501 _ => None,
1502 }
1503 }
1504 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1505}
1506
1507impl<'a> RangePat<'a> {}
1508
1509// RefExpr
1510#[derive(Debug, Clone, Copy)]
1511pub struct RefExpr<'a> {
1512 syntax: SyntaxNodeRef<'a>,
1513}
1514
1515impl<'a> AstNode<'a> for RefExpr<'a> {
1516 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1517 match syntax.kind() {
1518 REF_EXPR => Some(RefExpr { syntax }),
1519 _ => None,
1520 }
1521 }
1522 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1523}
1524
1525impl<'a> RefExpr<'a> {}
1526
1527// RefPat
1528#[derive(Debug, Clone, Copy)]
1529pub struct RefPat<'a> {
1530 syntax: SyntaxNodeRef<'a>,
1531}
1532
1533impl<'a> AstNode<'a> for RefPat<'a> {
1534 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1535 match syntax.kind() {
1536 REF_PAT => Some(RefPat { syntax }),
1537 _ => None,
1538 }
1539 }
1540 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1541}
1542
1543impl<'a> RefPat<'a> {}
1544
1545// ReferenceType
1546#[derive(Debug, Clone, Copy)]
1547pub struct ReferenceType<'a> {
1548 syntax: SyntaxNodeRef<'a>,
1549}
1550
1551impl<'a> AstNode<'a> for ReferenceType<'a> {
1552 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1553 match syntax.kind() {
1554 REFERENCE_TYPE => Some(ReferenceType { syntax }),
1555 _ => None,
1556 }
1557 }
1558 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1559}
1560
1561impl<'a> ReferenceType<'a> {}
1562
1563// RetType
1564#[derive(Debug, Clone, Copy)]
1565pub struct RetType<'a> {
1566 syntax: SyntaxNodeRef<'a>,
1567}
1568
1569impl<'a> AstNode<'a> for RetType<'a> {
1570 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1571 match syntax.kind() {
1572 RET_TYPE => Some(RetType { syntax }),
1573 _ => None,
1574 }
1575 }
1576 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1577}
1578
1579impl<'a> RetType<'a> {}
1580
1581// ReturnExpr
1582#[derive(Debug, Clone, Copy)]
1583pub struct ReturnExpr<'a> {
1584 syntax: SyntaxNodeRef<'a>,
1585}
1586
1587impl<'a> AstNode<'a> for ReturnExpr<'a> {
1588 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1589 match syntax.kind() {
1590 RETURN_EXPR => Some(ReturnExpr { syntax }),
1591 _ => None,
1592 }
1593 }
1594 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1595}
1596
1597impl<'a> ReturnExpr<'a> {}
1598
1599// Root
1600#[derive(Debug, Clone, Copy)]
1601pub struct Root<'a> {
1602 syntax: SyntaxNodeRef<'a>,
1603}
1604
1605impl<'a> AstNode<'a> for Root<'a> {
1606 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1607 match syntax.kind() {
1608 ROOT => Some(Root { syntax }),
1609 _ => None,
1610 }
1611 }
1612 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1613}
1614
1615impl<'a> ast::ModuleItemOwner<'a> for Root<'a> {}
1616impl<'a> ast::FnDefOwner<'a> for Root<'a> {}
1617impl<'a> Root<'a> {
1618 pub fn modules(self) -> impl Iterator<Item = Module<'a>> + 'a {
1619 super::children(self)
1620 }
1621}
1622
1623// SelfParam
1624#[derive(Debug, Clone, Copy)]
1625pub struct SelfParam<'a> {
1626 syntax: SyntaxNodeRef<'a>,
1627}
1628
1629impl<'a> AstNode<'a> for SelfParam<'a> {
1630 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1631 match syntax.kind() {
1632 SELF_PARAM => Some(SelfParam { syntax }),
1633 _ => None,
1634 }
1635 }
1636 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1637}
1638
1639impl<'a> SelfParam<'a> {}
1640
1641// SlicePat
1642#[derive(Debug, Clone, Copy)]
1643pub struct SlicePat<'a> {
1644 syntax: SyntaxNodeRef<'a>,
1645}
1646
1647impl<'a> AstNode<'a> for SlicePat<'a> {
1648 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1649 match syntax.kind() {
1650 SLICE_PAT => Some(SlicePat { syntax }),
1651 _ => None,
1652 }
1653 }
1654 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1655}
1656
1657impl<'a> SlicePat<'a> {}
1658
1659// SliceType
1660#[derive(Debug, Clone, Copy)]
1661pub struct SliceType<'a> {
1662 syntax: SyntaxNodeRef<'a>,
1663}
1664
1665impl<'a> AstNode<'a> for SliceType<'a> {
1666 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1667 match syntax.kind() {
1668 SLICE_TYPE => Some(SliceType { syntax }),
1669 _ => None,
1670 }
1671 }
1672 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1673}
1674
1675impl<'a> SliceType<'a> {}
1676
1677// StaticDef
1678#[derive(Debug, Clone, Copy)]
1679pub struct StaticDef<'a> {
1680 syntax: SyntaxNodeRef<'a>,
1681}
1682
1683impl<'a> AstNode<'a> for StaticDef<'a> {
1684 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1685 match syntax.kind() {
1686 STATIC_DEF => Some(StaticDef { syntax }),
1687 _ => None,
1688 }
1689 }
1690 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1691}
1692
1693impl<'a> ast::NameOwner<'a> for StaticDef<'a> {}
1694impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {}
1695impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {}
1696impl<'a> StaticDef<'a> {}
1697
1698// Stmt
1699#[derive(Debug, Clone, Copy)]
1700pub enum Stmt<'a> {
1701 ExprStmt(ExprStmt<'a>),
1702 LetStmt(LetStmt<'a>),
1703}
1704
1705impl<'a> AstNode<'a> for Stmt<'a> {
1706 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1707 match syntax.kind() {
1708 EXPR_STMT => Some(Stmt::ExprStmt(ExprStmt { syntax })),
1709 LET_STMT => Some(Stmt::LetStmt(LetStmt { syntax })),
1710 _ => None,
1711 }
1712 }
1713 fn syntax(self) -> SyntaxNodeRef<'a> {
1714 match self {
1715 Stmt::ExprStmt(inner) => inner.syntax(),
1716 Stmt::LetStmt(inner) => inner.syntax(),
1717 }
1718 }
1719}
1720
1721impl<'a> Stmt<'a> {}
1722
1723// StructDef
1724#[derive(Debug, Clone, Copy)]
1725pub struct StructDef<'a> {
1726 syntax: SyntaxNodeRef<'a>,
1727}
1728
1729impl<'a> AstNode<'a> for StructDef<'a> {
1730 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1731 match syntax.kind() {
1732 STRUCT_DEF => Some(StructDef { syntax }),
1733 _ => None,
1734 }
1735 }
1736 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1737}
1738
1739impl<'a> ast::NameOwner<'a> for StructDef<'a> {}
1740impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {}
1741impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {}
1742impl<'a> StructDef<'a> {
1743 pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a {
1744 super::children(self)
1745 }
1746}
1747
1748// StructLit
1749#[derive(Debug, Clone, Copy)]
1750pub struct StructLit<'a> {
1751 syntax: SyntaxNodeRef<'a>,
1752}
1753
1754impl<'a> AstNode<'a> for StructLit<'a> {
1755 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1756 match syntax.kind() {
1757 STRUCT_LIT => Some(StructLit { syntax }),
1758 _ => None,
1759 }
1760 }
1761 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1762}
1763
1764impl<'a> StructLit<'a> {}
1765
1766// StructPat
1767#[derive(Debug, Clone, Copy)]
1768pub struct StructPat<'a> {
1769 syntax: SyntaxNodeRef<'a>,
1770}
1771
1772impl<'a> AstNode<'a> for StructPat<'a> {
1773 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1774 match syntax.kind() {
1775 STRUCT_PAT => Some(StructPat { syntax }),
1776 _ => None,
1777 }
1778 }
1779 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1780}
1781
1782impl<'a> StructPat<'a> {}
1783
1784// TokenTree
1785#[derive(Debug, Clone, Copy)]
1786pub struct TokenTree<'a> {
1787 syntax: SyntaxNodeRef<'a>,
1788}
1789
1790impl<'a> AstNode<'a> for TokenTree<'a> {
1791 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1792 match syntax.kind() {
1793 TOKEN_TREE => Some(TokenTree { syntax }),
1794 _ => None,
1795 }
1796 }
1797 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1798}
1799
1800impl<'a> TokenTree<'a> {}
1801
1802// TraitDef
1803#[derive(Debug, Clone, Copy)]
1804pub struct TraitDef<'a> {
1805 syntax: SyntaxNodeRef<'a>,
1806}
1807
1808impl<'a> AstNode<'a> for TraitDef<'a> {
1809 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1810 match syntax.kind() {
1811 TRAIT_DEF => Some(TraitDef { syntax }),
1812 _ => None,
1813 }
1814 }
1815 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1816}
1817
1818impl<'a> ast::NameOwner<'a> for TraitDef<'a> {}
1819impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {}
1820impl<'a> TraitDef<'a> {}
1821
1822// TryExpr
1823#[derive(Debug, Clone, Copy)]
1824pub struct TryExpr<'a> {
1825 syntax: SyntaxNodeRef<'a>,
1826}
1827
1828impl<'a> AstNode<'a> for TryExpr<'a> {
1829 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1830 match syntax.kind() {
1831 TRY_EXPR => Some(TryExpr { syntax }),
1832 _ => None,
1833 }
1834 }
1835 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1836}
1837
1838impl<'a> TryExpr<'a> {}
1839
1840// TupleExpr
1841#[derive(Debug, Clone, Copy)]
1842pub struct TupleExpr<'a> {
1843 syntax: SyntaxNodeRef<'a>,
1844}
1845
1846impl<'a> AstNode<'a> for TupleExpr<'a> {
1847 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1848 match syntax.kind() {
1849 TUPLE_EXPR => Some(TupleExpr { syntax }),
1850 _ => None,
1851 }
1852 }
1853 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1854}
1855
1856impl<'a> TupleExpr<'a> {}
1857
1858// TuplePat
1859#[derive(Debug, Clone, Copy)]
1860pub struct TuplePat<'a> {
1861 syntax: SyntaxNodeRef<'a>,
1862}
1863
1864impl<'a> AstNode<'a> for TuplePat<'a> {
1865 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1866 match syntax.kind() {
1867 TUPLE_PAT => Some(TuplePat { syntax }),
1868 _ => None,
1869 }
1870 }
1871 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1872}
1873
1874impl<'a> TuplePat<'a> {}
1875
1876// TupleStructPat
1877#[derive(Debug, Clone, Copy)]
1878pub struct TupleStructPat<'a> {
1879 syntax: SyntaxNodeRef<'a>,
1880}
1881
1882impl<'a> AstNode<'a> for TupleStructPat<'a> {
1883 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1884 match syntax.kind() {
1885 TUPLE_STRUCT_PAT => Some(TupleStructPat { syntax }),
1886 _ => None,
1887 }
1888 }
1889 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1890}
1891
1892impl<'a> TupleStructPat<'a> {}
1893
1894// TupleType
1895#[derive(Debug, Clone, Copy)]
1896pub struct TupleType<'a> {
1897 syntax: SyntaxNodeRef<'a>,
1898}
1899
1900impl<'a> AstNode<'a> for TupleType<'a> {
1901 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1902 match syntax.kind() {
1903 TUPLE_TYPE => Some(TupleType { syntax }),
1904 _ => None,
1905 }
1906 }
1907 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1908}
1909
1910impl<'a> TupleType<'a> {}
1911
1912// TypeDef
1913#[derive(Debug, Clone, Copy)]
1914pub struct TypeDef<'a> {
1915 syntax: SyntaxNodeRef<'a>,
1916}
1917
1918impl<'a> AstNode<'a> for TypeDef<'a> {
1919 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1920 match syntax.kind() {
1921 TYPE_DEF => Some(TypeDef { syntax }),
1922 _ => None,
1923 }
1924 }
1925 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1926}
1927
1928impl<'a> ast::NameOwner<'a> for TypeDef<'a> {}
1929impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {}
1930impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {}
1931impl<'a> TypeDef<'a> {}
1932
1933// TypeParam
1934#[derive(Debug, Clone, Copy)]
1935pub struct TypeParam<'a> {
1936 syntax: SyntaxNodeRef<'a>,
1937}
1938
1939impl<'a> AstNode<'a> for TypeParam<'a> {
1940 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1941 match syntax.kind() {
1942 TYPE_PARAM => Some(TypeParam { syntax }),
1943 _ => None,
1944 }
1945 }
1946 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1947}
1948
1949impl<'a> ast::NameOwner<'a> for TypeParam<'a> {}
1950impl<'a> TypeParam<'a> {}
1951
1952// TypeParamList
1953#[derive(Debug, Clone, Copy)]
1954pub struct TypeParamList<'a> {
1955 syntax: SyntaxNodeRef<'a>,
1956}
1957
1958impl<'a> AstNode<'a> for TypeParamList<'a> {
1959 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1960 match syntax.kind() {
1961 TYPE_PARAM_LIST => Some(TypeParamList { syntax }),
1962 _ => None,
1963 }
1964 }
1965 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1966}
1967
1968impl<'a> TypeParamList<'a> {
1969 pub fn type_params(self) -> impl Iterator<Item = TypeParam<'a>> + 'a {
1970 super::children(self)
1971 }
1972
1973 pub fn lifetime_params(self) -> impl Iterator<Item = LifetimeParam<'a>> + 'a {
1974 super::children(self)
1975 }
1976}
1977
1978// TypeRef
1979#[derive(Debug, Clone, Copy)]
1980pub enum TypeRef<'a> {
1981 ParenType(ParenType<'a>),
1982 TupleType(TupleType<'a>),
1983 NeverType(NeverType<'a>),
1984 PathType(PathType<'a>),
1985 PointerType(PointerType<'a>),
1986 ArrayType(ArrayType<'a>),
1987 SliceType(SliceType<'a>),
1988 ReferenceType(ReferenceType<'a>),
1989 PlaceholderType(PlaceholderType<'a>),
1990 FnPointerType(FnPointerType<'a>),
1991 ForType(ForType<'a>),
1992 ImplTraitType(ImplTraitType<'a>),
1993 DynTraitType(DynTraitType<'a>),
1994}
1995
1996impl<'a> AstNode<'a> for TypeRef<'a> {
1997 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1998 match syntax.kind() {
1999 PAREN_TYPE => Some(TypeRef::ParenType(ParenType { syntax })),
2000 TUPLE_TYPE => Some(TypeRef::TupleType(TupleType { syntax })),
2001 NEVER_TYPE => Some(TypeRef::NeverType(NeverType { syntax })),
2002 PATH_TYPE => Some(TypeRef::PathType(PathType { syntax })),
2003 POINTER_TYPE => Some(TypeRef::PointerType(PointerType { syntax })),
2004 ARRAY_TYPE => Some(TypeRef::ArrayType(ArrayType { syntax })),
2005 SLICE_TYPE => Some(TypeRef::SliceType(SliceType { syntax })),
2006 REFERENCE_TYPE => Some(TypeRef::ReferenceType(ReferenceType { syntax })),
2007 PLACEHOLDER_TYPE => Some(TypeRef::PlaceholderType(PlaceholderType { syntax })),
2008 FN_POINTER_TYPE => Some(TypeRef::FnPointerType(FnPointerType { syntax })),
2009 FOR_TYPE => Some(TypeRef::ForType(ForType { syntax })),
2010 IMPL_TRAIT_TYPE => Some(TypeRef::ImplTraitType(ImplTraitType { syntax })),
2011 DYN_TRAIT_TYPE => Some(TypeRef::DynTraitType(DynTraitType { syntax })),
2012 _ => None,
2013 }
2014 }
2015 fn syntax(self) -> SyntaxNodeRef<'a> {
2016 match self {
2017 TypeRef::ParenType(inner) => inner.syntax(),
2018 TypeRef::TupleType(inner) => inner.syntax(),
2019 TypeRef::NeverType(inner) => inner.syntax(),
2020 TypeRef::PathType(inner) => inner.syntax(),
2021 TypeRef::PointerType(inner) => inner.syntax(),
2022 TypeRef::ArrayType(inner) => inner.syntax(),
2023 TypeRef::SliceType(inner) => inner.syntax(),
2024 TypeRef::ReferenceType(inner) => inner.syntax(),
2025 TypeRef::PlaceholderType(inner) => inner.syntax(),
2026 TypeRef::FnPointerType(inner) => inner.syntax(),
2027 TypeRef::ForType(inner) => inner.syntax(),
2028 TypeRef::ImplTraitType(inner) => inner.syntax(),
2029 TypeRef::DynTraitType(inner) => inner.syntax(),
2030 }
2031 }
2032}
2033
2034impl<'a> TypeRef<'a> {}
2035
2036// UseItem
2037#[derive(Debug, Clone, Copy)]
2038pub struct UseItem<'a> {
2039 syntax: SyntaxNodeRef<'a>,
2040}
2041
2042impl<'a> AstNode<'a> for UseItem<'a> {
2043 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
2044 match syntax.kind() {
2045 USE_ITEM => Some(UseItem { syntax }),
2046 _ => None,
2047 }
2048 }
2049 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
2050}
2051
2052impl<'a> UseItem<'a> {pub fn use_tree(self) -> Option<UseTree<'a>> {
2053 super::child_opt(self)
2054 }
2055}
2056
2057// UseTree
2058#[derive(Debug, Clone, Copy)]
2059pub struct UseTree<'a> {
2060 syntax: SyntaxNodeRef<'a>,
2061}
2062
2063impl<'a> AstNode<'a> for UseTree<'a> {
2064 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
2065 match syntax.kind() {
2066 USE_TREE => Some(UseTree { syntax }),
2067 _ => None,
2068 }
2069 }
2070 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
2071}
2072
2073impl<'a> UseTree<'a> {pub fn path(self) -> Option<Path<'a>> {
2074 super::child_opt(self)
2075 }
2076pub fn use_tree_list(self) -> Option<UseTreeList<'a>> {
2077 super::child_opt(self)
2078 }
2079}
2080
2081// UseTreeList
2082#[derive(Debug, Clone, Copy)]
2083pub struct UseTreeList<'a> {
2084 syntax: SyntaxNodeRef<'a>,
2085}
2086
2087impl<'a> AstNode<'a> for UseTreeList<'a> {
2088 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
2089 match syntax.kind() {
2090 USE_TREE_LIST => Some(UseTreeList { syntax }),
2091 _ => None,
2092 }
2093 }
2094 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
2095}
2096
2097impl<'a> UseTreeList<'a> {
2098 pub fn use_trees(self) -> impl Iterator<Item = UseTree<'a>> + 'a {
2099 super::children(self)
2100 }
2101}
2102
2103// WhereClause
2104#[derive(Debug, Clone, Copy)]
2105pub struct WhereClause<'a> {
2106 syntax: SyntaxNodeRef<'a>,
2107}
2108
2109impl<'a> AstNode<'a> for WhereClause<'a> {
2110 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
2111 match syntax.kind() {
2112 WHERE_CLAUSE => Some(WhereClause { syntax }),
2113 _ => None,
2114 }
2115 }
2116 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
2117}
2118
2119impl<'a> WhereClause<'a> {}
2120
2121// WhileExpr
2122#[derive(Debug, Clone, Copy)]
2123pub struct WhileExpr<'a> {
2124 syntax: SyntaxNodeRef<'a>,
2125}
2126
2127impl<'a> AstNode<'a> for WhileExpr<'a> {
2128 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
2129 match syntax.kind() {
2130 WHILE_EXPR => Some(WhileExpr { syntax }),
2131 _ => None,
2132 }
2133 }
2134 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
2135}
2136
2137impl<'a> ast::LoopBodyOwner<'a> for WhileExpr<'a> {}
2138impl<'a> WhileExpr<'a> {pub fn condition(self) -> Option<Condition<'a>> {
2139 super::child_opt(self)
2140 }
2141}
2142
diff --git a/crates/ra_syntax/src/ast/generated.rs.tera b/crates/ra_syntax/src/ast/generated.rs.tera
new file mode 100644
index 000000000..a72e9b732
--- /dev/null
+++ b/crates/ra_syntax/src/ast/generated.rs.tera
@@ -0,0 +1,83 @@
1use {
2 ast,
3 SyntaxNodeRef, AstNode,
4 SyntaxKind::*,
5};
6{% for node, methods in ast %}
7// {{ node }}
8{%- if methods.enum %}
9#[derive(Debug, Clone, Copy)]
10pub enum {{ node }}<'a> {
11{%- for kind in methods.enum %}
12 {{ kind }}({{ kind }}<'a>),
13{%- endfor %}
14}
15
16impl<'a> AstNode<'a> for {{ node }}<'a> {
17 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
18 match syntax.kind() {
19{%- for kind in methods.enum %}
20 {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })),
21{%- endfor %}
22 _ => None,
23 }
24 }
25 fn syntax(self) -> SyntaxNodeRef<'a> {
26 match self {
27{%- for kind in methods.enum %}
28 {{ node }}::{{ kind }}(inner) => inner.syntax(),
29{%- endfor %}
30 }
31 }
32}
33{% else %}
34#[derive(Debug, Clone, Copy)]
35pub struct {{ node }}<'a> {
36 syntax: SyntaxNodeRef<'a>,
37}
38
39impl<'a> AstNode<'a> for {{ node }}<'a> {
40 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
41 match syntax.kind() {
42 {{ node | SCREAM }} => Some({{ node }} { syntax }),
43 _ => None,
44 }
45 }
46 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
47}
48{% endif %}
49{% if methods.traits -%}
50{%- for t in methods.traits -%}
51impl<'a> ast::{{ t }}<'a> for {{ node }}<'a> {}
52{% endfor -%}
53{%- endif -%}
54
55impl<'a> {{ node }}<'a> {
56{%- if methods.collections -%}
57{%- for m in methods.collections -%}
58{%- set method_name = m.0 -%}
59{%- set ChildName = m.1 %}
60 pub fn {{ method_name }}(self) -> impl Iterator<Item = {{ ChildName }}<'a>> + 'a {
61 super::children(self)
62 }
63{% endfor -%}
64{%- endif -%}
65
66{%- if methods.options -%}
67{%- for m in methods.options -%}
68
69{%- if m is string -%}
70{%- set method_name = m | snake -%}
71{%- set ChildName = m %}
72{%- else -%}
73{%- set method_name = m.0 -%}
74{%- set ChildName = m.1 %}
75{%- endif -%}
76
77 pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> {
78 super::child_opt(self)
79 }
80{% endfor -%}
81{%- endif -%}
82}
83{% endfor %}
diff --git a/crates/ra_syntax/src/ast/mod.rs b/crates/ra_syntax/src/ast/mod.rs
new file mode 100644
index 000000000..a6da82957
--- /dev/null
+++ b/crates/ra_syntax/src/ast/mod.rs
@@ -0,0 +1,206 @@
1mod generated;
2
3use std::marker::PhantomData;
4
5use itertools::Itertools;
6use smol_str::SmolStr;
7
8use {
9 SyntaxNodeRef, SyntaxKind::*,
10 yellow::{RefRoot, SyntaxNodeChildren},
11};
12pub use self::generated::*;
13
14pub trait AstNode<'a>: Clone + Copy + 'a {
15 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self>
16 where Self: Sized;
17 fn syntax(self) -> SyntaxNodeRef<'a>;
18}
19
20pub trait NameOwner<'a>: AstNode<'a> {
21 fn name(self) -> Option<Name<'a>> {
22 child_opt(self)
23 }
24}
25
26pub trait LoopBodyOwner<'a>: AstNode<'a> {
27 fn loop_body(self) -> Option<Block<'a>> {
28 child_opt(self)
29 }
30}
31
32pub trait ArgListOwner<'a>: AstNode<'a> {
33 fn arg_list(self) -> Option<ArgList<'a>> {
34 child_opt(self)
35 }
36}
37
38pub trait FnDefOwner<'a>: AstNode<'a> {
39 fn functions(self) -> AstChildren<'a, FnDef<'a>> {
40 children(self)
41 }
42}
43
44pub trait ModuleItemOwner<'a>: AstNode<'a> {
45 fn items(self) -> AstChildren<'a, ModuleItem<'a>> {
46 children(self)
47 }
48}
49
50pub trait TypeParamsOwner<'a>: AstNode<'a> {
51 fn type_param_list(self) -> Option<TypeParamList<'a>> {
52 child_opt(self)
53 }
54
55 fn where_clause(self) -> Option<WhereClause<'a>> {
56 child_opt(self)
57 }
58}
59
60pub trait AttrsOwner<'a>: AstNode<'a> {
61 fn attrs(self) -> AstChildren<'a, Attr<'a>> {
62 children(self)
63 }
64}
65
66impl<'a> FnDef<'a> {
67 pub fn has_atom_attr(&self, atom: &str) -> bool {
68 self.attrs()
69 .filter_map(|x| x.as_atom())
70 .any(|x| x == atom)
71 }
72}
73
74impl<'a> Attr<'a> {
75 pub fn as_atom(&self) -> Option<SmolStr> {
76 let tt = self.value()?;
77 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?;
78 if attr.kind() == IDENT {
79 Some(attr.leaf_text().unwrap())
80 } else {
81 None
82 }
83 }
84
85 pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> {
86 let tt = self.value()?;
87 let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?;
88 let args = TokenTree::cast(args)?;
89 if attr.kind() == IDENT {
90 Some((attr.leaf_text().unwrap(), args))
91 } else {
92 None
93 }
94 }
95}
96
97impl<'a> Lifetime<'a> {
98 pub fn text(&self) -> SmolStr {
99 self.syntax().leaf_text().unwrap()
100 }
101}
102
103impl<'a> Name<'a> {
104 pub fn text(&self) -> SmolStr {
105 let ident = self.syntax().first_child()
106 .unwrap();
107 ident.leaf_text().unwrap()
108 }
109}
110
111impl<'a> NameRef<'a> {
112 pub fn text(&self) -> SmolStr {
113 let ident = self.syntax().first_child()
114 .unwrap();
115 ident.leaf_text().unwrap()
116 }
117}
118
119impl<'a> ImplItem<'a> {
120 pub fn target_type(self) -> Option<TypeRef<'a>> {
121 match self.target() {
122 (Some(t), None) | (_, Some(t)) => Some(t),
123 _ => None,
124 }
125 }
126
127 pub fn target_trait(self) -> Option<TypeRef<'a>> {
128 match self.target() {
129 (Some(t), Some(_)) => Some(t),
130 _ => None,
131 }
132 }
133
134 fn target(self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) {
135 let mut types = children(self);
136 let first = types.next();
137 let second = types.next();
138 (first, second)
139 }
140}
141
142impl<'a> Module<'a> {
143 pub fn has_semi(self) -> bool {
144 match self.syntax().last_child() {
145 None => false,
146 Some(node) => node.kind() == SEMI,
147 }
148 }
149}
150
151impl<'a> LetStmt<'a> {
152 pub fn has_semi(self) -> bool {
153 match self.syntax().last_child() {
154 None => false,
155 Some(node) => node.kind() == SEMI,
156 }
157 }
158}
159
160impl<'a> IfExpr<'a> {
161 pub fn then_branch(self) -> Option<Block<'a>> {
162 self.blocks().nth(0)
163 }
164 pub fn else_branch(self) -> Option<Block<'a>> {
165 self.blocks().nth(1)
166 }
167 fn blocks(self) -> AstChildren<'a, Block<'a>> {
168 children(self)
169 }
170}
171
172fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> {
173 children(parent).next()
174}
175
176fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstChildren<'a, C> {
177 AstChildren::new(parent.syntax())
178}
179
180
181#[derive(Debug)]
182pub struct AstChildren<'a, N> {
183 inner: SyntaxNodeChildren<RefRoot<'a>>,
184 ph: PhantomData<N>,
185}
186
187impl<'a, N> AstChildren<'a, N> {
188 fn new(parent: SyntaxNodeRef<'a>) -> Self {
189 AstChildren {
190 inner: parent.children(),
191 ph: PhantomData,
192 }
193 }
194}
195
196impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> {
197 type Item = N;
198 fn next(&mut self) -> Option<N> {
199 loop {
200 match N::cast(self.inner.next()?) {
201 Some(n) => return Some(n),
202 None => (),
203 }
204 }
205 }
206}
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
new file mode 100644
index 000000000..77ae4c7db
--- /dev/null
+++ b/crates/ra_syntax/src/grammar.ron
@@ -0,0 +1,538 @@
1Grammar(
2 single_byte_tokens: [
3 [";", "SEMI"],
4 [",", "COMMA"],
5 ["(", "L_PAREN"],
6 [")", "R_PAREN"],
7 ["{", "L_CURLY"],
8 ["}", "R_CURLY"],
9 ["[", "L_BRACK"],
10 ["]", "R_BRACK"],
11 ["<", "L_ANGLE"],
12 [">", "R_ANGLE"],
13 ["@", "AT"],
14 ["#", "POUND"],
15 ["~", "TILDE"],
16 ["?", "QUESTION"],
17 ["$", "DOLLAR"],
18 ["&", "AMP"],
19 ["|", "PIPE"],
20 ["+", "PLUS"],
21 ["*", "STAR"],
22 ["/", "SLASH"],
23 ["^", "CARET"],
24 ["%", "PERCENT"],
25 ],
26 multi_byte_tokens: [
27 [".", "DOT"],
28 ["..", "DOTDOT"],
29 ["...", "DOTDOTDOT"],
30 ["..=", "DOTDOTEQ"],
31 [":", "COLON"],
32 ["::", "COLONCOLON"],
33 ["=", "EQ"],
34 ["==", "EQEQ"],
35 ["=>", "FAT_ARROW"],
36 ["!", "EXCL"],
37 ["!=", "NEQ"],
38 ["-", "MINUS"],
39 ["->", "THIN_ARROW"],
40 ["<=", "LTEQ"],
41 [">=", "GTEQ"],
42 ["+=", "PLUSEQ"],
43 ["-=", "MINUSEQ"],
44 ["|=", "PIPEEQ"],
45 ["&=", "AMPEQ"],
46 ["^=", "CARETEQ"],
47 ["/=", "SLASHEQ"],
48 ["*=", "STAREQ"],
49 ["&&", "AMPAMP"],
50 ["||", "PIPEPIPE"],
51 ["<<", "SHL"],
52 [">>", "SHR"],
53 ["<<=", "SHLEQ"],
54 [">>=", "SHREQ"],
55 ],
56 keywords: [
57 "use",
58 "fn",
59 "struct",
60 "enum",
61 "trait",
62 "impl",
63 "dyn",
64 "true",
65 "false",
66 "as",
67 "extern",
68 "crate",
69 "mod",
70 "pub",
71 "self",
72 "super",
73 "in",
74 "where",
75 "for",
76 "loop",
77 "while",
78 "continue",
79 "break",
80 "if",
81 "else",
82 "match",
83 "const",
84 "static",
85 "mut",
86 "unsafe",
87 "type",
88 "ref",
89 "let",
90 "move",
91 "return",
92 ],
93 contextual_keywords: [
94 "auto",
95 "default",
96 "union",
97 ],
98 tokens: [
99 "ERROR",
100 "IDENT",
101 "UNDERSCORE",
102 "WHITESPACE",
103 "INT_NUMBER",
104 "FLOAT_NUMBER",
105 "LIFETIME",
106 "CHAR",
107 "BYTE",
108 "STRING",
109 "RAW_STRING",
110 "BYTE_STRING",
111 "RAW_BYTE_STRING",
112 "COMMENT",
113 "DOC_COMMENT",
114 "SHEBANG",
115 ],
116 nodes: [
117 "ROOT",
118
119 "STRUCT_DEF",
120 "ENUM_DEF",
121 "FN_DEF",
122 "RET_TYPE",
123 "EXTERN_CRATE_ITEM",
124 "MODULE",
125 "USE_ITEM",
126 "STATIC_DEF",
127 "CONST_DEF",
128 "TRAIT_DEF",
129 "IMPL_ITEM",
130 "TYPE_DEF",
131 "MACRO_CALL",
132 "TOKEN_TREE",
133
134 "PAREN_TYPE",
135 "TUPLE_TYPE",
136 "NEVER_TYPE",
137 "PATH_TYPE",
138 "POINTER_TYPE",
139 "ARRAY_TYPE",
140 "SLICE_TYPE",
141 "REFERENCE_TYPE",
142 "PLACEHOLDER_TYPE",
143 "FN_POINTER_TYPE",
144 "FOR_TYPE",
145 "IMPL_TRAIT_TYPE",
146 "DYN_TRAIT_TYPE",
147
148 "REF_PAT",
149 "BIND_PAT",
150 "PLACEHOLDER_PAT",
151 "PATH_PAT",
152 "STRUCT_PAT",
153 "FIELD_PAT_LIST",
154 "TUPLE_STRUCT_PAT",
155 "TUPLE_PAT",
156 "SLICE_PAT",
157 "RANGE_PAT",
158
159 // atoms
160 "TUPLE_EXPR",
161 "ARRAY_EXPR",
162 "PAREN_EXPR",
163 "PATH_EXPR",
164 "LAMBDA_EXPR",
165 "IF_EXPR",
166 "WHILE_EXPR",
167 "CONDITION",
168 "LOOP_EXPR",
169 "FOR_EXPR",
170 "CONTINUE_EXPR",
171 "BREAK_EXPR",
172 "LABEL",
173 "BLOCK_EXPR",
174 "RETURN_EXPR",
175 "MATCH_EXPR",
176 "MATCH_ARM_LIST",
177 "MATCH_ARM",
178 "MATCH_GUARD",
179 "STRUCT_LIT",
180 "NAMED_FIELD_LIST",
181 "NAMED_FIELD",
182
183 // postfix
184 "CALL_EXPR",
185 "INDEX_EXPR",
186 "METHOD_CALL_EXPR",
187 "FIELD_EXPR",
188 "TRY_EXPR",
189 "CAST_EXPR",
190
191 // unary
192 "REF_EXPR",
193 "PREFIX_EXPR",
194
195 "RANGE_EXPR", // just weird
196 "BIN_EXPR",
197
198 "BLOCK",
199 "EXTERN_BLOCK",
200 "EXTERN_ITEM_LIST",
201 "ENUM_VARIANT",
202 "NAMED_FIELD_DEF_LIST",
203 "NAMED_FIELD_DEF",
204 "POS_FIELD_LIST",
205 "POS_FIELD",
206 "ENUM_VARIANT_LIST",
207 "ITEM_LIST",
208 "ATTR",
209 "META_ITEM", // not an item actually
210 "USE_TREE",
211 "USE_TREE_LIST",
212 "PATH",
213 "PATH_SEGMENT",
214 "LITERAL",
215 "ALIAS",
216 "VISIBILITY",
217 "WHERE_CLAUSE",
218 "WHERE_PRED",
219 "ABI",
220 "NAME",
221 "NAME_REF",
222
223 "LET_STMT",
224 "EXPR_STMT",
225
226 "TYPE_PARAM_LIST",
227 "LIFETIME_PARAM",
228 "TYPE_PARAM",
229 "TYPE_ARG_LIST",
230 "LIFETIME_ARG",
231 "TYPE_ARG",
232 "ASSOC_TYPE_ARG",
233
234 "PARAM_LIST",
235 "PARAM",
236 "SELF_PARAM",
237 "ARG_LIST",
238 ],
239 ast: {
240 "Root": (
241 traits: [ "ModuleItemOwner", "FnDefOwner" ],
242 collections: [
243 ["modules", "Module"],
244 ]
245 ),
246 "FnDef": (
247 traits: [
248 "NameOwner",
249 "TypeParamsOwner",
250 "AttrsOwner",
251 ],
252 options: [ "ParamList", ["body", "Block"], "RetType" ],
253 ),
254 "RetType": (),
255 "StructDef": (
256 traits: [
257 "NameOwner",
258 "TypeParamsOwner",
259 "AttrsOwner",
260 ],
261 collections: [
262 ["fields", "NamedFieldDef"]
263 ]
264 ),
265 "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ),
266 "EnumDef": ( traits: [
267 "NameOwner",
268 "TypeParamsOwner",
269 "AttrsOwner",
270 ] ),
271 "TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ),
272 "Module": (
273 traits: ["NameOwner", "AttrsOwner" ],
274 options: [ "ItemList" ]
275 ),
276 "ItemList": (
277 traits: [ "FnDefOwner", "ModuleItemOwner" ],
278 ),
279 "ConstDef": ( traits: [
280 "NameOwner",
281 "TypeParamsOwner",
282 "AttrsOwner",
283 ] ),
284 "StaticDef": ( traits: [
285 "NameOwner",
286 "TypeParamsOwner",
287 "AttrsOwner",
288 ] ),
289 "TypeDef": ( traits: [
290 "NameOwner",
291 "TypeParamsOwner",
292 "AttrsOwner",
293 ] ),
294 "ImplItem": (),
295
296 "ParenType": (),
297 "TupleType": (),
298 "NeverType": (),
299 "PathType": (),
300 "PointerType": (),
301 "ArrayType": (),
302 "SliceType": (),
303 "ReferenceType": (),
304 "PlaceholderType": (),
305 "FnPointerType": (),
306 "ForType": (),
307 "ImplTraitType": (),
308 "DynTraitType": (),
309
310 "TypeRef": ( enum: [
311 "ParenType",
312 "TupleType",
313 "NeverType",
314 "PathType",
315 "PointerType",
316 "ArrayType",
317 "SliceType",
318 "ReferenceType",
319 "PlaceholderType",
320 "FnPointerType",
321 "ForType",
322 "ImplTraitType",
323 "DynTraitType",
324 ]),
325
326 "NominalDef": (
327 enum: ["StructDef", "EnumDef"],
328 traits: [
329 "NameOwner",
330 "TypeParamsOwner",
331 "AttrsOwner"
332 ],
333 ),
334 "ModuleItem": (
335 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplItem",
336 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ]
337 ),
338
339 "TupleExpr": (),
340 "ArrayExpr": (),
341 "ParenExpr": (),
342 "PathExpr": (),
343 "LambdaExpr": (
344 options: [
345 "ParamList",
346 ["body", "Expr"],
347 ]
348 ),
349 "IfExpr": (
350 options: [ "Condition" ]
351 ),
352 "LoopExpr": (
353 traits: ["LoopBodyOwner"],
354 ),
355 "ForExpr": (
356 traits: ["LoopBodyOwner"],
357 options: [
358 "Pat",
359 ["iterable", "Expr"],
360 ]
361 ),
362 "WhileExpr": (
363 traits: ["LoopBodyOwner"],
364 options: [ "Condition" ]
365 ),
366 "ContinueExpr": (),
367 "BreakExpr": (),
368 "Label": (),
369 "BlockExpr": (
370 options: [ "Block" ]
371 ),
372 "ReturnExpr": (),
373 "MatchExpr": (
374 options: [ "Expr", "MatchArmList" ],
375 ),
376 "MatchArmList": (
377 collections: [ ["arms", "MatchArm"] ],
378 ),
379 "MatchArm": (
380 options: [
381 [ "guard", "MatchGuard" ],
382 "Expr",
383 ],
384 collections: [ [ "pats", "Pat" ] ]
385 ),
386 "MatchGuard": (),
387 "StructLit": (),
388 "NamedFieldList": (),
389 "NamedField": (),
390 "CallExpr": (
391 traits: ["ArgListOwner"],
392 options: [ "Expr" ],
393 ),
394 "MethodCallExpr": (
395 traits: ["ArgListOwner"],
396 options: [ "Expr" ],
397 ),
398 "IndexExpr": (),
399 "FieldExpr": (),
400 "TryExpr": (),
401 "CastExpr": (),
402 "RefExpr": (),
403 "PrefixExpr": (),
404 "RangeExpr": (),
405 "BinExpr": (),
406 "Literal": (),
407
408 "Expr": (
409 enum: [
410 "TupleExpr",
411 "ArrayExpr",
412 "ParenExpr",
413 "PathExpr",
414 "LambdaExpr",
415 "IfExpr",
416 "LoopExpr",
417 "ForExpr",
418 "WhileExpr",
419 "ContinueExpr",
420 "BreakExpr",
421 "Label",
422 "BlockExpr",
423 "ReturnExpr",
424 "MatchExpr",
425 "MatchArmList",
426 "MatchArm",
427 "MatchGuard",
428 "StructLit",
429 "NamedFieldList",
430 "NamedField",
431 "CallExpr",
432 "IndexExpr",
433 "MethodCallExpr",
434 "FieldExpr",
435 "TryExpr",
436 "CastExpr",
437 "RefExpr",
438 "PrefixExpr",
439 "RangeExpr",
440 "BinExpr",
441 "Literal",
442 ],
443 ),
444
445 "RefPat": (),
446 "BindPat": ( traits: ["NameOwner"] ),
447 "PlaceholderPat": (),
448 "PathPat": (),
449 "StructPat": (),
450 "FieldPatList": (),
451 "TupleStructPat": (),
452 "TuplePat": (),
453 "SlicePat": (),
454 "RangePat": (),
455
456 "Pat": (
457 enum: [
458 "RefPat",
459 "BindPat",
460 "PlaceholderPat",
461 "PathPat",
462 "StructPat",
463 "FieldPatList",
464 "TupleStructPat",
465 "TuplePat",
466 "SlicePat",
467 "RangePat",
468 ],
469 ),
470
471 "Name": (),
472 "NameRef": (),
473 "Attr": ( options: [ ["value", "TokenTree"] ] ),
474 "TokenTree": (),
475 "TypeParamList": (
476 collections: [
477 ["type_params", "TypeParam" ],
478 ["lifetime_params", "LifetimeParam" ],
479 ]
480 ),
481 "TypeParam": ( traits: ["NameOwner"] ),
482 "LifetimeParam": ( options: [ "Lifetime" ] ),
483 "Lifetime": (),
484 "WhereClause": (),
485 "ExprStmt": (
486 options: [ ["expr", "Expr"] ]
487 ),
488 "LetStmt": ( options: [
489 ["pat", "Pat"],
490 ["initializer", "Expr"],
491 ]),
492 "Condition": (
493 options: [ "Pat", "Expr" ]
494 ),
495 "Stmt": (
496 enum: ["ExprStmt", "LetStmt"],
497 ),
498 "Block": (
499 options: [ "Expr" ],
500 collections: [
501 ["statements", "Stmt"],
502 ]
503 ),
504 "ParamList": (
505 options: [ "SelfParam" ],
506 collections: [
507 ["params", "Param"]
508 ]
509 ),
510 "SelfParam": (),
511 "Param": (
512 options: [ "Pat" ],
513 ),
514 "UseItem": (
515 options: [ "UseTree" ]
516 ),
517 "UseTree": (
518 options: [ "Path", "UseTreeList" ]
519 ),
520 "UseTreeList": (
521 collections: [["use_trees", "UseTree"]]
522 ),
523 "ExternCrateItem": (),
524 "ArgList": (
525 collections: [
526 ["args", "Expr"]
527 ]
528 ),
529 "Path": (
530 options: [
531 ["segment", "PathSegment"]
532 ]
533 ),
534 "PathSegment": (
535 options: [ "NameRef" ]
536 ),
537 },
538)
diff --git a/crates/ra_syntax/src/grammar/attributes.rs b/crates/ra_syntax/src/grammar/attributes.rs
new file mode 100644
index 000000000..cd30e8a45
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/attributes.rs
@@ -0,0 +1,31 @@
1use super::*;
2
3pub(super) fn inner_attributes(p: &mut Parser) {
4 while p.current() == POUND && p.nth(1) == EXCL {
5 attribute(p, true)
6 }
7}
8
9pub(super) fn outer_attributes(p: &mut Parser) {
10 while p.at(POUND) {
11 attribute(p, false)
12 }
13}
14
15fn attribute(p: &mut Parser, inner: bool) {
16 let attr = p.start();
17 assert!(p.at(POUND));
18 p.bump();
19
20 if inner {
21 assert!(p.at(EXCL));
22 p.bump();
23 }
24
25 if p.at(L_BRACK) {
26 items::token_tree(p);
27 } else {
28 p.error("expected `[`");
29 }
30 attr.complete(p, ATTR);
31}
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs
new file mode 100644
index 000000000..f01df56bc
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/expressions/atom.rs
@@ -0,0 +1,400 @@
1use super::*;
2
3// test expr_literals
4// fn foo() {
5// let _ = true;
6// let _ = false;
7// let _ = 1;
8// let _ = 2.0;
9// let _ = b'a';
10// let _ = 'b';
11// let _ = "c";
12// let _ = r"d";
13// let _ = b"e";
14// let _ = br"f";
15// }
16pub(crate) const LITERAL_FIRST: TokenSet =
17 token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR,
18 STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING];
19
20pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
21 if !p.at_ts(LITERAL_FIRST) {
22 return None;
23 }
24 let m = p.start();
25 p.bump();
26 Some(m.complete(p, LITERAL))
27}
28
29pub(super) const ATOM_EXPR_FIRST: TokenSet =
30 token_set_union![
31 LITERAL_FIRST,
32 token_set![L_CURLY, L_PAREN, L_BRACK, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW,
33 RETURN_KW, IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ],
34 ];
35
36const EXPR_RECOVERY_SET: TokenSet =
37 token_set![LET_KW];
38
39pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
40 match literal(p) {
41 Some(m) => return Some(m),
42 None => (),
43 }
44 if paths::is_path_start(p) || p.at(L_ANGLE) {
45 return Some(path_expr(p, r));
46 }
47 let la = p.nth(1);
48 let done = match p.current() {
49 L_PAREN => tuple_expr(p),
50 L_BRACK => array_expr(p),
51 PIPE => lambda_expr(p),
52 MOVE_KW if la == PIPE => lambda_expr(p),
53 IF_KW => if_expr(p),
54
55 LOOP_KW => loop_expr(p, None),
56 FOR_KW => for_expr(p, None),
57 WHILE_KW => while_expr(p, None),
58 LIFETIME if la == COLON => {
59 let m = p.start();
60 label(p);
61 match p.current() {
62 LOOP_KW => loop_expr(p, Some(m)),
63 FOR_KW => for_expr(p, Some(m)),
64 WHILE_KW => while_expr(p, Some(m)),
65 L_CURLY => block_expr(p, Some(m)),
66 _ => {
67 // test misplaced_label_err
68 // fn main() {
69 // 'loop: impl
70 // }
71 p.error("expected a loop");
72 m.complete(p, ERROR);
73 return None;
74 }
75 }
76 }
77
78 MATCH_KW => match_expr(p),
79 UNSAFE_KW if la == L_CURLY => {
80 let m = p.start();
81 p.bump();
82 block_expr(p, Some(m))
83 },
84 L_CURLY => block_expr(p, None),
85 RETURN_KW => return_expr(p),
86 CONTINUE_KW => continue_expr(p),
87 BREAK_KW => break_expr(p),
88 _ => {
89 p.err_recover("expected expression", EXPR_RECOVERY_SET);
90 return None;
91 }
92 };
93 Some(done)
94}
95
96// test tuple_expr
97// fn foo() {
98// ();
99// (1);
100// (1,);
101// }
102fn tuple_expr(p: &mut Parser) -> CompletedMarker {
103 assert!(p.at(L_PAREN));
104 let m = p.start();
105 p.expect(L_PAREN);
106
107 let mut saw_comma = false;
108 let mut saw_expr = false;
109 while !p.at(EOF) && !p.at(R_PAREN) {
110 saw_expr = true;
111 if !p.at_ts(EXPR_FIRST) {
112 p.error("expected expression");
113 break;
114 }
115 expr(p);
116 if !p.at(R_PAREN) {
117 saw_comma = true;
118 p.expect(COMMA);
119 }
120 }
121 p.expect(R_PAREN);
122 m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
123}
124
125// test array_expr
126// fn foo() {
127// [];
128// [1];
129// [1, 2,];
130// [1; 2];
131// }
132fn array_expr(p: &mut Parser) -> CompletedMarker {
133 assert!(p.at(L_BRACK));
134 let m = p.start();
135 p.bump();
136 if p.eat(R_BRACK) {
137 return m.complete(p, ARRAY_EXPR);
138 }
139 expr(p);
140 if p.eat(SEMI) {
141 expr(p);
142 p.expect(R_BRACK);
143 return m.complete(p, ARRAY_EXPR);
144 }
145 while !p.at(EOF) && !p.at(R_BRACK) {
146 p.expect(COMMA);
147 if p.at(R_BRACK) {
148 break;
149 }
150 if !p.at_ts(EXPR_FIRST) {
151 p.error("expected expression");
152 break;
153 }
154 expr(p);
155 }
156 p.expect(R_BRACK);
157 m.complete(p, ARRAY_EXPR)
158}
159
160// test lambda_expr
161// fn foo() {
162// || ();
163// || -> i32 { 92 };
164// |x| x;
165// move |x: i32,| x;
166// }
167fn lambda_expr(p: &mut Parser) -> CompletedMarker {
168 assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE));
169 let m = p.start();
170 p.eat(MOVE_KW);
171 params::param_list_opt_types(p);
172 if opt_fn_ret_type(p) {
173 if !p.at(L_CURLY) {
174 p.error("expected `{`");
175 }
176 }
177 expr(p);
178 m.complete(p, LAMBDA_EXPR)
179}
180
181// test if_expr
182// fn foo() {
183// if true {};
184// if true {} else {};
185// if true {} else if false {} else {};
186// if S {};
187// }
188fn if_expr(p: &mut Parser) -> CompletedMarker {
189 assert!(p.at(IF_KW));
190 let m = p.start();
191 p.bump();
192 cond(p);
193 block(p);
194 if p.at(ELSE_KW) {
195 p.bump();
196 if p.at(IF_KW) {
197 if_expr(p);
198 } else {
199 block(p);
200 }
201 }
202 m.complete(p, IF_EXPR)
203}
204
205// test label
206// fn foo() {
207// 'a: loop {}
208// 'b: while true {}
209// 'c: for x in () {}
210// }
211fn label(p: &mut Parser) {
212 assert!(p.at(LIFETIME) && p.nth(1) == COLON);
213 let m = p.start();
214 p.bump();
215 p.bump();
216 m.complete(p, LABEL);
217}
218
219// test loop_expr
220// fn foo() {
221// loop {};
222// }
223fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
224 assert!(p.at(LOOP_KW));
225 let m = m.unwrap_or_else(|| p.start());
226 p.bump();
227 block(p);
228 m.complete(p, LOOP_EXPR)
229}
230
231// test while_expr
232// fn foo() {
233// while true {};
234// while let Some(x) = it.next() {};
235// }
236fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
237 assert!(p.at(WHILE_KW));
238 let m = m.unwrap_or_else(|| p.start());
239 p.bump();
240 cond(p);
241 block(p);
242 m.complete(p, WHILE_EXPR)
243}
244
245// test for_expr
246// fn foo() {
247// for x in [] {};
248// }
249fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
250 assert!(p.at(FOR_KW));
251 let m = m.unwrap_or_else(|| p.start());
252 p.bump();
253 patterns::pattern(p);
254 p.expect(IN_KW);
255 expr_no_struct(p);
256 block(p);
257 m.complete(p, FOR_EXPR)
258}
259
260// test cond
261// fn foo() { if let Some(_) = None {} }
262fn cond(p: &mut Parser) {
263 let m = p.start();
264 if p.eat(LET_KW) {
265 patterns::pattern(p);
266 p.expect(EQ);
267 }
268 expr_no_struct(p);
269 m.complete(p, CONDITION);
270}
271
272// test match_expr
273// fn foo() {
274// match () { };
275// match S {};
276// }
277fn match_expr(p: &mut Parser) -> CompletedMarker {
278 assert!(p.at(MATCH_KW));
279 let m = p.start();
280 p.bump();
281 expr_no_struct(p);
282 if p.at(L_CURLY) {
283 match_arm_list(p);
284 } else {
285 p.error("expected `{`")
286 }
287 m.complete(p, MATCH_EXPR)
288}
289
290pub(crate) fn match_arm_list(p: &mut Parser) {
291 assert!(p.at(L_CURLY));
292 let m = p.start();
293 p.eat(L_CURLY);
294 while !p.at(EOF) && !p.at(R_CURLY) {
295 if p.at(L_CURLY) {
296 error_block(p, "expected match arm");
297 continue;
298 }
299 // test match_arms_commas
300 // fn foo() {
301 // match () {
302 // _ => (),
303 // _ => {}
304 // _ => ()
305 // }
306 // }
307 if match_arm(p).is_block() {
308 p.eat(COMMA);
309 } else if !p.at(R_CURLY) {
310 p.expect(COMMA);
311 }
312 }
313 p.expect(R_CURLY);
314 m.complete(p, MATCH_ARM_LIST);
315}
316
317// test match_arm
318// fn foo() {
319// match () {
320// _ => (),
321// X | Y if Z => (),
322// };
323// }
324fn match_arm(p: &mut Parser) -> BlockLike {
325 let m = p.start();
326 patterns::pattern_r(p, TokenSet::EMPTY);
327 while p.eat(PIPE) {
328 patterns::pattern(p);
329 }
330 if p.eat(IF_KW) {
331 expr_no_struct(p);
332 }
333 p.expect(FAT_ARROW);
334 let ret = expr_stmt(p);
335 m.complete(p, MATCH_ARM);
336 ret
337}
338
339// test block_expr
340// fn foo() {
341// {};
342// unsafe {};
343// 'label: {};
344// }
345fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
346 assert!(p.at(L_CURLY));
347 let m = m.unwrap_or_else(|| p.start());
348 block(p);
349 m.complete(p, BLOCK_EXPR)
350}
351
352// test return_expr
353// fn foo() {
354// return;
355// return 92;
356// }
357fn return_expr(p: &mut Parser) -> CompletedMarker {
358 assert!(p.at(RETURN_KW));
359 let m = p.start();
360 p.bump();
361 if p.at_ts(EXPR_FIRST) {
362 expr(p);
363 }
364 m.complete(p, RETURN_EXPR)
365}
366
367// test continue_expr
368// fn foo() {
369// loop {
370// continue;
371// continue 'l;
372// }
373// }
374fn continue_expr(p: &mut Parser) -> CompletedMarker {
375 assert!(p.at(CONTINUE_KW));
376 let m = p.start();
377 p.bump();
378 p.eat(LIFETIME);
379 m.complete(p, CONTINUE_EXPR)
380}
381
382// test break_expr
383// fn foo() {
384// loop {
385// break;
386// break 'l;
387// break 92;
388// break 'l 92;
389// }
390// }
391fn break_expr(p: &mut Parser) -> CompletedMarker {
392 assert!(p.at(BREAK_KW));
393 let m = p.start();
394 p.bump();
395 p.eat(LIFETIME);
396 if p.at_ts(EXPR_FIRST) {
397 expr(p);
398 }
399 m.complete(p, BREAK_EXPR)
400}
diff --git a/crates/ra_syntax/src/grammar/expressions/mod.rs b/crates/ra_syntax/src/grammar/expressions/mod.rs
new file mode 100644
index 000000000..20e0fa328
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/expressions/mod.rs
@@ -0,0 +1,450 @@
1mod atom;
2
3use super::*;
4pub(super) use self::atom::{literal, LITERAL_FIRST};
5pub(crate) use self::atom::match_arm_list;
6
7const EXPR_FIRST: TokenSet = LHS_FIRST;
8
9pub(super) fn expr(p: &mut Parser) -> BlockLike {
10 let r = Restrictions { forbid_structs: false, prefer_stmt: false };
11 expr_bp(p, r, 1)
12}
13
14pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike {
15 let r = Restrictions { forbid_structs: false, prefer_stmt: true };
16 expr_bp(p, r, 1)
17}
18
19fn expr_no_struct(p: &mut Parser) {
20 let r = Restrictions { forbid_structs: true, prefer_stmt: false };
21 expr_bp(p, r, 1);
22}
23
24// test block
25// fn a() {}
26// fn b() { let _ = 1; }
27// fn c() { 1; 2; }
28// fn d() { 1; 2 }
29pub(crate) fn block(p: &mut Parser) {
30 if !p.at(L_CURLY) {
31 p.error("expected a block");
32 return;
33 }
34 let m = p.start();
35 p.bump();
36 while !p.at(EOF) && !p.at(R_CURLY) {
37 match p.current() {
38 LET_KW => let_stmt(p),
39 _ => {
40 // test block_items
41 // fn a() { fn b() {} }
42 let m = p.start();
43 match items::maybe_item(p, items::ItemFlavor::Mod) {
44 items::MaybeItem::Item(kind) => {
45 m.complete(p, kind);
46 }
47 items::MaybeItem::Modifiers => {
48 m.abandon(p);
49 p.error("expected an item");
50 }
51 // test pub_expr
52 // fn foo() { pub 92; } //FIXME
53 items::MaybeItem::None => {
54 let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block;
55 if p.at(R_CURLY) {
56 m.abandon(p);
57 } else {
58 if is_blocklike {
59 p.eat(SEMI);
60 } else {
61 p.expect(SEMI);
62 }
63 m.complete(p, EXPR_STMT);
64 }
65 }
66 }
67 }
68 }
69 }
70 p.expect(R_CURLY);
71 m.complete(p, BLOCK);
72
73 // test let_stmt;
74 // fn foo() {
75 // let a;
76 // let b: i32;
77 // let c = 92;
78 // let d: i32 = 92;
79 // }
80 fn let_stmt(p: &mut Parser) {
81 assert!(p.at(LET_KW));
82 let m = p.start();
83 p.bump();
84 patterns::pattern(p);
85 if p.at(COLON) {
86 types::ascription(p);
87 }
88 if p.eat(EQ) {
89 expressions::expr(p);
90 }
91 p.expect(SEMI);
92 m.complete(p, LET_STMT);
93 }
94}
95
96#[derive(Clone, Copy)]
97struct Restrictions {
98 forbid_structs: bool,
99 prefer_stmt: bool,
100}
101
102enum Op {
103 Simple,
104 Composite(SyntaxKind, u8),
105}
106
107fn current_op(p: &Parser) -> (u8, Op) {
108 if let Some(t) = p.next3() {
109 match t {
110 (L_ANGLE, L_ANGLE, EQ) =>
111 return (1, Op::Composite(SHLEQ, 3)),
112 (R_ANGLE, R_ANGLE, EQ) =>
113 return (1, Op::Composite(SHREQ, 3)),
114 _ => (),
115 }
116 }
117
118 if let Some(t) = p.next2() {
119 match t {
120 (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)),
121 (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)),
122 (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)),
123 (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)),
124 (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)),
125 (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)),
126 (CARET, EQ) => return (1, Op::Composite(CARETEQ, 2)),
127 (PIPE, PIPE) => return (3, Op::Composite(PIPEPIPE, 2)),
128 (AMP, AMP) => return (4, Op::Composite(AMPAMP, 2)),
129 (L_ANGLE, EQ) => return (5, Op::Composite(LTEQ, 2)),
130 (R_ANGLE, EQ) => return (5, Op::Composite(GTEQ, 2)),
131 (L_ANGLE, L_ANGLE) => return (9, Op::Composite(SHL, 2)),
132 (R_ANGLE, R_ANGLE) => return (9, Op::Composite(SHR, 2)),
133 _ => (),
134 }
135 }
136
137 let bp = match p.current() {
138 EQ => 1,
139 DOTDOT => 2,
140 EQEQ | NEQ | L_ANGLE | R_ANGLE => 5,
141 PIPE => 6,
142 CARET => 7,
143 AMP => 8,
144 MINUS | PLUS => 10,
145 STAR | SLASH | PERCENT => 11,
146 _ => 0,
147 };
148 (bp, Op::Simple)
149}
150
151// Parses expression with binding power of at least bp.
152fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike {
153 let mut lhs = match lhs(p, r) {
154 Some(lhs) => {
155 // test stmt_bin_expr_ambiguity
156 // fn foo() {
157 // let _ = {1} & 2;
158 // {1} &2;
159 // }
160 if r.prefer_stmt && is_block(lhs.kind()) {
161 return BlockLike::Block;
162 }
163 lhs
164 }
165 None => return BlockLike::NotBlock,
166 };
167
168 loop {
169 let is_range = p.current() == DOTDOT;
170 let (op_bp, op) = current_op(p);
171 if op_bp < bp {
172 break;
173 }
174 let m = lhs.precede(p);
175 match op {
176 Op::Simple => p.bump(),
177 Op::Composite(kind, n) => {
178 p.bump_compound(kind, n);
179 }
180 }
181 expr_bp(p, r, op_bp + 1);
182 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
183 }
184 BlockLike::NotBlock
185}
186
187// test no_semi_after_block
188// fn foo() {
189// if true {}
190// loop {}
191// match () {}
192// while true {}
193// for _ in () {}
194// {}
195// {}
196// }
197fn is_block(kind: SyntaxKind) -> bool {
198 match kind {
199 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true,
200 _ => false,
201 }
202}
203
204const LHS_FIRST: TokenSet =
205 token_set_union![
206 token_set![AMP, STAR, EXCL, DOTDOT, MINUS],
207 atom::ATOM_EXPR_FIRST,
208 ];
209
210fn lhs(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
211 let m;
212 let kind = match p.current() {
213 // test ref_expr
214 // fn foo() {
215 // let _ = &1;
216 // let _ = &mut &f();
217 // }
218 AMP => {
219 m = p.start();
220 p.bump();
221 p.eat(MUT_KW);
222 REF_EXPR
223 }
224 // test unary_expr
225 // fn foo() {
226 // **&1;
227 // !!true;
228 // --1;
229 // }
230 STAR | EXCL | MINUS => {
231 m = p.start();
232 p.bump();
233 PREFIX_EXPR
234 }
235 // test full_range_expr
236 // fn foo() { xs[..]; }
237 DOTDOT => {
238 m = p.start();
239 p.bump();
240 if p.at_ts(EXPR_FIRST) {
241 expr_bp(p, r, 2);
242 }
243 return Some(m.complete(p, RANGE_EXPR));
244 }
245 _ => {
246 let lhs = atom::atom_expr(p, r)?;
247 return Some(postfix_expr(p, r, lhs));
248 }
249 };
250 expr_bp(p, r, 255);
251 Some(m.complete(p, kind))
252}
253
254fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker {
255 let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind());
256 loop {
257 lhs = match p.current() {
258 // test stmt_postfix_expr_ambiguity
259 // fn foo() {
260 // match () {
261 // _ => {}
262 // () => {}
263 // [] => {}
264 // }
265 // }
266 L_PAREN if allow_calls => call_expr(p, lhs),
267 L_BRACK if allow_calls => index_expr(p, lhs),
268 DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON {
269 method_call_expr(p, lhs)
270 } else {
271 field_expr(p, lhs)
272 },
273 DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs),
274 // test postfix_range
275 // fn foo() { let x = 1..; }
276 DOTDOT if !EXPR_FIRST.contains(p.nth(1)) => {
277 let m = lhs.precede(p);
278 p.bump();
279 m.complete(p, RANGE_EXPR)
280 }
281 QUESTION => try_expr(p, lhs),
282 AS_KW => cast_expr(p, lhs),
283 _ => break,
284 };
285 allow_calls = true
286 }
287 lhs
288}
289
290// test call_expr
291// fn foo() {
292// let _ = f();
293// let _ = f()(1)(1, 2,);
294// }
295fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
296 assert!(p.at(L_PAREN));
297 let m = lhs.precede(p);
298 arg_list(p);
299 m.complete(p, CALL_EXPR)
300}
301
302// test index_expr
303// fn foo() {
304// x[1][2];
305// }
306fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
307 assert!(p.at(L_BRACK));
308 let m = lhs.precede(p);
309 p.bump();
310 expr(p);
311 p.expect(R_BRACK);
312 m.complete(p, INDEX_EXPR)
313}
314
315// test method_call_expr
316// fn foo() {
317// x.foo();
318// y.bar::<T>(1, 2,);
319// }
320fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
321 assert!(
322 p.at(DOT) && p.nth(1) == IDENT
323 && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON)
324 );
325 let m = lhs.precede(p);
326 p.bump();
327 name_ref(p);
328 type_args::opt_type_arg_list(p, true);
329 if p.at(L_PAREN) {
330 arg_list(p);
331 }
332 m.complete(p, METHOD_CALL_EXPR)
333}
334
335// test field_expr
336// fn foo() {
337// x.foo;
338// x.0.bar;
339// }
340fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
341 assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER));
342 let m = lhs.precede(p);
343 p.bump();
344 if p.at(IDENT) {
345 name_ref(p)
346 } else {
347 p.bump()
348 }
349 m.complete(p, FIELD_EXPR)
350}
351
352// test try_expr
353// fn foo() {
354// x?;
355// }
356fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
357 assert!(p.at(QUESTION));
358 let m = lhs.precede(p);
359 p.bump();
360 m.complete(p, TRY_EXPR)
361}
362
363// test cast_expr
364// fn foo() {
365// 82 as i32;
366// }
367fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
368 assert!(p.at(AS_KW));
369 let m = lhs.precede(p);
370 p.bump();
371 types::type_(p);
372 m.complete(p, CAST_EXPR)
373}
374
375fn arg_list(p: &mut Parser) {
376 assert!(p.at(L_PAREN));
377 let m = p.start();
378 p.bump();
379 while !p.at(R_PAREN) && !p.at(EOF) {
380 if !p.at_ts(EXPR_FIRST) {
381 p.error("expected expression");
382 break;
383 }
384 expr(p);
385 if !p.at(R_PAREN) && !p.expect(COMMA) {
386 break;
387 }
388 }
389 p.eat(R_PAREN);
390 m.complete(p, ARG_LIST);
391}
392
393// test path_expr
394// fn foo() {
395// let _ = a;
396// let _ = a::b;
397// let _ = ::a::<b>;
398// let _ = format!();
399// }
400fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
401 assert!(paths::is_path_start(p) || p.at(L_ANGLE));
402 let m = p.start();
403 paths::expr_path(p);
404 match p.current() {
405 L_CURLY if !r.forbid_structs => {
406 named_field_list(p);
407 m.complete(p, STRUCT_LIT)
408 }
409 EXCL => {
410 items::macro_call_after_excl(p);
411 m.complete(p, MACRO_CALL)
412 }
413 _ => m.complete(p, PATH_EXPR)
414 }
415}
416
417// test struct_lit
418// fn foo() {
419// S {};
420// S { x, y: 32, };
421// S { x, y: 32, ..Default::default() };
422// }
423pub(crate) fn named_field_list(p: &mut Parser) {
424 assert!(p.at(L_CURLY));
425 let m = p.start();
426 p.bump();
427 while !p.at(EOF) && !p.at(R_CURLY) {
428 match p.current() {
429 IDENT => {
430 let m = p.start();
431 name_ref(p);
432 if p.eat(COLON) {
433 expr(p);
434 }
435 m.complete(p, NAMED_FIELD);
436 }
437 DOTDOT => {
438 p.bump();
439 expr(p);
440 }
441 L_CURLY => error_block(p, "expected a field"),
442 _ => p.err_and_bump("expected identifier"),
443 }
444 if !p.at(R_CURLY) {
445 p.expect(COMMA);
446 }
447 }
448 p.expect(R_CURLY);
449 m.complete(p, NAMED_FIELD_LIST);
450}
diff --git a/crates/ra_syntax/src/grammar/items/consts.rs b/crates/ra_syntax/src/grammar/items/consts.rs
new file mode 100644
index 000000000..5a5852f83
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/items/consts.rs
@@ -0,0 +1,21 @@
1use super::*;
2
3pub(super) fn static_def(p: &mut Parser) {
4 const_or_static(p, STATIC_KW)
5}
6
7pub(super) fn const_def(p: &mut Parser) {
8 const_or_static(p, CONST_KW)
9}
10
11fn const_or_static(p: &mut Parser, kw: SyntaxKind) {
12 assert!(p.at(kw));
13 p.bump();
14 p.eat(MUT_KW); // TODO: validator to forbid const mut
15 name(p);
16 types::ascription(p);
17 if p.eat(EQ) {
18 expressions::expr(p);
19 }
20 p.expect(SEMI);
21}
diff --git a/crates/ra_syntax/src/grammar/items/mod.rs b/crates/ra_syntax/src/grammar/items/mod.rs
new file mode 100644
index 000000000..2567313ab
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/items/mod.rs
@@ -0,0 +1,393 @@
1
2mod consts;
3mod nominal;
4mod traits;
5mod use_item;
6
7use super::*;
8pub(crate) use self::{
9 expressions::{named_field_list, match_arm_list},
10 nominal::{enum_variant_list, named_field_def_list},
11 traits::{trait_item_list, impl_item_list},
12 use_item::use_tree_list,
13};
14
15// test mod_contents
16// fn foo() {}
17// macro_rules! foo {}
18// foo::bar!();
19// super::baz! {}
20// struct S;
21pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
22 attributes::inner_attributes(p);
23 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
24 item_or_macro(p, stop_on_r_curly, ItemFlavor::Mod)
25 }
26}
27
28pub(super) enum ItemFlavor {
29 Mod, Trait
30}
31
32const ITEM_RECOVERY_SET: TokenSet =
33 token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW,
34 MOD_KW, PUB_KW, CRATE_KW];
35
36pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) {
37 let m = p.start();
38 match maybe_item(p, flavor) {
39 MaybeItem::Item(kind) => {
40 m.complete(p, kind);
41 }
42 MaybeItem::None => {
43 if paths::is_path_start(p) {
44 match macro_call(p) {
45 BlockLike::Block => (),
46 BlockLike::NotBlock => {
47 p.expect(SEMI);
48 }
49 }
50 m.complete(p, MACRO_CALL);
51 } else {
52 m.abandon(p);
53 if p.at(L_CURLY) {
54 error_block(p, "expected an item");
55 } else if p.at(R_CURLY) && !stop_on_r_curly {
56 let e = p.start();
57 p.error("unmatched `}`");
58 p.bump();
59 e.complete(p, ERROR);
60 } else if !p.at(EOF) && !p.at(R_CURLY) {
61 p.err_and_bump("expected an item");
62 } else {
63 p.error("expected an item");
64 }
65 }
66 }
67 MaybeItem::Modifiers => {
68 p.error("expected fn, trait or impl");
69 m.complete(p, ERROR);
70 }
71 }
72}
73
74pub(super) enum MaybeItem {
75 None,
76 Item(SyntaxKind),
77 Modifiers,
78}
79
80pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem {
81 attributes::outer_attributes(p);
82 opt_visibility(p);
83 if let Some(kind) = items_without_modifiers(p) {
84 return MaybeItem::Item(kind);
85 }
86
87 let mut has_mods = false;
88 // modifiers
89 has_mods |= p.eat(CONST_KW);
90
91 // test unsafe_block_in_mod
92 // fn foo(){} unsafe { } fn bar(){}
93 if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY {
94 p.eat(UNSAFE_KW);
95 has_mods = true;
96 }
97 if p.at(EXTERN_KW) {
98 has_mods = true;
99 abi(p);
100 }
101 if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW {
102 p.bump_remap(AUTO_KW);
103 has_mods = true;
104 }
105 if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW {
106 p.bump_remap(DEFAULT_KW);
107 has_mods = true;
108 }
109
110 // items
111 let kind = match p.current() {
112 // test extern_fn
113 // extern fn foo() {}
114
115 // test const_fn
116 // const fn foo() {}
117
118 // test const_unsafe_fn
119 // const unsafe fn foo() {}
120
121 // test unsafe_extern_fn
122 // unsafe extern "C" fn foo() {}
123
124 // test unsafe_fn
125 // unsafe fn foo() {}
126 FN_KW => {
127 fn_def(p, flavor);
128 FN_DEF
129 }
130
131 // test unsafe_trait
132 // unsafe trait T {}
133
134 // test auto_trait
135 // auto trait T {}
136
137 // test unsafe_auto_trait
138 // unsafe auto trait T {}
139 TRAIT_KW => {
140 traits::trait_def(p);
141 TRAIT_DEF
142 }
143
144 // test unsafe_impl
145 // unsafe impl Foo {}
146
147 // test default_impl
148 // default impl Foo {}
149
150 // test unsafe_default_impl
151 // unsafe default impl Foo {}
152 IMPL_KW => {
153 traits::impl_item(p);
154 IMPL_ITEM
155 }
156 _ => return if has_mods {
157 MaybeItem::Modifiers
158 } else {
159 MaybeItem::None
160 }
161 };
162
163 MaybeItem::Item(kind)
164}
165
166fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> {
167 let la = p.nth(1);
168 let kind = match p.current() {
169 // test extern_crate
170 // extern crate foo;
171 EXTERN_KW if la == CRATE_KW => {
172 extern_crate_item(p);
173 EXTERN_CRATE_ITEM
174 }
175 TYPE_KW => {
176 type_def(p);
177 TYPE_DEF
178 }
179 MOD_KW => {
180 mod_item(p);
181 MODULE
182 }
183 STRUCT_KW => {
184 // test struct_items
185 // struct Foo;
186 // struct Foo {}
187 // struct Foo();
188 // struct Foo(String, usize);
189 // struct Foo {
190 // a: i32,
191 // b: f32,
192 // }
193 nominal::struct_def(p, STRUCT_KW);
194 if p.at(SEMI) {
195 p.err_and_bump(
196 "expected item, found `;`\n\
197 consider removing this semicolon"
198 );
199 }
200 STRUCT_DEF
201 }
202 IDENT if p.at_contextual_kw("union") => {
203 // test union_items
204 // union Foo {}
205 // union Foo {
206 // a: i32,
207 // b: f32,
208 // }
209 nominal::struct_def(p, UNION_KW);
210 STRUCT_DEF
211 }
212 ENUM_KW => {
213 nominal::enum_def(p);
214 ENUM_DEF
215 }
216 USE_KW => {
217 use_item::use_item(p);
218 USE_ITEM
219 }
220 CONST_KW if (la == IDENT || la == MUT_KW) => {
221 consts::const_def(p);
222 CONST_DEF
223 }
224 STATIC_KW => {
225 consts::static_def(p);
226 STATIC_DEF
227 }
228 // test extern_block
229 // extern {}
230 EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => {
231 abi(p);
232 extern_item_list(p);
233 EXTERN_BLOCK
234 }
235 _ => return None,
236 };
237 Some(kind)
238}
239
240fn extern_crate_item(p: &mut Parser) {
241 assert!(p.at(EXTERN_KW));
242 p.bump();
243 assert!(p.at(CRATE_KW));
244 p.bump();
245 name(p);
246 opt_alias(p);
247 p.expect(SEMI);
248}
249
250pub(crate) fn extern_item_list(p: &mut Parser) {
251 assert!(p.at(L_CURLY));
252 let m = p.start();
253 p.bump();
254 mod_contents(p, true);
255 p.expect(R_CURLY);
256 m.complete(p, EXTERN_ITEM_LIST);
257}
258
259fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
260 assert!(p.at(FN_KW));
261 p.bump();
262
263 name_r(p, ITEM_RECOVERY_SET);
264 // test function_type_params
265 // fn foo<T: Clone + Copy>(){}
266 type_params::opt_type_param_list(p);
267
268 if p.at(L_PAREN) {
269 match flavor {
270 ItemFlavor::Mod =>
271 params::param_list(p),
272 ItemFlavor::Trait =>
273 params::param_list_opt_patterns(p),
274 }
275 } else {
276 p.error("expected function arguments");
277 }
278 // test function_ret_type
279 // fn foo() {}
280 // fn bar() -> () {}
281 opt_fn_ret_type(p);
282
283 // test function_where_clause
284 // fn foo<T>() where T: Copy {}
285 type_params::opt_where_clause(p);
286
287 // test fn_decl
288 // trait T { fn foo(); }
289 if p.at(SEMI) {
290 p.bump();
291 } else {
292 expressions::block(p)
293 }
294}
295
296// test type_item
297// type Foo = Bar;
298fn type_def(p: &mut Parser) {
299 assert!(p.at(TYPE_KW));
300 p.bump();
301
302 name(p);
303
304 // test type_item_type_params
305 // type Result<T> = ();
306 type_params::opt_type_param_list(p);
307
308 if p.at(COLON) {
309 type_params::bounds(p);
310 }
311
312 // test type_item_where_clause
313 // type Foo where Foo: Copy = ();
314 type_params::opt_where_clause(p);
315
316 if p.eat(EQ) {
317 types::type_(p);
318 }
319 p.expect(SEMI);
320}
321
322pub(crate) fn mod_item(p: &mut Parser) {
323 assert!(p.at(MOD_KW));
324 p.bump();
325
326 name(p);
327 if p.at(L_CURLY) {
328 mod_item_list(p);
329 } else if !p.eat(SEMI) {
330 p.error("expected `;` or `{`");
331 }
332}
333
334pub(crate) fn mod_item_list(p: &mut Parser) {
335 assert!(p.at(L_CURLY));
336 let m = p.start();
337 p.bump();
338 mod_contents(p, true);
339 p.expect(R_CURLY);
340 m.complete(p, ITEM_LIST);
341}
342
343fn macro_call(p: &mut Parser) -> BlockLike {
344 assert!(paths::is_path_start(p));
345 paths::use_path(p);
346 macro_call_after_excl(p)
347}
348
349pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike {
350 p.expect(EXCL);
351 p.eat(IDENT);
352 let flavor = match p.current() {
353 L_CURLY => {
354 token_tree(p);
355 BlockLike::Block
356 }
357 L_PAREN | L_BRACK => {
358 token_tree(p);
359 BlockLike::NotBlock
360 }
361 _ => {
362 p.error("expected `{`, `[`, `(`");
363 BlockLike::NotBlock
364 },
365 };
366
367 flavor
368}
369
370pub(crate) fn token_tree(p: &mut Parser) {
371 let closing_paren_kind = match p.current() {
372 L_CURLY => R_CURLY,
373 L_PAREN => R_PAREN,
374 L_BRACK => R_BRACK,
375 _ => unreachable!(),
376 };
377 let m = p.start();
378 p.bump();
379 while !p.at(EOF) && !p.at(closing_paren_kind) {
380 match p.current() {
381 L_CURLY | L_PAREN | L_BRACK => token_tree(p),
382 R_CURLY => {
383 p.error("unmatched `}`");
384 m.complete(p, TOKEN_TREE);
385 return;
386 }
387 R_PAREN | R_BRACK => p.err_and_bump("unmatched brace"),
388 _ => p.bump()
389 }
390 };
391 p.expect(closing_paren_kind);
392 m.complete(p, TOKEN_TREE);
393}
diff --git a/crates/ra_syntax/src/grammar/items/nominal.rs b/crates/ra_syntax/src/grammar/items/nominal.rs
new file mode 100644
index 000000000..8d02ad555
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/items/nominal.rs
@@ -0,0 +1,154 @@
1use super::*;
2
3pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) {
4 assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union"));
5 p.bump_remap(kind);
6
7 name_r(p, ITEM_RECOVERY_SET);
8 type_params::opt_type_param_list(p);
9 match p.current() {
10 WHERE_KW => {
11 type_params::opt_where_clause(p);
12 match p.current() {
13 SEMI => {
14 p.bump();
15 return;
16 }
17 L_CURLY => named_field_def_list(p),
18 _ => {
19 //TODO: special case `(` error message
20 p.error("expected `;` or `{`");
21 return;
22 }
23 }
24 }
25 SEMI if kind == STRUCT_KW => {
26 p.bump();
27 return;
28 }
29 L_CURLY => named_field_def_list(p),
30 L_PAREN if kind == STRUCT_KW => {
31 pos_field_list(p);
32 p.expect(SEMI);
33 }
34 _ if kind == STRUCT_KW => {
35 p.error("expected `;`, `{`, or `(`");
36 return;
37 }
38 _ => {
39 p.error("expected `{`");
40 return;
41 }
42 }
43}
44
45pub(super) fn enum_def(p: &mut Parser) {
46 assert!(p.at(ENUM_KW));
47 p.bump();
48 name_r(p, ITEM_RECOVERY_SET);
49 type_params::opt_type_param_list(p);
50 type_params::opt_where_clause(p);
51 if p.at(L_CURLY) {
52 enum_variant_list(p);
53 } else {
54 p.error("expected `{`")
55 }
56}
57
58pub(crate) fn enum_variant_list(p: &mut Parser) {
59 assert!(p.at(L_CURLY));
60 let m = p.start();
61 p.bump();
62 while !p.at(EOF) && !p.at(R_CURLY) {
63 if p.at(L_CURLY) {
64 error_block(p, "expected enum variant");
65 continue;
66 }
67 let var = p.start();
68 attributes::outer_attributes(p);
69 if p.at(IDENT) {
70 name(p);
71 match p.current() {
72 L_CURLY => named_field_def_list(p),
73 L_PAREN => pos_field_list(p),
74 EQ => {
75 p.bump();
76 expressions::expr(p);
77 }
78 _ => (),
79 }
80 var.complete(p, ENUM_VARIANT);
81 } else {
82 var.abandon(p);
83 p.err_and_bump("expected enum variant");
84 }
85 if !p.at(R_CURLY) {
86 p.expect(COMMA);
87 }
88 }
89 p.expect(R_CURLY);
90 m.complete(p, ENUM_VARIANT_LIST);
91}
92
93pub(crate) fn named_field_def_list(p: &mut Parser) {
94 assert!(p.at(L_CURLY));
95 let m = p.start();
96 p.bump();
97 while !p.at(R_CURLY) && !p.at(EOF) {
98 if p.at(L_CURLY) {
99 error_block(p, "expected field");
100 continue;
101 }
102 named_field_def(p);
103 if !p.at(R_CURLY) {
104 p.expect(COMMA);
105 }
106 }
107 p.expect(R_CURLY);
108 m.complete(p, NAMED_FIELD_DEF_LIST);
109
110 fn named_field_def(p: &mut Parser) {
111 let m = p.start();
112 // test field_attrs
113 // struct S {
114 // #[serde(with = "url_serde")]
115 // pub uri: Uri,
116 // }
117 attributes::outer_attributes(p);
118 opt_visibility(p);
119 if p.at(IDENT) {
120 name(p);
121 p.expect(COLON);
122 types::type_(p);
123 m.complete(p, NAMED_FIELD_DEF);
124 } else {
125 m.abandon(p);
126 p.err_and_bump("expected field declaration");
127 }
128 }
129}
130
131fn pos_field_list(p: &mut Parser) {
132 assert!(p.at(L_PAREN));
133 let m = p.start();
134 if !p.expect(L_PAREN) {
135 return;
136 }
137 while !p.at(R_PAREN) && !p.at(EOF) {
138 let m = p.start();
139 opt_visibility(p);
140 if !p.at_ts(types::TYPE_FIRST) {
141 p.error("expected a type");
142 m.complete(p, ERROR);
143 break;
144 }
145 types::type_(p);
146 m.complete(p, POS_FIELD);
147
148 if !p.at(R_PAREN) {
149 p.expect(COMMA);
150 }
151 }
152 p.expect(R_PAREN);
153 m.complete(p, POS_FIELD_LIST);
154}
diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs
new file mode 100644
index 000000000..c21cfb1a9
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/items/traits.rs
@@ -0,0 +1,117 @@
1use super::*;
2
3// test trait_item
4// trait T<U>: Hash + Clone where U: Copy {}
5pub(super) fn trait_def(p: &mut Parser) {
6 assert!(p.at(TRAIT_KW));
7 p.bump();
8 name_r(p, ITEM_RECOVERY_SET);
9 type_params::opt_type_param_list(p);
10 if p.at(COLON) {
11 type_params::bounds(p);
12 }
13 type_params::opt_where_clause(p);
14 if p.at(L_CURLY) {
15 trait_item_list(p);
16 } else {
17 p.error("expected `{`");
18 }
19}
20
21// test trait_item_list
22// impl F {
23// type A: Clone;
24// const B: i32;
25// fn foo() {}
26// fn bar(&self);
27// }
28pub(crate) fn trait_item_list(p: &mut Parser) {
29 assert!(p.at(L_CURLY));
30 let m = p.start();
31 p.bump();
32 while !p.at(EOF) && !p.at(R_CURLY) {
33 if p.at(L_CURLY) {
34 error_block(p, "expected an item");
35 continue;
36 }
37 item_or_macro(p, true, ItemFlavor::Trait);
38 }
39 p.expect(R_CURLY);
40 m.complete(p, ITEM_LIST);
41}
42
43// test impl_item
44// impl Foo {}
45pub(super) fn impl_item(p: &mut Parser) {
46 assert!(p.at(IMPL_KW));
47 p.bump();
48 if choose_type_params_over_qpath(p) {
49 type_params::opt_type_param_list(p);
50 }
51
52 // TODO: never type
53 // impl ! {}
54
55 // test impl_item_neg
56 // impl !Send for X {}
57 p.eat(EXCL);
58 types::type_(p);
59 if p.eat(FOR_KW) {
60 types::type_(p);
61 }
62 type_params::opt_where_clause(p);
63 if p.at(L_CURLY) {
64 impl_item_list(p);
65 } else {
66 p.error("expected `{`");
67 }
68}
69
70// test impl_item_list
71// impl F {
72// type A = i32;
73// const B: i32 = 92;
74// fn foo() {}
75// fn bar(&self) {}
76// }
77pub(crate) fn impl_item_list(p: &mut Parser) {
78 assert!(p.at(L_CURLY));
79 let m = p.start();
80 p.bump();
81
82 while !p.at(EOF) && !p.at(R_CURLY) {
83 if p.at(L_CURLY) {
84 error_block(p, "expected an item");
85 continue;
86 }
87 item_or_macro(p, true, ItemFlavor::Mod);
88 }
89 p.expect(R_CURLY);
90 m.complete(p, ITEM_LIST);
91}
92
93fn choose_type_params_over_qpath(p: &Parser) -> bool {
94 // There's an ambiguity between generic parameters and qualified paths in impls.
95 // If we see `<` it may start both, so we have to inspect some following tokens.
96 // The following combinations can only start generics,
97 // but not qualified paths (with one exception):
98 // `<` `>` - empty generic parameters
99 // `<` `#` - generic parameters with attributes
100 // `<` (LIFETIME|IDENT) `>` - single generic parameter
101 // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
102 // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
103 // `<` (LIFETIME|IDENT) `=` - generic parameter with a default
104 // The only truly ambiguous case is
105 // `<` IDENT `>` `::` IDENT ...
106 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
107 // because this is what almost always expected in practice, qualified paths in impls
108 // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
109 if !p.at(L_ANGLE) {
110 return false;
111 }
112 if p.nth(1) == POUND || p.nth(1) == R_ANGLE {
113 return true;
114 }
115 (p.nth(1) == LIFETIME || p.nth(1) == IDENT)
116 && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ)
117}
diff --git a/crates/ra_syntax/src/grammar/items/use_item.rs b/crates/ra_syntax/src/grammar/items/use_item.rs
new file mode 100644
index 000000000..1ee4349fd
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/items/use_item.rs
@@ -0,0 +1,68 @@
1use super::*;
2
3pub(super) fn use_item(p: &mut Parser) {
4 assert!(p.at(USE_KW));
5 p.bump();
6 use_tree(p);
7 p.expect(SEMI);
8}
9
10fn use_tree(p: &mut Parser) {
11 let la = p.nth(1);
12 let m = p.start();
13 match (p.current(), la) {
14 (STAR, _) => p.bump(),
15 (COLONCOLON, STAR) => {
16 p.bump();
17 p.bump();
18 }
19 (L_CURLY, _) | (COLONCOLON, L_CURLY) => {
20 if p.at(COLONCOLON) {
21 p.bump();
22 }
23 use_tree_list(p);
24 }
25 _ if paths::is_path_start(p) => {
26 paths::use_path(p);
27 match p.current() {
28 AS_KW => {
29 opt_alias(p);
30 }
31 COLONCOLON => {
32 p.bump();
33 match p.current() {
34 STAR => {
35 p.bump();
36 }
37 L_CURLY => use_tree_list(p),
38 _ => {
39 // is this unreachable?
40 p.error("expected `{` or `*`");
41 }
42 }
43 }
44 _ => (),
45 }
46 }
47 _ => {
48 m.abandon(p);
49 p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`");
50 return;
51 }
52 }
53 m.complete(p, USE_TREE);
54}
55
56pub(crate) fn use_tree_list(p: &mut Parser) {
57 assert!(p.at(L_CURLY));
58 let m = p.start();
59 p.bump();
60 while !p.at(EOF) && !p.at(R_CURLY) {
61 use_tree(p);
62 if !p.at(R_CURLY) {
63 p.expect(COMMA);
64 }
65 }
66 p.expect(R_CURLY);
67 m.complete(p, USE_TREE_LIST);
68}
diff --git a/crates/ra_syntax/src/grammar/mod.rs b/crates/ra_syntax/src/grammar/mod.rs
new file mode 100644
index 000000000..2cb11dc1e
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/mod.rs
@@ -0,0 +1,188 @@
1//! This is the actual "grammar" of the Rust language.
2//!
3//! Each function in this module and its children corresponds
4//! to a production of the format grammar. Submodules roughly
5//! correspond to different *areas* of the grammar. By convention,
6//! each submodule starts with `use super::*` import and exports
7//! "public" productions via `pub(super)`.
8//!
9//! See docs for `Parser` to learn about API, available to the grammar,
10//! and see docs for `Event` to learn how this actually manages to
11//! produce parse trees.
12//!
13//! Code in this module also contains inline tests, which start with
14//! `// test name-of-the-test` comment and look like this:
15//!
16//! ```
17//! // test function_with_zero_parameters
18//! // fn foo() {}
19//! ```
20//!
21//! After adding a new inline-test, run `cargo collect-tests` to extract
22//! it as a standalone text-fixture into `tests/data/parser/inline`, and
23//! run `cargo test` once to create the "gold" value.
24mod attributes;
25mod expressions;
26mod items;
27mod params;
28mod paths;
29mod patterns;
30mod type_args;
31mod type_params;
32mod types;
33
34use {
35 token_set::TokenSet,
36 parser_api::{Marker, CompletedMarker, Parser},
37 SyntaxKind::{self, *},
38};
39pub(crate) use self::{
40 expressions::{
41 block,
42 },
43 items::{
44 enum_variant_list,
45 extern_item_list,
46 impl_item_list,
47 match_arm_list,
48 mod_item_list,
49 named_field_def_list,
50 named_field_list,
51 token_tree,
52 trait_item_list,
53 use_tree_list,
54 },
55};
56
57pub(crate) fn root(p: &mut Parser) {
58 let m = p.start();
59 p.eat(SHEBANG);
60 items::mod_contents(p, false);
61 m.complete(p, ROOT);
62}
63
64
65#[derive(Clone, Copy, PartialEq, Eq)]
66enum BlockLike {
67 Block,
68 NotBlock,
69}
70
71impl BlockLike {
72 fn is_block(self) -> bool { self == BlockLike::Block }
73}
74
75fn opt_visibility(p: &mut Parser) {
76 match p.current() {
77 PUB_KW => {
78 let m = p.start();
79 p.bump();
80 if p.at(L_PAREN) {
81 match p.nth(1) {
82 // test crate_visibility
83 // pub(crate) struct S;
84 // pub(self) struct S;
85 // pub(self) struct S;
86 // pub(self) struct S;
87 CRATE_KW | SELF_KW | SUPER_KW => {
88 p.bump();
89 p.bump();
90 p.expect(R_PAREN);
91 }
92 IN_KW => {
93 p.bump();
94 p.bump();
95 paths::use_path(p);
96 p.expect(R_PAREN);
97 }
98 _ => (),
99 }
100 }
101 m.complete(p, VISIBILITY);
102 }
103 // test crate_keyword_vis
104 // crate fn main() { }
105 CRATE_KW => {
106 let m = p.start();
107 p.bump();
108 m.complete(p, VISIBILITY);
109 }
110 _ => (),
111 }
112}
113
114fn opt_alias(p: &mut Parser) {
115 if p.at(AS_KW) {
116 let m = p.start();
117 p.bump();
118 name(p);
119 m.complete(p, ALIAS);
120 }
121}
122
123fn abi(p: &mut Parser) {
124 assert!(p.at(EXTERN_KW));
125 let abi = p.start();
126 p.bump();
127 match p.current() {
128 STRING | RAW_STRING => p.bump(),
129 _ => (),
130 }
131 abi.complete(p, ABI);
132}
133
134fn opt_fn_ret_type(p: &mut Parser) -> bool {
135 if p.at(THIN_ARROW) {
136 let m = p.start();
137 p.bump();
138 types::type_(p);
139 m.complete(p, RET_TYPE);
140 true
141 } else {
142 false
143 }
144}
145
146fn name_r(p: &mut Parser, recovery: TokenSet) {
147 if p.at(IDENT) {
148 let m = p.start();
149 p.bump();
150 m.complete(p, NAME);
151 } else {
152 p.err_recover("expected a name", recovery);
153 }
154}
155
156fn name(p: &mut Parser) {
157 name_r(p, TokenSet::EMPTY)
158}
159
160fn name_ref(p: &mut Parser) {
161 if p.at(IDENT) {
162 let m = p.start();
163 p.bump();
164 m.complete(p, NAME_REF);
165 } else {
166 p.err_and_bump("expected identifier");
167 }
168}
169
170fn error_block(p: &mut Parser, message: &str) {
171 go(p, Some(message));
172 fn go(p: &mut Parser, message: Option<&str>) {
173 assert!(p.at(L_CURLY));
174 let m = p.start();
175 if let Some(message) = message {
176 p.error(message);
177 }
178 p.bump();
179 while !p.at(EOF) && !p.at(R_CURLY) {
180 match p.current() {
181 L_CURLY => go(p, None),
182 _ => p.bump(),
183 }
184 }
185 p.eat(R_CURLY);
186 m.complete(p, ERROR);
187 }
188}
diff --git a/crates/ra_syntax/src/grammar/params.rs b/crates/ra_syntax/src/grammar/params.rs
new file mode 100644
index 000000000..903c25939
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/params.rs
@@ -0,0 +1,142 @@
1use super::*;
2
3// test param_list
4// fn a() {}
5// fn b(x: i32) {}
6// fn c(x: i32, ) {}
7// fn d(x: i32, y: ()) {}
8pub(super) fn param_list(p: &mut Parser) {
9 list_(p, Flavor::Normal)
10}
11
12// test param_list_opt_patterns
13// fn foo<F: FnMut(&mut Foo<'a>)>(){}
14pub(super) fn param_list_opt_patterns(p: &mut Parser) {
15 list_(p, Flavor::OptionalPattern)
16}
17
18pub(super) fn param_list_opt_types(p: &mut Parser) {
19 list_(p, Flavor::OptionalType)
20}
21
22#[derive(Clone, Copy, Eq, PartialEq)]
23enum Flavor {
24 OptionalType,
25 OptionalPattern,
26 Normal,
27}
28
29impl Flavor {
30 fn type_required(self) -> bool {
31 match self {
32 Flavor::OptionalType => false,
33 _ => true,
34 }
35 }
36}
37
38fn list_(p: &mut Parser, flavor: Flavor) {
39 let (bra, ket) = if flavor.type_required() {
40 (L_PAREN, R_PAREN)
41 } else {
42 (PIPE, PIPE)
43 };
44 assert!(p.at(bra));
45 let m = p.start();
46 p.bump();
47 if flavor.type_required() {
48 opt_self_param(p);
49 }
50 while !p.at(EOF) && !p.at(ket) {
51 if !p.at_ts(VALUE_PARAMETER_FIRST) {
52 p.error("expected value parameter");
53 break;
54 }
55 value_parameter(p, flavor);
56 if !p.at(ket) {
57 p.expect(COMMA);
58 }
59 }
60 p.expect(ket);
61 m.complete(p, PARAM_LIST);
62}
63
64
65const VALUE_PARAMETER_FIRST: TokenSet =
66 token_set_union![
67 patterns::PATTERN_FIRST,
68 types::TYPE_FIRST,
69 ];
70
71fn value_parameter(p: &mut Parser, flavor: Flavor) {
72 let m = p.start();
73 match flavor {
74 Flavor::OptionalType | Flavor::Normal => {
75 patterns::pattern(p);
76 if p.at(COLON) || flavor.type_required() {
77 types::ascription(p)
78 }
79 },
80 // test value_parameters_no_patterns
81 // type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>;
82 Flavor::OptionalPattern => {
83 let la0 = p.current();
84 let la1 = p.nth(1);
85 let la2 = p.nth(2);
86 let la3 = p.nth(3);
87 if la0 == IDENT && la1 == COLON
88 || la0 == AMP && la1 == IDENT && la2 == COLON
89 || la0 == AMP && la1 == MUT_KW && la2 == IDENT && la3 == COLON {
90 patterns::pattern(p);
91 types::ascription(p);
92 } else {
93 types::type_(p);
94 }
95 },
96 }
97 m.complete(p, PARAM);
98}
99
100// test self_param
101// impl S {
102// fn a(self) {}
103// fn b(&self,) {}
104// fn c(&'a self,) {}
105// fn d(&'a mut self, x: i32) {}
106// fn e(mut self) {}
107// }
108fn opt_self_param(p: &mut Parser) {
109 let m;
110 if p.at(SELF_KW) || p.at(MUT_KW) && p.nth(1) == SELF_KW {
111 m = p.start();
112 p.eat(MUT_KW);
113 p.eat(SELF_KW);
114 // test arb_self_types
115 // impl S {
116 // fn a(self: &Self) {}
117 // fn b(mut self: Box<Self>) {}
118 // }
119 if p.at(COLON) {
120 types::ascription(p);
121 }
122 } else {
123 let la1 = p.nth(1);
124 let la2 = p.nth(2);
125 let la3 = p.nth(3);
126 let n_toks = match (p.current(), la1, la2, la3) {
127 (AMP, SELF_KW, _, _) => 2,
128 (AMP, MUT_KW, SELF_KW, _) => 3,
129 (AMP, LIFETIME, SELF_KW, _) => 3,
130 (AMP, LIFETIME, MUT_KW, SELF_KW) => 4,
131 _ => return,
132 };
133 m = p.start();
134 for _ in 0..n_toks {
135 p.bump();
136 }
137 }
138 m.complete(p, SELF_PARAM);
139 if !p.at(R_PAREN) {
140 p.expect(COMMA);
141 }
142}
diff --git a/crates/ra_syntax/src/grammar/paths.rs b/crates/ra_syntax/src/grammar/paths.rs
new file mode 100644
index 000000000..7c9fb8be2
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/paths.rs
@@ -0,0 +1,101 @@
1use super::*;
2
3pub(super) const PATH_FIRST: TokenSet =
4 token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE];
5
6pub(super) fn is_path_start(p: &Parser) -> bool {
7 match p.current() {
8 IDENT | SELF_KW | SUPER_KW | COLONCOLON => true,
9 _ => false,
10 }
11}
12
13pub(super) fn use_path(p: &mut Parser) {
14 path(p, Mode::Use)
15}
16
17pub(super) fn type_path(p: &mut Parser) {
18 path(p, Mode::Type)
19}
20
21pub(super) fn expr_path(p: &mut Parser) {
22 path(p, Mode::Expr)
23}
24
25#[derive(Clone, Copy, Eq, PartialEq)]
26enum Mode {
27 Use,
28 Type,
29 Expr,
30}
31
32fn path(p: &mut Parser, mode: Mode) {
33 let path = p.start();
34 path_segment(p, mode, true);
35 let mut qual = path.complete(p, PATH);
36 loop {
37 let use_tree = match p.nth(1) {
38 STAR | L_CURLY => true,
39 _ => false,
40 };
41 if p.at(COLONCOLON) && !use_tree {
42 let path = qual.precede(p);
43 p.bump();
44 path_segment(p, mode, false);
45 let path = path.complete(p, PATH);
46 qual = path;
47 } else {
48 break;
49 }
50 }
51}
52
53fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
54 let m = p.start();
55 // test qual_paths
56 // type X = <A as B>::Output;
57 // fn foo() { <usize as Default>::default(); }
58 if first && p.eat(L_ANGLE) {
59 types::type_(p);
60 if p.eat(AS_KW) {
61 if is_path_start(p) {
62 types::path_type(p);
63 } else {
64 p.error("expected a trait");
65 }
66 }
67 p.expect(R_ANGLE);
68 } else {
69 if first {
70 p.eat(COLONCOLON);
71 }
72 match p.current() {
73 IDENT => {
74 name_ref(p);
75 opt_path_type_args(p, mode);
76 }
77 SELF_KW | SUPER_KW => p.bump(),
78 _ => {
79 p.err_and_bump("expected identifier");
80 }
81 };
82 }
83 m.complete(p, PATH_SEGMENT);
84}
85
86fn opt_path_type_args(p: &mut Parser, mode: Mode) {
87 match mode {
88 Mode::Use => return,
89 Mode::Type => {
90 // test path_fn_trait_args
91 // type F = Box<Fn(x: i32) -> ()>;
92 if p.at(L_PAREN) {
93 params::param_list_opt_patterns(p);
94 opt_fn_ret_type(p);
95 } else {
96 type_args::opt_type_arg_list(p, false)
97 }
98 },
99 Mode::Expr => type_args::opt_type_arg_list(p, true),
100 }
101}
diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs
new file mode 100644
index 000000000..420bae7a7
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/patterns.rs
@@ -0,0 +1,224 @@
1use super::*;
2
3pub(super) const PATTERN_FIRST: TokenSet =
4 token_set_union![
5 token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE],
6 expressions::LITERAL_FIRST,
7 paths::PATH_FIRST,
8 ];
9
10pub(super) fn pattern(p: &mut Parser) {
11 pattern_r(p, PAT_RECOVERY_SET)
12}
13
14pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) {
15 if let Some(lhs) = atom_pat(p, recovery_set) {
16 // test range_pat
17 // fn main() {
18 // match 92 { 0 ... 100 => () }
19 // }
20 if p.at(DOTDOTDOT) {
21 let m = lhs.precede(p);
22 p.bump();
23 atom_pat(p, recovery_set);
24 m.complete(p, RANGE_PAT);
25 }
26 }
27}
28
29const PAT_RECOVERY_SET: TokenSet =
30 token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA];
31
32
33fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
34 let la0 = p.nth(0);
35 let la1 = p.nth(1);
36 if la0 == REF_KW || la0 == MUT_KW
37 || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) {
38 return Some(bind_pat(p, true));
39 }
40 if paths::is_path_start(p) {
41 return Some(path_pat(p));
42 }
43
44 // test literal_pattern
45 // fn main() {
46 // match () {
47 // 92 => (),
48 // 'c' => (),
49 // "hello" => (),
50 // }
51 // }
52 match expressions::literal(p) {
53 Some(m) => return Some(m),
54 None => (),
55 }
56
57 let m = match la0 {
58 UNDERSCORE => placeholder_pat(p),
59 AMP => ref_pat(p),
60 L_PAREN => tuple_pat(p),
61 L_BRACK => slice_pat(p),
62 _ => {
63 p.err_recover("expected pattern", recovery_set);
64 return None;
65 }
66 };
67 Some(m)
68}
69
70// test path_part
71// fn foo() {
72// let foo::Bar = ();
73// let ::Bar = ();
74// let Bar { .. } = ();
75// let Bar(..) = ();
76// }
77fn path_pat(p: &mut Parser) -> CompletedMarker {
78 assert!(paths::is_path_start(p));
79 let m = p.start();
80 paths::expr_path(p);
81 let kind = match p.current() {
82 L_PAREN => {
83 tuple_pat_fields(p);
84 TUPLE_STRUCT_PAT
85 }
86 L_CURLY => {
87 field_pat_list(p);
88 STRUCT_PAT
89 }
90 _ => PATH_PAT
91 };
92 m.complete(p, kind)
93}
94
95// test tuple_pat_fields
96// fn foo() {
97// let S() = ();
98// let S(_) = ();
99// let S(_,) = ();
100// let S(_, .. , x) = ();
101// }
102fn tuple_pat_fields(p: &mut Parser) {
103 assert!(p.at(L_PAREN));
104 p.bump();
105 pat_list(p, R_PAREN);
106 p.expect(R_PAREN);
107}
108
109// test field_pat_list
110// fn foo() {
111// let S {} = ();
112// let S { f, ref mut g } = ();
113// let S { h: _, ..} = ();
114// let S { h: _, } = ();
115// }
116fn field_pat_list(p: &mut Parser) {
117 assert!(p.at(L_CURLY));
118 let m = p.start();
119 p.bump();
120 while !p.at(EOF) && !p.at(R_CURLY) {
121 match p.current() {
122 DOTDOT => p.bump(),
123 IDENT if p.nth(1) == COLON => {
124 p.bump();
125 p.bump();
126 pattern(p);
127 }
128 L_CURLY => error_block(p, "expected ident"),
129 _ => {
130 bind_pat(p, false);
131 }
132 }
133 if !p.at(R_CURLY) {
134 p.expect(COMMA);
135 }
136 }
137 p.expect(R_CURLY);
138 m.complete(p, FIELD_PAT_LIST);
139}
140
141// test placeholder_pat
142// fn main() { let _ = (); }
143fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
144 assert!(p.at(UNDERSCORE));
145 let m = p.start();
146 p.bump();
147 m.complete(p, PLACEHOLDER_PAT)
148}
149
150// test ref_pat
151// fn main() {
152// let &a = ();
153// let &mut b = ();
154// }
155fn ref_pat(p: &mut Parser) -> CompletedMarker {
156 assert!(p.at(AMP));
157 let m = p.start();
158 p.bump();
159 p.eat(MUT_KW);
160 pattern(p);
161 m.complete(p, REF_PAT)
162}
163
164// test tuple_pat
165// fn main() {
166// let (a, b, ..) = ();
167// }
168fn tuple_pat(p: &mut Parser) -> CompletedMarker {
169 assert!(p.at(L_PAREN));
170 let m = p.start();
171 tuple_pat_fields(p);
172 m.complete(p, TUPLE_PAT)
173}
174
175// test slice_pat
176// fn main() {
177// let [a, b, ..] = [];
178// }
179fn slice_pat(p: &mut Parser) -> CompletedMarker {
180 assert!(p.at(L_BRACK));
181 let m = p.start();
182 p.bump();
183 pat_list(p, R_BRACK);
184 p.expect(R_BRACK);
185 m.complete(p, SLICE_PAT)
186}
187
188fn pat_list(p: &mut Parser, ket: SyntaxKind) {
189 while !p.at(EOF) && !p.at(ket) {
190 match p.current() {
191 DOTDOT => p.bump(),
192 _ => {
193 if !p.at_ts(PATTERN_FIRST) {
194 p.error("expected a pattern");
195 break;
196 }
197 pattern(p)
198 },
199 }
200 if !p.at(ket) {
201 p.expect(COMMA);
202 }
203 }
204}
205
206// test bind_pat
207// fn main() {
208// let a = ();
209// let mut b = ();
210// let ref c = ();
211// let ref mut d = ();
212// let e @ _ = ();
213// let ref mut f @ g @ _ = ();
214// }
215fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
216 let m = p.start();
217 p.eat(REF_KW);
218 p.eat(MUT_KW);
219 name(p);
220 if with_at && p.eat(AT) {
221 pattern(p);
222 }
223 m.complete(p, BIND_PAT)
224}
diff --git a/crates/ra_syntax/src/grammar/type_args.rs b/crates/ra_syntax/src/grammar/type_args.rs
new file mode 100644
index 000000000..29ff6e534
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/type_args.rs
@@ -0,0 +1,48 @@
1use super::*;
2
3pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) {
4 let m;
5 match (colon_colon_required, p.nth(0), p.nth(1)) {
6 (_, COLONCOLON, L_ANGLE) => {
7 m = p.start();
8 p.bump();
9 p.bump();
10 }
11 (false, L_ANGLE, _) => {
12 m = p.start();
13 p.bump();
14 }
15 _ => return,
16 };
17
18 while !p.at(EOF) && !p.at(R_ANGLE) {
19 type_arg(p);
20 if !p.at(R_ANGLE) && !p.expect(COMMA) {
21 break;
22 }
23 }
24 p.expect(R_ANGLE);
25 m.complete(p, TYPE_ARG_LIST);
26}
27
28// test type_arg
29// type A = B<'static, i32, Item=u64>
30fn type_arg(p: &mut Parser) {
31 let m = p.start();
32 match p.current() {
33 LIFETIME => {
34 p.bump();
35 m.complete(p, LIFETIME_ARG);
36 }
37 IDENT if p.nth(1) == EQ => {
38 name_ref(p);
39 p.bump();
40 types::type_(p);
41 m.complete(p, ASSOC_TYPE_ARG);
42 }
43 _ => {
44 types::type_(p);
45 m.complete(p, TYPE_ARG);
46 }
47 }
48}
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs
new file mode 100644
index 000000000..79bc95ce4
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/type_params.rs
@@ -0,0 +1,136 @@
1use super::*;
2
3pub(super) fn opt_type_param_list(p: &mut Parser) {
4 if !p.at(L_ANGLE) {
5 return;
6 }
7 let m = p.start();
8 p.bump();
9
10 while !p.at(EOF) && !p.at(R_ANGLE) {
11 match p.current() {
12 LIFETIME => lifetime_param(p),
13 IDENT => type_param(p),
14 _ => p.err_and_bump("expected type parameter"),
15 }
16 if !p.at(R_ANGLE) && !p.expect(COMMA) {
17 break;
18 }
19 }
20 p.expect(R_ANGLE);
21 m.complete(p, TYPE_PARAM_LIST);
22
23 fn lifetime_param(p: &mut Parser) {
24 assert!(p.at(LIFETIME));
25 let m = p.start();
26 p.bump();
27 if p.at(COLON) {
28 lifetime_bounds(p);
29 }
30 m.complete(p, LIFETIME_PARAM);
31 }
32
33 fn type_param(p: &mut Parser) {
34 assert!(p.at(IDENT));
35 let m = p.start();
36 name(p);
37 if p.at(COLON) {
38 bounds(p);
39 }
40 // test type_param_default
41 // struct S<T = i32>;
42 if p.at(EQ) {
43 p.bump();
44 types::type_(p)
45 }
46 m.complete(p, TYPE_PARAM);
47 }
48}
49
50// test type_param_bounds
51// struct S<T: 'a + ?Sized + (Copy)>;
52pub(super) fn bounds(p: &mut Parser) {
53 assert!(p.at(COLON));
54 p.bump();
55 bounds_without_colon(p);
56}
57
58fn lifetime_bounds(p: &mut Parser) {
59 assert!(p.at(COLON));
60 p.bump();
61 while p.at(LIFETIME) {
62 p.bump();
63 if !p.eat(PLUS) {
64 break;
65 }
66 }
67}
68
69pub(super) fn bounds_without_colon(p: &mut Parser) {
70 loop {
71 let has_paren = p.eat(L_PAREN);
72 p.eat(QUESTION);
73 match p.current() {
74 LIFETIME => p.bump(),
75 FOR_KW => {
76 types::for_type(p)
77 }
78 _ if paths::is_path_start(p) => {
79 types::path_type(p)
80 }
81 _ => break,
82 }
83 if has_paren {
84 p.expect(R_PAREN);
85 }
86 if !p.eat(PLUS) {
87 break;
88 }
89 }
90}
91
92// test where_clause
93// fn foo()
94// where
95// 'a: 'b + 'c,
96// T: Clone + Copy + 'static,
97// Iterator::Item: 'a,
98// {}
99pub(super) fn opt_where_clause(p: &mut Parser) {
100 if !p.at(WHERE_KW) {
101 return;
102 }
103 let m = p.start();
104 p.bump();
105 loop {
106 if !(paths::is_path_start(p) || p.current() == LIFETIME) {
107 break
108 }
109 where_predicate(p);
110 if p.current() != L_CURLY && p.current() != SEMI {
111 p.expect(COMMA);
112 }
113 }
114 m.complete(p, WHERE_CLAUSE);
115}
116
117fn where_predicate(p: &mut Parser) {
118 let m = p.start();
119 if p.at(LIFETIME) {
120 p.eat(LIFETIME);
121 if p.at(COLON) {
122 lifetime_bounds(p)
123 } else {
124 p.error("expected colon")
125 }
126 } else {
127 types::path_type(p);
128 if p.at(COLON) {
129 bounds(p);
130 } else {
131 p.error("expected colon")
132 }
133
134 }
135 m.complete(p, WHERE_PRED);
136}
diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs
new file mode 100644
index 000000000..27e5b086e
--- /dev/null
+++ b/crates/ra_syntax/src/grammar/types.rs
@@ -0,0 +1,247 @@
1use super::*;
2
3pub(super) const TYPE_FIRST: TokenSet =
4 token_set_union![
5 token_set![
6 L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, DYN_KW, L_ANGLE,
7 ],
8 paths::PATH_FIRST,
9 ];
10
11const TYPE_RECOVERY_SET: TokenSet =
12 token_set![R_PAREN, COMMA];
13
14pub(super) fn type_(p: &mut Parser) {
15 match p.current() {
16 L_PAREN => paren_or_tuple_type(p),
17 EXCL => never_type(p),
18 STAR => pointer_type(p),
19 L_BRACK => array_or_slice_type(p),
20 AMP => reference_type(p),
21 UNDERSCORE => placeholder_type(p),
22 FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p),
23 FOR_KW => for_type(p),
24 IMPL_KW => impl_trait_type(p),
25 DYN_KW => dyn_trait_type(p),
26 L_ANGLE => path_type(p),
27 _ if paths::is_path_start(p) => path_type(p),
28 _ => {
29 p.err_recover("expected type", TYPE_RECOVERY_SET);
30 }
31 }
32}
33
34pub(super) fn ascription(p: &mut Parser) {
35 p.expect(COLON);
36 type_(p)
37}
38
39fn type_no_plus(p: &mut Parser) {
40 type_(p);
41}
42
43fn paren_or_tuple_type(p: &mut Parser) {
44 assert!(p.at(L_PAREN));
45 let m = p.start();
46 p.bump();
47 let mut n_types: u32 = 0;
48 let mut trailing_comma: bool = false;
49 while !p.at(EOF) && !p.at(R_PAREN) {
50 n_types += 1;
51 type_(p);
52 if p.eat(COMMA) {
53 trailing_comma = true;
54 } else {
55 trailing_comma = false;
56 break;
57 }
58 }
59 p.expect(R_PAREN);
60
61 let kind = if n_types == 1 && !trailing_comma {
62 // test paren_type
63 // type T = (i32);
64 PAREN_TYPE
65 } else {
66 // test unit_type
67 // type T = ();
68
69 // test singleton_tuple_type
70 // type T = (i32,);
71 TUPLE_TYPE
72 };
73 m.complete(p, kind);
74}
75
76// test never_type
77// type Never = !;
78fn never_type(p: &mut Parser) {
79 assert!(p.at(EXCL));
80 let m = p.start();
81 p.bump();
82 m.complete(p, NEVER_TYPE);
83}
84
85fn pointer_type(p: &mut Parser) {
86 assert!(p.at(STAR));
87 let m = p.start();
88 p.bump();
89
90 match p.current() {
91 // test pointer_type_mut
92 // type M = *mut ();
93 // type C = *mut ();
94 MUT_KW | CONST_KW => p.bump(),
95 _ => {
96 // test pointer_type_no_mutability
97 // type T = *();
98 p.error(
99 "expected mut or const in raw pointer type \
100 (use `*mut T` or `*const T` as appropriate)",
101 );
102 }
103 };
104
105 type_no_plus(p);
106 m.complete(p, POINTER_TYPE);
107}
108
109fn array_or_slice_type(p: &mut Parser) {
110 assert!(p.at(L_BRACK));
111 let m = p.start();
112 p.bump();
113
114 type_(p);
115 let kind = match p.current() {
116 // test slice_type
117 // type T = [()];
118 R_BRACK => {
119 p.bump();
120 SLICE_TYPE
121 }
122
123 // test array_type
124 // type T = [(); 92];
125 SEMI => {
126 p.bump();
127 expressions::expr(p);
128 p.expect(R_BRACK);
129 ARRAY_TYPE
130 }
131 // test array_type_missing_semi
132 // type T = [() 92];
133 _ => {
134 p.error("expected `;` or `]`");
135 SLICE_TYPE
136 }
137 };
138 m.complete(p, kind);
139}
140
141// test reference_type;
142// type A = &();
143// type B = &'static ();
144// type C = &mut ();
145fn reference_type(p: &mut Parser) {
146 assert!(p.at(AMP));
147 let m = p.start();
148 p.bump();
149 p.eat(LIFETIME);
150 p.eat(MUT_KW);
151 type_no_plus(p);
152 m.complete(p, REFERENCE_TYPE);
153}
154
155// test placeholder_type
156// type Placeholder = _;
157fn placeholder_type(p: &mut Parser) {
158 assert!(p.at(UNDERSCORE));
159 let m = p.start();
160 p.bump();
161 m.complete(p, PLACEHOLDER_TYPE);
162}
163
164// test fn_pointer_type
165// type A = fn();
166// type B = unsafe fn();
167// type C = unsafe extern "C" fn();
168fn fn_pointer_type(p: &mut Parser) {
169 let m = p.start();
170 p.eat(UNSAFE_KW);
171 if p.at(EXTERN_KW) {
172 abi(p);
173 }
174 // test fn_pointer_type_missing_fn
175 // type F = unsafe ();
176 if !p.eat(FN_KW) {
177 m.abandon(p);
178 p.error("expected `fn`");
179 return;
180 }
181 if p.at(L_PAREN) {
182 params::param_list_opt_patterns(p);
183 } else {
184 p.error("expected parameters")
185 }
186 // test fn_pointer_type_with_ret
187 // type F = fn() -> ();
188 opt_fn_ret_type(p);
189 m.complete(p, FN_POINTER_TYPE);
190}
191
192// test for_type
193// type A = for<'a> fn() -> ();
194pub(super) fn for_type(p: &mut Parser) {
195 assert!(p.at(FOR_KW));
196 let m = p.start();
197 p.bump();
198 type_params::opt_type_param_list(p);
199 match p.current() {
200 FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p),
201 _ if paths::is_path_start(p) => path_type_(p, false),
202 _ => p.error("expected a path"),
203
204 }
205 m.complete(p, FOR_TYPE);
206}
207
208// test impl_trait_type
209// type A = impl Iterator<Item=Foo<'a>> + 'a;
210fn impl_trait_type(p: &mut Parser) {
211 assert!(p.at(IMPL_KW));
212 let m = p.start();
213 p.bump();
214 type_params::bounds_without_colon(p);
215 m.complete(p, IMPL_TRAIT_TYPE);
216}
217
218// test dyn_trait_type
219// type A = dyn Iterator<Item=Foo<'a>> + 'a;
220fn dyn_trait_type(p: &mut Parser) {
221 assert!(p.at(DYN_KW));
222 let m = p.start();
223 p.bump();
224 type_params::bounds_without_colon(p);
225 m.complete(p, DYN_TRAIT_TYPE);
226}
227
228// test path_type
229// type A = Foo;
230// type B = ::Foo;
231// type C = self::Foo;
232// type D = super::Foo;
233pub(super) fn path_type(p: &mut Parser) {
234 path_type_(p, true)
235}
236
237pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
238 assert!(paths::is_path_start(p) || p.at(L_ANGLE));
239 let m = p.start();
240 paths::type_path(p);
241 // test path_type_with_bounds
242 // fn foo() -> Box<T + 'f> {}
243 if allow_bounds && p.eat(PLUS) {
244 type_params::bounds_without_colon(p);
245 }
246 m.complete(p, PATH_TYPE);
247}
diff --git a/crates/ra_syntax/src/lexer/classes.rs b/crates/ra_syntax/src/lexer/classes.rs
new file mode 100644
index 000000000..4235d2648
--- /dev/null
+++ b/crates/ra_syntax/src/lexer/classes.rs
@@ -0,0 +1,26 @@
1use unicode_xid::UnicodeXID;
2
3pub fn is_ident_start(c: char) -> bool {
4 (c >= 'a' && c <= 'z')
5 || (c >= 'A' && c <= 'Z')
6 || c == '_'
7 || (c > '\x7f' && UnicodeXID::is_xid_start(c))
8}
9
10pub fn is_ident_continue(c: char) -> bool {
11 (c >= 'a' && c <= 'z')
12 || (c >= 'A' && c <= 'Z')
13 || (c >= '0' && c <= '9')
14 || c == '_'
15 || (c > '\x7f' && UnicodeXID::is_xid_continue(c))
16}
17
18pub fn is_whitespace(c: char) -> bool {
19 //FIXME: use is_pattern_whitespace
20 //https://github.com/behnam/rust-unic/issues/192
21 c.is_whitespace()
22}
23
24pub fn is_dec_digit(c: char) -> bool {
25 '0' <= c && c <= '9'
26}
diff --git a/crates/ra_syntax/src/lexer/comments.rs b/crates/ra_syntax/src/lexer/comments.rs
new file mode 100644
index 000000000..eb417c2dc
--- /dev/null
+++ b/crates/ra_syntax/src/lexer/comments.rs
@@ -0,0 +1,57 @@
1use lexer::ptr::Ptr;
2
3use SyntaxKind::{self, *};
4
5pub(crate) fn scan_shebang(ptr: &mut Ptr) -> bool {
6 if ptr.at_str("!/") {
7 ptr.bump();
8 ptr.bump();
9 bump_until_eol(ptr);
10 true
11 } else {
12 false
13 }
14}
15
16fn scan_block_comment(ptr: &mut Ptr) -> Option<SyntaxKind> {
17 if ptr.at('*') {
18 ptr.bump();
19 let mut depth: u32 = 1;
20 while depth > 0 {
21 if ptr.at_str("*/") {
22 depth -= 1;
23 ptr.bump();
24 ptr.bump();
25 } else if ptr.at_str("/*") {
26 depth += 1;
27 ptr.bump();
28 ptr.bump();
29 } else if ptr.bump().is_none() {
30 break;
31 }
32 }
33 Some(COMMENT)
34 } else {
35 None
36 }
37}
38
39pub(crate) fn scan_comment(ptr: &mut Ptr) -> Option<SyntaxKind> {
40 if ptr.at('/') {
41 bump_until_eol(ptr);
42 Some(COMMENT)
43 } else {
44 scan_block_comment(ptr)
45 }
46}
47
48fn bump_until_eol(ptr: &mut Ptr) {
49 loop {
50 if ptr.at('\n') || ptr.at_str("\r\n") {
51 return;
52 }
53 if ptr.bump().is_none() {
54 break;
55 }
56 }
57}
diff --git a/crates/ra_syntax/src/lexer/mod.rs b/crates/ra_syntax/src/lexer/mod.rs
new file mode 100644
index 000000000..3e11db88b
--- /dev/null
+++ b/crates/ra_syntax/src/lexer/mod.rs
@@ -0,0 +1,209 @@
1mod classes;
2mod comments;
3mod numbers;
4mod ptr;
5mod strings;
6
7use {
8 SyntaxKind::{self, *},
9 TextUnit,
10};
11
12use self::{
13 classes::*,
14 comments::{scan_comment, scan_shebang},
15 numbers::scan_number,
16 ptr::Ptr,
17 strings::{
18 is_string_literal_start, scan_byte_char_or_string, scan_char, scan_raw_string, scan_string,
19 },
20};
21
22/// A token of Rust source.
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct Token {
25 /// The kind of token.
26 pub kind: SyntaxKind,
27 /// The length of the token.
28 pub len: TextUnit,
29}
30
31/// Break a string up into its component tokens
32pub fn tokenize(text: &str) -> Vec<Token> {
33 let mut text = text;
34 let mut acc = Vec::new();
35 while !text.is_empty() {
36 let token = next_token(text);
37 acc.push(token);
38 let len: u32 = token.len.into();
39 text = &text[len as usize..];
40 }
41 acc
42}
43
44/// Get the next token from a string
45pub fn next_token(text: &str) -> Token {
46 assert!(!text.is_empty());
47 let mut ptr = Ptr::new(text);
48 let c = ptr.bump().unwrap();
49 let kind = next_token_inner(c, &mut ptr);
50 let len = ptr.into_len();
51 Token { kind, len }
52}
53
54fn next_token_inner(c: char, ptr: &mut Ptr) -> SyntaxKind {
55 if is_whitespace(c) {
56 ptr.bump_while(is_whitespace);
57 return WHITESPACE;
58 }
59
60 match c {
61 '#' => if scan_shebang(ptr) {
62 return SHEBANG;
63 },
64 '/' => if let Some(kind) = scan_comment(ptr) {
65 return kind;
66 },
67 _ => (),
68 }
69
70 let ident_start = is_ident_start(c) && !is_string_literal_start(c, ptr.current(), ptr.nth(1));
71 if ident_start {
72 return scan_ident(c, ptr);
73 }
74
75 if is_dec_digit(c) {
76 let kind = scan_number(c, ptr);
77 scan_literal_suffix(ptr);
78 return kind;
79 }
80
81 // One-byte tokens.
82 if let Some(kind) = SyntaxKind::from_char(c) {
83 return kind;
84 }
85
86 match c {
87 // Multi-byte tokens.
88 '.' => {
89 return match (ptr.current(), ptr.nth(1)) {
90 (Some('.'), Some('.')) => {
91 ptr.bump();
92 ptr.bump();
93 DOTDOTDOT
94 }
95 (Some('.'), Some('=')) => {
96 ptr.bump();
97 ptr.bump();
98 DOTDOTEQ
99 }
100 (Some('.'), _) => {
101 ptr.bump();
102 DOTDOT
103 }
104 _ => DOT,
105 };
106 }
107 ':' => {
108 return match ptr.current() {
109 Some(':') => {
110 ptr.bump();
111 COLONCOLON
112 }
113 _ => COLON,
114 };
115 }
116 '=' => {
117 return match ptr.current() {
118 Some('=') => {
119 ptr.bump();
120 EQEQ
121 }
122 Some('>') => {
123 ptr.bump();
124 FAT_ARROW
125 }
126 _ => EQ,
127 };
128 }
129 '!' => {
130 return match ptr.current() {
131 Some('=') => {
132 ptr.bump();
133 NEQ
134 }
135 _ => EXCL,
136 };
137 }
138 '-' => {
139 return if ptr.at('>') {
140 ptr.bump();
141 THIN_ARROW
142 } else {
143 MINUS
144 };
145 }
146
147 // If the character is an ident start not followed by another single
148 // quote, then this is a lifetime name:
149 '\'' => {
150 return if ptr.at_p(is_ident_start) && !ptr.at_str("''") {
151 ptr.bump();
152 while ptr.at_p(is_ident_continue) {
153 ptr.bump();
154 }
155 // lifetimes shouldn't end with a single quote
156 // if we find one, then this is an invalid character literal
157 if ptr.at('\'') {
158 ptr.bump();
159 return CHAR; // TODO: error reporting
160 }
161 LIFETIME
162 } else {
163 scan_char(ptr);
164 scan_literal_suffix(ptr);
165 CHAR
166 };
167 }
168 'b' => {
169 let kind = scan_byte_char_or_string(ptr);
170 scan_literal_suffix(ptr);
171 return kind;
172 }
173 '"' => {
174 scan_string(ptr);
175 scan_literal_suffix(ptr);
176 return STRING;
177 }
178 'r' => {
179 scan_raw_string(ptr);
180 scan_literal_suffix(ptr);
181 return RAW_STRING;
182 }
183 _ => (),
184 }
185 ERROR
186}
187
188fn scan_ident(c: char, ptr: &mut Ptr) -> SyntaxKind {
189 let is_single_letter = match ptr.current() {
190 None => true,
191 Some(c) if !is_ident_continue(c) => true,
192 _ => false,
193 };
194 if is_single_letter {
195 return if c == '_' { UNDERSCORE } else { IDENT };
196 }
197 ptr.bump_while(is_ident_continue);
198 if let Some(kind) = SyntaxKind::from_keyword(ptr.current_token_text()) {
199 return kind;
200 }
201 IDENT
202}
203
204fn scan_literal_suffix(ptr: &mut Ptr) {
205 if ptr.at_p(is_ident_start) {
206 ptr.bump();
207 }
208 ptr.bump_while(is_ident_continue);
209}
diff --git a/crates/ra_syntax/src/lexer/numbers.rs b/crates/ra_syntax/src/lexer/numbers.rs
new file mode 100644
index 000000000..22e7d4e99
--- /dev/null
+++ b/crates/ra_syntax/src/lexer/numbers.rs
@@ -0,0 +1,67 @@
1use lexer::classes::*;
2use lexer::ptr::Ptr;
3
4use SyntaxKind::{self, *};
5
6pub(crate) fn scan_number(c: char, ptr: &mut Ptr) -> SyntaxKind {
7 if c == '0' {
8 match ptr.current().unwrap_or('\0') {
9 'b' | 'o' => {
10 ptr.bump();
11 scan_digits(ptr, false);
12 }
13 'x' => {
14 ptr.bump();
15 scan_digits(ptr, true);
16 }
17 '0'...'9' | '_' | '.' | 'e' | 'E' => {
18 scan_digits(ptr, true);
19 }
20 _ => return INT_NUMBER,
21 }
22 } else {
23 scan_digits(ptr, false);
24 }
25
26 // might be a float, but don't be greedy if this is actually an
27 // integer literal followed by field/method access or a range pattern
28 // (`0..2` and `12.foo()`)
29 if ptr.at('.') && !(ptr.at_str("..") || ptr.nth_is_p(1, is_ident_start)) {
30 // might have stuff after the ., and if it does, it needs to start
31 // with a number
32 ptr.bump();
33 scan_digits(ptr, false);
34 scan_float_exponent(ptr);
35 return FLOAT_NUMBER;
36 }
37 // it might be a float if it has an exponent
38 if ptr.at('e') || ptr.at('E') {
39 scan_float_exponent(ptr);
40 return FLOAT_NUMBER;
41 }
42 INT_NUMBER
43}
44
45fn scan_digits(ptr: &mut Ptr, allow_hex: bool) {
46 while let Some(c) = ptr.current() {
47 match c {
48 '_' | '0'...'9' => {
49 ptr.bump();
50 }
51 'a'...'f' | 'A'...'F' if allow_hex => {
52 ptr.bump();
53 }
54 _ => return,
55 }
56 }
57}
58
59fn scan_float_exponent(ptr: &mut Ptr) {
60 if ptr.at('e') || ptr.at('E') {
61 ptr.bump();
62 if ptr.at('-') || ptr.at('+') {
63 ptr.bump();
64 }
65 scan_digits(ptr, false);
66 }
67}
diff --git a/crates/ra_syntax/src/lexer/ptr.rs b/crates/ra_syntax/src/lexer/ptr.rs
new file mode 100644
index 000000000..c9a5354ea
--- /dev/null
+++ b/crates/ra_syntax/src/lexer/ptr.rs
@@ -0,0 +1,166 @@
1use TextUnit;
2
3use std::str::Chars;
4
5/// A simple view into the characters of a string.
6pub(crate) struct Ptr<'s> {
7 text: &'s str,
8 len: TextUnit,
9}
10
11impl<'s> Ptr<'s> {
12 /// Creates a new `Ptr` from a string.
13 pub fn new(text: &'s str) -> Ptr<'s> {
14 Ptr {
15 text,
16 len: 0.into(),
17 }
18 }
19
20 /// Gets the length of the remaining string.
21 pub fn into_len(self) -> TextUnit {
22 self.len
23 }
24
25 /// Gets the current character, if one exists.
26 pub fn current(&self) -> Option<char> {
27 self.chars().next()
28 }
29
30 /// Gets the nth character from the current.
31 /// For example, 0 will return the current token, 1 will return the next, etc.
32 pub fn nth(&self, n: u32) -> Option<char> {
33 let mut chars = self.chars().peekable();
34 chars.by_ref().skip(n as usize).next()
35 }
36
37 /// Checks whether the current character is `c`.
38 pub fn at(&self, c: char) -> bool {
39 self.current() == Some(c)
40 }
41
42 /// Checks whether the next characters match `s`.
43 pub fn at_str(&self, s: &str) -> bool {
44 let chars = self.chars();
45 chars.as_str().starts_with(s)
46 }
47
48 /// Checks whether the current character satisfies the predicate `p`.
49 pub fn at_p<P: Fn(char) -> bool>(&self, p: P) -> bool {
50 self.current().map(p) == Some(true)
51 }
52
53 /// Checks whether the nth character satisfies the predicate `p`.
54 pub fn nth_is_p<P: Fn(char) -> bool>(&self, n: u32, p: P) -> bool {
55 self.nth(n).map(p) == Some(true)
56 }
57
58 /// Moves to the next character.
59 pub fn bump(&mut self) -> Option<char> {
60 let ch = self.chars().next()?;
61 self.len += TextUnit::of_char(ch);
62 Some(ch)
63 }
64
65 /// Moves to the next character as long as `pred` is satisfied.
66 pub fn bump_while<F: Fn(char) -> bool>(&mut self, pred: F) {
67 loop {
68 match self.current() {
69 Some(c) if pred(c) => {
70 self.bump();
71 }
72 _ => return,
73 }
74 }
75 }
76
77 /// Returns the text up to the current point.
78 pub fn current_token_text(&self) -> &str {
79 let len: u32 = self.len.into();
80 &self.text[..len as usize]
81 }
82
83 /// Returns an iterator over the remaining characters.
84 fn chars(&self) -> Chars {
85 let len: u32 = self.len.into();
86 self.text[len as usize..].chars()
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_current() {
96 let ptr = Ptr::new("test");
97 assert_eq!(ptr.current(), Some('t'));
98 }
99
100 #[test]
101 fn test_nth() {
102 let ptr = Ptr::new("test");
103 assert_eq!(ptr.nth(0), Some('t'));
104 assert_eq!(ptr.nth(1), Some('e'));
105 assert_eq!(ptr.nth(2), Some('s'));
106 assert_eq!(ptr.nth(3), Some('t'));
107 assert_eq!(ptr.nth(4), None);
108 }
109
110 #[test]
111 fn test_at() {
112 let ptr = Ptr::new("test");
113 assert!(ptr.at('t'));
114 assert!(!ptr.at('a'));
115 }
116
117 #[test]
118 fn test_at_str() {
119 let ptr = Ptr::new("test");
120 assert!(ptr.at_str("t"));
121 assert!(ptr.at_str("te"));
122 assert!(ptr.at_str("test"));
123 assert!(!ptr.at_str("tests"));
124 assert!(!ptr.at_str("rust"));
125 }
126
127 #[test]
128 fn test_at_p() {
129 let ptr = Ptr::new("test");
130 assert!(ptr.at_p(|c| c == 't'));
131 assert!(!ptr.at_p(|c| c == 'e'));
132 }
133
134 #[test]
135 fn test_nth_is_p() {
136 let ptr = Ptr::new("test");
137 assert!(ptr.nth_is_p(0,|c| c == 't'));
138 assert!(!ptr.nth_is_p(1,|c| c == 't'));
139 assert!(ptr.nth_is_p(3,|c| c == 't'));
140 assert!(!ptr.nth_is_p(150,|c| c == 't'));
141 }
142
143 #[test]
144 fn test_bump() {
145 let mut ptr = Ptr::new("test");
146 assert_eq!(ptr.current(), Some('t'));
147 ptr.bump();
148 assert_eq!(ptr.current(), Some('e'));
149 ptr.bump();
150 assert_eq!(ptr.current(), Some('s'));
151 ptr.bump();
152 assert_eq!(ptr.current(), Some('t'));
153 ptr.bump();
154 assert_eq!(ptr.current(), None);
155 ptr.bump();
156 assert_eq!(ptr.current(), None);
157 }
158
159 #[test]
160 fn test_bump_while() {
161 let mut ptr = Ptr::new("test");
162 assert_eq!(ptr.current(), Some('t'));
163 ptr.bump_while(|c| c != 's');
164 assert_eq!(ptr.current(), Some('s'));
165 }
166}
diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs
new file mode 100644
index 000000000..5ff483d14
--- /dev/null
+++ b/crates/ra_syntax/src/lexer/strings.rs
@@ -0,0 +1,123 @@
1use SyntaxKind::{self, *};
2
3use lexer::ptr::Ptr;
4
5pub(crate) fn is_string_literal_start(c: char, c1: Option<char>, c2: Option<char>) -> bool {
6 match (c, c1, c2) {
7 ('r', Some('"'), _)
8 | ('r', Some('#'), _)
9 | ('b', Some('"'), _)
10 | ('b', Some('\''), _)
11 | ('b', Some('r'), Some('"'))
12 | ('b', Some('r'), Some('#')) => true,
13 _ => false,
14 }
15}
16
17pub(crate) fn scan_char(ptr: &mut Ptr) {
18 while let Some(c) = ptr.current() {
19 match c {
20 '\\' => {
21 ptr.bump();
22 if ptr.at('\\') || ptr.at('\'') {
23 ptr.bump();
24 }
25 }
26 '\'' => {
27 ptr.bump();
28 return;
29 }
30 '\n' => return,
31 _ => {
32 ptr.bump();
33 }
34 }
35 }
36}
37
38pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind {
39 // unwrapping and not-exhaustive match are ok
40 // because of string_literal_start
41 let c = ptr.bump().unwrap();
42 match c {
43 '\'' => {
44 scan_byte(ptr);
45 BYTE
46 }
47 '"' => {
48 scan_byte_string(ptr);
49 BYTE_STRING
50 }
51 'r' => {
52 scan_raw_byte_string(ptr);
53 RAW_BYTE_STRING
54 }
55 _ => unreachable!(),
56 }
57}
58
59pub(crate) fn scan_string(ptr: &mut Ptr) {
60 while let Some(c) = ptr.current() {
61 match c {
62 '\\' => {
63 ptr.bump();
64 if ptr.at('\\') || ptr.at('"') {
65 ptr.bump();
66 }
67 }
68 '"' => {
69 ptr.bump();
70 return;
71 }
72 _ => {
73 ptr.bump();
74 },
75 }
76 }
77}
78
79pub(crate) fn scan_raw_string(ptr: &mut Ptr) {
80 let mut hashes = 0;
81 while ptr.at('#') {
82 hashes += 1;
83 ptr.bump();
84 }
85 if !ptr.at('"') {
86 return;
87 }
88 ptr.bump();
89
90 while let Some(c) = ptr.bump() {
91 if c == '"' {
92 let mut hashes_left = hashes;
93 while ptr.at('#') && hashes_left > 0{
94 hashes_left -= 1;
95 ptr.bump();
96 }
97 if hashes_left == 0 {
98 return;
99 }
100 }
101 }
102}
103
104fn scan_byte(ptr: &mut Ptr) {
105 scan_char(ptr)
106}
107
108fn scan_byte_string(ptr: &mut Ptr) {
109 scan_string(ptr)
110}
111
112fn scan_raw_byte_string(ptr: &mut Ptr) {
113 if !ptr.at('"') {
114 return;
115 }
116 ptr.bump();
117
118 while let Some(c) = ptr.bump() {
119 if c == '"' {
120 return;
121 }
122 }
123}
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
new file mode 100644
index 000000000..eb271762e
--- /dev/null
+++ b/crates/ra_syntax/src/lib.rs
@@ -0,0 +1,105 @@
1//! An experimental implementation of [Rust RFC#2256 libsyntax2.0][rfc#2256].
2//!
3//! The intent is to be an IDE-ready parser, i.e. one that offers
4//!
5//! - easy and fast incremental re-parsing,
6//! - graceful handling of errors, and
7//! - maintains all information in the source file.
8//!
9//! For more information, see [the RFC][rfc#2265], or [the working draft][RFC.md].
10//!
11//! [rfc#2256]: <https://github.com/rust-lang/rfcs/pull/2256>
12//! [RFC.md]: <https://github.com/matklad/libsyntax2/blob/master/docs/RFC.md>
13
14#![forbid(
15 missing_debug_implementations,
16 unconditional_recursion,
17 future_incompatible
18)]
19#![deny(bad_style, missing_docs)]
20#![allow(missing_docs)]
21//#![warn(unreachable_pub)] // rust-lang/rust#47816
22
23extern crate itertools;
24extern crate unicode_xid;
25extern crate drop_bomb;
26extern crate parking_lot;
27extern crate smol_str;
28extern crate text_unit;
29
30#[cfg(test)]
31#[macro_use]
32extern crate test_utils;
33
34pub mod algo;
35pub mod ast;
36mod lexer;
37#[macro_use]
38mod token_set;
39mod parser_api;
40mod grammar;
41mod parser_impl;
42mod reparsing;
43
44mod syntax_kinds;
45mod yellow;
46/// Utilities for simple uses of the parser.
47pub mod utils;
48pub mod text_utils;
49
50pub use {
51 text_unit::{TextRange, TextUnit},
52 smol_str::SmolStr,
53 ast::AstNode,
54 lexer::{tokenize, Token},
55 syntax_kinds::SyntaxKind,
56 yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError},
57 reparsing::AtomEdit,
58};
59
60use {
61 yellow::{GreenNode, SyntaxRoot},
62};
63
64#[derive(Clone, Debug, Hash)]
65pub struct File {
66 root: SyntaxNode
67}
68
69impl File {
70 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File {
71 let root = SyntaxRoot::new(green, errors);
72 let root = SyntaxNode::new_owned(root);
73 if cfg!(debug_assertions) {
74 utils::validate_block_structure(root.borrowed());
75 }
76 File { root }
77 }
78 pub fn parse(text: &str) -> File {
79 let tokens = tokenize(&text);
80 let (green, errors) = parser_impl::parse_with::<yellow::GreenBuilder>(
81 text, &tokens, grammar::root,
82 );
83 File::new(green, errors)
84 }
85 pub fn reparse(&self, edit: &AtomEdit) -> File {
86 self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
87 }
88 pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> {
89 reparsing::incremental_reparse(self.syntax(), edit, self.errors())
90 .map(|(green_node, errors)| File::new(green_node, errors))
91 }
92 fn full_reparse(&self, edit: &AtomEdit) -> File {
93 let text = text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert);
94 File::parse(&text)
95 }
96 pub fn ast(&self) -> ast::Root {
97 ast::Root::cast(self.syntax()).unwrap()
98 }
99 pub fn syntax(&self) -> SyntaxNodeRef {
100 self.root.borrowed()
101 }
102 pub fn errors(&self) -> Vec<SyntaxError> {
103 self.syntax().root.syntax_root().errors.clone()
104 }
105}
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs
new file mode 100644
index 000000000..772d753af
--- /dev/null
+++ b/crates/ra_syntax/src/parser_api.rs
@@ -0,0 +1,178 @@
1use {
2 token_set::TokenSet,
3 parser_impl::ParserImpl,
4 SyntaxKind::{self, ERROR},
5 drop_bomb::DropBomb,
6};
7
8/// `Parser` struct provides the low-level API for
9/// navigating through the stream of tokens and
10/// constructing the parse tree. The actual parsing
11/// happens in the `grammar` module.
12///
13/// However, the result of this `Parser` is not a real
14/// tree, but rather a flat stream of events of the form
15/// "start expression, consume number literal,
16/// finish expression". See `Event` docs for more.
17pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>);
18
19impl<'t> Parser<'t> {
20 /// Returns the kind of the current token.
21 /// If parser has already reached the end of input,
22 /// the special `EOF` kind is returned.
23 pub(crate) fn current(&self) -> SyntaxKind {
24 self.nth(0)
25 }
26
27 /// Lookahead operation: returns the kind of the next nth
28 /// token.
29 pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
30 self.0.nth(n)
31 }
32
33 /// Checks if the current token is `kind`.
34 pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
35 self.current() == kind
36 }
37
38 /// Checks if the current token is `kind`.
39 pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
40 kinds.contains(self.current())
41 }
42
43 pub(crate) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
44 self.0.next2()
45 }
46
47 pub(crate) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
48 self.0.next3()
49 }
50
51 /// Checks if the current token is contextual keyword with text `t`.
52 pub(crate) fn at_contextual_kw(&self, t: &str) -> bool {
53 self.0.at_kw(t)
54 }
55
56 /// Starts a new node in the syntax tree. All nodes and tokens
57 /// consumed between the `start` and the corresponding `Marker::complete`
58 /// belong to the same node.
59 pub(crate) fn start(&mut self) -> Marker {
60 Marker::new(self.0.start())
61 }
62
63 /// Advances the parser by one token.
64 pub(crate) fn bump(&mut self) {
65 self.0.bump();
66 }
67
68 /// Advances the parser by one token, remapping its kind.
69 /// This is useful to create contextual keywords from
70 /// identifiers. For example, the lexer creates an `union`
71 /// *identifier* token, but the parser remaps it to the
72 /// `union` keyword, and keyword is what ends up in the
73 /// final tree.
74 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
75 self.0.bump_remap(kind);
76 }
77
78 /// Advances the parser by `n` tokens, remapping its kind.
79 /// This is useful to create compound tokens from parts. For
80 /// example, an `<<` token is two consecutive remapped `<` tokens
81 pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
82 self.0.bump_compound(kind, n);
83 }
84
85 /// Emit error with the `message`
86 /// TODO: this should be much more fancy and support
87 /// structured errors with spans and notes, like rustc
88 /// does.
89 pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
90 self.0.error(message.into())
91 }
92
93 /// Consume the next token if it is `kind`.
94 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
95 if !self.at(kind) {
96 return false;
97 }
98 self.bump();
99 true
100 }
101
102 /// Consume the next token if it is `kind` or emit an error
103 /// otherwise.
104 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
105 if self.eat(kind) {
106 return true;
107 }
108 self.error(format!("expected {:?}", kind));
109 false
110 }
111
112 /// Create an error node and consume the next token.
113 pub(crate) fn err_and_bump(&mut self, message: &str) {
114 self.err_recover(message, TokenSet::EMPTY);
115 }
116
117 /// Create an error node and consume the next token.
118 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
119 if self.at(SyntaxKind::L_CURLY)
120 || self.at(SyntaxKind::R_CURLY)
121 || self.at_ts(recovery) {
122 self.error(message);
123 } else {
124 let m = self.start();
125 self.error(message);
126 self.bump();
127 m.complete(self, ERROR);
128 };
129 }
130}
131
132/// See `Parser::start`.
133pub(crate) struct Marker {
134 pos: u32,
135 bomb: DropBomb,
136}
137
138impl Marker {
139 fn new(pos: u32) -> Marker {
140 Marker {
141 pos,
142 bomb: DropBomb::new("Marker must be either completed or abandoned"),
143 }
144 }
145
146 /// Finishes the syntax tree node and assigns `kind` to it.
147 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
148 self.bomb.defuse();
149 p.0.complete(self.pos, kind);
150 CompletedMarker(self.pos, kind)
151 }
152
153 /// Abandons the syntax tree node. All its children
154 /// are attached to its parent instead.
155 pub(crate) fn abandon(mut self, p: &mut Parser) {
156 self.bomb.defuse();
157 p.0.abandon(self.pos);
158 }
159}
160
161pub(crate) struct CompletedMarker(u32, SyntaxKind);
162
163impl CompletedMarker {
164 /// This one is tricky :-)
165 /// This method allows to create a new node which starts
166 /// *before* the current one. That is, parser could start
167 /// node `A`, then complete it, and then after parsing the
168 /// whole `A`, decide that it should have started some node
169 /// `B` before starting `A`. `precede` allows to do exactly
170 /// that. See also docs about `forward_parent` in `Event::Start`.
171 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
172 Marker::new(p.0.precede(self.0))
173 }
174
175 pub(crate) fn kind(&self) -> SyntaxKind {
176 self.1
177 }
178}
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs
new file mode 100644
index 000000000..9fd56b996
--- /dev/null
+++ b/crates/ra_syntax/src/parser_impl/event.rs
@@ -0,0 +1,154 @@
1//! This module provides a way to construct a `File`.
2//! It is intended to be completely decoupled from the
3//! parser, so as to allow to evolve the tree representation
4//! and the parser algorithm independently.
5//!
6//! The `Sink` trait is the bridge between the parser and the
7//! tree builder: the parser produces a stream of events like
8//! `start node`, `finish node`, and `FileBuilder` converts
9//! this stream to a real tree.
10use std::mem;
11use {
12 lexer::Token,
13 parser_impl::Sink,
14 SyntaxKind::{self, TOMBSTONE},
15};
16
17
18/// `Parser` produces a flat list of `Event`s.
19/// They are converted to a tree-structure in
20/// a separate pass, via `TreeBuilder`.
21#[derive(Debug)]
22pub(crate) enum Event {
23 /// This event signifies the start of the node.
24 /// It should be either abandoned (in which case the
25 /// `kind` is `TOMBSTONE`, and the event is ignored),
26 /// or completed via a `Finish` event.
27 ///
28 /// All tokens between a `Start` and a `Finish` would
29 /// become the children of the respective node.
30 ///
31 /// For left-recursive syntactic constructs, the parser produces
32 /// a child node before it sees a parent. `forward_parent`
33 /// exists to allow to tweak parent-child relationships.
34 ///
35 /// Consider this path
36 ///
37 /// foo::bar
38 ///
39 /// The events for it would look like this:
40 ///
41 ///
42 /// START(PATH) IDENT('foo') FINISH START(PATH) COLONCOLON IDENT('bar') FINISH
43 /// | /\
44 /// | |
45 /// +------forward-parent------+
46 ///
47 /// And the tree would look like this
48 ///
49 /// +--PATH---------+
50 /// | | |
51 /// | | |
52 /// | '::' 'bar'
53 /// |
54 /// PATH
55 /// |
56 /// 'foo'
57 ///
58 /// See also `CompletedMarker::precede`.
59 Start {
60 kind: SyntaxKind,
61 forward_parent: Option<u32>,
62 },
63
64 /// Complete the previous `Start` event
65 Finish,
66
67 /// Produce a single leaf-element.
68 /// `n_raw_tokens` is used to glue complex contextual tokens.
69 /// For example, lexer tokenizes `>>` as `>`, `>`, and
70 /// `n_raw_tokens = 2` is used to produced a single `>>`.
71 Token {
72 kind: SyntaxKind,
73 n_raw_tokens: u8,
74 },
75
76 Error {
77 msg: String,
78 },
79}
80
81
82pub(super) fn process<'a, S: Sink<'a>>(builder: &mut S, tokens: &[Token], mut events: Vec<Event>) {
83 fn tombstone() -> Event {
84 Event::Start { kind: TOMBSTONE, forward_parent: None }
85 }
86 let eat_ws = |idx: &mut usize, builder: &mut S| {
87 while let Some(token) = tokens.get(*idx) {
88 if !token.kind.is_trivia() {
89 break;
90 }
91 builder.leaf(token.kind, token.len);
92 *idx += 1
93 }
94 };
95
96 let events: &mut [Event] = &mut events;
97 let mut depth = 0;
98 let mut forward_parents = Vec::new();
99 let mut next_tok_idx = 0;
100 for i in 0..events.len() {
101 match mem::replace(&mut events[i], tombstone()) {
102 Event::Start {
103 kind: TOMBSTONE, ..
104 } => (),
105
106 Event::Start { kind, forward_parent } => {
107 forward_parents.push(kind);
108 let mut idx = i;
109 let mut fp = forward_parent;
110 while let Some(fwd) = fp {
111 idx += fwd as usize;
112 fp = match mem::replace(&mut events[idx], tombstone()) {
113 Event::Start {
114 kind,
115 forward_parent,
116 } => {
117 forward_parents.push(kind);
118 forward_parent
119 },
120 _ => unreachable!(),
121 };
122 }
123 for kind in forward_parents.drain(..).rev() {
124 if depth > 0 {
125 eat_ws(&mut next_tok_idx, builder);
126 }
127 depth += 1;
128 builder.start_internal(kind);
129 }
130 }
131 Event::Finish => {
132 depth -= 1;
133 if depth == 0 {
134 eat_ws(&mut next_tok_idx, builder);
135 }
136
137 builder.finish_internal();
138 }
139 Event::Token {
140 kind,
141 mut n_raw_tokens,
142 } => {
143 eat_ws(&mut next_tok_idx, builder);
144 let mut len = 0.into();
145 for _ in 0..n_raw_tokens {
146 len += tokens[next_tok_idx].len;
147 next_tok_idx += 1;
148 }
149 builder.leaf(kind, len);
150 }
151 Event::Error { msg } => builder.error(msg),
152 }
153 }
154}
diff --git a/crates/ra_syntax/src/parser_impl/input.rs b/crates/ra_syntax/src/parser_impl/input.rs
new file mode 100644
index 000000000..c0fe4d488
--- /dev/null
+++ b/crates/ra_syntax/src/parser_impl/input.rs
@@ -0,0 +1,86 @@
1use {lexer::Token, SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit};
2
3use std::ops::{Add, AddAssign};
4
5pub(crate) struct ParserInput<'t> {
6 text: &'t str,
7 start_offsets: Vec<TextUnit>,
8 tokens: Vec<Token>, // non-whitespace tokens
9}
10
11impl<'t> ParserInput<'t> {
12 pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> {
13 let mut tokens = Vec::new();
14 let mut start_offsets = Vec::new();
15 let mut len = 0.into();
16 for &token in raw_tokens.iter() {
17 if !token.kind.is_trivia() {
18 tokens.push(token);
19 start_offsets.push(len);
20 }
21 len += token.len;
22 }
23
24 ParserInput {
25 text,
26 start_offsets,
27 tokens,
28 }
29 }
30
31 pub fn kind(&self, pos: InputPosition) -> SyntaxKind {
32 let idx = pos.0 as usize;
33 if !(idx < self.tokens.len()) {
34 return EOF;
35 }
36 self.tokens[idx].kind
37 }
38
39 pub fn len(&self, pos: InputPosition) -> TextUnit {
40 let idx = pos.0 as usize;
41 if !(idx < self.tokens.len()) {
42 return 0.into();
43 }
44 self.tokens[idx].len
45 }
46
47 pub fn start(&self, pos: InputPosition) -> TextUnit {
48 let idx = pos.0 as usize;
49 if !(idx < self.tokens.len()) {
50 return 0.into();
51 }
52 self.start_offsets[idx]
53 }
54
55 pub fn text(&self, pos: InputPosition) -> &'t str {
56 let idx = pos.0 as usize;
57 if !(idx < self.tokens.len()) {
58 return "";
59 }
60 let range = TextRange::offset_len(self.start_offsets[idx], self.tokens[idx].len);
61 &self.text[range]
62 }
63}
64
65#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
66pub(crate) struct InputPosition(u32);
67
68impl InputPosition {
69 pub fn new() -> Self {
70 InputPosition(0)
71 }
72}
73
74impl Add<u32> for InputPosition {
75 type Output = InputPosition;
76
77 fn add(self, rhs: u32) -> InputPosition {
78 InputPosition(self.0 + rhs)
79 }
80}
81
82impl AddAssign<u32> for InputPosition {
83 fn add_assign(&mut self, rhs: u32) {
84 self.0 += rhs
85 }
86}
diff --git a/crates/ra_syntax/src/parser_impl/mod.rs b/crates/ra_syntax/src/parser_impl/mod.rs
new file mode 100644
index 000000000..b343b404f
--- /dev/null
+++ b/crates/ra_syntax/src/parser_impl/mod.rs
@@ -0,0 +1,194 @@
1mod event;
2mod input;
3
4use std::cell::Cell;
5
6use {
7 lexer::Token,
8 parser_api::Parser,
9 parser_impl::{
10 event::{process, Event},
11 input::{InputPosition, ParserInput},
12 },
13 TextUnit,
14};
15
16use SyntaxKind::{self, EOF, TOMBSTONE};
17
18pub(crate) trait Sink<'a> {
19 type Tree;
20
21 fn new(text: &'a str) -> Self;
22
23 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
24 fn start_internal(&mut self, kind: SyntaxKind);
25 fn finish_internal(&mut self);
26 fn error(&mut self, err: String);
27 fn finish(self) -> Self::Tree;
28}
29
30/// Parse a sequence of tokens into the representative node tree
31pub(crate) fn parse_with<'a, S: Sink<'a>>(
32 text: &'a str,
33 tokens: &[Token],
34 parser: fn(&mut Parser),
35) -> S::Tree {
36 let events = {
37 let input = input::ParserInput::new(text, tokens);
38 let parser_impl = ParserImpl::new(&input);
39 let mut parser_api = Parser(parser_impl);
40 parser(&mut parser_api);
41 parser_api.0.into_events()
42 };
43 let mut sink = S::new(text);
44 process(&mut sink, tokens, events);
45 sink.finish()
46}
47
48/// Implementation details of `Parser`, extracted
49/// to a separate struct in order not to pollute
50/// the public API of the `Parser`.
51pub(crate) struct ParserImpl<'t> {
52 inp: &'t ParserInput<'t>,
53
54 pos: InputPosition,
55 events: Vec<Event>,
56 steps: Cell<u32>,
57}
58
59impl<'t> ParserImpl<'t> {
60 pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> {
61 ParserImpl {
62 inp,
63
64 pos: InputPosition::new(),
65 events: Vec::new(),
66 steps: Cell::new(0),
67 }
68 }
69
70 pub(crate) fn into_events(self) -> Vec<Event> {
71 assert_eq!(self.nth(0), EOF);
72 self.events
73 }
74
75 pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
76 let c1 = self.inp.kind(self.pos);
77 let c2 = self.inp.kind(self.pos + 1);
78 if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) {
79 Some((c1, c2))
80 } else {
81 None
82 }
83 }
84
85 pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
86 let c1 = self.inp.kind(self.pos);
87 let c2 = self.inp.kind(self.pos + 1);
88 let c3 = self.inp.kind(self.pos + 2);
89 if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos)
90 && self.inp.start(self.pos + 2) == self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1){
91 Some((c1, c2, c3))
92 } else {
93 None
94 }
95 }
96
97 pub(super) fn nth(&self, n: u32) -> SyntaxKind {
98 let steps = self.steps.get();
99 if steps > 10_000_000 {
100 panic!("the parser seems stuck");
101 }
102 self.steps.set(steps + 1);
103
104 self.inp.kind(self.pos + n)
105 }
106
107 pub(super) fn at_kw(&self, t: &str) -> bool {
108 self.inp.text(self.pos) == t
109 }
110
111 pub(super) fn start(&mut self) -> u32 {
112 let pos = self.events.len() as u32;
113 self.event(Event::Start {
114 kind: TOMBSTONE,
115 forward_parent: None,
116 });
117 pos
118 }
119
120 pub(super) fn bump(&mut self) {
121 let kind = self.nth(0);
122 if kind == EOF {
123 return;
124 }
125 self.do_bump(kind, 1);
126 }
127
128 pub(super) fn bump_remap(&mut self, kind: SyntaxKind) {
129 if self.nth(0) == EOF {
130 // TODO: panic!?
131 return;
132 }
133 self.do_bump(kind, 1);
134 }
135
136 pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
137 self.do_bump(kind, n);
138 }
139
140 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
141 self.pos += u32::from(n_raw_tokens);
142 self.event(Event::Token {
143 kind,
144 n_raw_tokens,
145 });
146 }
147
148 pub(super) fn error(&mut self, msg: String) {
149 self.event(Event::Error { msg })
150 }
151
152 pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) {
153 match self.events[pos as usize] {
154 Event::Start {
155 kind: ref mut slot, ..
156 } => {
157 *slot = kind;
158 }
159 _ => unreachable!(),
160 }
161 self.event(Event::Finish);
162 }
163
164 pub(super) fn abandon(&mut self, pos: u32) {
165 let idx = pos as usize;
166 if idx == self.events.len() - 1 {
167 match self.events.pop() {
168 Some(Event::Start {
169 kind: TOMBSTONE,
170 forward_parent: None,
171 }) => (),
172 _ => unreachable!(),
173 }
174 }
175 }
176
177 pub(super) fn precede(&mut self, pos: u32) -> u32 {
178 let new_pos = self.start();
179 match self.events[pos as usize] {
180 Event::Start {
181 ref mut forward_parent,
182 ..
183 } => {
184 *forward_parent = Some(new_pos - pos);
185 }
186 _ => unreachable!(),
187 }
188 new_pos
189 }
190
191 fn event(&mut self, event: Event) {
192 self.events.push(event)
193 }
194}
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs
new file mode 100644
index 000000000..da44913c5
--- /dev/null
+++ b/crates/ra_syntax/src/reparsing.rs
@@ -0,0 +1,343 @@
1use algo;
2use grammar;
3use lexer::{tokenize, Token};
4use text_unit::{TextRange, TextUnit};
5use yellow::{self, SyntaxNodeRef, GreenNode, SyntaxError};
6use parser_impl;
7use parser_api::Parser;
8use {
9 SyntaxKind::*,
10};
11use text_utils::replace_range;
12
13#[derive(Debug, Clone)]
14pub struct AtomEdit {
15 pub delete: TextRange,
16 pub insert: String,
17}
18
19impl AtomEdit {
20 pub fn replace(range: TextRange, replace_with: String) -> AtomEdit {
21 AtomEdit { delete: range, insert: replace_with }
22 }
23
24 pub fn delete(range: TextRange) -> AtomEdit {
25 AtomEdit::replace(range, String::new())
26 }
27
28 pub fn insert(offset: TextUnit, text: String) -> AtomEdit {
29 AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text)
30 }
31}
32
33pub(crate) fn incremental_reparse(
34 node: SyntaxNodeRef,
35 edit: &AtomEdit,
36 errors: Vec<SyntaxError>,
37) -> Option<(GreenNode, Vec<SyntaxError>)> {
38 let (node, green, new_errors) =
39 reparse_leaf(node, &edit).or_else(|| reparse_block(node, &edit))?;
40 let green_root = node.replace_with(green);
41 let errors = merge_errors(errors, new_errors, node, edit);
42 Some((green_root, errors))
43}
44
45fn reparse_leaf<'node>(
46 node: SyntaxNodeRef<'node>,
47 edit: &AtomEdit,
48) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> {
49 let node = algo::find_covering_node(node, edit.delete);
50 match node.kind() {
51 | WHITESPACE
52 | COMMENT
53 | DOC_COMMENT
54 | IDENT
55 | STRING
56 | RAW_STRING => {
57 let text = get_text_after_edit(node, &edit);
58 let tokens = tokenize(&text);
59 let token = match tokens[..] {
60 [token] if token.kind == node.kind() => token,
61 _ => return None,
62 };
63
64 if token.kind == IDENT && is_contextual_kw(&text) {
65 return None;
66 }
67
68 let green = GreenNode::new_leaf(node.kind(), &text);
69 let new_errors = vec![];
70 Some((node, green, new_errors))
71 }
72 _ => None,
73 }
74}
75
76fn reparse_block<'node>(
77 node: SyntaxNodeRef<'node>,
78 edit: &AtomEdit,
79) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> {
80 let (node, reparser) = find_reparsable_node(node, edit.delete)?;
81 let text = get_text_after_edit(node, &edit);
82 let tokens = tokenize(&text);
83 if !is_balanced(&tokens) {
84 return None;
85 }
86 let (green, new_errors) =
87 parser_impl::parse_with::<yellow::GreenBuilder>(
88 &text, &tokens, reparser,
89 );
90 Some((node, green, new_errors))
91}
92
93fn get_text_after_edit(node: SyntaxNodeRef, edit: &AtomEdit) -> String {
94 replace_range(
95 node.text().to_string(),
96 edit.delete - node.range().start(),
97 &edit.insert,
98 )
99}
100
101fn is_contextual_kw(text: &str) -> bool {
102 match text {
103 | "auto"
104 | "default"
105 | "union" => true,
106 _ => false,
107 }
108}
109
110fn find_reparsable_node<'node>(
111 node: SyntaxNodeRef<'node>,
112 range: TextRange,
113) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> {
114 let node = algo::find_covering_node(node, range);
115 return algo::ancestors(node)
116 .filter_map(|node| reparser(node).map(|r| (node, r)))
117 .next();
118
119 fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> {
120 let res = match node.kind() {
121 BLOCK => grammar::block,
122 NAMED_FIELD_DEF_LIST => grammar::named_field_def_list,
123 NAMED_FIELD_LIST => grammar::named_field_list,
124 ENUM_VARIANT_LIST => grammar::enum_variant_list,
125 MATCH_ARM_LIST => grammar::match_arm_list,
126 USE_TREE_LIST => grammar::use_tree_list,
127 EXTERN_ITEM_LIST => grammar::extern_item_list,
128 TOKEN_TREE if node.first_child().unwrap().kind() == L_CURLY => grammar::token_tree,
129 ITEM_LIST => {
130 let parent = node.parent().unwrap();
131 match parent.kind() {
132 IMPL_ITEM => grammar::impl_item_list,
133 TRAIT_DEF => grammar::trait_item_list,
134 MODULE => grammar::mod_item_list,
135 _ => return None,
136 }
137 }
138 _ => return None,
139 };
140 Some(res)
141 }
142}
143
144fn is_balanced(tokens: &[Token]) -> bool {
145 if tokens.len() == 0
146 || tokens.first().unwrap().kind != L_CURLY
147 || tokens.last().unwrap().kind != R_CURLY {
148 return false;
149 }
150 let mut balance = 0usize;
151 for t in tokens.iter() {
152 match t.kind {
153 L_CURLY => balance += 1,
154 R_CURLY => balance = match balance.checked_sub(1) {
155 Some(b) => b,
156 None => return false,
157 },
158 _ => (),
159 }
160 }
161 balance == 0
162}
163
164fn merge_errors(
165 old_errors: Vec<SyntaxError>,
166 new_errors: Vec<SyntaxError>,
167 old_node: SyntaxNodeRef,
168 edit: &AtomEdit,
169) -> Vec<SyntaxError> {
170 let mut res = Vec::new();
171 for e in old_errors {
172 if e.offset <= old_node.range().start() {
173 res.push(e)
174 } else if e.offset >= old_node.range().end() {
175 res.push(SyntaxError {
176 msg: e.msg,
177 offset: e.offset + TextUnit::of_str(&edit.insert) - edit.delete.len(),
178 })
179 }
180 }
181 for e in new_errors {
182 res.push(SyntaxError {
183 msg: e.msg,
184 offset: e.offset + old_node.range().start(),
185 })
186 }
187 res
188}
189
190#[cfg(test)]
191mod tests {
192 use super::{
193 super::{
194 File,
195 test_utils::extract_range,
196 text_utils::replace_range,
197 utils::dump_tree,
198 },
199 reparse_leaf, reparse_block, AtomEdit, GreenNode, SyntaxError, SyntaxNodeRef,
200 };
201
202 fn do_check<F>(
203 before: &str,
204 replace_with: &str,
205 reparser: F,
206 ) where
207 for<'a> F: Fn(
208 SyntaxNodeRef<'a>,
209 &AtomEdit,
210 ) -> Option<(SyntaxNodeRef<'a>, GreenNode, Vec<SyntaxError>)>
211 {
212 let (range, before) = extract_range(before);
213 let after = replace_range(before.clone(), range, replace_with);
214
215 let fully_reparsed = File::parse(&after);
216 let incrementally_reparsed = {
217 let f = File::parse(&before);
218 let edit = AtomEdit { delete: range, insert: replace_with.to_string() };
219 let (node, green, new_errors) =
220 reparser(f.syntax(), &edit).expect("cannot incrementally reparse");
221 let green_root = node.replace_with(green);
222 let errors = super::merge_errors(f.errors(), new_errors, node, &edit);
223 File::new(green_root, errors)
224 };
225
226 assert_eq_text!(
227 &dump_tree(fully_reparsed.syntax()),
228 &dump_tree(incrementally_reparsed.syntax()),
229 )
230 }
231
232 #[test]
233 fn reparse_block_tests() {
234 let do_check = |before, replace_to|
235 do_check(before, replace_to, reparse_block);
236
237 do_check(r"
238fn foo() {
239 let x = foo + <|>bar<|>
240}
241", "baz");
242 do_check(r"
243fn foo() {
244 let x = foo<|> + bar<|>
245}
246", "baz");
247 do_check(r"
248struct Foo {
249 f: foo<|><|>
250}
251", ",\n g: (),");
252 do_check(r"
253fn foo {
254 let;
255 1 + 1;
256 <|>92<|>;
257}
258", "62");
259 do_check(r"
260mod foo {
261 fn <|><|>
262}
263", "bar");
264 do_check(r"
265trait Foo {
266 type <|>Foo<|>;
267}
268", "Output");
269 do_check(r"
270impl IntoIterator<Item=i32> for Foo {
271 f<|><|>
272}
273", "n next(");
274 do_check(r"
275use a::b::{foo,<|>,bar<|>};
276 ", "baz");
277 do_check(r"
278pub enum A {
279 Foo<|><|>
280}
281", "\nBar;\n");
282 do_check(r"
283foo!{a, b<|><|> d}
284", ", c[3]");
285 do_check(r"
286fn foo() {
287 vec![<|><|>]
288}
289", "123");
290 do_check(r"
291extern {
292 fn<|>;<|>
293}
294", " exit(code: c_int)");
295 }
296
297 #[test]
298 fn reparse_leaf_tests() {
299 let do_check = |before, replace_to|
300 do_check(before, replace_to, reparse_leaf);
301
302 do_check(r"<|><|>
303fn foo() -> i32 { 1 }
304", "\n\n\n \n");
305 do_check(r"
306fn foo() -> <|><|> {}
307", " \n");
308 do_check(r"
309fn <|>foo<|>() -> i32 { 1 }
310", "bar");
311 do_check(r"
312fn foo<|><|>foo() { }
313", "bar");
314 do_check(r"
315fn foo /* <|><|> */ () {}
316", "some comment");
317 do_check(r"
318fn baz <|><|> () {}
319", " \t\t\n\n");
320 do_check(r"
321fn baz <|><|> () {}
322", " \t\t\n\n");
323 do_check(r"
324/// foo <|><|>omment
325mod { }
326", "c");
327 do_check(r#"
328fn -> &str { "Hello<|><|>" }
329"#, ", world");
330 do_check(r#"
331fn -> &str { // "Hello<|><|>"
332"#, ", world");
333 do_check(r##"
334fn -> &str { r#"Hello<|><|>"#
335"##, ", world");
336 do_check(r"
337#[derive(<|>Copy<|>)]
338enum Foo {
339
340}
341", "Clone");
342 }
343} \ No newline at end of file
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs
new file mode 100644
index 000000000..7882bded9
--- /dev/null
+++ b/crates/ra_syntax/src/syntax_kinds/generated.rs
@@ -0,0 +1,562 @@
1#![allow(bad_style, missing_docs, unreachable_pub)]
2#![cfg_attr(rustfmt, rustfmt_skip)]
3use super::SyntaxInfo;
4
5/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
6#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub enum SyntaxKind {
8 // Technical SyntaxKinds: they appear temporally during parsing,
9 // but never end up in the final tree
10 #[doc(hidden)]
11 TOMBSTONE,
12 #[doc(hidden)]
13 EOF,
14 SEMI,
15 COMMA,
16 L_PAREN,
17 R_PAREN,
18 L_CURLY,
19 R_CURLY,
20 L_BRACK,
21 R_BRACK,
22 L_ANGLE,
23 R_ANGLE,
24 AT,
25 POUND,
26 TILDE,
27 QUESTION,
28 DOLLAR,
29 AMP,
30 PIPE,
31 PLUS,
32 STAR,
33 SLASH,
34 CARET,
35 PERCENT,
36 DOT,
37 DOTDOT,
38 DOTDOTDOT,
39 DOTDOTEQ,
40 COLON,
41 COLONCOLON,
42 EQ,
43 EQEQ,
44 FAT_ARROW,
45 EXCL,
46 NEQ,
47 MINUS,
48 THIN_ARROW,
49 LTEQ,
50 GTEQ,
51 PLUSEQ,
52 MINUSEQ,
53 PIPEEQ,
54 AMPEQ,
55 CARETEQ,
56 SLASHEQ,
57 STAREQ,
58 AMPAMP,
59 PIPEPIPE,
60 SHL,
61 SHR,
62 SHLEQ,
63 SHREQ,
64 USE_KW,
65 FN_KW,
66 STRUCT_KW,
67 ENUM_KW,
68 TRAIT_KW,
69 IMPL_KW,
70 DYN_KW,
71 TRUE_KW,
72 FALSE_KW,
73 AS_KW,
74 EXTERN_KW,
75 CRATE_KW,
76 MOD_KW,
77 PUB_KW,
78 SELF_KW,
79 SUPER_KW,
80 IN_KW,
81 WHERE_KW,
82 FOR_KW,
83 LOOP_KW,
84 WHILE_KW,
85 CONTINUE_KW,
86 BREAK_KW,
87 IF_KW,
88 ELSE_KW,
89 MATCH_KW,
90 CONST_KW,
91 STATIC_KW,
92 MUT_KW,
93 UNSAFE_KW,
94 TYPE_KW,
95 REF_KW,
96 LET_KW,
97 MOVE_KW,
98 RETURN_KW,
99 AUTO_KW,
100 DEFAULT_KW,
101 UNION_KW,
102 ERROR,
103 IDENT,
104 UNDERSCORE,
105 WHITESPACE,
106 INT_NUMBER,
107 FLOAT_NUMBER,
108 LIFETIME,
109 CHAR,
110 BYTE,
111 STRING,
112 RAW_STRING,
113 BYTE_STRING,
114 RAW_BYTE_STRING,
115 COMMENT,
116 DOC_COMMENT,
117 SHEBANG,
118 ROOT,
119 STRUCT_DEF,
120 ENUM_DEF,
121 FN_DEF,
122 RET_TYPE,
123 EXTERN_CRATE_ITEM,
124 MODULE,
125 USE_ITEM,
126 STATIC_DEF,
127 CONST_DEF,
128 TRAIT_DEF,
129 IMPL_ITEM,
130 TYPE_DEF,
131 MACRO_CALL,
132 TOKEN_TREE,
133 PAREN_TYPE,
134 TUPLE_TYPE,
135 NEVER_TYPE,
136 PATH_TYPE,
137 POINTER_TYPE,
138 ARRAY_TYPE,
139 SLICE_TYPE,
140 REFERENCE_TYPE,
141 PLACEHOLDER_TYPE,
142 FN_POINTER_TYPE,
143 FOR_TYPE,
144 IMPL_TRAIT_TYPE,
145 DYN_TRAIT_TYPE,
146 REF_PAT,
147 BIND_PAT,
148 PLACEHOLDER_PAT,
149 PATH_PAT,
150 STRUCT_PAT,
151 FIELD_PAT_LIST,
152 TUPLE_STRUCT_PAT,
153 TUPLE_PAT,
154 SLICE_PAT,
155 RANGE_PAT,
156 TUPLE_EXPR,
157 ARRAY_EXPR,
158 PAREN_EXPR,
159 PATH_EXPR,
160 LAMBDA_EXPR,
161 IF_EXPR,
162 WHILE_EXPR,
163 CONDITION,
164 LOOP_EXPR,
165 FOR_EXPR,
166 CONTINUE_EXPR,
167 BREAK_EXPR,
168 LABEL,
169 BLOCK_EXPR,
170 RETURN_EXPR,
171 MATCH_EXPR,
172 MATCH_ARM_LIST,
173 MATCH_ARM,
174 MATCH_GUARD,
175 STRUCT_LIT,
176 NAMED_FIELD_LIST,
177 NAMED_FIELD,
178 CALL_EXPR,
179 INDEX_EXPR,
180 METHOD_CALL_EXPR,
181 FIELD_EXPR,
182 TRY_EXPR,
183 CAST_EXPR,
184 REF_EXPR,
185 PREFIX_EXPR,
186 RANGE_EXPR,
187 BIN_EXPR,
188 BLOCK,
189 EXTERN_BLOCK,
190 EXTERN_ITEM_LIST,
191 ENUM_VARIANT,
192 NAMED_FIELD_DEF_LIST,
193 NAMED_FIELD_DEF,
194 POS_FIELD_LIST,
195 POS_FIELD,
196 ENUM_VARIANT_LIST,
197 ITEM_LIST,
198 ATTR,
199 META_ITEM,
200 USE_TREE,
201 USE_TREE_LIST,
202 PATH,
203 PATH_SEGMENT,
204 LITERAL,
205 ALIAS,
206 VISIBILITY,
207 WHERE_CLAUSE,
208 WHERE_PRED,
209 ABI,
210 NAME,
211 NAME_REF,
212 LET_STMT,
213 EXPR_STMT,
214 TYPE_PARAM_LIST,
215 LIFETIME_PARAM,
216 TYPE_PARAM,
217 TYPE_ARG_LIST,
218 LIFETIME_ARG,
219 TYPE_ARG,
220 ASSOC_TYPE_ARG,
221 PARAM_LIST,
222 PARAM,
223 SELF_PARAM,
224 ARG_LIST,
225}
226use self::SyntaxKind::*;
227
228impl SyntaxKind {
229 pub fn is_keyword(self) -> bool {
230 match self {
231 | USE_KW
232 | FN_KW
233 | STRUCT_KW
234 | ENUM_KW
235 | TRAIT_KW
236 | IMPL_KW
237 | DYN_KW
238 | TRUE_KW
239 | FALSE_KW
240 | AS_KW
241 | EXTERN_KW
242 | CRATE_KW
243 | MOD_KW
244 | PUB_KW
245 | SELF_KW
246 | SUPER_KW
247 | IN_KW
248 | WHERE_KW
249 | FOR_KW
250 | LOOP_KW
251 | WHILE_KW
252 | CONTINUE_KW
253 | BREAK_KW
254 | IF_KW
255 | ELSE_KW
256 | MATCH_KW
257 | CONST_KW
258 | STATIC_KW
259 | MUT_KW
260 | UNSAFE_KW
261 | TYPE_KW
262 | REF_KW
263 | LET_KW
264 | MOVE_KW
265 | RETURN_KW
266 | AUTO_KW
267 | DEFAULT_KW
268 | UNION_KW
269 => true,
270 _ => false
271 }
272 }
273
274 pub(crate) fn info(self) -> &'static SyntaxInfo {
275 match self {
276 SEMI => &SyntaxInfo { name: "SEMI" },
277 COMMA => &SyntaxInfo { name: "COMMA" },
278 L_PAREN => &SyntaxInfo { name: "L_PAREN" },
279 R_PAREN => &SyntaxInfo { name: "R_PAREN" },
280 L_CURLY => &SyntaxInfo { name: "L_CURLY" },
281 R_CURLY => &SyntaxInfo { name: "R_CURLY" },
282 L_BRACK => &SyntaxInfo { name: "L_BRACK" },
283 R_BRACK => &SyntaxInfo { name: "R_BRACK" },
284 L_ANGLE => &SyntaxInfo { name: "L_ANGLE" },
285 R_ANGLE => &SyntaxInfo { name: "R_ANGLE" },
286 AT => &SyntaxInfo { name: "AT" },
287 POUND => &SyntaxInfo { name: "POUND" },
288 TILDE => &SyntaxInfo { name: "TILDE" },
289 QUESTION => &SyntaxInfo { name: "QUESTION" },
290 DOLLAR => &SyntaxInfo { name: "DOLLAR" },
291 AMP => &SyntaxInfo { name: "AMP" },
292 PIPE => &SyntaxInfo { name: "PIPE" },
293 PLUS => &SyntaxInfo { name: "PLUS" },
294 STAR => &SyntaxInfo { name: "STAR" },
295 SLASH => &SyntaxInfo { name: "SLASH" },
296 CARET => &SyntaxInfo { name: "CARET" },
297 PERCENT => &SyntaxInfo { name: "PERCENT" },
298 DOT => &SyntaxInfo { name: "DOT" },
299 DOTDOT => &SyntaxInfo { name: "DOTDOT" },
300 DOTDOTDOT => &SyntaxInfo { name: "DOTDOTDOT" },
301 DOTDOTEQ => &SyntaxInfo { name: "DOTDOTEQ" },
302 COLON => &SyntaxInfo { name: "COLON" },
303 COLONCOLON => &SyntaxInfo { name: "COLONCOLON" },
304 EQ => &SyntaxInfo { name: "EQ" },
305 EQEQ => &SyntaxInfo { name: "EQEQ" },
306 FAT_ARROW => &SyntaxInfo { name: "FAT_ARROW" },
307 EXCL => &SyntaxInfo { name: "EXCL" },
308 NEQ => &SyntaxInfo { name: "NEQ" },
309 MINUS => &SyntaxInfo { name: "MINUS" },
310 THIN_ARROW => &SyntaxInfo { name: "THIN_ARROW" },
311 LTEQ => &SyntaxInfo { name: "LTEQ" },
312 GTEQ => &SyntaxInfo { name: "GTEQ" },
313 PLUSEQ => &SyntaxInfo { name: "PLUSEQ" },
314 MINUSEQ => &SyntaxInfo { name: "MINUSEQ" },
315 PIPEEQ => &SyntaxInfo { name: "PIPEEQ" },
316 AMPEQ => &SyntaxInfo { name: "AMPEQ" },
317 CARETEQ => &SyntaxInfo { name: "CARETEQ" },
318 SLASHEQ => &SyntaxInfo { name: "SLASHEQ" },
319 STAREQ => &SyntaxInfo { name: "STAREQ" },
320 AMPAMP => &SyntaxInfo { name: "AMPAMP" },
321 PIPEPIPE => &SyntaxInfo { name: "PIPEPIPE" },
322 SHL => &SyntaxInfo { name: "SHL" },
323 SHR => &SyntaxInfo { name: "SHR" },
324 SHLEQ => &SyntaxInfo { name: "SHLEQ" },
325 SHREQ => &SyntaxInfo { name: "SHREQ" },
326 USE_KW => &SyntaxInfo { name: "USE_KW" },
327 FN_KW => &SyntaxInfo { name: "FN_KW" },
328 STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" },
329 ENUM_KW => &SyntaxInfo { name: "ENUM_KW" },
330 TRAIT_KW => &SyntaxInfo { name: "TRAIT_KW" },
331 IMPL_KW => &SyntaxInfo { name: "IMPL_KW" },
332 DYN_KW => &SyntaxInfo { name: "DYN_KW" },
333 TRUE_KW => &SyntaxInfo { name: "TRUE_KW" },
334 FALSE_KW => &SyntaxInfo { name: "FALSE_KW" },
335 AS_KW => &SyntaxInfo { name: "AS_KW" },
336 EXTERN_KW => &SyntaxInfo { name: "EXTERN_KW" },
337 CRATE_KW => &SyntaxInfo { name: "CRATE_KW" },
338 MOD_KW => &SyntaxInfo { name: "MOD_KW" },
339 PUB_KW => &SyntaxInfo { name: "PUB_KW" },
340 SELF_KW => &SyntaxInfo { name: "SELF_KW" },
341 SUPER_KW => &SyntaxInfo { name: "SUPER_KW" },
342 IN_KW => &SyntaxInfo { name: "IN_KW" },
343 WHERE_KW => &SyntaxInfo { name: "WHERE_KW" },
344 FOR_KW => &SyntaxInfo { name: "FOR_KW" },
345 LOOP_KW => &SyntaxInfo { name: "LOOP_KW" },
346 WHILE_KW => &SyntaxInfo { name: "WHILE_KW" },
347 CONTINUE_KW => &SyntaxInfo { name: "CONTINUE_KW" },
348 BREAK_KW => &SyntaxInfo { name: "BREAK_KW" },
349 IF_KW => &SyntaxInfo { name: "IF_KW" },
350 ELSE_KW => &SyntaxInfo { name: "ELSE_KW" },
351 MATCH_KW => &SyntaxInfo { name: "MATCH_KW" },
352 CONST_KW => &SyntaxInfo { name: "CONST_KW" },
353 STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
354 MUT_KW => &SyntaxInfo { name: "MUT_KW" },
355 UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
356 TYPE_KW => &SyntaxInfo { name: "TYPE_KW" },
357 REF_KW => &SyntaxInfo { name: "REF_KW" },
358 LET_KW => &SyntaxInfo { name: "LET_KW" },
359 MOVE_KW => &SyntaxInfo { name: "MOVE_KW" },
360 RETURN_KW => &SyntaxInfo { name: "RETURN_KW" },
361 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
362 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
363 UNION_KW => &SyntaxInfo { name: "UNION_KW" },
364 ERROR => &SyntaxInfo { name: "ERROR" },
365 IDENT => &SyntaxInfo { name: "IDENT" },
366 UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" },
367 WHITESPACE => &SyntaxInfo { name: "WHITESPACE" },
368 INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" },
369 FLOAT_NUMBER => &SyntaxInfo { name: "FLOAT_NUMBER" },
370 LIFETIME => &SyntaxInfo { name: "LIFETIME" },
371 CHAR => &SyntaxInfo { name: "CHAR" },
372 BYTE => &SyntaxInfo { name: "BYTE" },
373 STRING => &SyntaxInfo { name: "STRING" },
374 RAW_STRING => &SyntaxInfo { name: "RAW_STRING" },
375 BYTE_STRING => &SyntaxInfo { name: "BYTE_STRING" },
376 RAW_BYTE_STRING => &SyntaxInfo { name: "RAW_BYTE_STRING" },
377 COMMENT => &SyntaxInfo { name: "COMMENT" },
378 DOC_COMMENT => &SyntaxInfo { name: "DOC_COMMENT" },
379 SHEBANG => &SyntaxInfo { name: "SHEBANG" },
380 ROOT => &SyntaxInfo { name: "ROOT" },
381 STRUCT_DEF => &SyntaxInfo { name: "STRUCT_DEF" },
382 ENUM_DEF => &SyntaxInfo { name: "ENUM_DEF" },
383 FN_DEF => &SyntaxInfo { name: "FN_DEF" },
384 RET_TYPE => &SyntaxInfo { name: "RET_TYPE" },
385 EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" },
386 MODULE => &SyntaxInfo { name: "MODULE" },
387 USE_ITEM => &SyntaxInfo { name: "USE_ITEM" },
388 STATIC_DEF => &SyntaxInfo { name: "STATIC_DEF" },
389 CONST_DEF => &SyntaxInfo { name: "CONST_DEF" },
390 TRAIT_DEF => &SyntaxInfo { name: "TRAIT_DEF" },
391 IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" },
392 TYPE_DEF => &SyntaxInfo { name: "TYPE_DEF" },
393 MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" },
394 TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" },
395 PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" },
396 TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" },
397 NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" },
398 PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" },
399 POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" },
400 ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" },
401 SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" },
402 REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" },
403 PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" },
404 FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" },
405 FOR_TYPE => &SyntaxInfo { name: "FOR_TYPE" },
406 IMPL_TRAIT_TYPE => &SyntaxInfo { name: "IMPL_TRAIT_TYPE" },
407 DYN_TRAIT_TYPE => &SyntaxInfo { name: "DYN_TRAIT_TYPE" },
408 REF_PAT => &SyntaxInfo { name: "REF_PAT" },
409 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
410 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
411 PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
412 STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
413 FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" },
414 TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
415 TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
416 SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },
417 RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" },
418 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
419 ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" },
420 PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" },
421 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
422 LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" },
423 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
424 WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
425 CONDITION => &SyntaxInfo { name: "CONDITION" },
426 LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" },
427 FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" },
428 CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" },
429 BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" },
430 LABEL => &SyntaxInfo { name: "LABEL" },
431 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
432 RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
433 MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
434 MATCH_ARM_LIST => &SyntaxInfo { name: "MATCH_ARM_LIST" },
435 MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" },
436 MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" },
437 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" },
438 NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" },
439 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
440 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },
441 INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" },
442 METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" },
443 FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" },
444 TRY_EXPR => &SyntaxInfo { name: "TRY_EXPR" },
445 CAST_EXPR => &SyntaxInfo { name: "CAST_EXPR" },
446 REF_EXPR => &SyntaxInfo { name: "REF_EXPR" },
447 PREFIX_EXPR => &SyntaxInfo { name: "PREFIX_EXPR" },
448 RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" },
449 BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" },
450 BLOCK => &SyntaxInfo { name: "BLOCK" },
451 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
452 EXTERN_ITEM_LIST => &SyntaxInfo { name: "EXTERN_ITEM_LIST" },
453 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
454 NAMED_FIELD_DEF_LIST => &SyntaxInfo { name: "NAMED_FIELD_DEF_LIST" },
455 NAMED_FIELD_DEF => &SyntaxInfo { name: "NAMED_FIELD_DEF" },
456 POS_FIELD_LIST => &SyntaxInfo { name: "POS_FIELD_LIST" },
457 POS_FIELD => &SyntaxInfo { name: "POS_FIELD" },
458 ENUM_VARIANT_LIST => &SyntaxInfo { name: "ENUM_VARIANT_LIST" },
459 ITEM_LIST => &SyntaxInfo { name: "ITEM_LIST" },
460 ATTR => &SyntaxInfo { name: "ATTR" },
461 META_ITEM => &SyntaxInfo { name: "META_ITEM" },
462 USE_TREE => &SyntaxInfo { name: "USE_TREE" },
463 USE_TREE_LIST => &SyntaxInfo { name: "USE_TREE_LIST" },
464 PATH => &SyntaxInfo { name: "PATH" },
465 PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" },
466 LITERAL => &SyntaxInfo { name: "LITERAL" },
467 ALIAS => &SyntaxInfo { name: "ALIAS" },
468 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
469 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
470 WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" },
471 ABI => &SyntaxInfo { name: "ABI" },
472 NAME => &SyntaxInfo { name: "NAME" },
473 NAME_REF => &SyntaxInfo { name: "NAME_REF" },
474 LET_STMT => &SyntaxInfo { name: "LET_STMT" },
475 EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" },
476 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
477 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
478 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
479 TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" },
480 LIFETIME_ARG => &SyntaxInfo { name: "LIFETIME_ARG" },
481 TYPE_ARG => &SyntaxInfo { name: "TYPE_ARG" },
482 ASSOC_TYPE_ARG => &SyntaxInfo { name: "ASSOC_TYPE_ARG" },
483 PARAM_LIST => &SyntaxInfo { name: "PARAM_LIST" },
484 PARAM => &SyntaxInfo { name: "PARAM" },
485 SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" },
486 ARG_LIST => &SyntaxInfo { name: "ARG_LIST" },
487 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
488 EOF => &SyntaxInfo { name: "EOF" },
489 }
490 }
491 pub(crate) fn from_keyword(ident: &str) -> Option<SyntaxKind> {
492 let kw = match ident {
493 "use" => USE_KW,
494 "fn" => FN_KW,
495 "struct" => STRUCT_KW,
496 "enum" => ENUM_KW,
497 "trait" => TRAIT_KW,
498 "impl" => IMPL_KW,
499 "dyn" => DYN_KW,
500 "true" => TRUE_KW,
501 "false" => FALSE_KW,
502 "as" => AS_KW,
503 "extern" => EXTERN_KW,
504 "crate" => CRATE_KW,
505 "mod" => MOD_KW,
506 "pub" => PUB_KW,
507 "self" => SELF_KW,
508 "super" => SUPER_KW,
509 "in" => IN_KW,
510 "where" => WHERE_KW,
511 "for" => FOR_KW,
512 "loop" => LOOP_KW,
513 "while" => WHILE_KW,
514 "continue" => CONTINUE_KW,
515 "break" => BREAK_KW,
516 "if" => IF_KW,
517 "else" => ELSE_KW,
518 "match" => MATCH_KW,
519 "const" => CONST_KW,
520 "static" => STATIC_KW,
521 "mut" => MUT_KW,
522 "unsafe" => UNSAFE_KW,
523 "type" => TYPE_KW,
524 "ref" => REF_KW,
525 "let" => LET_KW,
526 "move" => MOVE_KW,
527 "return" => RETURN_KW,
528 _ => return None,
529 };
530 Some(kw)
531 }
532
533 pub(crate) fn from_char(c: char) -> Option<SyntaxKind> {
534 let tok = match c {
535 ';' => SEMI,
536 ',' => COMMA,
537 '(' => L_PAREN,
538 ')' => R_PAREN,
539 '{' => L_CURLY,
540 '}' => R_CURLY,
541 '[' => L_BRACK,
542 ']' => R_BRACK,
543 '<' => L_ANGLE,
544 '>' => R_ANGLE,
545 '@' => AT,
546 '#' => POUND,
547 '~' => TILDE,
548 '?' => QUESTION,
549 '$' => DOLLAR,
550 '&' => AMP,
551 '|' => PIPE,
552 '+' => PLUS,
553 '*' => STAR,
554 '/' => SLASH,
555 '^' => CARET,
556 '%' => PERCENT,
557 _ => return None,
558 };
559 Some(tok)
560 }
561}
562
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs.tera b/crates/ra_syntax/src/syntax_kinds/generated.rs.tera
new file mode 100644
index 000000000..90618721a
--- /dev/null
+++ b/crates/ra_syntax/src/syntax_kinds/generated.rs.tera
@@ -0,0 +1,73 @@
1#![allow(bad_style, missing_docs, unreachable_pub)]
2#![cfg_attr(rustfmt, rustfmt_skip)]
3use super::SyntaxInfo;
4
5/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
6#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub enum SyntaxKind {
8 // Technical SyntaxKinds: they appear temporally during parsing,
9 // but never end up in the final tree
10 #[doc(hidden)]
11 TOMBSTONE,
12 #[doc(hidden)]
13 EOF,
14
15{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
16 {{t.1}},
17{%- endfor -%}
18{% for kw in concat(a=keywords, b=contextual_keywords) %}
19 {{kw | upper}}_KW,
20{%- endfor -%}
21{% for t in concat(a=tokens, b=nodes) %}
22 {{t}},
23{%- endfor %}
24}
25use self::SyntaxKind::*;
26
27impl SyntaxKind {
28 pub fn is_keyword(self) -> bool {
29 match self {
30{%- for kw in concat(a=keywords, b=contextual_keywords) %}
31 | {{kw | upper}}_KW
32{%- endfor %}
33 => true,
34 _ => false
35 }
36 }
37
38 pub(crate) fn info(self) -> &'static SyntaxInfo {
39 match self {
40{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
41 {{t.1}} => &SyntaxInfo { name: "{{t.1}}" },
42{%- endfor -%}
43{% for kw in concat(a=keywords, b=contextual_keywords) %}
44 {{kw | upper}}_KW => &SyntaxInfo { name: "{{kw | upper}}_KW" },
45{%- endfor -%}
46{% for t in concat(a=tokens, b=nodes) %}
47 {{t}} => &SyntaxInfo { name: "{{t}}" },
48{%- endfor %}
49 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
50 EOF => &SyntaxInfo { name: "EOF" },
51 }
52 }
53 pub(crate) fn from_keyword(ident: &str) -> Option<SyntaxKind> {
54 let kw = match ident {
55{%- for kw in keywords %}
56 "{{kw}}" => {{kw | upper}}_KW,
57{%- endfor %}
58 _ => return None,
59 };
60 Some(kw)
61 }
62
63 pub(crate) fn from_char(c: char) -> Option<SyntaxKind> {
64 let tok = match c {
65{%- for t in single_byte_tokens %}
66 '{{t.0}}' => {{t.1}},
67{%- endfor %}
68 _ => return None,
69 };
70 Some(tok)
71 }
72}
73
diff --git a/crates/ra_syntax/src/syntax_kinds/mod.rs b/crates/ra_syntax/src/syntax_kinds/mod.rs
new file mode 100644
index 000000000..332cd13ac
--- /dev/null
+++ b/crates/ra_syntax/src/syntax_kinds/mod.rs
@@ -0,0 +1,26 @@
1mod generated;
2
3use std::fmt;
4use SyntaxKind::*;
5
6pub use self::generated::SyntaxKind;
7
8impl fmt::Debug for SyntaxKind {
9 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10 let name = self.info().name;
11 f.write_str(name)
12 }
13}
14
15pub(crate) struct SyntaxInfo {
16 pub name: &'static str,
17}
18
19impl SyntaxKind {
20 pub fn is_trivia(self) -> bool {
21 match self {
22 WHITESPACE | COMMENT | DOC_COMMENT => true,
23 _ => false,
24 }
25 }
26}
diff --git a/crates/ra_syntax/src/text_utils.rs b/crates/ra_syntax/src/text_utils.rs
new file mode 100644
index 000000000..58ae1e43e
--- /dev/null
+++ b/crates/ra_syntax/src/text_utils.rs
@@ -0,0 +1,26 @@
1use {TextRange, TextUnit};
2
3pub fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool {
4 range.start() <= offset && offset <= range.end()
5}
6
7pub fn is_subrange(range: TextRange, subrange: TextRange) -> bool {
8 range.start() <= subrange.start() && subrange.end() <= range.end()
9}
10
11pub fn intersect(r1: TextRange, r2: TextRange) -> Option<TextRange> {
12 let start = r1.start().max(r2.start());
13 let end = r1.end().min(r2.end());
14 if start <= end {
15 Some(TextRange::from_to(start, end))
16 } else {
17 None
18 }
19}
20
21pub fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String {
22 let start = u32::from(range.start()) as usize;
23 let end = u32::from(range.end()) as usize;
24 text.replace_range(start..end, replace_with);
25 text
26} \ No newline at end of file
diff --git a/crates/ra_syntax/src/token_set.rs b/crates/ra_syntax/src/token_set.rs
new file mode 100644
index 000000000..c83fba81b
--- /dev/null
+++ b/crates/ra_syntax/src/token_set.rs
@@ -0,0 +1,37 @@
1use SyntaxKind;
2
3#[derive(Clone, Copy)]
4pub(crate) struct TokenSet(pub(crate) u128);
5
6fn mask(kind: SyntaxKind) -> u128 {
7 1u128 << (kind as usize)
8}
9
10impl TokenSet {
11 pub const EMPTY: TokenSet = TokenSet(0);
12
13 pub fn contains(&self, kind: SyntaxKind) -> bool {
14 self.0 & mask(kind) != 0
15 }
16}
17
18#[macro_export]
19macro_rules! token_set {
20 ($($t:ident),*) => { TokenSet($(1u128 << ($t as usize))|*) };
21 ($($t:ident),* ,) => { token_set!($($t),*) };
22}
23
24#[macro_export]
25macro_rules! token_set_union {
26 ($($ts:expr),*) => { TokenSet($($ts.0)|*) };
27 ($($ts:expr),* ,) => { token_set_union!($($ts),*) };
28}
29
30#[test]
31fn token_set_works_for_tokens() {
32 use SyntaxKind::*;
33 let ts = token_set! { EOF, SHEBANG };
34 assert!(ts.contains(EOF));
35 assert!(ts.contains(SHEBANG));
36 assert!(!ts.contains(PLUS));
37}
diff --git a/crates/ra_syntax/src/utils.rs b/crates/ra_syntax/src/utils.rs
new file mode 100644
index 000000000..671dd7afa
--- /dev/null
+++ b/crates/ra_syntax/src/utils.rs
@@ -0,0 +1,85 @@
1use std::fmt::Write;
2use {
3 algo::walk::{preorder, walk, WalkEvent},
4 SyntaxKind, File, SyntaxNodeRef, TreeRoot,
5};
6
7/// Parse a file and create a string representation of the resulting parse tree.
8pub fn dump_tree(syntax: SyntaxNodeRef) -> String {
9 let mut errors: Vec<_> = syntax.root.syntax_root().errors.iter().cloned().collect();
10 errors.sort_by_key(|e| e.offset);
11 let mut err_pos = 0;
12 let mut level = 0;
13 let mut buf = String::new();
14 macro_rules! indent {
15 () => {
16 for _ in 0..level {
17 buf.push_str(" ");
18 }
19 };
20 }
21
22 for event in walk(syntax) {
23 match event {
24 WalkEvent::Enter(node) => {
25 indent!();
26 writeln!(buf, "{:?}", node).unwrap();
27 if node.first_child().is_none() {
28 let off = node.range().end();
29 while err_pos < errors.len() && errors[err_pos].offset <= off {
30 indent!();
31 writeln!(buf, "err: `{}`", errors[err_pos].msg).unwrap();
32 err_pos += 1;
33 }
34 }
35 level += 1;
36 }
37 WalkEvent::Exit(_) => level -= 1,
38 }
39 }
40
41 assert_eq!(level, 0);
42 for err in errors[err_pos..].iter() {
43 writeln!(buf, "err: `{}`", err.msg).unwrap();
44 }
45
46 return buf;
47}
48
49pub fn check_fuzz_invariants(text: &str) {
50 let file = File::parse(text);
51 let root = file.syntax();
52 validate_block_structure(root);
53 let _ = file.ast();
54 let _ = file.errors();
55}
56
57pub(crate) fn validate_block_structure(root: SyntaxNodeRef) {
58 let mut stack = Vec::new();
59 for node in preorder(root) {
60 match node.kind() {
61 SyntaxKind::L_CURLY => {
62 stack.push(node)
63 }
64 SyntaxKind::R_CURLY => {
65 if let Some(pair) = stack.pop() {
66 assert_eq!(
67 node.parent(),
68 pair.parent(),
69 "\nunpaired curleys:\n{}\n{}\n",
70 root.text(),
71 dump_tree(root),
72 );
73 assert!(
74 node.next_sibling().is_none() && pair.prev_sibling().is_none(),
75 "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n",
76 node,
77 root.text(),
78 node.text(),
79 );
80 }
81 }
82 _ => (),
83 }
84 }
85}
diff --git a/crates/ra_syntax/src/yellow/builder.rs b/crates/ra_syntax/src/yellow/builder.rs
new file mode 100644
index 000000000..e4ab37899
--- /dev/null
+++ b/crates/ra_syntax/src/yellow/builder.rs
@@ -0,0 +1,64 @@
1use {
2 parser_impl::Sink,
3 yellow::{GreenNode, SyntaxError},
4 SyntaxKind, TextRange, TextUnit,
5};
6
7pub(crate) struct GreenBuilder<'a> {
8 text: &'a str,
9 parents: Vec<(SyntaxKind, usize)>,
10 children: Vec<GreenNode>,
11 pos: TextUnit,
12 errors: Vec<SyntaxError>,
13}
14
15impl<'a> Sink<'a> for GreenBuilder<'a> {
16 type Tree = (GreenNode, Vec<SyntaxError>);
17
18 fn new(text: &'a str) -> Self {
19 GreenBuilder {
20 text,
21 parents: Vec::new(),
22 children: Vec::new(),
23 pos: 0.into(),
24 errors: Vec::new(),
25 }
26 }
27
28 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
29 let range = TextRange::offset_len(self.pos, len);
30 self.pos += len;
31 let text = &self.text[range];
32 self.children.push(
33 GreenNode::new_leaf(kind, text)
34 );
35 }
36
37 fn start_internal(&mut self, kind: SyntaxKind) {
38 let len = self.children.len();
39 self.parents.push((kind, len));
40 }
41
42 fn finish_internal(&mut self) {
43 let (kind, first_child) = self.parents.pop().unwrap();
44 let children: Vec<_> = self.children
45 .drain(first_child..)
46 .collect();
47 self.children.push(
48 GreenNode::new_branch(kind, children.into_boxed_slice())
49 );
50 }
51
52 fn error(&mut self, message: String) {
53 self.errors.push(SyntaxError {
54 msg: message,
55 offset: self.pos,
56 })
57 }
58
59 fn finish(mut self) -> (GreenNode, Vec<SyntaxError>) {
60 assert_eq!(self.children.len(), 1);
61 let root = self.children.pop().unwrap();
62 (root, self.errors)
63 }
64}
diff --git a/crates/ra_syntax/src/yellow/green.rs b/crates/ra_syntax/src/yellow/green.rs
new file mode 100644
index 000000000..8fb691643
--- /dev/null
+++ b/crates/ra_syntax/src/yellow/green.rs
@@ -0,0 +1,90 @@
1use std::sync::Arc;
2
3use smol_str::SmolStr;
4
5use {SyntaxKind, TextUnit};
6
7#[derive(Clone, Debug)]
8pub(crate) enum GreenNode {
9 Leaf {
10 kind: SyntaxKind,
11 text: SmolStr,
12 },
13 Branch(Arc<GreenBranch>),
14}
15
16impl GreenNode {
17 pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
18 GreenNode::Leaf { kind, text: SmolStr::new(text) }
19 }
20
21 pub(crate) fn new_branch(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenNode {
22 GreenNode::Branch(Arc::new(GreenBranch::new(kind, children)))
23 }
24
25 pub fn kind(&self) -> SyntaxKind {
26 match self {
27 GreenNode::Leaf { kind, .. } => *kind,
28 GreenNode::Branch(b) => b.kind(),
29 }
30 }
31
32 pub fn text_len(&self) -> TextUnit {
33 match self {
34 GreenNode::Leaf { text, .. } => TextUnit::from(text.len() as u32),
35 GreenNode::Branch(b) => b.text_len(),
36 }
37 }
38
39 pub fn children(&self) -> &[GreenNode] {
40 match self {
41 GreenNode::Leaf { .. } => &[],
42 GreenNode::Branch(b) => b.children(),
43 }
44 }
45
46 pub fn leaf_text_ref(&self) -> Option<&SmolStr> {
47 match self {
48 GreenNode::Leaf { text, .. } => Some(text),
49 GreenNode::Branch(_) => None,
50 }
51 }
52}
53
54#[derive(Clone, Debug)]
55pub(crate) struct GreenBranch {
56 text_len: TextUnit,
57 kind: SyntaxKind,
58 children: Box<[GreenNode]>,
59}
60
61impl GreenBranch {
62 fn new(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenBranch {
63 let text_len = children.iter().map(|x| x.text_len()).sum::<TextUnit>();
64 GreenBranch {
65 text_len,
66 kind,
67 children,
68 }
69 }
70
71 pub fn kind(&self) -> SyntaxKind {
72 self.kind
73 }
74
75 pub fn text_len(&self) -> TextUnit {
76 self.text_len
77 }
78
79 pub fn children(&self) -> &[GreenNode] {
80 &*self.children
81 }
82}
83
84#[test]
85fn test_sizes() {
86 use std::mem::size_of;
87 println!("GreenBranch = {}", size_of::<GreenBranch>());
88 println!("GreenNode = {}", size_of::<GreenNode>());
89 println!("SmolStr = {}", size_of::<SmolStr>());
90}
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs
new file mode 100644
index 000000000..0596e702f
--- /dev/null
+++ b/crates/ra_syntax/src/yellow/mod.rs
@@ -0,0 +1,100 @@
1mod builder;
2mod green;
3mod red;
4mod syntax;
5mod syntax_text;
6
7use std::{
8 sync::Arc,
9 ptr,
10};
11pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren};
12pub(crate) use self::{
13 builder::GreenBuilder,
14 green::GreenNode,
15 red::RedNode,
16 syntax_text::SyntaxText,
17};
18
19#[derive(Debug)]
20pub struct SyntaxRoot {
21 red: RedNode,
22 pub(crate) errors: Vec<SyntaxError>,
23}
24
25pub trait TreeRoot: Clone + Send + Sync {
26 fn borrowed(&self) -> RefRoot;
27 fn owned(&self) -> OwnedRoot;
28
29 #[doc(hidden)]
30 fn syntax_root(&self) -> &SyntaxRoot;
31}
32#[derive(Clone, Debug)]
33pub struct OwnedRoot(Arc<SyntaxRoot>);
34#[derive(Clone, Copy, Debug)]
35pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection
36
37impl<'a> RefRoot<'a> {
38 fn syntax_root(&self) -> &'a SyntaxRoot {
39 self.0.syntax_root()
40 }
41}
42
43impl TreeRoot for OwnedRoot {
44 fn borrowed(&self) -> RefRoot {
45 RefRoot(&self)
46 }
47 fn owned(&self) -> OwnedRoot {
48 self.clone()
49 }
50
51 fn syntax_root(&self) -> &SyntaxRoot {
52 &*self.0
53 }
54}
55
56impl<'a> TreeRoot for RefRoot<'a> {
57 fn borrowed(&self) -> RefRoot {
58 *self
59 }
60 fn owned(&self) -> OwnedRoot {
61 self.0.clone()
62 }
63 fn syntax_root(&self) -> &SyntaxRoot {
64 self.0.syntax_root()
65 }
66}
67
68impl SyntaxRoot {
69 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot {
70 SyntaxRoot {
71 red: RedNode::new_root(green),
72 errors,
73 }
74 }
75}
76
77#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
78pub(crate) struct RedPtr(ptr::NonNull<RedNode>);
79
80unsafe impl Send for RedPtr {}
81
82unsafe impl Sync for RedPtr {}
83
84impl RedPtr {
85 fn new(red: &RedNode) -> RedPtr {
86 RedPtr(red.into())
87 }
88
89 unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode {
90 &*self.0.as_ptr()
91 }
92}
93
94#[test]
95fn assert_send_sync() {
96 fn f<T: Send + Sync>() {}
97 f::<GreenNode>();
98 f::<RedNode>();
99 f::<SyntaxNode>();
100}
diff --git a/crates/ra_syntax/src/yellow/red.rs b/crates/ra_syntax/src/yellow/red.rs
new file mode 100644
index 000000000..84cfe4fba
--- /dev/null
+++ b/crates/ra_syntax/src/yellow/red.rs
@@ -0,0 +1,113 @@
1use parking_lot::RwLock;
2use {yellow::{GreenNode, RedPtr}, TextUnit};
3
4#[derive(Debug)]
5pub(crate) struct RedNode {
6 green: GreenNode,
7 parent: Option<ParentData>,
8 children: RwLock<Box<[RedChild]>>,
9}
10
11#[derive(Debug)]
12enum RedChild {
13 Zigot(TextUnit),
14 Child(RedNode)
15}
16
17impl RedChild {
18 fn set(&mut self, node: RedNode) -> &RedNode {
19 match self {
20 RedChild::Child(node) => return node,
21 RedChild::Zigot(_) => {
22 *self = RedChild::Child(node);
23 match self {
24 RedChild::Child(node) => return node,
25 RedChild::Zigot(_) => unreachable!()
26 }
27 }
28 }
29 }
30}
31
32#[derive(Debug)]
33struct ParentData {
34 parent: RedPtr,
35 start_offset: TextUnit,
36 index_in_parent: usize,
37}
38
39impl RedNode {
40 pub fn new_root(green: GreenNode) -> RedNode {
41 RedNode::new(green, None)
42 }
43
44 fn new_child(
45 green: GreenNode,
46 parent: RedPtr,
47 start_offset: TextUnit,
48 index_in_parent: usize,
49 ) -> RedNode {
50 let parent_data = ParentData {
51 parent,
52 start_offset,
53 index_in_parent,
54 };
55 RedNode::new(green, Some(parent_data))
56 }
57
58 fn new(green: GreenNode, parent: Option<ParentData>) -> RedNode {
59 let mut start_offset = parent.as_ref().map(|it| it.start_offset).unwrap_or(0.into());
60 let children = green.children()
61 .iter()
62 .map(|child| {
63 let off = start_offset;
64 start_offset += child.text_len();
65 RedChild::Zigot(off)
66 })
67 .collect::<Vec<_>>()
68 .into_boxed_slice();
69 RedNode {
70 green,
71 parent,
72 children: RwLock::new(children),
73 }
74 }
75
76 pub(crate) fn green(&self) -> &GreenNode {
77 &self.green
78 }
79
80 pub(crate) fn start_offset(&self) -> TextUnit {
81 match &self.parent {
82 None => 0.into(),
83 Some(p) => p.start_offset,
84 }
85 }
86
87 pub(crate) fn n_children(&self) -> usize {
88 self.green.children().len()
89 }
90
91 pub(crate) fn get_child(&self, idx: usize) -> Option<RedPtr> {
92 if idx >= self.n_children() {
93 return None;
94 }
95 let start_offset = match &self.children.read()[idx] {
96 RedChild::Child(child) => return Some(RedPtr::new(child)),
97 RedChild::Zigot(start_offset) => *start_offset,
98 };
99 let green_children = self.green.children();
100 let child =
101 RedNode::new_child(green_children[idx].clone(), RedPtr::new(self), start_offset, idx);
102 let mut children = self.children.write();
103 let child = children[idx].set(child);
104 Some(RedPtr::new(child))
105 }
106
107 pub(crate) fn parent(&self) -> Option<RedPtr> {
108 Some(self.parent.as_ref()?.parent)
109 }
110 pub(crate) fn index_in_parent(&self) -> Option<usize> {
111 Some(self.parent.as_ref()?.index_in_parent)
112 }
113}
diff --git a/crates/ra_syntax/src/yellow/syntax.rs b/crates/ra_syntax/src/yellow/syntax.rs
new file mode 100644
index 000000000..1d99cab4a
--- /dev/null
+++ b/crates/ra_syntax/src/yellow/syntax.rs
@@ -0,0 +1,215 @@
1use std::{
2 fmt, sync::Arc,
3 hash::{Hasher, Hash},
4 ops::Range,
5};
6
7use smol_str::SmolStr;
8
9use {
10 yellow::{GreenNode, RedNode, TreeRoot, SyntaxRoot, RedPtr, RefRoot, OwnedRoot, SyntaxText},
11 SyntaxKind::{self, *},
12 TextRange, TextUnit,
13};
14
15
16#[derive(Clone, Copy)]
17pub struct SyntaxNode<R: TreeRoot = OwnedRoot> {
18 pub(crate) root: R,
19 // Guaranteed to not dangle, because `root` holds a
20 // strong reference to red's ancestor
21 red: RedPtr,
22}
23
24unsafe impl<R: TreeRoot> Send for SyntaxNode<R> {}
25unsafe impl<R: TreeRoot> Sync for SyntaxNode<R> {}
26
27impl<R1: TreeRoot, R2: TreeRoot> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2> {
28 fn eq(&self, other: &SyntaxNode<R1>) -> bool {
29 self.red == other.red
30 }
31}
32
33impl<R: TreeRoot> Eq for SyntaxNode<R> {}
34impl<R: TreeRoot> Hash for SyntaxNode<R> {
35 fn hash<H: Hasher>(&self, state: &mut H) {
36 self.red.hash(state)
37 }
38}
39
40pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
41
42#[test]
43fn syntax_node_ref_is_copy() {
44 fn assert_copy<T: Copy>(){}
45 assert_copy::<SyntaxNodeRef>()
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
49pub struct SyntaxError {
50 pub msg: String,
51 pub offset: TextUnit,
52}
53
54impl SyntaxNode<OwnedRoot> {
55 pub(crate) fn new_owned(root: SyntaxRoot) -> Self {
56 let root = OwnedRoot(Arc::new(root));
57 let red = RedPtr::new(&root.syntax_root().red);
58 SyntaxNode { root, red }
59 }
60}
61
62impl<'a> SyntaxNode<RefRoot<'a>> {
63 pub(crate) fn leaf_text_ref(self) -> Option<&'a SmolStr> {
64 let red = unsafe { self.red.get(self.root.syntax_root()) };
65 red.green().leaf_text_ref()
66 }
67}
68
69impl<R: TreeRoot> SyntaxNode<R> {
70 pub fn borrowed<'a>(&'a self) -> SyntaxNodeRef<'a> {
71 SyntaxNode {
72 root: self.root.borrowed(),
73 red: self.red,
74 }
75 }
76
77 pub fn owned(&self) -> SyntaxNode {
78 SyntaxNode {
79 root: self.root.owned(),
80 red: self.red,
81 }
82 }
83
84 pub fn kind(&self) -> SyntaxKind {
85 self.red().green().kind()
86 }
87
88 pub fn range(&self) -> TextRange {
89 let red = self.red();
90 TextRange::offset_len(red.start_offset(), red.green().text_len())
91 }
92
93 pub fn text(&self) -> SyntaxText {
94 SyntaxText::new(self.borrowed())
95 }
96
97 pub fn children(&self) -> SyntaxNodeChildren<R> {
98 SyntaxNodeChildren {
99 parent: self.clone(),
100 iter: (0..self.red().n_children())
101 }
102 }
103
104 pub fn parent(&self) -> Option<SyntaxNode<R>> {
105 let parent = self.red().parent()?;
106 Some(SyntaxNode {
107 root: self.root.clone(),
108 red: parent,
109 })
110 }
111
112 pub fn first_child(&self) -> Option<SyntaxNode<R>> {
113 let red = self.red().get_child(0)?;
114 Some(SyntaxNode { root: self.root.clone(), red })
115 }
116
117 pub fn last_child(&self) -> Option<SyntaxNode<R>> {
118 let n = self.red().n_children();
119 let n = n.checked_sub(1)?;
120 let red = self.red().get_child(n)?;
121 Some(SyntaxNode { root: self.root.clone(), red })
122 }
123
124 pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
125 let red = self.red();
126 let parent = self.parent()?;
127 let next_sibling_idx = red.index_in_parent()? + 1;
128 let sibling_red = parent.red().get_child(next_sibling_idx)?;
129 Some(SyntaxNode {
130 root: self.root.clone(),
131 red: sibling_red,
132 })
133 }
134
135 pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
136 let red = self.red();
137 let parent = self.parent()?;
138 let prev_sibling_idx = red.index_in_parent()?.checked_sub(1)?;
139 let sibling_red = parent.red().get_child(prev_sibling_idx)?;
140 Some(SyntaxNode {
141 root: self.root.clone(),
142 red: sibling_red,
143 })
144 }
145
146 pub fn is_leaf(&self) -> bool {
147 self.first_child().is_none()
148 }
149
150 pub fn leaf_text(&self) -> Option<SmolStr> {
151 self.borrowed().leaf_text_ref().map(|it| it.clone())
152 }
153
154 pub(crate) fn replace_with(&self, green: GreenNode) -> GreenNode {
155 assert_eq!(self.kind(), green.kind());
156 match self.parent() {
157 None => green,
158 Some(parent) => {
159 let children: Vec<_> = parent.children().map(|child| {
160 if child == *self {
161 green.clone()
162 } else {
163 child.red().green().clone()
164 }
165 }).collect();
166 let new_parent = GreenNode::new_branch(
167 parent.kind(),
168 children.into_boxed_slice(),
169 );
170 parent.replace_with(new_parent)
171 },
172 }
173 }
174
175 fn red(&self) -> &RedNode {
176 unsafe { self.red.get(self.root.syntax_root()) }
177 }
178}
179
180impl<R: TreeRoot> fmt::Debug for SyntaxNode<R> {
181 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
182 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
183 if has_short_text(self.kind()) {
184 write!(fmt, " \"{}\"", self.text())?;
185 }
186 Ok(())
187 }
188}
189
190#[derive(Debug)]
191pub struct SyntaxNodeChildren<R: TreeRoot> {
192 parent: SyntaxNode<R>,
193 iter: Range<usize>,
194}
195
196impl<R: TreeRoot> Iterator for SyntaxNodeChildren<R> {
197 type Item = SyntaxNode<R>;
198
199 fn next(&mut self) -> Option<SyntaxNode<R>> {
200 self.iter.next().map(|i| {
201 let red = self.parent.red();
202 SyntaxNode {
203 root: self.parent.root.clone(),
204 red: red.get_child(i).unwrap(),
205 }
206 })
207 }
208}
209
210fn has_short_text(kind: SyntaxKind) -> bool {
211 match kind {
212 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,
213 _ => false,
214 }
215}
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs
new file mode 100644
index 000000000..280bedd78
--- /dev/null
+++ b/crates/ra_syntax/src/yellow/syntax_text.rs
@@ -0,0 +1,122 @@
1use std::{
2 fmt, ops,
3};
4
5use {
6 SyntaxNodeRef, TextRange, TextUnit,
7 algo::walk::preorder,
8 text_utils::{intersect, contains_offset_nonstrict},
9};
10
11#[derive(Clone)]
12pub struct SyntaxText<'a> {
13 node: SyntaxNodeRef<'a>,
14 range: TextRange,
15}
16
17impl<'a> SyntaxText<'a> {
18 pub(crate) fn new(node: SyntaxNodeRef<'a>) -> SyntaxText<'a> {
19 SyntaxText {
20 node,
21 range: node.range()
22 }
23 }
24 pub fn chunks(&self) -> impl Iterator<Item=&'a str> {
25 let range = self.range;
26 preorder(self.node)
27 .filter_map(move |node| {
28 let text = node.leaf_text_ref()?;
29 let range = intersect(range, node.range())?;
30 let range = range - node.range().start();
31 Some(&text[range])
32 })
33 }
34 pub fn push_to(&self, buf: &mut String) {
35 self.chunks().for_each(|it| buf.push_str(it));
36 }
37 pub fn to_string(&self) -> String {
38 self.chunks().collect()
39 }
40 pub fn contains(&self, c: char) -> bool {
41 self.chunks().any(|it| it.contains(c))
42 }
43 pub fn find(&self, c: char) -> Option<TextUnit> {
44 let mut acc: TextUnit = 0.into();
45 for chunk in self.chunks() {
46 if let Some(pos) = chunk.find(c) {
47 let pos: TextUnit = (pos as u32).into();
48 return Some(acc + pos);
49 }
50 acc += TextUnit::of_str(chunk);
51 }
52 None
53 }
54 pub fn len(&self) -> TextUnit {
55 self.range.len()
56 }
57 pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> {
58 let range = range.restrict(self.range)
59 .unwrap_or_else(|| {
60 panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range)
61 });
62 SyntaxText { node: self.node, range }
63 }
64 pub fn char_at(&self, offset: TextUnit) -> Option<char> {
65 let mut start: TextUnit = 0.into();
66 for chunk in self.chunks() {
67 let end = start + TextUnit::of_str(chunk);
68 if start <= offset && offset < end {
69 let off: usize = u32::from(offset - start) as usize;
70 return Some(chunk[off..].chars().next().unwrap());
71 }
72 start = end;
73 }
74 None
75 }
76}
77
78impl<'a> fmt::Debug for SyntaxText<'a> {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 fmt::Debug::fmt(&self.to_string(), f)
81 }
82}
83
84impl<'a> fmt::Display for SyntaxText<'a> {
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 fmt::Display::fmt(&self.to_string(), f)
87 }
88}
89
90pub trait SyntaxTextSlice: fmt::Debug {
91 fn restrict(&self, range: TextRange) -> Option<TextRange>;
92}
93
94impl SyntaxTextSlice for TextRange {
95 fn restrict(&self, range: TextRange) -> Option<TextRange> {
96 intersect(*self, range)
97 }
98}
99
100impl SyntaxTextSlice for ops::RangeTo<TextUnit> {
101 fn restrict(&self, range: TextRange) -> Option<TextRange> {
102 if !contains_offset_nonstrict(range, self.end) {
103 return None;
104 }
105 Some(TextRange::from_to(range.start(), self.end))
106 }
107}
108
109impl SyntaxTextSlice for ops::RangeFrom<TextUnit> {
110 fn restrict(&self, range: TextRange) -> Option<TextRange> {
111 if !contains_offset_nonstrict(range, self.start) {
112 return None;
113 }
114 Some(TextRange::from_to(self.start, range.end()))
115 }
116}
117
118impl SyntaxTextSlice for ops::Range<TextUnit> {
119 fn restrict(&self, range: TextRange) -> Option<TextRange> {
120 TextRange::from_to(self.start, self.end).restrict(range)
121 }
122}
diff --git a/crates/ra_syntax/tests/data/lexer/00012_block_comment.rs b/crates/ra_syntax/tests/data/lexer/00012_block_comment.rs
new file mode 100644
index 000000000..708aac197
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/00012_block_comment.rs
@@ -0,0 +1,4 @@
1/* */
2/**/
3/* /* */ */
4/*
diff --git a/crates/ra_syntax/tests/data/lexer/00012_block_comment.txt b/crates/ra_syntax/tests/data/lexer/00012_block_comment.txt
new file mode 100644
index 000000000..9958b2518
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/00012_block_comment.txt
@@ -0,0 +1,7 @@
1COMMENT 5 "/* */"
2WHITESPACE 1 "\n"
3COMMENT 4 "/**/"
4WHITESPACE 1 "\n"
5COMMENT 11 "/* /* */ */"
6WHITESPACE 1 "\n"
7COMMENT 3 "/*\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0001_hello.rs b/crates/ra_syntax/tests/data/lexer/0001_hello.rs
new file mode 100644
index 000000000..95d09f2b1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0001_hello.rs
@@ -0,0 +1 @@
hello world \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/lexer/0001_hello.txt b/crates/ra_syntax/tests/data/lexer/0001_hello.txt
new file mode 100644
index 000000000..27a5940a9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0001_hello.txt
@@ -0,0 +1,3 @@
1IDENT 5 "hello"
2WHITESPACE 1 " "
3IDENT 5 "world"
diff --git a/crates/ra_syntax/tests/data/lexer/0002_whitespace.rs b/crates/ra_syntax/tests/data/lexer/0002_whitespace.rs
new file mode 100644
index 000000000..08fce1418
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0002_whitespace.rs
@@ -0,0 +1,4 @@
1a b c
2d
3
4e f
diff --git a/crates/ra_syntax/tests/data/lexer/0002_whitespace.txt b/crates/ra_syntax/tests/data/lexer/0002_whitespace.txt
new file mode 100644
index 000000000..01d260918
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0002_whitespace.txt
@@ -0,0 +1,12 @@
1IDENT 1 "a"
2WHITESPACE 1 " "
3IDENT 1 "b"
4WHITESPACE 2 " "
5IDENT 1 "c"
6WHITESPACE 1 "\n"
7IDENT 1 "d"
8WHITESPACE 2 "\n\n"
9IDENT 1 "e"
10WHITESPACE 1 "\t"
11IDENT 1 "f"
12WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0003_ident.rs b/crates/ra_syntax/tests/data/lexer/0003_ident.rs
new file mode 100644
index 000000000..c05c9c009
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0003_ident.rs
@@ -0,0 +1 @@
foo foo_ _foo _ __ x привет
diff --git a/crates/ra_syntax/tests/data/lexer/0003_ident.txt b/crates/ra_syntax/tests/data/lexer/0003_ident.txt
new file mode 100644
index 000000000..4a0d5c053
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0003_ident.txt
@@ -0,0 +1,14 @@
1IDENT 3 "foo"
2WHITESPACE 1 " "
3IDENT 4 "foo_"
4WHITESPACE 1 " "
5IDENT 4 "_foo"
6WHITESPACE 1 " "
7UNDERSCORE 1 "_"
8WHITESPACE 1 " "
9IDENT 2 "__"
10WHITESPACE 1 " "
11IDENT 1 "x"
12WHITESPACE 1 " "
13IDENT 12 "привет"
14WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0004_numbers.rs b/crates/ra_syntax/tests/data/lexer/0004_numbers.rs
new file mode 100644
index 000000000..dc974b553
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0004_numbers.rs
@@ -0,0 +1,9 @@
10 0b 0o 0x 00 0_ 0. 0e 0E 0z
201790 0b1790 0o1790 0x1790aAbBcCdDeEfF 001279 0_1279 0.1279 0e1279 0E1279
30..2
40.foo()
50e+1
60.e+1
70.0E-2
80___0.10000____0000e+111__
91i64 92.0f32 11__s \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/lexer/0004_numbers.txt b/crates/ra_syntax/tests/data/lexer/0004_numbers.txt
new file mode 100644
index 000000000..4b5fd9f71
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0004_numbers.txt
@@ -0,0 +1,67 @@
1INT_NUMBER 1 "0"
2WHITESPACE 1 " "
3INT_NUMBER 2 "0b"
4WHITESPACE 1 " "
5INT_NUMBER 2 "0o"
6WHITESPACE 1 " "
7INT_NUMBER 2 "0x"
8WHITESPACE 1 " "
9INT_NUMBER 2 "00"
10WHITESPACE 1 " "
11INT_NUMBER 2 "0_"
12WHITESPACE 1 " "
13FLOAT_NUMBER 2 "0."
14WHITESPACE 1 " "
15INT_NUMBER 2 "0e"
16WHITESPACE 1 " "
17INT_NUMBER 2 "0E"
18WHITESPACE 1 " "
19INT_NUMBER 2 "0z"
20WHITESPACE 1 "\n"
21INT_NUMBER 5 "01790"
22WHITESPACE 1 " "
23INT_NUMBER 6 "0b1790"
24WHITESPACE 1 " "
25INT_NUMBER 6 "0o1790"
26WHITESPACE 1 " "
27INT_NUMBER 18 "0x1790aAbBcCdDeEfF"
28WHITESPACE 1 " "
29INT_NUMBER 6 "001279"
30WHITESPACE 1 " "
31INT_NUMBER 6 "0_1279"
32WHITESPACE 1 " "
33FLOAT_NUMBER 6 "0.1279"
34WHITESPACE 1 " "
35INT_NUMBER 6 "0e1279"
36WHITESPACE 1 " "
37INT_NUMBER 6 "0E1279"
38WHITESPACE 1 "\n"
39INT_NUMBER 1 "0"
40DOTDOT 2 ".."
41INT_NUMBER 1 "2"
42WHITESPACE 1 "\n"
43INT_NUMBER 1 "0"
44DOT 1 "."
45IDENT 3 "foo"
46L_PAREN 1 "("
47R_PAREN 1 ")"
48WHITESPACE 1 "\n"
49INT_NUMBER 2 "0e"
50PLUS 1 "+"
51INT_NUMBER 1 "1"
52WHITESPACE 1 "\n"
53INT_NUMBER 1 "0"
54DOT 1 "."
55IDENT 1 "e"
56PLUS 1 "+"
57INT_NUMBER 1 "1"
58WHITESPACE 1 "\n"
59FLOAT_NUMBER 6 "0.0E-2"
60WHITESPACE 1 "\n"
61FLOAT_NUMBER 26 "0___0.10000____0000e+111__"
62WHITESPACE 1 "\n"
63INT_NUMBER 4 "1i64"
64WHITESPACE 1 " "
65FLOAT_NUMBER 7 "92.0f32"
66WHITESPACE 1 " "
67INT_NUMBER 5 "11__s"
diff --git a/crates/ra_syntax/tests/data/lexer/0005_symbols.rs b/crates/ra_syntax/tests/data/lexer/0005_symbols.rs
new file mode 100644
index 000000000..487569b5a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0005_symbols.rs
@@ -0,0 +1,6 @@
1; , ( ) { } [ ] < > @ # ~ ? $ & | + * / ^ %
2. .. ... ..=
3: ::
4= =>
5! !=
6- ->
diff --git a/crates/ra_syntax/tests/data/lexer/0005_symbols.txt b/crates/ra_syntax/tests/data/lexer/0005_symbols.txt
new file mode 100644
index 000000000..a6bc83a6f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0005_symbols.txt
@@ -0,0 +1,68 @@
1SEMI 1 ";"
2WHITESPACE 1 " "
3COMMA 1 ","
4WHITESPACE 1 " "
5L_PAREN 1 "("
6WHITESPACE 1 " "
7R_PAREN 1 ")"
8WHITESPACE 1 " "
9L_CURLY 1 "{"
10WHITESPACE 1 " "
11R_CURLY 1 "}"
12WHITESPACE 1 " "
13L_BRACK 1 "["
14WHITESPACE 1 " "
15R_BRACK 1 "]"
16WHITESPACE 1 " "
17L_ANGLE 1 "<"
18WHITESPACE 1 " "
19R_ANGLE 1 ">"
20WHITESPACE 1 " "
21AT 1 "@"
22WHITESPACE 1 " "
23POUND 1 "#"
24WHITESPACE 1 " "
25TILDE 1 "~"
26WHITESPACE 1 " "
27QUESTION 1 "?"
28WHITESPACE 1 " "
29DOLLAR 1 "$"
30WHITESPACE 1 " "
31AMP 1 "&"
32WHITESPACE 1 " "
33PIPE 1 "|"
34WHITESPACE 1 " "
35PLUS 1 "+"
36WHITESPACE 1 " "
37STAR 1 "*"
38WHITESPACE 1 " "
39SLASH 1 "/"
40WHITESPACE 1 " "
41CARET 1 "^"
42WHITESPACE 1 " "
43PERCENT 1 "%"
44WHITESPACE 1 "\n"
45DOT 1 "."
46WHITESPACE 1 " "
47DOTDOT 2 ".."
48WHITESPACE 1 " "
49DOTDOTDOT 3 "..."
50WHITESPACE 1 " "
51DOTDOTEQ 3 "..="
52WHITESPACE 1 "\n"
53COLON 1 ":"
54WHITESPACE 1 " "
55COLONCOLON 2 "::"
56WHITESPACE 1 "\n"
57EQ 1 "="
58WHITESPACE 1 " "
59FAT_ARROW 2 "=>"
60WHITESPACE 1 "\n"
61EXCL 1 "!"
62WHITESPACE 1 " "
63NEQ 2 "!="
64WHITESPACE 1 "\n"
65MINUS 1 "-"
66WHITESPACE 1 " "
67THIN_ARROW 2 "->"
68WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0006_chars.rs b/crates/ra_syntax/tests/data/lexer/0006_chars.rs
new file mode 100644
index 000000000..454ee0a5f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0006_chars.rs
@@ -0,0 +1 @@
'x' ' ' '0' 'hello' '\x7f' '\n' '\\' '\''
diff --git a/crates/ra_syntax/tests/data/lexer/0006_chars.txt b/crates/ra_syntax/tests/data/lexer/0006_chars.txt
new file mode 100644
index 000000000..950954fbc
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0006_chars.txt
@@ -0,0 +1,16 @@
1CHAR 3 "\'x\'"
2WHITESPACE 1 " "
3CHAR 3 "\' \'"
4WHITESPACE 1 " "
5CHAR 3 "\'0\'"
6WHITESPACE 1 " "
7CHAR 7 "\'hello\'"
8WHITESPACE 1 " "
9CHAR 6 "\'\\x7f\'"
10WHITESPACE 1 " "
11CHAR 4 "\'\\n\'"
12WHITESPACE 1 " "
13CHAR 4 "\'\\\\\'"
14WHITESPACE 1 " "
15CHAR 4 "\'\\\'\'"
16WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs
new file mode 100644
index 000000000..b764f1dce
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs
@@ -0,0 +1 @@
'a 'foo 'foo_bar_baz '_
diff --git a/crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt
new file mode 100644
index 000000000..005c29100
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt
@@ -0,0 +1,8 @@
1LIFETIME 2 "\'a"
2WHITESPACE 1 " "
3LIFETIME 4 "\'foo"
4WHITESPACE 1 " "
5LIFETIME 12 "\'foo_bar_baz"
6WHITESPACE 1 " "
7LIFETIME 2 "\'_"
8WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs
new file mode 100644
index 000000000..b54930f5e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs
@@ -0,0 +1,3 @@
1b'' b'x' b"foo" br""
2b''suf b""ix br""br
3b'\n' b'\\' b'\'' b'hello'
diff --git a/crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt
new file mode 100644
index 000000000..bc03b51a8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt
@@ -0,0 +1,22 @@
1BYTE 3 "b\'\'"
2WHITESPACE 1 " "
3BYTE 4 "b\'x\'"
4WHITESPACE 1 " "
5BYTE_STRING 6 "b\"foo\""
6WHITESPACE 1 " "
7RAW_BYTE_STRING 4 "br\"\""
8WHITESPACE 1 "\n"
9BYTE 6 "b\'\'suf"
10WHITESPACE 1 " "
11BYTE_STRING 5 "b\"\"ix"
12WHITESPACE 1 " "
13RAW_BYTE_STRING 6 "br\"\"br"
14WHITESPACE 1 "\n"
15BYTE 5 "b\'\\n\'"
16WHITESPACE 1 " "
17BYTE 5 "b\'\\\\\'"
18WHITESPACE 1 " "
19BYTE 5 "b\'\\\'\'"
20WHITESPACE 1 " "
21BYTE 8 "b\'hello\'"
22WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0009_strings.rs b/crates/ra_syntax/tests/data/lexer/0009_strings.rs
new file mode 100644
index 000000000..4ddb5bffc
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0009_strings.rs
@@ -0,0 +1,2 @@
1"hello" r"world" "\n\"\\no escape" "multi
2line"
diff --git a/crates/ra_syntax/tests/data/lexer/0009_strings.txt b/crates/ra_syntax/tests/data/lexer/0009_strings.txt
new file mode 100644
index 000000000..4cb4d711d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0009_strings.txt
@@ -0,0 +1,8 @@
1STRING 7 "\"hello\""
2WHITESPACE 1 " "
3RAW_STRING 8 "r\"world\""
4WHITESPACE 1 " "
5STRING 17 "\"\\n\\\"\\\\no escape\""
6WHITESPACE 1 " "
7STRING 12 "\"multi\nline\""
8WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0010_comments.rs b/crates/ra_syntax/tests/data/lexer/0010_comments.rs
new file mode 100644
index 000000000..71bdd1f9c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0010_comments.rs
@@ -0,0 +1,3 @@
1#!/usr/bin/env bash
2// hello
3//! World
diff --git a/crates/ra_syntax/tests/data/lexer/0010_comments.txt b/crates/ra_syntax/tests/data/lexer/0010_comments.txt
new file mode 100644
index 000000000..3c997de3f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0010_comments.txt
@@ -0,0 +1,6 @@
1SHEBANG 19 "#!/usr/bin/env bash"
2WHITESPACE 1 "\n"
3COMMENT 8 "// hello"
4WHITESPACE 1 "\n"
5COMMENT 9 "//! World"
6WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0011_keywords.rs b/crates/ra_syntax/tests/data/lexer/0011_keywords.rs
new file mode 100644
index 000000000..e6bf64d4d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0011_keywords.rs
@@ -0,0 +1,3 @@
1fn use struct trait enum impl true false as extern crate
2mod pub self super in where for loop while if match const
3static mut type ref let else move return
diff --git a/crates/ra_syntax/tests/data/lexer/0011_keywords.txt b/crates/ra_syntax/tests/data/lexer/0011_keywords.txt
new file mode 100644
index 000000000..d6a1abe8a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0011_keywords.txt
@@ -0,0 +1,62 @@
1FN_KW 2 "fn"
2WHITESPACE 1 " "
3USE_KW 3 "use"
4WHITESPACE 1 " "
5STRUCT_KW 6 "struct"
6WHITESPACE 1 " "
7TRAIT_KW 5 "trait"
8WHITESPACE 1 " "
9ENUM_KW 4 "enum"
10WHITESPACE 1 " "
11IMPL_KW 4 "impl"
12WHITESPACE 1 " "
13TRUE_KW 4 "true"
14WHITESPACE 1 " "
15FALSE_KW 5 "false"
16WHITESPACE 1 " "
17AS_KW 2 "as"
18WHITESPACE 1 " "
19EXTERN_KW 6 "extern"
20WHITESPACE 1 " "
21CRATE_KW 5 "crate"
22WHITESPACE 1 "\n"
23MOD_KW 3 "mod"
24WHITESPACE 1 " "
25PUB_KW 3 "pub"
26WHITESPACE 1 " "
27SELF_KW 4 "self"
28WHITESPACE 1 " "
29SUPER_KW 5 "super"
30WHITESPACE 1 " "
31IN_KW 2 "in"
32WHITESPACE 1 " "
33WHERE_KW 5 "where"
34WHITESPACE 1 " "
35FOR_KW 3 "for"
36WHITESPACE 1 " "
37LOOP_KW 4 "loop"
38WHITESPACE 1 " "
39WHILE_KW 5 "while"
40WHITESPACE 1 " "
41IF_KW 2 "if"
42WHITESPACE 1 " "
43MATCH_KW 5 "match"
44WHITESPACE 1 " "
45CONST_KW 5 "const"
46WHITESPACE 1 "\n"
47STATIC_KW 6 "static"
48WHITESPACE 1 " "
49MUT_KW 3 "mut"
50WHITESPACE 1 " "
51TYPE_KW 4 "type"
52WHITESPACE 1 " "
53REF_KW 3 "ref"
54WHITESPACE 1 " "
55LET_KW 3 "let"
56WHITESPACE 1 " "
57ELSE_KW 4 "else"
58WHITESPACE 1 " "
59MOVE_KW 4 "move"
60WHITESPACE 1 " "
61RETURN_KW 6 "return"
62WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs
new file mode 100644
index 000000000..e5ed0b693
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs
@@ -0,0 +1 @@
r###"this is a r##"raw"## string"###
diff --git a/crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt
new file mode 100644
index 000000000..9cf0957d1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt
@@ -0,0 +1,2 @@
1RAW_STRING 36 "r###\"this is a r##\"raw\"## string\"###"
2WHITESPACE 1 "\n"
diff --git a/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs
new file mode 100644
index 000000000..9c0007077
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs
@@ -0,0 +1 @@
'1 \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt
new file mode 100644
index 000000000..812dfbc18
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt
@@ -0,0 +1 @@
CHAR 2 "\'1"
diff --git a/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs
new file mode 100644
index 000000000..d771a26d4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs
@@ -0,0 +1 @@
"hello
diff --git a/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt
new file mode 100644
index 000000000..728c40b66
--- /dev/null
+++ b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt
@@ -0,0 +1 @@
STRING 7 "\"hello\n"
diff --git a/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs
new file mode 100644
index 000000000..fe5030d89
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs
@@ -0,0 +1,4 @@
1struct S {
2 a: u32
3 b: u32
4} \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt
new file mode 100644
index 000000000..aa375fe8a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt
@@ -0,0 +1,34 @@
1ROOT@[0; 34)
2 STRUCT_DEF@[0; 34)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 WHITESPACE@[8; 9)
8 NAMED_FIELD_DEF_LIST@[9; 34)
9 L_CURLY@[9; 10)
10 WHITESPACE@[10; 15)
11 NAMED_FIELD_DEF@[15; 21)
12 NAME@[15; 16)
13 IDENT@[15; 16) "a"
14 COLON@[16; 17)
15 WHITESPACE@[17; 18)
16 PATH_TYPE@[18; 21)
17 PATH@[18; 21)
18 PATH_SEGMENT@[18; 21)
19 NAME_REF@[18; 21)
20 IDENT@[18; 21) "u32"
21 err: `expected COMMA`
22 WHITESPACE@[21; 26)
23 NAMED_FIELD_DEF@[26; 32)
24 NAME@[26; 27)
25 IDENT@[26; 27) "b"
26 COLON@[27; 28)
27 WHITESPACE@[28; 29)
28 PATH_TYPE@[29; 32)
29 PATH@[29; 32)
30 PATH_SEGMENT@[29; 32)
31 NAME_REF@[29; 32)
32 IDENT@[29; 32) "u32"
33 WHITESPACE@[32; 33)
34 R_CURLY@[33; 34)
diff --git a/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs
new file mode 100644
index 000000000..98f23de1f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs
@@ -0,0 +1,3 @@
1if match
2
3struct S {} \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt
new file mode 100644
index 000000000..771d6e1ef
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt
@@ -0,0 +1,18 @@
1ROOT@[0; 21)
2 ERROR@[0; 2)
3 IF_KW@[0; 2)
4 err: `expected an item`
5 WHITESPACE@[2; 3)
6 err: `expected an item`
7 ERROR@[3; 8)
8 MATCH_KW@[3; 8)
9 WHITESPACE@[8; 10)
10 STRUCT_DEF@[10; 21)
11 STRUCT_KW@[10; 16)
12 WHITESPACE@[16; 17)
13 NAME@[17; 18)
14 IDENT@[17; 18) "S"
15 WHITESPACE@[18; 19)
16 NAMED_FIELD_DEF_LIST@[19; 21)
17 L_CURLY@[19; 20)
18 R_CURLY@[20; 21)
diff --git a/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs
new file mode 100644
index 000000000..48a3a3980
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs
@@ -0,0 +1,2 @@
1#!/use/bin/env rusti
2#!/use/bin/env rusti
diff --git a/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt
new file mode 100644
index 000000000..57fb48420
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt
@@ -0,0 +1,7 @@
1ROOT@[0; 42)
2 SHEBANG@[0; 20)
3 WHITESPACE@[20; 21)
4 err: `expected an item`
5 ERROR@[21; 41)
6 SHEBANG@[21; 41)
7 WHITESPACE@[41; 42)
diff --git a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs
new file mode 100644
index 000000000..009312270
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs
@@ -0,0 +1,4 @@
1struct S {
2 a: i32,
3 b: String,
4}; \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt
new file mode 100644
index 000000000..b51c0573a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt
@@ -0,0 +1,39 @@
1ROOT@[0; 40)
2 STRUCT_DEF@[0; 40)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 WHITESPACE@[8; 9)
8 NAMED_FIELD_DEF_LIST@[9; 39)
9 L_CURLY@[9; 10)
10 WHITESPACE@[10; 15)
11 NAMED_FIELD_DEF@[15; 21)
12 NAME@[15; 16)
13 IDENT@[15; 16) "a"
14 COLON@[16; 17)
15 WHITESPACE@[17; 18)
16 PATH_TYPE@[18; 21)
17 PATH@[18; 21)
18 PATH_SEGMENT@[18; 21)
19 NAME_REF@[18; 21)
20 IDENT@[18; 21) "i32"
21 COMMA@[21; 22)
22 WHITESPACE@[22; 27)
23 NAMED_FIELD_DEF@[27; 36)
24 NAME@[27; 28)
25 IDENT@[27; 28) "b"
26 COLON@[28; 29)
27 WHITESPACE@[29; 30)
28 PATH_TYPE@[30; 36)
29 PATH@[30; 36)
30 PATH_SEGMENT@[30; 36)
31 NAME_REF@[30; 36)
32 IDENT@[30; 36) "String"
33 COMMA@[36; 37)
34 WHITESPACE@[37; 38)
35 R_CURLY@[38; 39)
36 err: `expected item, found `;`
37consider removing this semicolon`
38 ERROR@[39; 40)
39 SEMI@[39; 40)
diff --git a/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs
new file mode 100644
index 000000000..060e65d06
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs
@@ -0,0 +1 @@
use foo::92; \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt
new file mode 100644
index 000000000..646c84534
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt
@@ -0,0 +1,16 @@
1ROOT@[0; 12)
2 USE_ITEM@[0; 12)
3 USE_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 USE_TREE@[4; 11)
6 PATH@[4; 11)
7 PATH@[4; 7)
8 PATH_SEGMENT@[4; 7)
9 NAME_REF@[4; 7)
10 IDENT@[4; 7) "foo"
11 COLONCOLON@[7; 9)
12 err: `expected identifier`
13 PATH_SEGMENT@[9; 11)
14 ERROR@[9; 11)
15 INT_NUMBER@[9; 11) "92"
16 SEMI@[11; 12)
diff --git a/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs
new file mode 100644
index 000000000..de7f81628
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs
@@ -0,0 +1,8 @@
1#[foo(foo, +, 92)]
2fn foo() {
3}
4
5
6#[foo(
7fn foo() {
8}
diff --git a/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt
new file mode 100644
index 000000000..b3cf9b889
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt
@@ -0,0 +1,55 @@
1ROOT@[0; 54)
2 FN_DEF@[0; 31)
3 ATTR@[0; 18)
4 POUND@[0; 1)
5 TOKEN_TREE@[1; 18)
6 L_BRACK@[1; 2)
7 IDENT@[2; 5) "foo"
8 TOKEN_TREE@[5; 17)
9 L_PAREN@[5; 6)
10 IDENT@[6; 9) "foo"
11 COMMA@[9; 10)
12 WHITESPACE@[10; 11)
13 PLUS@[11; 12)
14 COMMA@[12; 13)
15 WHITESPACE@[13; 14)
16 INT_NUMBER@[14; 16) "92"
17 R_PAREN@[16; 17)
18 R_BRACK@[17; 18)
19 WHITESPACE@[18; 19)
20 FN_KW@[19; 21)
21 WHITESPACE@[21; 22)
22 NAME@[22; 25)
23 IDENT@[22; 25) "foo"
24 PARAM_LIST@[25; 27)
25 L_PAREN@[25; 26)
26 R_PAREN@[26; 27)
27 WHITESPACE@[27; 28)
28 BLOCK@[28; 31)
29 L_CURLY@[28; 29)
30 WHITESPACE@[29; 30)
31 R_CURLY@[30; 31)
32 WHITESPACE@[31; 34)
33 ATTR@[34; 53)
34 POUND@[34; 35)
35 TOKEN_TREE@[35; 53)
36 L_BRACK@[35; 36)
37 IDENT@[36; 39) "foo"
38 TOKEN_TREE@[39; 53)
39 L_PAREN@[39; 40)
40 WHITESPACE@[40; 41)
41 FN_KW@[41; 43)
42 WHITESPACE@[43; 44)
43 IDENT@[44; 47) "foo"
44 TOKEN_TREE@[47; 49)
45 L_PAREN@[47; 48)
46 R_PAREN@[48; 49)
47 WHITESPACE@[49; 50)
48 TOKEN_TREE@[50; 53)
49 L_CURLY@[50; 51)
50 WHITESPACE@[51; 52)
51 R_CURLY@[52; 53)
52 err: `expected R_PAREN`
53 err: `expected R_BRACK`
54 err: `expected an item`
55 WHITESPACE@[53; 54)
diff --git a/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs
new file mode 100644
index 000000000..8069c111b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs
@@ -0,0 +1,7 @@
1struct S {
2 f: u32,
3 pub 92
4 + - *
5 pub x: u32,
6 z: f64,
7}
diff --git a/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt
new file mode 100644
index 000000000..9abda7099
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt
@@ -0,0 +1,74 @@
1ROOT@[0; 74)
2 STRUCT_DEF@[0; 73)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 WHITESPACE@[8; 9)
8 NAMED_FIELD_DEF_LIST@[9; 73)
9 L_CURLY@[9; 10)
10 WHITESPACE@[10; 15)
11 NAMED_FIELD_DEF@[15; 21)
12 NAME@[15; 16)
13 IDENT@[15; 16) "f"
14 COLON@[16; 17)
15 WHITESPACE@[17; 18)
16 PATH_TYPE@[18; 21)
17 PATH@[18; 21)
18 PATH_SEGMENT@[18; 21)
19 NAME_REF@[18; 21)
20 IDENT@[18; 21) "u32"
21 COMMA@[21; 22)
22 WHITESPACE@[22; 27)
23 VISIBILITY@[27; 30)
24 PUB_KW@[27; 30)
25 WHITESPACE@[30; 31)
26 err: `expected field declaration`
27 ERROR@[31; 33)
28 INT_NUMBER@[31; 33) "92"
29 err: `expected COMMA`
30 WHITESPACE@[33; 38)
31 err: `expected field declaration`
32 ERROR@[38; 39)
33 PLUS@[38; 39)
34 err: `expected COMMA`
35 WHITESPACE@[39; 40)
36 err: `expected field declaration`
37 ERROR@[40; 41)
38 MINUS@[40; 41)
39 err: `expected COMMA`
40 WHITESPACE@[41; 42)
41 err: `expected field declaration`
42 ERROR@[42; 43)
43 STAR@[42; 43)
44 err: `expected COMMA`
45 WHITESPACE@[43; 48)
46 NAMED_FIELD_DEF@[48; 58)
47 VISIBILITY@[48; 51)
48 PUB_KW@[48; 51)
49 WHITESPACE@[51; 52)
50 NAME@[52; 53)
51 IDENT@[52; 53) "x"
52 COLON@[53; 54)
53 WHITESPACE@[54; 55)
54 PATH_TYPE@[55; 58)
55 PATH@[55; 58)
56 PATH_SEGMENT@[55; 58)
57 NAME_REF@[55; 58)
58 IDENT@[55; 58) "u32"
59 COMMA@[58; 59)
60 WHITESPACE@[59; 64)
61 NAMED_FIELD_DEF@[64; 70)
62 NAME@[64; 65)
63 IDENT@[64; 65) "z"
64 COLON@[65; 66)
65 WHITESPACE@[66; 67)
66 PATH_TYPE@[67; 70)
67 PATH@[67; 70)
68 PATH_SEGMENT@[67; 70)
69 NAME_REF@[67; 70)
70 IDENT@[67; 70) "f64"
71 COMMA@[70; 71)
72 WHITESPACE@[71; 72)
73 R_CURLY@[72; 73)
74 WHITESPACE@[73; 74)
diff --git a/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs
new file mode 100644
index 000000000..dc869fb78
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs
@@ -0,0 +1,9 @@
1}
2
3struct S;
4
5}
6
7fn foo(){}
8
9}
diff --git a/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt
new file mode 100644
index 000000000..802c69b31
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt
@@ -0,0 +1,32 @@
1ROOT@[0; 31)
2 ERROR@[0; 1)
3 R_CURLY@[0; 1)
4 err: `unmatched `}``
5 WHITESPACE@[1; 3)
6 STRUCT_DEF@[3; 12)
7 STRUCT_KW@[3; 9)
8 WHITESPACE@[9; 10)
9 NAME@[10; 11)
10 IDENT@[10; 11) "S"
11 SEMI@[11; 12)
12 WHITESPACE@[12; 14)
13 err: `unmatched `}``
14 ERROR@[14; 15)
15 R_CURLY@[14; 15)
16 WHITESPACE@[15; 17)
17 FN_DEF@[17; 27)
18 FN_KW@[17; 19)
19 WHITESPACE@[19; 20)
20 NAME@[20; 23)
21 IDENT@[20; 23) "foo"
22 PARAM_LIST@[23; 25)
23 L_PAREN@[23; 24)
24 R_PAREN@[24; 25)
25 BLOCK@[25; 27)
26 L_CURLY@[25; 26)
27 R_CURLY@[26; 27)
28 WHITESPACE@[27; 29)
29 err: `unmatched `}``
30 ERROR@[29; 30)
31 R_CURLY@[29; 30)
32 WHITESPACE@[30; 31)
diff --git a/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs
new file mode 100644
index 000000000..9fcac19b5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs
@@ -0,0 +1,13 @@
1fn foo() {
2}
3
4bar() {
5 if true {
6 1
7 } else {
8 2 + 3
9 }
10}
11
12fn baz() {
13}
diff --git a/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt
new file mode 100644
index 000000000..95a34333b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt
@@ -0,0 +1,70 @@
1ROOT@[0; 95)
2 FN_DEF@[0; 12)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 12)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 R_CURLY@[11; 12)
15 WHITESPACE@[12; 14)
16 MACRO_CALL@[14; 19)
17 PATH@[14; 17)
18 PATH_SEGMENT@[14; 17)
19 NAME_REF@[14; 17)
20 IDENT@[14; 17) "bar"
21 err: `expected EXCL`
22 TOKEN_TREE@[17; 19)
23 L_PAREN@[17; 18)
24 R_PAREN@[18; 19)
25 err: `expected SEMI`
26 WHITESPACE@[19; 20)
27 err: `expected an item`
28 ERROR@[20; 80)
29 L_CURLY@[20; 21)
30 WHITESPACE@[21; 26)
31 IF_KW@[26; 28)
32 WHITESPACE@[28; 29)
33 TRUE_KW@[29; 33)
34 WHITESPACE@[33; 34)
35 ERROR@[34; 51)
36 L_CURLY@[34; 35)
37 WHITESPACE@[35; 44)
38 INT_NUMBER@[44; 45) "1"
39 WHITESPACE@[45; 50)
40 R_CURLY@[50; 51)
41 WHITESPACE@[51; 52)
42 ELSE_KW@[52; 56)
43 WHITESPACE@[56; 57)
44 ERROR@[57; 78)
45 L_CURLY@[57; 58)
46 WHITESPACE@[58; 67)
47 INT_NUMBER@[67; 68) "2"
48 WHITESPACE@[68; 69)
49 PLUS@[69; 70)
50 WHITESPACE@[70; 71)
51 INT_NUMBER@[71; 72) "3"
52 WHITESPACE@[72; 77)
53 R_CURLY@[77; 78)
54 WHITESPACE@[78; 79)
55 R_CURLY@[79; 80)
56 WHITESPACE@[80; 82)
57 FN_DEF@[82; 94)
58 FN_KW@[82; 84)
59 WHITESPACE@[84; 85)
60 NAME@[85; 88)
61 IDENT@[85; 88) "baz"
62 PARAM_LIST@[88; 90)
63 L_PAREN@[88; 89)
64 R_PAREN@[89; 90)
65 WHITESPACE@[90; 91)
66 BLOCK@[91; 94)
67 L_CURLY@[91; 92)
68 WHITESPACE@[92; 93)
69 R_CURLY@[93; 94)
70 WHITESPACE@[94; 95)
diff --git a/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs
new file mode 100644
index 000000000..0dd30d0bd
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs
@@ -0,0 +1,5 @@
1struct S<90 + 2> {
2 f: u32
3}
4
5struct T;
diff --git a/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt
new file mode 100644
index 000000000..fa8adf881
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt
@@ -0,0 +1,44 @@
1ROOT@[0; 43)
2 STRUCT_DEF@[0; 11)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 11)
8 L_ANGLE@[8; 9)
9 err: `expected type parameter`
10 ERROR@[9; 11)
11 INT_NUMBER@[9; 11) "90"
12 err: `expected COMMA`
13 err: `expected R_ANGLE`
14 err: `expected `;`, `{`, or `(``
15 WHITESPACE@[11; 12)
16 err: `expected an item`
17 ERROR@[12; 13)
18 PLUS@[12; 13)
19 WHITESPACE@[13; 14)
20 err: `expected an item`
21 ERROR@[14; 15)
22 INT_NUMBER@[14; 15) "2"
23 err: `expected an item`
24 ERROR@[15; 16)
25 R_ANGLE@[15; 16)
26 WHITESPACE@[16; 17)
27 err: `expected an item`
28 ERROR@[17; 31)
29 L_CURLY@[17; 18)
30 WHITESPACE@[18; 23)
31 IDENT@[23; 24) "f"
32 COLON@[24; 25)
33 WHITESPACE@[25; 26)
34 IDENT@[26; 29) "u32"
35 WHITESPACE@[29; 30)
36 R_CURLY@[30; 31)
37 WHITESPACE@[31; 33)
38 STRUCT_DEF@[33; 42)
39 STRUCT_KW@[33; 39)
40 WHITESPACE@[39; 40)
41 NAME@[40; 41)
42 IDENT@[40; 41) "T"
43 SEMI@[41; 42)
44 WHITESPACE@[42; 43)
diff --git a/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs
new file mode 100644
index 000000000..985775282
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs
@@ -0,0 +1,3 @@
1fn main() {
2 || -> () unsafe { () };
3}
diff --git a/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt
new file mode 100644
index 000000000..38667e030
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt
@@ -0,0 +1,42 @@
1ROOT@[0; 42)
2 FN_DEF@[0; 41)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 41)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 EXPR_STMT@[16; 39)
15 LAMBDA_EXPR@[16; 38)
16 PARAM_LIST@[16; 18)
17 PIPE@[16; 17)
18 PIPE@[17; 18)
19 WHITESPACE@[18; 19)
20 RET_TYPE@[19; 24)
21 THIN_ARROW@[19; 21)
22 WHITESPACE@[21; 22)
23 TUPLE_TYPE@[22; 24)
24 L_PAREN@[22; 23)
25 R_PAREN@[23; 24)
26 err: `expected `{``
27 WHITESPACE@[24; 25)
28 BLOCK_EXPR@[25; 38)
29 UNSAFE_KW@[25; 31)
30 WHITESPACE@[31; 32)
31 BLOCK@[32; 38)
32 L_CURLY@[32; 33)
33 WHITESPACE@[33; 34)
34 TUPLE_EXPR@[34; 36)
35 L_PAREN@[34; 35)
36 R_PAREN@[35; 36)
37 WHITESPACE@[36; 37)
38 R_CURLY@[37; 38)
39 SEMI@[38; 39)
40 WHITESPACE@[39; 40)
41 R_CURLY@[40; 41)
42 WHITESPACE@[41; 42)
diff --git a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs
new file mode 100644
index 000000000..c1bd0a2d1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs
@@ -0,0 +1 @@
extern struct Foo;
diff --git a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt
new file mode 100644
index 000000000..0cb7447c4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt
@@ -0,0 +1,13 @@
1ROOT@[0; 19)
2 ERROR@[0; 6)
3 ABI@[0; 6)
4 EXTERN_KW@[0; 6)
5 err: `expected fn, trait or impl`
6 WHITESPACE@[6; 7)
7 STRUCT_DEF@[7; 18)
8 STRUCT_KW@[7; 13)
9 WHITESPACE@[13; 14)
10 NAME@[14; 17)
11 IDENT@[14; 17) "Foo"
12 SEMI@[17; 18)
13 WHITESPACE@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt b/crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt
new file mode 100644
index 000000000..a03aa05e3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt
@@ -0,0 +1,387 @@
1ROOT@[0; 389)
2 FN_DEF@[0; 389)
3 VISIBILITY@[0; 10)
4 PUB_KW@[0; 3)
5 L_PAREN@[3; 4)
6 SUPER_KW@[4; 9)
7 R_PAREN@[9; 10)
8 WHITESPACE@[10; 11)
9 FN_KW@[11; 13)
10 WHITESPACE@[13; 14)
11 NAME@[14; 21)
12 IDENT@[14; 21) "process"
13 TYPE_PARAM_LIST@[21; 38)
14 L_ANGLE@[21; 22)
15 LIFETIME_PARAM@[22; 24)
16 LIFETIME@[22; 24) "'a"
17 COMMA@[24; 25)
18 WHITESPACE@[25; 26)
19 TYPE_PARAM@[26; 37)
20 NAME@[26; 27)
21 IDENT@[26; 27) "S"
22 COLON@[27; 28)
23 WHITESPACE@[28; 29)
24 PATH@[29; 37)
25 PATH_SEGMENT@[29; 37)
26 NAME_REF@[29; 33)
27 IDENT@[29; 33) "Sink"
28 TYPE_ARG_LIST@[33; 37)
29 L_ANGLE@[33; 34)
30 LIFETIME_ARG@[34; 36)
31 LIFETIME@[34; 36) "'a"
32 R_ANGLE@[36; 37)
33 R_ANGLE@[37; 38)
34 PARAM_LIST@[38; 93)
35 L_PAREN@[38; 39)
36 PARAM@[39; 54)
37 BIND_PAT@[39; 46)
38 NAME@[39; 46)
39 IDENT@[39; 46) "builder"
40 COLON@[46; 47)
41 WHITESPACE@[47; 48)
42 REFERENCE_TYPE@[48; 54)
43 AMP@[48; 49)
44 MUT_KW@[49; 52)
45 WHITESPACE@[52; 53)
46 PATH_TYPE@[53; 54)
47 PATH@[53; 54)
48 PATH_SEGMENT@[53; 54)
49 NAME_REF@[53; 54)
50 IDENT@[53; 54) "S"
51 COMMA@[54; 55)
52 WHITESPACE@[55; 56)
53 PARAM@[56; 72)
54 BIND_PAT@[56; 62)
55 NAME@[56; 62)
56 IDENT@[56; 62) "tokens"
57 COLON@[62; 63)
58 WHITESPACE@[63; 64)
59 REFERENCE_TYPE@[64; 72)
60 AMP@[64; 65)
61 SLICE_TYPE@[65; 72)
62 L_BRACK@[65; 66)
63 PATH_TYPE@[66; 71)
64 PATH@[66; 71)
65 PATH_SEGMENT@[66; 71)
66 NAME_REF@[66; 71)
67 IDENT@[66; 71) "Token"
68 R_BRACK@[71; 72)
69 COMMA@[72; 73)
70 WHITESPACE@[73; 74)
71 PARAM@[74; 92)
72 BIND_PAT@[74; 80)
73 NAME@[74; 80)
74 IDENT@[74; 80) "events"
75 COLON@[80; 81)
76 WHITESPACE@[81; 82)
77 PATH_TYPE@[82; 92)
78 PATH@[82; 92)
79 PATH_SEGMENT@[82; 92)
80 NAME_REF@[82; 85)
81 IDENT@[82; 85) "Vec"
82 TYPE_ARG_LIST@[85; 92)
83 L_ANGLE@[85; 86)
84 TYPE_ARG@[86; 91)
85 PATH_TYPE@[86; 91)
86 PATH@[86; 91)
87 PATH_SEGMENT@[86; 91)
88 NAME_REF@[86; 91)
89 IDENT@[86; 91) "Event"
90 R_ANGLE@[91; 92)
91 R_PAREN@[92; 93)
92 WHITESPACE@[93; 94)
93 BLOCK_EXPR@[94; 389)
94 L_CURLY@[94; 95)
95 WHITESPACE@[95; 100)
96 LET_STMT@[100; 125)
97 LET_KW@[100; 103)
98 WHITESPACE@[103; 104)
99 BIND_PAT@[104; 120)
100 MUT_KW@[104; 107)
101 WHITESPACE@[107; 108)
102 NAME@[108; 120)
103 IDENT@[108; 120) "next_tok_idx"
104 WHITESPACE@[120; 121)
105 EQ@[121; 122)
106 WHITESPACE@[122; 123)
107 LITERAL@[123; 124)
108 INT_NUMBER@[123; 124) "0"
109 SEMI@[124; 125)
110 WHITESPACE@[125; 130)
111 LET_STMT@[130; 389)
112 LET_KW@[130; 133)
113 WHITESPACE@[133; 134)
114 BIND_PAT@[134; 140)
115 NAME@[134; 140)
116 IDENT@[134; 140) "eat_ws"
117 WHITESPACE@[140; 141)
118 EQ@[141; 142)
119 WHITESPACE@[142; 143)
120 LAMBDA_EXPR@[143; 389)
121 PARAM_LIST@[143; 388)
122 PIPE@[143; 144)
123 PARAM@[144; 159)
124 BIND_PAT@[144; 147)
125 NAME@[144; 147)
126 IDENT@[144; 147) "idx"
127 COLON@[147; 148)
128 WHITESPACE@[148; 149)
129 REFERENCE_TYPE@[149; 159)
130 AMP@[149; 150)
131 MUT_KW@[150; 153)
132 WHITESPACE@[153; 154)
133 PATH_TYPE@[154; 159)
134 PATH@[154; 159)
135 PATH_SEGMENT@[154; 159)
136 NAME_REF@[154; 159)
137 IDENT@[154; 159) "usize"
138 COMMA@[159; 160)
139 WHITESPACE@[160; 161)
140 PARAM@[161; 167)
141 REF_PAT@[161; 167)
142 AMP@[161; 162)
143 MUT_KW@[162; 165)
144 WHITESPACE@[165; 166)
145 err: `expected pattern`
146 ERROR@[166; 167)
147 PIPE@[166; 167)
148 err: `expected COMMA`
149 WHITESPACE@[167; 168)
150 err: `expected pattern`
151 PARAM@[168; 169)
152 ERROR@[168; 169)
153 L_CURLY@[168; 169)
154 err: `expected COMMA`
155 WHITESPACE@[169; 178)
156 err: `expected pattern`
157 PARAM@[178; 183)
158 ERROR@[178; 183)
159 WHILE_KW@[178; 183)
160 err: `expected COMMA`
161 WHITESPACE@[183; 184)
162 err: `expected pattern`
163 PARAM@[184; 187)
164 ERROR@[184; 187)
165 LET_KW@[184; 187)
166 err: `expected COMMA`
167 WHITESPACE@[187; 188)
168 PARAM@[188; 199)
169 TUPLE_STRUCT_PAT@[188; 199)
170 PATH@[188; 192)
171 PATH_SEGMENT@[188; 192)
172 NAME_REF@[188; 192)
173 IDENT@[188; 192) "Some"
174 L_PAREN@[192; 193)
175 BIND_PAT@[193; 198)
176 NAME@[193; 198)
177 IDENT@[193; 198) "token"
178 R_PAREN@[198; 199)
179 err: `expected COMMA`
180 WHITESPACE@[199; 200)
181 err: `expected pattern`
182 PARAM@[200; 201)
183 ERROR@[200; 201)
184 EQ@[200; 201)
185 err: `expected COMMA`
186 WHITESPACE@[201; 202)
187 PARAM@[202; 208)
188 BIND_PAT@[202; 208)
189 NAME@[202; 208)
190 IDENT@[202; 208) "tokens"
191 err: `expected COMMA`
192 err: `expected pattern`
193 PARAM@[208; 209)
194 ERROR@[208; 209)
195 DOT@[208; 209)
196 err: `expected COMMA`
197 PARAM@[209; 218)
198 TUPLE_STRUCT_PAT@[209; 218)
199 PATH@[209; 212)
200 PATH_SEGMENT@[209; 212)
201 NAME_REF@[209; 212)
202 IDENT@[209; 212) "get"
203 L_PAREN@[212; 213)
204 err: `expected pattern`
205 ERROR@[213; 214)
206 STAR@[213; 214)
207 err: `expected COMMA`
208 BIND_PAT@[214; 217)
209 NAME@[214; 217)
210 IDENT@[214; 217) "idx"
211 R_PAREN@[217; 218)
212 err: `expected COMMA`
213 WHITESPACE@[218; 219)
214 err: `expected pattern`
215 PARAM@[219; 220)
216 ERROR@[219; 220)
217 L_CURLY@[219; 220)
218 err: `expected COMMA`
219 WHITESPACE@[220; 233)
220 err: `expected pattern`
221 PARAM@[233; 235)
222 ERROR@[233; 235)
223 IF_KW@[233; 235)
224 err: `expected COMMA`
225 WHITESPACE@[235; 236)
226 err: `expected pattern`
227 PARAM@[236; 237)
228 ERROR@[236; 237)
229 EXCL@[236; 237)
230 err: `expected COMMA`
231 PARAM@[237; 242)
232 BIND_PAT@[237; 242)
233 NAME@[237; 242)
234 IDENT@[237; 242) "token"
235 err: `expected COMMA`
236 err: `expected pattern`
237 PARAM@[242; 243)
238 ERROR@[242; 243)
239 DOT@[242; 243)
240 err: `expected COMMA`
241 PARAM@[243; 247)
242 BIND_PAT@[243; 247)
243 NAME@[243; 247)
244 IDENT@[243; 247) "kind"
245 err: `expected COMMA`
246 err: `expected pattern`
247 PARAM@[247; 248)
248 ERROR@[247; 248)
249 DOT@[247; 248)
250 err: `expected COMMA`
251 PARAM@[248; 259)
252 TUPLE_STRUCT_PAT@[248; 259)
253 PATH@[248; 257)
254 PATH_SEGMENT@[248; 257)
255 NAME_REF@[248; 257)
256 IDENT@[248; 257) "is_trivia"
257 L_PAREN@[257; 258)
258 R_PAREN@[258; 259)
259 err: `expected COMMA`
260 WHITESPACE@[259; 260)
261 err: `expected pattern`
262 PARAM@[260; 261)
263 ERROR@[260; 261)
264 L_CURLY@[260; 261)
265 err: `expected COMMA`
266 WHITESPACE@[261; 278)
267 PARAM@[278; 283)
268 BIND_PAT@[278; 283)
269 NAME@[278; 283)
270 IDENT@[278; 283) "break"
271 err: `expected COMMA`
272 err: `expected pattern`
273 PARAM@[283; 284)
274 ERROR@[283; 284)
275 SEMI@[283; 284)
276 err: `expected COMMA`
277 WHITESPACE@[284; 297)
278 err: `expected pattern`
279 PARAM@[297; 298)
280 ERROR@[297; 298)
281 R_CURLY@[297; 298)
282 err: `expected COMMA`
283 WHITESPACE@[298; 311)
284 PARAM@[311; 318)
285 BIND_PAT@[311; 318)
286 NAME@[311; 318)
287 IDENT@[311; 318) "builder"
288 err: `expected COMMA`
289 err: `expected pattern`
290 PARAM@[318; 319)
291 ERROR@[318; 319)
292 DOT@[318; 319)
293 err: `expected COMMA`
294 PARAM@[319; 346)
295 TUPLE_STRUCT_PAT@[319; 346)
296 PATH@[319; 323)
297 PATH_SEGMENT@[319; 323)
298 NAME_REF@[319; 323)
299 IDENT@[319; 323) "leaf"
300 L_PAREN@[323; 324)
301 BIND_PAT@[324; 329)
302 NAME@[324; 329)
303 IDENT@[324; 329) "token"
304 err: `expected COMMA`
305 err: `expected pattern`
306 ERROR@[329; 330)
307 DOT@[329; 330)
308 err: `expected COMMA`
309 BIND_PAT@[330; 334)
310 NAME@[330; 334)
311 IDENT@[330; 334) "kind"
312 COMMA@[334; 335)
313 WHITESPACE@[335; 336)
314 BIND_PAT@[336; 341)
315 NAME@[336; 341)
316 IDENT@[336; 341) "token"
317 err: `expected COMMA`
318 err: `expected pattern`
319 ERROR@[341; 342)
320 DOT@[341; 342)
321 err: `expected COMMA`
322 BIND_PAT@[342; 345)
323 NAME@[342; 345)
324 IDENT@[342; 345) "len"
325 R_PAREN@[345; 346)
326 err: `expected COMMA`
327 err: `expected pattern`
328 PARAM@[346; 347)
329 ERROR@[346; 347)
330 SEMI@[346; 347)
331 err: `expected COMMA`
332 WHITESPACE@[347; 360)
333 err: `expected pattern`
334 PARAM@[360; 361)
335 ERROR@[360; 361)
336 STAR@[360; 361)
337 err: `expected COMMA`
338 PARAM@[361; 364)
339 BIND_PAT@[361; 364)
340 NAME@[361; 364)
341 IDENT@[361; 364) "idx"
342 err: `expected COMMA`
343 WHITESPACE@[364; 365)
344 err: `expected pattern`
345 PARAM@[365; 366)
346 ERROR@[365; 366)
347 PLUS@[365; 366)
348 err: `expected COMMA`
349 err: `expected pattern`
350 PARAM@[366; 367)
351 ERROR@[366; 367)
352 EQ@[366; 367)
353 err: `expected COMMA`
354 WHITESPACE@[367; 368)
355 PARAM@[368; 369)
356 LITERAL@[368; 369)
357 INT_NUMBER@[368; 369) "1"
358 err: `expected COMMA`
359 WHITESPACE@[369; 378)
360 err: `expected pattern`
361 PARAM@[378; 379)
362 ERROR@[378; 379)
363 R_CURLY@[378; 379)
364 err: `expected COMMA`
365 WHITESPACE@[379; 384)
366 err: `expected pattern`
367 PARAM@[384; 385)
368 ERROR@[384; 385)
369 R_CURLY@[384; 385)
370 err: `expected COMMA`
371 err: `expected pattern`
372 PARAM@[385; 386)
373 ERROR@[385; 386)
374 SEMI@[385; 386)
375 err: `expected COMMA`
376 WHITESPACE@[386; 387)
377 err: `expected pattern`
378 PARAM@[387; 388)
379 ERROR@[387; 388)
380 R_CURLY@[387; 388)
381 err: `expected COMMA`
382 err: `expected PIPE`
383 WHITESPACE@[388; 389)
384 err: `expected expression`
385 err: `expected SEMI`
386 err: `expected R_CURLY`
387 ERROR@[389; 389)
diff --git a/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs
new file mode 100644
index 000000000..20dde3bc3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs
@@ -0,0 +1,7 @@
1pub struct Cache(
2 RefCell<HashMap<
3 TypeId,
4 Box<@ Any>,
5 >>
6);
7
diff --git a/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt
new file mode 100644
index 000000000..e1a6b6432
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt
@@ -0,0 +1,89 @@
1ROOT@[0; 86)
2 STRUCT_DEF@[0; 72)
3 VISIBILITY@[0; 3)
4 PUB_KW@[0; 3)
5 WHITESPACE@[3; 4)
6 STRUCT_KW@[4; 10)
7 WHITESPACE@[10; 11)
8 NAME@[11; 16)
9 IDENT@[11; 16) "Cache"
10 POS_FIELD_LIST@[16; 72)
11 L_PAREN@[16; 17)
12 WHITESPACE@[17; 22)
13 POS_FIELD@[22; 68)
14 PATH_TYPE@[22; 68)
15 PATH@[22; 68)
16 PATH_SEGMENT@[22; 68)
17 NAME_REF@[22; 29)
18 IDENT@[22; 29) "RefCell"
19 TYPE_ARG_LIST@[29; 68)
20 L_ANGLE@[29; 30)
21 TYPE_ARG@[30; 68)
22 PATH_TYPE@[30; 68)
23 PATH@[30; 68)
24 PATH_SEGMENT@[30; 68)
25 NAME_REF@[30; 37)
26 IDENT@[30; 37) "HashMap"
27 TYPE_ARG_LIST@[37; 68)
28 L_ANGLE@[37; 38)
29 WHITESPACE@[38; 47)
30 TYPE_ARG@[47; 53)
31 PATH_TYPE@[47; 53)
32 PATH@[47; 53)
33 PATH_SEGMENT@[47; 53)
34 NAME_REF@[47; 53)
35 IDENT@[47; 53) "TypeId"
36 COMMA@[53; 54)
37 WHITESPACE@[54; 63)
38 TYPE_ARG@[63; 68)
39 PATH_TYPE@[63; 68)
40 PATH@[63; 68)
41 PATH_SEGMENT@[63; 68)
42 NAME_REF@[63; 66)
43 IDENT@[63; 66) "Box"
44 TYPE_ARG_LIST@[66; 68)
45 L_ANGLE@[66; 67)
46 err: `expected type`
47 TYPE_ARG@[67; 68)
48 ERROR@[67; 68)
49 AT@[67; 68)
50 err: `expected COMMA`
51 err: `expected R_ANGLE`
52 err: `expected COMMA`
53 err: `expected R_ANGLE`
54 err: `expected COMMA`
55 err: `expected R_ANGLE`
56 err: `expected COMMA`
57 WHITESPACE@[68; 69)
58 POS_FIELD@[69; 72)
59 PATH_TYPE@[69; 72)
60 PATH@[69; 72)
61 PATH_SEGMENT@[69; 72)
62 NAME_REF@[69; 72)
63 IDENT@[69; 72) "Any"
64 err: `expected COMMA`
65 err: `expected a type`
66 err: `expected R_PAREN`
67 err: `expected SEMI`
68 err: `expected an item`
69 ERROR@[72; 72)
70 ERROR@[72; 73)
71 R_ANGLE@[72; 73)
72 err: `expected an item`
73 ERROR@[73; 74)
74 COMMA@[73; 74)
75 WHITESPACE@[74; 79)
76 err: `expected an item`
77 ERROR@[79; 80)
78 R_ANGLE@[79; 80)
79 err: `expected an item`
80 ERROR@[80; 81)
81 R_ANGLE@[80; 81)
82 WHITESPACE@[81; 82)
83 err: `expected an item`
84 ERROR@[82; 83)
85 R_PAREN@[82; 83)
86 err: `expected an item`
87 ERROR@[83; 84)
88 SEMI@[83; 84)
89 WHITESPACE@[84; 86)
diff --git a/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs
new file mode 100644
index 000000000..75c1d2f98
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs
@@ -0,0 +1 @@
fn foo<T>() where T {}
diff --git a/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt
new file mode 100644
index 000000000..37826ce86
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt
@@ -0,0 +1,31 @@
1ROOT@[0; 23)
2 FN_DEF@[0; 22)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 TYPE_PARAM_LIST@[6; 9)
8 L_ANGLE@[6; 7)
9 TYPE_PARAM@[7; 8)
10 NAME@[7; 8)
11 IDENT@[7; 8) "T"
12 R_ANGLE@[8; 9)
13 PARAM_LIST@[9; 11)
14 L_PAREN@[9; 10)
15 R_PAREN@[10; 11)
16 WHITESPACE@[11; 12)
17 WHERE_CLAUSE@[12; 19)
18 WHERE_KW@[12; 17)
19 WHITESPACE@[17; 18)
20 WHERE_PRED@[18; 19)
21 PATH_TYPE@[18; 19)
22 PATH@[18; 19)
23 PATH_SEGMENT@[18; 19)
24 NAME_REF@[18; 19)
25 IDENT@[18; 19) "T"
26 err: `expected colon`
27 WHITESPACE@[19; 20)
28 BLOCK@[20; 22)
29 L_CURLY@[20; 21)
30 R_CURLY@[21; 22)
31 WHITESPACE@[22; 23)
diff --git a/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs
new file mode 100644
index 000000000..156e70251
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs
@@ -0,0 +1,2 @@
1fn foo(}) {
2}
diff --git a/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt
new file mode 100644
index 000000000..5f736a978
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt
@@ -0,0 +1,24 @@
1ROOT@[0; 14)
2 FN_DEF@[0; 7)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 7)
8 L_PAREN@[6; 7)
9 err: `expected value parameter`
10 err: `expected R_PAREN`
11 err: `expected a block`
12 err: `unmatched `}``
13 ERROR@[7; 8)
14 R_CURLY@[7; 8)
15 err: `expected an item`
16 ERROR@[8; 9)
17 R_PAREN@[8; 9)
18 WHITESPACE@[9; 10)
19 err: `expected an item`
20 ERROR@[10; 13)
21 L_CURLY@[10; 11)
22 WHITESPACE@[11; 12)
23 R_CURLY@[12; 13)
24 WHITESPACE@[13; 14)
diff --git a/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs
new file mode 100644
index 000000000..9ae857686
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 foo(
3 1, 2
4 )
5 return 92;
6}
diff --git a/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt
new file mode 100644
index 000000000..a3163adcb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt
@@ -0,0 +1,43 @@
1ROOT@[0; 56)
2 FN_DEF@[0; 55)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 55)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 38)
15 CALL_EXPR@[15; 38)
16 PATH_EXPR@[15; 18)
17 PATH@[15; 18)
18 PATH_SEGMENT@[15; 18)
19 NAME_REF@[15; 18)
20 IDENT@[15; 18) "foo"
21 ARG_LIST@[18; 38)
22 L_PAREN@[18; 19)
23 WHITESPACE@[19; 28)
24 LITERAL@[28; 29)
25 INT_NUMBER@[28; 29) "1"
26 COMMA@[29; 30)
27 WHITESPACE@[30; 31)
28 LITERAL@[31; 32)
29 INT_NUMBER@[31; 32) "2"
30 WHITESPACE@[32; 37)
31 R_PAREN@[37; 38)
32 err: `expected SEMI`
33 WHITESPACE@[38; 43)
34 EXPR_STMT@[43; 53)
35 RETURN_EXPR@[43; 52)
36 RETURN_KW@[43; 49)
37 WHITESPACE@[49; 50)
38 LITERAL@[50; 52)
39 INT_NUMBER@[50; 52) "92"
40 SEMI@[52; 53)
41 WHITESPACE@[53; 54)
42 R_CURLY@[54; 55)
43 WHITESPACE@[55; 56)
diff --git a/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs
new file mode 100644
index 000000000..17bd49777
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs
@@ -0,0 +1,4 @@
1fn foo(foo: i32) {
2 let bar = 92;
3 1 +
4}
diff --git a/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt
new file mode 100644
index 000000000..f0be287ad
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt
@@ -0,0 +1,46 @@
1ROOT@[0; 47)
2 FN_DEF@[0; 46)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 16)
8 L_PAREN@[6; 7)
9 PARAM@[7; 15)
10 BIND_PAT@[7; 10)
11 NAME@[7; 10)
12 IDENT@[7; 10) "foo"
13 COLON@[10; 11)
14 WHITESPACE@[11; 12)
15 PATH_TYPE@[12; 15)
16 PATH@[12; 15)
17 PATH_SEGMENT@[12; 15)
18 NAME_REF@[12; 15)
19 IDENT@[12; 15) "i32"
20 R_PAREN@[15; 16)
21 WHITESPACE@[16; 17)
22 BLOCK@[17; 46)
23 L_CURLY@[17; 18)
24 WHITESPACE@[18; 23)
25 LET_STMT@[23; 36)
26 LET_KW@[23; 26)
27 WHITESPACE@[26; 27)
28 BIND_PAT@[27; 30)
29 NAME@[27; 30)
30 IDENT@[27; 30) "bar"
31 WHITESPACE@[30; 31)
32 EQ@[31; 32)
33 WHITESPACE@[32; 33)
34 LITERAL@[33; 35)
35 INT_NUMBER@[33; 35) "92"
36 SEMI@[35; 36)
37 WHITESPACE@[36; 41)
38 BIN_EXPR@[41; 44)
39 LITERAL@[41; 42)
40 INT_NUMBER@[41; 42) "1"
41 WHITESPACE@[42; 43)
42 PLUS@[43; 44)
43 err: `expected expression`
44 WHITESPACE@[44; 45)
45 R_CURLY@[45; 46)
46 WHITESPACE@[46; 47)
diff --git a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs
new file mode 100644
index 000000000..fe604006c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs
@@ -0,0 +1,8 @@
1impl FnScopes {
2 fn new_scope(&) -> ScopeId {
3 let res = self.scopes.len();
4 self.scopes.push(ScopeData { parent: None, entries: vec![] })
5 }
6
7 fn set_parent
8}
diff --git a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
new file mode 100644
index 000000000..c4d9f5e7e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
@@ -0,0 +1,131 @@
1ROOT@[0; 183)
2 IMPL_ITEM@[0; 182)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 13)
6 PATH@[5; 13)
7 PATH_SEGMENT@[5; 13)
8 NAME_REF@[5; 13)
9 IDENT@[5; 13) "FnScopes"
10 WHITESPACE@[13; 14)
11 ITEM_LIST@[14; 182)
12 L_CURLY@[14; 15)
13 WHITESPACE@[15; 20)
14 FN_DEF@[20; 161)
15 FN_KW@[20; 22)
16 WHITESPACE@[22; 23)
17 NAME@[23; 32)
18 IDENT@[23; 32) "new_scope"
19 PARAM_LIST@[32; 35)
20 L_PAREN@[32; 33)
21 PARAM@[33; 34)
22 REF_PAT@[33; 34)
23 AMP@[33; 34)
24 err: `expected pattern`
25 err: `expected COLON`
26 err: `expected type`
27 R_PAREN@[34; 35)
28 WHITESPACE@[35; 36)
29 RET_TYPE@[36; 46)
30 THIN_ARROW@[36; 38)
31 WHITESPACE@[38; 39)
32 PATH_TYPE@[39; 46)
33 PATH@[39; 46)
34 PATH_SEGMENT@[39; 46)
35 NAME_REF@[39; 46)
36 IDENT@[39; 46) "ScopeId"
37 WHITESPACE@[46; 47)
38 BLOCK@[47; 161)
39 L_CURLY@[47; 48)
40 WHITESPACE@[48; 57)
41 LET_STMT@[57; 85)
42 LET_KW@[57; 60)
43 WHITESPACE@[60; 61)
44 BIND_PAT@[61; 64)
45 NAME@[61; 64)
46 IDENT@[61; 64) "res"
47 WHITESPACE@[64; 65)
48 EQ@[65; 66)
49 WHITESPACE@[66; 67)
50 METHOD_CALL_EXPR@[67; 84)
51 FIELD_EXPR@[67; 78)
52 PATH_EXPR@[67; 71)
53 PATH@[67; 71)
54 PATH_SEGMENT@[67; 71)
55 SELF_KW@[67; 71)
56 DOT@[71; 72)
57 NAME_REF@[72; 78)
58 IDENT@[72; 78) "scopes"
59 DOT@[78; 79)
60 NAME_REF@[79; 82)
61 IDENT@[79; 82) "len"
62 ARG_LIST@[82; 84)
63 L_PAREN@[82; 83)
64 R_PAREN@[83; 84)
65 SEMI@[84; 85)
66 WHITESPACE@[85; 94)
67 METHOD_CALL_EXPR@[94; 155)
68 FIELD_EXPR@[94; 105)
69 PATH_EXPR@[94; 98)
70 PATH@[94; 98)
71 PATH_SEGMENT@[94; 98)
72 SELF_KW@[94; 98)
73 DOT@[98; 99)
74 NAME_REF@[99; 105)
75 IDENT@[99; 105) "scopes"
76 DOT@[105; 106)
77 NAME_REF@[106; 110)
78 IDENT@[106; 110) "push"
79 ARG_LIST@[110; 155)
80 L_PAREN@[110; 111)
81 STRUCT_LIT@[111; 154)
82 PATH@[111; 120)
83 PATH_SEGMENT@[111; 120)
84 NAME_REF@[111; 120)
85 IDENT@[111; 120) "ScopeData"
86 WHITESPACE@[120; 121)
87 NAMED_FIELD_LIST@[121; 154)
88 L_CURLY@[121; 122)
89 WHITESPACE@[122; 123)
90 NAMED_FIELD@[123; 135)
91 NAME_REF@[123; 129)
92 IDENT@[123; 129) "parent"
93 COLON@[129; 130)
94 WHITESPACE@[130; 131)
95 PATH_EXPR@[131; 135)
96 PATH@[131; 135)
97 PATH_SEGMENT@[131; 135)
98 NAME_REF@[131; 135)
99 IDENT@[131; 135) "None"
100 COMMA@[135; 136)
101 WHITESPACE@[136; 137)
102 NAMED_FIELD@[137; 152)
103 NAME_REF@[137; 144)
104 IDENT@[137; 144) "entries"
105 COLON@[144; 145)
106 WHITESPACE@[145; 146)
107 MACRO_CALL@[146; 152)
108 PATH@[146; 149)
109 PATH_SEGMENT@[146; 149)
110 NAME_REF@[146; 149)
111 IDENT@[146; 149) "vec"
112 EXCL@[149; 150)
113 TOKEN_TREE@[150; 152)
114 L_BRACK@[150; 151)
115 R_BRACK@[151; 152)
116 WHITESPACE@[152; 153)
117 R_CURLY@[153; 154)
118 R_PAREN@[154; 155)
119 WHITESPACE@[155; 160)
120 R_CURLY@[160; 161)
121 WHITESPACE@[161; 167)
122 FN_DEF@[167; 180)
123 FN_KW@[167; 169)
124 WHITESPACE@[169; 170)
125 NAME@[170; 180)
126 IDENT@[170; 180) "set_parent"
127 err: `expected function arguments`
128 err: `expected a block`
129 WHITESPACE@[180; 181)
130 R_CURLY@[181; 182)
131 WHITESPACE@[182; 183)
diff --git a/crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs
new file mode 100644
index 000000000..48bf3d68b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs
@@ -0,0 +1,12 @@
1fn foo() {
2 let foo =
3 let bar = 1;
4 let
5 let baz = 92;
6 let
7 if true {}
8 let
9 while true {}
10 let
11 loop {}
12}
diff --git a/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt
new file mode 100644
index 000000000..6e74771f1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt
@@ -0,0 +1,103 @@
1ROOT@[0; 139)
2 FN_DEF@[0; 138)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 138)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 24)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 BIND_PAT@[19; 22)
18 NAME@[19; 22)
19 IDENT@[19; 22) "foo"
20 WHITESPACE@[22; 23)
21 EQ@[23; 24)
22 err: `expected expression`
23 err: `expected SEMI`
24 WHITESPACE@[24; 29)
25 LET_STMT@[29; 41)
26 LET_KW@[29; 32)
27 WHITESPACE@[32; 33)
28 BIND_PAT@[33; 36)
29 NAME@[33; 36)
30 IDENT@[33; 36) "bar"
31 WHITESPACE@[36; 37)
32 EQ@[37; 38)
33 WHITESPACE@[38; 39)
34 LITERAL@[39; 40)
35 INT_NUMBER@[39; 40) "1"
36 SEMI@[40; 41)
37 WHITESPACE@[41; 46)
38 LET_STMT@[46; 49)
39 LET_KW@[46; 49)
40 err: `expected pattern`
41 err: `expected SEMI`
42 WHITESPACE@[49; 54)
43 LET_STMT@[54; 67)
44 LET_KW@[54; 57)
45 WHITESPACE@[57; 58)
46 BIND_PAT@[58; 61)
47 NAME@[58; 61)
48 IDENT@[58; 61) "baz"
49 WHITESPACE@[61; 62)
50 EQ@[62; 63)
51 WHITESPACE@[63; 64)
52 LITERAL@[64; 66)
53 INT_NUMBER@[64; 66) "92"
54 SEMI@[66; 67)
55 WHITESPACE@[67; 72)
56 LET_STMT@[72; 75)
57 LET_KW@[72; 75)
58 err: `expected pattern`
59 err: `expected SEMI`
60 WHITESPACE@[75; 80)
61 EXPR_STMT@[80; 90)
62 IF_EXPR@[80; 90)
63 IF_KW@[80; 82)
64 WHITESPACE@[82; 83)
65 CONDITION@[83; 87)
66 LITERAL@[83; 87)
67 TRUE_KW@[83; 87)
68 WHITESPACE@[87; 88)
69 BLOCK@[88; 90)
70 L_CURLY@[88; 89)
71 R_CURLY@[89; 90)
72 WHITESPACE@[90; 95)
73 LET_STMT@[95; 98)
74 LET_KW@[95; 98)
75 err: `expected pattern`
76 err: `expected SEMI`
77 WHITESPACE@[98; 103)
78 EXPR_STMT@[103; 116)
79 WHILE_EXPR@[103; 116)
80 WHILE_KW@[103; 108)
81 WHITESPACE@[108; 109)
82 CONDITION@[109; 113)
83 LITERAL@[109; 113)
84 TRUE_KW@[109; 113)
85 WHITESPACE@[113; 114)
86 BLOCK@[114; 116)
87 L_CURLY@[114; 115)
88 R_CURLY@[115; 116)
89 WHITESPACE@[116; 121)
90 LET_STMT@[121; 124)
91 LET_KW@[121; 124)
92 err: `expected pattern`
93 err: `expected SEMI`
94 WHITESPACE@[124; 129)
95 LOOP_EXPR@[129; 136)
96 LOOP_KW@[129; 133)
97 WHITESPACE@[133; 134)
98 BLOCK@[134; 136)
99 L_CURLY@[134; 135)
100 R_CURLY@[135; 136)
101 WHITESPACE@[136; 137)
102 R_CURLY@[137; 138)
103 WHITESPACE@[138; 139)
diff --git a/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs
new file mode 100644
index 000000000..3393b668b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs
@@ -0,0 +1,3 @@
1fn
2
3fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt
new file mode 100644
index 000000000..b5218b0fa
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt
@@ -0,0 +1,20 @@
1ROOT@[0; 16)
2 FN_DEF@[0; 2)
3 FN_KW@[0; 2)
4 err: `expected a name`
5 err: `expected function arguments`
6 err: `expected a block`
7 WHITESPACE@[2; 4)
8 FN_DEF@[4; 15)
9 FN_KW@[4; 6)
10 WHITESPACE@[6; 7)
11 NAME@[7; 10)
12 IDENT@[7; 10) "foo"
13 PARAM_LIST@[10; 12)
14 L_PAREN@[10; 11)
15 R_PAREN@[11; 12)
16 WHITESPACE@[12; 13)
17 BLOCK@[13; 15)
18 L_CURLY@[13; 14)
19 R_CURLY@[14; 15)
20 WHITESPACE@[15; 16)
diff --git a/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs
new file mode 100644
index 000000000..7a6c264f6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs
@@ -0,0 +1,2 @@
1fn foo(x: i32, y) {
2}
diff --git a/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt
new file mode 100644
index 000000000..8dcb58ae2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt
@@ -0,0 +1,34 @@
1ROOT@[0; 22)
2 FN_DEF@[0; 21)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 17)
8 L_PAREN@[6; 7)
9 PARAM@[7; 13)
10 BIND_PAT@[7; 8)
11 NAME@[7; 8)
12 IDENT@[7; 8) "x"
13 COLON@[8; 9)
14 WHITESPACE@[9; 10)
15 PATH_TYPE@[10; 13)
16 PATH@[10; 13)
17 PATH_SEGMENT@[10; 13)
18 NAME_REF@[10; 13)
19 IDENT@[10; 13) "i32"
20 COMMA@[13; 14)
21 WHITESPACE@[14; 15)
22 PARAM@[15; 16)
23 BIND_PAT@[15; 16)
24 NAME@[15; 16)
25 IDENT@[15; 16) "y"
26 err: `expected COLON`
27 err: `expected type`
28 R_PAREN@[16; 17)
29 WHITESPACE@[17; 18)
30 BLOCK@[18; 21)
31 L_CURLY@[18; 19)
32 WHITESPACE@[19; 20)
33 R_CURLY@[20; 21)
34 WHITESPACE@[21; 22)
diff --git a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs
new file mode 100644
index 000000000..cd2d493a1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs
@@ -0,0 +1,3 @@
1fn a() { [1, 2, @, struct, let] }
2fn b() { foo(1, 2, @, impl, let) }
3fn c() { foo.bar(1, 2, @, ], trait, let) }
diff --git a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
new file mode 100644
index 000000000..287e56ac4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
@@ -0,0 +1,189 @@
1ROOT@[0; 112)
2 FN_DEF@[0; 33)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 4)
6 IDENT@[3; 4) "a"
7 PARAM_LIST@[4; 6)
8 L_PAREN@[4; 5)
9 R_PAREN@[5; 6)
10 WHITESPACE@[6; 7)
11 BLOCK@[7; 33)
12 L_CURLY@[7; 8)
13 WHITESPACE@[8; 9)
14 EXPR_STMT@[9; 15)
15 ARRAY_EXPR@[9; 15)
16 L_BRACK@[9; 10)
17 LITERAL@[10; 11)
18 INT_NUMBER@[10; 11) "1"
19 COMMA@[11; 12)
20 WHITESPACE@[12; 13)
21 LITERAL@[13; 14)
22 INT_NUMBER@[13; 14) "2"
23 COMMA@[14; 15)
24 err: `expected expression`
25 err: `expected R_BRACK`
26 err: `expected SEMI`
27 WHITESPACE@[15; 16)
28 err: `expected expression`
29 EXPR_STMT@[16; 17)
30 ERROR@[16; 17)
31 AT@[16; 17)
32 err: `expected SEMI`
33 err: `expected expression`
34 EXPR_STMT@[17; 18)
35 ERROR@[17; 18)
36 COMMA@[17; 18)
37 err: `expected SEMI`
38 WHITESPACE@[18; 19)
39 STRUCT_DEF@[19; 26)
40 STRUCT_KW@[19; 25)
41 err: `expected a name`
42 ERROR@[25; 26)
43 COMMA@[25; 26)
44 err: `expected `;`, `{`, or `(``
45 WHITESPACE@[26; 27)
46 LET_STMT@[27; 31)
47 LET_KW@[27; 30)
48 err: `expected pattern`
49 ERROR@[30; 31)
50 R_BRACK@[30; 31)
51 err: `expected SEMI`
52 WHITESPACE@[31; 32)
53 R_CURLY@[32; 33)
54 WHITESPACE@[33; 34)
55 FN_DEF@[34; 68)
56 FN_KW@[34; 36)
57 WHITESPACE@[36; 37)
58 NAME@[37; 38)
59 IDENT@[37; 38) "b"
60 PARAM_LIST@[38; 40)
61 L_PAREN@[38; 39)
62 R_PAREN@[39; 40)
63 WHITESPACE@[40; 41)
64 BLOCK@[41; 68)
65 L_CURLY@[41; 42)
66 WHITESPACE@[42; 43)
67 EXPR_STMT@[43; 52)
68 CALL_EXPR@[43; 52)
69 PATH_EXPR@[43; 46)
70 PATH@[43; 46)
71 PATH_SEGMENT@[43; 46)
72 NAME_REF@[43; 46)
73 IDENT@[43; 46) "foo"
74 ARG_LIST@[46; 52)
75 L_PAREN@[46; 47)
76 LITERAL@[47; 48)
77 INT_NUMBER@[47; 48) "1"
78 COMMA@[48; 49)
79 WHITESPACE@[49; 50)
80 LITERAL@[50; 51)
81 INT_NUMBER@[50; 51) "2"
82 COMMA@[51; 52)
83 err: `expected expression`
84 err: `expected SEMI`
85 WHITESPACE@[52; 53)
86 err: `expected expression`
87 EXPR_STMT@[53; 54)
88 ERROR@[53; 54)
89 AT@[53; 54)
90 err: `expected SEMI`
91 err: `expected expression`
92 EXPR_STMT@[54; 55)
93 ERROR@[54; 55)
94 COMMA@[54; 55)
95 err: `expected SEMI`
96 WHITESPACE@[55; 56)
97 IMPL_ITEM@[56; 60)
98 IMPL_KW@[56; 60)
99 err: `expected type`
100 err: `expected `{``
101 err: `expected expression`
102 EXPR_STMT@[60; 61)
103 ERROR@[60; 61)
104 COMMA@[60; 61)
105 err: `expected SEMI`
106 WHITESPACE@[61; 62)
107 LET_STMT@[62; 65)
108 LET_KW@[62; 65)
109 err: `expected pattern`
110 err: `expected SEMI`
111 err: `expected expression`
112 ERROR@[65; 66)
113 R_PAREN@[65; 66)
114 WHITESPACE@[66; 67)
115 R_CURLY@[67; 68)
116 WHITESPACE@[68; 69)
117 FN_DEF@[69; 111)
118 FN_KW@[69; 71)
119 WHITESPACE@[71; 72)
120 NAME@[72; 73)
121 IDENT@[72; 73) "c"
122 PARAM_LIST@[73; 75)
123 L_PAREN@[73; 74)
124 R_PAREN@[74; 75)
125 WHITESPACE@[75; 76)
126 BLOCK@[76; 111)
127 L_CURLY@[76; 77)
128 WHITESPACE@[77; 78)
129 EXPR_STMT@[78; 91)
130 METHOD_CALL_EXPR@[78; 91)
131 PATH_EXPR@[78; 81)
132 PATH@[78; 81)
133 PATH_SEGMENT@[78; 81)
134 NAME_REF@[78; 81)
135 IDENT@[78; 81) "foo"
136 DOT@[81; 82)
137 NAME_REF@[82; 85)
138 IDENT@[82; 85) "bar"
139 ARG_LIST@[85; 91)
140 L_PAREN@[85; 86)
141 LITERAL@[86; 87)
142 INT_NUMBER@[86; 87) "1"
143 COMMA@[87; 88)
144 WHITESPACE@[88; 89)
145 LITERAL@[89; 90)
146 INT_NUMBER@[89; 90) "2"
147 COMMA@[90; 91)
148 err: `expected expression`
149 err: `expected SEMI`
150 WHITESPACE@[91; 92)
151 err: `expected expression`
152 EXPR_STMT@[92; 93)
153 ERROR@[92; 93)
154 AT@[92; 93)
155 err: `expected SEMI`
156 err: `expected expression`
157 EXPR_STMT@[93; 94)
158 ERROR@[93; 94)
159 COMMA@[93; 94)
160 err: `expected SEMI`
161 WHITESPACE@[94; 95)
162 err: `expected expression`
163 EXPR_STMT@[95; 96)
164 ERROR@[95; 96)
165 R_BRACK@[95; 96)
166 err: `expected SEMI`
167 err: `expected expression`
168 EXPR_STMT@[96; 97)
169 ERROR@[96; 97)
170 COMMA@[96; 97)
171 err: `expected SEMI`
172 WHITESPACE@[97; 98)
173 TRAIT_DEF@[98; 104)
174 TRAIT_KW@[98; 103)
175 err: `expected a name`
176 ERROR@[103; 104)
177 COMMA@[103; 104)
178 err: `expected `{``
179 WHITESPACE@[104; 105)
180 LET_STMT@[105; 108)
181 LET_KW@[105; 108)
182 err: `expected pattern`
183 err: `expected SEMI`
184 err: `expected expression`
185 ERROR@[108; 109)
186 R_PAREN@[108; 109)
187 WHITESPACE@[109; 110)
188 R_CURLY@[110; 111)
189 WHITESPACE@[111; 112)
diff --git a/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs
new file mode 100644
index 000000000..0206d563e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs
@@ -0,0 +1,5 @@
1fn main() {
2 foo! (
3 bar, "baz", 1, 2.0
4 } //~ ERROR incorrect close delimiter
5}
diff --git a/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt
new file mode 100644
index 000000000..2df81b12b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt
@@ -0,0 +1,43 @@
1ROOT@[0; 94)
2 FN_DEF@[0; 55)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 55)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 MACRO_CALL@[16; 49)
15 PATH@[16; 19)
16 PATH_SEGMENT@[16; 19)
17 NAME_REF@[16; 19)
18 IDENT@[16; 19) "foo"
19 EXCL@[19; 20)
20 WHITESPACE@[20; 21)
21 TOKEN_TREE@[21; 49)
22 L_PAREN@[21; 22)
23 WHITESPACE@[22; 31)
24 IDENT@[31; 34) "bar"
25 COMMA@[34; 35)
26 WHITESPACE@[35; 36)
27 STRING@[36; 41)
28 COMMA@[41; 42)
29 WHITESPACE@[42; 43)
30 INT_NUMBER@[43; 44) "1"
31 COMMA@[44; 45)
32 WHITESPACE@[45; 46)
33 FLOAT_NUMBER@[46; 49) "2.0"
34 err: `unmatched `}``
35 WHITESPACE@[49; 54)
36 R_CURLY@[54; 55)
37 WHITESPACE@[55; 56)
38 COMMENT@[56; 91)
39 WHITESPACE@[91; 92)
40 err: `unmatched `}``
41 ERROR@[92; 93)
42 R_CURLY@[92; 93)
43 WHITESPACE@[93; 94)
diff --git a/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs
new file mode 100644
index 000000000..6c2e95c02
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs
@@ -0,0 +1,7 @@
1fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {}
2
3fn main() {
4 let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
5 let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>;
6 let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
7}
diff --git a/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt
new file mode 100644
index 000000000..195c12e08
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt
@@ -0,0 +1,310 @@
1ROOT@[0; 240)
2 FN_DEF@[0; 53)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 4)
6 IDENT@[3; 4) "f"
7 TYPE_PARAM_LIST@[4; 48)
8 L_ANGLE@[4; 5)
9 TYPE_PARAM@[5; 47)
10 NAME@[5; 6)
11 IDENT@[5; 6) "T"
12 COLON@[6; 7)
13 WHITESPACE@[7; 8)
14 L_PAREN@[8; 9)
15 PATH_TYPE@[9; 13)
16 PATH@[9; 13)
17 PATH_SEGMENT@[9; 13)
18 NAME_REF@[9; 13)
19 IDENT@[9; 13) "Copy"
20 R_PAREN@[13; 14)
21 WHITESPACE@[14; 15)
22 PLUS@[15; 16)
23 WHITESPACE@[16; 17)
24 L_PAREN@[17; 18)
25 QUESTION@[18; 19)
26 PATH_TYPE@[19; 24)
27 PATH@[19; 24)
28 PATH_SEGMENT@[19; 24)
29 NAME_REF@[19; 24)
30 IDENT@[19; 24) "Sized"
31 R_PAREN@[24; 25)
32 WHITESPACE@[25; 26)
33 PLUS@[26; 27)
34 WHITESPACE@[27; 28)
35 L_PAREN@[28; 29)
36 FOR_TYPE@[29; 46)
37 FOR_KW@[29; 32)
38 TYPE_PARAM_LIST@[32; 36)
39 L_ANGLE@[32; 33)
40 LIFETIME_PARAM@[33; 35)
41 LIFETIME@[33; 35) "'a"
42 R_ANGLE@[35; 36)
43 WHITESPACE@[36; 37)
44 PATH_TYPE@[37; 46)
45 PATH@[37; 46)
46 PATH_SEGMENT@[37; 46)
47 NAME_REF@[37; 42)
48 IDENT@[37; 42) "Trait"
49 TYPE_ARG_LIST@[42; 46)
50 L_ANGLE@[42; 43)
51 LIFETIME_ARG@[43; 45)
52 LIFETIME@[43; 45) "'a"
53 R_ANGLE@[45; 46)
54 R_PAREN@[46; 47)
55 R_ANGLE@[47; 48)
56 PARAM_LIST@[48; 50)
57 L_PAREN@[48; 49)
58 R_PAREN@[49; 50)
59 WHITESPACE@[50; 51)
60 BLOCK@[51; 53)
61 L_CURLY@[51; 52)
62 R_CURLY@[52; 53)
63 WHITESPACE@[53; 55)
64 FN_DEF@[55; 239)
65 FN_KW@[55; 57)
66 WHITESPACE@[57; 58)
67 NAME@[58; 62)
68 IDENT@[58; 62) "main"
69 PARAM_LIST@[62; 64)
70 L_PAREN@[62; 63)
71 R_PAREN@[63; 64)
72 WHITESPACE@[64; 65)
73 BLOCK@[65; 239)
74 L_CURLY@[65; 66)
75 WHITESPACE@[66; 71)
76 LET_STMT@[71; 121)
77 LET_KW@[71; 74)
78 WHITESPACE@[74; 75)
79 PLACEHOLDER_PAT@[75; 76)
80 UNDERSCORE@[75; 76)
81 COLON@[76; 77)
82 WHITESPACE@[77; 78)
83 PATH_TYPE@[78; 121)
84 PATH@[78; 88)
85 PATH_SEGMENT@[78; 88)
86 NAME_REF@[78; 81)
87 IDENT@[78; 81) "Box"
88 TYPE_ARG_LIST@[81; 88)
89 L_ANGLE@[81; 82)
90 TYPE_ARG@[82; 88)
91 PAREN_TYPE@[82; 88)
92 L_PAREN@[82; 83)
93 PATH_TYPE@[83; 87)
94 PATH@[83; 87)
95 PATH_SEGMENT@[83; 87)
96 NAME_REF@[83; 87)
97 IDENT@[83; 87) "Copy"
98 R_PAREN@[87; 88)
99 err: `expected COMMA`
100 err: `expected R_ANGLE`
101 WHITESPACE@[88; 89)
102 PLUS@[89; 90)
103 WHITESPACE@[90; 91)
104 L_PAREN@[91; 92)
105 QUESTION@[92; 93)
106 PATH_TYPE@[93; 98)
107 PATH@[93; 98)
108 PATH_SEGMENT@[93; 98)
109 NAME_REF@[93; 98)
110 IDENT@[93; 98) "Sized"
111 R_PAREN@[98; 99)
112 WHITESPACE@[99; 100)
113 PLUS@[100; 101)
114 WHITESPACE@[101; 102)
115 L_PAREN@[102; 103)
116 FOR_TYPE@[103; 120)
117 FOR_KW@[103; 106)
118 TYPE_PARAM_LIST@[106; 110)
119 L_ANGLE@[106; 107)
120 LIFETIME_PARAM@[107; 109)
121 LIFETIME@[107; 109) "'a"
122 R_ANGLE@[109; 110)
123 WHITESPACE@[110; 111)
124 PATH_TYPE@[111; 120)
125 PATH@[111; 120)
126 PATH_SEGMENT@[111; 120)
127 NAME_REF@[111; 116)
128 IDENT@[111; 116) "Trait"
129 TYPE_ARG_LIST@[116; 120)
130 L_ANGLE@[116; 117)
131 LIFETIME_ARG@[117; 119)
132 LIFETIME@[117; 119) "'a"
133 R_ANGLE@[119; 120)
134 R_PAREN@[120; 121)
135 err: `expected SEMI`
136 err: `expected expression`
137 EXPR_STMT@[121; 123)
138 ERROR@[121; 122)
139 R_ANGLE@[121; 122)
140 SEMI@[122; 123)
141 WHITESPACE@[123; 128)
142 LET_STMT@[128; 141)
143 LET_KW@[128; 131)
144 WHITESPACE@[131; 132)
145 PLACEHOLDER_PAT@[132; 133)
146 UNDERSCORE@[132; 133)
147 COLON@[133; 134)
148 WHITESPACE@[134; 135)
149 PATH_TYPE@[135; 141)
150 PATH@[135; 141)
151 PATH_SEGMENT@[135; 141)
152 NAME_REF@[135; 138)
153 IDENT@[135; 138) "Box"
154 TYPE_ARG_LIST@[138; 141)
155 L_ANGLE@[138; 139)
156 TYPE_ARG@[139; 141)
157 PAREN_TYPE@[139; 141)
158 L_PAREN@[139; 140)
159 err: `expected type`
160 ERROR@[140; 141)
161 QUESTION@[140; 141)
162 err: `expected R_PAREN`
163 err: `expected COMMA`
164 err: `expected R_ANGLE`
165 err: `expected SEMI`
166 EXPR_STMT@[141; 146)
167 PATH_EXPR@[141; 146)
168 PATH@[141; 146)
169 PATH_SEGMENT@[141; 146)
170 NAME_REF@[141; 146)
171 IDENT@[141; 146) "Sized"
172 err: `expected SEMI`
173 err: `expected expression`
174 EXPR_STMT@[146; 147)
175 ERROR@[146; 147)
176 R_PAREN@[146; 147)
177 err: `expected SEMI`
178 WHITESPACE@[147; 148)
179 err: `expected expression`
180 EXPR_STMT@[148; 149)
181 ERROR@[148; 149)
182 PLUS@[148; 149)
183 err: `expected SEMI`
184 WHITESPACE@[149; 150)
185 EXPR_STMT@[150; 151)
186 PAREN_EXPR@[150; 151)
187 L_PAREN@[150; 151)
188 err: `expected expression`
189 err: `expected R_PAREN`
190 err: `expected SEMI`
191 EXPR_STMT@[151; 157)
192 FOR_EXPR@[151; 157)
193 FOR_KW@[151; 154)
194 err: `expected pattern`
195 ERROR@[154; 155)
196 L_ANGLE@[154; 155)
197 err: `expected IN_KW`
198 err: `expected expression`
199 ERROR@[155; 157)
200 LIFETIME@[155; 157) "'a"
201 err: `expected a block`
202 err: `expected expression`
203 EXPR_STMT@[157; 158)
204 ERROR@[157; 158)
205 R_ANGLE@[157; 158)
206 err: `expected SEMI`
207 WHITESPACE@[158; 159)
208 EXPR_STMT@[159; 180)
209 BIN_EXPR@[159; 180)
210 BIN_EXPR@[159; 178)
211 BIN_EXPR@[159; 169)
212 BIN_EXPR@[159; 167)
213 PATH_EXPR@[159; 164)
214 PATH@[159; 164)
215 PATH_SEGMENT@[159; 164)
216 NAME_REF@[159; 164)
217 IDENT@[159; 164) "Trait"
218 L_ANGLE@[164; 165)
219 err: `expected expression`
220 ERROR@[165; 167)
221 LIFETIME@[165; 167) "'a"
222 R_ANGLE@[167; 168)
223 err: `expected expression`
224 ERROR@[168; 169)
225 R_PAREN@[168; 169)
226 WHITESPACE@[169; 170)
227 PLUS@[170; 171)
228 WHITESPACE@[171; 172)
229 PAREN_EXPR@[172; 178)
230 L_PAREN@[172; 173)
231 PATH_EXPR@[173; 177)
232 PATH@[173; 177)
233 PATH_SEGMENT@[173; 177)
234 NAME_REF@[173; 177)
235 IDENT@[173; 177) "Copy"
236 R_PAREN@[177; 178)
237 R_ANGLE@[178; 179)
238 err: `expected expression`
239 ERROR@[179; 180)
240 SEMI@[179; 180)
241 err: `expected SEMI`
242 WHITESPACE@[180; 185)
243 LET_STMT@[185; 235)
244 LET_KW@[185; 188)
245 WHITESPACE@[188; 189)
246 PLACEHOLDER_PAT@[189; 190)
247 UNDERSCORE@[189; 190)
248 COLON@[190; 191)
249 WHITESPACE@[191; 192)
250 PATH_TYPE@[192; 235)
251 PATH@[192; 215)
252 PATH_SEGMENT@[192; 215)
253 NAME_REF@[192; 195)
254 IDENT@[192; 195) "Box"
255 TYPE_ARG_LIST@[195; 215)
256 L_ANGLE@[195; 196)
257 TYPE_ARG@[196; 215)
258 PAREN_TYPE@[196; 215)
259 L_PAREN@[196; 197)
260 FOR_TYPE@[197; 214)
261 FOR_KW@[197; 200)
262 TYPE_PARAM_LIST@[200; 204)
263 L_ANGLE@[200; 201)
264 LIFETIME_PARAM@[201; 203)
265 LIFETIME@[201; 203) "'a"
266 R_ANGLE@[203; 204)
267 WHITESPACE@[204; 205)
268 PATH_TYPE@[205; 214)
269 PATH@[205; 214)
270 PATH_SEGMENT@[205; 214)
271 NAME_REF@[205; 210)
272 IDENT@[205; 210) "Trait"
273 TYPE_ARG_LIST@[210; 214)
274 L_ANGLE@[210; 211)
275 LIFETIME_ARG@[211; 213)
276 LIFETIME@[211; 213) "'a"
277 R_ANGLE@[213; 214)
278 R_PAREN@[214; 215)
279 err: `expected COMMA`
280 err: `expected R_ANGLE`
281 WHITESPACE@[215; 216)
282 PLUS@[216; 217)
283 WHITESPACE@[217; 218)
284 L_PAREN@[218; 219)
285 PATH_TYPE@[219; 223)
286 PATH@[219; 223)
287 PATH_SEGMENT@[219; 223)
288 NAME_REF@[219; 223)
289 IDENT@[219; 223) "Copy"
290 R_PAREN@[223; 224)
291 WHITESPACE@[224; 225)
292 PLUS@[225; 226)
293 WHITESPACE@[226; 227)
294 L_PAREN@[227; 228)
295 QUESTION@[228; 229)
296 PATH_TYPE@[229; 234)
297 PATH@[229; 234)
298 PATH_SEGMENT@[229; 234)
299 NAME_REF@[229; 234)
300 IDENT@[229; 234) "Sized"
301 R_PAREN@[234; 235)
302 err: `expected SEMI`
303 err: `expected expression`
304 EXPR_STMT@[235; 237)
305 ERROR@[235; 236)
306 R_ANGLE@[235; 236)
307 SEMI@[236; 237)
308 WHITESPACE@[237; 238)
309 R_CURLY@[238; 239)
310 WHITESPACE@[239; 240)
diff --git a/crates/ra_syntax/tests/data/parser/err/0025_nope.rs b/crates/ra_syntax/tests/data/parser/err/0025_nope.rs
new file mode 100644
index 000000000..28726ed51
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0025_nope.rs
@@ -0,0 +1,31 @@
1fn main() {
2 enum Test {
3 Var1,
4 Var2(String),
5 Var3 {
6 abc: {}, //~ ERROR: expected type, found `{`
7 },
8 }
9
10 // recover...
11 let a = 1;
12 enum Test2 {
13 Fine,
14 }
15
16 enum Test3 {
17 StillFine {
18 def: i32,
19 },
20 }
21
22 {
23 // fail again
24 enum Test4 {
25 Nope(i32 {}) //~ ERROR: found `{`
26 //~^ ERROR: found `{`
27 }
28 }
29 // still recover later
30 let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
31}
diff --git a/crates/ra_syntax/tests/data/parser/err/0025_nope.txt b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt
new file mode 100644
index 000000000..c30b8585f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt
@@ -0,0 +1,203 @@
1ROOT@[0; 575)
2 FN_DEF@[0; 574)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 574)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 ENUM_DEF@[16; 152)
15 ENUM_KW@[16; 20)
16 WHITESPACE@[20; 21)
17 NAME@[21; 25)
18 IDENT@[21; 25) "Test"
19 WHITESPACE@[25; 26)
20 ENUM_VARIANT_LIST@[26; 152)
21 L_CURLY@[26; 27)
22 WHITESPACE@[27; 36)
23 ENUM_VARIANT@[36; 40)
24 NAME@[36; 40)
25 IDENT@[36; 40) "Var1"
26 COMMA@[40; 41)
27 WHITESPACE@[41; 50)
28 ENUM_VARIANT@[50; 62)
29 NAME@[50; 54)
30 IDENT@[50; 54) "Var2"
31 POS_FIELD_LIST@[54; 62)
32 L_PAREN@[54; 55)
33 POS_FIELD@[55; 61)
34 PATH_TYPE@[55; 61)
35 PATH@[55; 61)
36 PATH_SEGMENT@[55; 61)
37 NAME_REF@[55; 61)
38 IDENT@[55; 61) "String"
39 R_PAREN@[61; 62)
40 COMMA@[62; 63)
41 WHITESPACE@[63; 72)
42 ENUM_VARIANT@[72; 145)
43 NAME@[72; 76)
44 IDENT@[72; 76) "Var3"
45 WHITESPACE@[76; 77)
46 NAMED_FIELD_DEF_LIST@[77; 145)
47 L_CURLY@[77; 78)
48 WHITESPACE@[78; 91)
49 NAMED_FIELD_DEF@[91; 95)
50 NAME@[91; 94)
51 IDENT@[91; 94) "abc"
52 COLON@[94; 95)
53 err: `expected type`
54 err: `expected COMMA`
55 WHITESPACE@[95; 96)
56 err: `expected field`
57 ERROR@[96; 98)
58 L_CURLY@[96; 97)
59 R_CURLY@[97; 98)
60 err: `expected field declaration`
61 ERROR@[98; 99)
62 COMMA@[98; 99)
63 WHITESPACE@[99; 100)
64 COMMENT@[100; 135)
65 WHITESPACE@[135; 144)
66 R_CURLY@[144; 145)
67 COMMA@[145; 146)
68 WHITESPACE@[146; 151)
69 R_CURLY@[151; 152)
70 WHITESPACE@[152; 158)
71 COMMENT@[158; 171)
72 WHITESPACE@[171; 176)
73 LET_STMT@[176; 186)
74 LET_KW@[176; 179)
75 WHITESPACE@[179; 180)
76 BIND_PAT@[180; 181)
77 NAME@[180; 181)
78 IDENT@[180; 181) "a"
79 WHITESPACE@[181; 182)
80 EQ@[182; 183)
81 WHITESPACE@[183; 184)
82 LITERAL@[184; 185)
83 INT_NUMBER@[184; 185) "1"
84 SEMI@[185; 186)
85 WHITESPACE@[186; 191)
86 ENUM_DEF@[191; 223)
87 ENUM_KW@[191; 195)
88 WHITESPACE@[195; 196)
89 NAME@[196; 201)
90 IDENT@[196; 201) "Test2"
91 WHITESPACE@[201; 202)
92 ENUM_VARIANT_LIST@[202; 223)
93 L_CURLY@[202; 203)
94 WHITESPACE@[203; 212)
95 ENUM_VARIANT@[212; 216)
96 NAME@[212; 216)
97 IDENT@[212; 216) "Fine"
98 COMMA@[216; 217)
99 WHITESPACE@[217; 222)
100 R_CURLY@[222; 223)
101 WHITESPACE@[223; 229)
102 ENUM_DEF@[229; 300)
103 ENUM_KW@[229; 233)
104 WHITESPACE@[233; 234)
105 NAME@[234; 239)
106 IDENT@[234; 239) "Test3"
107 WHITESPACE@[239; 240)
108 ENUM_VARIANT_LIST@[240; 300)
109 L_CURLY@[240; 241)
110 WHITESPACE@[241; 250)
111 ENUM_VARIANT@[250; 293)
112 NAME@[250; 259)
113 IDENT@[250; 259) "StillFine"
114 WHITESPACE@[259; 260)
115 NAMED_FIELD_DEF_LIST@[260; 293)
116 L_CURLY@[260; 261)
117 WHITESPACE@[261; 274)
118 NAMED_FIELD_DEF@[274; 282)
119 NAME@[274; 277)
120 IDENT@[274; 277) "def"
121 COLON@[277; 278)
122 WHITESPACE@[278; 279)
123 PATH_TYPE@[279; 282)
124 PATH@[279; 282)
125 PATH_SEGMENT@[279; 282)
126 NAME_REF@[279; 282)
127 IDENT@[279; 282) "i32"
128 COMMA@[282; 283)
129 WHITESPACE@[283; 292)
130 R_CURLY@[292; 293)
131 COMMA@[293; 294)
132 WHITESPACE@[294; 299)
133 R_CURLY@[299; 300)
134 WHITESPACE@[300; 306)
135 EXPR_STMT@[306; 459)
136 BLOCK_EXPR@[306; 459)
137 BLOCK@[306; 459)
138 L_CURLY@[306; 307)
139 WHITESPACE@[307; 316)
140 COMMENT@[316; 329)
141 WHITESPACE@[329; 338)
142 ENUM_DEF@[338; 453)
143 ENUM_KW@[338; 342)
144 WHITESPACE@[342; 343)
145 NAME@[343; 348)
146 IDENT@[343; 348) "Test4"
147 WHITESPACE@[348; 349)
148 ENUM_VARIANT_LIST@[349; 453)
149 L_CURLY@[349; 350)
150 WHITESPACE@[350; 363)
151 ENUM_VARIANT@[363; 372)
152 NAME@[363; 367)
153 IDENT@[363; 367) "Nope"
154 POS_FIELD_LIST@[367; 372)
155 L_PAREN@[367; 368)
156 POS_FIELD@[368; 371)
157 PATH_TYPE@[368; 371)
158 PATH@[368; 371)
159 PATH_SEGMENT@[368; 371)
160 NAME_REF@[368; 371)
161 IDENT@[368; 371) "i32"
162 err: `expected COMMA`
163 WHITESPACE@[371; 372)
164 err: `expected a type`
165 err: `expected R_PAREN`
166 err: `expected COMMA`
167 err: `expected enum variant`
168 ERROR@[372; 372)
169 ERROR@[372; 374)
170 L_CURLY@[372; 373)
171 R_CURLY@[373; 374)
172 err: `expected enum variant`
173 ERROR@[374; 375)
174 R_PAREN@[374; 375)
175 WHITESPACE@[375; 376)
176 COMMENT@[376; 396)
177 WHITESPACE@[396; 422)
178 COMMENT@[422; 443)
179 WHITESPACE@[443; 452)
180 R_CURLY@[452; 453)
181 WHITESPACE@[453; 458)
182 R_CURLY@[458; 459)
183 WHITESPACE@[459; 464)
184 COMMENT@[464; 486)
185 WHITESPACE@[486; 491)
186 LET_STMT@[491; 510)
187 LET_KW@[491; 494)
188 WHITESPACE@[494; 495)
189 BIND_PAT@[495; 505)
190 NAME@[495; 505)
191 IDENT@[495; 505) "bad_syntax"
192 WHITESPACE@[505; 506)
193 EQ@[506; 507)
194 WHITESPACE@[507; 508)
195 err: `expected expression`
196 ERROR@[508; 509)
197 UNDERSCORE@[508; 509)
198 SEMI@[509; 510)
199 WHITESPACE@[510; 511)
200 COMMENT@[511; 572)
201 WHITESPACE@[572; 573)
202 R_CURLY@[573; 574)
203 WHITESPACE@[574; 575)
diff --git a/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs b/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs
new file mode 100644
index 000000000..53c93d9e9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs
@@ -0,0 +1,199 @@
1//! An experimental implementation of [Rust RFC#2256 lrs);
2 let root = SyntaxNode::new_owned(root);
3 validate_block_structure(root.borrowed());
4 File { root }
5 }
6 pub fn parse(text: &str) -> File {
7 let tokens = tokenize(&text);
8 let (green, errors) = parser_impl::parse_with::<yellow::GreenBuilder>(
9 text, &tokens, grammar::root,
10 );
11 File::new(green, errors)
12 }
13 pub fn reparse(&self, edit: &AtomEdit) -> File {
14 self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
15 }
16 pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> {
17 let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?;
18 let text = replace_range(
19 node.text().to_string(),
20 edit.delete - node.range().start(),
21 &edit.insert,
22 );
23 let tokens = tokenize(&text);
24 if !is_balanced(&tokens) {
25 return None;
26 }
27 let (green, new_errors) = parser_impl::parse_with::<yellow::GreenBuilder>(
28 &te2t, &tokens, reparser,
29 );
30 let green_root = node.replace_with(green);
31 let errors = merge_errors(self.errors(), new_errors, node, edit);
32 Some(File::new(green_root, errors))
33 }
34 fn full_reparse(&self, edit: &AtomEdit) -> File {
35 let text = replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert);
36 File::parse(&text)
37 }
38 pub fn ast(&self) -> ast::Root {
39 ast::Root::cast(self.syntax()).unwrap()
40 }
41 pub fn syntax(&self) -> SyntaxNodeRef {
42 self.root.brroowed()
43 }
44 mp_tree(root),
45 );
46 assert!(
47 node.next_sibling().is_none() && pair.prev_sibling().is_none(),
48 "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n",
49 node,
50 root.text(),
51 node.text(),
52 );
53 }
54 }
55 _ => (),
56 }
57 }
58}
59
60#[derive(Debug, Clone)]
61pub struct AtomEdit {
62 pub delete: TextRange,
63 pub insert: String,
64}
65
66impl AtomEdit {
67 pub fn replace(range: TextRange, replace_with: String) -> AtomEdit {
68 AtomEdit { delete: range, insert: replace_with }
69 }
70
71 pub fn delete(range: TextRange) -> AtomEdit {
72 AtomEdit::replace(range, String::new())
73 }
74
75 pub fn insert(offset: TextUnit, text: String) -> AtomEdit {
76 AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text)
77 }
78}
79
80fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(SyntaxNodeRef, fn(&mut Parser))> {
81 let node = algo::find_covering_node(node, range);
82 return algo::ancestors(node)
83 .filter_map(|node| reparser(node).map(|r| (node, r)))
84 .next();
85
86 fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> {
87 let res = match node.kind() {
88 BLOCK => grammar::block,
89 NAMED_FIELD_DEF_LIST => grammar::named_field_def_list,
90 _ => return None,
91 };
92 Some(res)
93 }
94}
95
96pub /*(meh)*/ fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String {
97 let start = u32::from(range.start()) as usize;
98 let end = u32::from(range.end()) as usize;
99 text.replace_range(start..end, replace_with);
100 text
101}
102
103fn is_balanced(tokens: &[Token]) -> bool {
104 if tokens.len() == 0
105 || tokens.first().unwrap().kind != L_CURLY
106 || tokens.last().unwrap().kind != R_CURLY {
107 return false
108 }
109 let mut balance = 0usize;
110 for t in tokens.iter() {
111 match t.kind {
112 L_CURLYt {
113 pub delete: TextRange,
114 pub insert: String,
115}
116
117impl AtomEdit {
118 pub fn replace(range: TextRange, replace_with: String) -> AtomEdit {
119 AtomEdit { delete: range, insert: replace_with }
120 }
121
122 pub fn delete(range: TextRange) -> AtomEdit {
123 AtomEdit::replace(range, String::new())
124 }
125
126 pub fn insert(offset: TextUnit, text: String) -> AtomEdit {
127 AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text)
128 }
129}
130
131fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(SyntaxNodeRef, fn(&mut Parser))> {
132 let node = algo::find_covering_node(node, range);
133 return algo::ancestors(node)
134 .filter_map(|node| reparser(node).map(|r| (node, r)))
135 .next();
136
137 fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> {
138 let res = match node.kind() {
139 ;
140 let end = u32::from(range.end()) as usize;
141 text.replaT => grammar::named_field_def_list,
142 _ => return None,
143 };
144 Some(res)
145 }
146}
147
148pub /*(meh)*/ fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String {
149 let start = u32::from(range.start()) as usize;
150 let end = u32::from(range.end()) as usize;
151 text.replace_range(start..end, replace_with);
152 text
153}
154
155fn is_balanced(tokens: &[Token]) -> bool {
156 if tokens.len() == 0
157 || tokens.first().unwrap().kind != L_CURLY
158 || tokens.last().unwrap().kind != R_CURLY {
159 return false
160 }
161 let mut balance = 0usize;
162 for t in tokens.iter() {
163 match t.kind {
164 L_CURLY => balance += 1,
165 R_CURLY => balance = match balance.checked_sub(1) {
166 Some(b) => b,
167 None => return false,
168 },
169 _ => (),
170 }
171 }
172 balance == 0
173}
174
175fn merge_errors(
176 old_errors: Vec<SyntaxError>,
177 new_errors: Vec<SyntaxError>,
178 old_node: SyntaxNodeRef,
179 edit: &AtomEdit,
180) -> Vec<SyntaxError> {
181 let mut res = Vec::new();
182 for e in old_errors {
183 if e.offset < old_node.range().start() {
184 res.push(e)
185 } else if e.offset > old_node.range().end() {
186 res.push(SyntaxError {
187 msg: e.msg,
188 offset: e.offset + TextUnit::of_str(&edit.insert) - edit.delete.len(),
189 })
190 }
191 }
192 for e in new_errors {
193 res.push(SyntaxError {
194 msg: e.msg,
195 offset: e.offset + old_node.range().start(),
196 })
197 }
198 res
199}
diff --git a/crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs b/crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs
new file mode 100644
index 000000000..099cc5f84
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs
@@ -0,0 +1,106 @@
1use ra_syntax::{
2 File, TextRange, SyntaxNodeRef, TextUnit,
3 SyntaxKind::*,
4 algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node, ancestors, Direction, siblings},
5};
6
7pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> {
8 let syntax = file.syntax();
9 extend(syntax.borrowed(), range)
10}
11
12pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> {
13 if range.is_empty() {
14 let offset = range.start();
15 let mut leaves = find_leaf_at_offset(root, offset);
16 if leaves.clone().all(|it| it.kind() == WHITESPACE) {
17 return Some(extend_ws(root, leaves.next()?, offset));
18 }
19 let leaf = match leaves {
20 LeafAtOffset::None => return None,
21 LeafAtOffset::Single(l) => l,
22 LeafAtOffset::Between(l, r) => pick_best(l, r),
23 };
24 return Some(leaf.range());
25 };
26 let node = find_covering_node(root, range);
27 if node.kind() == COMMENT && range == node.range() {
28 if let Some(range) = extend_comments(node) {
29 return Some(range);
30 }
31 }
32
33 match ancestors(node).skip_while(|n| n.range() == range).next() {
34 None => None,
35 Some(parent) => Some(parent.range()),
36 }
37}
38
39fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange {
40 let ws_text = ws.leaf_text().unwrap();
41 let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start();
42 let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start();
43 let ws_suffix = &ws_text.as_str()[suffix];
44 let ws_prefix = &ws_text.as_str()[prefix];
45 if ws_text.contains("\n") && !ws_suffix.contains("\n") {
46 if let Some(node) = ws.next_sibling() {
47 let start = match ws_prefix.rfind('\n') {
48 Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32),
49 None => node.range().start()
50 };
51 let end = if root.text().char_at(node.range().end()) == Some('\n') {
52 node.range().end() + TextUnit::of_char('\n')
53 } else {
54 node.range().end()
55 };
56 return TextRange::from_to(start, end);
57 }
58 }
59 ws.range()
60}
61
62fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: Syntd[axNodeRef<'a>) -> SyntaxNodeRef<'a> {
63 return if priority(r) > priority(l) { r } else { l };
64 fn priority(n: SyntaxNodeRef) -> usize {
65 match n.kind() {
66 WHITESPACE => 0,
67 IDENT | SELF_KW | SUPER_KW | CRATE_KW => 2,
68 _ => 1,
69 }
70 }
71}
72
73fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
74 let left = adj_com[ments(node, Direction::Backward);
75 let right = adj_comments(node, Direction::Forward);
76 if left != right {
77 Some(TextRange::from_to(
78 left.range().start(),
79 right.range().end(),
80 ))
81 } else {
82 None
83 }
84}
85
86fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
87 let mut res = node;
88 for node in siblings(node, dir) {
89 match node.kind() {
90 COMMENT => res = node,
91 WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
92 _ => break
93 }
94 }
95 res
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use test_utils::extract_offset;
102
103 fn do_check(before: &str, afters: &[&str]) {
104 let (cursor, before) = extract_offset(before);
105 let file = File::parse(&before);
106 let mut range = TextRange::of
diff --git a/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs
new file mode 100644
index 000000000..31a1e435f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs
@@ -0,0 +1 @@
const unsafe fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt
new file mode 100644
index 000000000..956532981
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt
@@ -0,0 +1,18 @@
1ROOT@[0; 25)
2 FN_DEF@[0; 24)
3 CONST_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 UNSAFE_KW@[6; 12)
6 WHITESPACE@[12; 13)
7 FN_KW@[13; 15)
8 WHITESPACE@[15; 16)
9 NAME@[16; 19)
10 IDENT@[16; 19) "foo"
11 PARAM_LIST@[19; 21)
12 L_PAREN@[19; 20)
13 R_PAREN@[20; 21)
14 WHITESPACE@[21; 22)
15 BLOCK@[22; 24)
16 L_CURLY@[22; 23)
17 R_CURLY@[23; 24)
18 WHITESPACE@[24; 25)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs
new file mode 100644
index 000000000..8c84d9cd7
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs
@@ -0,0 +1 @@
const fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt
new file mode 100644
index 000000000..bda875fc5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt
@@ -0,0 +1,16 @@
1ROOT@[0; 18)
2 FN_DEF@[0; 17)
3 CONST_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 FN_KW@[6; 8)
6 WHITESPACE@[8; 9)
7 NAME@[9; 12)
8 IDENT@[9; 12) "foo"
9 PARAM_LIST@[12; 14)
10 L_PAREN@[12; 13)
11 R_PAREN@[13; 14)
12 WHITESPACE@[14; 15)
13 BLOCK@[15; 17)
14 L_CURLY@[15; 16)
15 R_CURLY@[16; 17)
16 WHITESPACE@[17; 18)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs
new file mode 100644
index 000000000..26a9ccd1e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs
@@ -0,0 +1 @@
extern {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt
new file mode 100644
index 000000000..2c2bbd035
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt
@@ -0,0 +1,9 @@
1ROOT@[0; 10)
2 EXTERN_BLOCK@[0; 9)
3 ABI@[0; 6)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 EXTERN_ITEM_LIST@[7; 9)
7 L_CURLY@[7; 8)
8 R_CURLY@[8; 9)
9 WHITESPACE@[9; 10)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs
new file mode 100644
index 000000000..394a049f0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs
@@ -0,0 +1 @@
extern fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt
new file mode 100644
index 000000000..f6e769475
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt
@@ -0,0 +1,17 @@
1ROOT@[0; 19)
2 FN_DEF@[0; 18)
3 ABI@[0; 6)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 FN_KW@[7; 9)
7 WHITESPACE@[9; 10)
8 NAME@[10; 13)
9 IDENT@[10; 13) "foo"
10 PARAM_LIST@[13; 15)
11 L_PAREN@[13; 14)
12 R_PAREN@[14; 15)
13 WHITESPACE@[15; 16)
14 BLOCK@[16; 18)
15 L_CURLY@[16; 17)
16 R_CURLY@[17; 18)
17 WHITESPACE@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs
new file mode 100644
index 000000000..49af74e1b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs
@@ -0,0 +1 @@
extern crate foo;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt
new file mode 100644
index 000000000..fc025b0f3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt
@@ -0,0 +1,10 @@
1ROOT@[0; 18)
2 EXTERN_CRATE_ITEM@[0; 17)
3 EXTERN_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 CRATE_KW@[7; 12)
6 WHITESPACE@[12; 13)
7 NAME@[13; 16)
8 IDENT@[13; 16) "foo"
9 SEMI@[16; 17)
10 WHITESPACE@[17; 18)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs
new file mode 100644
index 000000000..04e021550
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs
@@ -0,0 +1 @@
unsafe trait T {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt
new file mode 100644
index 000000000..fb97cc042
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt
@@ -0,0 +1,13 @@
1ROOT@[0; 18)
2 TRAIT_DEF@[0; 17)
3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 TRAIT_KW@[7; 12)
6 WHITESPACE@[12; 13)
7 NAME@[13; 14)
8 IDENT@[13; 14) "T"
9 WHITESPACE@[14; 15)
10 ITEM_LIST@[15; 17)
11 L_CURLY@[15; 16)
12 R_CURLY@[16; 17)
13 WHITESPACE@[17; 18)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs
new file mode 100644
index 000000000..41055f41d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs
@@ -0,0 +1 @@
unsafe impl Foo {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt
new file mode 100644
index 000000000..fa596394f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt
@@ -0,0 +1,16 @@
1ROOT@[0; 19)
2 IMPL_ITEM@[0; 18)
3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 IMPL_KW@[7; 11)
6 WHITESPACE@[11; 12)
7 PATH_TYPE@[12; 15)
8 PATH@[12; 15)
9 PATH_SEGMENT@[12; 15)
10 NAME_REF@[12; 15)
11 IDENT@[12; 15) "Foo"
12 WHITESPACE@[15; 16)
13 ITEM_LIST@[16; 18)
14 L_CURLY@[16; 17)
15 R_CURLY@[17; 18)
16 WHITESPACE@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs
new file mode 100644
index 000000000..03d29f324
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs
@@ -0,0 +1 @@
unsafe auto trait T {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt
new file mode 100644
index 000000000..e642bbf80
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt
@@ -0,0 +1,15 @@
1ROOT@[0; 23)
2 TRAIT_DEF@[0; 22)
3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 AUTO_KW@[7; 11)
6 WHITESPACE@[11; 12)
7 TRAIT_KW@[12; 17)
8 WHITESPACE@[17; 18)
9 NAME@[18; 19)
10 IDENT@[18; 19) "T"
11 WHITESPACE@[19; 20)
12 ITEM_LIST@[20; 22)
13 L_CURLY@[20; 21)
14 R_CURLY@[21; 22)
15 WHITESPACE@[22; 23)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs
new file mode 100644
index 000000000..9cd6c57bd
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs
@@ -0,0 +1 @@
unsafe default impl Foo {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt
new file mode 100644
index 000000000..99d33a902
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt
@@ -0,0 +1,18 @@
1ROOT@[0; 27)
2 IMPL_ITEM@[0; 26)
3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 DEFAULT_KW@[7; 14)
6 WHITESPACE@[14; 15)
7 IMPL_KW@[15; 19)
8 WHITESPACE@[19; 20)
9 PATH_TYPE@[20; 23)
10 PATH@[20; 23)
11 PATH_SEGMENT@[20; 23)
12 NAME_REF@[20; 23)
13 IDENT@[20; 23) "Foo"
14 WHITESPACE@[23; 24)
15 ITEM_LIST@[24; 26)
16 L_CURLY@[24; 25)
17 R_CURLY@[25; 26)
18 WHITESPACE@[26; 27)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs
new file mode 100644
index 000000000..33cfc4cd7
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs
@@ -0,0 +1 @@
unsafe fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt
new file mode 100644
index 000000000..39ec53b26
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt
@@ -0,0 +1,16 @@
1ROOT@[0; 19)
2 FN_DEF@[0; 18)
3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 FN_KW@[7; 9)
6 WHITESPACE@[9; 10)
7 NAME@[10; 13)
8 IDENT@[10; 13) "foo"
9 PARAM_LIST@[13; 15)
10 L_PAREN@[13; 14)
11 R_PAREN@[14; 15)
12 WHITESPACE@[15; 16)
13 BLOCK@[16; 18)
14 L_CURLY@[16; 17)
15 R_CURLY@[17; 18)
16 WHITESPACE@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs
new file mode 100644
index 000000000..1295c2cd2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs
@@ -0,0 +1 @@
unsafe extern "C" fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt
new file mode 100644
index 000000000..54e296ed6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt
@@ -0,0 +1,21 @@
1ROOT@[0; 30)
2 FN_DEF@[0; 29)
3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 ABI@[7; 17)
6 EXTERN_KW@[7; 13)
7 WHITESPACE@[13; 14)
8 STRING@[14; 17)
9 WHITESPACE@[17; 18)
10 FN_KW@[18; 20)
11 WHITESPACE@[20; 21)
12 NAME@[21; 24)
13 IDENT@[21; 24) "foo"
14 PARAM_LIST@[24; 26)
15 L_PAREN@[24; 25)
16 R_PAREN@[25; 26)
17 WHITESPACE@[26; 27)
18 BLOCK@[27; 29)
19 L_CURLY@[27; 28)
20 R_CURLY@[28; 29)
21 WHITESPACE@[29; 30)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs
new file mode 100644
index 000000000..26141e904
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs
@@ -0,0 +1 @@
fn foo(){} unsafe { } fn bar(){}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt
new file mode 100644
index 000000000..9825e5ace
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt
@@ -0,0 +1,35 @@
1ROOT@[0; 33)
2 FN_DEF@[0; 10)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 BLOCK@[8; 10)
11 L_CURLY@[8; 9)
12 R_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 err: `expected an item`
15 ERROR@[11; 17)
16 UNSAFE_KW@[11; 17)
17 WHITESPACE@[17; 18)
18 err: `expected an item`
19 ERROR@[18; 21)
20 L_CURLY@[18; 19)
21 WHITESPACE@[19; 20)
22 R_CURLY@[20; 21)
23 WHITESPACE@[21; 22)
24 FN_DEF@[22; 32)
25 FN_KW@[22; 24)
26 WHITESPACE@[24; 25)
27 NAME@[25; 28)
28 IDENT@[25; 28) "bar"
29 PARAM_LIST@[28; 30)
30 L_PAREN@[28; 29)
31 R_PAREN@[29; 30)
32 BLOCK@[30; 32)
33 L_CURLY@[30; 31)
34 R_CURLY@[31; 32)
35 WHITESPACE@[32; 33)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs
new file mode 100644
index 000000000..defd110c4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs
@@ -0,0 +1 @@
type Result<T> = ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt
new file mode 100644
index 000000000..bf65e8a37
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt
@@ -0,0 +1,20 @@
1ROOT@[0; 21)
2 TYPE_DEF@[0; 20)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 11)
6 IDENT@[5; 11) "Result"
7 TYPE_PARAM_LIST@[11; 14)
8 L_ANGLE@[11; 12)
9 TYPE_PARAM@[12; 13)
10 NAME@[12; 13)
11 IDENT@[12; 13) "T"
12 R_ANGLE@[13; 14)
13 WHITESPACE@[14; 15)
14 EQ@[15; 16)
15 WHITESPACE@[16; 17)
16 TUPLE_TYPE@[17; 19)
17 L_PAREN@[17; 18)
18 R_PAREN@[18; 19)
19 SEMI@[19; 20)
20 WHITESPACE@[20; 21)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs
new file mode 100644
index 000000000..04c0344fa
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs
@@ -0,0 +1 @@
type Foo = Bar;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt
new file mode 100644
index 000000000..71048bcc5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt
@@ -0,0 +1,16 @@
1ROOT@[0; 16)
2 TYPE_DEF@[0; 15)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 8)
6 IDENT@[5; 8) "Foo"
7 WHITESPACE@[8; 9)
8 EQ@[9; 10)
9 WHITESPACE@[10; 11)
10 PATH_TYPE@[11; 14)
11 PATH@[11; 14)
12 PATH_SEGMENT@[11; 14)
13 NAME_REF@[11; 14)
14 IDENT@[11; 14) "Bar"
15 SEMI@[14; 15)
16 WHITESPACE@[15; 16)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs
new file mode 100644
index 000000000..a602d07f0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs
@@ -0,0 +1 @@
type Foo where Foo: Copy = ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt
new file mode 100644
index 000000000..c3fca013e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt
@@ -0,0 +1,32 @@
1ROOT@[0; 31)
2 TYPE_DEF@[0; 30)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 8)
6 IDENT@[5; 8) "Foo"
7 WHITESPACE@[8; 9)
8 WHERE_CLAUSE@[9; 24)
9 WHERE_KW@[9; 14)
10 WHITESPACE@[14; 15)
11 WHERE_PRED@[15; 24)
12 PATH_TYPE@[15; 18)
13 PATH@[15; 18)
14 PATH_SEGMENT@[15; 18)
15 NAME_REF@[15; 18)
16 IDENT@[15; 18) "Foo"
17 COLON@[18; 19)
18 WHITESPACE@[19; 20)
19 PATH_TYPE@[20; 24)
20 PATH@[20; 24)
21 PATH_SEGMENT@[20; 24)
22 NAME_REF@[20; 24)
23 IDENT@[20; 24) "Copy"
24 err: `expected COMMA`
25 WHITESPACE@[24; 25)
26 EQ@[25; 26)
27 WHITESPACE@[26; 27)
28 TUPLE_TYPE@[27; 29)
29 L_PAREN@[27; 28)
30 R_PAREN@[28; 29)
31 SEMI@[29; 30)
32 WHITESPACE@[30; 31)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs
new file mode 100644
index 000000000..6e1b25101
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs
@@ -0,0 +1 @@
type T = (i32);
diff --git a/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt
new file mode 100644
index 000000000..97e73fea1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt
@@ -0,0 +1,19 @@
1ROOT@[0; 16)
2 TYPE_DEF@[0; 15)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 PAREN_TYPE@[9; 14)
11 L_PAREN@[9; 10)
12 PATH_TYPE@[10; 13)
13 PATH@[10; 13)
14 PATH_SEGMENT@[10; 13)
15 NAME_REF@[10; 13)
16 IDENT@[10; 13) "i32"
17 R_PAREN@[13; 14)
18 SEMI@[14; 15)
19 WHITESPACE@[15; 16)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs
new file mode 100644
index 000000000..c039cf7d3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs
@@ -0,0 +1 @@
type T = ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt
new file mode 100644
index 000000000..5d04d42fc
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt
@@ -0,0 +1,14 @@
1ROOT@[0; 13)
2 TYPE_DEF@[0; 12)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 TUPLE_TYPE@[9; 11)
11 L_PAREN@[9; 10)
12 R_PAREN@[10; 11)
13 SEMI@[11; 12)
14 WHITESPACE@[12; 13)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs
new file mode 100644
index 000000000..cb66bad24
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs
@@ -0,0 +1 @@
type T = (i32,);
diff --git a/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt
new file mode 100644
index 000000000..2cd8be9ab
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt
@@ -0,0 +1,20 @@
1ROOT@[0; 17)
2 TYPE_DEF@[0; 16)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 TUPLE_TYPE@[9; 15)
11 L_PAREN@[9; 10)
12 PATH_TYPE@[10; 13)
13 PATH@[10; 13)
14 PATH_SEGMENT@[10; 13)
15 NAME_REF@[10; 13)
16 IDENT@[10; 13) "i32"
17 COMMA@[13; 14)
18 R_PAREN@[14; 15)
19 SEMI@[15; 16)
20 WHITESPACE@[16; 17)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs
new file mode 100644
index 000000000..de399fcf4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs
@@ -0,0 +1 @@
type Never = !;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt
new file mode 100644
index 000000000..6205d9669
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt
@@ -0,0 +1,13 @@
1ROOT@[0; 16)
2 TYPE_DEF@[0; 15)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 10)
6 IDENT@[5; 10) "Never"
7 WHITESPACE@[10; 11)
8 EQ@[11; 12)
9 WHITESPACE@[12; 13)
10 NEVER_TYPE@[13; 14)
11 EXCL@[13; 14)
12 SEMI@[14; 15)
13 WHITESPACE@[15; 16)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs
new file mode 100644
index 000000000..fae705131
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs
@@ -0,0 +1 @@
type T = *();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt
new file mode 100644
index 000000000..23e68557a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt
@@ -0,0 +1,17 @@
1ROOT@[0; 14)
2 TYPE_DEF@[0; 13)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 POINTER_TYPE@[9; 12)
11 STAR@[9; 10)
12 err: `expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate)`
13 TUPLE_TYPE@[10; 12)
14 L_PAREN@[10; 11)
15 R_PAREN@[11; 12)
16 SEMI@[12; 13)
17 WHITESPACE@[13; 14)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs
new file mode 100644
index 000000000..04b2bb9ba
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs
@@ -0,0 +1,2 @@
1type M = *mut ();
2type C = *mut ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt
new file mode 100644
index 000000000..33f5ad8b4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt
@@ -0,0 +1,35 @@
1ROOT@[0; 36)
2 TYPE_DEF@[0; 17)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "M"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 POINTER_TYPE@[9; 16)
11 STAR@[9; 10)
12 MUT_KW@[10; 13)
13 WHITESPACE@[13; 14)
14 TUPLE_TYPE@[14; 16)
15 L_PAREN@[14; 15)
16 R_PAREN@[15; 16)
17 SEMI@[16; 17)
18 WHITESPACE@[17; 18)
19 TYPE_DEF@[18; 35)
20 TYPE_KW@[18; 22)
21 WHITESPACE@[22; 23)
22 NAME@[23; 24)
23 IDENT@[23; 24) "C"
24 WHITESPACE@[24; 25)
25 EQ@[25; 26)
26 WHITESPACE@[26; 27)
27 POINTER_TYPE@[27; 34)
28 STAR@[27; 28)
29 MUT_KW@[28; 31)
30 WHITESPACE@[31; 32)
31 TUPLE_TYPE@[32; 34)
32 L_PAREN@[32; 33)
33 R_PAREN@[33; 34)
34 SEMI@[34; 35)
35 WHITESPACE@[35; 36)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs
new file mode 100644
index 000000000..a94851443
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs
@@ -0,0 +1 @@
type T = [() 92];
diff --git a/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt
new file mode 100644
index 000000000..90bdc5d2e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt
@@ -0,0 +1,27 @@
1ROOT@[0; 18)
2 TYPE_DEF@[0; 12)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 SLICE_TYPE@[9; 12)
11 L_BRACK@[9; 10)
12 TUPLE_TYPE@[10; 12)
13 L_PAREN@[10; 11)
14 R_PAREN@[11; 12)
15 err: `expected `;` or `]``
16 err: `expected SEMI`
17 WHITESPACE@[12; 13)
18 err: `expected an item`
19 ERROR@[13; 15)
20 INT_NUMBER@[13; 15) "92"
21 err: `expected an item`
22 ERROR@[15; 16)
23 R_BRACK@[15; 16)
24 err: `expected an item`
25 ERROR@[16; 17)
26 SEMI@[16; 17)
27 WHITESPACE@[17; 18)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs
new file mode 100644
index 000000000..27eb22f22
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs
@@ -0,0 +1 @@
type T = [(); 92];
diff --git a/crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt
new file mode 100644
index 000000000..809c86974
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt
@@ -0,0 +1,21 @@
1ROOT@[0; 19)
2 TYPE_DEF@[0; 18)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 ARRAY_TYPE@[9; 17)
11 L_BRACK@[9; 10)
12 TUPLE_TYPE@[10; 12)
13 L_PAREN@[10; 11)
14 R_PAREN@[11; 12)
15 SEMI@[12; 13)
16 WHITESPACE@[13; 14)
17 LITERAL@[14; 16)
18 INT_NUMBER@[14; 16) "92"
19 R_BRACK@[16; 17)
20 SEMI@[17; 18)
21 WHITESPACE@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs
new file mode 100644
index 000000000..4da1af827
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs
@@ -0,0 +1 @@
type T = [()];
diff --git a/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt
new file mode 100644
index 000000000..978530a6a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt
@@ -0,0 +1,17 @@
1ROOT@[0; 15)
2 TYPE_DEF@[0; 14)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "T"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 SLICE_TYPE@[9; 13)
11 L_BRACK@[9; 10)
12 TUPLE_TYPE@[10; 12)
13 L_PAREN@[10; 11)
14 R_PAREN@[11; 12)
15 R_BRACK@[12; 13)
16 SEMI@[13; 14)
17 WHITESPACE@[14; 15)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs
new file mode 100644
index 000000000..3ac0badab
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs
@@ -0,0 +1,3 @@
1type A = &();
2type B = &'static ();
3type C = &mut ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt
new file mode 100644
index 000000000..ff27ce5dd
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt
@@ -0,0 +1,50 @@
1ROOT@[0; 54)
2 TYPE_DEF@[0; 13)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 REFERENCE_TYPE@[9; 12)
11 AMP@[9; 10)
12 TUPLE_TYPE@[10; 12)
13 L_PAREN@[10; 11)
14 R_PAREN@[11; 12)
15 SEMI@[12; 13)
16 WHITESPACE@[13; 14)
17 TYPE_DEF@[14; 35)
18 TYPE_KW@[14; 18)
19 WHITESPACE@[18; 19)
20 NAME@[19; 20)
21 IDENT@[19; 20) "B"
22 WHITESPACE@[20; 21)
23 EQ@[21; 22)
24 WHITESPACE@[22; 23)
25 REFERENCE_TYPE@[23; 34)
26 AMP@[23; 24)
27 LIFETIME@[24; 31) "'static"
28 WHITESPACE@[31; 32)
29 TUPLE_TYPE@[32; 34)
30 L_PAREN@[32; 33)
31 R_PAREN@[33; 34)
32 SEMI@[34; 35)
33 WHITESPACE@[35; 36)
34 TYPE_DEF@[36; 53)
35 TYPE_KW@[36; 40)
36 WHITESPACE@[40; 41)
37 NAME@[41; 42)
38 IDENT@[41; 42) "C"
39 WHITESPACE@[42; 43)
40 EQ@[43; 44)
41 WHITESPACE@[44; 45)
42 REFERENCE_TYPE@[45; 52)
43 AMP@[45; 46)
44 MUT_KW@[46; 49)
45 WHITESPACE@[49; 50)
46 TUPLE_TYPE@[50; 52)
47 L_PAREN@[50; 51)
48 R_PAREN@[51; 52)
49 SEMI@[52; 53)
50 WHITESPACE@[53; 54)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs
new file mode 100644
index 000000000..7952dbd57
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs
@@ -0,0 +1 @@
type Placeholder = _;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt
new file mode 100644
index 000000000..538e4e69c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt
@@ -0,0 +1,13 @@
1ROOT@[0; 22)
2 TYPE_DEF@[0; 21)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 16)
6 IDENT@[5; 16) "Placeholder"
7 WHITESPACE@[16; 17)
8 EQ@[17; 18)
9 WHITESPACE@[18; 19)
10 PLACEHOLDER_TYPE@[19; 20)
11 UNDERSCORE@[19; 20)
12 SEMI@[20; 21)
13 WHITESPACE@[21; 22)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs
new file mode 100644
index 000000000..c9bf3bdb4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs
@@ -0,0 +1,3 @@
1type A = fn();
2type B = unsafe fn();
3type C = unsafe extern "C" fn();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt
new file mode 100644
index 000000000..4dba83eb5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt
@@ -0,0 +1,55 @@
1ROOT@[0; 70)
2 TYPE_DEF@[0; 14)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 FN_POINTER_TYPE@[9; 13)
11 FN_KW@[9; 11)
12 PARAM_LIST@[11; 13)
13 L_PAREN@[11; 12)
14 R_PAREN@[12; 13)
15 SEMI@[13; 14)
16 WHITESPACE@[14; 15)
17 TYPE_DEF@[15; 36)
18 TYPE_KW@[15; 19)
19 WHITESPACE@[19; 20)
20 NAME@[20; 21)
21 IDENT@[20; 21) "B"
22 WHITESPACE@[21; 22)
23 EQ@[22; 23)
24 WHITESPACE@[23; 24)
25 FN_POINTER_TYPE@[24; 35)
26 UNSAFE_KW@[24; 30)
27 WHITESPACE@[30; 31)
28 FN_KW@[31; 33)
29 PARAM_LIST@[33; 35)
30 L_PAREN@[33; 34)
31 R_PAREN@[34; 35)
32 SEMI@[35; 36)
33 WHITESPACE@[36; 37)
34 TYPE_DEF@[37; 69)
35 TYPE_KW@[37; 41)
36 WHITESPACE@[41; 42)
37 NAME@[42; 43)
38 IDENT@[42; 43) "C"
39 WHITESPACE@[43; 44)
40 EQ@[44; 45)
41 WHITESPACE@[45; 46)
42 FN_POINTER_TYPE@[46; 68)
43 UNSAFE_KW@[46; 52)
44 WHITESPACE@[52; 53)
45 ABI@[53; 63)
46 EXTERN_KW@[53; 59)
47 WHITESPACE@[59; 60)
48 STRING@[60; 63)
49 WHITESPACE@[63; 64)
50 FN_KW@[64; 66)
51 PARAM_LIST@[66; 68)
52 L_PAREN@[66; 67)
53 R_PAREN@[67; 68)
54 SEMI@[68; 69)
55 WHITESPACE@[69; 70)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs
new file mode 100644
index 000000000..f014914ff
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs
@@ -0,0 +1 @@
type F = unsafe ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt
new file mode 100644
index 000000000..fa0771ab1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt
@@ -0,0 +1,23 @@
1ROOT@[0; 20)
2 TYPE_DEF@[0; 15)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "F"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 UNSAFE_KW@[9; 15)
11 err: `expected `fn``
12 err: `expected SEMI`
13 WHITESPACE@[15; 16)
14 err: `expected an item`
15 ERROR@[16; 17)
16 L_PAREN@[16; 17)
17 err: `expected an item`
18 ERROR@[17; 18)
19 R_PAREN@[17; 18)
20 err: `expected an item`
21 ERROR@[18; 19)
22 SEMI@[18; 19)
23 WHITESPACE@[19; 20)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs
new file mode 100644
index 000000000..e3ba5e87f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs
@@ -0,0 +1 @@
type F = fn() -> ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt
new file mode 100644
index 000000000..203839636
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt
@@ -0,0 +1,23 @@
1ROOT@[0; 21)
2 TYPE_DEF@[0; 20)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "F"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 FN_POINTER_TYPE@[9; 19)
11 FN_KW@[9; 11)
12 PARAM_LIST@[11; 13)
13 L_PAREN@[11; 12)
14 R_PAREN@[12; 13)
15 WHITESPACE@[13; 14)
16 RET_TYPE@[14; 19)
17 THIN_ARROW@[14; 16)
18 WHITESPACE@[16; 17)
19 TUPLE_TYPE@[17; 19)
20 L_PAREN@[17; 18)
21 R_PAREN@[18; 19)
22 SEMI@[19; 20)
23 WHITESPACE@[20; 21)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs
new file mode 100644
index 000000000..4d6a18c6b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs
@@ -0,0 +1 @@
type A = for<'a> fn() -> ();
diff --git a/crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt
new file mode 100644
index 000000000..f6b962b2c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt
@@ -0,0 +1,31 @@
1ROOT@[0; 29)
2 TYPE_DEF@[0; 28)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 FOR_TYPE@[9; 27)
11 FOR_KW@[9; 12)
12 TYPE_PARAM_LIST@[12; 16)
13 L_ANGLE@[12; 13)
14 LIFETIME_PARAM@[13; 15)
15 LIFETIME@[13; 15) "'a"
16 R_ANGLE@[15; 16)
17 WHITESPACE@[16; 17)
18 FN_POINTER_TYPE@[17; 27)
19 FN_KW@[17; 19)
20 PARAM_LIST@[19; 21)
21 L_PAREN@[19; 20)
22 R_PAREN@[20; 21)
23 WHITESPACE@[21; 22)
24 RET_TYPE@[22; 27)
25 THIN_ARROW@[22; 24)
26 WHITESPACE@[24; 25)
27 TUPLE_TYPE@[25; 27)
28 L_PAREN@[25; 26)
29 R_PAREN@[26; 27)
30 SEMI@[27; 28)
31 WHITESPACE@[28; 29)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs
new file mode 100644
index 000000000..bf94f32e1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs
@@ -0,0 +1,4 @@
1type A = Foo;
2type B = ::Foo;
3type C = self::Foo;
4type D = super::Foo;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt
new file mode 100644
index 000000000..b0a110a2c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt
@@ -0,0 +1,70 @@
1ROOT@[0; 71)
2 TYPE_DEF@[0; 13)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 PATH_TYPE@[9; 12)
11 PATH@[9; 12)
12 PATH_SEGMENT@[9; 12)
13 NAME_REF@[9; 12)
14 IDENT@[9; 12) "Foo"
15 SEMI@[12; 13)
16 WHITESPACE@[13; 14)
17 TYPE_DEF@[14; 29)
18 TYPE_KW@[14; 18)
19 WHITESPACE@[18; 19)
20 NAME@[19; 20)
21 IDENT@[19; 20) "B"
22 WHITESPACE@[20; 21)
23 EQ@[21; 22)
24 WHITESPACE@[22; 23)
25 PATH_TYPE@[23; 28)
26 PATH@[23; 28)
27 PATH_SEGMENT@[23; 28)
28 COLONCOLON@[23; 25)
29 NAME_REF@[25; 28)
30 IDENT@[25; 28) "Foo"
31 SEMI@[28; 29)
32 WHITESPACE@[29; 30)
33 TYPE_DEF@[30; 49)
34 TYPE_KW@[30; 34)
35 WHITESPACE@[34; 35)
36 NAME@[35; 36)
37 IDENT@[35; 36) "C"
38 WHITESPACE@[36; 37)
39 EQ@[37; 38)
40 WHITESPACE@[38; 39)
41 PATH_TYPE@[39; 48)
42 PATH@[39; 48)
43 PATH@[39; 43)
44 PATH_SEGMENT@[39; 43)
45 SELF_KW@[39; 43)
46 COLONCOLON@[43; 45)
47 PATH_SEGMENT@[45; 48)
48 NAME_REF@[45; 48)
49 IDENT@[45; 48) "Foo"
50 SEMI@[48; 49)
51 WHITESPACE@[49; 50)
52 TYPE_DEF@[50; 70)
53 TYPE_KW@[50; 54)
54 WHITESPACE@[54; 55)
55 NAME@[55; 56)
56 IDENT@[55; 56) "D"
57 WHITESPACE@[56; 57)
58 EQ@[57; 58)
59 WHITESPACE@[58; 59)
60 PATH_TYPE@[59; 69)
61 PATH@[59; 69)
62 PATH@[59; 64)
63 PATH_SEGMENT@[59; 64)
64 SUPER_KW@[59; 64)
65 COLONCOLON@[64; 66)
66 PATH_SEGMENT@[66; 69)
67 NAME_REF@[66; 69)
68 IDENT@[66; 69) "Foo"
69 SEMI@[69; 70)
70 WHITESPACE@[70; 71)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs
new file mode 100644
index 000000000..820a9e72c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs
@@ -0,0 +1,8 @@
1fn main() {
2 let a = ();
3 let mut b = ();
4 let ref c = ();
5 let ref mut d = ();
6 let e @ _ = ();
7 let ref mut f @ g @ _ = ();
8}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt
new file mode 100644
index 000000000..9adc89b7c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt
@@ -0,0 +1,127 @@
1ROOT@[0; 146)
2 FN_DEF@[0; 145)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 145)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 LET_STMT@[16; 27)
15 LET_KW@[16; 19)
16 WHITESPACE@[19; 20)
17 BIND_PAT@[20; 21)
18 NAME@[20; 21)
19 IDENT@[20; 21) "a"
20 WHITESPACE@[21; 22)
21 EQ@[22; 23)
22 WHITESPACE@[23; 24)
23 TUPLE_EXPR@[24; 26)
24 L_PAREN@[24; 25)
25 R_PAREN@[25; 26)
26 SEMI@[26; 27)
27 WHITESPACE@[27; 32)
28 LET_STMT@[32; 47)
29 LET_KW@[32; 35)
30 WHITESPACE@[35; 36)
31 BIND_PAT@[36; 41)
32 MUT_KW@[36; 39)
33 WHITESPACE@[39; 40)
34 NAME@[40; 41)
35 IDENT@[40; 41) "b"
36 WHITESPACE@[41; 42)
37 EQ@[42; 43)
38 WHITESPACE@[43; 44)
39 TUPLE_EXPR@[44; 46)
40 L_PAREN@[44; 45)
41 R_PAREN@[45; 46)
42 SEMI@[46; 47)
43 WHITESPACE@[47; 52)
44 LET_STMT@[52; 67)
45 LET_KW@[52; 55)
46 WHITESPACE@[55; 56)
47 BIND_PAT@[56; 61)
48 REF_KW@[56; 59)
49 WHITESPACE@[59; 60)
50 NAME@[60; 61)
51 IDENT@[60; 61) "c"
52 WHITESPACE@[61; 62)
53 EQ@[62; 63)
54 WHITESPACE@[63; 64)
55 TUPLE_EXPR@[64; 66)
56 L_PAREN@[64; 65)
57 R_PAREN@[65; 66)
58 SEMI@[66; 67)
59 WHITESPACE@[67; 72)
60 LET_STMT@[72; 91)
61 LET_KW@[72; 75)
62 WHITESPACE@[75; 76)
63 BIND_PAT@[76; 85)
64 REF_KW@[76; 79)
65 WHITESPACE@[79; 80)
66 MUT_KW@[80; 83)
67 WHITESPACE@[83; 84)
68 NAME@[84; 85)
69 IDENT@[84; 85) "d"
70 WHITESPACE@[85; 86)
71 EQ@[86; 87)
72 WHITESPACE@[87; 88)
73 TUPLE_EXPR@[88; 90)
74 L_PAREN@[88; 89)
75 R_PAREN@[89; 90)
76 SEMI@[90; 91)
77 WHITESPACE@[91; 96)
78 LET_STMT@[96; 111)
79 LET_KW@[96; 99)
80 WHITESPACE@[99; 100)
81 BIND_PAT@[100; 105)
82 NAME@[100; 101)
83 IDENT@[100; 101) "e"
84 WHITESPACE@[101; 102)
85 AT@[102; 103)
86 WHITESPACE@[103; 104)
87 PLACEHOLDER_PAT@[104; 105)
88 UNDERSCORE@[104; 105)
89 WHITESPACE@[105; 106)
90 EQ@[106; 107)
91 WHITESPACE@[107; 108)
92 TUPLE_EXPR@[108; 110)
93 L_PAREN@[108; 109)
94 R_PAREN@[109; 110)
95 SEMI@[110; 111)
96 WHITESPACE@[111; 116)
97 LET_STMT@[116; 143)
98 LET_KW@[116; 119)
99 WHITESPACE@[119; 120)
100 BIND_PAT@[120; 137)
101 REF_KW@[120; 123)
102 WHITESPACE@[123; 124)
103 MUT_KW@[124; 127)
104 WHITESPACE@[127; 128)
105 NAME@[128; 129)
106 IDENT@[128; 129) "f"
107 WHITESPACE@[129; 130)
108 AT@[130; 131)
109 WHITESPACE@[131; 132)
110 BIND_PAT@[132; 137)
111 NAME@[132; 133)
112 IDENT@[132; 133) "g"
113 WHITESPACE@[133; 134)
114 AT@[134; 135)
115 WHITESPACE@[135; 136)
116 PLACEHOLDER_PAT@[136; 137)
117 UNDERSCORE@[136; 137)
118 WHITESPACE@[137; 138)
119 EQ@[138; 139)
120 WHITESPACE@[139; 140)
121 TUPLE_EXPR@[140; 142)
122 L_PAREN@[140; 141)
123 R_PAREN@[141; 142)
124 SEMI@[142; 143)
125 WHITESPACE@[143; 144)
126 R_CURLY@[144; 145)
127 WHITESPACE@[145; 146)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs
new file mode 100644
index 000000000..de41f5cae
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs
@@ -0,0 +1,4 @@
1fn main() {
2 let &a = ();
3 let &mut b = ();
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt
new file mode 100644
index 000000000..a625637cd
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt
@@ -0,0 +1,49 @@
1ROOT@[0; 52)
2 FN_DEF@[0; 51)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 51)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 LET_STMT@[16; 28)
15 LET_KW@[16; 19)
16 WHITESPACE@[19; 20)
17 REF_PAT@[20; 22)
18 AMP@[20; 21)
19 BIND_PAT@[21; 22)
20 NAME@[21; 22)
21 IDENT@[21; 22) "a"
22 WHITESPACE@[22; 23)
23 EQ@[23; 24)
24 WHITESPACE@[24; 25)
25 TUPLE_EXPR@[25; 27)
26 L_PAREN@[25; 26)
27 R_PAREN@[26; 27)
28 SEMI@[27; 28)
29 WHITESPACE@[28; 33)
30 LET_STMT@[33; 49)
31 LET_KW@[33; 36)
32 WHITESPACE@[36; 37)
33 REF_PAT@[37; 43)
34 AMP@[37; 38)
35 MUT_KW@[38; 41)
36 WHITESPACE@[41; 42)
37 BIND_PAT@[42; 43)
38 NAME@[42; 43)
39 IDENT@[42; 43) "b"
40 WHITESPACE@[43; 44)
41 EQ@[44; 45)
42 WHITESPACE@[45; 46)
43 TUPLE_EXPR@[46; 48)
44 L_PAREN@[46; 47)
45 R_PAREN@[47; 48)
46 SEMI@[48; 49)
47 WHITESPACE@[49; 50)
48 R_CURLY@[50; 51)
49 WHITESPACE@[51; 52)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs
new file mode 100644
index 000000000..4d719c433
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs
@@ -0,0 +1 @@
fn main() { let _ = (); }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt
new file mode 100644
index 000000000..e89ff4e7c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt
@@ -0,0 +1,28 @@
1ROOT@[0; 26)
2 FN_DEF@[0; 25)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 25)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 12)
14 LET_STMT@[12; 23)
15 LET_KW@[12; 15)
16 WHITESPACE@[15; 16)
17 PLACEHOLDER_PAT@[16; 17)
18 UNDERSCORE@[16; 17)
19 WHITESPACE@[17; 18)
20 EQ@[18; 19)
21 WHITESPACE@[19; 20)
22 TUPLE_EXPR@[20; 22)
23 L_PAREN@[20; 21)
24 R_PAREN@[21; 22)
25 SEMI@[22; 23)
26 WHITESPACE@[23; 24)
27 R_CURLY@[24; 25)
28 WHITESPACE@[25; 26)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs
new file mode 100644
index 000000000..faeefde94
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs
@@ -0,0 +1,4 @@
1pub(crate) struct S;
2pub(self) struct S;
3pub(self) struct S;
4pub(self) struct S;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt
new file mode 100644
index 000000000..3b5fbf95d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt
@@ -0,0 +1,53 @@
1ROOT@[0; 81)
2 STRUCT_DEF@[0; 20)
3 VISIBILITY@[0; 10)
4 PUB_KW@[0; 3)
5 L_PAREN@[3; 4)
6 CRATE_KW@[4; 9)
7 R_PAREN@[9; 10)
8 WHITESPACE@[10; 11)
9 STRUCT_KW@[11; 17)
10 WHITESPACE@[17; 18)
11 NAME@[18; 19)
12 IDENT@[18; 19) "S"
13 SEMI@[19; 20)
14 WHITESPACE@[20; 21)
15 STRUCT_DEF@[21; 40)
16 VISIBILITY@[21; 30)
17 PUB_KW@[21; 24)
18 L_PAREN@[24; 25)
19 SELF_KW@[25; 29)
20 R_PAREN@[29; 30)
21 WHITESPACE@[30; 31)
22 STRUCT_KW@[31; 37)
23 WHITESPACE@[37; 38)
24 NAME@[38; 39)
25 IDENT@[38; 39) "S"
26 SEMI@[39; 40)
27 WHITESPACE@[40; 41)
28 STRUCT_DEF@[41; 60)
29 VISIBILITY@[41; 50)
30 PUB_KW@[41; 44)
31 L_PAREN@[44; 45)
32 SELF_KW@[45; 49)
33 R_PAREN@[49; 50)
34 WHITESPACE@[50; 51)
35 STRUCT_KW@[51; 57)
36 WHITESPACE@[57; 58)
37 NAME@[58; 59)
38 IDENT@[58; 59) "S"
39 SEMI@[59; 60)
40 WHITESPACE@[60; 61)
41 STRUCT_DEF@[61; 80)
42 VISIBILITY@[61; 70)
43 PUB_KW@[61; 64)
44 L_PAREN@[64; 65)
45 SELF_KW@[65; 69)
46 R_PAREN@[69; 70)
47 WHITESPACE@[70; 71)
48 STRUCT_KW@[71; 77)
49 WHITESPACE@[77; 78)
50 NAME@[78; 79)
51 IDENT@[78; 79) "S"
52 SEMI@[79; 80)
53 WHITESPACE@[80; 81)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs
new file mode 100644
index 000000000..d22d8cada
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs
@@ -0,0 +1,2 @@
1fn foo() {}
2fn bar() -> () {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt
new file mode 100644
index 000000000..a3d235ce1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt
@@ -0,0 +1,34 @@
1ROOT@[0; 30)
2 FN_DEF@[0; 11)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 11)
12 L_CURLY@[9; 10)
13 R_CURLY@[10; 11)
14 WHITESPACE@[11; 12)
15 FN_DEF@[12; 29)
16 FN_KW@[12; 14)
17 WHITESPACE@[14; 15)
18 NAME@[15; 18)
19 IDENT@[15; 18) "bar"
20 PARAM_LIST@[18; 20)
21 L_PAREN@[18; 19)
22 R_PAREN@[19; 20)
23 WHITESPACE@[20; 21)
24 RET_TYPE@[21; 26)
25 THIN_ARROW@[21; 23)
26 WHITESPACE@[23; 24)
27 TUPLE_TYPE@[24; 26)
28 L_PAREN@[24; 25)
29 R_PAREN@[25; 26)
30 WHITESPACE@[26; 27)
31 BLOCK@[27; 29)
32 L_CURLY@[27; 28)
33 R_CURLY@[28; 29)
34 WHITESPACE@[29; 30)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs
new file mode 100644
index 000000000..333ebabef
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let _ = a;
3 let _ = a::b;
4 let _ = ::a::<b>;
5 let _ = format!();
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt
new file mode 100644
index 000000000..618afc0a9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt
@@ -0,0 +1,95 @@
1ROOT@[0; 91)
2 FN_DEF@[0; 90)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 90)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 25)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 PLACEHOLDER_PAT@[19; 20)
18 UNDERSCORE@[19; 20)
19 WHITESPACE@[20; 21)
20 EQ@[21; 22)
21 WHITESPACE@[22; 23)
22 PATH_EXPR@[23; 24)
23 PATH@[23; 24)
24 PATH_SEGMENT@[23; 24)
25 NAME_REF@[23; 24)
26 IDENT@[23; 24) "a"
27 SEMI@[24; 25)
28 WHITESPACE@[25; 30)
29 LET_STMT@[30; 43)
30 LET_KW@[30; 33)
31 WHITESPACE@[33; 34)
32 PLACEHOLDER_PAT@[34; 35)
33 UNDERSCORE@[34; 35)
34 WHITESPACE@[35; 36)
35 EQ@[36; 37)
36 WHITESPACE@[37; 38)
37 PATH_EXPR@[38; 42)
38 PATH@[38; 42)
39 PATH@[38; 39)
40 PATH_SEGMENT@[38; 39)
41 NAME_REF@[38; 39)
42 IDENT@[38; 39) "a"
43 COLONCOLON@[39; 41)
44 PATH_SEGMENT@[41; 42)
45 NAME_REF@[41; 42)
46 IDENT@[41; 42) "b"
47 SEMI@[42; 43)
48 WHITESPACE@[43; 48)
49 LET_STMT@[48; 65)
50 LET_KW@[48; 51)
51 WHITESPACE@[51; 52)
52 PLACEHOLDER_PAT@[52; 53)
53 UNDERSCORE@[52; 53)
54 WHITESPACE@[53; 54)
55 EQ@[54; 55)
56 WHITESPACE@[55; 56)
57 PATH_EXPR@[56; 64)
58 PATH@[56; 64)
59 PATH_SEGMENT@[56; 64)
60 COLONCOLON@[56; 58)
61 NAME_REF@[58; 59)
62 IDENT@[58; 59) "a"
63 TYPE_ARG_LIST@[59; 64)
64 COLONCOLON@[59; 61)
65 L_ANGLE@[61; 62)
66 TYPE_ARG@[62; 63)
67 PATH_TYPE@[62; 63)
68 PATH@[62; 63)
69 PATH_SEGMENT@[62; 63)
70 NAME_REF@[62; 63)
71 IDENT@[62; 63) "b"
72 R_ANGLE@[63; 64)
73 SEMI@[64; 65)
74 WHITESPACE@[65; 70)
75 LET_STMT@[70; 88)
76 LET_KW@[70; 73)
77 WHITESPACE@[73; 74)
78 PLACEHOLDER_PAT@[74; 75)
79 UNDERSCORE@[74; 75)
80 WHITESPACE@[75; 76)
81 EQ@[76; 77)
82 WHITESPACE@[77; 78)
83 MACRO_CALL@[78; 87)
84 PATH@[78; 84)
85 PATH_SEGMENT@[78; 84)
86 NAME_REF@[78; 84)
87 IDENT@[78; 84) "format"
88 EXCL@[84; 85)
89 TOKEN_TREE@[85; 87)
90 L_PAREN@[85; 86)
91 R_PAREN@[86; 87)
92 SEMI@[87; 88)
93 WHITESPACE@[88; 89)
94 R_CURLY@[89; 90)
95 WHITESPACE@[90; 91)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs
new file mode 100644
index 000000000..2e11a5a6e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs
@@ -0,0 +1,12 @@
1fn foo() {
2 let _ = true;
3 let _ = false;
4 let _ = 1;
5 let _ = 2.0;
6 let _ = b'a';
7 let _ = 'b';
8 let _ = "c";
9 let _ = r"d";
10 let _ = b"e";
11 let _ = br"f";
12}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt
new file mode 100644
index 000000000..8105ee25a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt
@@ -0,0 +1,135 @@
1ROOT@[0; 189)
2 FN_DEF@[0; 188)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 188)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 28)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 PLACEHOLDER_PAT@[19; 20)
18 UNDERSCORE@[19; 20)
19 WHITESPACE@[20; 21)
20 EQ@[21; 22)
21 WHITESPACE@[22; 23)
22 LITERAL@[23; 27)
23 TRUE_KW@[23; 27)
24 SEMI@[27; 28)
25 WHITESPACE@[28; 33)
26 LET_STMT@[33; 47)
27 LET_KW@[33; 36)
28 WHITESPACE@[36; 37)
29 PLACEHOLDER_PAT@[37; 38)
30 UNDERSCORE@[37; 38)
31 WHITESPACE@[38; 39)
32 EQ@[39; 40)
33 WHITESPACE@[40; 41)
34 LITERAL@[41; 46)
35 FALSE_KW@[41; 46)
36 SEMI@[46; 47)
37 WHITESPACE@[47; 52)
38 LET_STMT@[52; 62)
39 LET_KW@[52; 55)
40 WHITESPACE@[55; 56)
41 PLACEHOLDER_PAT@[56; 57)
42 UNDERSCORE@[56; 57)
43 WHITESPACE@[57; 58)
44 EQ@[58; 59)
45 WHITESPACE@[59; 60)
46 LITERAL@[60; 61)
47 INT_NUMBER@[60; 61) "1"
48 SEMI@[61; 62)
49 WHITESPACE@[62; 67)
50 LET_STMT@[67; 79)
51 LET_KW@[67; 70)
52 WHITESPACE@[70; 71)
53 PLACEHOLDER_PAT@[71; 72)
54 UNDERSCORE@[71; 72)
55 WHITESPACE@[72; 73)
56 EQ@[73; 74)
57 WHITESPACE@[74; 75)
58 LITERAL@[75; 78)
59 FLOAT_NUMBER@[75; 78) "2.0"
60 SEMI@[78; 79)
61 WHITESPACE@[79; 84)
62 LET_STMT@[84; 97)
63 LET_KW@[84; 87)
64 WHITESPACE@[87; 88)
65 PLACEHOLDER_PAT@[88; 89)
66 UNDERSCORE@[88; 89)
67 WHITESPACE@[89; 90)
68 EQ@[90; 91)
69 WHITESPACE@[91; 92)
70 LITERAL@[92; 96)
71 BYTE@[92; 96)
72 SEMI@[96; 97)
73 WHITESPACE@[97; 102)
74 LET_STMT@[102; 114)
75 LET_KW@[102; 105)
76 WHITESPACE@[105; 106)
77 PLACEHOLDER_PAT@[106; 107)
78 UNDERSCORE@[106; 107)
79 WHITESPACE@[107; 108)
80 EQ@[108; 109)
81 WHITESPACE@[109; 110)
82 LITERAL@[110; 113)
83 CHAR@[110; 113)
84 SEMI@[113; 114)
85 WHITESPACE@[114; 119)
86 LET_STMT@[119; 131)
87 LET_KW@[119; 122)
88 WHITESPACE@[122; 123)
89 PLACEHOLDER_PAT@[123; 124)
90 UNDERSCORE@[123; 124)
91 WHITESPACE@[124; 125)
92 EQ@[125; 126)
93 WHITESPACE@[126; 127)
94 LITERAL@[127; 130)
95 STRING@[127; 130)
96 SEMI@[130; 131)
97 WHITESPACE@[131; 136)
98 LET_STMT@[136; 149)
99 LET_KW@[136; 139)
100 WHITESPACE@[139; 140)
101 PLACEHOLDER_PAT@[140; 141)
102 UNDERSCORE@[140; 141)
103 WHITESPACE@[141; 142)
104 EQ@[142; 143)
105 WHITESPACE@[143; 144)
106 LITERAL@[144; 148)
107 RAW_STRING@[144; 148)
108 SEMI@[148; 149)
109 WHITESPACE@[149; 154)
110 LET_STMT@[154; 167)
111 LET_KW@[154; 157)
112 WHITESPACE@[157; 158)
113 PLACEHOLDER_PAT@[158; 159)
114 UNDERSCORE@[158; 159)
115 WHITESPACE@[159; 160)
116 EQ@[160; 161)
117 WHITESPACE@[161; 162)
118 LITERAL@[162; 166)
119 BYTE_STRING@[162; 166)
120 SEMI@[166; 167)
121 WHITESPACE@[167; 172)
122 LET_STMT@[172; 186)
123 LET_KW@[172; 175)
124 WHITESPACE@[175; 176)
125 PLACEHOLDER_PAT@[176; 177)
126 UNDERSCORE@[176; 177)
127 WHITESPACE@[177; 178)
128 EQ@[178; 179)
129 WHITESPACE@[179; 180)
130 LITERAL@[180; 185)
131 RAW_BYTE_STRING@[180; 185)
132 SEMI@[185; 186)
133 WHITESPACE@[186; 187)
134 R_CURLY@[187; 188)
135 WHITESPACE@[188; 189)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs
new file mode 100644
index 000000000..919bde0ee
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs
@@ -0,0 +1 @@
struct S<T: 'a + ?Sized + (Copy)>;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt
new file mode 100644
index 000000000..549b571c2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt
@@ -0,0 +1,36 @@
1ROOT@[0; 35)
2 STRUCT_DEF@[0; 34)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 33)
8 L_ANGLE@[8; 9)
9 TYPE_PARAM@[9; 32)
10 NAME@[9; 10)
11 IDENT@[9; 10) "T"
12 COLON@[10; 11)
13 WHITESPACE@[11; 12)
14 LIFETIME@[12; 14) "'a"
15 WHITESPACE@[14; 15)
16 PLUS@[15; 16)
17 WHITESPACE@[16; 17)
18 QUESTION@[17; 18)
19 PATH_TYPE@[18; 32)
20 PATH@[18; 23)
21 PATH_SEGMENT@[18; 23)
22 NAME_REF@[18; 23)
23 IDENT@[18; 23) "Sized"
24 WHITESPACE@[23; 24)
25 PLUS@[24; 25)
26 WHITESPACE@[25; 26)
27 L_PAREN@[26; 27)
28 PATH_TYPE@[27; 31)
29 PATH@[27; 31)
30 PATH_SEGMENT@[27; 31)
31 NAME_REF@[27; 31)
32 IDENT@[27; 31) "Copy"
33 R_PAREN@[31; 32)
34 R_ANGLE@[32; 33)
35 SEMI@[33; 34)
36 WHITESPACE@[34; 35)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs
new file mode 100644
index 000000000..540eacb02
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs
@@ -0,0 +1 @@
struct S<T = i32>;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt
new file mode 100644
index 000000000..a75b7ed0a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt
@@ -0,0 +1,22 @@
1ROOT@[0; 19)
2 STRUCT_DEF@[0; 18)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 17)
8 L_ANGLE@[8; 9)
9 TYPE_PARAM@[9; 16)
10 NAME@[9; 10)
11 IDENT@[9; 10) "T"
12 WHITESPACE@[10; 11)
13 EQ@[11; 12)
14 WHITESPACE@[12; 13)
15 PATH_TYPE@[13; 16)
16 PATH@[13; 16)
17 PATH_SEGMENT@[13; 16)
18 NAME_REF@[13; 16)
19 IDENT@[13; 16) "i32"
20 R_ANGLE@[16; 17)
21 SEMI@[17; 18)
22 WHITESPACE@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs
new file mode 100644
index 000000000..0c9a20718
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 let _ = f();
3 let _ = f()(1)(1, 2,);
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt
new file mode 100644
index 000000000..f8e31045a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt
@@ -0,0 +1,70 @@
1ROOT@[0; 57)
2 FN_DEF@[0; 56)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 56)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 27)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 PLACEHOLDER_PAT@[19; 20)
18 UNDERSCORE@[19; 20)
19 WHITESPACE@[20; 21)
20 EQ@[21; 22)
21 WHITESPACE@[22; 23)
22 CALL_EXPR@[23; 26)
23 PATH_EXPR@[23; 24)
24 PATH@[23; 24)
25 PATH_SEGMENT@[23; 24)
26 NAME_REF@[23; 24)
27 IDENT@[23; 24) "f"
28 ARG_LIST@[24; 26)
29 L_PAREN@[24; 25)
30 R_PAREN@[25; 26)
31 SEMI@[26; 27)
32 WHITESPACE@[27; 32)
33 LET_STMT@[32; 54)
34 LET_KW@[32; 35)
35 WHITESPACE@[35; 36)
36 PLACEHOLDER_PAT@[36; 37)
37 UNDERSCORE@[36; 37)
38 WHITESPACE@[37; 38)
39 EQ@[38; 39)
40 WHITESPACE@[39; 40)
41 CALL_EXPR@[40; 53)
42 CALL_EXPR@[40; 46)
43 CALL_EXPR@[40; 43)
44 PATH_EXPR@[40; 41)
45 PATH@[40; 41)
46 PATH_SEGMENT@[40; 41)
47 NAME_REF@[40; 41)
48 IDENT@[40; 41) "f"
49 ARG_LIST@[41; 43)
50 L_PAREN@[41; 42)
51 R_PAREN@[42; 43)
52 ARG_LIST@[43; 46)
53 L_PAREN@[43; 44)
54 LITERAL@[44; 45)
55 INT_NUMBER@[44; 45) "1"
56 R_PAREN@[45; 46)
57 ARG_LIST@[46; 53)
58 L_PAREN@[46; 47)
59 LITERAL@[47; 48)
60 INT_NUMBER@[47; 48) "1"
61 COMMA@[48; 49)
62 WHITESPACE@[49; 50)
63 LITERAL@[50; 51)
64 INT_NUMBER@[50; 51) "2"
65 COMMA@[51; 52)
66 R_PAREN@[52; 53)
67 SEMI@[53; 54)
68 WHITESPACE@[54; 55)
69 R_CURLY@[55; 56)
70 WHITESPACE@[56; 57)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs
new file mode 100644
index 000000000..2dac6be95
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 let _ = &1;
3 let _ = &mut &f();
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt
new file mode 100644
index 000000000..77f2ca22c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt
@@ -0,0 +1,54 @@
1ROOT@[0; 52)
2 FN_DEF@[0; 51)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 51)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 26)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 PLACEHOLDER_PAT@[19; 20)
18 UNDERSCORE@[19; 20)
19 WHITESPACE@[20; 21)
20 EQ@[21; 22)
21 WHITESPACE@[22; 23)
22 REF_EXPR@[23; 25)
23 AMP@[23; 24)
24 LITERAL@[24; 25)
25 INT_NUMBER@[24; 25) "1"
26 SEMI@[25; 26)
27 WHITESPACE@[26; 31)
28 LET_STMT@[31; 49)
29 LET_KW@[31; 34)
30 WHITESPACE@[34; 35)
31 PLACEHOLDER_PAT@[35; 36)
32 UNDERSCORE@[35; 36)
33 WHITESPACE@[36; 37)
34 EQ@[37; 38)
35 WHITESPACE@[38; 39)
36 REF_EXPR@[39; 48)
37 AMP@[39; 40)
38 MUT_KW@[40; 43)
39 WHITESPACE@[43; 44)
40 REF_EXPR@[44; 48)
41 AMP@[44; 45)
42 CALL_EXPR@[45; 48)
43 PATH_EXPR@[45; 46)
44 PATH@[45; 46)
45 PATH_SEGMENT@[45; 46)
46 NAME_REF@[45; 46)
47 IDENT@[45; 46) "f"
48 ARG_LIST@[46; 48)
49 L_PAREN@[46; 47)
50 R_PAREN@[47; 48)
51 SEMI@[48; 49)
52 WHITESPACE@[49; 50)
53 R_CURLY@[50; 51)
54 WHITESPACE@[51; 52)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0045_block.rs b/crates/ra_syntax/tests/data/parser/inline/0045_block.rs
new file mode 100644
index 000000000..81f44c533
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0045_block.rs
@@ -0,0 +1,4 @@
1fn a() {}
2fn b() { let _ = 1; }
3fn c() { 1; 2; }
4fn d() { 1; 2 }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0045_block.txt b/crates/ra_syntax/tests/data/parser/inline/0045_block.txt
new file mode 100644
index 000000000..e6c841f21
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0045_block.txt
@@ -0,0 +1,86 @@
1ROOT@[0; 65)
2 FN_DEF@[0; 9)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 4)
6 IDENT@[3; 4) "a"
7 PARAM_LIST@[4; 6)
8 L_PAREN@[4; 5)
9 R_PAREN@[5; 6)
10 WHITESPACE@[6; 7)
11 BLOCK@[7; 9)
12 L_CURLY@[7; 8)
13 R_CURLY@[8; 9)
14 WHITESPACE@[9; 10)
15 FN_DEF@[10; 31)
16 FN_KW@[10; 12)
17 WHITESPACE@[12; 13)
18 NAME@[13; 14)
19 IDENT@[13; 14) "b"
20 PARAM_LIST@[14; 16)
21 L_PAREN@[14; 15)
22 R_PAREN@[15; 16)
23 WHITESPACE@[16; 17)
24 BLOCK@[17; 31)
25 L_CURLY@[17; 18)
26 WHITESPACE@[18; 19)
27 LET_STMT@[19; 29)
28 LET_KW@[19; 22)
29 WHITESPACE@[22; 23)
30 PLACEHOLDER_PAT@[23; 24)
31 UNDERSCORE@[23; 24)
32 WHITESPACE@[24; 25)
33 EQ@[25; 26)
34 WHITESPACE@[26; 27)
35 LITERAL@[27; 28)
36 INT_NUMBER@[27; 28) "1"
37 SEMI@[28; 29)
38 WHITESPACE@[29; 30)
39 R_CURLY@[30; 31)
40 WHITESPACE@[31; 32)
41 FN_DEF@[32; 48)
42 FN_KW@[32; 34)
43 WHITESPACE@[34; 35)
44 NAME@[35; 36)
45 IDENT@[35; 36) "c"
46 PARAM_LIST@[36; 38)
47 L_PAREN@[36; 37)
48 R_PAREN@[37; 38)
49 WHITESPACE@[38; 39)
50 BLOCK@[39; 48)
51 L_CURLY@[39; 40)
52 WHITESPACE@[40; 41)
53 EXPR_STMT@[41; 43)
54 LITERAL@[41; 42)
55 INT_NUMBER@[41; 42) "1"
56 SEMI@[42; 43)
57 WHITESPACE@[43; 44)
58 EXPR_STMT@[44; 46)
59 LITERAL@[44; 45)
60 INT_NUMBER@[44; 45) "2"
61 SEMI@[45; 46)
62 WHITESPACE@[46; 47)
63 R_CURLY@[47; 48)
64 WHITESPACE@[48; 49)
65 FN_DEF@[49; 64)
66 FN_KW@[49; 51)
67 WHITESPACE@[51; 52)
68 NAME@[52; 53)
69 IDENT@[52; 53) "d"
70 PARAM_LIST@[53; 55)
71 L_PAREN@[53; 54)
72 R_PAREN@[54; 55)
73 WHITESPACE@[55; 56)
74 BLOCK@[56; 64)
75 L_CURLY@[56; 57)
76 WHITESPACE@[57; 58)
77 EXPR_STMT@[58; 60)
78 LITERAL@[58; 59)
79 INT_NUMBER@[58; 59) "1"
80 SEMI@[59; 60)
81 WHITESPACE@[60; 61)
82 LITERAL@[61; 62)
83 INT_NUMBER@[61; 62) "2"
84 WHITESPACE@[62; 63)
85 R_CURLY@[63; 64)
86 WHITESPACE@[64; 65)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs
new file mode 100644
index 000000000..ef6aa84a2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs
@@ -0,0 +1 @@
default impl Foo {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt
new file mode 100644
index 000000000..19fe5ca85
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt
@@ -0,0 +1,16 @@
1ROOT@[0; 20)
2 IMPL_ITEM@[0; 19)
3 DEFAULT_KW@[0; 7)
4 WHITESPACE@[7; 8)
5 IMPL_KW@[8; 12)
6 WHITESPACE@[12; 13)
7 PATH_TYPE@[13; 16)
8 PATH@[13; 16)
9 PATH_SEGMENT@[13; 16)
10 NAME_REF@[13; 16)
11 IDENT@[13; 16) "Foo"
12 WHITESPACE@[16; 17)
13 ITEM_LIST@[17; 19)
14 L_CURLY@[17; 18)
15 R_CURLY@[18; 19)
16 WHITESPACE@[19; 20)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs
new file mode 100644
index 000000000..d6337f6b3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs
@@ -0,0 +1 @@
impl Foo {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt
new file mode 100644
index 000000000..6419243e2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt
@@ -0,0 +1,14 @@
1ROOT@[0; 12)
2 IMPL_ITEM@[0; 11)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 8)
6 PATH@[5; 8)
7 PATH_SEGMENT@[5; 8)
8 NAME_REF@[5; 8)
9 IDENT@[5; 8) "Foo"
10 WHITESPACE@[8; 9)
11 ITEM_LIST@[9; 11)
12 L_CURLY@[9; 10)
13 R_CURLY@[10; 11)
14 WHITESPACE@[11; 12)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs
new file mode 100644
index 000000000..b7527c870
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs
@@ -0,0 +1 @@
impl !Send for X {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt
new file mode 100644
index 000000000..6739f9c55
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt
@@ -0,0 +1,23 @@
1ROOT@[0; 20)
2 IMPL_ITEM@[0; 19)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 EXCL@[5; 6)
6 PATH_TYPE@[6; 10)
7 PATH@[6; 10)
8 PATH_SEGMENT@[6; 10)
9 NAME_REF@[6; 10)
10 IDENT@[6; 10) "Send"
11 WHITESPACE@[10; 11)
12 FOR_KW@[11; 14)
13 WHITESPACE@[14; 15)
14 PATH_TYPE@[15; 16)
15 PATH@[15; 16)
16 PATH_SEGMENT@[15; 16)
17 NAME_REF@[15; 16)
18 IDENT@[15; 16) "X"
19 WHITESPACE@[16; 17)
20 ITEM_LIST@[17; 19)
21 L_CURLY@[17; 18)
22 R_CURLY@[18; 19)
23 WHITESPACE@[19; 20)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs
new file mode 100644
index 000000000..a5ec3239f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs
@@ -0,0 +1,6 @@
1impl F {
2 type A: Clone;
3 const B: i32;
4 fn foo() {}
5 fn bar(&self);
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt
new file mode 100644
index 000000000..72d9220e8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt
@@ -0,0 +1,69 @@
1ROOT@[0; 83)
2 IMPL_ITEM@[0; 82)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6)
6 PATH@[5; 6)
7 PATH_SEGMENT@[5; 6)
8 NAME_REF@[5; 6)
9 IDENT@[5; 6) "F"
10 WHITESPACE@[6; 7)
11 ITEM_LIST@[7; 82)
12 L_CURLY@[7; 8)
13 WHITESPACE@[8; 13)
14 TYPE_DEF@[13; 27)
15 TYPE_KW@[13; 17)
16 WHITESPACE@[17; 18)
17 NAME@[18; 19)
18 IDENT@[18; 19) "A"
19 COLON@[19; 20)
20 WHITESPACE@[20; 21)
21 PATH_TYPE@[21; 26)
22 PATH@[21; 26)
23 PATH_SEGMENT@[21; 26)
24 NAME_REF@[21; 26)
25 IDENT@[21; 26) "Clone"
26 SEMI@[26; 27)
27 WHITESPACE@[27; 32)
28 CONST_DEF@[32; 45)
29 CONST_KW@[32; 37)
30 WHITESPACE@[37; 38)
31 NAME@[38; 39)
32 IDENT@[38; 39) "B"
33 COLON@[39; 40)
34 WHITESPACE@[40; 41)
35 PATH_TYPE@[41; 44)
36 PATH@[41; 44)
37 PATH_SEGMENT@[41; 44)
38 NAME_REF@[41; 44)
39 IDENT@[41; 44) "i32"
40 SEMI@[44; 45)
41 WHITESPACE@[45; 50)
42 FN_DEF@[50; 61)
43 FN_KW@[50; 52)
44 WHITESPACE@[52; 53)
45 NAME@[53; 56)
46 IDENT@[53; 56) "foo"
47 PARAM_LIST@[56; 58)
48 L_PAREN@[56; 57)
49 R_PAREN@[57; 58)
50 WHITESPACE@[58; 59)
51 BLOCK@[59; 61)
52 L_CURLY@[59; 60)
53 R_CURLY@[60; 61)
54 WHITESPACE@[61; 66)
55 FN_DEF@[66; 80)
56 FN_KW@[66; 68)
57 WHITESPACE@[68; 69)
58 NAME@[69; 72)
59 IDENT@[69; 72) "bar"
60 PARAM_LIST@[72; 79)
61 L_PAREN@[72; 73)
62 SELF_PARAM@[73; 78)
63 AMP@[73; 74)
64 SELF_KW@[74; 78)
65 R_PAREN@[78; 79)
66 SEMI@[79; 80)
67 WHITESPACE@[80; 81)
68 R_CURLY@[81; 82)
69 WHITESPACE@[82; 83)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs
new file mode 100644
index 000000000..0a9af907f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let a;
3 let b: i32;
4 let c = 92;
5 let d: i32 = 92;
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt
new file mode 100644
index 000000000..30dc83454
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt
@@ -0,0 +1,71 @@
1ROOT@[0; 77)
2 FN_DEF@[0; 76)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 76)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 21)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 BIND_PAT@[19; 20)
18 NAME@[19; 20)
19 IDENT@[19; 20) "a"
20 SEMI@[20; 21)
21 WHITESPACE@[21; 26)
22 LET_STMT@[26; 37)
23 LET_KW@[26; 29)
24 WHITESPACE@[29; 30)
25 BIND_PAT@[30; 31)
26 NAME@[30; 31)
27 IDENT@[30; 31) "b"
28 COLON@[31; 32)
29 WHITESPACE@[32; 33)
30 PATH_TYPE@[33; 36)
31 PATH@[33; 36)
32 PATH_SEGMENT@[33; 36)
33 NAME_REF@[33; 36)
34 IDENT@[33; 36) "i32"
35 SEMI@[36; 37)
36 WHITESPACE@[37; 42)
37 LET_STMT@[42; 53)
38 LET_KW@[42; 45)
39 WHITESPACE@[45; 46)
40 BIND_PAT@[46; 47)
41 NAME@[46; 47)
42 IDENT@[46; 47) "c"
43 WHITESPACE@[47; 48)
44 EQ@[48; 49)
45 WHITESPACE@[49; 50)
46 LITERAL@[50; 52)
47 INT_NUMBER@[50; 52) "92"
48 SEMI@[52; 53)
49 WHITESPACE@[53; 58)
50 LET_STMT@[58; 74)
51 LET_KW@[58; 61)
52 WHITESPACE@[61; 62)
53 BIND_PAT@[62; 63)
54 NAME@[62; 63)
55 IDENT@[62; 63) "d"
56 COLON@[63; 64)
57 WHITESPACE@[64; 65)
58 PATH_TYPE@[65; 68)
59 PATH@[65; 68)
60 PATH_SEGMENT@[65; 68)
61 NAME_REF@[65; 68)
62 IDENT@[65; 68) "i32"
63 WHITESPACE@[68; 69)
64 EQ@[69; 70)
65 WHITESPACE@[70; 71)
66 LITERAL@[71; 73)
67 INT_NUMBER@[71; 73) "92"
68 SEMI@[73; 74)
69 WHITESPACE@[74; 75)
70 R_CURLY@[75; 76)
71 WHITESPACE@[76; 77)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs
new file mode 100644
index 000000000..1a3aa35ae
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 x.foo();
3 y.bar::<T>(1, 2,);
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt
new file mode 100644
index 000000000..530c80fa8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt
@@ -0,0 +1,62 @@
1ROOT@[0; 49)
2 FN_DEF@[0; 48)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 48)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 23)
15 METHOD_CALL_EXPR@[15; 22)
16 PATH_EXPR@[15; 16)
17 PATH@[15; 16)
18 PATH_SEGMENT@[15; 16)
19 NAME_REF@[15; 16)
20 IDENT@[15; 16) "x"
21 DOT@[16; 17)
22 NAME_REF@[17; 20)
23 IDENT@[17; 20) "foo"
24 ARG_LIST@[20; 22)
25 L_PAREN@[20; 21)
26 R_PAREN@[21; 22)
27 SEMI@[22; 23)
28 WHITESPACE@[23; 28)
29 EXPR_STMT@[28; 46)
30 METHOD_CALL_EXPR@[28; 45)
31 PATH_EXPR@[28; 29)
32 PATH@[28; 29)
33 PATH_SEGMENT@[28; 29)
34 NAME_REF@[28; 29)
35 IDENT@[28; 29) "y"
36 DOT@[29; 30)
37 NAME_REF@[30; 33)
38 IDENT@[30; 33) "bar"
39 TYPE_ARG_LIST@[33; 38)
40 COLONCOLON@[33; 35)
41 L_ANGLE@[35; 36)
42 TYPE_ARG@[36; 37)
43 PATH_TYPE@[36; 37)
44 PATH@[36; 37)
45 PATH_SEGMENT@[36; 37)
46 NAME_REF@[36; 37)
47 IDENT@[36; 37) "T"
48 R_ANGLE@[37; 38)
49 ARG_LIST@[38; 45)
50 L_PAREN@[38; 39)
51 LITERAL@[39; 40)
52 INT_NUMBER@[39; 40) "1"
53 COMMA@[40; 41)
54 WHITESPACE@[41; 42)
55 LITERAL@[42; 43)
56 INT_NUMBER@[42; 43) "2"
57 COMMA@[43; 44)
58 R_PAREN@[44; 45)
59 SEMI@[45; 46)
60 WHITESPACE@[46; 47)
61 R_CURLY@[47; 48)
62 WHITESPACE@[48; 49)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs
new file mode 100644
index 000000000..3e69538e5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 x.foo;
3 x.0.bar;
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt
new file mode 100644
index 000000000..9086219ca
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt
@@ -0,0 +1,42 @@
1ROOT@[0; 37)
2 FN_DEF@[0; 36)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 36)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 21)
15 FIELD_EXPR@[15; 20)
16 PATH_EXPR@[15; 16)
17 PATH@[15; 16)
18 PATH_SEGMENT@[15; 16)
19 NAME_REF@[15; 16)
20 IDENT@[15; 16) "x"
21 DOT@[16; 17)
22 NAME_REF@[17; 20)
23 IDENT@[17; 20) "foo"
24 SEMI@[20; 21)
25 WHITESPACE@[21; 26)
26 EXPR_STMT@[26; 34)
27 FIELD_EXPR@[26; 33)
28 FIELD_EXPR@[26; 29)
29 PATH_EXPR@[26; 27)
30 PATH@[26; 27)
31 PATH_SEGMENT@[26; 27)
32 NAME_REF@[26; 27)
33 IDENT@[26; 27) "x"
34 DOT@[27; 28)
35 INT_NUMBER@[28; 29) "0"
36 DOT@[29; 30)
37 NAME_REF@[30; 33)
38 IDENT@[30; 33) "bar"
39 SEMI@[33; 34)
40 WHITESPACE@[34; 35)
41 R_CURLY@[35; 36)
42 WHITESPACE@[36; 37)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs
new file mode 100644
index 000000000..d9868718c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs
@@ -0,0 +1 @@
fn a() { fn b() {} }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt
new file mode 100644
index 000000000..20122d763
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt
@@ -0,0 +1,28 @@
1ROOT@[0; 21)
2 FN_DEF@[0; 20)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 4)
6 IDENT@[3; 4) "a"
7 PARAM_LIST@[4; 6)
8 L_PAREN@[4; 5)
9 R_PAREN@[5; 6)
10 WHITESPACE@[6; 7)
11 BLOCK@[7; 20)
12 L_CURLY@[7; 8)
13 WHITESPACE@[8; 9)
14 FN_DEF@[9; 18)
15 FN_KW@[9; 11)
16 WHITESPACE@[11; 12)
17 NAME@[12; 13)
18 IDENT@[12; 13) "b"
19 PARAM_LIST@[13; 15)
20 L_PAREN@[13; 14)
21 R_PAREN@[14; 15)
22 WHITESPACE@[15; 16)
23 BLOCK@[16; 18)
24 L_CURLY@[16; 17)
25 R_CURLY@[17; 18)
26 WHITESPACE@[18; 19)
27 R_CURLY@[19; 20)
28 WHITESPACE@[20; 21)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs
new file mode 100644
index 000000000..da3412fa8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let S {} = ();
3 let S { f, ref mut g } = ();
4 let S { h: _, ..} = ();
5 let S { h: _, } = ();
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt
new file mode 100644
index 000000000..4df4ca35b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt
@@ -0,0 +1,126 @@
1ROOT@[0; 119)
2 FN_DEF@[0; 118)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 118)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 29)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 STRUCT_PAT@[19; 23)
18 PATH@[19; 20)
19 PATH_SEGMENT@[19; 20)
20 NAME_REF@[19; 20)
21 IDENT@[19; 20) "S"
22 WHITESPACE@[20; 21)
23 FIELD_PAT_LIST@[21; 23)
24 L_CURLY@[21; 22)
25 R_CURLY@[22; 23)
26 WHITESPACE@[23; 24)
27 EQ@[24; 25)
28 WHITESPACE@[25; 26)
29 TUPLE_EXPR@[26; 28)
30 L_PAREN@[26; 27)
31 R_PAREN@[27; 28)
32 SEMI@[28; 29)
33 WHITESPACE@[29; 34)
34 LET_STMT@[34; 62)
35 LET_KW@[34; 37)
36 WHITESPACE@[37; 38)
37 STRUCT_PAT@[38; 56)
38 PATH@[38; 39)
39 PATH_SEGMENT@[38; 39)
40 NAME_REF@[38; 39)
41 IDENT@[38; 39) "S"
42 WHITESPACE@[39; 40)
43 FIELD_PAT_LIST@[40; 56)
44 L_CURLY@[40; 41)
45 WHITESPACE@[41; 42)
46 BIND_PAT@[42; 43)
47 NAME@[42; 43)
48 IDENT@[42; 43) "f"
49 COMMA@[43; 44)
50 WHITESPACE@[44; 45)
51 BIND_PAT@[45; 54)
52 REF_KW@[45; 48)
53 WHITESPACE@[48; 49)
54 MUT_KW@[49; 52)
55 WHITESPACE@[52; 53)
56 NAME@[53; 54)
57 IDENT@[53; 54) "g"
58 WHITESPACE@[54; 55)
59 R_CURLY@[55; 56)
60 WHITESPACE@[56; 57)
61 EQ@[57; 58)
62 WHITESPACE@[58; 59)
63 TUPLE_EXPR@[59; 61)
64 L_PAREN@[59; 60)
65 R_PAREN@[60; 61)
66 SEMI@[61; 62)
67 WHITESPACE@[62; 67)
68 LET_STMT@[67; 90)
69 LET_KW@[67; 70)
70 WHITESPACE@[70; 71)
71 STRUCT_PAT@[71; 84)
72 PATH@[71; 72)
73 PATH_SEGMENT@[71; 72)
74 NAME_REF@[71; 72)
75 IDENT@[71; 72) "S"
76 WHITESPACE@[72; 73)
77 FIELD_PAT_LIST@[73; 84)
78 L_CURLY@[73; 74)
79 WHITESPACE@[74; 75)
80 IDENT@[75; 76) "h"
81 COLON@[76; 77)
82 WHITESPACE@[77; 78)
83 PLACEHOLDER_PAT@[78; 79)
84 UNDERSCORE@[78; 79)
85 COMMA@[79; 80)
86 WHITESPACE@[80; 81)
87 DOTDOT@[81; 83)
88 R_CURLY@[83; 84)
89 WHITESPACE@[84; 85)
90 EQ@[85; 86)
91 WHITESPACE@[86; 87)
92 TUPLE_EXPR@[87; 89)
93 L_PAREN@[87; 88)
94 R_PAREN@[88; 89)
95 SEMI@[89; 90)
96 WHITESPACE@[90; 95)
97 LET_STMT@[95; 116)
98 LET_KW@[95; 98)
99 WHITESPACE@[98; 99)
100 STRUCT_PAT@[99; 110)
101 PATH@[99; 100)
102 PATH_SEGMENT@[99; 100)
103 NAME_REF@[99; 100)
104 IDENT@[99; 100) "S"
105 WHITESPACE@[100; 101)
106 FIELD_PAT_LIST@[101; 110)
107 L_CURLY@[101; 102)
108 WHITESPACE@[102; 103)
109 IDENT@[103; 104) "h"
110 COLON@[104; 105)
111 WHITESPACE@[105; 106)
112 PLACEHOLDER_PAT@[106; 107)
113 UNDERSCORE@[106; 107)
114 COMMA@[107; 108)
115 WHITESPACE@[108; 109)
116 R_CURLY@[109; 110)
117 WHITESPACE@[110; 111)
118 EQ@[111; 112)
119 WHITESPACE@[112; 113)
120 TUPLE_EXPR@[113; 115)
121 L_PAREN@[113; 114)
122 R_PAREN@[114; 115)
123 SEMI@[115; 116)
124 WHITESPACE@[116; 117)
125 R_CURLY@[117; 118)
126 WHITESPACE@[118; 119)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs
new file mode 100644
index 000000000..80c0a43f5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs
@@ -0,0 +1,7 @@
1impl S {
2 fn a(self) {}
3 fn b(&self,) {}
4 fn c(&'a self,) {}
5 fn d(&'a mut self, x: i32) {}
6 fn e(mut self) {}
7}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt
new file mode 100644
index 000000000..f0e47c2dc
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt
@@ -0,0 +1,116 @@
1ROOT@[0; 128)
2 IMPL_ITEM@[0; 127)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6)
6 PATH@[5; 6)
7 PATH_SEGMENT@[5; 6)
8 NAME_REF@[5; 6)
9 IDENT@[5; 6) "S"
10 WHITESPACE@[6; 7)
11 ITEM_LIST@[7; 127)
12 L_CURLY@[7; 8)
13 WHITESPACE@[8; 13)
14 FN_DEF@[13; 26)
15 FN_KW@[13; 15)
16 WHITESPACE@[15; 16)
17 NAME@[16; 17)
18 IDENT@[16; 17) "a"
19 PARAM_LIST@[17; 23)
20 L_PAREN@[17; 18)
21 SELF_PARAM@[18; 22)
22 SELF_KW@[18; 22)
23 R_PAREN@[22; 23)
24 WHITESPACE@[23; 24)
25 BLOCK@[24; 26)
26 L_CURLY@[24; 25)
27 R_CURLY@[25; 26)
28 WHITESPACE@[26; 31)
29 FN_DEF@[31; 46)
30 FN_KW@[31; 33)
31 WHITESPACE@[33; 34)
32 NAME@[34; 35)
33 IDENT@[34; 35) "b"
34 PARAM_LIST@[35; 43)
35 L_PAREN@[35; 36)
36 SELF_PARAM@[36; 41)
37 AMP@[36; 37)
38 SELF_KW@[37; 41)
39 COMMA@[41; 42)
40 R_PAREN@[42; 43)
41 WHITESPACE@[43; 44)
42 BLOCK@[44; 46)
43 L_CURLY@[44; 45)
44 R_CURLY@[45; 46)
45 WHITESPACE@[46; 51)
46 FN_DEF@[51; 69)
47 FN_KW@[51; 53)
48 WHITESPACE@[53; 54)
49 NAME@[54; 55)
50 IDENT@[54; 55) "c"
51 PARAM_LIST@[55; 66)
52 L_PAREN@[55; 56)
53 SELF_PARAM@[56; 64)
54 AMP@[56; 57)
55 LIFETIME@[57; 59) "'a"
56 WHITESPACE@[59; 60)
57 SELF_KW@[60; 64)
58 COMMA@[64; 65)
59 R_PAREN@[65; 66)
60 WHITESPACE@[66; 67)
61 BLOCK@[67; 69)
62 L_CURLY@[67; 68)
63 R_CURLY@[68; 69)
64 WHITESPACE@[69; 74)
65 FN_DEF@[74; 103)
66 FN_KW@[74; 76)
67 WHITESPACE@[76; 77)
68 NAME@[77; 78)
69 IDENT@[77; 78) "d"
70 PARAM_LIST@[78; 100)
71 L_PAREN@[78; 79)
72 SELF_PARAM@[79; 91)
73 AMP@[79; 80)
74 LIFETIME@[80; 82) "'a"
75 WHITESPACE@[82; 83)
76 MUT_KW@[83; 86)
77 WHITESPACE@[86; 87)
78 SELF_KW@[87; 91)
79 COMMA@[91; 92)
80 WHITESPACE@[92; 93)
81 PARAM@[93; 99)
82 BIND_PAT@[93; 94)
83 NAME@[93; 94)
84 IDENT@[93; 94) "x"
85 COLON@[94; 95)
86 WHITESPACE@[95; 96)
87 PATH_TYPE@[96; 99)
88 PATH@[96; 99)
89 PATH_SEGMENT@[96; 99)
90 NAME_REF@[96; 99)
91 IDENT@[96; 99) "i32"
92 R_PAREN@[99; 100)
93 WHITESPACE@[100; 101)
94 BLOCK@[101; 103)
95 L_CURLY@[101; 102)
96 R_CURLY@[102; 103)
97 WHITESPACE@[103; 108)
98 FN_DEF@[108; 125)
99 FN_KW@[108; 110)
100 WHITESPACE@[110; 111)
101 NAME@[111; 112)
102 IDENT@[111; 112) "e"
103 PARAM_LIST@[112; 122)
104 L_PAREN@[112; 113)
105 SELF_PARAM@[113; 121)
106 MUT_KW@[113; 116)
107 WHITESPACE@[116; 117)
108 SELF_KW@[117; 121)
109 R_PAREN@[121; 122)
110 WHITESPACE@[122; 123)
111 BLOCK@[123; 125)
112 L_CURLY@[123; 124)
113 R_CURLY@[124; 125)
114 WHITESPACE@[125; 126)
115 R_CURLY@[126; 127)
116 WHITESPACE@[127; 128)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs
new file mode 100644
index 000000000..4385afca9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs
@@ -0,0 +1 @@
trait T<U>: Hash + Clone where U: Copy {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt
new file mode 100644
index 000000000..40c77db4b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt
@@ -0,0 +1,49 @@
1ROOT@[0; 42)
2 TRAIT_DEF@[0; 41)
3 TRAIT_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 NAME@[6; 7)
6 IDENT@[6; 7) "T"
7 TYPE_PARAM_LIST@[7; 10)
8 L_ANGLE@[7; 8)
9 TYPE_PARAM@[8; 9)
10 NAME@[8; 9)
11 IDENT@[8; 9) "U"
12 R_ANGLE@[9; 10)
13 COLON@[10; 11)
14 WHITESPACE@[11; 12)
15 PATH_TYPE@[12; 24)
16 PATH@[12; 16)
17 PATH_SEGMENT@[12; 16)
18 NAME_REF@[12; 16)
19 IDENT@[12; 16) "Hash"
20 WHITESPACE@[16; 17)
21 PLUS@[17; 18)
22 WHITESPACE@[18; 19)
23 PATH_TYPE@[19; 24)
24 PATH@[19; 24)
25 PATH_SEGMENT@[19; 24)
26 NAME_REF@[19; 24)
27 IDENT@[19; 24) "Clone"
28 WHITESPACE@[24; 25)
29 WHERE_CLAUSE@[25; 38)
30 WHERE_KW@[25; 30)
31 WHITESPACE@[30; 31)
32 WHERE_PRED@[31; 38)
33 PATH_TYPE@[31; 32)
34 PATH@[31; 32)
35 PATH_SEGMENT@[31; 32)
36 NAME_REF@[31; 32)
37 IDENT@[31; 32) "U"
38 COLON@[32; 33)
39 WHITESPACE@[33; 34)
40 PATH_TYPE@[34; 38)
41 PATH@[34; 38)
42 PATH_SEGMENT@[34; 38)
43 NAME_REF@[34; 38)
44 IDENT@[34; 38) "Copy"
45 WHITESPACE@[38; 39)
46 ITEM_LIST@[39; 41)
47 L_CURLY@[39; 40)
48 R_CURLY@[40; 41)
49 WHITESPACE@[41; 42)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs
new file mode 100644
index 000000000..72adf6035
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs
@@ -0,0 +1 @@
auto trait T {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt
new file mode 100644
index 000000000..0303d76bd
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt
@@ -0,0 +1,13 @@
1ROOT@[0; 16)
2 TRAIT_DEF@[0; 15)
3 AUTO_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 TRAIT_KW@[5; 10)
6 WHITESPACE@[10; 11)
7 NAME@[11; 12)
8 IDENT@[11; 12) "T"
9 WHITESPACE@[12; 13)
10 ITEM_LIST@[13; 15)
11 L_CURLY@[13; 14)
12 R_CURLY@[14; 15)
13 WHITESPACE@[15; 16)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs
new file mode 100644
index 000000000..f0c8cc3a8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs
@@ -0,0 +1 @@
type A = B<'static, i32, Item=u64>
diff --git a/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt
new file mode 100644
index 000000000..aaf2924ba
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt
@@ -0,0 +1,40 @@
1ROOT@[0; 35)
2 TYPE_DEF@[0; 34)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 PATH_TYPE@[9; 34)
11 PATH@[9; 34)
12 PATH_SEGMENT@[9; 34)
13 NAME_REF@[9; 10)
14 IDENT@[9; 10) "B"
15 TYPE_ARG_LIST@[10; 34)
16 L_ANGLE@[10; 11)
17 LIFETIME_ARG@[11; 18)
18 LIFETIME@[11; 18) "'static"
19 COMMA@[18; 19)
20 WHITESPACE@[19; 20)
21 TYPE_ARG@[20; 23)
22 PATH_TYPE@[20; 23)
23 PATH@[20; 23)
24 PATH_SEGMENT@[20; 23)
25 NAME_REF@[20; 23)
26 IDENT@[20; 23) "i32"
27 COMMA@[23; 24)
28 WHITESPACE@[24; 25)
29 ASSOC_TYPE_ARG@[25; 33)
30 NAME_REF@[25; 29)
31 IDENT@[25; 29) "Item"
32 EQ@[29; 30)
33 PATH_TYPE@[30; 33)
34 PATH@[30; 33)
35 PATH_SEGMENT@[30; 33)
36 NAME_REF@[30; 33)
37 IDENT@[30; 33) "u64"
38 R_ANGLE@[33; 34)
39 err: `expected SEMI`
40 WHITESPACE@[34; 35)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs
new file mode 100644
index 000000000..f0920b2a8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs
@@ -0,0 +1 @@
fn foo<T>() where T: Copy {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt
new file mode 100644
index 000000000..281e79deb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt
@@ -0,0 +1,37 @@
1ROOT@[0; 29)
2 FN_DEF@[0; 28)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 TYPE_PARAM_LIST@[6; 9)
8 L_ANGLE@[6; 7)
9 TYPE_PARAM@[7; 8)
10 NAME@[7; 8)
11 IDENT@[7; 8) "T"
12 R_ANGLE@[8; 9)
13 PARAM_LIST@[9; 11)
14 L_PAREN@[9; 10)
15 R_PAREN@[10; 11)
16 WHITESPACE@[11; 12)
17 WHERE_CLAUSE@[12; 25)
18 WHERE_KW@[12; 17)
19 WHITESPACE@[17; 18)
20 WHERE_PRED@[18; 25)
21 PATH_TYPE@[18; 19)
22 PATH@[18; 19)
23 PATH_SEGMENT@[18; 19)
24 NAME_REF@[18; 19)
25 IDENT@[18; 19) "T"
26 COLON@[19; 20)
27 WHITESPACE@[20; 21)
28 PATH_TYPE@[21; 25)
29 PATH@[21; 25)
30 PATH_SEGMENT@[21; 25)
31 NAME_REF@[21; 25)
32 IDENT@[21; 25) "Copy"
33 WHITESPACE@[25; 26)
34 BLOCK@[26; 28)
35 L_CURLY@[26; 27)
36 R_CURLY@[27; 28)
37 WHITESPACE@[28; 29)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs
new file mode 100644
index 000000000..9df40ed39
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs
@@ -0,0 +1 @@
fn foo<T: Clone + Copy>(){}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt
new file mode 100644
index 000000000..b6fea5ab2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt
@@ -0,0 +1,34 @@
1ROOT@[0; 28)
2 FN_DEF@[0; 27)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 TYPE_PARAM_LIST@[6; 23)
8 L_ANGLE@[6; 7)
9 TYPE_PARAM@[7; 22)
10 NAME@[7; 8)
11 IDENT@[7; 8) "T"
12 COLON@[8; 9)
13 WHITESPACE@[9; 10)
14 PATH_TYPE@[10; 22)
15 PATH@[10; 15)
16 PATH_SEGMENT@[10; 15)
17 NAME_REF@[10; 15)
18 IDENT@[10; 15) "Clone"
19 WHITESPACE@[15; 16)
20 PLUS@[16; 17)
21 WHITESPACE@[17; 18)
22 PATH_TYPE@[18; 22)
23 PATH@[18; 22)
24 PATH_SEGMENT@[18; 22)
25 NAME_REF@[18; 22)
26 IDENT@[18; 22) "Copy"
27 R_ANGLE@[22; 23)
28 PARAM_LIST@[23; 25)
29 L_PAREN@[23; 24)
30 R_PAREN@[24; 25)
31 BLOCK@[25; 27)
32 L_CURLY@[25; 26)
33 R_CURLY@[26; 27)
34 WHITESPACE@[27; 28)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs
new file mode 100644
index 000000000..eb711f68a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 S {};
3 S { x, y: 32, };
4 S { x, y: 32, ..Default::default() };
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt
new file mode 100644
index 000000000..cf6e881b2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt
@@ -0,0 +1,97 @@
1ROOT@[0; 86)
2 FN_DEF@[0; 85)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 85)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 20)
15 STRUCT_LIT@[15; 19)
16 PATH@[15; 16)
17 PATH_SEGMENT@[15; 16)
18 NAME_REF@[15; 16)
19 IDENT@[15; 16) "S"
20 WHITESPACE@[16; 17)
21 NAMED_FIELD_LIST@[17; 19)
22 L_CURLY@[17; 18)
23 R_CURLY@[18; 19)
24 SEMI@[19; 20)
25 WHITESPACE@[20; 25)
26 EXPR_STMT@[25; 41)
27 STRUCT_LIT@[25; 40)
28 PATH@[25; 26)
29 PATH_SEGMENT@[25; 26)
30 NAME_REF@[25; 26)
31 IDENT@[25; 26) "S"
32 WHITESPACE@[26; 27)
33 NAMED_FIELD_LIST@[27; 40)
34 L_CURLY@[27; 28)
35 WHITESPACE@[28; 29)
36 NAMED_FIELD@[29; 30)
37 NAME_REF@[29; 30)
38 IDENT@[29; 30) "x"
39 COMMA@[30; 31)
40 WHITESPACE@[31; 32)
41 NAMED_FIELD@[32; 37)
42 NAME_REF@[32; 33)
43 IDENT@[32; 33) "y"
44 COLON@[33; 34)
45 WHITESPACE@[34; 35)
46 LITERAL@[35; 37)
47 INT_NUMBER@[35; 37) "32"
48 COMMA@[37; 38)
49 WHITESPACE@[38; 39)
50 R_CURLY@[39; 40)
51 SEMI@[40; 41)
52 WHITESPACE@[41; 46)
53 EXPR_STMT@[46; 83)
54 STRUCT_LIT@[46; 82)
55 PATH@[46; 47)
56 PATH_SEGMENT@[46; 47)
57 NAME_REF@[46; 47)
58 IDENT@[46; 47) "S"
59 WHITESPACE@[47; 48)
60 NAMED_FIELD_LIST@[48; 82)
61 L_CURLY@[48; 49)
62 WHITESPACE@[49; 50)
63 NAMED_FIELD@[50; 51)
64 NAME_REF@[50; 51)
65 IDENT@[50; 51) "x"
66 COMMA@[51; 52)
67 WHITESPACE@[52; 53)
68 NAMED_FIELD@[53; 58)
69 NAME_REF@[53; 54)
70 IDENT@[53; 54) "y"
71 COLON@[54; 55)
72 WHITESPACE@[55; 56)
73 LITERAL@[56; 58)
74 INT_NUMBER@[56; 58) "32"
75 COMMA@[58; 59)
76 WHITESPACE@[59; 60)
77 DOTDOT@[60; 62)
78 CALL_EXPR@[62; 80)
79 PATH_EXPR@[62; 78)
80 PATH@[62; 78)
81 PATH@[62; 69)
82 PATH_SEGMENT@[62; 69)
83 NAME_REF@[62; 69)
84 IDENT@[62; 69) "Default"
85 COLONCOLON@[69; 71)
86 PATH_SEGMENT@[71; 78)
87 NAME_REF@[71; 78)
88 IDENT@[71; 78) "default"
89 ARG_LIST@[78; 80)
90 L_PAREN@[78; 79)
91 R_PAREN@[79; 80)
92 WHITESPACE@[80; 81)
93 R_CURLY@[81; 82)
94 SEMI@[82; 83)
95 WHITESPACE@[83; 84)
96 R_CURLY@[84; 85)
97 WHITESPACE@[85; 86)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs
new file mode 100644
index 000000000..54c5a7c46
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs
@@ -0,0 +1 @@
type A = impl Iterator<Item=Foo<'a>> + 'a;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt
new file mode 100644
index 000000000..68fce58ee
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt
@@ -0,0 +1,40 @@
1ROOT@[0; 43)
2 TYPE_DEF@[0; 42)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 IMPL_TRAIT_TYPE@[9; 41)
11 IMPL_KW@[9; 13)
12 WHITESPACE@[13; 14)
13 PATH_TYPE@[14; 41)
14 PATH@[14; 36)
15 PATH_SEGMENT@[14; 36)
16 NAME_REF@[14; 22)
17 IDENT@[14; 22) "Iterator"
18 TYPE_ARG_LIST@[22; 36)
19 L_ANGLE@[22; 23)
20 ASSOC_TYPE_ARG@[23; 35)
21 NAME_REF@[23; 27)
22 IDENT@[23; 27) "Item"
23 EQ@[27; 28)
24 PATH_TYPE@[28; 35)
25 PATH@[28; 35)
26 PATH_SEGMENT@[28; 35)
27 NAME_REF@[28; 31)
28 IDENT@[28; 31) "Foo"
29 TYPE_ARG_LIST@[31; 35)
30 L_ANGLE@[31; 32)
31 LIFETIME_ARG@[32; 34)
32 LIFETIME@[32; 34) "'a"
33 R_ANGLE@[34; 35)
34 R_ANGLE@[35; 36)
35 WHITESPACE@[36; 37)
36 PLUS@[37; 38)
37 WHITESPACE@[38; 39)
38 LIFETIME@[39; 41) "'a"
39 SEMI@[41; 42)
40 WHITESPACE@[42; 43)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt
new file mode 100644
index 000000000..93f6285ac
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt
@@ -0,0 +1,91 @@
1ROOT@[0; 74)
2 FN_DEF@[0; 74)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 9)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK_EXPR@[9; 74)
12 L_CURLY@[9; 10)
13 EXPR_STMT@[10; 26)
14 LAMBDA_EXPR@[10; 20)
15 PARAM_LIST@[10; 18)
16 WHITESPACE@[10; 15)
17 PIPE@[15; 16)
18 PIPE@[16; 17)
19 WHITESPACE@[17; 18)
20 TUPLE_EXPR@[18; 20)
21 L_PAREN@[18; 19)
22 R_PAREN@[19; 20)
23 SEMI@[20; 21)
24 WHITESPACE@[21; 26)
25 EXPR_STMT@[26; 48)
26 LAMBDA_EXPR@[26; 42)
27 PARAM_LIST@[26; 29)
28 PIPE@[26; 27)
29 PIPE@[27; 28)
30 WHITESPACE@[28; 29)
31 THIN_ARROW@[29; 31)
32 PATH_TYPE@[31; 36)
33 PATH@[31; 36)
34 PATH_SEGMENT@[31; 36)
35 NAME_REF@[31; 36)
36 WHITESPACE@[31; 32)
37 IDENT@[32; 35) "i32"
38 WHITESPACE@[35; 36)
39 BLOCK_EXPR@[36; 42)
40 L_CURLY@[36; 37)
41 LITERAL@[37; 41)
42 WHITESPACE@[37; 38)
43 INT_NUMBER@[38; 40) "92"
44 WHITESPACE@[40; 41)
45 R_CURLY@[41; 42)
46 SEMI@[42; 43)
47 WHITESPACE@[43; 48)
48 EXPR_STMT@[48; 59)
49 LAMBDA_EXPR@[48; 53)
50 PARAM_LIST@[48; 52)
51 PIPE@[48; 49)
52 PARAM@[49; 50)
53 BIND_PAT@[49; 50)
54 NAME@[49; 50)
55 IDENT@[49; 50) "x"
56 PIPE@[50; 51)
57 WHITESPACE@[51; 52)
58 PATH_EXPR@[52; 53)
59 PATH@[52; 53)
60 PATH_SEGMENT@[52; 53)
61 NAME_REF@[52; 53)
62 IDENT@[52; 53) "x"
63 SEMI@[53; 54)
64 WHITESPACE@[54; 59)
65 EXPR_STMT@[59; 72)
66 LAMBDA_EXPR@[59; 70)
67 PARAM_LIST@[59; 69)
68 PIPE@[59; 60)
69 PARAM@[60; 66)
70 BIND_PAT@[60; 61)
71 NAME@[60; 61)
72 IDENT@[60; 61) "x"
73 COLON@[61; 62)
74 PATH_TYPE@[62; 66)
75 PATH@[62; 66)
76 PATH_SEGMENT@[62; 66)
77 NAME_REF@[62; 66)
78 WHITESPACE@[62; 63)
79 IDENT@[63; 66) "i32"
80 COMMA@[66; 67)
81 PIPE@[67; 68)
82 WHITESPACE@[68; 69)
83 PATH_EXPR@[69; 70)
84 PATH@[69; 70)
85 PATH_SEGMENT@[69; 70)
86 NAME_REF@[69; 70)
87 IDENT@[69; 70) "x"
88 SEMI@[70; 71)
89 WHITESPACE@[71; 72)
90 R_CURLY@[72; 73)
91 WHITESPACE@[73; 74)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs
new file mode 100644
index 000000000..9d55bedbb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs
@@ -0,0 +1,4 @@
1fn a() {}
2fn b(x: i32) {}
3fn c(x: i32, ) {}
4fn d(x: i32, y: ()) {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt
new file mode 100644
index 000000000..de547d699
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt
@@ -0,0 +1,99 @@
1ROOT@[0; 67)
2 FN_DEF@[0; 9)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 4)
6 IDENT@[3; 4) "a"
7 PARAM_LIST@[4; 6)
8 L_PAREN@[4; 5)
9 R_PAREN@[5; 6)
10 WHITESPACE@[6; 7)
11 BLOCK@[7; 9)
12 L_CURLY@[7; 8)
13 R_CURLY@[8; 9)
14 WHITESPACE@[9; 10)
15 FN_DEF@[10; 25)
16 FN_KW@[10; 12)
17 WHITESPACE@[12; 13)
18 NAME@[13; 14)
19 IDENT@[13; 14) "b"
20 PARAM_LIST@[14; 22)
21 L_PAREN@[14; 15)
22 PARAM@[15; 21)
23 BIND_PAT@[15; 16)
24 NAME@[15; 16)
25 IDENT@[15; 16) "x"
26 COLON@[16; 17)
27 WHITESPACE@[17; 18)
28 PATH_TYPE@[18; 21)
29 PATH@[18; 21)
30 PATH_SEGMENT@[18; 21)
31 NAME_REF@[18; 21)
32 IDENT@[18; 21) "i32"
33 R_PAREN@[21; 22)
34 WHITESPACE@[22; 23)
35 BLOCK@[23; 25)
36 L_CURLY@[23; 24)
37 R_CURLY@[24; 25)
38 WHITESPACE@[25; 26)
39 FN_DEF@[26; 43)
40 FN_KW@[26; 28)
41 WHITESPACE@[28; 29)
42 NAME@[29; 30)
43 IDENT@[29; 30) "c"
44 PARAM_LIST@[30; 40)
45 L_PAREN@[30; 31)
46 PARAM@[31; 37)
47 BIND_PAT@[31; 32)
48 NAME@[31; 32)
49 IDENT@[31; 32) "x"
50 COLON@[32; 33)
51 WHITESPACE@[33; 34)
52 PATH_TYPE@[34; 37)
53 PATH@[34; 37)
54 PATH_SEGMENT@[34; 37)
55 NAME_REF@[34; 37)
56 IDENT@[34; 37) "i32"
57 COMMA@[37; 38)
58 WHITESPACE@[38; 39)
59 R_PAREN@[39; 40)
60 WHITESPACE@[40; 41)
61 BLOCK@[41; 43)
62 L_CURLY@[41; 42)
63 R_CURLY@[42; 43)
64 WHITESPACE@[43; 44)
65 FN_DEF@[44; 66)
66 FN_KW@[44; 46)
67 WHITESPACE@[46; 47)
68 NAME@[47; 48)
69 IDENT@[47; 48) "d"
70 PARAM_LIST@[48; 63)
71 L_PAREN@[48; 49)
72 PARAM@[49; 55)
73 BIND_PAT@[49; 50)
74 NAME@[49; 50)
75 IDENT@[49; 50) "x"
76 COLON@[50; 51)
77 WHITESPACE@[51; 52)
78 PATH_TYPE@[52; 55)
79 PATH@[52; 55)
80 PATH_SEGMENT@[52; 55)
81 NAME_REF@[52; 55)
82 IDENT@[52; 55) "i32"
83 COMMA@[55; 56)
84 WHITESPACE@[56; 57)
85 PARAM@[57; 62)
86 BIND_PAT@[57; 58)
87 NAME@[57; 58)
88 IDENT@[57; 58) "y"
89 COLON@[58; 59)
90 WHITESPACE@[59; 60)
91 TUPLE_TYPE@[60; 62)
92 L_PAREN@[60; 61)
93 R_PAREN@[61; 62)
94 R_PAREN@[62; 63)
95 WHITESPACE@[63; 64)
96 BLOCK@[64; 66)
97 L_CURLY@[64; 65)
98 R_CURLY@[65; 66)
99 WHITESPACE@[66; 67)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs
new file mode 100644
index 000000000..4b0d9af89
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 if true {};
3 if true {} else {};
4 if true {} else if false {} else {};
5 if S {};
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt
new file mode 100644
index 000000000..ae1a8101e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt
@@ -0,0 +1,95 @@
1ROOT@[0; 107)
2 FN_DEF@[0; 106)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 106)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 26)
15 IF_EXPR@[15; 25)
16 IF_KW@[15; 17)
17 WHITESPACE@[17; 18)
18 CONDITION@[18; 22)
19 LITERAL@[18; 22)
20 TRUE_KW@[18; 22)
21 WHITESPACE@[22; 23)
22 BLOCK@[23; 25)
23 L_CURLY@[23; 24)
24 R_CURLY@[24; 25)
25 SEMI@[25; 26)
26 WHITESPACE@[26; 31)
27 EXPR_STMT@[31; 50)
28 IF_EXPR@[31; 49)
29 IF_KW@[31; 33)
30 WHITESPACE@[33; 34)
31 CONDITION@[34; 38)
32 LITERAL@[34; 38)
33 TRUE_KW@[34; 38)
34 WHITESPACE@[38; 39)
35 BLOCK@[39; 41)
36 L_CURLY@[39; 40)
37 R_CURLY@[40; 41)
38 WHITESPACE@[41; 42)
39 ELSE_KW@[42; 46)
40 WHITESPACE@[46; 47)
41 BLOCK@[47; 49)
42 L_CURLY@[47; 48)
43 R_CURLY@[48; 49)
44 SEMI@[49; 50)
45 WHITESPACE@[50; 55)
46 EXPR_STMT@[55; 91)
47 IF_EXPR@[55; 90)
48 IF_KW@[55; 57)
49 WHITESPACE@[57; 58)
50 CONDITION@[58; 62)
51 LITERAL@[58; 62)
52 TRUE_KW@[58; 62)
53 WHITESPACE@[62; 63)
54 BLOCK@[63; 65)
55 L_CURLY@[63; 64)
56 R_CURLY@[64; 65)
57 WHITESPACE@[65; 66)
58 ELSE_KW@[66; 70)
59 WHITESPACE@[70; 71)
60 IF_EXPR@[71; 90)
61 IF_KW@[71; 73)
62 WHITESPACE@[73; 74)
63 CONDITION@[74; 79)
64 LITERAL@[74; 79)
65 FALSE_KW@[74; 79)
66 WHITESPACE@[79; 80)
67 BLOCK@[80; 82)
68 L_CURLY@[80; 81)
69 R_CURLY@[81; 82)
70 WHITESPACE@[82; 83)
71 ELSE_KW@[83; 87)
72 WHITESPACE@[87; 88)
73 BLOCK@[88; 90)
74 L_CURLY@[88; 89)
75 R_CURLY@[89; 90)
76 SEMI@[90; 91)
77 WHITESPACE@[91; 96)
78 EXPR_STMT@[96; 104)
79 IF_EXPR@[96; 103)
80 IF_KW@[96; 98)
81 WHITESPACE@[98; 99)
82 CONDITION@[99; 100)
83 PATH_EXPR@[99; 100)
84 PATH@[99; 100)
85 PATH_SEGMENT@[99; 100)
86 NAME_REF@[99; 100)
87 IDENT@[99; 100) "S"
88 WHITESPACE@[100; 101)
89 BLOCK@[101; 103)
90 L_CURLY@[101; 102)
91 R_CURLY@[102; 103)
92 SEMI@[103; 104)
93 WHITESPACE@[104; 105)
94 R_CURLY@[105; 106)
95 WHITESPACE@[106; 107)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs
new file mode 100644
index 000000000..c20d29751
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 || ();
3 || -> i32 { 92 };
4 |x| x;
5 move |x: i32,| x;
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt
new file mode 100644
index 000000000..82aaf3897
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt
@@ -0,0 +1,95 @@
1ROOT@[0; 79)
2 FN_DEF@[0; 78)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 78)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 21)
15 LAMBDA_EXPR@[15; 20)
16 PARAM_LIST@[15; 17)
17 PIPE@[15; 16)
18 PIPE@[16; 17)
19 WHITESPACE@[17; 18)
20 TUPLE_EXPR@[18; 20)
21 L_PAREN@[18; 19)
22 R_PAREN@[19; 20)
23 SEMI@[20; 21)
24 WHITESPACE@[21; 26)
25 EXPR_STMT@[26; 43)
26 LAMBDA_EXPR@[26; 42)
27 PARAM_LIST@[26; 28)
28 PIPE@[26; 27)
29 PIPE@[27; 28)
30 WHITESPACE@[28; 29)
31 RET_TYPE@[29; 35)
32 THIN_ARROW@[29; 31)
33 WHITESPACE@[31; 32)
34 PATH_TYPE@[32; 35)
35 PATH@[32; 35)
36 PATH_SEGMENT@[32; 35)
37 NAME_REF@[32; 35)
38 IDENT@[32; 35) "i32"
39 WHITESPACE@[35; 36)
40 BLOCK_EXPR@[36; 42)
41 BLOCK@[36; 42)
42 L_CURLY@[36; 37)
43 WHITESPACE@[37; 38)
44 LITERAL@[38; 40)
45 INT_NUMBER@[38; 40) "92"
46 WHITESPACE@[40; 41)
47 R_CURLY@[41; 42)
48 SEMI@[42; 43)
49 WHITESPACE@[43; 48)
50 EXPR_STMT@[48; 54)
51 LAMBDA_EXPR@[48; 53)
52 PARAM_LIST@[48; 51)
53 PIPE@[48; 49)
54 PARAM@[49; 50)
55 BIND_PAT@[49; 50)
56 NAME@[49; 50)
57 IDENT@[49; 50) "x"
58 PIPE@[50; 51)
59 WHITESPACE@[51; 52)
60 PATH_EXPR@[52; 53)
61 PATH@[52; 53)
62 PATH_SEGMENT@[52; 53)
63 NAME_REF@[52; 53)
64 IDENT@[52; 53) "x"
65 SEMI@[53; 54)
66 WHITESPACE@[54; 59)
67 EXPR_STMT@[59; 76)
68 LAMBDA_EXPR@[59; 75)
69 MOVE_KW@[59; 63)
70 WHITESPACE@[63; 64)
71 PARAM_LIST@[64; 73)
72 PIPE@[64; 65)
73 PARAM@[65; 71)
74 BIND_PAT@[65; 66)
75 NAME@[65; 66)
76 IDENT@[65; 66) "x"
77 COLON@[66; 67)
78 WHITESPACE@[67; 68)
79 PATH_TYPE@[68; 71)
80 PATH@[68; 71)
81 PATH_SEGMENT@[68; 71)
82 NAME_REF@[68; 71)
83 IDENT@[68; 71) "i32"
84 COMMA@[71; 72)
85 PIPE@[72; 73)
86 WHITESPACE@[73; 74)
87 PATH_EXPR@[74; 75)
88 PATH@[74; 75)
89 PATH_SEGMENT@[74; 75)
90 NAME_REF@[74; 75)
91 IDENT@[74; 75) "x"
92 SEMI@[75; 76)
93 WHITESPACE@[76; 77)
94 R_CURLY@[77; 78)
95 WHITESPACE@[78; 79)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs
new file mode 100644
index 000000000..2fed74c5e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 {};
3 unsafe {};
4 'label: {};
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt
new file mode 100644
index 000000000..12a1ff49a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt
@@ -0,0 +1,42 @@
1ROOT@[0; 52)
2 FN_DEF@[0; 51)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 51)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 18)
15 BLOCK_EXPR@[15; 17)
16 BLOCK@[15; 17)
17 L_CURLY@[15; 16)
18 R_CURLY@[16; 17)
19 SEMI@[17; 18)
20 WHITESPACE@[18; 23)
21 EXPR_STMT@[23; 33)
22 BLOCK_EXPR@[23; 32)
23 UNSAFE_KW@[23; 29)
24 WHITESPACE@[29; 30)
25 BLOCK@[30; 32)
26 L_CURLY@[30; 31)
27 R_CURLY@[31; 32)
28 SEMI@[32; 33)
29 WHITESPACE@[33; 38)
30 EXPR_STMT@[38; 49)
31 BLOCK_EXPR@[38; 48)
32 LABEL@[38; 45)
33 LIFETIME@[38; 44) "'label"
34 COLON@[44; 45)
35 WHITESPACE@[45; 46)
36 BLOCK@[46; 48)
37 L_CURLY@[46; 47)
38 R_CURLY@[47; 48)
39 SEMI@[48; 49)
40 WHITESPACE@[49; 50)
41 R_CURLY@[50; 51)
42 WHITESPACE@[51; 52)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs
new file mode 100644
index 000000000..d9d99d2d3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs
@@ -0,0 +1 @@
fn foo() { pub 92; } //FIXME
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt
new file mode 100644
index 000000000..5f179c3ca
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt
@@ -0,0 +1,25 @@
1ROOT@[0; 29)
2 FN_DEF@[0; 20)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 20)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 EXPR_STMT@[11; 18)
15 VISIBILITY@[11; 14)
16 PUB_KW@[11; 14)
17 WHITESPACE@[14; 15)
18 LITERAL@[15; 17)
19 INT_NUMBER@[15; 17) "92"
20 SEMI@[17; 18)
21 WHITESPACE@[18; 19)
22 R_CURLY@[19; 20)
23 WHITESPACE@[20; 21)
24 COMMENT@[21; 28)
25 WHITESPACE@[28; 29)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs
new file mode 100644
index 000000000..5733666b6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 return;
3 return 92;
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt
new file mode 100644
index 000000000..ead1ada96
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt
@@ -0,0 +1,28 @@
1ROOT@[0; 40)
2 FN_DEF@[0; 39)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 39)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 22)
15 RETURN_EXPR@[15; 21)
16 RETURN_KW@[15; 21)
17 SEMI@[21; 22)
18 WHITESPACE@[22; 27)
19 EXPR_STMT@[27; 37)
20 RETURN_EXPR@[27; 36)
21 RETURN_KW@[27; 33)
22 WHITESPACE@[33; 34)
23 LITERAL@[34; 36)
24 INT_NUMBER@[34; 36) "92"
25 SEMI@[36; 37)
26 WHITESPACE@[37; 38)
27 R_CURLY@[38; 39)
28 WHITESPACE@[39; 40)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs
new file mode 100644
index 000000000..2c0e88414
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 match () {
3 _ => (),
4 X | Y if Z => (),
5 };
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt
new file mode 100644
index 000000000..013d1716a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt
@@ -0,0 +1,66 @@
1ROOT@[0; 78)
2 FN_DEF@[0; 77)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 77)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 75)
15 MATCH_EXPR@[15; 74)
16 MATCH_KW@[15; 20)
17 WHITESPACE@[20; 21)
18 TUPLE_EXPR@[21; 23)
19 L_PAREN@[21; 22)
20 R_PAREN@[22; 23)
21 WHITESPACE@[23; 24)
22 MATCH_ARM_LIST@[24; 74)
23 L_CURLY@[24; 25)
24 WHITESPACE@[25; 34)
25 MATCH_ARM@[34; 41)
26 PLACEHOLDER_PAT@[34; 35)
27 UNDERSCORE@[34; 35)
28 WHITESPACE@[35; 36)
29 FAT_ARROW@[36; 38)
30 WHITESPACE@[38; 39)
31 TUPLE_EXPR@[39; 41)
32 L_PAREN@[39; 40)
33 R_PAREN@[40; 41)
34 COMMA@[41; 42)
35 WHITESPACE@[42; 51)
36 MATCH_ARM@[51; 67)
37 BIND_PAT@[51; 52)
38 NAME@[51; 52)
39 IDENT@[51; 52) "X"
40 WHITESPACE@[52; 53)
41 PIPE@[53; 54)
42 WHITESPACE@[54; 55)
43 BIND_PAT@[55; 56)
44 NAME@[55; 56)
45 IDENT@[55; 56) "Y"
46 WHITESPACE@[56; 57)
47 IF_KW@[57; 59)
48 WHITESPACE@[59; 60)
49 PATH_EXPR@[60; 61)
50 PATH@[60; 61)
51 PATH_SEGMENT@[60; 61)
52 NAME_REF@[60; 61)
53 IDENT@[60; 61) "Z"
54 WHITESPACE@[61; 62)
55 FAT_ARROW@[62; 64)
56 WHITESPACE@[64; 65)
57 TUPLE_EXPR@[65; 67)
58 L_PAREN@[65; 66)
59 R_PAREN@[66; 67)
60 COMMA@[67; 68)
61 WHITESPACE@[68; 73)
62 R_CURLY@[73; 74)
63 SEMI@[74; 75)
64 WHITESPACE@[75; 76)
65 R_CURLY@[76; 77)
66 WHITESPACE@[77; 78)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs
new file mode 100644
index 000000000..c9205dfa3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 match () { };
3 match S {};
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt
new file mode 100644
index 000000000..d7740e3cc
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt
@@ -0,0 +1,44 @@
1ROOT@[0; 47)
2 FN_DEF@[0; 46)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 46)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 28)
15 MATCH_EXPR@[15; 27)
16 MATCH_KW@[15; 20)
17 WHITESPACE@[20; 21)
18 TUPLE_EXPR@[21; 23)
19 L_PAREN@[21; 22)
20 R_PAREN@[22; 23)
21 WHITESPACE@[23; 24)
22 MATCH_ARM_LIST@[24; 27)
23 L_CURLY@[24; 25)
24 WHITESPACE@[25; 26)
25 R_CURLY@[26; 27)
26 SEMI@[27; 28)
27 WHITESPACE@[28; 33)
28 EXPR_STMT@[33; 44)
29 MATCH_EXPR@[33; 43)
30 MATCH_KW@[33; 38)
31 WHITESPACE@[38; 39)
32 PATH_EXPR@[39; 40)
33 PATH@[39; 40)
34 PATH_SEGMENT@[39; 40)
35 NAME_REF@[39; 40)
36 IDENT@[39; 40) "S"
37 WHITESPACE@[40; 41)
38 MATCH_ARM_LIST@[41; 43)
39 L_CURLY@[41; 42)
40 R_CURLY@[42; 43)
41 SEMI@[43; 44)
42 WHITESPACE@[44; 45)
43 R_CURLY@[45; 46)
44 WHITESPACE@[46; 47)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs
new file mode 100644
index 000000000..0dfe63629
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let S() = ();
3 let S(_) = ();
4 let S(_,) = ();
5 let S(_, .. , x) = ();
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt
new file mode 100644
index 000000000..734e0726c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt
@@ -0,0 +1,103 @@
1ROOT@[0; 97)
2 FN_DEF@[0; 96)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 96)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 28)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 TUPLE_STRUCT_PAT@[19; 22)
18 PATH@[19; 20)
19 PATH_SEGMENT@[19; 20)
20 NAME_REF@[19; 20)
21 IDENT@[19; 20) "S"
22 L_PAREN@[20; 21)
23 R_PAREN@[21; 22)
24 WHITESPACE@[22; 23)
25 EQ@[23; 24)
26 WHITESPACE@[24; 25)
27 TUPLE_EXPR@[25; 27)
28 L_PAREN@[25; 26)
29 R_PAREN@[26; 27)
30 SEMI@[27; 28)
31 WHITESPACE@[28; 33)
32 LET_STMT@[33; 47)
33 LET_KW@[33; 36)
34 WHITESPACE@[36; 37)
35 TUPLE_STRUCT_PAT@[37; 41)
36 PATH@[37; 38)
37 PATH_SEGMENT@[37; 38)
38 NAME_REF@[37; 38)
39 IDENT@[37; 38) "S"
40 L_PAREN@[38; 39)
41 PLACEHOLDER_PAT@[39; 40)
42 UNDERSCORE@[39; 40)
43 R_PAREN@[40; 41)
44 WHITESPACE@[41; 42)
45 EQ@[42; 43)
46 WHITESPACE@[43; 44)
47 TUPLE_EXPR@[44; 46)
48 L_PAREN@[44; 45)
49 R_PAREN@[45; 46)
50 SEMI@[46; 47)
51 WHITESPACE@[47; 52)
52 LET_STMT@[52; 67)
53 LET_KW@[52; 55)
54 WHITESPACE@[55; 56)
55 TUPLE_STRUCT_PAT@[56; 61)
56 PATH@[56; 57)
57 PATH_SEGMENT@[56; 57)
58 NAME_REF@[56; 57)
59 IDENT@[56; 57) "S"
60 L_PAREN@[57; 58)
61 PLACEHOLDER_PAT@[58; 59)
62 UNDERSCORE@[58; 59)
63 COMMA@[59; 60)
64 R_PAREN@[60; 61)
65 WHITESPACE@[61; 62)
66 EQ@[62; 63)
67 WHITESPACE@[63; 64)
68 TUPLE_EXPR@[64; 66)
69 L_PAREN@[64; 65)
70 R_PAREN@[65; 66)
71 SEMI@[66; 67)
72 WHITESPACE@[67; 72)
73 LET_STMT@[72; 94)
74 LET_KW@[72; 75)
75 WHITESPACE@[75; 76)
76 TUPLE_STRUCT_PAT@[76; 88)
77 PATH@[76; 77)
78 PATH_SEGMENT@[76; 77)
79 NAME_REF@[76; 77)
80 IDENT@[76; 77) "S"
81 L_PAREN@[77; 78)
82 PLACEHOLDER_PAT@[78; 79)
83 UNDERSCORE@[78; 79)
84 COMMA@[79; 80)
85 WHITESPACE@[80; 81)
86 DOTDOT@[81; 83)
87 WHITESPACE@[83; 84)
88 COMMA@[84; 85)
89 WHITESPACE@[85; 86)
90 BIND_PAT@[86; 87)
91 NAME@[86; 87)
92 IDENT@[86; 87) "x"
93 R_PAREN@[87; 88)
94 WHITESPACE@[88; 89)
95 EQ@[89; 90)
96 WHITESPACE@[90; 91)
97 TUPLE_EXPR@[91; 93)
98 L_PAREN@[91; 92)
99 R_PAREN@[92; 93)
100 SEMI@[93; 94)
101 WHITESPACE@[94; 95)
102 R_CURLY@[95; 96)
103 WHITESPACE@[96; 97)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs
new file mode 100644
index 000000000..f6e32c7c1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 let foo::Bar = ();
3 let ::Bar = ();
4 let Bar { .. } = ();
5 let Bar(..) = ();
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt
new file mode 100644
index 000000000..1a8d1546d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt
@@ -0,0 +1,95 @@
1ROOT@[0; 103)
2 FN_DEF@[0; 102)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 102)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 33)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 PATH_PAT@[19; 27)
18 PATH@[19; 27)
19 PATH@[19; 22)
20 PATH_SEGMENT@[19; 22)
21 NAME_REF@[19; 22)
22 IDENT@[19; 22) "foo"
23 COLONCOLON@[22; 24)
24 PATH_SEGMENT@[24; 27)
25 NAME_REF@[24; 27)
26 IDENT@[24; 27) "Bar"
27 WHITESPACE@[27; 28)
28 EQ@[28; 29)
29 WHITESPACE@[29; 30)
30 TUPLE_EXPR@[30; 32)
31 L_PAREN@[30; 31)
32 R_PAREN@[31; 32)
33 SEMI@[32; 33)
34 WHITESPACE@[33; 38)
35 LET_STMT@[38; 53)
36 LET_KW@[38; 41)
37 WHITESPACE@[41; 42)
38 PATH_PAT@[42; 47)
39 PATH@[42; 47)
40 PATH_SEGMENT@[42; 47)
41 COLONCOLON@[42; 44)
42 NAME_REF@[44; 47)
43 IDENT@[44; 47) "Bar"
44 WHITESPACE@[47; 48)
45 EQ@[48; 49)
46 WHITESPACE@[49; 50)
47 TUPLE_EXPR@[50; 52)
48 L_PAREN@[50; 51)
49 R_PAREN@[51; 52)
50 SEMI@[52; 53)
51 WHITESPACE@[53; 58)
52 LET_STMT@[58; 78)
53 LET_KW@[58; 61)
54 WHITESPACE@[61; 62)
55 STRUCT_PAT@[62; 72)
56 PATH@[62; 65)
57 PATH_SEGMENT@[62; 65)
58 NAME_REF@[62; 65)
59 IDENT@[62; 65) "Bar"
60 WHITESPACE@[65; 66)
61 FIELD_PAT_LIST@[66; 72)
62 L_CURLY@[66; 67)
63 WHITESPACE@[67; 68)
64 DOTDOT@[68; 70)
65 WHITESPACE@[70; 71)
66 R_CURLY@[71; 72)
67 WHITESPACE@[72; 73)
68 EQ@[73; 74)
69 WHITESPACE@[74; 75)
70 TUPLE_EXPR@[75; 77)
71 L_PAREN@[75; 76)
72 R_PAREN@[76; 77)
73 SEMI@[77; 78)
74 WHITESPACE@[78; 83)
75 LET_STMT@[83; 100)
76 LET_KW@[83; 86)
77 WHITESPACE@[86; 87)
78 TUPLE_STRUCT_PAT@[87; 94)
79 PATH@[87; 90)
80 PATH_SEGMENT@[87; 90)
81 NAME_REF@[87; 90)
82 IDENT@[87; 90) "Bar"
83 L_PAREN@[90; 91)
84 DOTDOT@[91; 93)
85 R_PAREN@[93; 94)
86 WHITESPACE@[94; 95)
87 EQ@[95; 96)
88 WHITESPACE@[96; 97)
89 TUPLE_EXPR@[97; 99)
90 L_PAREN@[97; 98)
91 R_PAREN@[98; 99)
92 SEMI@[99; 100)
93 WHITESPACE@[100; 101)
94 R_CURLY@[101; 102)
95 WHITESPACE@[102; 103)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs
new file mode 100644
index 000000000..f10851487
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs
@@ -0,0 +1,6 @@
1impl F {
2 type A = i32;
3 const B: i32 = 92;
4 fn foo() {}
5 fn bar(&self) {}
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt
new file mode 100644
index 000000000..1f524f34a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt
@@ -0,0 +1,78 @@
1ROOT@[0; 89)
2 IMPL_ITEM@[0; 88)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6)
6 PATH@[5; 6)
7 PATH_SEGMENT@[5; 6)
8 NAME_REF@[5; 6)
9 IDENT@[5; 6) "F"
10 WHITESPACE@[6; 7)
11 ITEM_LIST@[7; 88)
12 L_CURLY@[7; 8)
13 WHITESPACE@[8; 13)
14 TYPE_DEF@[13; 26)
15 TYPE_KW@[13; 17)
16 WHITESPACE@[17; 18)
17 NAME@[18; 19)
18 IDENT@[18; 19) "A"
19 WHITESPACE@[19; 20)
20 EQ@[20; 21)
21 WHITESPACE@[21; 22)
22 PATH_TYPE@[22; 25)
23 PATH@[22; 25)
24 PATH_SEGMENT@[22; 25)
25 NAME_REF@[22; 25)
26 IDENT@[22; 25) "i32"
27 SEMI@[25; 26)
28 WHITESPACE@[26; 31)
29 CONST_DEF@[31; 49)
30 CONST_KW@[31; 36)
31 WHITESPACE@[36; 37)
32 NAME@[37; 38)
33 IDENT@[37; 38) "B"
34 COLON@[38; 39)
35 WHITESPACE@[39; 40)
36 PATH_TYPE@[40; 43)
37 PATH@[40; 43)
38 PATH_SEGMENT@[40; 43)
39 NAME_REF@[40; 43)
40 IDENT@[40; 43) "i32"
41 WHITESPACE@[43; 44)
42 EQ@[44; 45)
43 WHITESPACE@[45; 46)
44 LITERAL@[46; 48)
45 INT_NUMBER@[46; 48) "92"
46 SEMI@[48; 49)
47 WHITESPACE@[49; 54)
48 FN_DEF@[54; 65)
49 FN_KW@[54; 56)
50 WHITESPACE@[56; 57)
51 NAME@[57; 60)
52 IDENT@[57; 60) "foo"
53 PARAM_LIST@[60; 62)
54 L_PAREN@[60; 61)
55 R_PAREN@[61; 62)
56 WHITESPACE@[62; 63)
57 BLOCK@[63; 65)
58 L_CURLY@[63; 64)
59 R_CURLY@[64; 65)
60 WHITESPACE@[65; 70)
61 FN_DEF@[70; 86)
62 FN_KW@[70; 72)
63 WHITESPACE@[72; 73)
64 NAME@[73; 76)
65 IDENT@[73; 76) "bar"
66 PARAM_LIST@[76; 83)
67 L_PAREN@[76; 77)
68 SELF_PARAM@[77; 82)
69 AMP@[77; 78)
70 SELF_KW@[78; 82)
71 R_PAREN@[82; 83)
72 WHITESPACE@[83; 84)
73 BLOCK@[84; 86)
74 L_CURLY@[84; 85)
75 R_CURLY@[85; 86)
76 WHITESPACE@[86; 87)
77 R_CURLY@[87; 88)
78 WHITESPACE@[88; 89)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs
new file mode 100644
index 000000000..f1c3f7118
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 **&1;
3 !!true;
4 --1;
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt
new file mode 100644
index 000000000..4d77c8c11
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt
@@ -0,0 +1,44 @@
1ROOT@[0; 44)
2 FN_DEF@[0; 43)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 43)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 20)
15 PREFIX_EXPR@[15; 19)
16 STAR@[15; 16)
17 PREFIX_EXPR@[16; 19)
18 STAR@[16; 17)
19 REF_EXPR@[17; 19)
20 AMP@[17; 18)
21 LITERAL@[18; 19)
22 INT_NUMBER@[18; 19) "1"
23 SEMI@[19; 20)
24 WHITESPACE@[20; 25)
25 EXPR_STMT@[25; 32)
26 PREFIX_EXPR@[25; 31)
27 EXCL@[25; 26)
28 PREFIX_EXPR@[26; 31)
29 EXCL@[26; 27)
30 LITERAL@[27; 31)
31 TRUE_KW@[27; 31)
32 SEMI@[31; 32)
33 WHITESPACE@[32; 37)
34 EXPR_STMT@[37; 41)
35 PREFIX_EXPR@[37; 40)
36 MINUS@[37; 38)
37 PREFIX_EXPR@[38; 40)
38 MINUS@[38; 39)
39 LITERAL@[39; 40)
40 INT_NUMBER@[39; 40) "1"
41 SEMI@[40; 41)
42 WHITESPACE@[41; 42)
43 R_CURLY@[42; 43)
44 WHITESPACE@[43; 44)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs
new file mode 100644
index 000000000..8b74f7bc8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 x?;
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt
new file mode 100644
index 000000000..b80235146
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt
@@ -0,0 +1,25 @@
1ROOT@[0; 21)
2 FN_DEF@[0; 20)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 20)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 18)
15 TRY_EXPR@[15; 17)
16 PATH_EXPR@[15; 16)
17 PATH@[15; 16)
18 PATH_SEGMENT@[15; 16)
19 NAME_REF@[15; 16)
20 IDENT@[15; 16) "x"
21 QUESTION@[16; 17)
22 SEMI@[17; 18)
23 WHITESPACE@[18; 19)
24 R_CURLY@[19; 20)
25 WHITESPACE@[20; 21)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0076_cond.rs b/crates/ra_syntax/tests/data/parser/inline/0076_cond.rs
new file mode 100644
index 000000000..fdb37ee6f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0076_cond.rs
@@ -0,0 +1 @@
fn foo() { if let Some(_) = None {} }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0076_cond.txt b/crates/ra_syntax/tests/data/parser/inline/0076_cond.txt
new file mode 100644
index 000000000..1808f10fb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0076_cond.txt
@@ -0,0 +1,43 @@
1ROOT@[0; 38)
2 FN_DEF@[0; 37)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 37)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 IF_EXPR@[11; 35)
15 IF_KW@[11; 13)
16 WHITESPACE@[13; 14)
17 CONDITION@[14; 32)
18 LET_KW@[14; 17)
19 WHITESPACE@[17; 18)
20 TUPLE_STRUCT_PAT@[18; 25)
21 PATH@[18; 22)
22 PATH_SEGMENT@[18; 22)
23 NAME_REF@[18; 22)
24 IDENT@[18; 22) "Some"
25 L_PAREN@[22; 23)
26 PLACEHOLDER_PAT@[23; 24)
27 UNDERSCORE@[23; 24)
28 R_PAREN@[24; 25)
29 WHITESPACE@[25; 26)
30 EQ@[26; 27)
31 WHITESPACE@[27; 28)
32 PATH_EXPR@[28; 32)
33 PATH@[28; 32)
34 PATH_SEGMENT@[28; 32)
35 NAME_REF@[28; 32)
36 IDENT@[28; 32) "None"
37 WHITESPACE@[32; 33)
38 BLOCK@[33; 35)
39 L_CURLY@[33; 34)
40 R_CURLY@[34; 35)
41 WHITESPACE@[35; 36)
42 R_CURLY@[36; 37)
43 WHITESPACE@[37; 38)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs
new file mode 100644
index 000000000..293046a04
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 while true {};
3 while let Some(x) = it.next() {};
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt
new file mode 100644
index 000000000..c73157c04
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt
@@ -0,0 +1,66 @@
1ROOT@[0; 70)
2 FN_DEF@[0; 69)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 69)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 29)
15 WHILE_EXPR@[15; 28)
16 WHILE_KW@[15; 20)
17 WHITESPACE@[20; 21)
18 CONDITION@[21; 25)
19 LITERAL@[21; 25)
20 TRUE_KW@[21; 25)
21 WHITESPACE@[25; 26)
22 BLOCK@[26; 28)
23 L_CURLY@[26; 27)
24 R_CURLY@[27; 28)
25 SEMI@[28; 29)
26 WHITESPACE@[29; 34)
27 EXPR_STMT@[34; 67)
28 WHILE_EXPR@[34; 66)
29 WHILE_KW@[34; 39)
30 WHITESPACE@[39; 40)
31 CONDITION@[40; 63)
32 LET_KW@[40; 43)
33 WHITESPACE@[43; 44)
34 TUPLE_STRUCT_PAT@[44; 51)
35 PATH@[44; 48)
36 PATH_SEGMENT@[44; 48)
37 NAME_REF@[44; 48)
38 IDENT@[44; 48) "Some"
39 L_PAREN@[48; 49)
40 BIND_PAT@[49; 50)
41 NAME@[49; 50)
42 IDENT@[49; 50) "x"
43 R_PAREN@[50; 51)
44 WHITESPACE@[51; 52)
45 EQ@[52; 53)
46 WHITESPACE@[53; 54)
47 METHOD_CALL_EXPR@[54; 63)
48 PATH_EXPR@[54; 56)
49 PATH@[54; 56)
50 PATH_SEGMENT@[54; 56)
51 NAME_REF@[54; 56)
52 IDENT@[54; 56) "it"
53 DOT@[56; 57)
54 NAME_REF@[57; 61)
55 IDENT@[57; 61) "next"
56 ARG_LIST@[61; 63)
57 L_PAREN@[61; 62)
58 R_PAREN@[62; 63)
59 WHITESPACE@[63; 64)
60 BLOCK@[64; 66)
61 L_CURLY@[64; 65)
62 R_CURLY@[65; 66)
63 SEMI@[66; 67)
64 WHITESPACE@[67; 68)
65 R_CURLY@[68; 69)
66 WHITESPACE@[69; 70)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs
new file mode 100644
index 000000000..24a15c5c5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs
@@ -0,0 +1,5 @@
1fn foo() {}
2macro_rules! foo {}
3foo::bar!();
4super::baz! {}
5struct S;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt
new file mode 100644
index 000000000..57b2b9372
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt
@@ -0,0 +1,65 @@
1ROOT@[0; 70)
2 FN_DEF@[0; 11)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 11)
12 L_CURLY@[9; 10)
13 R_CURLY@[10; 11)
14 WHITESPACE@[11; 12)
15 MACRO_CALL@[12; 31)
16 PATH@[12; 23)
17 PATH_SEGMENT@[12; 23)
18 NAME_REF@[12; 23)
19 IDENT@[12; 23) "macro_rules"
20 EXCL@[23; 24)
21 WHITESPACE@[24; 25)
22 IDENT@[25; 28) "foo"
23 WHITESPACE@[28; 29)
24 TOKEN_TREE@[29; 31)
25 L_CURLY@[29; 30)
26 R_CURLY@[30; 31)
27 WHITESPACE@[31; 32)
28 MACRO_CALL@[32; 44)
29 PATH@[32; 40)
30 PATH@[32; 35)
31 PATH_SEGMENT@[32; 35)
32 NAME_REF@[32; 35)
33 IDENT@[32; 35) "foo"
34 COLONCOLON@[35; 37)
35 PATH_SEGMENT@[37; 40)
36 NAME_REF@[37; 40)
37 IDENT@[37; 40) "bar"
38 EXCL@[40; 41)
39 TOKEN_TREE@[41; 43)
40 L_PAREN@[41; 42)
41 R_PAREN@[42; 43)
42 SEMI@[43; 44)
43 WHITESPACE@[44; 45)
44 MACRO_CALL@[45; 59)
45 PATH@[45; 55)
46 PATH@[45; 50)
47 PATH_SEGMENT@[45; 50)
48 SUPER_KW@[45; 50)
49 COLONCOLON@[50; 52)
50 PATH_SEGMENT@[52; 55)
51 NAME_REF@[52; 55)
52 IDENT@[52; 55) "baz"
53 EXCL@[55; 56)
54 WHITESPACE@[56; 57)
55 TOKEN_TREE@[57; 59)
56 L_CURLY@[57; 58)
57 R_CURLY@[58; 59)
58 WHITESPACE@[59; 60)
59 STRUCT_DEF@[60; 69)
60 STRUCT_KW@[60; 66)
61 WHITESPACE@[66; 67)
62 NAME@[67; 68)
63 IDENT@[67; 68) "S"
64 SEMI@[68; 69)
65 WHITESPACE@[69; 70)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs
new file mode 100644
index 000000000..3e53d56d6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 82 as i32;
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt
new file mode 100644
index 000000000..6d57078b3
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt
@@ -0,0 +1,29 @@
1ROOT@[0; 28)
2 FN_DEF@[0; 27)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 27)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 25)
15 CAST_EXPR@[15; 24)
16 LITERAL@[15; 17)
17 INT_NUMBER@[15; 17) "82"
18 WHITESPACE@[17; 18)
19 AS_KW@[18; 20)
20 WHITESPACE@[20; 21)
21 PATH_TYPE@[21; 24)
22 PATH@[21; 24)
23 PATH_SEGMENT@[21; 24)
24 NAME_REF@[21; 24)
25 IDENT@[21; 24) "i32"
26 SEMI@[24; 25)
27 WHITESPACE@[25; 26)
28 R_CURLY@[26; 27)
29 WHITESPACE@[27; 28)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs
new file mode 100644
index 000000000..e4f774280
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 ();
3 (1);
4 (1,);
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt
new file mode 100644
index 000000000..cf541411f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt
@@ -0,0 +1,38 @@
1ROOT@[0; 40)
2 FN_DEF@[0; 39)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 39)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 18)
15 TUPLE_EXPR@[15; 17)
16 L_PAREN@[15; 16)
17 R_PAREN@[16; 17)
18 SEMI@[17; 18)
19 WHITESPACE@[18; 23)
20 EXPR_STMT@[23; 27)
21 PAREN_EXPR@[23; 26)
22 L_PAREN@[23; 24)
23 LITERAL@[24; 25)
24 INT_NUMBER@[24; 25) "1"
25 R_PAREN@[25; 26)
26 SEMI@[26; 27)
27 WHITESPACE@[27; 32)
28 EXPR_STMT@[32; 37)
29 TUPLE_EXPR@[32; 36)
30 L_PAREN@[32; 33)
31 LITERAL@[33; 34)
32 INT_NUMBER@[33; 34) "1"
33 COMMA@[34; 35)
34 R_PAREN@[35; 36)
35 SEMI@[36; 37)
36 WHITESPACE@[37; 38)
37 R_CURLY@[38; 39)
38 WHITESPACE@[39; 40)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs
new file mode 100644
index 000000000..b9ba78a6c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 x[1][2];
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt
new file mode 100644
index 000000000..4624aab23
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt
@@ -0,0 +1,33 @@
1ROOT@[0; 26)
2 FN_DEF@[0; 25)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 25)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 23)
15 INDEX_EXPR@[15; 22)
16 INDEX_EXPR@[15; 19)
17 PATH_EXPR@[15; 16)
18 PATH@[15; 16)
19 PATH_SEGMENT@[15; 16)
20 NAME_REF@[15; 16)
21 IDENT@[15; 16) "x"
22 L_BRACK@[16; 17)
23 LITERAL@[17; 18)
24 INT_NUMBER@[17; 18) "1"
25 R_BRACK@[18; 19)
26 L_BRACK@[19; 20)
27 LITERAL@[20; 21)
28 INT_NUMBER@[20; 21) "2"
29 R_BRACK@[21; 22)
30 SEMI@[22; 23)
31 WHITESPACE@[23; 24)
32 R_CURLY@[24; 25)
33 WHITESPACE@[25; 26)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs
new file mode 100644
index 000000000..f785acd36
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs
@@ -0,0 +1,3 @@
1fn main() {
2 let (a, b, ..) = ();
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt
new file mode 100644
index 000000000..2d68a5ff2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt
@@ -0,0 +1,40 @@
1ROOT@[0; 39)
2 FN_DEF@[0; 38)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 38)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 LET_STMT@[16; 36)
15 LET_KW@[16; 19)
16 WHITESPACE@[19; 20)
17 TUPLE_PAT@[20; 30)
18 L_PAREN@[20; 21)
19 BIND_PAT@[21; 22)
20 NAME@[21; 22)
21 IDENT@[21; 22) "a"
22 COMMA@[22; 23)
23 WHITESPACE@[23; 24)
24 BIND_PAT@[24; 25)
25 NAME@[24; 25)
26 IDENT@[24; 25) "b"
27 COMMA@[25; 26)
28 WHITESPACE@[26; 27)
29 DOTDOT@[27; 29)
30 R_PAREN@[29; 30)
31 WHITESPACE@[30; 31)
32 EQ@[31; 32)
33 WHITESPACE@[32; 33)
34 TUPLE_EXPR@[33; 35)
35 L_PAREN@[33; 34)
36 R_PAREN@[34; 35)
37 SEMI@[35; 36)
38 WHITESPACE@[36; 37)
39 R_CURLY@[37; 38)
40 WHITESPACE@[38; 39)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs
new file mode 100644
index 000000000..c39fe8e68
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs
@@ -0,0 +1 @@
fn foo() { let x = 1..; }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt
new file mode 100644
index 000000000..475251ea7
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt
@@ -0,0 +1,30 @@
1ROOT@[0; 26)
2 FN_DEF@[0; 25)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 25)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 LET_STMT@[11; 23)
15 LET_KW@[11; 14)
16 WHITESPACE@[14; 15)
17 BIND_PAT@[15; 16)
18 NAME@[15; 16)
19 IDENT@[15; 16) "x"
20 WHITESPACE@[16; 17)
21 EQ@[17; 18)
22 WHITESPACE@[18; 19)
23 RANGE_EXPR@[19; 22)
24 LITERAL@[19; 20)
25 INT_NUMBER@[19; 20) "1"
26 DOTDOT@[20; 22)
27 SEMI@[22; 23)
28 WHITESPACE@[23; 24)
29 R_CURLY@[24; 25)
30 WHITESPACE@[25; 26)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs
new file mode 100644
index 000000000..9f078fa48
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 loop {};
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt
new file mode 100644
index 000000000..5321fade9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt
@@ -0,0 +1,24 @@
1ROOT@[0; 26)
2 FN_DEF@[0; 25)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 25)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 23)
15 LOOP_EXPR@[15; 22)
16 LOOP_KW@[15; 19)
17 WHITESPACE@[19; 20)
18 BLOCK@[20; 22)
19 L_CURLY@[20; 21)
20 R_CURLY@[21; 22)
21 SEMI@[22; 23)
22 WHITESPACE@[23; 24)
23 R_CURLY@[24; 25)
24 WHITESPACE@[25; 26)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs
new file mode 100644
index 000000000..972197d2a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 for x in [] {};
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt
new file mode 100644
index 000000000..7ddf8122f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt
@@ -0,0 +1,34 @@
1ROOT@[0; 33)
2 FN_DEF@[0; 32)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 32)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 30)
15 FOR_EXPR@[15; 29)
16 FOR_KW@[15; 18)
17 WHITESPACE@[18; 19)
18 BIND_PAT@[19; 20)
19 NAME@[19; 20)
20 IDENT@[19; 20) "x"
21 WHITESPACE@[20; 21)
22 IN_KW@[21; 23)
23 WHITESPACE@[23; 24)
24 ARRAY_EXPR@[24; 26)
25 L_BRACK@[24; 25)
26 R_BRACK@[25; 26)
27 WHITESPACE@[26; 27)
28 BLOCK@[27; 29)
29 L_CURLY@[27; 28)
30 R_CURLY@[28; 29)
31 SEMI@[29; 30)
32 WHITESPACE@[30; 31)
33 R_CURLY@[31; 32)
34 WHITESPACE@[32; 33)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs
new file mode 100644
index 000000000..1f25d577a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs
@@ -0,0 +1,7 @@
1fn foo() {
2 match () {
3 _ => (),
4 _ => {}
5 _ => ()
6 }
7}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt
new file mode 100644
index 000000000..560931645
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt
@@ -0,0 +1,59 @@
1ROOT@[0; 83)
2 FN_DEF@[0; 82)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 82)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 MATCH_EXPR@[15; 80)
15 MATCH_KW@[15; 20)
16 WHITESPACE@[20; 21)
17 TUPLE_EXPR@[21; 23)
18 L_PAREN@[21; 22)
19 R_PAREN@[22; 23)
20 WHITESPACE@[23; 24)
21 MATCH_ARM_LIST@[24; 80)
22 L_CURLY@[24; 25)
23 WHITESPACE@[25; 34)
24 MATCH_ARM@[34; 41)
25 PLACEHOLDER_PAT@[34; 35)
26 UNDERSCORE@[34; 35)
27 WHITESPACE@[35; 36)
28 FAT_ARROW@[36; 38)
29 WHITESPACE@[38; 39)
30 TUPLE_EXPR@[39; 41)
31 L_PAREN@[39; 40)
32 R_PAREN@[40; 41)
33 COMMA@[41; 42)
34 WHITESPACE@[42; 51)
35 MATCH_ARM@[51; 58)
36 PLACEHOLDER_PAT@[51; 52)
37 UNDERSCORE@[51; 52)
38 WHITESPACE@[52; 53)
39 FAT_ARROW@[53; 55)
40 WHITESPACE@[55; 56)
41 BLOCK_EXPR@[56; 58)
42 BLOCK@[56; 58)
43 L_CURLY@[56; 57)
44 R_CURLY@[57; 58)
45 WHITESPACE@[58; 67)
46 MATCH_ARM@[67; 74)
47 PLACEHOLDER_PAT@[67; 68)
48 UNDERSCORE@[67; 68)
49 WHITESPACE@[68; 69)
50 FAT_ARROW@[69; 71)
51 WHITESPACE@[71; 72)
52 TUPLE_EXPR@[72; 74)
53 L_PAREN@[72; 73)
54 R_PAREN@[73; 74)
55 WHITESPACE@[74; 79)
56 R_CURLY@[79; 80)
57 WHITESPACE@[80; 81)
58 R_CURLY@[81; 82)
59 WHITESPACE@[82; 83)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs
new file mode 100644
index 000000000..4dc1999d1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 [];
3 [1];
4 [1, 2,];
5 [1; 2];
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt
new file mode 100644
index 000000000..dcdeff609
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt
@@ -0,0 +1,54 @@
1ROOT@[0; 55)
2 FN_DEF@[0; 54)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 54)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 18)
15 ARRAY_EXPR@[15; 17)
16 L_BRACK@[15; 16)
17 R_BRACK@[16; 17)
18 SEMI@[17; 18)
19 WHITESPACE@[18; 23)
20 EXPR_STMT@[23; 27)
21 ARRAY_EXPR@[23; 26)
22 L_BRACK@[23; 24)
23 LITERAL@[24; 25)
24 INT_NUMBER@[24; 25) "1"
25 R_BRACK@[25; 26)
26 SEMI@[26; 27)
27 WHITESPACE@[27; 32)
28 EXPR_STMT@[32; 40)
29 ARRAY_EXPR@[32; 39)
30 L_BRACK@[32; 33)
31 LITERAL@[33; 34)
32 INT_NUMBER@[33; 34) "1"
33 COMMA@[34; 35)
34 WHITESPACE@[35; 36)
35 LITERAL@[36; 37)
36 INT_NUMBER@[36; 37) "2"
37 COMMA@[37; 38)
38 R_BRACK@[38; 39)
39 SEMI@[39; 40)
40 WHITESPACE@[40; 45)
41 EXPR_STMT@[45; 52)
42 ARRAY_EXPR@[45; 51)
43 L_BRACK@[45; 46)
44 LITERAL@[46; 47)
45 INT_NUMBER@[46; 47) "1"
46 SEMI@[47; 48)
47 WHITESPACE@[48; 49)
48 LITERAL@[49; 50)
49 INT_NUMBER@[49; 50) "2"
50 R_BRACK@[50; 51)
51 SEMI@[51; 52)
52 WHITESPACE@[52; 53)
53 R_CURLY@[53; 54)
54 WHITESPACE@[54; 55)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs
new file mode 100644
index 000000000..d769da43d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs
@@ -0,0 +1,9 @@
1fn foo() {
2 if true {}
3 loop {}
4 match () {}
5 while true {}
6 for _ in () {}
7 {}
8 {}
9}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt
new file mode 100644
index 000000000..f1b0e2787
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt
@@ -0,0 +1,87 @@
1ROOT@[0; 107)
2 FN_DEF@[0; 106)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 106)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 25)
15 IF_EXPR@[15; 25)
16 IF_KW@[15; 17)
17 WHITESPACE@[17; 18)
18 CONDITION@[18; 22)
19 LITERAL@[18; 22)
20 TRUE_KW@[18; 22)
21 WHITESPACE@[22; 23)
22 BLOCK@[23; 25)
23 L_CURLY@[23; 24)
24 R_CURLY@[24; 25)
25 WHITESPACE@[25; 30)
26 EXPR_STMT@[30; 37)
27 LOOP_EXPR@[30; 37)
28 LOOP_KW@[30; 34)
29 WHITESPACE@[34; 35)
30 BLOCK@[35; 37)
31 L_CURLY@[35; 36)
32 R_CURLY@[36; 37)
33 WHITESPACE@[37; 42)
34 EXPR_STMT@[42; 53)
35 MATCH_EXPR@[42; 53)
36 MATCH_KW@[42; 47)
37 WHITESPACE@[47; 48)
38 TUPLE_EXPR@[48; 50)
39 L_PAREN@[48; 49)
40 R_PAREN@[49; 50)
41 WHITESPACE@[50; 51)
42 MATCH_ARM_LIST@[51; 53)
43 L_CURLY@[51; 52)
44 R_CURLY@[52; 53)
45 WHITESPACE@[53; 58)
46 EXPR_STMT@[58; 71)
47 WHILE_EXPR@[58; 71)
48 WHILE_KW@[58; 63)
49 WHITESPACE@[63; 64)
50 CONDITION@[64; 68)
51 LITERAL@[64; 68)
52 TRUE_KW@[64; 68)
53 WHITESPACE@[68; 69)
54 BLOCK@[69; 71)
55 L_CURLY@[69; 70)
56 R_CURLY@[70; 71)
57 WHITESPACE@[71; 76)
58 EXPR_STMT@[76; 90)
59 FOR_EXPR@[76; 90)
60 FOR_KW@[76; 79)
61 WHITESPACE@[79; 80)
62 PLACEHOLDER_PAT@[80; 81)
63 UNDERSCORE@[80; 81)
64 WHITESPACE@[81; 82)
65 IN_KW@[82; 84)
66 WHITESPACE@[84; 85)
67 TUPLE_EXPR@[85; 87)
68 L_PAREN@[85; 86)
69 R_PAREN@[86; 87)
70 WHITESPACE@[87; 88)
71 BLOCK@[88; 90)
72 L_CURLY@[88; 89)
73 R_CURLY@[89; 90)
74 WHITESPACE@[90; 95)
75 EXPR_STMT@[95; 97)
76 BLOCK_EXPR@[95; 97)
77 BLOCK@[95; 97)
78 L_CURLY@[95; 96)
79 R_CURLY@[96; 97)
80 WHITESPACE@[97; 102)
81 BLOCK_EXPR@[102; 104)
82 BLOCK@[102; 104)
83 L_CURLY@[102; 103)
84 R_CURLY@[103; 104)
85 WHITESPACE@[104; 105)
86 R_CURLY@[105; 106)
87 WHITESPACE@[106; 107)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs
new file mode 100644
index 000000000..2edd578f9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs
@@ -0,0 +1,7 @@
1fn foo() {
2 match () {
3 _ => {}
4 () => {}
5 [] => {}
6 }
7}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt
new file mode 100644
index 000000000..91edf3f84
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt
@@ -0,0 +1,62 @@
1ROOT@[0; 84)
2 FN_DEF@[0; 83)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 83)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 MATCH_EXPR@[15; 81)
15 MATCH_KW@[15; 20)
16 WHITESPACE@[20; 21)
17 TUPLE_EXPR@[21; 23)
18 L_PAREN@[21; 22)
19 R_PAREN@[22; 23)
20 WHITESPACE@[23; 24)
21 MATCH_ARM_LIST@[24; 81)
22 L_CURLY@[24; 25)
23 WHITESPACE@[25; 34)
24 MATCH_ARM@[34; 41)
25 PLACEHOLDER_PAT@[34; 35)
26 UNDERSCORE@[34; 35)
27 WHITESPACE@[35; 36)
28 FAT_ARROW@[36; 38)
29 WHITESPACE@[38; 39)
30 BLOCK_EXPR@[39; 41)
31 BLOCK@[39; 41)
32 L_CURLY@[39; 40)
33 R_CURLY@[40; 41)
34 WHITESPACE@[41; 50)
35 MATCH_ARM@[50; 58)
36 TUPLE_PAT@[50; 52)
37 L_PAREN@[50; 51)
38 R_PAREN@[51; 52)
39 WHITESPACE@[52; 53)
40 FAT_ARROW@[53; 55)
41 WHITESPACE@[55; 56)
42 BLOCK_EXPR@[56; 58)
43 BLOCK@[56; 58)
44 L_CURLY@[56; 57)
45 R_CURLY@[57; 58)
46 WHITESPACE@[58; 67)
47 MATCH_ARM@[67; 75)
48 SLICE_PAT@[67; 69)
49 L_BRACK@[67; 68)
50 R_BRACK@[68; 69)
51 WHITESPACE@[69; 70)
52 FAT_ARROW@[70; 72)
53 WHITESPACE@[72; 73)
54 BLOCK_EXPR@[73; 75)
55 BLOCK@[73; 75)
56 L_CURLY@[73; 74)
57 R_CURLY@[74; 75)
58 WHITESPACE@[75; 80)
59 R_CURLY@[80; 81)
60 WHITESPACE@[81; 82)
61 R_CURLY@[82; 83)
62 WHITESPACE@[83; 84)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs
new file mode 100644
index 000000000..37b843742
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 let _ = {1} & 2;
3 {1} &2;
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt
new file mode 100644
index 000000000..ff1298acb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt
@@ -0,0 +1,52 @@
1ROOT@[0; 46)
2 FN_DEF@[0; 45)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 45)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LET_STMT@[15; 31)
15 LET_KW@[15; 18)
16 WHITESPACE@[18; 19)
17 PLACEHOLDER_PAT@[19; 20)
18 UNDERSCORE@[19; 20)
19 WHITESPACE@[20; 21)
20 EQ@[21; 22)
21 WHITESPACE@[22; 23)
22 BIN_EXPR@[23; 30)
23 BLOCK_EXPR@[23; 26)
24 BLOCK@[23; 26)
25 L_CURLY@[23; 24)
26 LITERAL@[24; 25)
27 INT_NUMBER@[24; 25) "1"
28 R_CURLY@[25; 26)
29 WHITESPACE@[26; 27)
30 AMP@[27; 28)
31 WHITESPACE@[28; 29)
32 LITERAL@[29; 30)
33 INT_NUMBER@[29; 30) "2"
34 SEMI@[30; 31)
35 WHITESPACE@[31; 36)
36 EXPR_STMT@[36; 39)
37 BLOCK_EXPR@[36; 39)
38 BLOCK@[36; 39)
39 L_CURLY@[36; 37)
40 LITERAL@[37; 38)
41 INT_NUMBER@[37; 38) "1"
42 R_CURLY@[38; 39)
43 WHITESPACE@[39; 40)
44 EXPR_STMT@[40; 43)
45 REF_EXPR@[40; 42)
46 AMP@[40; 41)
47 LITERAL@[41; 42)
48 INT_NUMBER@[41; 42) "2"
49 SEMI@[42; 43)
50 WHITESPACE@[43; 44)
51 R_CURLY@[44; 45)
52 WHITESPACE@[45; 46)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs
new file mode 100644
index 000000000..7955973b9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs
@@ -0,0 +1,3 @@
1fn main() {
2 let [a, b, ..] = [];
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt
new file mode 100644
index 000000000..99e8dd427
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt
@@ -0,0 +1,40 @@
1ROOT@[0; 39)
2 FN_DEF@[0; 38)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 38)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 LET_STMT@[16; 36)
15 LET_KW@[16; 19)
16 WHITESPACE@[19; 20)
17 SLICE_PAT@[20; 30)
18 L_BRACK@[20; 21)
19 BIND_PAT@[21; 22)
20 NAME@[21; 22)
21 IDENT@[21; 22) "a"
22 COMMA@[22; 23)
23 WHITESPACE@[23; 24)
24 BIND_PAT@[24; 25)
25 NAME@[24; 25)
26 IDENT@[24; 25) "b"
27 COMMA@[25; 26)
28 WHITESPACE@[26; 27)
29 DOTDOT@[27; 29)
30 R_BRACK@[29; 30)
31 WHITESPACE@[30; 31)
32 EQ@[31; 32)
33 WHITESPACE@[32; 33)
34 ARRAY_EXPR@[33; 35)
35 L_BRACK@[33; 34)
36 R_BRACK@[34; 35)
37 SEMI@[35; 36)
38 WHITESPACE@[36; 37)
39 R_CURLY@[37; 38)
40 WHITESPACE@[38; 39)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs
new file mode 100644
index 000000000..c9f74f7f5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs
@@ -0,0 +1 @@
trait T { fn foo(); }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt
new file mode 100644
index 000000000..c35bc8428
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt
@@ -0,0 +1,22 @@
1ROOT@[0; 22)
2 TRAIT_DEF@[0; 21)
3 TRAIT_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 NAME@[6; 7)
6 IDENT@[6; 7) "T"
7 WHITESPACE@[7; 8)
8 ITEM_LIST@[8; 21)
9 L_CURLY@[8; 9)
10 WHITESPACE@[9; 10)
11 FN_DEF@[10; 19)
12 FN_KW@[10; 12)
13 WHITESPACE@[12; 13)
14 NAME@[13; 16)
15 IDENT@[13; 16) "foo"
16 PARAM_LIST@[16; 18)
17 L_PAREN@[16; 17)
18 R_PAREN@[17; 18)
19 SEMI@[18; 19)
20 WHITESPACE@[19; 20)
21 R_CURLY@[20; 21)
22 WHITESPACE@[21; 22)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs
new file mode 100644
index 000000000..16f674d9d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs
@@ -0,0 +1,7 @@
1fn main() {
2 match () {
3 92 => (),
4 'c' => (),
5 "hello" => (),
6 }
7}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt
new file mode 100644
index 000000000..3128bfd7d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt
@@ -0,0 +1,60 @@
1ROOT@[0; 95)
2 FN_DEF@[0; 94)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 94)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 MATCH_EXPR@[16; 92)
15 MATCH_KW@[16; 21)
16 WHITESPACE@[21; 22)
17 TUPLE_EXPR@[22; 24)
18 L_PAREN@[22; 23)
19 R_PAREN@[23; 24)
20 WHITESPACE@[24; 25)
21 MATCH_ARM_LIST@[25; 92)
22 L_CURLY@[25; 26)
23 WHITESPACE@[26; 35)
24 MATCH_ARM@[35; 43)
25 LITERAL@[35; 37)
26 INT_NUMBER@[35; 37) "92"
27 WHITESPACE@[37; 38)
28 FAT_ARROW@[38; 40)
29 WHITESPACE@[40; 41)
30 TUPLE_EXPR@[41; 43)
31 L_PAREN@[41; 42)
32 R_PAREN@[42; 43)
33 COMMA@[43; 44)
34 WHITESPACE@[44; 53)
35 MATCH_ARM@[53; 62)
36 LITERAL@[53; 56)
37 CHAR@[53; 56)
38 WHITESPACE@[56; 57)
39 FAT_ARROW@[57; 59)
40 WHITESPACE@[59; 60)
41 TUPLE_EXPR@[60; 62)
42 L_PAREN@[60; 61)
43 R_PAREN@[61; 62)
44 COMMA@[62; 63)
45 WHITESPACE@[63; 72)
46 MATCH_ARM@[72; 85)
47 LITERAL@[72; 79)
48 STRING@[72; 79)
49 WHITESPACE@[79; 80)
50 FAT_ARROW@[80; 82)
51 WHITESPACE@[82; 83)
52 TUPLE_EXPR@[83; 85)
53 L_PAREN@[83; 84)
54 R_PAREN@[84; 85)
55 COMMA@[85; 86)
56 WHITESPACE@[86; 91)
57 R_CURLY@[91; 92)
58 WHITESPACE@[92; 93)
59 R_CURLY@[93; 94)
60 WHITESPACE@[94; 95)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs
new file mode 100644
index 000000000..aef45e561
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs
@@ -0,0 +1 @@
type F = Box<Fn(x: i32) -> ()>;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt
new file mode 100644
index 000000000..26a690d3a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt
@@ -0,0 +1,46 @@
1ROOT@[0; 32)
2 TYPE_DEF@[0; 31)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "F"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 PATH_TYPE@[9; 30)
11 PATH@[9; 30)
12 PATH_SEGMENT@[9; 30)
13 NAME_REF@[9; 12)
14 IDENT@[9; 12) "Box"
15 TYPE_ARG_LIST@[12; 30)
16 L_ANGLE@[12; 13)
17 TYPE_ARG@[13; 29)
18 PATH_TYPE@[13; 29)
19 PATH@[13; 29)
20 PATH_SEGMENT@[13; 29)
21 NAME_REF@[13; 15)
22 IDENT@[13; 15) "Fn"
23 PARAM_LIST@[15; 23)
24 L_PAREN@[15; 16)
25 PARAM@[16; 22)
26 BIND_PAT@[16; 17)
27 NAME@[16; 17)
28 IDENT@[16; 17) "x"
29 COLON@[17; 18)
30 WHITESPACE@[18; 19)
31 PATH_TYPE@[19; 22)
32 PATH@[19; 22)
33 PATH_SEGMENT@[19; 22)
34 NAME_REF@[19; 22)
35 IDENT@[19; 22) "i32"
36 R_PAREN@[22; 23)
37 WHITESPACE@[23; 24)
38 RET_TYPE@[24; 29)
39 THIN_ARROW@[24; 26)
40 WHITESPACE@[26; 27)
41 TUPLE_TYPE@[27; 29)
42 L_PAREN@[27; 28)
43 R_PAREN@[28; 29)
44 R_ANGLE@[29; 30)
45 SEMI@[30; 31)
46 WHITESPACE@[31; 32)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs
new file mode 100644
index 000000000..657467e75
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs
@@ -0,0 +1,3 @@
1fn main() {
2 match 92 { 0 ... 100 => () }
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt
new file mode 100644
index 000000000..4f14d5431
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt
@@ -0,0 +1,42 @@
1ROOT@[0; 47)
2 FN_DEF@[0; 46)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 46)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 MATCH_EXPR@[16; 44)
15 MATCH_KW@[16; 21)
16 WHITESPACE@[21; 22)
17 LITERAL@[22; 24)
18 INT_NUMBER@[22; 24) "92"
19 WHITESPACE@[24; 25)
20 MATCH_ARM_LIST@[25; 44)
21 L_CURLY@[25; 26)
22 WHITESPACE@[26; 27)
23 MATCH_ARM@[27; 42)
24 RANGE_PAT@[27; 36)
25 LITERAL@[27; 28)
26 INT_NUMBER@[27; 28) "0"
27 WHITESPACE@[28; 29)
28 DOTDOTDOT@[29; 32)
29 WHITESPACE@[32; 33)
30 LITERAL@[33; 36)
31 INT_NUMBER@[33; 36) "100"
32 WHITESPACE@[36; 37)
33 FAT_ARROW@[37; 39)
34 WHITESPACE@[39; 40)
35 TUPLE_EXPR@[40; 42)
36 L_PAREN@[40; 41)
37 R_PAREN@[41; 42)
38 WHITESPACE@[42; 43)
39 R_CURLY@[43; 44)
40 WHITESPACE@[44; 45)
41 R_CURLY@[45; 46)
42 WHITESPACE@[46; 47)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs
new file mode 100644
index 000000000..215210e27
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs
@@ -0,0 +1 @@
fn foo() -> Box<T + 'f> {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt
new file mode 100644
index 000000000..4b864f741
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt
@@ -0,0 +1,36 @@
1ROOT@[0; 27)
2 FN_DEF@[0; 26)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 RET_TYPE@[9; 23)
12 THIN_ARROW@[9; 11)
13 WHITESPACE@[11; 12)
14 PATH_TYPE@[12; 23)
15 PATH@[12; 23)
16 PATH_SEGMENT@[12; 23)
17 NAME_REF@[12; 15)
18 IDENT@[12; 15) "Box"
19 TYPE_ARG_LIST@[15; 23)
20 L_ANGLE@[15; 16)
21 TYPE_ARG@[16; 22)
22 PATH_TYPE@[16; 22)
23 PATH@[16; 17)
24 PATH_SEGMENT@[16; 17)
25 NAME_REF@[16; 17)
26 IDENT@[16; 17) "T"
27 WHITESPACE@[17; 18)
28 PLUS@[18; 19)
29 WHITESPACE@[19; 20)
30 LIFETIME@[20; 22) "'f"
31 R_ANGLE@[22; 23)
32 WHITESPACE@[23; 24)
33 BLOCK@[24; 26)
34 L_CURLY@[24; 25)
35 R_CURLY@[25; 26)
36 WHITESPACE@[26; 27)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs
new file mode 100644
index 000000000..d8c23c76a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs
@@ -0,0 +1 @@
type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt
new file mode 100644
index 000000000..3c8352067
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt
@@ -0,0 +1,81 @@
1ROOT@[0; 54)
2 TYPE_DEF@[0; 53)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "F"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 PATH_TYPE@[9; 52)
11 PATH@[9; 52)
12 PATH_SEGMENT@[9; 52)
13 NAME_REF@[9; 12)
14 IDENT@[9; 12) "Box"
15 TYPE_ARG_LIST@[12; 52)
16 L_ANGLE@[12; 13)
17 TYPE_ARG@[13; 51)
18 PATH_TYPE@[13; 51)
19 PATH@[13; 51)
20 PATH_SEGMENT@[13; 51)
21 NAME_REF@[13; 15)
22 IDENT@[13; 15) "Fn"
23 PARAM_LIST@[15; 51)
24 L_PAREN@[15; 16)
25 PARAM@[16; 22)
26 BIND_PAT@[16; 17)
27 NAME@[16; 17)
28 IDENT@[16; 17) "a"
29 COLON@[17; 18)
30 WHITESPACE@[18; 19)
31 PATH_TYPE@[19; 22)
32 PATH@[19; 22)
33 PATH_SEGMENT@[19; 22)
34 NAME_REF@[19; 22)
35 IDENT@[19; 22) "i32"
36 COMMA@[22; 23)
37 WHITESPACE@[23; 24)
38 PARAM@[24; 32)
39 REF_PAT@[24; 26)
40 AMP@[24; 25)
41 BIND_PAT@[25; 26)
42 NAME@[25; 26)
43 IDENT@[25; 26) "b"
44 COLON@[26; 27)
45 WHITESPACE@[27; 28)
46 REFERENCE_TYPE@[28; 32)
47 AMP@[28; 29)
48 PATH_TYPE@[29; 32)
49 PATH@[29; 32)
50 PATH_SEGMENT@[29; 32)
51 NAME_REF@[29; 32)
52 IDENT@[29; 32) "i32"
53 COMMA@[32; 33)
54 WHITESPACE@[33; 34)
55 PARAM@[34; 46)
56 REF_PAT@[34; 40)
57 AMP@[34; 35)
58 MUT_KW@[35; 38)
59 WHITESPACE@[38; 39)
60 BIND_PAT@[39; 40)
61 NAME@[39; 40)
62 IDENT@[39; 40) "c"
63 COLON@[40; 41)
64 WHITESPACE@[41; 42)
65 REFERENCE_TYPE@[42; 46)
66 AMP@[42; 43)
67 PATH_TYPE@[43; 46)
68 PATH@[43; 46)
69 PATH_SEGMENT@[43; 46)
70 NAME_REF@[43; 46)
71 IDENT@[43; 46) "i32"
72 COMMA@[46; 47)
73 WHITESPACE@[47; 48)
74 PARAM@[48; 50)
75 TUPLE_TYPE@[48; 50)
76 L_PAREN@[48; 49)
77 R_PAREN@[49; 50)
78 R_PAREN@[50; 51)
79 R_ANGLE@[51; 52)
80 SEMI@[52; 53)
81 WHITESPACE@[53; 54)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs
new file mode 100644
index 000000000..9b93442c0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs
@@ -0,0 +1 @@
fn foo<F: FnMut(&mut Foo<'a>)>(){}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt
new file mode 100644
index 000000000..39bab8dd2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt
@@ -0,0 +1,44 @@
1ROOT@[0; 35)
2 FN_DEF@[0; 34)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 TYPE_PARAM_LIST@[6; 30)
8 L_ANGLE@[6; 7)
9 TYPE_PARAM@[7; 29)
10 NAME@[7; 8)
11 IDENT@[7; 8) "F"
12 COLON@[8; 9)
13 WHITESPACE@[9; 10)
14 PATH_TYPE@[10; 29)
15 PATH@[10; 29)
16 PATH_SEGMENT@[10; 29)
17 NAME_REF@[10; 15)
18 IDENT@[10; 15) "FnMut"
19 PARAM_LIST@[15; 29)
20 L_PAREN@[15; 16)
21 PARAM@[16; 28)
22 REFERENCE_TYPE@[16; 28)
23 AMP@[16; 17)
24 MUT_KW@[17; 20)
25 WHITESPACE@[20; 21)
26 PATH_TYPE@[21; 28)
27 PATH@[21; 28)
28 PATH_SEGMENT@[21; 28)
29 NAME_REF@[21; 24)
30 IDENT@[21; 24) "Foo"
31 TYPE_ARG_LIST@[24; 28)
32 L_ANGLE@[24; 25)
33 LIFETIME_ARG@[25; 27)
34 LIFETIME@[25; 27) "'a"
35 R_ANGLE@[27; 28)
36 R_PAREN@[28; 29)
37 R_ANGLE@[29; 30)
38 PARAM_LIST@[30; 32)
39 L_PAREN@[30; 31)
40 R_PAREN@[31; 32)
41 BLOCK@[32; 34)
42 L_CURLY@[32; 33)
43 R_CURLY@[33; 34)
44 WHITESPACE@[34; 35)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs
new file mode 100644
index 000000000..592a005f9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs
@@ -0,0 +1,6 @@
1fn foo()
2where
3 'a: 'b + 'c,
4 T: Clone + Copy + 'static,
5 Iterator::Item: 'a,
6{}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt
new file mode 100644
index 000000000..9fe803554
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt
@@ -0,0 +1,71 @@
1ROOT@[0; 87)
2 FN_DEF@[0; 86)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 WHERE_CLAUSE@[9; 83)
12 WHERE_KW@[9; 14)
13 WHITESPACE@[14; 18)
14 WHERE_PRED@[18; 29)
15 LIFETIME@[18; 20) "'a"
16 COLON@[20; 21)
17 WHITESPACE@[21; 22)
18 LIFETIME@[22; 24) "'b"
19 WHITESPACE@[24; 25)
20 PLUS@[25; 26)
21 WHITESPACE@[26; 27)
22 LIFETIME@[27; 29) "'c"
23 COMMA@[29; 30)
24 WHITESPACE@[30; 34)
25 WHERE_PRED@[34; 59)
26 PATH_TYPE@[34; 35)
27 PATH@[34; 35)
28 PATH_SEGMENT@[34; 35)
29 NAME_REF@[34; 35)
30 IDENT@[34; 35) "T"
31 COLON@[35; 36)
32 WHITESPACE@[36; 37)
33 PATH_TYPE@[37; 59)
34 PATH@[37; 42)
35 PATH_SEGMENT@[37; 42)
36 NAME_REF@[37; 42)
37 IDENT@[37; 42) "Clone"
38 WHITESPACE@[42; 43)
39 PLUS@[43; 44)
40 WHITESPACE@[44; 45)
41 PATH_TYPE@[45; 59)
42 PATH@[45; 49)
43 PATH_SEGMENT@[45; 49)
44 NAME_REF@[45; 49)
45 IDENT@[45; 49) "Copy"
46 WHITESPACE@[49; 50)
47 PLUS@[50; 51)
48 WHITESPACE@[51; 52)
49 LIFETIME@[52; 59) "'static"
50 COMMA@[59; 60)
51 WHITESPACE@[60; 64)
52 WHERE_PRED@[64; 82)
53 PATH_TYPE@[64; 78)
54 PATH@[64; 78)
55 PATH@[64; 72)
56 PATH_SEGMENT@[64; 72)
57 NAME_REF@[64; 72)
58 IDENT@[64; 72) "Iterator"
59 COLONCOLON@[72; 74)
60 PATH_SEGMENT@[74; 78)
61 NAME_REF@[74; 78)
62 IDENT@[74; 78) "Item"
63 COLON@[78; 79)
64 WHITESPACE@[79; 80)
65 LIFETIME@[80; 82) "'a"
66 COMMA@[82; 83)
67 WHITESPACE@[83; 84)
68 BLOCK@[84; 86)
69 L_CURLY@[84; 85)
70 R_CURLY@[85; 86)
71 WHITESPACE@[86; 87)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs
new file mode 100644
index 000000000..660d927cf
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs
@@ -0,0 +1 @@
crate fn main() { }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt
new file mode 100644
index 000000000..96a4e9162
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt
@@ -0,0 +1,18 @@
1ROOT@[0; 20)
2 FN_DEF@[0; 19)
3 VISIBILITY@[0; 5)
4 CRATE_KW@[0; 5)
5 WHITESPACE@[5; 6)
6 FN_KW@[6; 8)
7 WHITESPACE@[8; 9)
8 NAME@[9; 13)
9 IDENT@[9; 13) "main"
10 PARAM_LIST@[13; 15)
11 L_PAREN@[13; 14)
12 R_PAREN@[14; 15)
13 WHITESPACE@[15; 16)
14 BLOCK@[16; 19)
15 L_CURLY@[16; 17)
16 WHITESPACE@[17; 18)
17 R_CURLY@[18; 19)
18 WHITESPACE@[19; 20)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs
new file mode 100644
index 000000000..c3ecabb99
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs
@@ -0,0 +1 @@
type A = dyn Iterator<Item=Foo<'a>> + 'a;
diff --git a/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt
new file mode 100644
index 000000000..c81ae5545
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt
@@ -0,0 +1,40 @@
1ROOT@[0; 42)
2 TYPE_DEF@[0; 41)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 DYN_TRAIT_TYPE@[9; 40)
11 DYN_KW@[9; 12)
12 WHITESPACE@[12; 13)
13 PATH_TYPE@[13; 40)
14 PATH@[13; 35)
15 PATH_SEGMENT@[13; 35)
16 NAME_REF@[13; 21)
17 IDENT@[13; 21) "Iterator"
18 TYPE_ARG_LIST@[21; 35)
19 L_ANGLE@[21; 22)
20 ASSOC_TYPE_ARG@[22; 34)
21 NAME_REF@[22; 26)
22 IDENT@[22; 26) "Item"
23 EQ@[26; 27)
24 PATH_TYPE@[27; 34)
25 PATH@[27; 34)
26 PATH_SEGMENT@[27; 34)
27 NAME_REF@[27; 30)
28 IDENT@[27; 30) "Foo"
29 TYPE_ARG_LIST@[30; 34)
30 L_ANGLE@[30; 31)
31 LIFETIME_ARG@[31; 33)
32 LIFETIME@[31; 33) "'a"
33 R_ANGLE@[33; 34)
34 R_ANGLE@[34; 35)
35 WHITESPACE@[35; 36)
36 PLUS@[36; 37)
37 WHITESPACE@[37; 38)
38 LIFETIME@[38; 40) "'a"
39 SEMI@[40; 41)
40 WHITESPACE@[41; 42)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs
new file mode 100644
index 000000000..d140692e2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs
@@ -0,0 +1,2 @@
1type X = <A as B>::Output;
2fn foo() { <usize as Default>::default(); }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt
new file mode 100644
index 000000000..99516bf15
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt
@@ -0,0 +1,78 @@
1ROOT@[0; 71)
2 TYPE_DEF@[0; 26)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "X"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 PATH_TYPE@[9; 25)
11 PATH@[9; 25)
12 PATH@[9; 17)
13 PATH_SEGMENT@[9; 17)
14 L_ANGLE@[9; 10)
15 PATH_TYPE@[10; 11)
16 PATH@[10; 11)
17 PATH_SEGMENT@[10; 11)
18 NAME_REF@[10; 11)
19 IDENT@[10; 11) "A"
20 WHITESPACE@[11; 12)
21 AS_KW@[12; 14)
22 WHITESPACE@[14; 15)
23 PATH_TYPE@[15; 16)
24 PATH@[15; 16)
25 PATH_SEGMENT@[15; 16)
26 NAME_REF@[15; 16)
27 IDENT@[15; 16) "B"
28 R_ANGLE@[16; 17)
29 COLONCOLON@[17; 19)
30 PATH_SEGMENT@[19; 25)
31 NAME_REF@[19; 25)
32 IDENT@[19; 25) "Output"
33 SEMI@[25; 26)
34 WHITESPACE@[26; 27)
35 FN_DEF@[27; 70)
36 FN_KW@[27; 29)
37 WHITESPACE@[29; 30)
38 NAME@[30; 33)
39 IDENT@[30; 33) "foo"
40 PARAM_LIST@[33; 35)
41 L_PAREN@[33; 34)
42 R_PAREN@[34; 35)
43 WHITESPACE@[35; 36)
44 BLOCK@[36; 70)
45 L_CURLY@[36; 37)
46 WHITESPACE@[37; 38)
47 EXPR_STMT@[38; 68)
48 CALL_EXPR@[38; 67)
49 PATH_EXPR@[38; 65)
50 PATH@[38; 65)
51 PATH@[38; 56)
52 PATH_SEGMENT@[38; 56)
53 L_ANGLE@[38; 39)
54 PATH_TYPE@[39; 44)
55 PATH@[39; 44)
56 PATH_SEGMENT@[39; 44)
57 NAME_REF@[39; 44)
58 IDENT@[39; 44) "usize"
59 WHITESPACE@[44; 45)
60 AS_KW@[45; 47)
61 WHITESPACE@[47; 48)
62 PATH_TYPE@[48; 55)
63 PATH@[48; 55)
64 PATH_SEGMENT@[48; 55)
65 NAME_REF@[48; 55)
66 IDENT@[48; 55) "Default"
67 R_ANGLE@[55; 56)
68 COLONCOLON@[56; 58)
69 PATH_SEGMENT@[58; 65)
70 NAME_REF@[58; 65)
71 IDENT@[58; 65) "default"
72 ARG_LIST@[65; 67)
73 L_PAREN@[65; 66)
74 R_PAREN@[66; 67)
75 SEMI@[67; 68)
76 WHITESPACE@[68; 69)
77 R_CURLY@[69; 70)
78 WHITESPACE@[70; 71)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs
new file mode 100644
index 000000000..ae21ad94c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs
@@ -0,0 +1 @@
fn foo() { xs[..]; }
diff --git a/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt
new file mode 100644
index 000000000..19f77fb73
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt
@@ -0,0 +1,28 @@
1ROOT@[0; 21)
2 FN_DEF@[0; 20)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 20)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 EXPR_STMT@[11; 18)
15 INDEX_EXPR@[11; 17)
16 PATH_EXPR@[11; 13)
17 PATH@[11; 13)
18 PATH_SEGMENT@[11; 13)
19 NAME_REF@[11; 13)
20 IDENT@[11; 13) "xs"
21 L_BRACK@[13; 14)
22 RANGE_EXPR@[14; 16)
23 DOTDOT@[14; 16)
24 R_BRACK@[16; 17)
25 SEMI@[17; 18)
26 WHITESPACE@[18; 19)
27 R_CURLY@[19; 20)
28 WHITESPACE@[20; 21)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs
new file mode 100644
index 000000000..4744d8ac0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs
@@ -0,0 +1,4 @@
1struct S {
2 #[serde(with = "url_serde")]
3 pub uri: Uri,
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt
new file mode 100644
index 000000000..420712e89
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt
@@ -0,0 +1,42 @@
1ROOT@[0; 64)
2 STRUCT_DEF@[0; 63)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 WHITESPACE@[8; 9)
8 NAMED_FIELD_DEF_LIST@[9; 63)
9 L_CURLY@[9; 10)
10 WHITESPACE@[10; 15)
11 NAMED_FIELD_DEF@[15; 60)
12 ATTR@[15; 43)
13 POUND@[15; 16)
14 TOKEN_TREE@[16; 43)
15 L_BRACK@[16; 17)
16 IDENT@[17; 22) "serde"
17 TOKEN_TREE@[22; 42)
18 L_PAREN@[22; 23)
19 IDENT@[23; 27) "with"
20 WHITESPACE@[27; 28)
21 EQ@[28; 29)
22 WHITESPACE@[29; 30)
23 STRING@[30; 41)
24 R_PAREN@[41; 42)
25 R_BRACK@[42; 43)
26 WHITESPACE@[43; 48)
27 VISIBILITY@[48; 51)
28 PUB_KW@[48; 51)
29 WHITESPACE@[51; 52)
30 NAME@[52; 55)
31 IDENT@[52; 55) "uri"
32 COLON@[55; 56)
33 WHITESPACE@[56; 57)
34 PATH_TYPE@[57; 60)
35 PATH@[57; 60)
36 PATH_SEGMENT@[57; 60)
37 NAME_REF@[57; 60)
38 IDENT@[57; 60) "Uri"
39 COMMA@[60; 61)
40 WHITESPACE@[61; 62)
41 R_CURLY@[62; 63)
42 WHITESPACE@[63; 64)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs
new file mode 100644
index 000000000..6a170d5ac
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs
@@ -0,0 +1,4 @@
1impl S {
2 fn a(self: &Self) {}
3 fn b(mut self: Box<Self>) {}
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt
new file mode 100644
index 000000000..9a306921e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt
@@ -0,0 +1,72 @@
1ROOT@[0; 69)
2 IMPL_ITEM@[0; 68)
3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6)
6 PATH@[5; 6)
7 PATH_SEGMENT@[5; 6)
8 NAME_REF@[5; 6)
9 IDENT@[5; 6) "S"
10 WHITESPACE@[6; 7)
11 ITEM_LIST@[7; 68)
12 L_CURLY@[7; 8)
13 WHITESPACE@[8; 13)
14 FN_DEF@[13; 33)
15 FN_KW@[13; 15)
16 WHITESPACE@[15; 16)
17 NAME@[16; 17)
18 IDENT@[16; 17) "a"
19 PARAM_LIST@[17; 30)
20 L_PAREN@[17; 18)
21 SELF_PARAM@[18; 29)
22 SELF_KW@[18; 22)
23 COLON@[22; 23)
24 WHITESPACE@[23; 24)
25 REFERENCE_TYPE@[24; 29)
26 AMP@[24; 25)
27 PATH_TYPE@[25; 29)
28 PATH@[25; 29)
29 PATH_SEGMENT@[25; 29)
30 NAME_REF@[25; 29)
31 IDENT@[25; 29) "Self"
32 R_PAREN@[29; 30)
33 WHITESPACE@[30; 31)
34 BLOCK@[31; 33)
35 L_CURLY@[31; 32)
36 R_CURLY@[32; 33)
37 WHITESPACE@[33; 38)
38 FN_DEF@[38; 66)
39 FN_KW@[38; 40)
40 WHITESPACE@[40; 41)
41 NAME@[41; 42)
42 IDENT@[41; 42) "b"
43 PARAM_LIST@[42; 63)
44 L_PAREN@[42; 43)
45 SELF_PARAM@[43; 62)
46 MUT_KW@[43; 46)
47 WHITESPACE@[46; 47)
48 SELF_KW@[47; 51)
49 COLON@[51; 52)
50 WHITESPACE@[52; 53)
51 PATH_TYPE@[53; 62)
52 PATH@[53; 62)
53 PATH_SEGMENT@[53; 62)
54 NAME_REF@[53; 56)
55 IDENT@[53; 56) "Box"
56 TYPE_ARG_LIST@[56; 62)
57 L_ANGLE@[56; 57)
58 TYPE_ARG@[57; 61)
59 PATH_TYPE@[57; 61)
60 PATH@[57; 61)
61 PATH_SEGMENT@[57; 61)
62 NAME_REF@[57; 61)
63 IDENT@[57; 61) "Self"
64 R_ANGLE@[61; 62)
65 R_PAREN@[62; 63)
66 WHITESPACE@[63; 64)
67 BLOCK@[64; 66)
68 L_CURLY@[64; 65)
69 R_CURLY@[65; 66)
70 WHITESPACE@[66; 67)
71 R_CURLY@[67; 68)
72 WHITESPACE@[68; 69)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs
new file mode 100644
index 000000000..474cc3f0e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 loop {
3 continue;
4 continue 'l;
5 }
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt
new file mode 100644
index 000000000..1c78704fa
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt
@@ -0,0 +1,35 @@
1ROOT@[0; 69)
2 FN_DEF@[0; 68)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 68)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LOOP_EXPR@[15; 66)
15 LOOP_KW@[15; 19)
16 WHITESPACE@[19; 20)
17 BLOCK@[20; 66)
18 L_CURLY@[20; 21)
19 WHITESPACE@[21; 30)
20 EXPR_STMT@[30; 39)
21 CONTINUE_EXPR@[30; 38)
22 CONTINUE_KW@[30; 38)
23 SEMI@[38; 39)
24 WHITESPACE@[39; 48)
25 EXPR_STMT@[48; 60)
26 CONTINUE_EXPR@[48; 59)
27 CONTINUE_KW@[48; 56)
28 WHITESPACE@[56; 57)
29 LIFETIME@[57; 59) "'l"
30 SEMI@[59; 60)
31 WHITESPACE@[60; 65)
32 R_CURLY@[65; 66)
33 WHITESPACE@[66; 67)
34 R_CURLY@[67; 68)
35 WHITESPACE@[68; 69)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs
new file mode 100644
index 000000000..1b4094636
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs
@@ -0,0 +1,8 @@
1fn foo() {
2 loop {
3 break;
4 break 'l;
5 break 92;
6 break 'l 92;
7 }
8}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt
new file mode 100644
index 000000000..92b6b8bea
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt
@@ -0,0 +1,53 @@
1ROOT@[0; 102)
2 FN_DEF@[0; 101)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 101)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 LOOP_EXPR@[15; 99)
15 LOOP_KW@[15; 19)
16 WHITESPACE@[19; 20)
17 BLOCK@[20; 99)
18 L_CURLY@[20; 21)
19 WHITESPACE@[21; 30)
20 EXPR_STMT@[30; 36)
21 BREAK_EXPR@[30; 35)
22 BREAK_KW@[30; 35)
23 SEMI@[35; 36)
24 WHITESPACE@[36; 45)
25 EXPR_STMT@[45; 54)
26 BREAK_EXPR@[45; 53)
27 BREAK_KW@[45; 50)
28 WHITESPACE@[50; 51)
29 LIFETIME@[51; 53) "'l"
30 SEMI@[53; 54)
31 WHITESPACE@[54; 63)
32 EXPR_STMT@[63; 72)
33 BREAK_EXPR@[63; 71)
34 BREAK_KW@[63; 68)
35 WHITESPACE@[68; 69)
36 LITERAL@[69; 71)
37 INT_NUMBER@[69; 71) "92"
38 SEMI@[71; 72)
39 WHITESPACE@[72; 81)
40 EXPR_STMT@[81; 93)
41 BREAK_EXPR@[81; 92)
42 BREAK_KW@[81; 86)
43 WHITESPACE@[86; 87)
44 LIFETIME@[87; 89) "'l"
45 WHITESPACE@[89; 90)
46 LITERAL@[90; 92)
47 INT_NUMBER@[90; 92) "92"
48 SEMI@[92; 93)
49 WHITESPACE@[93; 98)
50 R_CURLY@[98; 99)
51 WHITESPACE@[99; 100)
52 R_CURLY@[100; 101)
53 WHITESPACE@[101; 102)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0107_label.rs b/crates/ra_syntax/tests/data/parser/inline/0107_label.rs
new file mode 100644
index 000000000..48e83f263
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0107_label.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 'a: loop {}
3 'b: while true {}
4 'c: for x in () {}
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0107_label.txt b/crates/ra_syntax/tests/data/parser/inline/0107_label.txt
new file mode 100644
index 000000000..768515595
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0107_label.txt
@@ -0,0 +1,64 @@
1ROOT@[0; 74)
2 FN_DEF@[0; 73)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 73)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 26)
15 LOOP_EXPR@[15; 26)
16 LABEL@[15; 18)
17 LIFETIME@[15; 17) "'a"
18 COLON@[17; 18)
19 WHITESPACE@[18; 19)
20 LOOP_KW@[19; 23)
21 WHITESPACE@[23; 24)
22 BLOCK@[24; 26)
23 L_CURLY@[24; 25)
24 R_CURLY@[25; 26)
25 WHITESPACE@[26; 31)
26 EXPR_STMT@[31; 48)
27 WHILE_EXPR@[31; 48)
28 LABEL@[31; 34)
29 LIFETIME@[31; 33) "'b"
30 COLON@[33; 34)
31 WHITESPACE@[34; 35)
32 WHILE_KW@[35; 40)
33 WHITESPACE@[40; 41)
34 CONDITION@[41; 45)
35 LITERAL@[41; 45)
36 TRUE_KW@[41; 45)
37 WHITESPACE@[45; 46)
38 BLOCK@[46; 48)
39 L_CURLY@[46; 47)
40 R_CURLY@[47; 48)
41 WHITESPACE@[48; 53)
42 FOR_EXPR@[53; 71)
43 LABEL@[53; 56)
44 LIFETIME@[53; 55) "'c"
45 COLON@[55; 56)
46 WHITESPACE@[56; 57)
47 FOR_KW@[57; 60)
48 WHITESPACE@[60; 61)
49 BIND_PAT@[61; 62)
50 NAME@[61; 62)
51 IDENT@[61; 62) "x"
52 WHITESPACE@[62; 63)
53 IN_KW@[63; 65)
54 WHITESPACE@[65; 66)
55 TUPLE_EXPR@[66; 68)
56 L_PAREN@[66; 67)
57 R_PAREN@[67; 68)
58 WHITESPACE@[68; 69)
59 BLOCK@[69; 71)
60 L_CURLY@[69; 70)
61 R_CURLY@[70; 71)
62 WHITESPACE@[71; 72)
63 R_CURLY@[72; 73)
64 WHITESPACE@[73; 74)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs
new file mode 100644
index 000000000..a2164c510
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs
@@ -0,0 +1,3 @@
1fn main() {
2 'loop: impl
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt
new file mode 100644
index 000000000..d00305b97
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt
@@ -0,0 +1,28 @@
1ROOT@[0; 30)
2 FN_DEF@[0; 29)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 29)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 EXPR_STMT@[16; 22)
15 ERROR@[16; 22)
16 LABEL@[16; 22)
17 LIFETIME@[16; 21) "'loop"
18 COLON@[21; 22)
19 err: `expected a loop`
20 err: `expected SEMI`
21 WHITESPACE@[22; 23)
22 IMPL_ITEM@[23; 27)
23 IMPL_KW@[23; 27)
24 err: `expected type`
25 err: `expected `{``
26 WHITESPACE@[27; 28)
27 R_CURLY@[28; 29)
28 WHITESPACE@[29; 30)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs
new file mode 100644
index 000000000..693e3f3ee
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs
@@ -0,0 +1,8 @@
1struct Foo;
2struct Foo {}
3struct Foo();
4struct Foo(String, usize);
5struct Foo {
6 a: i32,
7 b: f32,
8}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt
new file mode 100644
index 000000000..f9b34cc5e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt
@@ -0,0 +1,87 @@
1ROOT@[0; 106)
2 STRUCT_DEF@[0; 11)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 10)
6 IDENT@[7; 10) "Foo"
7 SEMI@[10; 11)
8 WHITESPACE@[11; 12)
9 STRUCT_DEF@[12; 25)
10 STRUCT_KW@[12; 18)
11 WHITESPACE@[18; 19)
12 NAME@[19; 22)
13 IDENT@[19; 22) "Foo"
14 WHITESPACE@[22; 23)
15 NAMED_FIELD_DEF_LIST@[23; 25)
16 L_CURLY@[23; 24)
17 R_CURLY@[24; 25)
18 WHITESPACE@[25; 26)
19 STRUCT_DEF@[26; 39)
20 STRUCT_KW@[26; 32)
21 WHITESPACE@[32; 33)
22 NAME@[33; 36)
23 IDENT@[33; 36) "Foo"
24 POS_FIELD_LIST@[36; 38)
25 L_PAREN@[36; 37)
26 R_PAREN@[37; 38)
27 SEMI@[38; 39)
28 WHITESPACE@[39; 40)
29 STRUCT_DEF@[40; 66)
30 STRUCT_KW@[40; 46)
31 WHITESPACE@[46; 47)
32 NAME@[47; 50)
33 IDENT@[47; 50) "Foo"
34 POS_FIELD_LIST@[50; 65)
35 L_PAREN@[50; 51)
36 POS_FIELD@[51; 57)
37 PATH_TYPE@[51; 57)
38 PATH@[51; 57)
39 PATH_SEGMENT@[51; 57)
40 NAME_REF@[51; 57)
41 IDENT@[51; 57) "String"
42 COMMA@[57; 58)
43 WHITESPACE@[58; 59)
44 POS_FIELD@[59; 64)
45 PATH_TYPE@[59; 64)
46 PATH@[59; 64)
47 PATH_SEGMENT@[59; 64)
48 NAME_REF@[59; 64)
49 IDENT@[59; 64) "usize"
50 R_PAREN@[64; 65)
51 SEMI@[65; 66)
52 WHITESPACE@[66; 67)
53 STRUCT_DEF@[67; 105)
54 STRUCT_KW@[67; 73)
55 WHITESPACE@[73; 74)
56 NAME@[74; 77)
57 IDENT@[74; 77) "Foo"
58 WHITESPACE@[77; 78)
59 NAMED_FIELD_DEF_LIST@[78; 105)
60 L_CURLY@[78; 79)
61 WHITESPACE@[79; 84)
62 NAMED_FIELD_DEF@[84; 90)
63 NAME@[84; 85)
64 IDENT@[84; 85) "a"
65 COLON@[85; 86)
66 WHITESPACE@[86; 87)
67 PATH_TYPE@[87; 90)
68 PATH@[87; 90)
69 PATH_SEGMENT@[87; 90)
70 NAME_REF@[87; 90)
71 IDENT@[87; 90) "i32"
72 COMMA@[90; 91)
73 WHITESPACE@[91; 96)
74 NAMED_FIELD_DEF@[96; 102)
75 NAME@[96; 97)
76 IDENT@[96; 97) "b"
77 COLON@[97; 98)
78 WHITESPACE@[98; 99)
79 PATH_TYPE@[99; 102)
80 PATH@[99; 102)
81 PATH_SEGMENT@[99; 102)
82 NAME_REF@[99; 102)
83 IDENT@[99; 102) "f32"
84 COMMA@[102; 103)
85 WHITESPACE@[103; 104)
86 R_CURLY@[104; 105)
87 WHITESPACE@[105; 106)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs
new file mode 100644
index 000000000..b7dd610d8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs
@@ -0,0 +1,5 @@
1union Foo {}
2union Foo {
3 a: i32,
4 b: f32,
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt
new file mode 100644
index 000000000..e2e755414
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt
@@ -0,0 +1,46 @@
1ROOT@[0; 51)
2 STRUCT_DEF@[0; 12)
3 UNION_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 NAME@[6; 9)
6 IDENT@[6; 9) "Foo"
7 WHITESPACE@[9; 10)
8 NAMED_FIELD_DEF_LIST@[10; 12)
9 L_CURLY@[10; 11)
10 R_CURLY@[11; 12)
11 WHITESPACE@[12; 13)
12 STRUCT_DEF@[13; 50)
13 UNION_KW@[13; 18)
14 WHITESPACE@[18; 19)
15 NAME@[19; 22)
16 IDENT@[19; 22) "Foo"
17 WHITESPACE@[22; 23)
18 NAMED_FIELD_DEF_LIST@[23; 50)
19 L_CURLY@[23; 24)
20 WHITESPACE@[24; 29)
21 NAMED_FIELD_DEF@[29; 35)
22 NAME@[29; 30)
23 IDENT@[29; 30) "a"
24 COLON@[30; 31)
25 WHITESPACE@[31; 32)
26 PATH_TYPE@[32; 35)
27 PATH@[32; 35)
28 PATH_SEGMENT@[32; 35)
29 NAME_REF@[32; 35)
30 IDENT@[32; 35) "i32"
31 COMMA@[35; 36)
32 WHITESPACE@[36; 41)
33 NAMED_FIELD_DEF@[41; 47)
34 NAME@[41; 42)
35 IDENT@[41; 42) "b"
36 COLON@[42; 43)
37 WHITESPACE@[43; 44)
38 PATH_TYPE@[44; 47)
39 PATH@[44; 47)
40 PATH_SEGMENT@[44; 47)
41 NAME_REF@[44; 47)
42 IDENT@[44; 47) "f32"
43 COMMA@[47; 48)
44 WHITESPACE@[48; 49)
45 R_CURLY@[49; 50)
46 WHITESPACE@[50; 51)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0000_empty.rs b/crates/ra_syntax/tests/data/parser/ok/0000_empty.rs
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0000_empty.rs
diff --git a/crates/ra_syntax/tests/data/parser/ok/0000_empty.txt b/crates/ra_syntax/tests/data/parser/ok/0000_empty.txt
new file mode 100644
index 000000000..9f505ee96
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0000_empty.txt
@@ -0,0 +1 @@
ROOT@[0; 0)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs
new file mode 100644
index 000000000..512aeb3e7
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs
@@ -0,0 +1,3 @@
1struct S<T: Copy> {
2 f: T,
3}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt
new file mode 100644
index 000000000..aa2f1b712
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt
@@ -0,0 +1,37 @@
1ROOT@[0; 32)
2 STRUCT_DEF@[0; 31)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 TYPE_PARAM_LIST@[8; 17)
8 L_ANGLE@[8; 9)
9 TYPE_PARAM@[9; 16)
10 NAME@[9; 10)
11 IDENT@[9; 10) "T"
12 COLON@[10; 11)
13 WHITESPACE@[11; 12)
14 PATH_TYPE@[12; 16)
15 PATH@[12; 16)
16 PATH_SEGMENT@[12; 16)
17 NAME_REF@[12; 16)
18 IDENT@[12; 16) "Copy"
19 R_ANGLE@[16; 17)
20 WHITESPACE@[17; 18)
21 NAMED_FIELD_DEF_LIST@[18; 31)
22 L_CURLY@[18; 19)
23 WHITESPACE@[19; 24)
24 NAMED_FIELD_DEF@[24; 28)
25 NAME@[24; 25)
26 IDENT@[24; 25) "f"
27 COLON@[25; 26)
28 WHITESPACE@[26; 27)
29 PATH_TYPE@[27; 28)
30 PATH@[27; 28)
31 PATH_SEGMENT@[27; 28)
32 NAME_REF@[27; 28)
33 IDENT@[27; 28) "T"
34 COMMA@[28; 29)
35 WHITESPACE@[29; 30)
36 R_CURLY@[30; 31)
37 WHITESPACE@[31; 32)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs
new file mode 100644
index 000000000..cc3866d25
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs
@@ -0,0 +1,3 @@
1struct S {
2 foo: u32
3} \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt
new file mode 100644
index 000000000..0b65387ef
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt
@@ -0,0 +1,22 @@
1ROOT@[0; 25)
2 STRUCT_DEF@[0; 25)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "S"
7 WHITESPACE@[8; 9)
8 NAMED_FIELD_DEF_LIST@[9; 25)
9 L_CURLY@[9; 10)
10 WHITESPACE@[10; 15)
11 NAMED_FIELD_DEF@[15; 23)
12 NAME@[15; 18)
13 IDENT@[15; 18) "foo"
14 COLON@[18; 19)
15 WHITESPACE@[19; 20)
16 PATH_TYPE@[20; 23)
17 PATH@[20; 23)
18 PATH_SEGMENT@[20; 23)
19 NAME_REF@[20; 23)
20 IDENT@[20; 23) "u32"
21 WHITESPACE@[23; 24)
22 R_CURLY@[24; 25)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs
new file mode 100644
index 000000000..53dc9e617
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs
@@ -0,0 +1 @@
#!/use/bin/env rusti \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt
new file mode 100644
index 000000000..bb8874ead
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt
@@ -0,0 +1,2 @@
1ROOT@[0; 20)
2 SHEBANG@[0; 20)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs
new file mode 100644
index 000000000..03210551c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs
@@ -0,0 +1,2 @@
1fn foo() {
2}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt
new file mode 100644
index 000000000..8ed92f2a4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt
@@ -0,0 +1,15 @@
1ROOT@[0; 13)
2 FN_DEF@[0; 12)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 12)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 11)
14 R_CURLY@[11; 12)
15 WHITESPACE@[12; 13)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs
new file mode 100644
index 000000000..e81f8b1e8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs
@@ -0,0 +1,10 @@
1#![attr]
2#![attr(true)]
3#![attr(ident)]
4#![attr(ident, 100, true, "true", ident = 100, ident = "hello", ident(100))]
5#![attr(100)]
6#![attr(enabled = true)]
7#![enabled(true)]
8#![attr("hello")]
9#![repr(C, align = 4)]
10#![repr(C, align(4))] \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt
new file mode 100644
index 000000000..2b64c497f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt
@@ -0,0 +1,164 @@
1ROOT@[0; 236)
2 ATTR@[0; 8)
3 POUND@[0; 1)
4 EXCL@[1; 2)
5 TOKEN_TREE@[2; 8)
6 L_BRACK@[2; 3)
7 IDENT@[3; 7) "attr"
8 R_BRACK@[7; 8)
9 WHITESPACE@[8; 9)
10 ATTR@[9; 23)
11 POUND@[9; 10)
12 EXCL@[10; 11)
13 TOKEN_TREE@[11; 23)
14 L_BRACK@[11; 12)
15 IDENT@[12; 16) "attr"
16 TOKEN_TREE@[16; 22)
17 L_PAREN@[16; 17)
18 TRUE_KW@[17; 21)
19 R_PAREN@[21; 22)
20 R_BRACK@[22; 23)
21 WHITESPACE@[23; 24)
22 ATTR@[24; 39)
23 POUND@[24; 25)
24 EXCL@[25; 26)
25 TOKEN_TREE@[26; 39)
26 L_BRACK@[26; 27)
27 IDENT@[27; 31) "attr"
28 TOKEN_TREE@[31; 38)
29 L_PAREN@[31; 32)
30 IDENT@[32; 37) "ident"
31 R_PAREN@[37; 38)
32 R_BRACK@[38; 39)
33 WHITESPACE@[39; 40)
34 ATTR@[40; 116)
35 POUND@[40; 41)
36 EXCL@[41; 42)
37 TOKEN_TREE@[42; 116)
38 L_BRACK@[42; 43)
39 IDENT@[43; 47) "attr"
40 TOKEN_TREE@[47; 115)
41 L_PAREN@[47; 48)
42 IDENT@[48; 53) "ident"
43 COMMA@[53; 54)
44 WHITESPACE@[54; 55)
45 INT_NUMBER@[55; 58) "100"
46 COMMA@[58; 59)
47 WHITESPACE@[59; 60)
48 TRUE_KW@[60; 64)
49 COMMA@[64; 65)
50 WHITESPACE@[65; 66)
51 STRING@[66; 72)
52 COMMA@[72; 73)
53 WHITESPACE@[73; 74)
54 IDENT@[74; 79) "ident"
55 WHITESPACE@[79; 80)
56 EQ@[80; 81)
57 WHITESPACE@[81; 82)
58 INT_NUMBER@[82; 85) "100"
59 COMMA@[85; 86)
60 WHITESPACE@[86; 87)
61 IDENT@[87; 92) "ident"
62 WHITESPACE@[92; 93)
63 EQ@[93; 94)
64 WHITESPACE@[94; 95)
65 STRING@[95; 102)
66 COMMA@[102; 103)
67 WHITESPACE@[103; 104)
68 IDENT@[104; 109) "ident"
69 TOKEN_TREE@[109; 114)
70 L_PAREN@[109; 110)
71 INT_NUMBER@[110; 113) "100"
72 R_PAREN@[113; 114)
73 R_PAREN@[114; 115)
74 R_BRACK@[115; 116)
75 WHITESPACE@[116; 117)
76 ATTR@[117; 130)
77 POUND@[117; 118)
78 EXCL@[118; 119)
79 TOKEN_TREE@[119; 130)
80 L_BRACK@[119; 120)
81 IDENT@[120; 124) "attr"
82 TOKEN_TREE@[124; 129)
83 L_PAREN@[124; 125)
84 INT_NUMBER@[125; 128) "100"
85 R_PAREN@[128; 129)
86 R_BRACK@[129; 130)
87 WHITESPACE@[130; 131)
88 ATTR@[131; 155)
89 POUND@[131; 132)
90 EXCL@[132; 133)
91 TOKEN_TREE@[133; 155)
92 L_BRACK@[133; 134)
93 IDENT@[134; 138) "attr"
94 TOKEN_TREE@[138; 154)
95 L_PAREN@[138; 139)
96 IDENT@[139; 146) "enabled"
97 WHITESPACE@[146; 147)
98 EQ@[147; 148)
99 WHITESPACE@[148; 149)
100 TRUE_KW@[149; 153)
101 R_PAREN@[153; 154)
102 R_BRACK@[154; 155)
103 WHITESPACE@[155; 156)
104 ATTR@[156; 173)
105 POUND@[156; 157)
106 EXCL@[157; 158)
107 TOKEN_TREE@[158; 173)
108 L_BRACK@[158; 159)
109 IDENT@[159; 166) "enabled"
110 TOKEN_TREE@[166; 172)
111 L_PAREN@[166; 167)
112 TRUE_KW@[167; 171)
113 R_PAREN@[171; 172)
114 R_BRACK@[172; 173)
115 WHITESPACE@[173; 174)
116 ATTR@[174; 191)
117 POUND@[174; 175)
118 EXCL@[175; 176)
119 TOKEN_TREE@[176; 191)
120 L_BRACK@[176; 177)
121 IDENT@[177; 181) "attr"
122 TOKEN_TREE@[181; 190)
123 L_PAREN@[181; 182)
124 STRING@[182; 189)
125 R_PAREN@[189; 190)
126 R_BRACK@[190; 191)
127 WHITESPACE@[191; 192)
128 ATTR@[192; 214)
129 POUND@[192; 193)
130 EXCL@[193; 194)
131 TOKEN_TREE@[194; 214)
132 L_BRACK@[194; 195)
133 IDENT@[195; 199) "repr"
134 TOKEN_TREE@[199; 213)
135 L_PAREN@[199; 200)
136 IDENT@[200; 201) "C"
137 COMMA@[201; 202)
138 WHITESPACE@[202; 203)
139 IDENT@[203; 208) "align"
140 WHITESPACE@[208; 209)
141 EQ@[209; 210)
142 WHITESPACE@[210; 211)
143 INT_NUMBER@[211; 212) "4"
144 R_PAREN@[212; 213)
145 R_BRACK@[213; 214)
146 WHITESPACE@[214; 215)
147 ATTR@[215; 236)
148 POUND@[215; 216)
149 EXCL@[216; 217)
150 TOKEN_TREE@[217; 236)
151 L_BRACK@[217; 218)
152 IDENT@[218; 222) "repr"
153 TOKEN_TREE@[222; 235)
154 L_PAREN@[222; 223)
155 IDENT@[223; 224) "C"
156 COMMA@[224; 225)
157 WHITESPACE@[225; 226)
158 IDENT@[226; 231) "align"
159 TOKEN_TREE@[231; 234)
160 L_PAREN@[231; 232)
161 INT_NUMBER@[232; 233) "4"
162 R_PAREN@[233; 234)
163 R_PAREN@[234; 235)
164 R_BRACK@[235; 236)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs
new file mode 100644
index 000000000..3ce336676
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs
@@ -0,0 +1,2 @@
1extern crate foo;
2extern crate foo as bar;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt
new file mode 100644
index 000000000..12193397e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt
@@ -0,0 +1,25 @@
1ROOT@[0; 43)
2 EXTERN_CRATE_ITEM@[0; 17)
3 EXTERN_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 CRATE_KW@[7; 12)
6 WHITESPACE@[12; 13)
7 NAME@[13; 16)
8 IDENT@[13; 16) "foo"
9 SEMI@[16; 17)
10 WHITESPACE@[17; 18)
11 EXTERN_CRATE_ITEM@[18; 42)
12 EXTERN_KW@[18; 24)
13 WHITESPACE@[24; 25)
14 CRATE_KW@[25; 30)
15 WHITESPACE@[30; 31)
16 NAME@[31; 34)
17 IDENT@[31; 34) "foo"
18 WHITESPACE@[34; 35)
19 ALIAS@[35; 41)
20 AS_KW@[35; 37)
21 WHITESPACE@[37; 38)
22 NAME@[38; 41)
23 IDENT@[38; 41) "bar"
24 SEMI@[41; 42)
25 WHITESPACE@[42; 43)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs
new file mode 100644
index 000000000..d22993bc1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs
@@ -0,0 +1,17 @@
1mod a;
2
3mod b {
4}
5
6mod c {
7 fn foo() {
8 }
9 struct S {}
10}
11
12mod d {
13 #![attr]
14 mod e;
15 mod f {
16 }
17} \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt
new file mode 100644
index 000000000..c790f8431
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt
@@ -0,0 +1,90 @@
1ROOT@[0; 118)
2 MODULE@[0; 6)
3 MOD_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 NAME@[4; 5)
6 IDENT@[4; 5) "a"
7 SEMI@[5; 6)
8 WHITESPACE@[6; 8)
9 MODULE@[8; 17)
10 MOD_KW@[8; 11)
11 WHITESPACE@[11; 12)
12 NAME@[12; 13)
13 IDENT@[12; 13) "b"
14 WHITESPACE@[13; 14)
15 ITEM_LIST@[14; 17)
16 L_CURLY@[14; 15)
17 WHITESPACE@[15; 16)
18 R_CURLY@[16; 17)
19 WHITESPACE@[17; 19)
20 MODULE@[19; 65)
21 MOD_KW@[19; 22)
22 WHITESPACE@[22; 23)
23 NAME@[23; 24)
24 IDENT@[23; 24) "c"
25 WHITESPACE@[24; 25)
26 ITEM_LIST@[25; 65)
27 L_CURLY@[25; 26)
28 WHITESPACE@[26; 31)
29 FN_DEF@[31; 47)
30 FN_KW@[31; 33)
31 WHITESPACE@[33; 34)
32 NAME@[34; 37)
33 IDENT@[34; 37) "foo"
34 PARAM_LIST@[37; 39)
35 L_PAREN@[37; 38)
36 R_PAREN@[38; 39)
37 WHITESPACE@[39; 40)
38 BLOCK@[40; 47)
39 L_CURLY@[40; 41)
40 WHITESPACE@[41; 46)
41 R_CURLY@[46; 47)
42 WHITESPACE@[47; 52)
43 STRUCT_DEF@[52; 63)
44 STRUCT_KW@[52; 58)
45 WHITESPACE@[58; 59)
46 NAME@[59; 60)
47 IDENT@[59; 60) "S"
48 WHITESPACE@[60; 61)
49 NAMED_FIELD_DEF_LIST@[61; 63)
50 L_CURLY@[61; 62)
51 R_CURLY@[62; 63)
52 WHITESPACE@[63; 64)
53 R_CURLY@[64; 65)
54 WHITESPACE@[65; 67)
55 MODULE@[67; 118)
56 MOD_KW@[67; 70)
57 WHITESPACE@[70; 71)
58 NAME@[71; 72)
59 IDENT@[71; 72) "d"
60 WHITESPACE@[72; 73)
61 ITEM_LIST@[73; 118)
62 L_CURLY@[73; 74)
63 WHITESPACE@[74; 79)
64 ATTR@[79; 87)
65 POUND@[79; 80)
66 EXCL@[80; 81)
67 TOKEN_TREE@[81; 87)
68 L_BRACK@[81; 82)
69 IDENT@[82; 86) "attr"
70 R_BRACK@[86; 87)
71 WHITESPACE@[87; 92)
72 MODULE@[92; 98)
73 MOD_KW@[92; 95)
74 WHITESPACE@[95; 96)
75 NAME@[96; 97)
76 IDENT@[96; 97) "e"
77 SEMI@[97; 98)
78 WHITESPACE@[98; 103)
79 MODULE@[103; 116)
80 MOD_KW@[103; 106)
81 WHITESPACE@[106; 107)
82 NAME@[107; 108)
83 IDENT@[107; 108) "f"
84 WHITESPACE@[108; 109)
85 ITEM_LIST@[109; 116)
86 L_CURLY@[109; 110)
87 WHITESPACE@[110; 115)
88 R_CURLY@[115; 116)
89 WHITESPACE@[116; 117)
90 R_CURLY@[117; 118)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs
new file mode 100644
index 000000000..05a6aff83
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs
@@ -0,0 +1,2 @@
1use foo;
2use ::bar; \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt
new file mode 100644
index 000000000..4bcd15357
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt
@@ -0,0 +1,21 @@
1ROOT@[0; 19)
2 USE_ITEM@[0; 8)
3 USE_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 USE_TREE@[4; 7)
6 PATH@[4; 7)
7 PATH_SEGMENT@[4; 7)
8 NAME_REF@[4; 7)
9 IDENT@[4; 7) "foo"
10 SEMI@[7; 8)
11 WHITESPACE@[8; 9)
12 USE_ITEM@[9; 19)
13 USE_KW@[9; 12)
14 WHITESPACE@[12; 13)
15 USE_TREE@[13; 18)
16 PATH@[13; 18)
17 PATH_SEGMENT@[13; 18)
18 COLONCOLON@[13; 15)
19 NAME_REF@[15; 18)
20 IDENT@[15; 18) "bar"
21 SEMI@[18; 19)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs
new file mode 100644
index 000000000..1e71b7a6c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs
@@ -0,0 +1,2 @@
1use ::foo::bar::baz;
2use foo::bar::baz;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt
new file mode 100644
index 000000000..f76ea1a35
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt
@@ -0,0 +1,42 @@
1ROOT@[0; 40)
2 USE_ITEM@[0; 20)
3 USE_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 USE_TREE@[4; 19)
6 PATH@[4; 19)
7 PATH@[4; 14)
8 PATH@[4; 9)
9 PATH_SEGMENT@[4; 9)
10 COLONCOLON@[4; 6)
11 NAME_REF@[6; 9)
12 IDENT@[6; 9) "foo"
13 COLONCOLON@[9; 11)
14 PATH_SEGMENT@[11; 14)
15 NAME_REF@[11; 14)
16 IDENT@[11; 14) "bar"
17 COLONCOLON@[14; 16)
18 PATH_SEGMENT@[16; 19)
19 NAME_REF@[16; 19)
20 IDENT@[16; 19) "baz"
21 SEMI@[19; 20)
22 WHITESPACE@[20; 21)
23 USE_ITEM@[21; 39)
24 USE_KW@[21; 24)
25 WHITESPACE@[24; 25)
26 USE_TREE@[25; 38)
27 PATH@[25; 38)
28 PATH@[25; 33)
29 PATH@[25; 28)
30 PATH_SEGMENT@[25; 28)
31 NAME_REF@[25; 28)
32 IDENT@[25; 28) "foo"
33 COLONCOLON@[28; 30)
34 PATH_SEGMENT@[30; 33)
35 NAME_REF@[30; 33)
36 IDENT@[30; 33) "bar"
37 COLONCOLON@[33; 35)
38 PATH_SEGMENT@[35; 38)
39 NAME_REF@[35; 38)
40 IDENT@[35; 38) "baz"
41 SEMI@[38; 39)
42 WHITESPACE@[39; 40)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs
new file mode 100644
index 000000000..8b80c0d90
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs
@@ -0,0 +1,3 @@
1#[cfg(test)]
2#[ignore]
3fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt
new file mode 100644
index 000000000..203a07193
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt
@@ -0,0 +1,32 @@
1ROOT@[0; 35)
2 FN_DEF@[0; 34)
3 ATTR@[0; 12)
4 POUND@[0; 1)
5 TOKEN_TREE@[1; 12)
6 L_BRACK@[1; 2)
7 IDENT@[2; 5) "cfg"
8 TOKEN_TREE@[5; 11)
9 L_PAREN@[5; 6)
10 IDENT@[6; 10) "test"
11 R_PAREN@[10; 11)
12 R_BRACK@[11; 12)
13 WHITESPACE@[12; 13)
14 ATTR@[13; 22)
15 POUND@[13; 14)
16 TOKEN_TREE@[14; 22)
17 L_BRACK@[14; 15)
18 IDENT@[15; 21) "ignore"
19 R_BRACK@[21; 22)
20 WHITESPACE@[22; 23)
21 FN_KW@[23; 25)
22 WHITESPACE@[25; 26)
23 NAME@[26; 29)
24 IDENT@[26; 29) "foo"
25 PARAM_LIST@[29; 31)
26 L_PAREN@[29; 30)
27 R_PAREN@[30; 31)
28 WHITESPACE@[31; 32)
29 BLOCK@[32; 34)
30 L_CURLY@[32; 33)
31 R_CURLY@[33; 34)
32 WHITESPACE@[34; 35)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs
new file mode 100644
index 000000000..75b1db121
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs
@@ -0,0 +1,5 @@
1fn a() {}
2pub fn b() {}
3pub(crate) fn c() {}
4pub(super) fn d() {}
5pub(in foo::bar::baz) fn e() {}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt
new file mode 100644
index 000000000..66901af54
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt
@@ -0,0 +1,102 @@
1ROOT@[0; 98)
2 FN_DEF@[0; 9)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 4)
6 IDENT@[3; 4) "a"
7 PARAM_LIST@[4; 6)
8 L_PAREN@[4; 5)
9 R_PAREN@[5; 6)
10 WHITESPACE@[6; 7)
11 BLOCK@[7; 9)
12 L_CURLY@[7; 8)
13 R_CURLY@[8; 9)
14 WHITESPACE@[9; 10)
15 FN_DEF@[10; 23)
16 VISIBILITY@[10; 13)
17 PUB_KW@[10; 13)
18 WHITESPACE@[13; 14)
19 FN_KW@[14; 16)
20 WHITESPACE@[16; 17)
21 NAME@[17; 18)
22 IDENT@[17; 18) "b"
23 PARAM_LIST@[18; 20)
24 L_PAREN@[18; 19)
25 R_PAREN@[19; 20)
26 WHITESPACE@[20; 21)
27 BLOCK@[21; 23)
28 L_CURLY@[21; 22)
29 R_CURLY@[22; 23)
30 WHITESPACE@[23; 24)
31 FN_DEF@[24; 44)
32 VISIBILITY@[24; 34)
33 PUB_KW@[24; 27)
34 L_PAREN@[27; 28)
35 CRATE_KW@[28; 33)
36 R_PAREN@[33; 34)
37 WHITESPACE@[34; 35)
38 FN_KW@[35; 37)
39 WHITESPACE@[37; 38)
40 NAME@[38; 39)
41 IDENT@[38; 39) "c"
42 PARAM_LIST@[39; 41)
43 L_PAREN@[39; 40)
44 R_PAREN@[40; 41)
45 WHITESPACE@[41; 42)
46 BLOCK@[42; 44)
47 L_CURLY@[42; 43)
48 R_CURLY@[43; 44)
49 WHITESPACE@[44; 45)
50 FN_DEF@[45; 65)
51 VISIBILITY@[45; 55)
52 PUB_KW@[45; 48)
53 L_PAREN@[48; 49)
54 SUPER_KW@[49; 54)
55 R_PAREN@[54; 55)
56 WHITESPACE@[55; 56)
57 FN_KW@[56; 58)
58 WHITESPACE@[58; 59)
59 NAME@[59; 60)
60 IDENT@[59; 60) "d"
61 PARAM_LIST@[60; 62)
62 L_PAREN@[60; 61)
63 R_PAREN@[61; 62)
64 WHITESPACE@[62; 63)
65 BLOCK@[63; 65)
66 L_CURLY@[63; 64)
67 R_CURLY@[64; 65)
68 WHITESPACE@[65; 66)
69 FN_DEF@[66; 97)
70 VISIBILITY@[66; 87)
71 PUB_KW@[66; 69)
72 L_PAREN@[69; 70)
73 IN_KW@[70; 72)
74 WHITESPACE@[72; 73)
75 PATH@[73; 86)
76 PATH@[73; 81)
77 PATH@[73; 76)
78 PATH_SEGMENT@[73; 76)
79 NAME_REF@[73; 76)
80 IDENT@[73; 76) "foo"
81 COLONCOLON@[76; 78)
82 PATH_SEGMENT@[78; 81)
83 NAME_REF@[78; 81)
84 IDENT@[78; 81) "bar"
85 COLONCOLON@[81; 83)
86 PATH_SEGMENT@[83; 86)
87 NAME_REF@[83; 86)
88 IDENT@[83; 86) "baz"
89 R_PAREN@[86; 87)
90 WHITESPACE@[87; 88)
91 FN_KW@[88; 90)
92 WHITESPACE@[90; 91)
93 NAME@[91; 92)
94 IDENT@[91; 92) "e"
95 PARAM_LIST@[92; 94)
96 L_PAREN@[92; 93)
97 R_PAREN@[93; 94)
98 WHITESPACE@[94; 95)
99 BLOCK@[95; 97)
100 L_CURLY@[95; 96)
101 R_CURLY@[96; 97)
102 WHITESPACE@[97; 98)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs
new file mode 100644
index 000000000..faf6a42c7
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs
@@ -0,0 +1,3 @@
1use self::foo;
2use super::super::bar;
3use ::self::a::super::bar;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt
new file mode 100644
index 000000000..95be4f75d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt
@@ -0,0 +1,57 @@
1ROOT@[0; 65)
2 USE_ITEM@[0; 14)
3 USE_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 USE_TREE@[4; 13)
6 PATH@[4; 13)
7 PATH@[4; 8)
8 PATH_SEGMENT@[4; 8)
9 SELF_KW@[4; 8)
10 COLONCOLON@[8; 10)
11 PATH_SEGMENT@[10; 13)
12 NAME_REF@[10; 13)
13 IDENT@[10; 13) "foo"
14 SEMI@[13; 14)
15 WHITESPACE@[14; 15)
16 USE_ITEM@[15; 37)
17 USE_KW@[15; 18)
18 WHITESPACE@[18; 19)
19 USE_TREE@[19; 36)
20 PATH@[19; 36)
21 PATH@[19; 31)
22 PATH@[19; 24)
23 PATH_SEGMENT@[19; 24)
24 SUPER_KW@[19; 24)
25 COLONCOLON@[24; 26)
26 PATH_SEGMENT@[26; 31)
27 SUPER_KW@[26; 31)
28 COLONCOLON@[31; 33)
29 PATH_SEGMENT@[33; 36)
30 NAME_REF@[33; 36)
31 IDENT@[33; 36) "bar"
32 SEMI@[36; 37)
33 WHITESPACE@[37; 38)
34 USE_ITEM@[38; 64)
35 USE_KW@[38; 41)
36 WHITESPACE@[41; 42)
37 USE_TREE@[42; 63)
38 PATH@[42; 63)
39 PATH@[42; 58)
40 PATH@[42; 51)
41 PATH@[42; 48)
42 PATH_SEGMENT@[42; 48)
43 COLONCOLON@[42; 44)
44 SELF_KW@[44; 48)
45 COLONCOLON@[48; 50)
46 PATH_SEGMENT@[50; 51)
47 NAME_REF@[50; 51)
48 IDENT@[50; 51) "a"
49 COLONCOLON@[51; 53)
50 PATH_SEGMENT@[53; 58)
51 SUPER_KW@[53; 58)
52 COLONCOLON@[58; 60)
53 PATH_SEGMENT@[60; 63)
54 NAME_REF@[60; 63)
55 IDENT@[60; 63) "bar"
56 SEMI@[63; 64)
57 WHITESPACE@[64; 65)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs
new file mode 100644
index 000000000..5e4aa3a33
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs
@@ -0,0 +1,7 @@
1use *;
2use ::*;
3use ::{};
4use {};
5use foo::*;
6use foo::{};
7use ::foo::{a, b, c};
diff --git a/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt
new file mode 100644
index 000000000..4aa539159
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt
@@ -0,0 +1,95 @@
1ROOT@[0; 81)
2 USE_ITEM@[0; 6)
3 USE_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 USE_TREE@[4; 5)
6 STAR@[4; 5)
7 SEMI@[5; 6)
8 WHITESPACE@[6; 7)
9 USE_ITEM@[7; 15)
10 USE_KW@[7; 10)
11 WHITESPACE@[10; 11)
12 USE_TREE@[11; 14)
13 COLONCOLON@[11; 13)
14 STAR@[13; 14)
15 SEMI@[14; 15)
16 WHITESPACE@[15; 16)
17 USE_ITEM@[16; 25)
18 USE_KW@[16; 19)
19 WHITESPACE@[19; 20)
20 USE_TREE@[20; 24)
21 COLONCOLON@[20; 22)
22 USE_TREE_LIST@[22; 24)
23 L_CURLY@[22; 23)
24 R_CURLY@[23; 24)
25 SEMI@[24; 25)
26 WHITESPACE@[25; 26)
27 USE_ITEM@[26; 33)
28 USE_KW@[26; 29)
29 WHITESPACE@[29; 30)
30 USE_TREE@[30; 32)
31 USE_TREE_LIST@[30; 32)
32 L_CURLY@[30; 31)
33 R_CURLY@[31; 32)
34 SEMI@[32; 33)
35 WHITESPACE@[33; 34)
36 USE_ITEM@[34; 45)
37 USE_KW@[34; 37)
38 WHITESPACE@[37; 38)
39 USE_TREE@[38; 44)
40 PATH@[38; 41)
41 PATH_SEGMENT@[38; 41)
42 NAME_REF@[38; 41)
43 IDENT@[38; 41) "foo"
44 COLONCOLON@[41; 43)
45 STAR@[43; 44)
46 SEMI@[44; 45)
47 WHITESPACE@[45; 46)
48 USE_ITEM@[46; 58)
49 USE_KW@[46; 49)
50 WHITESPACE@[49; 50)
51 USE_TREE@[50; 57)
52 PATH@[50; 53)
53 PATH_SEGMENT@[50; 53)
54 NAME_REF@[50; 53)
55 IDENT@[50; 53) "foo"
56 COLONCOLON@[53; 55)
57 USE_TREE_LIST@[55; 57)
58 L_CURLY@[55; 56)
59 R_CURLY@[56; 57)
60 SEMI@[57; 58)
61 WHITESPACE@[58; 59)
62 USE_ITEM@[59; 80)
63 USE_KW@[59; 62)
64 WHITESPACE@[62; 63)
65 USE_TREE@[63; 79)
66 PATH@[63; 68)
67 PATH_SEGMENT@[63; 68)
68 COLONCOLON@[63; 65)
69 NAME_REF@[65; 68)
70 IDENT@[65; 68) "foo"
71 COLONCOLON@[68; 70)
72 USE_TREE_LIST@[70; 79)
73 L_CURLY@[70; 71)
74 USE_TREE@[71; 72)
75 PATH@[71; 72)
76 PATH_SEGMENT@[71; 72)
77 NAME_REF@[71; 72)
78 IDENT@[71; 72) "a"
79 COMMA@[72; 73)
80 WHITESPACE@[73; 74)
81 USE_TREE@[74; 75)
82 PATH@[74; 75)
83 PATH_SEGMENT@[74; 75)
84 NAME_REF@[74; 75)
85 IDENT@[74; 75) "b"
86 COMMA@[75; 76)
87 WHITESPACE@[76; 77)
88 USE_TREE@[77; 78)
89 PATH@[77; 78)
90 PATH_SEGMENT@[77; 78)
91 NAME_REF@[77; 78)
92 IDENT@[77; 78) "c"
93 R_CURLY@[78; 79)
94 SEMI@[79; 80)
95 WHITESPACE@[80; 81)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs
new file mode 100644
index 000000000..46a0783a2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs
@@ -0,0 +1,2 @@
1use foo as bar;
2use foo::{a as b, *, ::*, ::foo as x};
diff --git a/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt
new file mode 100644
index 000000000..aa4ef3715
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt
@@ -0,0 +1,65 @@
1ROOT@[0; 55)
2 USE_ITEM@[0; 15)
3 USE_KW@[0; 3)
4 WHITESPACE@[3; 4)
5 USE_TREE@[4; 14)
6 PATH@[4; 7)
7 PATH_SEGMENT@[4; 7)
8 NAME_REF@[4; 7)
9 IDENT@[4; 7) "foo"
10 WHITESPACE@[7; 8)
11 ALIAS@[8; 14)
12 AS_KW@[8; 10)
13 WHITESPACE@[10; 11)
14 NAME@[11; 14)
15 IDENT@[11; 14) "bar"
16 SEMI@[14; 15)
17 WHITESPACE@[15; 16)
18 USE_ITEM@[16; 54)
19 USE_KW@[16; 19)
20 WHITESPACE@[19; 20)
21 USE_TREE@[20; 53)
22 PATH@[20; 23)
23 PATH_SEGMENT@[20; 23)
24 NAME_REF@[20; 23)
25 IDENT@[20; 23) "foo"
26 COLONCOLON@[23; 25)
27 USE_TREE_LIST@[25; 53)
28 L_CURLY@[25; 26)
29 USE_TREE@[26; 32)
30 PATH@[26; 27)
31 PATH_SEGMENT@[26; 27)
32 NAME_REF@[26; 27)
33 IDENT@[26; 27) "a"
34 WHITESPACE@[27; 28)
35 ALIAS@[28; 32)
36 AS_KW@[28; 30)
37 WHITESPACE@[30; 31)
38 NAME@[31; 32)
39 IDENT@[31; 32) "b"
40 COMMA@[32; 33)
41 WHITESPACE@[33; 34)
42 USE_TREE@[34; 35)
43 STAR@[34; 35)
44 COMMA@[35; 36)
45 WHITESPACE@[36; 37)
46 USE_TREE@[37; 40)
47 COLONCOLON@[37; 39)
48 STAR@[39; 40)
49 COMMA@[40; 41)
50 WHITESPACE@[41; 42)
51 USE_TREE@[42; 52)
52 PATH@[42; 47)
53 PATH_SEGMENT@[42; 47)
54 COLONCOLON@[42; 44)
55 NAME_REF@[44; 47)
56 IDENT@[44; 47) "foo"
57 WHITESPACE@[47; 48)
58 ALIAS@[48; 52)
59 AS_KW@[48; 50)
60 WHITESPACE@[50; 51)
61 NAME@[51; 52)
62 IDENT@[51; 52) "x"
63 R_CURLY@[52; 53)
64 SEMI@[53; 54)
65 WHITESPACE@[54; 55)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs
new file mode 100644
index 000000000..69638350c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs
@@ -0,0 +1,10 @@
1struct A;
2struct B {}
3struct C();
4
5struct D {
6 a: u32,
7 pub b: u32
8}
9
10struct E(pub x, y,);
diff --git a/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt
new file mode 100644
index 000000000..349481157
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt
@@ -0,0 +1,93 @@
1ROOT@[0; 97)
2 STRUCT_DEF@[0; 9)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "A"
7 SEMI@[8; 9)
8 WHITESPACE@[9; 10)
9 STRUCT_DEF@[10; 21)
10 STRUCT_KW@[10; 16)
11 WHITESPACE@[16; 17)
12 NAME@[17; 18)
13 IDENT@[17; 18) "B"
14 WHITESPACE@[18; 19)
15 NAMED_FIELD_DEF_LIST@[19; 21)
16 L_CURLY@[19; 20)
17 R_CURLY@[20; 21)
18 WHITESPACE@[21; 22)
19 STRUCT_DEF@[22; 33)
20 STRUCT_KW@[22; 28)
21 WHITESPACE@[28; 29)
22 NAME@[29; 30)
23 IDENT@[29; 30) "C"
24 POS_FIELD_LIST@[30; 32)
25 L_PAREN@[30; 31)
26 R_PAREN@[31; 32)
27 SEMI@[32; 33)
28 WHITESPACE@[33; 35)
29 STRUCT_DEF@[35; 74)
30 STRUCT_KW@[35; 41)
31 WHITESPACE@[41; 42)
32 NAME@[42; 43)
33 IDENT@[42; 43) "D"
34 WHITESPACE@[43; 44)
35 NAMED_FIELD_DEF_LIST@[44; 74)
36 L_CURLY@[44; 45)
37 WHITESPACE@[45; 50)
38 NAMED_FIELD_DEF@[50; 56)
39 NAME@[50; 51)
40 IDENT@[50; 51) "a"
41 COLON@[51; 52)
42 WHITESPACE@[52; 53)
43 PATH_TYPE@[53; 56)
44 PATH@[53; 56)
45 PATH_SEGMENT@[53; 56)
46 NAME_REF@[53; 56)
47 IDENT@[53; 56) "u32"
48 COMMA@[56; 57)
49 WHITESPACE@[57; 62)
50 NAMED_FIELD_DEF@[62; 72)
51 VISIBILITY@[62; 65)
52 PUB_KW@[62; 65)
53 WHITESPACE@[65; 66)
54 NAME@[66; 67)
55 IDENT@[66; 67) "b"
56 COLON@[67; 68)
57 WHITESPACE@[68; 69)
58 PATH_TYPE@[69; 72)
59 PATH@[69; 72)
60 PATH_SEGMENT@[69; 72)
61 NAME_REF@[69; 72)
62 IDENT@[69; 72) "u32"
63 WHITESPACE@[72; 73)
64 R_CURLY@[73; 74)
65 WHITESPACE@[74; 76)
66 STRUCT_DEF@[76; 96)
67 STRUCT_KW@[76; 82)
68 WHITESPACE@[82; 83)
69 NAME@[83; 84)
70 IDENT@[83; 84) "E"
71 POS_FIELD_LIST@[84; 95)
72 L_PAREN@[84; 85)
73 POS_FIELD@[85; 90)
74 VISIBILITY@[85; 88)
75 PUB_KW@[85; 88)
76 WHITESPACE@[88; 89)
77 PATH_TYPE@[89; 90)
78 PATH@[89; 90)
79 PATH_SEGMENT@[89; 90)
80 NAME_REF@[89; 90)
81 IDENT@[89; 90) "x"
82 COMMA@[90; 91)
83 WHITESPACE@[91; 92)
84 POS_FIELD@[92; 93)
85 PATH_TYPE@[92; 93)
86 PATH@[92; 93)
87 PATH_SEGMENT@[92; 93)
88 NAME_REF@[92; 93)
89 IDENT@[92; 93) "y"
90 COMMA@[93; 94)
91 R_PAREN@[94; 95)
92 SEMI@[95; 96)
93 WHITESPACE@[96; 97)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs
new file mode 100644
index 000000000..fe0a7bb97
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs
@@ -0,0 +1,2 @@
1#[foo(a,)]
2fn foo() {}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt
new file mode 100644
index 000000000..8cfd77256
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt
@@ -0,0 +1,26 @@
1ROOT@[0; 23)
2 FN_DEF@[0; 22)
3 ATTR@[0; 10)
4 POUND@[0; 1)
5 TOKEN_TREE@[1; 10)
6 L_BRACK@[1; 2)
7 IDENT@[2; 5) "foo"
8 TOKEN_TREE@[5; 9)
9 L_PAREN@[5; 6)
10 IDENT@[6; 7) "a"
11 COMMA@[7; 8)
12 R_PAREN@[8; 9)
13 R_BRACK@[9; 10)
14 WHITESPACE@[10; 11)
15 FN_KW@[11; 13)
16 WHITESPACE@[13; 14)
17 NAME@[14; 17)
18 IDENT@[14; 17) "foo"
19 PARAM_LIST@[17; 19)
20 L_PAREN@[17; 18)
21 R_PAREN@[18; 19)
22 WHITESPACE@[19; 20)
23 BLOCK@[20; 22)
24 L_CURLY@[20; 21)
25 R_CURLY@[21; 22)
26 WHITESPACE@[22; 23)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs
new file mode 100644
index 000000000..88c544923
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs
@@ -0,0 +1,17 @@
1struct S1<T>;
2struct S2<T>(u32);
3struct S3<T> { u: u32 }
4
5struct S4<>;
6struct S5<'a>;
7struct S6<'a:>;
8struct S7<'a: 'b>;
9struct S8<'a: 'b + >;
10struct S9<'a: 'b + 'c>;
11struct S10<'a,>;
12struct S11<'a, 'b>;
13struct S12<'a: 'b+, 'b: 'c,>;
14
15struct S13<T>;
16struct S14<T, U>;
17struct S15<'a, T, U>;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt
new file mode 100644
index 000000000..a98e823f6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt
@@ -0,0 +1,257 @@
1ROOT@[0; 290)
2 STRUCT_DEF@[0; 13)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 9)
6 IDENT@[7; 9) "S1"
7 TYPE_PARAM_LIST@[9; 12)
8 L_ANGLE@[9; 10)
9 TYPE_PARAM@[10; 11)
10 NAME@[10; 11)
11 IDENT@[10; 11) "T"
12 R_ANGLE@[11; 12)
13 SEMI@[12; 13)
14 WHITESPACE@[13; 14)
15 STRUCT_DEF@[14; 32)
16 STRUCT_KW@[14; 20)
17 WHITESPACE@[20; 21)
18 NAME@[21; 23)
19 IDENT@[21; 23) "S2"
20 TYPE_PARAM_LIST@[23; 26)
21 L_ANGLE@[23; 24)
22 TYPE_PARAM@[24; 25)
23 NAME@[24; 25)
24 IDENT@[24; 25) "T"
25 R_ANGLE@[25; 26)
26 POS_FIELD_LIST@[26; 31)
27 L_PAREN@[26; 27)
28 POS_FIELD@[27; 30)
29 PATH_TYPE@[27; 30)
30 PATH@[27; 30)
31 PATH_SEGMENT@[27; 30)
32 NAME_REF@[27; 30)
33 IDENT@[27; 30) "u32"
34 R_PAREN@[30; 31)
35 SEMI@[31; 32)
36 WHITESPACE@[32; 33)
37 STRUCT_DEF@[33; 56)
38 STRUCT_KW@[33; 39)
39 WHITESPACE@[39; 40)
40 NAME@[40; 42)
41 IDENT@[40; 42) "S3"
42 TYPE_PARAM_LIST@[42; 45)
43 L_ANGLE@[42; 43)
44 TYPE_PARAM@[43; 44)
45 NAME@[43; 44)
46 IDENT@[43; 44) "T"
47 R_ANGLE@[44; 45)
48 WHITESPACE@[45; 46)
49 NAMED_FIELD_DEF_LIST@[46; 56)
50 L_CURLY@[46; 47)
51 WHITESPACE@[47; 48)
52 NAMED_FIELD_DEF@[48; 54)
53 NAME@[48; 49)
54 IDENT@[48; 49) "u"
55 COLON@[49; 50)
56 WHITESPACE@[50; 51)
57 PATH_TYPE@[51; 54)
58 PATH@[51; 54)
59 PATH_SEGMENT@[51; 54)
60 NAME_REF@[51; 54)
61 IDENT@[51; 54) "u32"
62 WHITESPACE@[54; 55)
63 R_CURLY@[55; 56)
64 WHITESPACE@[56; 58)
65 STRUCT_DEF@[58; 70)
66 STRUCT_KW@[58; 64)
67 WHITESPACE@[64; 65)
68 NAME@[65; 67)
69 IDENT@[65; 67) "S4"
70 TYPE_PARAM_LIST@[67; 69)
71 L_ANGLE@[67; 68)
72 R_ANGLE@[68; 69)
73 SEMI@[69; 70)
74 WHITESPACE@[70; 71)
75 STRUCT_DEF@[71; 85)
76 STRUCT_KW@[71; 77)
77 WHITESPACE@[77; 78)
78 NAME@[78; 80)
79 IDENT@[78; 80) "S5"
80 TYPE_PARAM_LIST@[80; 84)
81 L_ANGLE@[80; 81)
82 LIFETIME_PARAM@[81; 83)
83 LIFETIME@[81; 83) "'a"
84 R_ANGLE@[83; 84)
85 SEMI@[84; 85)
86 WHITESPACE@[85; 86)
87 STRUCT_DEF@[86; 101)
88 STRUCT_KW@[86; 92)
89 WHITESPACE@[92; 93)
90 NAME@[93; 95)
91 IDENT@[93; 95) "S6"
92 TYPE_PARAM_LIST@[95; 100)
93 L_ANGLE@[95; 96)
94 LIFETIME_PARAM@[96; 99)
95 LIFETIME@[96; 98) "'a"
96 COLON@[98; 99)
97 R_ANGLE@[99; 100)
98 SEMI@[100; 101)
99 WHITESPACE@[101; 102)
100 STRUCT_DEF@[102; 120)
101 STRUCT_KW@[102; 108)
102 WHITESPACE@[108; 109)
103 NAME@[109; 111)
104 IDENT@[109; 111) "S7"
105 TYPE_PARAM_LIST@[111; 119)
106 L_ANGLE@[111; 112)
107 LIFETIME_PARAM@[112; 118)
108 LIFETIME@[112; 114) "'a"
109 COLON@[114; 115)
110 WHITESPACE@[115; 116)
111 LIFETIME@[116; 118) "'b"
112 R_ANGLE@[118; 119)
113 SEMI@[119; 120)
114 WHITESPACE@[120; 121)
115 STRUCT_DEF@[121; 142)
116 STRUCT_KW@[121; 127)
117 WHITESPACE@[127; 128)
118 NAME@[128; 130)
119 IDENT@[128; 130) "S8"
120 TYPE_PARAM_LIST@[130; 141)
121 L_ANGLE@[130; 131)
122 LIFETIME_PARAM@[131; 139)
123 LIFETIME@[131; 133) "'a"
124 COLON@[133; 134)
125 WHITESPACE@[134; 135)
126 LIFETIME@[135; 137) "'b"
127 WHITESPACE@[137; 138)
128 PLUS@[138; 139)
129 WHITESPACE@[139; 140)
130 R_ANGLE@[140; 141)
131 SEMI@[141; 142)
132 WHITESPACE@[142; 143)
133 STRUCT_DEF@[143; 166)
134 STRUCT_KW@[143; 149)
135 WHITESPACE@[149; 150)
136 NAME@[150; 152)
137 IDENT@[150; 152) "S9"
138 TYPE_PARAM_LIST@[152; 165)
139 L_ANGLE@[152; 153)
140 LIFETIME_PARAM@[153; 164)
141 LIFETIME@[153; 155) "'a"
142 COLON@[155; 156)
143 WHITESPACE@[156; 157)
144 LIFETIME@[157; 159) "'b"
145 WHITESPACE@[159; 160)
146 PLUS@[160; 161)
147 WHITESPACE@[161; 162)
148 LIFETIME@[162; 164) "'c"
149 R_ANGLE@[164; 165)
150 SEMI@[165; 166)
151 WHITESPACE@[166; 167)
152 STRUCT_DEF@[167; 183)
153 STRUCT_KW@[167; 173)
154 WHITESPACE@[173; 174)
155 NAME@[174; 177)
156 IDENT@[174; 177) "S10"
157 TYPE_PARAM_LIST@[177; 182)
158 L_ANGLE@[177; 178)
159 LIFETIME_PARAM@[178; 180)
160 LIFETIME@[178; 180) "'a"
161 COMMA@[180; 181)
162 R_ANGLE@[181; 182)
163 SEMI@[182; 183)
164 WHITESPACE@[183; 184)
165 STRUCT_DEF@[184; 203)
166 STRUCT_KW@[184; 190)
167 WHITESPACE@[190; 191)
168 NAME@[191; 194)
169 IDENT@[191; 194) "S11"
170 TYPE_PARAM_LIST@[194; 202)
171 L_ANGLE@[194; 195)
172 LIFETIME_PARAM@[195; 197)
173 LIFETIME@[195; 197) "'a"
174 COMMA@[197; 198)
175 WHITESPACE@[198; 199)
176 LIFETIME_PARAM@[199; 201)
177 LIFETIME@[199; 201) "'b"
178 R_ANGLE@[201; 202)
179 SEMI@[202; 203)
180 WHITESPACE@[203; 204)
181 STRUCT_DEF@[204; 233)
182 STRUCT_KW@[204; 210)
183 WHITESPACE@[210; 211)
184 NAME@[211; 214)
185 IDENT@[211; 214) "S12"
186 TYPE_PARAM_LIST@[214; 232)
187 L_ANGLE@[214; 215)
188 LIFETIME_PARAM@[215; 222)
189 LIFETIME@[215; 217) "'a"
190 COLON@[217; 218)
191 WHITESPACE@[218; 219)
192 LIFETIME@[219; 221) "'b"
193 PLUS@[221; 222)
194 COMMA@[222; 223)
195 WHITESPACE@[223; 224)
196 LIFETIME_PARAM@[224; 230)
197 LIFETIME@[224; 226) "'b"
198 COLON@[226; 227)
199 WHITESPACE@[227; 228)
200 LIFETIME@[228; 230) "'c"
201 COMMA@[230; 231)
202 R_ANGLE@[231; 232)
203 SEMI@[232; 233)
204 WHITESPACE@[233; 235)
205 STRUCT_DEF@[235; 249)
206 STRUCT_KW@[235; 241)
207 WHITESPACE@[241; 242)
208 NAME@[242; 245)
209 IDENT@[242; 245) "S13"
210 TYPE_PARAM_LIST@[245; 248)
211 L_ANGLE@[245; 246)
212 TYPE_PARAM@[246; 247)
213 NAME@[246; 247)
214 IDENT@[246; 247) "T"
215 R_ANGLE@[247; 248)
216 SEMI@[248; 249)
217 WHITESPACE@[249; 250)
218 STRUCT_DEF@[250; 267)
219 STRUCT_KW@[250; 256)
220 WHITESPACE@[256; 257)
221 NAME@[257; 260)
222 IDENT@[257; 260) "S14"
223 TYPE_PARAM_LIST@[260; 266)
224 L_ANGLE@[260; 261)
225 TYPE_PARAM@[261; 262)
226 NAME@[261; 262)
227 IDENT@[261; 262) "T"
228 COMMA@[262; 263)
229 WHITESPACE@[263; 264)
230 TYPE_PARAM@[264; 265)
231 NAME@[264; 265)
232 IDENT@[264; 265) "U"
233 R_ANGLE@[265; 266)
234 SEMI@[266; 267)
235 WHITESPACE@[267; 268)
236 STRUCT_DEF@[268; 289)
237 STRUCT_KW@[268; 274)
238 WHITESPACE@[274; 275)
239 NAME@[275; 278)
240 IDENT@[275; 278) "S15"
241 TYPE_PARAM_LIST@[278; 288)
242 L_ANGLE@[278; 279)
243 LIFETIME_PARAM@[279; 281)
244 LIFETIME@[279; 281) "'a"
245 COMMA@[281; 282)
246 WHITESPACE@[282; 283)
247 TYPE_PARAM@[283; 284)
248 NAME@[283; 284)
249 IDENT@[283; 284) "T"
250 COMMA@[284; 285)
251 WHITESPACE@[285; 286)
252 TYPE_PARAM@[286; 287)
253 NAME@[286; 287)
254 IDENT@[286; 287) "U"
255 R_ANGLE@[287; 288)
256 SEMI@[288; 289)
257 WHITESPACE@[289; 290)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0019_enums.rs b/crates/ra_syntax/tests/data/parser/ok/0019_enums.rs
new file mode 100644
index 000000000..7a1afa0e6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0019_enums.rs
@@ -0,0 +1,25 @@
1enum E1 {
2}
3
4enum E2<T> {
5}
6
7enum E3 {
8 X
9}
10
11enum E4 {
12 X,
13}
14
15enum E5 {
16 A,
17 B = 92,
18 C {
19 a: u32,
20 pub b: f64,
21 },
22 F {},
23 D(u32,),
24 E(),
25}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0019_enums.txt b/crates/ra_syntax/tests/data/parser/ok/0019_enums.txt
new file mode 100644
index 000000000..6333e47c5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0019_enums.txt
@@ -0,0 +1,155 @@
1ROOT@[0; 182)
2 ENUM_DEF@[0; 11)
3 ENUM_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 7)
6 IDENT@[5; 7) "E1"
7 WHITESPACE@[7; 8)
8 ENUM_VARIANT_LIST@[8; 11)
9 L_CURLY@[8; 9)
10 WHITESPACE@[9; 10)
11 R_CURLY@[10; 11)
12 WHITESPACE@[11; 13)
13 ENUM_DEF@[13; 27)
14 ENUM_KW@[13; 17)
15 WHITESPACE@[17; 18)
16 NAME@[18; 20)
17 IDENT@[18; 20) "E2"
18 TYPE_PARAM_LIST@[20; 23)
19 L_ANGLE@[20; 21)
20 TYPE_PARAM@[21; 22)
21 NAME@[21; 22)
22 IDENT@[21; 22) "T"
23 R_ANGLE@[22; 23)
24 WHITESPACE@[23; 24)
25 ENUM_VARIANT_LIST@[24; 27)
26 L_CURLY@[24; 25)
27 WHITESPACE@[25; 26)
28 R_CURLY@[26; 27)
29 WHITESPACE@[27; 29)
30 ENUM_DEF@[29; 46)
31 ENUM_KW@[29; 33)
32 WHITESPACE@[33; 34)
33 NAME@[34; 36)
34 IDENT@[34; 36) "E3"
35 WHITESPACE@[36; 37)
36 ENUM_VARIANT_LIST@[37; 46)
37 L_CURLY@[37; 38)
38 WHITESPACE@[38; 43)
39 ENUM_VARIANT@[43; 44)
40 NAME@[43; 44)
41 IDENT@[43; 44) "X"
42 WHITESPACE@[44; 45)
43 R_CURLY@[45; 46)
44 WHITESPACE@[46; 48)
45 ENUM_DEF@[48; 66)
46 ENUM_KW@[48; 52)
47 WHITESPACE@[52; 53)
48 NAME@[53; 55)
49 IDENT@[53; 55) "E4"
50 WHITESPACE@[55; 56)
51 ENUM_VARIANT_LIST@[56; 66)
52 L_CURLY@[56; 57)
53 WHITESPACE@[57; 62)
54 ENUM_VARIANT@[62; 63)
55 NAME@[62; 63)
56 IDENT@[62; 63) "X"
57 COMMA@[63; 64)
58 WHITESPACE@[64; 65)
59 R_CURLY@[65; 66)
60 WHITESPACE@[66; 68)
61 ENUM_DEF@[68; 181)
62 ENUM_KW@[68; 72)
63 WHITESPACE@[72; 73)
64 NAME@[73; 75)
65 IDENT@[73; 75) "E5"
66 WHITESPACE@[75; 76)
67 ENUM_VARIANT_LIST@[76; 181)
68 L_CURLY@[76; 77)
69 WHITESPACE@[77; 82)
70 ENUM_VARIANT@[82; 83)
71 NAME@[82; 83)
72 IDENT@[82; 83) "A"
73 COMMA@[83; 84)
74 WHITESPACE@[84; 89)
75 ENUM_VARIANT@[89; 95)
76 NAME@[89; 90)
77 IDENT@[89; 90) "B"
78 WHITESPACE@[90; 91)
79 EQ@[91; 92)
80 WHITESPACE@[92; 93)
81 LITERAL@[93; 95)
82 INT_NUMBER@[93; 95) "92"
83 COMMA@[95; 96)
84 WHITESPACE@[96; 101)
85 ENUM_VARIANT@[101; 146)
86 NAME@[101; 102)
87 IDENT@[101; 102) "C"
88 WHITESPACE@[102; 103)
89 NAMED_FIELD_DEF_LIST@[103; 146)
90 L_CURLY@[103; 104)
91 WHITESPACE@[104; 113)
92 NAMED_FIELD_DEF@[113; 119)
93 NAME@[113; 114)
94 IDENT@[113; 114) "a"
95 COLON@[114; 115)
96 WHITESPACE@[115; 116)
97 PATH_TYPE@[116; 119)
98 PATH@[116; 119)
99 PATH_SEGMENT@[116; 119)
100 NAME_REF@[116; 119)
101 IDENT@[116; 119) "u32"
102 COMMA@[119; 120)
103 WHITESPACE@[120; 129)
104 NAMED_FIELD_DEF@[129; 139)
105 VISIBILITY@[129; 132)
106 PUB_KW@[129; 132)
107 WHITESPACE@[132; 133)
108 NAME@[133; 134)
109 IDENT@[133; 134) "b"
110 COLON@[134; 135)
111 WHITESPACE@[135; 136)
112 PATH_TYPE@[136; 139)
113 PATH@[136; 139)
114 PATH_SEGMENT@[136; 139)
115 NAME_REF@[136; 139)
116 IDENT@[136; 139) "f64"
117 COMMA@[139; 140)
118 WHITESPACE@[140; 145)
119 R_CURLY@[145; 146)
120 COMMA@[146; 147)
121 WHITESPACE@[147; 152)
122 ENUM_VARIANT@[152; 156)
123 NAME@[152; 153)
124 IDENT@[152; 153) "F"
125 WHITESPACE@[153; 154)
126 NAMED_FIELD_DEF_LIST@[154; 156)
127 L_CURLY@[154; 155)
128 R_CURLY@[155; 156)
129 COMMA@[156; 157)
130 WHITESPACE@[157; 162)
131 ENUM_VARIANT@[162; 169)
132 NAME@[162; 163)
133 IDENT@[162; 163) "D"
134 POS_FIELD_LIST@[163; 169)
135 L_PAREN@[163; 164)
136 POS_FIELD@[164; 167)
137 PATH_TYPE@[164; 167)
138 PATH@[164; 167)
139 PATH_SEGMENT@[164; 167)
140 NAME_REF@[164; 167)
141 IDENT@[164; 167) "u32"
142 COMMA@[167; 168)
143 R_PAREN@[168; 169)
144 COMMA@[169; 170)
145 WHITESPACE@[170; 175)
146 ENUM_VARIANT@[175; 178)
147 NAME@[175; 176)
148 IDENT@[175; 176) "E"
149 POS_FIELD_LIST@[176; 178)
150 L_PAREN@[176; 177)
151 R_PAREN@[177; 178)
152 COMMA@[178; 179)
153 WHITESPACE@[179; 180)
154 R_CURLY@[180; 181)
155 WHITESPACE@[181; 182)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs
new file mode 100644
index 000000000..a1b9f00a4
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs
@@ -0,0 +1,9 @@
1struct A<T>;
2struct B<T:>;
3struct C<T: 'a>;
4struct D<T: 'a + >;
5struct E<T: 'a + 'd >;
6struct F<T: 'a + 'd + Clone>;
7struct G<T: Clone + Copy>;
8struct H<T: ::Foo + self::Bar + 'a>;
9struct I<T:, U:,>;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt
new file mode 100644
index 000000000..ac1a58e9a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt
@@ -0,0 +1,198 @@
1ROOT@[0; 200)
2 STRUCT_DEF@[0; 12)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 8)
6 IDENT@[7; 8) "A"
7 TYPE_PARAM_LIST@[8; 11)
8 L_ANGLE@[8; 9)
9 TYPE_PARAM@[9; 10)
10 NAME@[9; 10)
11 IDENT@[9; 10) "T"
12 R_ANGLE@[10; 11)
13 SEMI@[11; 12)
14 WHITESPACE@[12; 13)
15 STRUCT_DEF@[13; 26)
16 STRUCT_KW@[13; 19)
17 WHITESPACE@[19; 20)
18 NAME@[20; 21)
19 IDENT@[20; 21) "B"
20 TYPE_PARAM_LIST@[21; 25)
21 L_ANGLE@[21; 22)
22 TYPE_PARAM@[22; 24)
23 NAME@[22; 23)
24 IDENT@[22; 23) "T"
25 COLON@[23; 24)
26 R_ANGLE@[24; 25)
27 SEMI@[25; 26)
28 WHITESPACE@[26; 27)
29 STRUCT_DEF@[27; 43)
30 STRUCT_KW@[27; 33)
31 WHITESPACE@[33; 34)
32 NAME@[34; 35)
33 IDENT@[34; 35) "C"
34 TYPE_PARAM_LIST@[35; 42)
35 L_ANGLE@[35; 36)
36 TYPE_PARAM@[36; 41)
37 NAME@[36; 37)
38 IDENT@[36; 37) "T"
39 COLON@[37; 38)
40 WHITESPACE@[38; 39)
41 LIFETIME@[39; 41) "'a"
42 R_ANGLE@[41; 42)
43 SEMI@[42; 43)
44 WHITESPACE@[43; 44)
45 STRUCT_DEF@[44; 63)
46 STRUCT_KW@[44; 50)
47 WHITESPACE@[50; 51)
48 NAME@[51; 52)
49 IDENT@[51; 52) "D"
50 TYPE_PARAM_LIST@[52; 62)
51 L_ANGLE@[52; 53)
52 TYPE_PARAM@[53; 60)
53 NAME@[53; 54)
54 IDENT@[53; 54) "T"
55 COLON@[54; 55)
56 WHITESPACE@[55; 56)
57 LIFETIME@[56; 58) "'a"
58 WHITESPACE@[58; 59)
59 PLUS@[59; 60)
60 WHITESPACE@[60; 61)
61 R_ANGLE@[61; 62)
62 SEMI@[62; 63)
63 WHITESPACE@[63; 64)
64 STRUCT_DEF@[64; 86)
65 STRUCT_KW@[64; 70)
66 WHITESPACE@[70; 71)
67 NAME@[71; 72)
68 IDENT@[71; 72) "E"
69 TYPE_PARAM_LIST@[72; 85)
70 L_ANGLE@[72; 73)
71 TYPE_PARAM@[73; 83)
72 NAME@[73; 74)
73 IDENT@[73; 74) "T"
74 COLON@[74; 75)
75 WHITESPACE@[75; 76)
76 LIFETIME@[76; 78) "'a"
77 WHITESPACE@[78; 79)
78 PLUS@[79; 80)
79 WHITESPACE@[80; 81)
80 LIFETIME@[81; 83) "'d"
81 WHITESPACE@[83; 84)
82 R_ANGLE@[84; 85)
83 SEMI@[85; 86)
84 WHITESPACE@[86; 87)
85 STRUCT_DEF@[87; 116)
86 STRUCT_KW@[87; 93)
87 WHITESPACE@[93; 94)
88 NAME@[94; 95)
89 IDENT@[94; 95) "F"
90 TYPE_PARAM_LIST@[95; 115)
91 L_ANGLE@[95; 96)
92 TYPE_PARAM@[96; 114)
93 NAME@[96; 97)
94 IDENT@[96; 97) "T"
95 COLON@[97; 98)
96 WHITESPACE@[98; 99)
97 LIFETIME@[99; 101) "'a"
98 WHITESPACE@[101; 102)
99 PLUS@[102; 103)
100 WHITESPACE@[103; 104)
101 LIFETIME@[104; 106) "'d"
102 WHITESPACE@[106; 107)
103 PLUS@[107; 108)
104 WHITESPACE@[108; 109)
105 PATH_TYPE@[109; 114)
106 PATH@[109; 114)
107 PATH_SEGMENT@[109; 114)
108 NAME_REF@[109; 114)
109 IDENT@[109; 114) "Clone"
110 R_ANGLE@[114; 115)
111 SEMI@[115; 116)
112 WHITESPACE@[116; 117)
113 STRUCT_DEF@[117; 143)
114 STRUCT_KW@[117; 123)
115 WHITESPACE@[123; 124)
116 NAME@[124; 125)
117 IDENT@[124; 125) "G"
118 TYPE_PARAM_LIST@[125; 142)
119 L_ANGLE@[125; 126)
120 TYPE_PARAM@[126; 141)
121 NAME@[126; 127)
122 IDENT@[126; 127) "T"
123 COLON@[127; 128)
124 WHITESPACE@[128; 129)
125 PATH_TYPE@[129; 141)
126 PATH@[129; 134)
127 PATH_SEGMENT@[129; 134)
128 NAME_REF@[129; 134)
129 IDENT@[129; 134) "Clone"
130 WHITESPACE@[134; 135)
131 PLUS@[135; 136)
132 WHITESPACE@[136; 137)
133 PATH_TYPE@[137; 141)
134 PATH@[137; 141)
135 PATH_SEGMENT@[137; 141)
136 NAME_REF@[137; 141)
137 IDENT@[137; 141) "Copy"
138 R_ANGLE@[141; 142)
139 SEMI@[142; 143)
140 WHITESPACE@[143; 144)
141 STRUCT_DEF@[144; 180)
142 STRUCT_KW@[144; 150)
143 WHITESPACE@[150; 151)
144 NAME@[151; 152)
145 IDENT@[151; 152) "H"
146 TYPE_PARAM_LIST@[152; 179)
147 L_ANGLE@[152; 153)
148 TYPE_PARAM@[153; 178)
149 NAME@[153; 154)
150 IDENT@[153; 154) "T"
151 COLON@[154; 155)
152 WHITESPACE@[155; 156)
153 PATH_TYPE@[156; 178)
154 PATH@[156; 161)
155 PATH_SEGMENT@[156; 161)
156 COLONCOLON@[156; 158)
157 NAME_REF@[158; 161)
158 IDENT@[158; 161) "Foo"
159 WHITESPACE@[161; 162)
160 PLUS@[162; 163)
161 WHITESPACE@[163; 164)
162 PATH_TYPE@[164; 178)
163 PATH@[164; 173)
164 PATH@[164; 168)
165 PATH_SEGMENT@[164; 168)
166 SELF_KW@[164; 168)
167 COLONCOLON@[168; 170)
168 PATH_SEGMENT@[170; 173)
169 NAME_REF@[170; 173)
170 IDENT@[170; 173) "Bar"
171 WHITESPACE@[173; 174)
172 PLUS@[174; 175)
173 WHITESPACE@[175; 176)
174 LIFETIME@[176; 178) "'a"
175 R_ANGLE@[178; 179)
176 SEMI@[179; 180)
177 WHITESPACE@[180; 181)
178 STRUCT_DEF@[181; 199)
179 STRUCT_KW@[181; 187)
180 WHITESPACE@[187; 188)
181 NAME@[188; 189)
182 IDENT@[188; 189) "I"
183 TYPE_PARAM_LIST@[189; 198)
184 L_ANGLE@[189; 190)
185 TYPE_PARAM@[190; 192)
186 NAME@[190; 191)
187 IDENT@[190; 191) "T"
188 COLON@[191; 192)
189 COMMA@[192; 193)
190 WHITESPACE@[193; 194)
191 TYPE_PARAM@[194; 196)
192 NAME@[194; 195)
193 IDENT@[194; 195) "U"
194 COLON@[195; 196)
195 COMMA@[196; 197)
196 R_ANGLE@[197; 198)
197 SEMI@[198; 199)
198 WHITESPACE@[199; 200)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs
new file mode 100644
index 000000000..e929eef74
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs
@@ -0,0 +1,8 @@
1extern fn foo() {
2}
3
4extern "C" fn bar() {
5}
6
7extern r"D" fn baz() {
8}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt
new file mode 100644
index 000000000..5ceef46e0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt
@@ -0,0 +1,56 @@
1ROOT@[0; 71)
2 FN_DEF@[0; 19)
3 ABI@[0; 6)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 FN_KW@[7; 9)
7 WHITESPACE@[9; 10)
8 NAME@[10; 13)
9 IDENT@[10; 13) "foo"
10 PARAM_LIST@[13; 15)
11 L_PAREN@[13; 14)
12 R_PAREN@[14; 15)
13 WHITESPACE@[15; 16)
14 BLOCK@[16; 19)
15 L_CURLY@[16; 17)
16 WHITESPACE@[17; 18)
17 R_CURLY@[18; 19)
18 WHITESPACE@[19; 21)
19 FN_DEF@[21; 44)
20 ABI@[21; 31)
21 EXTERN_KW@[21; 27)
22 WHITESPACE@[27; 28)
23 STRING@[28; 31)
24 WHITESPACE@[31; 32)
25 FN_KW@[32; 34)
26 WHITESPACE@[34; 35)
27 NAME@[35; 38)
28 IDENT@[35; 38) "bar"
29 PARAM_LIST@[38; 40)
30 L_PAREN@[38; 39)
31 R_PAREN@[39; 40)
32 WHITESPACE@[40; 41)
33 BLOCK@[41; 44)
34 L_CURLY@[41; 42)
35 WHITESPACE@[42; 43)
36 R_CURLY@[43; 44)
37 WHITESPACE@[44; 46)
38 FN_DEF@[46; 70)
39 ABI@[46; 57)
40 EXTERN_KW@[46; 52)
41 WHITESPACE@[52; 53)
42 RAW_STRING@[53; 57)
43 WHITESPACE@[57; 58)
44 FN_KW@[58; 60)
45 WHITESPACE@[60; 61)
46 NAME@[61; 64)
47 IDENT@[61; 64) "baz"
48 PARAM_LIST@[64; 66)
49 L_PAREN@[64; 65)
50 R_PAREN@[65; 66)
51 WHITESPACE@[66; 67)
52 BLOCK@[67; 70)
53 L_CURLY@[67; 68)
54 WHITESPACE@[68; 69)
55 R_CURLY@[69; 70)
56 WHITESPACE@[70; 71)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs
new file mode 100644
index 000000000..f5fe0e6ef
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs
@@ -0,0 +1,5 @@
1extern {
2}
3
4extern "C" {
5}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt
new file mode 100644
index 000000000..2099e2433
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt
@@ -0,0 +1,21 @@
1ROOT@[0; 27)
2 EXTERN_BLOCK@[0; 10)
3 ABI@[0; 6)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 EXTERN_ITEM_LIST@[7; 10)
7 L_CURLY@[7; 8)
8 WHITESPACE@[8; 9)
9 R_CURLY@[9; 10)
10 WHITESPACE@[10; 12)
11 EXTERN_BLOCK@[12; 26)
12 ABI@[12; 22)
13 EXTERN_KW@[12; 18)
14 WHITESPACE@[18; 19)
15 STRING@[19; 22)
16 WHITESPACE@[22; 23)
17 EXTERN_ITEM_LIST@[23; 26)
18 L_CURLY@[23; 24)
19 WHITESPACE@[24; 25)
20 R_CURLY@[25; 26)
21 WHITESPACE@[26; 27)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs
new file mode 100644
index 000000000..5fb92ce33
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs
@@ -0,0 +1,2 @@
1static FOO: u32 = 1;
2static mut BAR: i32 = 92;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt
new file mode 100644
index 000000000..5c1a3a7a5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt
@@ -0,0 +1,41 @@
1ROOT@[0; 47)
2 STATIC_DEF@[0; 20)
3 STATIC_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 NAME@[7; 10)
6 IDENT@[7; 10) "FOO"
7 COLON@[10; 11)
8 WHITESPACE@[11; 12)
9 PATH_TYPE@[12; 15)
10 PATH@[12; 15)
11 PATH_SEGMENT@[12; 15)
12 NAME_REF@[12; 15)
13 IDENT@[12; 15) "u32"
14 WHITESPACE@[15; 16)
15 EQ@[16; 17)
16 WHITESPACE@[17; 18)
17 LITERAL@[18; 19)
18 INT_NUMBER@[18; 19) "1"
19 SEMI@[19; 20)
20 WHITESPACE@[20; 21)
21 STATIC_DEF@[21; 46)
22 STATIC_KW@[21; 27)
23 WHITESPACE@[27; 28)
24 MUT_KW@[28; 31)
25 WHITESPACE@[31; 32)
26 NAME@[32; 35)
27 IDENT@[32; 35) "BAR"
28 COLON@[35; 36)
29 WHITESPACE@[36; 37)
30 PATH_TYPE@[37; 40)
31 PATH@[37; 40)
32 PATH_SEGMENT@[37; 40)
33 NAME_REF@[37; 40)
34 IDENT@[37; 40) "i32"
35 WHITESPACE@[40; 41)
36 EQ@[41; 42)
37 WHITESPACE@[42; 43)
38 LITERAL@[43; 45)
39 INT_NUMBER@[43; 45) "92"
40 SEMI@[45; 46)
41 WHITESPACE@[46; 47)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs
new file mode 100644
index 000000000..7446859b5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs
@@ -0,0 +1,2 @@
1const FOO: u32 = 92;
2const mut BAR: u32 = 62;
diff --git a/crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt
new file mode 100644
index 000000000..d0e5842da
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt
@@ -0,0 +1,41 @@
1ROOT@[0; 46)
2 CONST_DEF@[0; 20)
3 CONST_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 NAME@[6; 9)
6 IDENT@[6; 9) "FOO"
7 COLON@[9; 10)
8 WHITESPACE@[10; 11)
9 PATH_TYPE@[11; 14)
10 PATH@[11; 14)
11 PATH_SEGMENT@[11; 14)
12 NAME_REF@[11; 14)
13 IDENT@[11; 14) "u32"
14 WHITESPACE@[14; 15)
15 EQ@[15; 16)
16 WHITESPACE@[16; 17)
17 LITERAL@[17; 19)
18 INT_NUMBER@[17; 19) "92"
19 SEMI@[19; 20)
20 WHITESPACE@[20; 21)
21 CONST_DEF@[21; 45)
22 CONST_KW@[21; 26)
23 WHITESPACE@[26; 27)
24 MUT_KW@[27; 30)
25 WHITESPACE@[30; 31)
26 NAME@[31; 34)
27 IDENT@[31; 34) "BAR"
28 COLON@[34; 35)
29 WHITESPACE@[35; 36)
30 PATH_TYPE@[36; 39)
31 PATH@[36; 39)
32 PATH_SEGMENT@[36; 39)
33 NAME_REF@[36; 39)
34 IDENT@[36; 39) "u32"
35 WHITESPACE@[39; 40)
36 EQ@[40; 41)
37 WHITESPACE@[41; 42)
38 LITERAL@[42; 44)
39 INT_NUMBER@[42; 44) "62"
40 SEMI@[44; 45)
41 WHITESPACE@[45; 46)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs
new file mode 100644
index 000000000..289809809
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs
@@ -0,0 +1,3 @@
1fn main() {
2 extern fn f() {}
3}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt
new file mode 100644
index 000000000..363b3576e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt
@@ -0,0 +1,31 @@
1ROOT@[0; 35)
2 FN_DEF@[0; 34)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 34)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 FN_DEF@[16; 32)
15 ABI@[16; 22)
16 EXTERN_KW@[16; 22)
17 WHITESPACE@[22; 23)
18 FN_KW@[23; 25)
19 WHITESPACE@[25; 26)
20 NAME@[26; 27)
21 IDENT@[26; 27) "f"
22 PARAM_LIST@[27; 29)
23 L_PAREN@[27; 28)
24 R_PAREN@[28; 29)
25 WHITESPACE@[29; 30)
26 BLOCK@[30; 32)
27 L_CURLY@[30; 31)
28 R_CURLY@[31; 32)
29 WHITESPACE@[32; 33)
30 R_CURLY@[33; 34)
31 WHITESPACE@[34; 35)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs
new file mode 100644
index 000000000..7641a3d28
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs
@@ -0,0 +1,3 @@
1fn main() {
2 const fn f() {}
3}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt
new file mode 100644
index 000000000..d45fc2559
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt
@@ -0,0 +1,30 @@
1ROOT@[0; 34)
2 FN_DEF@[0; 33)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 33)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 FN_DEF@[16; 31)
15 CONST_KW@[16; 21)
16 WHITESPACE@[21; 22)
17 FN_KW@[22; 24)
18 WHITESPACE@[24; 25)
19 NAME@[25; 26)
20 IDENT@[25; 26) "f"
21 PARAM_LIST@[26; 28)
22 L_PAREN@[26; 27)
23 R_PAREN@[27; 28)
24 WHITESPACE@[28; 29)
25 BLOCK@[29; 31)
26 L_CURLY@[29; 30)
27 R_CURLY@[30; 31)
28 WHITESPACE@[31; 32)
29 R_CURLY@[32; 33)
30 WHITESPACE@[33; 34)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs
new file mode 100644
index 000000000..f3c5ff938
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs
@@ -0,0 +1,4 @@
1fn main() {
2 unsafe fn f() {}
3 unsafe { 92 }
4}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt
new file mode 100644
index 000000000..5a39fa98c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt
@@ -0,0 +1,41 @@
1ROOT@[0; 53)
2 FN_DEF@[0; 52)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 7)
6 IDENT@[3; 7) "main"
7 PARAM_LIST@[7; 9)
8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10)
11 BLOCK@[10; 52)
12 L_CURLY@[10; 11)
13 WHITESPACE@[11; 16)
14 FN_DEF@[16; 32)
15 UNSAFE_KW@[16; 22)
16 WHITESPACE@[22; 23)
17 FN_KW@[23; 25)
18 WHITESPACE@[25; 26)
19 NAME@[26; 27)
20 IDENT@[26; 27) "f"
21 PARAM_LIST@[27; 29)
22 L_PAREN@[27; 28)
23 R_PAREN@[28; 29)
24 WHITESPACE@[29; 30)
25 BLOCK@[30; 32)
26 L_CURLY@[30; 31)
27 R_CURLY@[31; 32)
28 WHITESPACE@[32; 37)
29 BLOCK_EXPR@[37; 50)
30 UNSAFE_KW@[37; 43)
31 WHITESPACE@[43; 44)
32 BLOCK@[44; 50)
33 L_CURLY@[44; 45)
34 WHITESPACE@[45; 46)
35 LITERAL@[46; 48)
36 INT_NUMBER@[46; 48) "92"
37 WHITESPACE@[48; 49)
38 R_CURLY@[49; 50)
39 WHITESPACE@[50; 51)
40 R_CURLY@[51; 52)
41 WHITESPACE@[52; 53)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs
new file mode 100644
index 000000000..cc9598470
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs
@@ -0,0 +1,14 @@
1fn binding_power() {
2 let x = 1 + 2 * 3 % 4 - 5 / 6;
3 1 + 2 * 3;
4 1 << 2 + 3;
5 1 & 2 >> 3;
6 1 ^ 2 & 3;
7 1 | 2 ^ 3;
8 1 == 2 | 3;
9 1 && 2 == 3;
10 //1 || 2 && 2;
11 //1 .. 2 || 3;
12 //1 = 2 .. 3;
13 //---&*1 - --2 * 9;
14}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt
new file mode 100644
index 000000000..27efd180f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt
@@ -0,0 +1,185 @@
1ROOT@[0; 248)
2 FN_DEF@[0; 247)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 16)
6 IDENT@[3; 16) "binding_power"
7 PARAM_LIST@[16; 18)
8 L_PAREN@[16; 17)
9 R_PAREN@[17; 18)
10 WHITESPACE@[18; 19)
11 BLOCK@[19; 247)
12 L_CURLY@[19; 20)
13 WHITESPACE@[20; 25)
14 LET_STMT@[25; 55)
15 LET_KW@[25; 28)
16 WHITESPACE@[28; 29)
17 BIND_PAT@[29; 30)
18 NAME@[29; 30)
19 IDENT@[29; 30) "x"
20 WHITESPACE@[30; 31)
21 EQ@[31; 32)
22 WHITESPACE@[32; 33)
23 BIN_EXPR@[33; 54)
24 BIN_EXPR@[33; 46)
25 LITERAL@[33; 34)
26 INT_NUMBER@[33; 34) "1"
27 WHITESPACE@[34; 35)
28 PLUS@[35; 36)
29 WHITESPACE@[36; 37)
30 BIN_EXPR@[37; 46)
31 BIN_EXPR@[37; 42)
32 LITERAL@[37; 38)
33 INT_NUMBER@[37; 38) "2"
34 WHITESPACE@[38; 39)
35 STAR@[39; 40)
36 WHITESPACE@[40; 41)
37 LITERAL@[41; 42)
38 INT_NUMBER@[41; 42) "3"
39 WHITESPACE@[42; 43)
40 PERCENT@[43; 44)
41 WHITESPACE@[44; 45)
42 LITERAL@[45; 46)
43 INT_NUMBER@[45; 46) "4"
44 WHITESPACE@[46; 47)
45 MINUS@[47; 48)
46 WHITESPACE@[48; 49)
47 BIN_EXPR@[49; 54)
48 LITERAL@[49; 50)
49 INT_NUMBER@[49; 50) "5"
50 WHITESPACE@[50; 51)
51 SLASH@[51; 52)
52 WHITESPACE@[52; 53)
53 LITERAL@[53; 54)
54 INT_NUMBER@[53; 54) "6"
55 SEMI@[54; 55)
56 WHITESPACE@[55; 60)
57 EXPR_STMT@[60; 70)
58 BIN_EXPR@[60; 69)
59 LITERAL@[60; 61)
60 INT_NUMBER@[60; 61) "1"
61 WHITESPACE@[61; 62)
62 PLUS@[62; 63)
63 WHITESPACE@[63; 64)
64 BIN_EXPR@[64; 69)
65 LITERAL@[64; 65)
66 INT_NUMBER@[64; 65) "2"
67 WHITESPACE@[65; 66)
68 STAR@[66; 67)
69 WHITESPACE@[67; 68)
70 LITERAL@[68; 69)
71 INT_NUMBER@[68; 69) "3"
72 SEMI@[69; 70)
73 WHITESPACE@[70; 75)
74 EXPR_STMT@[75; 86)
75 BIN_EXPR@[75; 85)
76 LITERAL@[75; 76)
77 INT_NUMBER@[75; 76) "1"
78 WHITESPACE@[76; 77)
79 SHL@[77; 79)
80 WHITESPACE@[79; 80)
81 BIN_EXPR@[80; 85)
82 LITERAL@[80; 81)
83 INT_NUMBER@[80; 81) "2"
84 WHITESPACE@[81; 82)
85 PLUS@[82; 83)
86 WHITESPACE@[83; 84)
87 LITERAL@[84; 85)
88 INT_NUMBER@[84; 85) "3"
89 SEMI@[85; 86)
90 WHITESPACE@[86; 91)
91 EXPR_STMT@[91; 102)
92 BIN_EXPR@[91; 101)
93 LITERAL@[91; 92)
94 INT_NUMBER@[91; 92) "1"
95 WHITESPACE@[92; 93)
96 AMP@[93; 94)
97 WHITESPACE@[94; 95)
98 BIN_EXPR@[95; 101)
99 LITERAL@[95; 96)
100 INT_NUMBER@[95; 96) "2"
101 WHITESPACE@[96; 97)
102 SHR@[97; 99)
103 WHITESPACE@[99; 100)
104 LITERAL@[100; 101)
105 INT_NUMBER@[100; 101) "3"
106 SEMI@[101; 102)
107 WHITESPACE@[102; 107)
108 EXPR_STMT@[107; 117)
109 BIN_EXPR@[107; 116)
110 LITERAL@[107; 108)
111 INT_NUMBER@[107; 108) "1"
112 WHITESPACE@[108; 109)
113 CARET@[109; 110)
114 WHITESPACE@[110; 111)
115 BIN_EXPR@[111; 116)
116 LITERAL@[111; 112)
117 INT_NUMBER@[111; 112) "2"
118 WHITESPACE@[112; 113)
119 AMP@[113; 114)
120 WHITESPACE@[114; 115)
121 LITERAL@[115; 116)
122 INT_NUMBER@[115; 116) "3"
123 SEMI@[116; 117)
124 WHITESPACE@[117; 122)
125 EXPR_STMT@[122; 132)
126 BIN_EXPR@[122; 131)
127 LITERAL@[122; 123)
128 INT_NUMBER@[122; 123) "1"
129 WHITESPACE@[123; 124)
130 PIPE@[124; 125)
131 WHITESPACE@[125; 126)
132 BIN_EXPR@[126; 131)
133 LITERAL@[126; 127)
134 INT_NUMBER@[126; 127) "2"
135 WHITESPACE@[127; 128)
136 CARET@[128; 129)
137 WHITESPACE@[129; 130)
138 LITERAL@[130; 131)
139 INT_NUMBER@[130; 131) "3"
140 SEMI@[131; 132)
141 WHITESPACE@[132; 137)
142 EXPR_STMT@[137; 148)
143 BIN_EXPR@[137; 147)
144 LITERAL@[137; 138)
145 INT_NUMBER@[137; 138) "1"
146 WHITESPACE@[138; 139)
147 EQEQ@[139; 141)
148 WHITESPACE@[141; 142)
149 BIN_EXPR@[142; 147)
150 LITERAL@[142; 143)
151 INT_NUMBER@[142; 143) "2"
152 WHITESPACE@[143; 144)
153 PIPE@[144; 145)
154 WHITESPACE@[145; 146)
155 LITERAL@[146; 147)
156 INT_NUMBER@[146; 147) "3"
157 SEMI@[147; 148)
158 WHITESPACE@[148; 153)
159 EXPR_STMT@[153; 165)
160 BIN_EXPR@[153; 164)
161 LITERAL@[153; 154)
162 INT_NUMBER@[153; 154) "1"
163 WHITESPACE@[154; 155)
164 AMPAMP@[155; 157)
165 WHITESPACE@[157; 158)
166 BIN_EXPR@[158; 164)
167 LITERAL@[158; 159)
168 INT_NUMBER@[158; 159) "2"
169 WHITESPACE@[159; 160)
170 EQEQ@[160; 162)
171 WHITESPACE@[162; 163)
172 LITERAL@[163; 164)
173 INT_NUMBER@[163; 164) "3"
174 SEMI@[164; 165)
175 WHITESPACE@[165; 170)
176 COMMENT@[170; 184)
177 WHITESPACE@[184; 189)
178 COMMENT@[189; 203)
179 WHITESPACE@[203; 208)
180 COMMENT@[208; 221)
181 WHITESPACE@[221; 226)
182 COMMENT@[226; 245)
183 WHITESPACE@[245; 246)
184 R_CURLY@[246; 247)
185 WHITESPACE@[247; 248)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs
new file mode 100644
index 000000000..03f4ae7b2
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs
@@ -0,0 +1,6 @@
1fn foo() {
2 ..1 + 1;
3 ..z = 2;
4 x = false..1 == 1;
5 let x = 1..;
6}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt
new file mode 100644
index 000000000..6d6d2f4d0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt
@@ -0,0 +1,83 @@
1ROOT@[0; 79)
2 FN_DEF@[0; 78)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 78)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 23)
15 RANGE_EXPR@[15; 22)
16 DOTDOT@[15; 17)
17 BIN_EXPR@[17; 22)
18 LITERAL@[17; 18)
19 INT_NUMBER@[17; 18) "1"
20 WHITESPACE@[18; 19)
21 PLUS@[19; 20)
22 WHITESPACE@[20; 21)
23 LITERAL@[21; 22)
24 INT_NUMBER@[21; 22) "1"
25 SEMI@[22; 23)
26 WHITESPACE@[23; 28)
27 EXPR_STMT@[28; 36)
28 BIN_EXPR@[28; 35)
29 RANGE_EXPR@[28; 31)
30 DOTDOT@[28; 30)
31 PATH_EXPR@[30; 31)
32 PATH@[30; 31)
33 PATH_SEGMENT@[30; 31)
34 NAME_REF@[30; 31)
35 IDENT@[30; 31) "z"
36 WHITESPACE@[31; 32)
37 EQ@[32; 33)
38 WHITESPACE@[33; 34)
39 LITERAL@[34; 35)
40 INT_NUMBER@[34; 35) "2"
41 SEMI@[35; 36)
42 WHITESPACE@[36; 41)
43 EXPR_STMT@[41; 59)
44 BIN_EXPR@[41; 58)
45 PATH_EXPR@[41; 42)
46 PATH@[41; 42)
47 PATH_SEGMENT@[41; 42)
48 NAME_REF@[41; 42)
49 IDENT@[41; 42) "x"
50 WHITESPACE@[42; 43)
51 EQ@[43; 44)
52 WHITESPACE@[44; 45)
53 RANGE_EXPR@[45; 58)
54 LITERAL@[45; 50)
55 FALSE_KW@[45; 50)
56 DOTDOT@[50; 52)
57 BIN_EXPR@[52; 58)
58 LITERAL@[52; 53)
59 INT_NUMBER@[52; 53) "1"
60 WHITESPACE@[53; 54)
61 EQEQ@[54; 56)
62 WHITESPACE@[56; 57)
63 LITERAL@[57; 58)
64 INT_NUMBER@[57; 58) "1"
65 SEMI@[58; 59)
66 WHITESPACE@[59; 64)
67 LET_STMT@[64; 76)
68 LET_KW@[64; 67)
69 WHITESPACE@[67; 68)
70 BIND_PAT@[68; 69)
71 NAME@[68; 69)
72 IDENT@[68; 69) "x"
73 WHITESPACE@[69; 70)
74 EQ@[70; 71)
75 WHITESPACE@[71; 72)
76 RANGE_EXPR@[72; 75)
77 LITERAL@[72; 73)
78 INT_NUMBER@[72; 73) "1"
79 DOTDOT@[73; 75)
80 SEMI@[75; 76)
81 WHITESPACE@[76; 77)
82 R_CURLY@[77; 78)
83 WHITESPACE@[78; 79)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0030_traits.rs b/crates/ra_syntax/tests/data/parser/ok/0030_traits.rs
new file mode 100644
index 000000000..23c4be0e1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0030_traits.rs
@@ -0,0 +1,11 @@
1pub trait WriteMessage {
2 fn write_message(&FrontendMessage);
3}
4
5trait Runnable {
6 fn handler();
7}
8
9trait TraitWithExpr {
10 fn fn_with_expr(x: [i32; 1]);
11}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0030_traits.txt b/crates/ra_syntax/tests/data/parser/ok/0030_traits.txt
new file mode 100644
index 000000000..ddd666407
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0030_traits.txt
@@ -0,0 +1,93 @@
1ROOT@[0; 164)
2 TRAIT_DEF@[0; 66)
3 VISIBILITY@[0; 3)
4 PUB_KW@[0; 3)
5 WHITESPACE@[3; 4)
6 TRAIT_KW@[4; 9)
7 WHITESPACE@[9; 10)
8 NAME@[10; 22)
9 IDENT@[10; 22) "WriteMessage"
10 WHITESPACE@[22; 23)
11 ITEM_LIST@[23; 66)
12 L_CURLY@[23; 24)
13 WHITESPACE@[24; 29)
14 FN_DEF@[29; 64)
15 FN_KW@[29; 31)
16 WHITESPACE@[31; 32)
17 NAME@[32; 45)
18 IDENT@[32; 45) "write_message"
19 PARAM_LIST@[45; 63)
20 L_PAREN@[45; 46)
21 PARAM@[46; 62)
22 REFERENCE_TYPE@[46; 62)
23 AMP@[46; 47)
24 PATH_TYPE@[47; 62)
25 PATH@[47; 62)
26 PATH_SEGMENT@[47; 62)
27 NAME_REF@[47; 62)
28 IDENT@[47; 62) "FrontendMessage"
29 R_PAREN@[62; 63)
30 SEMI@[63; 64)
31 WHITESPACE@[64; 65)
32 R_CURLY@[65; 66)
33 WHITESPACE@[66; 68)
34 TRAIT_DEF@[68; 104)
35 TRAIT_KW@[68; 73)
36 WHITESPACE@[73; 74)
37 NAME@[74; 82)
38 IDENT@[74; 82) "Runnable"
39 WHITESPACE@[82; 83)
40 ITEM_LIST@[83; 104)
41 L_CURLY@[83; 84)
42 WHITESPACE@[84; 89)
43 FN_DEF@[89; 102)
44 FN_KW@[89; 91)
45 WHITESPACE@[91; 92)
46 NAME@[92; 99)
47 IDENT@[92; 99) "handler"
48 PARAM_LIST@[99; 101)
49 L_PAREN@[99; 100)
50 R_PAREN@[100; 101)
51 SEMI@[101; 102)
52 WHITESPACE@[102; 103)
53 R_CURLY@[103; 104)
54 WHITESPACE@[104; 106)
55 TRAIT_DEF@[106; 163)
56 TRAIT_KW@[106; 111)
57 WHITESPACE@[111; 112)
58 NAME@[112; 125)
59 IDENT@[112; 125) "TraitWithExpr"
60 WHITESPACE@[125; 126)
61 ITEM_LIST@[126; 163)
62 L_CURLY@[126; 127)
63 WHITESPACE@[127; 132)
64 FN_DEF@[132; 161)
65 FN_KW@[132; 134)
66 WHITESPACE@[134; 135)
67 NAME@[135; 147)
68 IDENT@[135; 147) "fn_with_expr"
69 PARAM_LIST@[147; 160)
70 L_PAREN@[147; 148)
71 PARAM@[148; 159)
72 BIND_PAT@[148; 149)
73 NAME@[148; 149)
74 IDENT@[148; 149) "x"
75 COLON@[149; 150)
76 WHITESPACE@[150; 151)
77 ARRAY_TYPE@[151; 159)
78 L_BRACK@[151; 152)
79 PATH_TYPE@[152; 155)
80 PATH@[152; 155)
81 PATH_SEGMENT@[152; 155)
82 NAME_REF@[152; 155)
83 IDENT@[152; 155) "i32"
84 SEMI@[155; 156)
85 WHITESPACE@[156; 157)
86 LITERAL@[157; 158)
87 INT_NUMBER@[157; 158) "1"
88 R_BRACK@[158; 159)
89 R_PAREN@[159; 160)
90 SEMI@[160; 161)
91 WHITESPACE@[161; 162)
92 R_CURLY@[162; 163)
93 WHITESPACE@[163; 164)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0031_extern.rs b/crates/ra_syntax/tests/data/parser/ok/0031_extern.rs
new file mode 100644
index 000000000..b33ac273c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0031_extern.rs
@@ -0,0 +1,29 @@
1extern {
2 pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int;
3 pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) -> ::c_int;
4 pub fn connect(socket: ::c_int, address: *const sockaddr,
5 len: socklen_t) -> ::c_int;
6 pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int;
7 pub fn getsockname(socket: ::c_int, address: *mut sockaddr,
8 address_len: *mut socklen_t) -> ::c_int;
9 pub fn getsockopt(sockfd: ::c_int,
10 level: ::c_int,
11 optname: ::c_int,
12 optval: *mut ::c_void,
13 optlen: *mut ::socklen_t) -> ::c_int;
14 pub fn setsockopt(socket: ::c_int, level: ::c_int, name: ::c_int,
15 value: *const ::c_void,
16 option_len: socklen_t) -> ::c_int;
17 pub fn getpeername(socket: ::c_int, address: *mut sockaddr,
18 address_len: *mut socklen_t) -> ::c_int;
19 pub fn sendto(socket: ::c_int, buf: *const ::c_void, len: ::size_t,
20 flags: ::c_int, addr: *const sockaddr,
21 addrlen: socklen_t) -> ::ssize_t;
22 pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t,
23 flags: ::c_int) -> ::ssize_t;
24 pub fn recvfrom(socket: ::c_int, buf: *mut ::c_void, len: ::size_t,
25 flags: ::c_int, addr: *mut ::sockaddr,
26 addrlen: *mut ::socklen_t) -> ::ssize_t;
27 pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t,
28 flags: ::c_int) -> ::ssize_t;
29}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0031_extern.txt b/crates/ra_syntax/tests/data/parser/ok/0031_extern.txt
new file mode 100644
index 000000000..f3f1c25a9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0031_extern.txt
@@ -0,0 +1,973 @@
1ROOT@[0; 1598)
2 EXTERN_BLOCK@[0; 1597)
3 ABI@[0; 6)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 EXTERN_ITEM_LIST@[7; 1597)
7 L_CURLY@[7; 8)
8 WHITESPACE@[8; 13)
9 FN_DEF@[13; 87)
10 VISIBILITY@[13; 16)
11 PUB_KW@[13; 16)
12 WHITESPACE@[16; 17)
13 FN_KW@[17; 19)
14 WHITESPACE@[19; 20)
15 NAME@[20; 26)
16 IDENT@[20; 26) "socket"
17 PARAM_LIST@[26; 75)
18 L_PAREN@[26; 27)
19 PARAM@[27; 42)
20 BIND_PAT@[27; 33)
21 NAME@[27; 33)
22 IDENT@[27; 33) "domain"
23 COLON@[33; 34)
24 WHITESPACE@[34; 35)
25 PATH_TYPE@[35; 42)
26 PATH@[35; 42)
27 PATH_SEGMENT@[35; 42)
28 COLONCOLON@[35; 37)
29 NAME_REF@[37; 42)
30 IDENT@[37; 42) "c_int"
31 COMMA@[42; 43)
32 WHITESPACE@[43; 44)
33 PARAM@[44; 55)
34 BIND_PAT@[44; 46)
35 NAME@[44; 46)
36 IDENT@[44; 46) "ty"
37 COLON@[46; 47)
38 WHITESPACE@[47; 48)
39 PATH_TYPE@[48; 55)
40 PATH@[48; 55)
41 PATH_SEGMENT@[48; 55)
42 COLONCOLON@[48; 50)
43 NAME_REF@[50; 55)
44 IDENT@[50; 55) "c_int"
45 COMMA@[55; 56)
46 WHITESPACE@[56; 57)
47 PARAM@[57; 74)
48 BIND_PAT@[57; 65)
49 NAME@[57; 65)
50 IDENT@[57; 65) "protocol"
51 COLON@[65; 66)
52 WHITESPACE@[66; 67)
53 PATH_TYPE@[67; 74)
54 PATH@[67; 74)
55 PATH_SEGMENT@[67; 74)
56 COLONCOLON@[67; 69)
57 NAME_REF@[69; 74)
58 IDENT@[69; 74) "c_int"
59 R_PAREN@[74; 75)
60 WHITESPACE@[75; 76)
61 RET_TYPE@[76; 86)
62 THIN_ARROW@[76; 78)
63 WHITESPACE@[78; 79)
64 PATH_TYPE@[79; 86)
65 PATH@[79; 86)
66 PATH_SEGMENT@[79; 86)
67 COLONCOLON@[79; 81)
68 NAME_REF@[81; 86)
69 IDENT@[81; 86) "c_int"
70 SEMI@[86; 87)
71 WHITESPACE@[87; 92)
72 FN_DEF@[92; 167)
73 VISIBILITY@[92; 95)
74 PUB_KW@[92; 95)
75 WHITESPACE@[95; 96)
76 FN_KW@[96; 98)
77 WHITESPACE@[98; 99)
78 NAME@[99; 103)
79 IDENT@[99; 103) "bind"
80 PARAM_LIST@[103; 155)
81 L_PAREN@[103; 104)
82 PARAM@[104; 115)
83 BIND_PAT@[104; 106)
84 NAME@[104; 106)
85 IDENT@[104; 106) "fd"
86 COLON@[106; 107)
87 WHITESPACE@[107; 108)
88 PATH_TYPE@[108; 115)
89 PATH@[108; 115)
90 PATH_SEGMENT@[108; 115)
91 COLONCOLON@[108; 110)
92 NAME_REF@[110; 115)
93 IDENT@[110; 115) "c_int"
94 COMMA@[115; 116)
95 WHITESPACE@[116; 117)
96 PARAM@[117; 138)
97 BIND_PAT@[117; 121)
98 NAME@[117; 121)
99 IDENT@[117; 121) "addr"
100 COLON@[121; 122)
101 WHITESPACE@[122; 123)
102 POINTER_TYPE@[123; 138)
103 STAR@[123; 124)
104 CONST_KW@[124; 129)
105 WHITESPACE@[129; 130)
106 PATH_TYPE@[130; 138)
107 PATH@[130; 138)
108 PATH_SEGMENT@[130; 138)
109 NAME_REF@[130; 138)
110 IDENT@[130; 138) "sockaddr"
111 COMMA@[138; 139)
112 WHITESPACE@[139; 140)
113 PARAM@[140; 154)
114 BIND_PAT@[140; 143)
115 NAME@[140; 143)
116 IDENT@[140; 143) "len"
117 COLON@[143; 144)
118 WHITESPACE@[144; 145)
119 PATH_TYPE@[145; 154)
120 PATH@[145; 154)
121 PATH_SEGMENT@[145; 154)
122 NAME_REF@[145; 154)
123 IDENT@[145; 154) "socklen_t"
124 R_PAREN@[154; 155)
125 WHITESPACE@[155; 156)
126 RET_TYPE@[156; 166)
127 THIN_ARROW@[156; 158)
128 WHITESPACE@[158; 159)
129 PATH_TYPE@[159; 166)
130 PATH@[159; 166)
131 PATH_SEGMENT@[159; 166)
132 COLONCOLON@[159; 161)
133 NAME_REF@[161; 166)
134 IDENT@[161; 166) "c_int"
135 SEMI@[166; 167)
136 WHITESPACE@[167; 172)
137 FN_DEF@[172; 276)
138 VISIBILITY@[172; 175)
139 PUB_KW@[172; 175)
140 WHITESPACE@[175; 176)
141 FN_KW@[176; 178)
142 WHITESPACE@[178; 179)
143 NAME@[179; 186)
144 IDENT@[179; 186) "connect"
145 PARAM_LIST@[186; 264)
146 L_PAREN@[186; 187)
147 PARAM@[187; 202)
148 BIND_PAT@[187; 193)
149 NAME@[187; 193)
150 IDENT@[187; 193) "socket"
151 COLON@[193; 194)
152 WHITESPACE@[194; 195)
153 PATH_TYPE@[195; 202)
154 PATH@[195; 202)
155 PATH_SEGMENT@[195; 202)
156 COLONCOLON@[195; 197)
157 NAME_REF@[197; 202)
158 IDENT@[197; 202) "c_int"
159 COMMA@[202; 203)
160 WHITESPACE@[203; 204)
161 PARAM@[204; 228)
162 BIND_PAT@[204; 211)
163 NAME@[204; 211)
164 IDENT@[204; 211) "address"
165 COLON@[211; 212)
166 WHITESPACE@[212; 213)
167 POINTER_TYPE@[213; 228)
168 STAR@[213; 214)
169 CONST_KW@[214; 219)
170 WHITESPACE@[219; 220)
171 PATH_TYPE@[220; 228)
172 PATH@[220; 228)
173 PATH_SEGMENT@[220; 228)
174 NAME_REF@[220; 228)
175 IDENT@[220; 228) "sockaddr"
176 COMMA@[228; 229)
177 WHITESPACE@[229; 249)
178 PARAM@[249; 263)
179 BIND_PAT@[249; 252)
180 NAME@[249; 252)
181 IDENT@[249; 252) "len"
182 COLON@[252; 253)
183 WHITESPACE@[253; 254)
184 PATH_TYPE@[254; 263)
185 PATH@[254; 263)
186 PATH_SEGMENT@[254; 263)
187 NAME_REF@[254; 263)
188 IDENT@[254; 263) "socklen_t"
189 R_PAREN@[263; 264)
190 WHITESPACE@[264; 265)
191 RET_TYPE@[265; 275)
192 THIN_ARROW@[265; 267)
193 WHITESPACE@[267; 268)
194 PATH_TYPE@[268; 275)
195 PATH@[268; 275)
196 PATH_SEGMENT@[268; 275)
197 COLONCOLON@[268; 270)
198 NAME_REF@[270; 275)
199 IDENT@[270; 275) "c_int"
200 SEMI@[275; 276)
201 WHITESPACE@[276; 281)
202 FN_DEF@[281; 341)
203 VISIBILITY@[281; 284)
204 PUB_KW@[281; 284)
205 WHITESPACE@[284; 285)
206 FN_KW@[285; 287)
207 WHITESPACE@[287; 288)
208 NAME@[288; 294)
209 IDENT@[288; 294) "listen"
210 PARAM_LIST@[294; 329)
211 L_PAREN@[294; 295)
212 PARAM@[295; 310)
213 BIND_PAT@[295; 301)
214 NAME@[295; 301)
215 IDENT@[295; 301) "socket"
216 COLON@[301; 302)
217 WHITESPACE@[302; 303)
218 PATH_TYPE@[303; 310)
219 PATH@[303; 310)
220 PATH_SEGMENT@[303; 310)
221 COLONCOLON@[303; 305)
222 NAME_REF@[305; 310)
223 IDENT@[305; 310) "c_int"
224 COMMA@[310; 311)
225 WHITESPACE@[311; 312)
226 PARAM@[312; 328)
227 BIND_PAT@[312; 319)
228 NAME@[312; 319)
229 IDENT@[312; 319) "backlog"
230 COLON@[319; 320)
231 WHITESPACE@[320; 321)
232 PATH_TYPE@[321; 328)
233 PATH@[321; 328)
234 PATH_SEGMENT@[321; 328)
235 COLONCOLON@[321; 323)
236 NAME_REF@[323; 328)
237 IDENT@[323; 328) "c_int"
238 R_PAREN@[328; 329)
239 WHITESPACE@[329; 330)
240 RET_TYPE@[330; 340)
241 THIN_ARROW@[330; 332)
242 WHITESPACE@[332; 333)
243 PATH_TYPE@[333; 340)
244 PATH@[333; 340)
245 PATH_SEGMENT@[333; 340)
246 COLONCOLON@[333; 335)
247 NAME_REF@[335; 340)
248 IDENT@[335; 340) "c_int"
249 SEMI@[340; 341)
250 WHITESPACE@[341; 346)
251 FN_DEF@[346; 469)
252 VISIBILITY@[346; 349)
253 PUB_KW@[346; 349)
254 WHITESPACE@[349; 350)
255 FN_KW@[350; 352)
256 WHITESPACE@[352; 353)
257 NAME@[353; 364)
258 IDENT@[353; 364) "getsockname"
259 PARAM_LIST@[364; 457)
260 L_PAREN@[364; 365)
261 PARAM@[365; 380)
262 BIND_PAT@[365; 371)
263 NAME@[365; 371)
264 IDENT@[365; 371) "socket"
265 COLON@[371; 372)
266 WHITESPACE@[372; 373)
267 PATH_TYPE@[373; 380)
268 PATH@[373; 380)
269 PATH_SEGMENT@[373; 380)
270 COLONCOLON@[373; 375)
271 NAME_REF@[375; 380)
272 IDENT@[375; 380) "c_int"
273 COMMA@[380; 381)
274 WHITESPACE@[381; 382)
275 PARAM@[382; 404)
276 BIND_PAT@[382; 389)
277 NAME@[382; 389)
278 IDENT@[382; 389) "address"
279 COLON@[389; 390)
280 WHITESPACE@[390; 391)
281 POINTER_TYPE@[391; 404)
282 STAR@[391; 392)
283 MUT_KW@[392; 395)
284 WHITESPACE@[395; 396)
285 PATH_TYPE@[396; 404)
286 PATH@[396; 404)
287 PATH_SEGMENT@[396; 404)
288 NAME_REF@[396; 404)
289 IDENT@[396; 404) "sockaddr"
290 COMMA@[404; 405)
291 WHITESPACE@[405; 429)
292 PARAM@[429; 456)
293 BIND_PAT@[429; 440)
294 NAME@[429; 440)
295 IDENT@[429; 440) "address_len"
296 COLON@[440; 441)
297 WHITESPACE@[441; 442)
298 POINTER_TYPE@[442; 456)
299 STAR@[442; 443)
300 MUT_KW@[443; 446)
301 WHITESPACE@[446; 447)
302 PATH_TYPE@[447; 456)
303 PATH@[447; 456)
304 PATH_SEGMENT@[447; 456)
305 NAME_REF@[447; 456)
306 IDENT@[447; 456) "socklen_t"
307 R_PAREN@[456; 457)
308 WHITESPACE@[457; 458)
309 RET_TYPE@[458; 468)
310 THIN_ARROW@[458; 460)
311 WHITESPACE@[460; 461)
312 PATH_TYPE@[461; 468)
313 PATH@[461; 468)
314 PATH_SEGMENT@[461; 468)
315 COLONCOLON@[461; 463)
316 NAME_REF@[463; 468)
317 IDENT@[463; 468) "c_int"
318 SEMI@[468; 469)
319 WHITESPACE@[469; 474)
320 FN_DEF@[474; 691)
321 VISIBILITY@[474; 477)
322 PUB_KW@[474; 477)
323 WHITESPACE@[477; 478)
324 FN_KW@[478; 480)
325 WHITESPACE@[480; 481)
326 NAME@[481; 491)
327 IDENT@[481; 491) "getsockopt"
328 PARAM_LIST@[491; 679)
329 L_PAREN@[491; 492)
330 PARAM@[492; 507)
331 BIND_PAT@[492; 498)
332 NAME@[492; 498)
333 IDENT@[492; 498) "sockfd"
334 COLON@[498; 499)
335 WHITESPACE@[499; 500)
336 PATH_TYPE@[500; 507)
337 PATH@[500; 507)
338 PATH_SEGMENT@[500; 507)
339 COLONCOLON@[500; 502)
340 NAME_REF@[502; 507)
341 IDENT@[502; 507) "c_int"
342 COMMA@[507; 508)
343 WHITESPACE@[508; 531)
344 PARAM@[531; 545)
345 BIND_PAT@[531; 536)
346 NAME@[531; 536)
347 IDENT@[531; 536) "level"
348 COLON@[536; 537)
349 WHITESPACE@[537; 538)
350 PATH_TYPE@[538; 545)
351 PATH@[538; 545)
352 PATH_SEGMENT@[538; 545)
353 COLONCOLON@[538; 540)
354 NAME_REF@[540; 545)
355 IDENT@[540; 545) "c_int"
356 COMMA@[545; 546)
357 WHITESPACE@[546; 569)
358 PARAM@[569; 585)
359 BIND_PAT@[569; 576)
360 NAME@[569; 576)
361 IDENT@[569; 576) "optname"
362 COLON@[576; 577)
363 WHITESPACE@[577; 578)
364 PATH_TYPE@[578; 585)
365 PATH@[578; 585)
366 PATH_SEGMENT@[578; 585)
367 COLONCOLON@[578; 580)
368 NAME_REF@[580; 585)
369 IDENT@[580; 585) "c_int"
370 COMMA@[585; 586)
371 WHITESPACE@[586; 609)
372 PARAM@[609; 630)
373 BIND_PAT@[609; 615)
374 NAME@[609; 615)
375 IDENT@[609; 615) "optval"
376 COLON@[615; 616)
377 WHITESPACE@[616; 617)
378 POINTER_TYPE@[617; 630)
379 STAR@[617; 618)
380 MUT_KW@[618; 621)
381 WHITESPACE@[621; 622)
382 PATH_TYPE@[622; 630)
383 PATH@[622; 630)
384 PATH_SEGMENT@[622; 630)
385 COLONCOLON@[622; 624)
386 NAME_REF@[624; 630)
387 IDENT@[624; 630) "c_void"
388 COMMA@[630; 631)
389 WHITESPACE@[631; 654)
390 PARAM@[654; 678)
391 BIND_PAT@[654; 660)
392 NAME@[654; 660)
393 IDENT@[654; 660) "optlen"
394 COLON@[660; 661)
395 WHITESPACE@[661; 662)
396 POINTER_TYPE@[662; 678)
397 STAR@[662; 663)
398 MUT_KW@[663; 666)
399 WHITESPACE@[666; 667)
400 PATH_TYPE@[667; 678)
401 PATH@[667; 678)
402 PATH_SEGMENT@[667; 678)
403 COLONCOLON@[667; 669)
404 NAME_REF@[669; 678)
405 IDENT@[669; 678) "socklen_t"
406 R_PAREN@[678; 679)
407 WHITESPACE@[679; 680)
408 RET_TYPE@[680; 690)
409 THIN_ARROW@[680; 682)
410 WHITESPACE@[682; 683)
411 PATH_TYPE@[683; 690)
412 PATH@[683; 690)
413 PATH_SEGMENT@[683; 690)
414 COLONCOLON@[683; 685)
415 NAME_REF@[685; 690)
416 IDENT@[685; 690) "c_int"
417 SEMI@[690; 691)
418 WHITESPACE@[691; 696)
419 FN_DEF@[696; 864)
420 VISIBILITY@[696; 699)
421 PUB_KW@[696; 699)
422 WHITESPACE@[699; 700)
423 FN_KW@[700; 702)
424 WHITESPACE@[702; 703)
425 NAME@[703; 713)
426 IDENT@[703; 713) "setsockopt"
427 PARAM_LIST@[713; 852)
428 L_PAREN@[713; 714)
429 PARAM@[714; 729)
430 BIND_PAT@[714; 720)
431 NAME@[714; 720)
432 IDENT@[714; 720) "socket"
433 COLON@[720; 721)
434 WHITESPACE@[721; 722)
435 PATH_TYPE@[722; 729)
436 PATH@[722; 729)
437 PATH_SEGMENT@[722; 729)
438 COLONCOLON@[722; 724)
439 NAME_REF@[724; 729)
440 IDENT@[724; 729) "c_int"
441 COMMA@[729; 730)
442 WHITESPACE@[730; 731)
443 PARAM@[731; 745)
444 BIND_PAT@[731; 736)
445 NAME@[731; 736)
446 IDENT@[731; 736) "level"
447 COLON@[736; 737)
448 WHITESPACE@[737; 738)
449 PATH_TYPE@[738; 745)
450 PATH@[738; 745)
451 PATH_SEGMENT@[738; 745)
452 COLONCOLON@[738; 740)
453 NAME_REF@[740; 745)
454 IDENT@[740; 745) "c_int"
455 COMMA@[745; 746)
456 WHITESPACE@[746; 747)
457 PARAM@[747; 760)
458 BIND_PAT@[747; 751)
459 NAME@[747; 751)
460 IDENT@[747; 751) "name"
461 COLON@[751; 752)
462 WHITESPACE@[752; 753)
463 PATH_TYPE@[753; 760)
464 PATH@[753; 760)
465 PATH_SEGMENT@[753; 760)
466 COLONCOLON@[753; 755)
467 NAME_REF@[755; 760)
468 IDENT@[755; 760) "c_int"
469 COMMA@[760; 761)
470 WHITESPACE@[761; 784)
471 PARAM@[784; 806)
472 BIND_PAT@[784; 789)
473 NAME@[784; 789)
474 IDENT@[784; 789) "value"
475 COLON@[789; 790)
476 WHITESPACE@[790; 791)
477 POINTER_TYPE@[791; 806)
478 STAR@[791; 792)
479 CONST_KW@[792; 797)
480 WHITESPACE@[797; 798)
481 PATH_TYPE@[798; 806)
482 PATH@[798; 806)
483 PATH_SEGMENT@[798; 806)
484 COLONCOLON@[798; 800)
485 NAME_REF@[800; 806)
486 IDENT@[800; 806) "c_void"
487 COMMA@[806; 807)
488 WHITESPACE@[807; 830)
489 PARAM@[830; 851)
490 BIND_PAT@[830; 840)
491 NAME@[830; 840)
492 IDENT@[830; 840) "option_len"
493 COLON@[840; 841)
494 WHITESPACE@[841; 842)
495 PATH_TYPE@[842; 851)
496 PATH@[842; 851)
497 PATH_SEGMENT@[842; 851)
498 NAME_REF@[842; 851)
499 IDENT@[842; 851) "socklen_t"
500 R_PAREN@[851; 852)
501 WHITESPACE@[852; 853)
502 RET_TYPE@[853; 863)
503 THIN_ARROW@[853; 855)
504 WHITESPACE@[855; 856)
505 PATH_TYPE@[856; 863)
506 PATH@[856; 863)
507 PATH_SEGMENT@[856; 863)
508 COLONCOLON@[856; 858)
509 NAME_REF@[858; 863)
510 IDENT@[858; 863) "c_int"
511 SEMI@[863; 864)
512 WHITESPACE@[864; 869)
513 FN_DEF@[869; 992)
514 VISIBILITY@[869; 872)
515 PUB_KW@[869; 872)
516 WHITESPACE@[872; 873)
517 FN_KW@[873; 875)
518 WHITESPACE@[875; 876)
519 NAME@[876; 887)
520 IDENT@[876; 887) "getpeername"
521 PARAM_LIST@[887; 980)
522 L_PAREN@[887; 888)
523 PARAM@[888; 903)
524 BIND_PAT@[888; 894)
525 NAME@[888; 894)
526 IDENT@[888; 894) "socket"
527 COLON@[894; 895)
528 WHITESPACE@[895; 896)
529 PATH_TYPE@[896; 903)
530 PATH@[896; 903)
531 PATH_SEGMENT@[896; 903)
532 COLONCOLON@[896; 898)
533 NAME_REF@[898; 903)
534 IDENT@[898; 903) "c_int"
535 COMMA@[903; 904)
536 WHITESPACE@[904; 905)
537 PARAM@[905; 927)
538 BIND_PAT@[905; 912)
539 NAME@[905; 912)
540 IDENT@[905; 912) "address"
541 COLON@[912; 913)
542 WHITESPACE@[913; 914)
543 POINTER_TYPE@[914; 927)
544 STAR@[914; 915)
545 MUT_KW@[915; 918)
546 WHITESPACE@[918; 919)
547 PATH_TYPE@[919; 927)
548 PATH@[919; 927)
549 PATH_SEGMENT@[919; 927)
550 NAME_REF@[919; 927)
551 IDENT@[919; 927) "sockaddr"
552 COMMA@[927; 928)
553 WHITESPACE@[928; 952)
554 PARAM@[952; 979)
555 BIND_PAT@[952; 963)
556 NAME@[952; 963)
557 IDENT@[952; 963) "address_len"
558 COLON@[963; 964)
559 WHITESPACE@[964; 965)
560 POINTER_TYPE@[965; 979)
561 STAR@[965; 966)
562 MUT_KW@[966; 969)
563 WHITESPACE@[969; 970)
564 PATH_TYPE@[970; 979)
565 PATH@[970; 979)
566 PATH_SEGMENT@[970; 979)
567 NAME_REF@[970; 979)
568 IDENT@[970; 979) "socklen_t"
569 R_PAREN@[979; 980)
570 WHITESPACE@[980; 981)
571 RET_TYPE@[981; 991)
572 THIN_ARROW@[981; 983)
573 WHITESPACE@[983; 984)
574 PATH_TYPE@[984; 991)
575 PATH@[984; 991)
576 PATH_SEGMENT@[984; 991)
577 COLONCOLON@[984; 986)
578 NAME_REF@[986; 991)
579 IDENT@[986; 991) "c_int"
580 SEMI@[991; 992)
581 WHITESPACE@[992; 997)
582 FN_DEF@[997; 1173)
583 VISIBILITY@[997; 1000)
584 PUB_KW@[997; 1000)
585 WHITESPACE@[1000; 1001)
586 FN_KW@[1001; 1003)
587 WHITESPACE@[1003; 1004)
588 NAME@[1004; 1010)
589 IDENT@[1004; 1010) "sendto"
590 PARAM_LIST@[1010; 1159)
591 L_PAREN@[1010; 1011)
592 PARAM@[1011; 1026)
593 BIND_PAT@[1011; 1017)
594 NAME@[1011; 1017)
595 IDENT@[1011; 1017) "socket"
596 COLON@[1017; 1018)
597 WHITESPACE@[1018; 1019)
598 PATH_TYPE@[1019; 1026)
599 PATH@[1019; 1026)
600 PATH_SEGMENT@[1019; 1026)
601 COLONCOLON@[1019; 1021)
602 NAME_REF@[1021; 1026)
603 IDENT@[1021; 1026) "c_int"
604 COMMA@[1026; 1027)
605 WHITESPACE@[1027; 1028)
606 PARAM@[1028; 1048)
607 BIND_PAT@[1028; 1031)
608 NAME@[1028; 1031)
609 IDENT@[1028; 1031) "buf"
610 COLON@[1031; 1032)
611 WHITESPACE@[1032; 1033)
612 POINTER_TYPE@[1033; 1048)
613 STAR@[1033; 1034)
614 CONST_KW@[1034; 1039)
615 WHITESPACE@[1039; 1040)
616 PATH_TYPE@[1040; 1048)
617 PATH@[1040; 1048)
618 PATH_SEGMENT@[1040; 1048)
619 COLONCOLON@[1040; 1042)
620 NAME_REF@[1042; 1048)
621 IDENT@[1042; 1048) "c_void"
622 COMMA@[1048; 1049)
623 WHITESPACE@[1049; 1050)
624 PARAM@[1050; 1063)
625 BIND_PAT@[1050; 1053)
626 NAME@[1050; 1053)
627 IDENT@[1050; 1053) "len"
628 COLON@[1053; 1054)
629 WHITESPACE@[1054; 1055)
630 PATH_TYPE@[1055; 1063)
631 PATH@[1055; 1063)
632 PATH_SEGMENT@[1055; 1063)
633 COLONCOLON@[1055; 1057)
634 NAME_REF@[1057; 1063)
635 IDENT@[1057; 1063) "size_t"
636 COMMA@[1063; 1064)
637 WHITESPACE@[1064; 1083)
638 PARAM@[1083; 1097)
639 BIND_PAT@[1083; 1088)
640 NAME@[1083; 1088)
641 IDENT@[1083; 1088) "flags"
642 COLON@[1088; 1089)
643 WHITESPACE@[1089; 1090)
644 PATH_TYPE@[1090; 1097)
645 PATH@[1090; 1097)
646 PATH_SEGMENT@[1090; 1097)
647 COLONCOLON@[1090; 1092)
648 NAME_REF@[1092; 1097)
649 IDENT@[1092; 1097) "c_int"
650 COMMA@[1097; 1098)
651 WHITESPACE@[1098; 1099)
652 PARAM@[1099; 1120)
653 BIND_PAT@[1099; 1103)
654 NAME@[1099; 1103)
655 IDENT@[1099; 1103) "addr"
656 COLON@[1103; 1104)
657 WHITESPACE@[1104; 1105)
658 POINTER_TYPE@[1105; 1120)
659 STAR@[1105; 1106)
660 CONST_KW@[1106; 1111)
661 WHITESPACE@[1111; 1112)
662 PATH_TYPE@[1112; 1120)
663 PATH@[1112; 1120)
664 PATH_SEGMENT@[1112; 1120)
665 NAME_REF@[1112; 1120)
666 IDENT@[1112; 1120) "sockaddr"
667 COMMA@[1120; 1121)
668 WHITESPACE@[1121; 1140)
669 PARAM@[1140; 1158)
670 BIND_PAT@[1140; 1147)
671 NAME@[1140; 1147)
672 IDENT@[1140; 1147) "addrlen"
673 COLON@[1147; 1148)
674 WHITESPACE@[1148; 1149)
675 PATH_TYPE@[1149; 1158)
676 PATH@[1149; 1158)
677 PATH_SEGMENT@[1149; 1158)
678 NAME_REF@[1149; 1158)
679 IDENT@[1149; 1158) "socklen_t"
680 R_PAREN@[1158; 1159)
681 WHITESPACE@[1159; 1160)
682 RET_TYPE@[1160; 1172)
683 THIN_ARROW@[1160; 1162)
684 WHITESPACE@[1162; 1163)
685 PATH_TYPE@[1163; 1172)
686 PATH@[1163; 1172)
687 PATH_SEGMENT@[1163; 1172)
688 COLONCOLON@[1163; 1165)
689 NAME_REF@[1165; 1172)
690 IDENT@[1165; 1172) "ssize_t"
691 SEMI@[1172; 1173)
692 WHITESPACE@[1173; 1178)
693 FN_DEF@[1178; 1289)
694 VISIBILITY@[1178; 1181)
695 PUB_KW@[1178; 1181)
696 WHITESPACE@[1181; 1182)
697 FN_KW@[1182; 1184)
698 WHITESPACE@[1184; 1185)
699 NAME@[1185; 1189)
700 IDENT@[1185; 1189) "send"
701 PARAM_LIST@[1189; 1275)
702 L_PAREN@[1189; 1190)
703 PARAM@[1190; 1205)
704 BIND_PAT@[1190; 1196)
705 NAME@[1190; 1196)
706 IDENT@[1190; 1196) "socket"
707 COLON@[1196; 1197)
708 WHITESPACE@[1197; 1198)
709 PATH_TYPE@[1198; 1205)
710 PATH@[1198; 1205)
711 PATH_SEGMENT@[1198; 1205)
712 COLONCOLON@[1198; 1200)
713 NAME_REF@[1200; 1205)
714 IDENT@[1200; 1205) "c_int"
715 COMMA@[1205; 1206)
716 WHITESPACE@[1206; 1207)
717 PARAM@[1207; 1227)
718 BIND_PAT@[1207; 1210)
719 NAME@[1207; 1210)
720 IDENT@[1207; 1210) "buf"
721 COLON@[1210; 1211)
722 WHITESPACE@[1211; 1212)
723 POINTER_TYPE@[1212; 1227)
724 STAR@[1212; 1213)
725 CONST_KW@[1213; 1218)
726 WHITESPACE@[1218; 1219)
727 PATH_TYPE@[1219; 1227)
728 PATH@[1219; 1227)
729 PATH_SEGMENT@[1219; 1227)
730 COLONCOLON@[1219; 1221)
731 NAME_REF@[1221; 1227)
732 IDENT@[1221; 1227) "c_void"
733 COMMA@[1227; 1228)
734 WHITESPACE@[1228; 1229)
735 PARAM@[1229; 1242)
736 BIND_PAT@[1229; 1232)
737 NAME@[1229; 1232)
738 IDENT@[1229; 1232) "len"
739 COLON@[1232; 1233)
740 WHITESPACE@[1233; 1234)
741 PATH_TYPE@[1234; 1242)
742 PATH@[1234; 1242)
743 PATH_SEGMENT@[1234; 1242)
744 COLONCOLON@[1234; 1236)
745 NAME_REF@[1236; 1242)
746 IDENT@[1236; 1242) "size_t"
747 COMMA@[1242; 1243)
748 WHITESPACE@[1243; 1260)
749 PARAM@[1260; 1274)
750 BIND_PAT@[1260; 1265)
751 NAME@[1260; 1265)
752 IDENT@[1260; 1265) "flags"
753 COLON@[1265; 1266)
754 WHITESPACE@[1266; 1267)
755 PATH_TYPE@[1267; 1274)
756 PATH@[1267; 1274)
757 PATH_SEGMENT@[1267; 1274)
758 COLONCOLON@[1267; 1269)
759 NAME_REF@[1269; 1274)
760 IDENT@[1269; 1274) "c_int"
761 R_PAREN@[1274; 1275)
762 WHITESPACE@[1275; 1276)
763 RET_TYPE@[1276; 1288)
764 THIN_ARROW@[1276; 1278)
765 WHITESPACE@[1278; 1279)
766 PATH_TYPE@[1279; 1288)
767 PATH@[1279; 1288)
768 PATH_SEGMENT@[1279; 1288)
769 COLONCOLON@[1279; 1281)
770 NAME_REF@[1281; 1288)
771 IDENT@[1281; 1288) "ssize_t"
772 SEMI@[1288; 1289)
773 WHITESPACE@[1289; 1294)
774 FN_DEF@[1294; 1481)
775 VISIBILITY@[1294; 1297)
776 PUB_KW@[1294; 1297)
777 WHITESPACE@[1297; 1298)
778 FN_KW@[1298; 1300)
779 WHITESPACE@[1300; 1301)
780 NAME@[1301; 1309)
781 IDENT@[1301; 1309) "recvfrom"
782 PARAM_LIST@[1309; 1467)
783 L_PAREN@[1309; 1310)
784 PARAM@[1310; 1325)
785 BIND_PAT@[1310; 1316)
786 NAME@[1310; 1316)
787 IDENT@[1310; 1316) "socket"
788 COLON@[1316; 1317)
789 WHITESPACE@[1317; 1318)
790 PATH_TYPE@[1318; 1325)
791 PATH@[1318; 1325)
792 PATH_SEGMENT@[1318; 1325)
793 COLONCOLON@[1318; 1320)
794 NAME_REF@[1320; 1325)
795 IDENT@[1320; 1325) "c_int"
796 COMMA@[1325; 1326)
797 WHITESPACE@[1326; 1327)
798 PARAM@[1327; 1345)
799 BIND_PAT@[1327; 1330)
800 NAME@[1327; 1330)
801 IDENT@[1327; 1330) "buf"
802 COLON@[1330; 1331)
803 WHITESPACE@[1331; 1332)
804 POINTER_TYPE@[1332; 1345)
805 STAR@[1332; 1333)
806 MUT_KW@[1333; 1336)
807 WHITESPACE@[1336; 1337)
808 PATH_TYPE@[1337; 1345)
809 PATH@[1337; 1345)
810 PATH_SEGMENT@[1337; 1345)
811 COLONCOLON@[1337; 1339)
812 NAME_REF@[1339; 1345)
813 IDENT@[1339; 1345) "c_void"
814 COMMA@[1345; 1346)
815 WHITESPACE@[1346; 1347)
816 PARAM@[1347; 1360)
817 BIND_PAT@[1347; 1350)
818 NAME@[1347; 1350)
819 IDENT@[1347; 1350) "len"
820 COLON@[1350; 1351)
821 WHITESPACE@[1351; 1352)
822 PATH_TYPE@[1352; 1360)
823 PATH@[1352; 1360)
824 PATH_SEGMENT@[1352; 1360)
825 COLONCOLON@[1352; 1354)
826 NAME_REF@[1354; 1360)
827 IDENT@[1354; 1360) "size_t"
828 COMMA@[1360; 1361)
829 WHITESPACE@[1361; 1382)
830 PARAM@[1382; 1396)
831 BIND_PAT@[1382; 1387)
832 NAME@[1382; 1387)
833 IDENT@[1382; 1387) "flags"
834 COLON@[1387; 1388)
835 WHITESPACE@[1388; 1389)
836 PATH_TYPE@[1389; 1396)
837 PATH@[1389; 1396)
838 PATH_SEGMENT@[1389; 1396)
839 COLONCOLON@[1389; 1391)
840 NAME_REF@[1391; 1396)
841 IDENT@[1391; 1396) "c_int"
842 COMMA@[1396; 1397)
843 WHITESPACE@[1397; 1398)
844 PARAM@[1398; 1419)
845 BIND_PAT@[1398; 1402)
846 NAME@[1398; 1402)
847 IDENT@[1398; 1402) "addr"
848 COLON@[1402; 1403)
849 WHITESPACE@[1403; 1404)
850 POINTER_TYPE@[1404; 1419)
851 STAR@[1404; 1405)
852 MUT_KW@[1405; 1408)
853 WHITESPACE@[1408; 1409)
854 PATH_TYPE@[1409; 1419)
855 PATH@[1409; 1419)
856 PATH_SEGMENT@[1409; 1419)
857 COLONCOLON@[1409; 1411)
858 NAME_REF@[1411; 1419)
859 IDENT@[1411; 1419) "sockaddr"
860 COMMA@[1419; 1420)
861 WHITESPACE@[1420; 1441)
862 PARAM@[1441; 1466)
863 BIND_PAT@[1441; 1448)
864 NAME@[1441; 1448)
865 IDENT@[1441; 1448) "addrlen"
866 COLON@[1448; 1449)
867 WHITESPACE@[1449; 1450)
868 POINTER_TYPE@[1450; 1466)
869 STAR@[1450; 1451)
870 MUT_KW@[1451; 1454)
871 WHITESPACE@[1454; 1455)
872 PATH_TYPE@[1455; 1466)
873 PATH@[1455; 1466)
874 PATH_SEGMENT@[1455; 1466)
875 COLONCOLON@[1455; 1457)
876 NAME_REF@[1457; 1466)
877 IDENT@[1457; 1466) "socklen_t"
878 R_PAREN@[1466; 1467)
879 WHITESPACE@[1467; 1468)
880 RET_TYPE@[1468; 1480)
881 THIN_ARROW@[1468; 1470)
882 WHITESPACE@[1470; 1471)
883 PATH_TYPE@[1471; 1480)
884 PATH@[1471; 1480)
885 PATH_SEGMENT@[1471; 1480)
886 COLONCOLON@[1471; 1473)
887 NAME_REF@[1473; 1480)
888 IDENT@[1473; 1480) "ssize_t"
889 SEMI@[1480; 1481)
890 WHITESPACE@[1481; 1486)
891 FN_DEF@[1486; 1595)
892 VISIBILITY@[1486; 1489)
893 PUB_KW@[1486; 1489)
894 WHITESPACE@[1489; 1490)
895 FN_KW@[1490; 1492)
896 WHITESPACE@[1492; 1493)
897 NAME@[1493; 1497)
898 IDENT@[1493; 1497) "recv"
899 PARAM_LIST@[1497; 1581)
900 L_PAREN@[1497; 1498)
901 PARAM@[1498; 1513)
902 BIND_PAT@[1498; 1504)
903 NAME@[1498; 1504)
904 IDENT@[1498; 1504) "socket"
905 COLON@[1504; 1505)
906 WHITESPACE@[1505; 1506)
907 PATH_TYPE@[1506; 1513)
908 PATH@[1506; 1513)
909 PATH_SEGMENT@[1506; 1513)
910 COLONCOLON@[1506; 1508)
911 NAME_REF@[1508; 1513)
912 IDENT@[1508; 1513) "c_int"
913 COMMA@[1513; 1514)
914 WHITESPACE@[1514; 1515)
915 PARAM@[1515; 1533)
916 BIND_PAT@[1515; 1518)
917 NAME@[1515; 1518)
918 IDENT@[1515; 1518) "buf"
919 COLON@[1518; 1519)
920 WHITESPACE@[1519; 1520)
921 POINTER_TYPE@[1520; 1533)
922 STAR@[1520; 1521)
923 MUT_KW@[1521; 1524)
924 WHITESPACE@[1524; 1525)
925 PATH_TYPE@[1525; 1533)
926 PATH@[1525; 1533)
927 PATH_SEGMENT@[1525; 1533)
928 COLONCOLON@[1525; 1527)
929 NAME_REF@[1527; 1533)
930 IDENT@[1527; 1533) "c_void"
931 COMMA@[1533; 1534)
932 WHITESPACE@[1534; 1535)
933 PARAM@[1535; 1548)
934 BIND_PAT@[1535; 1538)
935 NAME@[1535; 1538)
936 IDENT@[1535; 1538) "len"
937 COLON@[1538; 1539)
938 WHITESPACE@[1539; 1540)
939 PATH_TYPE@[1540; 1548)
940 PATH@[1540; 1548)
941 PATH_SEGMENT@[1540; 1548)
942 COLONCOLON@[1540; 1542)
943 NAME_REF@[1542; 1548)
944 IDENT@[1542; 1548) "size_t"
945 COMMA@[1548; 1549)
946 WHITESPACE@[1549; 1566)
947 PARAM@[1566; 1580)
948 BIND_PAT@[1566; 1571)
949 NAME@[1566; 1571)
950 IDENT@[1566; 1571) "flags"
951 COLON@[1571; 1572)
952 WHITESPACE@[1572; 1573)
953 PATH_TYPE@[1573; 1580)
954 PATH@[1573; 1580)
955 PATH_SEGMENT@[1573; 1580)
956 COLONCOLON@[1573; 1575)
957 NAME_REF@[1575; 1580)
958 IDENT@[1575; 1580) "c_int"
959 R_PAREN@[1580; 1581)
960 WHITESPACE@[1581; 1582)
961 RET_TYPE@[1582; 1594)
962 THIN_ARROW@[1582; 1584)
963 WHITESPACE@[1584; 1585)
964 PATH_TYPE@[1585; 1594)
965 PATH@[1585; 1594)
966 PATH_SEGMENT@[1585; 1594)
967 COLONCOLON@[1585; 1587)
968 NAME_REF@[1587; 1594)
969 IDENT@[1587; 1594) "ssize_t"
970 SEMI@[1594; 1595)
971 WHITESPACE@[1595; 1596)
972 R_CURLY@[1596; 1597)
973 WHITESPACE@[1597; 1598)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs
new file mode 100644
index 000000000..588170fbe
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs
@@ -0,0 +1,4 @@
1fn test_serialization<SER>()
2where
3 SER: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,
4{}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt
new file mode 100644
index 000000000..e3b9386a8
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt
@@ -0,0 +1,85 @@
1ROOT@[0; 116)
2 FN_DEF@[0; 115)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 21)
6 IDENT@[3; 21) "test_serialization"
7 TYPE_PARAM_LIST@[21; 26)
8 L_ANGLE@[21; 22)
9 TYPE_PARAM@[22; 25)
10 NAME@[22; 25)
11 IDENT@[22; 25) "SER"
12 R_ANGLE@[25; 26)
13 PARAM_LIST@[26; 28)
14 L_PAREN@[26; 27)
15 R_PAREN@[27; 28)
16 WHITESPACE@[28; 29)
17 WHERE_CLAUSE@[29; 112)
18 WHERE_KW@[29; 34)
19 WHITESPACE@[34; 39)
20 WHERE_PRED@[39; 111)
21 PATH_TYPE@[39; 42)
22 PATH@[39; 42)
23 PATH_SEGMENT@[39; 42)
24 NAME_REF@[39; 42)
25 IDENT@[39; 42) "SER"
26 COLON@[42; 43)
27 WHITESPACE@[43; 44)
28 PATH_TYPE@[44; 111)
29 PATH@[44; 53)
30 PATH_SEGMENT@[44; 53)
31 NAME_REF@[44; 53)
32 IDENT@[44; 53) "Serialize"
33 WHITESPACE@[53; 54)
34 PLUS@[54; 55)
35 WHITESPACE@[55; 56)
36 FOR_TYPE@[56; 81)
37 FOR_KW@[56; 59)
38 TYPE_PARAM_LIST@[59; 64)
39 L_ANGLE@[59; 60)
40 LIFETIME_PARAM@[60; 63)
41 LIFETIME@[60; 63) "'de"
42 R_ANGLE@[63; 64)
43 WHITESPACE@[64; 65)
44 PATH_TYPE@[65; 81)
45 PATH@[65; 81)
46 PATH_SEGMENT@[65; 81)
47 NAME_REF@[65; 76)
48 IDENT@[65; 76) "Deserialize"
49 TYPE_ARG_LIST@[76; 81)
50 L_ANGLE@[76; 77)
51 LIFETIME_ARG@[77; 80)
52 LIFETIME@[77; 80) "'de"
53 R_ANGLE@[80; 81)
54 WHITESPACE@[81; 82)
55 PLUS@[82; 83)
56 WHITESPACE@[83; 84)
57 PATH_TYPE@[84; 111)
58 PATH@[84; 93)
59 PATH_SEGMENT@[84; 93)
60 NAME_REF@[84; 93)
61 IDENT@[84; 93) "PartialEq"
62 WHITESPACE@[93; 94)
63 PLUS@[94; 95)
64 WHITESPACE@[95; 96)
65 PATH_TYPE@[96; 111)
66 PATH@[96; 111)
67 PATH@[96; 104)
68 PATH@[96; 99)
69 PATH_SEGMENT@[96; 99)
70 NAME_REF@[96; 99)
71 IDENT@[96; 99) "std"
72 COLONCOLON@[99; 101)
73 PATH_SEGMENT@[101; 104)
74 NAME_REF@[101; 104)
75 IDENT@[101; 104) "fmt"
76 COLONCOLON@[104; 106)
77 PATH_SEGMENT@[106; 111)
78 NAME_REF@[106; 111)
79 IDENT@[106; 111) "Debug"
80 COMMA@[111; 112)
81 WHITESPACE@[112; 113)
82 BLOCK@[113; 115)
83 L_CURLY@[113; 114)
84 R_CURLY@[114; 115)
85 WHITESPACE@[115; 116)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs
new file mode 100644
index 000000000..728d78137
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs
@@ -0,0 +1,28 @@
1// format with label break value.
2fn main() {
3 'empty_block: {}
4
5 'block: {
6 do_thing();
7 if condition_not_met() {
8 break 'block;
9 }
10 do_next_thing();
11 if condition_not_met() {
12 break 'block;
13 }
14 do_last_thing();
15 }
16
17 let result = 'block: {
18 if foo() {
19 // comment
20 break 'block 1;
21 }
22 if bar() {
23 /* comment */
24 break 'block 2;
25 }
26 3
27 };
28}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt
new file mode 100644
index 000000000..6abb9234c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt
@@ -0,0 +1,215 @@
1ROOT@[0; 506)
2 COMMENT@[0; 33)
3 WHITESPACE@[33; 34)
4 FN_DEF@[34; 505)
5 FN_KW@[34; 36)
6 WHITESPACE@[36; 37)
7 NAME@[37; 41)
8 IDENT@[37; 41) "main"
9 PARAM_LIST@[41; 43)
10 L_PAREN@[41; 42)
11 R_PAREN@[42; 43)
12 WHITESPACE@[43; 44)
13 BLOCK@[44; 505)
14 L_CURLY@[44; 45)
15 WHITESPACE@[45; 50)
16 EXPR_STMT@[50; 66)
17 BLOCK_EXPR@[50; 66)
18 LABEL@[50; 63)
19 LIFETIME@[50; 62) "'empty_block"
20 COLON@[62; 63)
21 WHITESPACE@[63; 64)
22 BLOCK@[64; 66)
23 L_CURLY@[64; 65)
24 R_CURLY@[65; 66)
25 WHITESPACE@[66; 72)
26 EXPR_STMT@[72; 295)
27 BLOCK_EXPR@[72; 295)
28 LABEL@[72; 79)
29 LIFETIME@[72; 78) "'block"
30 COLON@[78; 79)
31 WHITESPACE@[79; 80)
32 BLOCK@[80; 295)
33 L_CURLY@[80; 81)
34 WHITESPACE@[81; 90)
35 EXPR_STMT@[90; 101)
36 CALL_EXPR@[90; 100)
37 PATH_EXPR@[90; 98)
38 PATH@[90; 98)
39 PATH_SEGMENT@[90; 98)
40 NAME_REF@[90; 98)
41 IDENT@[90; 98) "do_thing"
42 ARG_LIST@[98; 100)
43 L_PAREN@[98; 99)
44 R_PAREN@[99; 100)
45 SEMI@[100; 101)
46 WHITESPACE@[101; 110)
47 EXPR_STMT@[110; 170)
48 IF_EXPR@[110; 170)
49 IF_KW@[110; 112)
50 WHITESPACE@[112; 113)
51 CONDITION@[113; 132)
52 CALL_EXPR@[113; 132)
53 PATH_EXPR@[113; 130)
54 PATH@[113; 130)
55 PATH_SEGMENT@[113; 130)
56 NAME_REF@[113; 130)
57 IDENT@[113; 130) "condition_not_met"
58 ARG_LIST@[130; 132)
59 L_PAREN@[130; 131)
60 R_PAREN@[131; 132)
61 WHITESPACE@[132; 133)
62 BLOCK@[133; 170)
63 L_CURLY@[133; 134)
64 WHITESPACE@[134; 147)
65 EXPR_STMT@[147; 160)
66 BREAK_EXPR@[147; 159)
67 BREAK_KW@[147; 152)
68 WHITESPACE@[152; 153)
69 LIFETIME@[153; 159) "'block"
70 SEMI@[159; 160)
71 WHITESPACE@[160; 169)
72 R_CURLY@[169; 170)
73 WHITESPACE@[170; 179)
74 EXPR_STMT@[179; 195)
75 CALL_EXPR@[179; 194)
76 PATH_EXPR@[179; 192)
77 PATH@[179; 192)
78 PATH_SEGMENT@[179; 192)
79 NAME_REF@[179; 192)
80 IDENT@[179; 192) "do_next_thing"
81 ARG_LIST@[192; 194)
82 L_PAREN@[192; 193)
83 R_PAREN@[193; 194)
84 SEMI@[194; 195)
85 WHITESPACE@[195; 204)
86 EXPR_STMT@[204; 264)
87 IF_EXPR@[204; 264)
88 IF_KW@[204; 206)
89 WHITESPACE@[206; 207)
90 CONDITION@[207; 226)
91 CALL_EXPR@[207; 226)
92 PATH_EXPR@[207; 224)
93 PATH@[207; 224)
94 PATH_SEGMENT@[207; 224)
95 NAME_REF@[207; 224)
96 IDENT@[207; 224) "condition_not_met"
97 ARG_LIST@[224; 226)
98 L_PAREN@[224; 225)
99 R_PAREN@[225; 226)
100 WHITESPACE@[226; 227)
101 BLOCK@[227; 264)
102 L_CURLY@[227; 228)
103 WHITESPACE@[228; 241)
104 EXPR_STMT@[241; 254)
105 BREAK_EXPR@[241; 253)
106 BREAK_KW@[241; 246)
107 WHITESPACE@[246; 247)
108 LIFETIME@[247; 253) "'block"
109 SEMI@[253; 254)
110 WHITESPACE@[254; 263)
111 R_CURLY@[263; 264)
112 WHITESPACE@[264; 273)
113 EXPR_STMT@[273; 289)
114 CALL_EXPR@[273; 288)
115 PATH_EXPR@[273; 286)
116 PATH@[273; 286)
117 PATH_SEGMENT@[273; 286)
118 NAME_REF@[273; 286)
119 IDENT@[273; 286) "do_last_thing"
120 ARG_LIST@[286; 288)
121 L_PAREN@[286; 287)
122 R_PAREN@[287; 288)
123 SEMI@[288; 289)
124 WHITESPACE@[289; 294)
125 R_CURLY@[294; 295)
126 WHITESPACE@[295; 301)
127 LET_STMT@[301; 503)
128 LET_KW@[301; 304)
129 WHITESPACE@[304; 305)
130 BIND_PAT@[305; 311)
131 NAME@[305; 311)
132 IDENT@[305; 311) "result"
133 WHITESPACE@[311; 312)
134 EQ@[312; 313)
135 WHITESPACE@[313; 314)
136 BLOCK_EXPR@[314; 502)
137 LABEL@[314; 321)
138 LIFETIME@[314; 320) "'block"
139 COLON@[320; 321)
140 WHITESPACE@[321; 322)
141 BLOCK@[322; 502)
142 L_CURLY@[322; 323)
143 WHITESPACE@[323; 332)
144 EXPR_STMT@[332; 403)
145 IF_EXPR@[332; 403)
146 IF_KW@[332; 334)
147 WHITESPACE@[334; 335)
148 CONDITION@[335; 340)
149 CALL_EXPR@[335; 340)
150 PATH_EXPR@[335; 338)
151 PATH@[335; 338)
152 PATH_SEGMENT@[335; 338)
153 NAME_REF@[335; 338)
154 IDENT@[335; 338) "foo"
155 ARG_LIST@[338; 340)
156 L_PAREN@[338; 339)
157 R_PAREN@[339; 340)
158 WHITESPACE@[340; 341)
159 BLOCK@[341; 403)
160 L_CURLY@[341; 342)
161 WHITESPACE@[342; 355)
162 COMMENT@[355; 365)
163 WHITESPACE@[365; 378)
164 EXPR_STMT@[378; 393)
165 BREAK_EXPR@[378; 392)
166 BREAK_KW@[378; 383)
167 WHITESPACE@[383; 384)
168 LIFETIME@[384; 390) "'block"
169 WHITESPACE@[390; 391)
170 LITERAL@[391; 392)
171 INT_NUMBER@[391; 392) "1"
172 SEMI@[392; 393)
173 WHITESPACE@[393; 402)
174 R_CURLY@[402; 403)
175 WHITESPACE@[403; 412)
176 EXPR_STMT@[412; 486)
177 IF_EXPR@[412; 486)
178 IF_KW@[412; 414)
179 WHITESPACE@[414; 415)
180 CONDITION@[415; 420)
181 CALL_EXPR@[415; 420)
182 PATH_EXPR@[415; 418)
183 PATH@[415; 418)
184 PATH_SEGMENT@[415; 418)
185 NAME_REF@[415; 418)
186 IDENT@[415; 418) "bar"
187 ARG_LIST@[418; 420)
188 L_PAREN@[418; 419)
189 R_PAREN@[419; 420)
190 WHITESPACE@[420; 421)
191 BLOCK@[421; 486)
192 L_CURLY@[421; 422)
193 WHITESPACE@[422; 435)
194 COMMENT@[435; 448)
195 WHITESPACE@[448; 461)
196 EXPR_STMT@[461; 476)
197 BREAK_EXPR@[461; 475)
198 BREAK_KW@[461; 466)
199 WHITESPACE@[466; 467)
200 LIFETIME@[467; 473) "'block"
201 WHITESPACE@[473; 474)
202 LITERAL@[474; 475)
203 INT_NUMBER@[474; 475) "2"
204 SEMI@[475; 476)
205 WHITESPACE@[476; 485)
206 R_CURLY@[485; 486)
207 WHITESPACE@[486; 495)
208 LITERAL@[495; 496)
209 INT_NUMBER@[495; 496) "3"
210 WHITESPACE@[496; 501)
211 R_CURLY@[501; 502)
212 SEMI@[502; 503)
213 WHITESPACE@[503; 504)
214 R_CURLY@[504; 505)
215 WHITESPACE@[505; 506)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs
new file mode 100644
index 000000000..2a70ee83a
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs
@@ -0,0 +1,16 @@
1macro parse_use_trees($($s:expr),* $(,)*) {
2 vec![
3 $(parse_use_tree($s),)*
4 ]
5}
6
7#[test]
8fn test_use_tree_merge() {
9 macro test_merge([$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) {
10 assert_eq!(
11 merge_use_trees(parse_use_trees!($($input,)*)),
12 parse_use_trees!($($output,)*),
13 );
14 }
15}
16
diff --git a/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt
new file mode 100644
index 000000000..74af9d71b
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt
@@ -0,0 +1,317 @@
1ROOT@[0; 350)
2 MACRO_CALL@[0; 41)
3 PATH@[0; 5)
4 PATH_SEGMENT@[0; 5)
5 NAME_REF@[0; 5)
6 IDENT@[0; 5) "macro"
7 err: `expected EXCL`
8 WHITESPACE@[5; 6)
9 IDENT@[6; 21) "parse_use_trees"
10 TOKEN_TREE@[21; 41)
11 L_PAREN@[21; 22)
12 DOLLAR@[22; 23)
13 TOKEN_TREE@[23; 32)
14 L_PAREN@[23; 24)
15 DOLLAR@[24; 25)
16 IDENT@[25; 26) "s"
17 COLON@[26; 27)
18 IDENT@[27; 31) "expr"
19 R_PAREN@[31; 32)
20 COMMA@[32; 33)
21 STAR@[33; 34)
22 WHITESPACE@[34; 35)
23 DOLLAR@[35; 36)
24 TOKEN_TREE@[36; 39)
25 L_PAREN@[36; 37)
26 COMMA@[37; 38)
27 R_PAREN@[38; 39)
28 STAR@[39; 40)
29 R_PAREN@[40; 41)
30 err: `expected SEMI`
31 WHITESPACE@[41; 42)
32 err: `expected an item`
33 ERROR@[42; 93)
34 L_CURLY@[42; 43)
35 WHITESPACE@[43; 48)
36 IDENT@[48; 51) "vec"
37 EXCL@[51; 52)
38 L_BRACK@[52; 53)
39 WHITESPACE@[53; 62)
40 DOLLAR@[62; 63)
41 L_PAREN@[63; 64)
42 IDENT@[64; 78) "parse_use_tree"
43 L_PAREN@[78; 79)
44 DOLLAR@[79; 80)
45 IDENT@[80; 81) "s"
46 R_PAREN@[81; 82)
47 COMMA@[82; 83)
48 R_PAREN@[83; 84)
49 STAR@[84; 85)
50 WHITESPACE@[85; 90)
51 R_BRACK@[90; 91)
52 WHITESPACE@[91; 92)
53 R_CURLY@[92; 93)
54 WHITESPACE@[93; 95)
55 FN_DEF@[95; 348)
56 ATTR@[95; 102)
57 POUND@[95; 96)
58 TOKEN_TREE@[96; 102)
59 L_BRACK@[96; 97)
60 IDENT@[97; 101) "test"
61 R_BRACK@[101; 102)
62 WHITESPACE@[102; 103)
63 FN_KW@[103; 105)
64 WHITESPACE@[105; 106)
65 NAME@[106; 125)
66 IDENT@[106; 125) "test_use_tree_merge"
67 PARAM_LIST@[125; 127)
68 L_PAREN@[125; 126)
69 R_PAREN@[126; 127)
70 WHITESPACE@[127; 128)
71 BLOCK@[128; 348)
72 L_CURLY@[128; 129)
73 WHITESPACE@[129; 134)
74 EXPR_STMT@[134; 139)
75 PATH_EXPR@[134; 139)
76 PATH@[134; 139)
77 PATH_SEGMENT@[134; 139)
78 NAME_REF@[134; 139)
79 IDENT@[134; 139) "macro"
80 err: `expected SEMI`
81 WHITESPACE@[139; 140)
82 EXPR_STMT@[140; 154)
83 CALL_EXPR@[140; 154)
84 PATH_EXPR@[140; 150)
85 PATH@[140; 150)
86 PATH_SEGMENT@[140; 150)
87 NAME_REF@[140; 150)
88 IDENT@[140; 150) "test_merge"
89 ARG_LIST@[150; 154)
90 L_PAREN@[150; 151)
91 ARRAY_EXPR@[151; 154)
92 L_BRACK@[151; 152)
93 err: `expected expression`
94 ERROR@[152; 153)
95 DOLLAR@[152; 153)
96 err: `expected COMMA`
97 PAREN_EXPR@[153; 154)
98 L_PAREN@[153; 154)
99 err: `expected expression`
100 err: `expected R_PAREN`
101 err: `expected COMMA`
102 err: `expected expression`
103 err: `expected R_BRACK`
104 err: `expected COMMA`
105 err: `expected SEMI`
106 err: `expected expression`
107 EXPR_STMT@[154; 155)
108 ERROR@[154; 155)
109 DOLLAR@[154; 155)
110 err: `expected SEMI`
111 EXPR_STMT@[155; 160)
112 PATH_EXPR@[155; 160)
113 PATH@[155; 160)
114 PATH_SEGMENT@[155; 160)
115 NAME_REF@[155; 160)
116 IDENT@[155; 160) "input"
117 err: `expected SEMI`
118 err: `expected expression`
119 EXPR_STMT@[160; 161)
120 ERROR@[160; 161)
121 COLON@[160; 161)
122 err: `expected SEMI`
123 EXPR_STMT@[161; 165)
124 PATH_EXPR@[161; 165)
125 PATH@[161; 165)
126 PATH_SEGMENT@[161; 165)
127 NAME_REF@[161; 165)
128 IDENT@[161; 165) "expr"
129 err: `expected SEMI`
130 err: `expected expression`
131 EXPR_STMT@[165; 166)
132 ERROR@[165; 166)
133 R_PAREN@[165; 166)
134 err: `expected SEMI`
135 err: `expected expression`
136 EXPR_STMT@[166; 167)
137 ERROR@[166; 167)
138 COMMA@[166; 167)
139 err: `expected SEMI`
140 EXPR_STMT@[167; 170)
141 PREFIX_EXPR@[167; 170)
142 STAR@[167; 168)
143 WHITESPACE@[168; 169)
144 err: `expected expression`
145 ERROR@[169; 170)
146 DOLLAR@[169; 170)
147 err: `expected SEMI`
148 EXPR_STMT@[170; 171)
149 PAREN_EXPR@[170; 171)
150 L_PAREN@[170; 171)
151 err: `expected expression`
152 err: `expected R_PAREN`
153 err: `expected SEMI`
154 err: `expected expression`
155 EXPR_STMT@[171; 172)
156 ERROR@[171; 172)
157 COMMA@[171; 172)
158 err: `expected SEMI`
159 err: `expected expression`
160 EXPR_STMT@[172; 173)
161 ERROR@[172; 173)
162 R_PAREN@[172; 173)
163 err: `expected SEMI`
164 EXPR_STMT@[173; 175)
165 PREFIX_EXPR@[173; 175)
166 STAR@[173; 174)
167 err: `expected expression`
168 ERROR@[174; 175)
169 R_BRACK@[174; 175)
170 err: `expected SEMI`
171 err: `expected expression`
172 EXPR_STMT@[175; 176)
173 ERROR@[175; 176)
174 COMMA@[175; 176)
175 err: `expected SEMI`
176 WHITESPACE@[176; 177)
177 EXPR_STMT@[177; 180)
178 ARRAY_EXPR@[177; 180)
179 L_BRACK@[177; 178)
180 err: `expected expression`
181 ERROR@[178; 179)
182 DOLLAR@[178; 179)
183 err: `expected COMMA`
184 PAREN_EXPR@[179; 180)
185 L_PAREN@[179; 180)
186 err: `expected expression`
187 err: `expected R_PAREN`
188 err: `expected COMMA`
189 err: `expected expression`
190 err: `expected R_BRACK`
191 err: `expected SEMI`
192 err: `expected expression`
193 EXPR_STMT@[180; 181)
194 ERROR@[180; 181)
195 DOLLAR@[180; 181)
196 err: `expected SEMI`
197 EXPR_STMT@[181; 187)
198 PATH_EXPR@[181; 187)
199 PATH@[181; 187)
200 PATH_SEGMENT@[181; 187)
201 NAME_REF@[181; 187)
202 IDENT@[181; 187) "output"
203 err: `expected SEMI`
204 err: `expected expression`
205 EXPR_STMT@[187; 188)
206 ERROR@[187; 188)
207 COLON@[187; 188)
208 err: `expected SEMI`
209 EXPR_STMT@[188; 192)
210 PATH_EXPR@[188; 192)
211 PATH@[188; 192)
212 PATH_SEGMENT@[188; 192)
213 NAME_REF@[188; 192)
214 IDENT@[188; 192) "expr"
215 err: `expected SEMI`
216 err: `expected expression`
217 EXPR_STMT@[192; 193)
218 ERROR@[192; 193)
219 R_PAREN@[192; 193)
220 err: `expected SEMI`
221 err: `expected expression`
222 EXPR_STMT@[193; 194)
223 ERROR@[193; 194)
224 COMMA@[193; 194)
225 err: `expected SEMI`
226 EXPR_STMT@[194; 197)
227 PREFIX_EXPR@[194; 197)
228 STAR@[194; 195)
229 WHITESPACE@[195; 196)
230 err: `expected expression`
231 ERROR@[196; 197)
232 DOLLAR@[196; 197)
233 err: `expected SEMI`
234 EXPR_STMT@[197; 198)
235 PAREN_EXPR@[197; 198)
236 L_PAREN@[197; 198)
237 err: `expected expression`
238 err: `expected R_PAREN`
239 err: `expected SEMI`
240 err: `expected expression`
241 EXPR_STMT@[198; 199)
242 ERROR@[198; 199)
243 COMMA@[198; 199)
244 err: `expected SEMI`
245 err: `expected expression`
246 EXPR_STMT@[199; 200)
247 ERROR@[199; 200)
248 R_PAREN@[199; 200)
249 err: `expected SEMI`
250 EXPR_STMT@[200; 202)
251 PREFIX_EXPR@[200; 202)
252 STAR@[200; 201)
253 err: `expected expression`
254 ERROR@[201; 202)
255 R_BRACK@[201; 202)
256 err: `expected SEMI`
257 err: `expected expression`
258 EXPR_STMT@[202; 203)
259 ERROR@[202; 203)
260 R_PAREN@[202; 203)
261 err: `expected SEMI`
262 WHITESPACE@[203; 204)
263 BLOCK_EXPR@[204; 346)
264 BLOCK@[204; 346)
265 L_CURLY@[204; 205)
266 WHITESPACE@[205; 214)
267 EXPR_STMT@[214; 340)
268 MACRO_CALL@[214; 339)
269 PATH@[214; 223)
270 PATH_SEGMENT@[214; 223)
271 NAME_REF@[214; 223)
272 IDENT@[214; 223) "assert_eq"
273 EXCL@[223; 224)
274 TOKEN_TREE@[224; 339)
275 L_PAREN@[224; 225)
276 WHITESPACE@[225; 238)
277 IDENT@[238; 253) "merge_use_trees"
278 TOKEN_TREE@[253; 284)
279 L_PAREN@[253; 254)
280 IDENT@[254; 269) "parse_use_trees"
281 EXCL@[269; 270)
282 TOKEN_TREE@[270; 283)
283 L_PAREN@[270; 271)
284 DOLLAR@[271; 272)
285 TOKEN_TREE@[272; 281)
286 L_PAREN@[272; 273)
287 DOLLAR@[273; 274)
288 IDENT@[274; 279) "input"
289 COMMA@[279; 280)
290 R_PAREN@[280; 281)
291 STAR@[281; 282)
292 R_PAREN@[282; 283)
293 R_PAREN@[283; 284)
294 COMMA@[284; 285)
295 WHITESPACE@[285; 298)
296 IDENT@[298; 313) "parse_use_trees"
297 EXCL@[313; 314)
298 TOKEN_TREE@[314; 328)
299 L_PAREN@[314; 315)
300 DOLLAR@[315; 316)
301 TOKEN_TREE@[316; 326)
302 L_PAREN@[316; 317)
303 DOLLAR@[317; 318)
304 IDENT@[318; 324) "output"
305 COMMA@[324; 325)
306 R_PAREN@[325; 326)
307 STAR@[326; 327)
308 R_PAREN@[327; 328)
309 COMMA@[328; 329)
310 WHITESPACE@[329; 338)
311 R_PAREN@[338; 339)
312 SEMI@[339; 340)
313 WHITESPACE@[340; 345)
314 R_CURLY@[345; 346)
315 WHITESPACE@[346; 347)
316 R_CURLY@[347; 348)
317 WHITESPACE@[348; 350)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt b/crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt
new file mode 100644
index 000000000..1a8ca761d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt
@@ -0,0 +1,250 @@
1ROOT@[0; 350)
2 MACRO_CALL@[0; 41)
3 PATH@[0; 5)
4 PATH_SEGMENT@[0; 5)
5 NAME_REF@[0; 5)
6 IDENT@[0; 5) "macro"
7 err: `expected EXCL`
8 WHITESPACE@[5; 6)
9 IDENT@[6; 21) "parse_use_trees"
10 TOKEN_TREE@[21; 41)
11 L_PAREN@[21; 22)
12 DOLLAR@[22; 23)
13 TOKEN_TREE@[23; 32)
14 L_PAREN@[23; 24)
15 DOLLAR@[24; 25)
16 IDENT@[25; 26) "s"
17 COLON@[26; 27)
18 IDENT@[27; 31) "expr"
19 R_PAREN@[31; 32)
20 COMMA@[32; 33)
21 STAR@[33; 34)
22 WHITESPACE@[34; 35)
23 DOLLAR@[35; 36)
24 TOKEN_TREE@[36; 39)
25 L_PAREN@[36; 37)
26 COMMA@[37; 38)
27 R_PAREN@[38; 39)
28 STAR@[39; 40)
29 R_PAREN@[40; 41)
30 err: `expected SEMI`
31 WHITESPACE@[41; 42)
32 err: `expected an item`
33 ERROR@[42; 93)
34 L_CURLY@[42; 43)
35 WHITESPACE@[43; 48)
36 IDENT@[48; 51) "vec"
37 EXCL@[51; 52)
38 L_BRACK@[52; 53)
39 WHITESPACE@[53; 62)
40 DOLLAR@[62; 63)
41 L_PAREN@[63; 64)
42 IDENT@[64; 78) "parse_use_tree"
43 L_PAREN@[78; 79)
44 DOLLAR@[79; 80)
45 IDENT@[80; 81) "s"
46 R_PAREN@[81; 82)
47 COMMA@[82; 83)
48 R_PAREN@[83; 84)
49 STAR@[84; 85)
50 WHITESPACE@[85; 90)
51 R_BRACK@[90; 91)
52 WHITESPACE@[91; 92)
53 R_CURLY@[92; 93)
54 WHITESPACE@[93; 95)
55 FN_DEF@[95; 348)
56 ATTR@[95; 102)
57 POUND@[95; 96)
58 TOKEN_TREE@[96; 102)
59 L_BRACK@[96; 97)
60 IDENT@[97; 101) "test"
61 R_BRACK@[101; 102)
62 WHITESPACE@[102; 103)
63 FN_KW@[103; 105)
64 WHITESPACE@[105; 106)
65 NAME@[106; 125)
66 IDENT@[106; 125) "test_use_tree_merge"
67 PARAM_LIST@[125; 127)
68 L_PAREN@[125; 126)
69 R_PAREN@[126; 127)
70 WHITESPACE@[127; 128)
71 BLOCK@[128; 348)
72 L_CURLY@[128; 129)
73 WHITESPACE@[129; 134)
74 EXPR_STMT@[134; 139)
75 PATH_EXPR@[134; 139)
76 PATH@[134; 139)
77 PATH_SEGMENT@[134; 139)
78 NAME_REF@[134; 139)
79 IDENT@[134; 139) "macro"
80 err: `expected SEMI`
81 WHITESPACE@[139; 140)
82 EXPR_STMT@[140; 203)
83 CALL_EXPR@[140; 203)
84 PATH_EXPR@[140; 150)
85 PATH@[140; 150)
86 PATH_SEGMENT@[140; 150)
87 NAME_REF@[140; 150)
88 IDENT@[140; 150) "test_merge"
89 ARG_LIST@[150; 203)
90 L_PAREN@[150; 151)
91 ARRAY_EXPR@[151; 202)
92 L_BRACK@[151; 152)
93 err: `expected expression`
94 ERROR@[152; 153)
95 DOLLAR@[152; 153)
96 err: `expected COMMA`
97 TUPLE_EXPR@[153; 166)
98 L_PAREN@[153; 154)
99 err: `expected expression`
100 ERROR@[154; 155)
101 DOLLAR@[154; 155)
102 err: `expected COMMA`
103 PATH_EXPR@[155; 160)
104 PATH@[155; 160)
105 PATH_SEGMENT@[155; 160)
106 NAME_REF@[155; 160)
107 IDENT@[155; 160) "input"
108 err: `expected COMMA`
109 err: `expected expression`
110 ERROR@[160; 161)
111 COLON@[160; 161)
112 err: `expected COMMA`
113 PATH_EXPR@[161; 165)
114 PATH@[161; 165)
115 PATH_SEGMENT@[161; 165)
116 NAME_REF@[161; 165)
117 IDENT@[161; 165) "expr"
118 R_PAREN@[165; 166)
119 COMMA@[166; 167)
120 PREFIX_EXPR@[167; 170)
121 STAR@[167; 168)
122 WHITESPACE@[168; 169)
123 err: `expected expression`
124 ERROR@[169; 170)
125 DOLLAR@[169; 170)
126 err: `expected COMMA`
127 BIN_EXPR@[170; 175)
128 PAREN_EXPR@[170; 173)
129 L_PAREN@[170; 171)
130 err: `expected expression`
131 ERROR@[171; 172)
132 COMMA@[171; 172)
133 R_PAREN@[172; 173)
134 STAR@[173; 174)
135 err: `expected expression`
136 ERROR@[174; 175)
137 R_BRACK@[174; 175)
138 COMMA@[175; 176)
139 WHITESPACE@[176; 177)
140 ARRAY_EXPR@[177; 202)
141 L_BRACK@[177; 178)
142 err: `expected expression`
143 ERROR@[178; 179)
144 DOLLAR@[178; 179)
145 err: `expected COMMA`
146 TUPLE_EXPR@[179; 193)
147 L_PAREN@[179; 180)
148 err: `expected expression`
149 ERROR@[180; 181)
150 DOLLAR@[180; 181)
151 err: `expected COMMA`
152 PATH_EXPR@[181; 187)
153 PATH@[181; 187)
154 PATH_SEGMENT@[181; 187)
155 NAME_REF@[181; 187)
156 IDENT@[181; 187) "output"
157 err: `expected COMMA`
158 err: `expected expression`
159 ERROR@[187; 188)
160 COLON@[187; 188)
161 err: `expected COMMA`
162 PATH_EXPR@[188; 192)
163 PATH@[188; 192)
164 PATH_SEGMENT@[188; 192)
165 NAME_REF@[188; 192)
166 IDENT@[188; 192) "expr"
167 R_PAREN@[192; 193)
168 COMMA@[193; 194)
169 PREFIX_EXPR@[194; 197)
170 STAR@[194; 195)
171 WHITESPACE@[195; 196)
172 err: `expected expression`
173 ERROR@[196; 197)
174 DOLLAR@[196; 197)
175 err: `expected COMMA`
176 BIN_EXPR@[197; 202)
177 PAREN_EXPR@[197; 200)
178 L_PAREN@[197; 198)
179 err: `expected expression`
180 ERROR@[198; 199)
181 COMMA@[198; 199)
182 R_PAREN@[199; 200)
183 STAR@[200; 201)
184 err: `expected expression`
185 ERROR@[201; 202)
186 R_BRACK@[201; 202)
187 err: `expected COMMA`
188 err: `expected expression`
189 err: `expected R_BRACK`
190 err: `expected COMMA`
191 err: `expected expression`
192 err: `expected R_BRACK`
193 R_PAREN@[202; 203)
194 err: `expected SEMI`
195 WHITESPACE@[203; 204)
196 BLOCK_EXPR@[204; 346)
197 BLOCK@[204; 346)
198 L_CURLY@[204; 205)
199 WHITESPACE@[205; 214)
200 EXPR_STMT@[214; 340)
201 MACRO_CALL@[214; 339)
202 PATH@[214; 223)
203 PATH_SEGMENT@[214; 223)
204 NAME_REF@[214; 223)
205 IDENT@[214; 223) "assert_eq"
206 EXCL@[223; 224)
207 TOKEN_TREE@[224; 339)
208 L_PAREN@[224; 225)
209 WHITESPACE@[225; 238)
210 IDENT@[238; 253) "merge_use_trees"
211 TOKEN_TREE@[253; 284)
212 L_PAREN@[253; 254)
213 IDENT@[254; 269) "parse_use_trees"
214 EXCL@[269; 270)
215 TOKEN_TREE@[270; 283)
216 L_PAREN@[270; 271)
217 DOLLAR@[271; 272)
218 TOKEN_TREE@[272; 281)
219 L_PAREN@[272; 273)
220 DOLLAR@[273; 274)
221 IDENT@[274; 279) "input"
222 COMMA@[279; 280)
223 R_PAREN@[280; 281)
224 STAR@[281; 282)
225 R_PAREN@[282; 283)
226 R_PAREN@[283; 284)
227 COMMA@[284; 285)
228 WHITESPACE@[285; 298)
229 IDENT@[298; 313) "parse_use_trees"
230 EXCL@[313; 314)
231 TOKEN_TREE@[314; 328)
232 L_PAREN@[314; 315)
233 DOLLAR@[315; 316)
234 TOKEN_TREE@[316; 326)
235 L_PAREN@[316; 317)
236 DOLLAR@[317; 318)
237 IDENT@[318; 324) "output"
238 COMMA@[324; 325)
239 R_PAREN@[325; 326)
240 STAR@[326; 327)
241 R_PAREN@[327; 328)
242 COMMA@[328; 329)
243 WHITESPACE@[329; 338)
244 R_PAREN@[338; 339)
245 SEMI@[339; 340)
246 WHITESPACE@[340; 345)
247 R_CURLY@[345; 346)
248 WHITESPACE@[346; 347)
249 R_CURLY@[347; 348)
250 WHITESPACE@[348; 350)
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs
new file mode 100644
index 000000000..27380efef
--- /dev/null
+++ b/crates/ra_syntax/tests/test.rs
@@ -0,0 +1,151 @@
1extern crate ra_syntax;
2#[macro_use]
3extern crate test_utils;
4extern crate walkdir;
5
6use std::{
7 fs,
8 path::{Path, PathBuf},
9 fmt::Write,
10};
11
12use ra_syntax::{
13 File,
14 utils::{dump_tree, check_fuzz_invariants},
15};
16
17#[test]
18fn lexer_tests() {
19 dir_tests(&["lexer"], |text| {
20 let tokens = ra_syntax::tokenize(text);
21 dump_tokens(&tokens, text)
22 })
23}
24
25#[test]
26fn parser_tests() {
27 dir_tests(&["parser/inline", "parser/ok", "parser/err"], |text| {
28 let file = File::parse(text);
29 dump_tree(file.syntax())
30 })
31}
32
33#[test]
34fn parser_fuzz_tests() {
35 for (_, text) in collect_tests(&["parser/fuzz-failures"]) {
36 check_fuzz_invariants(&text)
37 }
38}
39
40
41/// Read file and normalize newlines.
42///
43/// `rustc` seems to always normalize `\r\n` newlines to `\n`:
44///
45/// ```
46/// let s = "
47/// ";
48/// assert_eq!(s.as_bytes(), &[10]);
49/// ```
50///
51/// so this should always be correct.
52fn read_text(path: &Path) -> String {
53 fs::read_to_string(path).unwrap().replace("\r\n", "\n")
54}
55
56pub fn dir_tests<F>(paths: &[&str], f: F)
57 where
58 F: Fn(&str) -> String,
59{
60 for (path, input_code) in collect_tests(paths) {
61 let parse_tree = f(&input_code);
62 let path = path.with_extension("txt");
63 if !path.exists() {
64 println!("\nfile: {}", path.display());
65 println!("No .txt file with expected result, creating...\n");
66 println!("{}\n{}", input_code, parse_tree);
67 fs::write(&path, parse_tree).unwrap();
68 panic!("No expected result")
69 }
70 let expected = read_text(&path);
71 let expected = expected.as_str();
72 let parse_tree = parse_tree.as_str();
73 assert_equal_text(expected, parse_tree, &path);
74 }
75}
76
77const REWRITE: bool = false;
78
79fn assert_equal_text(expected: &str, actual: &str, path: &Path) {
80 if expected == actual {
81 return;
82 }
83 let dir = project_dir();
84 let pretty_path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
85 if expected.trim() == actual.trim() {
86 println!("whitespace difference, rewriting");
87 println!("file: {}\n", pretty_path.display());
88 fs::write(path, actual).unwrap();
89 return;
90 }
91 if REWRITE {
92 println!("rewriting {}", pretty_path.display());
93 fs::write(path, actual).unwrap();
94 return;
95 }
96 assert_eq_text!(expected, actual, "file: {}", pretty_path.display());
97}
98
99fn collect_tests(paths: &[&str]) -> Vec<(PathBuf, String)> {
100 paths
101 .iter()
102 .flat_map(|path| {
103 let path = test_data_dir().join(path);
104 test_from_dir(&path).into_iter()
105 })
106 .map(|path| {
107 let text = read_text(&path);
108 (path, text)
109 })
110 .collect()
111}
112
113fn test_from_dir(dir: &Path) -> Vec<PathBuf> {
114 let mut acc = Vec::new();
115 for file in fs::read_dir(&dir).unwrap() {
116 let file = file.unwrap();
117 let path = file.path();
118 if path.extension().unwrap_or_default() == "rs" {
119 acc.push(path);
120 }
121 }
122 acc.sort();
123 acc
124}
125
126fn project_dir() -> PathBuf {
127 let dir = env!("CARGO_MANIFEST_DIR");
128 PathBuf::from(dir)
129 .parent()
130 .unwrap()
131 .parent()
132 .unwrap()
133 .to_owned()
134}
135
136fn test_data_dir() -> PathBuf {
137 project_dir().join("crates/ra_syntax/tests/data")
138}
139
140fn dump_tokens(tokens: &[ra_syntax::Token], text: &str) -> String {
141 let mut acc = String::new();
142 let mut offset = 0;
143 for token in tokens {
144 let len: u32 = token.len.into();
145 let len = len as usize;
146 let token_text = &text[offset..offset + len];
147 offset += len;
148 write!(acc, "{:?} {} {:?}\n", token.kind, token.len, token_text).unwrap()
149 }
150 acc
151}