aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-07 16:59:09 +0100
committerBenjamin Coenen <[email protected]>2020-04-07 16:59:09 +0100
commit18a5e164838e1dc2abcc6b79d4fc2f96ffd2507c (patch)
treebc80b5c49c3b7ba31c7fe967bb34fe14bac9d5ed
parentab864ed259c10ff51f7c9c3421d098eeea7b0245 (diff)
parent33c364b545350134b945fbca834194fd1a28fe08 (diff)
Merge branch 'master' of github.com:rust-analyzer/rust-analyzer
-rw-r--r--.github/workflows/ci.yaml2
-rw-r--r--.github/workflows/release.yaml4
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_assists/src/lib.rs5
-rw-r--r--crates/ra_hir/src/diagnostics.rs2
-rw-r--r--crates/ra_hir/src/semantics.rs2
-rw-r--r--crates/ra_hir/src/semantics/source_to_def.rs18
-rw-r--r--crates/ra_hir_def/src/lib.rs5
-rw-r--r--crates/ra_hir_expand/src/builtin_derive.rs6
-rw-r--r--crates/ra_hir_ty/Cargo.toml1
-rw-r--r--crates/ra_hir_ty/src/_match.rs1411
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs21
-rw-r--r--crates/ra_hir_ty/src/expr.rs89
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs6
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs12
-rw-r--r--crates/ra_hir_ty/src/lib.rs9
-rw-r--r--crates/ra_hir_ty/src/test_db.rs6
-rw-r--r--crates/ra_hir_ty/src/tests.rs3
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs25
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs7
-rw-r--r--crates/ra_ide/src/call_info.rs14
-rw-r--r--crates/ra_ide/src/completion.rs8
-rw-r--r--crates/ra_ide/src/completion/complete_fn_param.rs4
-rw-r--r--crates/ra_ide/src/completion/complete_keyword.rs6
-rw-r--r--crates/ra_ide/src/completion/complete_qualified_path.rs (renamed from crates/ra_ide/src/completion/complete_path.rs)2
-rw-r--r--crates/ra_ide/src/completion/complete_record.rs11
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs (renamed from crates/ra_ide/src/completion/complete_scope.rs)2
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs4
-rw-r--r--crates/ra_ide/src/completion/presentation.rs43
-rw-r--r--crates/ra_ide/src/diagnostics.rs10
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs42
-rw-r--r--crates/ra_ide/src/display/structure.rs16
-rw-r--r--crates/ra_ide/src/goto_type_definition.rs6
-rw-r--r--crates/ra_ide/src/lib.rs5
-rw-r--r--crates/ra_ide/src/marks.rs1
-rw-r--r--crates/ra_ide/src/runnables.rs4
-rw-r--r--crates/ra_ide_db/src/search.rs2
-rw-r--r--crates/ra_ide_db/src/symbol_index.rs16
-rw-r--r--crates/ra_syntax/src/tests.rs14
-rw-r--r--crates/ra_syntax/src/validation.rs12
-rw-r--r--crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.rast (renamed from crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.rast (renamed from crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.rast (renamed from crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.rast (renamed from crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.rast (renamed from crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0005_attribute_recover.rast (renamed from crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.rast (renamed from crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.rast (renamed from crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.rast (renamed from crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast (renamed from crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.rast (renamed from crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0011_extern_struct.rast (renamed from crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast (renamed from crates/ra_syntax/test_data/parser/err/0012_broken_lambda.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0013_invalid_type.rast (renamed from crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.rast (renamed from crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0015_curly_in_params.rast (renamed from crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0016_missing_semi.rast (renamed from crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.rast (renamed from crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.rast (renamed from crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0019_let_recover.rast (renamed from crates/ra_syntax/test_data/parser/err/0019_let_recover.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0020_fn_recover.rast (renamed from crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0021_incomplete_param.rast (renamed from crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0022_bad_exprs.rast (renamed from crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.rast (renamed from crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast (renamed from crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0025_nope.rast (renamed from crates/ra_syntax/test_data/parser/err/0025_nope.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0026_imp_recovery.rast (renamed from crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.rast (renamed from crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0029_field_completion.rast (renamed from crates/ra_syntax/test_data/parser/err/0029_field_completion.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.rast (renamed from crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast (renamed from crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast (renamed from crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.rast (renamed from crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0035_use_recover.rast (renamed from crates/ra_syntax/test_data/parser/err/0035_use_recover.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0036_partial_use.rast (renamed from crates/ra_syntax/test_data/parser/err/0036_partial_use.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rast (renamed from crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rast (renamed from crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.rast (renamed from crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0002_use_tree_list.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0002_use_tree_list.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0007_type_param_bounds.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0010_extern_block.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0010_extern_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0012_type_item_where_clause.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0012_type_item_where_clause.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0014_never_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0014_never_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0016_unsafe_trait.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0016_unsafe_trait.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0017_array_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0017_array_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0020_use_star.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0020_use_star.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0022_crate_visibility.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0022_crate_visibility.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0023_placeholder_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0023_placeholder_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0025_slice_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0025_slice_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0028_impl_trait_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0030_cond.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0041_trait_item.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0041_trait_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0043_use_alias.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0043_use_alias.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0046_singleton_tuple_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0046_singleton_tuple_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0047_unsafe_default_impl.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0047_unsafe_default_impl.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0050_fn_decl.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0050_fn_decl.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0051_unit_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0051_unit_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0052_path_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0052_path_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0060_extern_crate.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0060_extern_crate.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0063_impl_def_neg.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0063_impl_def_neg.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0065_dyn_trait_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0067_crate_path.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0067_crate_path.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0069_use_tree_list_after_path.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0069_use_tree_list_after_path.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0073_type_item_type_params.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0073_type_item_type_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0075_block.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0075_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0078_type_item.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0078_type_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0079_impl_def.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0079_impl_def.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0083_struct_items.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0083_struct_items.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0084_paren_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0084_paren_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0087_unsafe_impl.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0087_unsafe_impl.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0090_type_param_default.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0090_type_param_default.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0091_auto_trait.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0091_auto_trait.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0094_unsafe_auto_trait.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0094_unsafe_auto_trait.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0097_default_impl.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0097_default_impl.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0109_label.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0109_label.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0110_use_path.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0110_use_path.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0114_tuple_struct_where.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0114_tuple_struct_where.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0117_macro_call_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0117_macro_call_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0131_existential_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0131_existential_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0147_const_param.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0147_const_param.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0151_trait_alias.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0151_trait_alias.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0157_variant_discriminant.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0157_variant_discriminant.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rast (renamed from crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0000_empty.rast (renamed from crates/ra_syntax/test_data/parser/ok/0000_empty.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0001_struct_item.rast (renamed from crates/ra_syntax/test_data/parser/ok/0001_struct_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0002_struct_item_field.rast (renamed from crates/ra_syntax/test_data/parser/ok/0002_struct_item_field.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0004_file_shebang.rast (renamed from crates/ra_syntax/test_data/parser/ok/0004_file_shebang.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0005_fn_item.rast (renamed from crates/ra_syntax/test_data/parser/ok/0005_fn_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.rast (renamed from crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0007_extern_crate.rast (renamed from crates/ra_syntax/test_data/parser/ok/0007_extern_crate.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0008_mod_item.rast (renamed from crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0009_use_item.rast (renamed from crates/ra_syntax/test_data/parser/ok/0009_use_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0010_use_path_segments.rast (renamed from crates/ra_syntax/test_data/parser/ok/0010_use_path_segments.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rast (renamed from crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0012_visibility.rast (renamed from crates/ra_syntax/test_data/parser/ok/0012_visibility.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast (renamed from crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0014_use_tree.rast (renamed from crates/ra_syntax/test_data/parser/ok/0014_use_tree.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0015_use_tree.rast (renamed from crates/ra_syntax/test_data/parser/ok/0015_use_tree.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0016_struct_flavors.rast (renamed from crates/ra_syntax/test_data/parser/ok/0016_struct_flavors.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.rast (renamed from crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0018_struct_type_params.rast (renamed from crates/ra_syntax/test_data/parser/ok/0018_struct_type_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0019_enums.rast (renamed from crates/ra_syntax/test_data/parser/ok/0019_enums.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0020_type_param_bounds.rast (renamed from crates/ra_syntax/test_data/parser/ok/0020_type_param_bounds.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0021_extern_fn.rast (renamed from crates/ra_syntax/test_data/parser/ok/0021_extern_fn.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0022_empty_extern_block.rast (renamed from crates/ra_syntax/test_data/parser/ok/0022_empty_extern_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0023_static_items.rast (renamed from crates/ra_syntax/test_data/parser/ok/0023_static_items.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0024_const_item.rast (renamed from crates/ra_syntax/test_data/parser/ok/0024_const_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.rast (renamed from crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.rast (renamed from crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast (renamed from crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.rast (renamed from crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0029_range_forms.rast (renamed from crates/ra_syntax/test_data/parser/ok/0029_range_forms.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.rast (renamed from crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0030_traits.rast (renamed from crates/ra_syntax/test_data/parser/ok/0030_traits.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0031_extern.rast (renamed from crates/ra_syntax/test_data/parser/ok/0031_extern.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0032_where_for.rast (renamed from crates/ra_syntax/test_data/parser/ok/0032_where_for.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0033_label_break.rast (renamed from crates/ra_syntax/test_data/parser/ok/0033_label_break.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.rast (renamed from crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast (renamed from crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.rast (renamed from crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0037_mod.rast (renamed from crates/ra_syntax/test_data/parser/ok/0037_mod.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.rast (renamed from crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.rast (renamed from crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0040_raw_struct_item_field.rast (renamed from crates/ra_syntax/test_data/parser/ok/0040_raw_struct_item_field.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.rast (renamed from crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.rast (renamed from crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.rast (renamed from crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0044_let_attrs.rast (renamed from crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.rast (renamed from crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.rast (renamed from crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast (renamed from crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.rast (renamed from crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0049_async_block.rast (renamed from crates/ra_syntax/test_data/parser/ok/0049_async_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.rast (renamed from crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast (renamed from crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0052_for_range_block.rast (renamed from crates/ra_syntax/test_data/parser/ok/0052_for_range_block.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast (renamed from crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast (renamed from crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.rast (renamed from crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rast (renamed from crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rast (renamed from crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rast (renamed from crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rast (renamed from crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0060_as_range.rast (renamed from crates/ra_syntax/test_data/parser/ok/0060_as_range.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0061_match_full_range.rast (renamed from crates/ra_syntax/test_data/parser/ok/0061_match_full_range.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.rast (renamed from crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast (renamed from crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast (renamed from crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast (renamed from crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.txt)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rast (renamed from crates/ra_syntax/test_data/parser/ok/0065_comment_newline.txt)0
-rw-r--r--crates/rust-analyzer/src/config.rs40
-rw-r--r--crates/rust-analyzer/src/lib.rs13
-rw-r--r--crates/stdx/src/lib.rs15
-rw-r--r--crates/test_utils/src/lib.rs34
-rw-r--r--editors/code/package.json20
-rw-r--r--xtask/src/lib.rs4
322 files changed, 1823 insertions, 160 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 217f17975..02a3b6228 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -10,7 +10,7 @@ on:
10env: 10env:
11 CARGO_INCREMENTAL: 0 11 CARGO_INCREMENTAL: 0
12 CARGO_NET_RETRY: 10 12 CARGO_NET_RETRY: 10
13 RUN_SLOW_TESTS: 1 13 CI: 1
14 RUST_BACKTRACE: short 14 RUST_BACKTRACE: short
15 RUSTFLAGS: -D warnings 15 RUSTFLAGS: -D warnings
16 RUSTUP_MAX_RETRIES: 10 16 RUSTUP_MAX_RETRIES: 10
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index fd184e8f1..4db122ec7 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -60,6 +60,10 @@ jobs:
60 if: matrix.os != 'ubuntu-latest' 60 if: matrix.os != 'ubuntu-latest'
61 run: cargo xtask dist 61 run: cargo xtask dist
62 62
63 - name: Nightly analysis-stats check
64 if: matrix.os == 'ubuntu-latest' && github.ref != 'refs/heads/release'
65 run: ./dist/rust-analyzer-linux analysis-stats .
66
63 - name: Upload artifacts 67 - name: Upload artifacts
64 uses: actions/upload-artifact@v1 68 uses: actions/upload-artifact@v1
65 with: 69 with:
diff --git a/Cargo.lock b/Cargo.lock
index 91a57bf79..eb9824218 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -995,6 +995,7 @@ dependencies = [
995 "ra_prof", 995 "ra_prof",
996 "ra_syntax", 996 "ra_syntax",
997 "rustc-hash", 997 "rustc-hash",
998 "smallvec",
998 "stdx", 999 "stdx",
999 "test_utils", 1000 "test_utils",
1000] 1001]
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index fa3d3913f..c698d6e8c 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -5,6 +5,11 @@
5//! certain context. For example, if the cursor is over `,`, a "swap `,`" assist 5//! certain context. For example, if the cursor is over `,`, a "swap `,`" assist
6//! becomes available. 6//! becomes available.
7 7
8#[allow(unused)]
9macro_rules! eprintln {
10 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
11}
12
8mod assist_ctx; 13mod assist_ctx;
9mod marks; 14mod marks;
10#[cfg(test)] 15#[cfg(test)]
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs
index a9040ea3d..c82883d0c 100644
--- a/crates/ra_hir/src/diagnostics.rs
+++ b/crates/ra_hir/src/diagnostics.rs
@@ -1,4 +1,4 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2pub use hir_def::diagnostics::UnresolvedModule; 2pub use hir_def::diagnostics::UnresolvedModule;
3pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 3pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
4pub use hir_ty::diagnostics::{MissingFields, MissingOkInTailExpr, NoSuchField}; 4pub use hir_ty::diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField};
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 16a5fe968..2ad231d36 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -9,6 +9,7 @@ use hir_def::{
9 AsMacroCall, TraitId, 9 AsMacroCall, TraitId,
10}; 10};
11use hir_expand::ExpansionInfo; 11use hir_expand::ExpansionInfo;
12use itertools::Itertools;
12use ra_db::{FileId, FileRange}; 13use ra_db::{FileId, FileRange};
13use ra_prof::profile; 14use ra_prof::profile;
14use ra_syntax::{ 15use ra_syntax::{
@@ -135,7 +136,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
135 node: &SyntaxNode, 136 node: &SyntaxNode,
136 offset: TextUnit, 137 offset: TextUnit,
137 ) -> impl Iterator<Item = SyntaxNode> + '_ { 138 ) -> impl Iterator<Item = SyntaxNode> + '_ {
138 use itertools::Itertools;
139 node.token_at_offset(offset) 139 node.token_at_offset(offset)
140 .map(|token| self.ancestors_with_macros(token.parent())) 140 .map(|token| self.ancestors_with_macros(token.parent()))
141 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) 141 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs
index 8843f2835..66724919b 100644
--- a/crates/ra_hir/src/semantics/source_to_def.rs
+++ b/crates/ra_hir/src/semantics/source_to_def.rs
@@ -208,12 +208,12 @@ impl SourceToDefCtx<'_, '_> {
208 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { 208 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) {
209 let res: GenericDefId = match_ast! { 209 let res: GenericDefId = match_ast! {
210 match (container.value) { 210 match (container.value) {
211 ast::FnDef(it) => { self.fn_to_def(container.with_value(it))?.into() }, 211 ast::FnDef(it) => self.fn_to_def(container.with_value(it))?.into(),
212 ast::StructDef(it) => { self.struct_to_def(container.with_value(it))?.into() }, 212 ast::StructDef(it) => self.struct_to_def(container.with_value(it))?.into(),
213 ast::EnumDef(it) => { self.enum_to_def(container.with_value(it))?.into() }, 213 ast::EnumDef(it) => self.enum_to_def(container.with_value(it))?.into(),
214 ast::TraitDef(it) => { self.trait_to_def(container.with_value(it))?.into() }, 214 ast::TraitDef(it) => self.trait_to_def(container.with_value(it))?.into(),
215 ast::TypeAliasDef(it) => { self.type_alias_to_def(container.with_value(it))?.into() }, 215 ast::TypeAliasDef(it) => self.type_alias_to_def(container.with_value(it))?.into(),
216 ast::ImplDef(it) => { self.impl_to_def(container.with_value(it))?.into() }, 216 ast::ImplDef(it) => self.impl_to_def(container.with_value(it))?.into(),
217 _ => continue, 217 _ => continue,
218 } 218 }
219 }; 219 };
@@ -226,9 +226,9 @@ impl SourceToDefCtx<'_, '_> {
226 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { 226 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) {
227 let res: DefWithBodyId = match_ast! { 227 let res: DefWithBodyId = match_ast! {
228 match (container.value) { 228 match (container.value) {
229 ast::ConstDef(it) => { self.const_to_def(container.with_value(it))?.into() }, 229 ast::ConstDef(it) => self.const_to_def(container.with_value(it))?.into(),
230 ast::StaticDef(it) => { self.static_to_def(container.with_value(it))?.into() }, 230 ast::StaticDef(it) => self.static_to_def(container.with_value(it))?.into(),
231 ast::FnDef(it) => { self.fn_to_def(container.with_value(it))?.into() }, 231 ast::FnDef(it) => self.fn_to_def(container.with_value(it))?.into(),
232 _ => continue, 232 _ => continue,
233 } 233 }
234 }; 234 };
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index bd32ac20a..2d27bbdf8 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -7,6 +7,11 @@
7//! Note that `hir_def` is a work in progress, so not all of the above is 7//! Note that `hir_def` is a work in progress, so not all of the above is
8//! actually true. 8//! actually true.
9 9
10#[allow(unused)]
11macro_rules! eprintln {
12 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
13}
14
10pub mod db; 15pub mod db;
11 16
12pub mod attr; 17pub mod attr;
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs
index 79aea5806..bb45b0f1d 100644
--- a/crates/ra_hir_expand/src/builtin_derive.rs
+++ b/crates/ra_hir_expand/src/builtin_derive.rs
@@ -73,9 +73,9 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, mbe::ExpandError> {
73 let node = item.syntax(); 73 let node = item.syntax();
74 let (name, params) = match_ast! { 74 let (name, params) = match_ast! {
75 match node { 75 match node {
76 ast::StructDef(it) => { (it.name(), it.type_param_list()) }, 76 ast::StructDef(it) => (it.name(), it.type_param_list()),
77 ast::EnumDef(it) => { (it.name(), it.type_param_list()) }, 77 ast::EnumDef(it) => (it.name(), it.type_param_list()),
78 ast::UnionDef(it) => { (it.name(), it.type_param_list()) }, 78 ast::UnionDef(it) => (it.name(), it.type_param_list()),
79 _ => { 79 _ => {
80 debug!("unexpected node is {:?}", node); 80 debug!("unexpected node is {:?}", node);
81 return Err(mbe::ExpandError::ConversionError) 81 return Err(mbe::ExpandError::ConversionError)
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 45be08430..9a4a7aa6f 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -9,6 +9,7 @@ doctest = false
9 9
10[dependencies] 10[dependencies]
11arrayvec = "0.5.1" 11arrayvec = "0.5.1"
12smallvec = "1.2.0"
12ena = "0.13.1" 13ena = "0.13.1"
13log = "0.4.8" 14log = "0.4.8"
14rustc-hash = "1.1.0" 15rustc-hash = "1.1.0"
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs
new file mode 100644
index 000000000..f29a25505
--- /dev/null
+++ b/crates/ra_hir_ty/src/_match.rs
@@ -0,0 +1,1411 @@
1//! This module implements match statement exhaustiveness checking and usefulness checking
2//! for match arms.
3//!
4//! It is modeled on the rustc module `librustc_mir_build::hair::pattern::_match`, which
5//! contains very detailed documentation about the algorithms used here. I've duplicated
6//! most of that documentation below.
7//!
8//! This file includes the logic for exhaustiveness and usefulness checking for
9//! pattern-matching. Specifically, given a list of patterns for a type, we can
10//! tell whether:
11//! (a) the patterns cover every possible constructor for the type [exhaustiveness]
12//! (b) each pattern is necessary [usefulness]
13//!
14//! The algorithm implemented here is a modified version of the one described in:
15//! http://moscova.inria.fr/~maranget/papers/warn/index.html
16//! However, to save future implementors from reading the original paper, we
17//! summarise the algorithm here to hopefully save time and be a little clearer
18//! (without being so rigorous).
19//!
20//! The core of the algorithm revolves about a "usefulness" check. In particular, we
21//! are trying to compute a predicate `U(P, p)` where `P` is a list of patterns (we refer to this as
22//! a matrix). `U(P, p)` represents whether, given an existing list of patterns
23//! `P_1 ..= P_m`, adding a new pattern `p` will be "useful" (that is, cover previously-
24//! uncovered values of the type).
25//!
26//! If we have this predicate, then we can easily compute both exhaustiveness of an
27//! entire set of patterns and the individual usefulness of each one.
28//! (a) the set of patterns is exhaustive iff `U(P, _)` is false (i.e., adding a wildcard
29//! match doesn't increase the number of values we're matching)
30//! (b) a pattern `P_i` is not useful if `U(P[0..=(i-1), P_i)` is false (i.e., adding a
31//! pattern to those that have come before it doesn't increase the number of values
32//! we're matching).
33//!
34//! During the course of the algorithm, the rows of the matrix won't just be individual patterns,
35//! but rather partially-deconstructed patterns in the form of a list of patterns. The paper
36//! calls those pattern-vectors, and we will call them pattern-stacks. The same holds for the
37//! new pattern `p`.
38//!
39//! For example, say we have the following:
40//! ```
41//! // x: (Option<bool>, Result<()>)
42//! match x {
43//! (Some(true), _) => {}
44//! (None, Err(())) => {}
45//! (None, Err(_)) => {}
46//! }
47//! ```
48//! Here, the matrix `P` starts as:
49//! [
50//! [(Some(true), _)],
51//! [(None, Err(()))],
52//! [(None, Err(_))],
53//! ]
54//! We can tell it's not exhaustive, because `U(P, _)` is true (we're not covering
55//! `[(Some(false), _)]`, for instance). In addition, row 3 is not useful, because
56//! all the values it covers are already covered by row 2.
57//!
58//! A list of patterns can be thought of as a stack, because we are mainly interested in the top of
59//! the stack at any given point, and we can pop or apply constructors to get new pattern-stacks.
60//! To match the paper, the top of the stack is at the beginning / on the left.
61//!
62//! There are two important operations on pattern-stacks necessary to understand the algorithm:
63//! 1. We can pop a given constructor off the top of a stack. This operation is called
64//! `specialize`, and is denoted `S(c, p)` where `c` is a constructor (like `Some` or
65//! `None`) and `p` a pattern-stack.
66//! If the pattern on top of the stack can cover `c`, this removes the constructor and
67//! pushes its arguments onto the stack. It also expands OR-patterns into distinct patterns.
68//! Otherwise the pattern-stack is discarded.
69//! This essentially filters those pattern-stacks whose top covers the constructor `c` and
70//! discards the others.
71//!
72//! For example, the first pattern above initially gives a stack `[(Some(true), _)]`. If we
73//! pop the tuple constructor, we are left with `[Some(true), _]`, and if we then pop the
74//! `Some` constructor we get `[true, _]`. If we had popped `None` instead, we would get
75//! nothing back.
76//!
77//! This returns zero or more new pattern-stacks, as follows. We look at the pattern `p_1`
78//! on top of the stack, and we have four cases:
79//! 1.1. `p_1 = c(r_1, .., r_a)`, i.e. the top of the stack has constructor `c`. We
80//! push onto the stack the arguments of this constructor, and return the result:
81//! r_1, .., r_a, p_2, .., p_n
82//! 1.2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and
83//! return nothing.
84//! 1.3. `p_1 = _`. We push onto the stack as many wildcards as the constructor `c` has
85//! arguments (its arity), and return the resulting stack:
86//! _, .., _, p_2, .., p_n
87//! 1.4. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
88//! stack:
89//! S(c, (r_1, p_2, .., p_n))
90//! S(c, (r_2, p_2, .., p_n))
91//!
92//! 2. We can pop a wildcard off the top of the stack. This is called `D(p)`, where `p` is
93//! a pattern-stack.
94//! This is used when we know there are missing constructor cases, but there might be
95//! existing wildcard patterns, so to check the usefulness of the matrix, we have to check
96//! all its *other* components.
97//!
98//! It is computed as follows. We look at the pattern `p_1` on top of the stack,
99//! and we have three cases:
100//! 1.1. `p_1 = c(r_1, .., r_a)`. We discard the current stack and return nothing.
101//! 1.2. `p_1 = _`. We return the rest of the stack:
102//! p_2, .., p_n
103//! 1.3. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
104//! stack.
105//! D((r_1, p_2, .., p_n))
106//! D((r_2, p_2, .., p_n))
107//!
108//! Note that the OR-patterns are not always used directly in Rust, but are used to derive the
109//! exhaustive integer matching rules, so they're written here for posterity.
110//!
111//! Both those operations extend straightforwardly to a list or pattern-stacks, i.e. a matrix, by
112//! working row-by-row. Popping a constructor ends up keeping only the matrix rows that start with
113//! the given constructor, and popping a wildcard keeps those rows that start with a wildcard.
114//!
115//!
116//! The algorithm for computing `U`
117//! -------------------------------
118//! The algorithm is inductive (on the number of columns: i.e., components of tuple patterns).
119//! That means we're going to check the components from left-to-right, so the algorithm
120//! operates principally on the first component of the matrix and new pattern-stack `p`.
121//! This algorithm is realised in the `is_useful` function.
122//!
123//! Base case. (`n = 0`, i.e., an empty tuple pattern)
124//! - If `P` already contains an empty pattern (i.e., if the number of patterns `m > 0`),
125//! then `U(P, p)` is false.
126//! - Otherwise, `P` must be empty, so `U(P, p)` is true.
127//!
128//! Inductive step. (`n > 0`, i.e., whether there's at least one column
129//! [which may then be expanded into further columns later])
130//! We're going to match on the top of the new pattern-stack, `p_1`.
131//! - If `p_1 == c(r_1, .., r_a)`, i.e. we have a constructor pattern.
132//! Then, the usefulness of `p_1` can be reduced to whether it is useful when
133//! we ignore all the patterns in the first column of `P` that involve other constructors.
134//! This is where `S(c, P)` comes in:
135//! `U(P, p) := U(S(c, P), S(c, p))`
136//! This special case is handled in `is_useful_specialized`.
137//!
138//! For example, if `P` is:
139//! [
140//! [Some(true), _],
141//! [None, 0],
142//! ]
143//! and `p` is [Some(false), 0], then we don't care about row 2 since we know `p` only
144//! matches values that row 2 doesn't. For row 1 however, we need to dig into the
145//! arguments of `Some` to know whether some new value is covered. So we compute
146//! `U([[true, _]], [false, 0])`.
147//!
148//! - If `p_1 == _`, then we look at the list of constructors that appear in the first
149//! component of the rows of `P`:
150//! + If there are some constructors that aren't present, then we might think that the
151//! wildcard `_` is useful, since it covers those constructors that weren't covered
152//! before.
153//! That's almost correct, but only works if there were no wildcards in those first
154//! components. So we need to check that `p` is useful with respect to the rows that
155//! start with a wildcard, if there are any. This is where `D` comes in:
156//! `U(P, p) := U(D(P), D(p))`
157//!
158//! For example, if `P` is:
159//! [
160//! [_, true, _],
161//! [None, false, 1],
162//! ]
163//! and `p` is [_, false, _], the `Some` constructor doesn't appear in `P`. So if we
164//! only had row 2, we'd know that `p` is useful. However row 1 starts with a
165//! wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
166//!
167//! + Otherwise, all possible constructors (for the relevant type) are present. In this
168//! case we must check whether the wildcard pattern covers any unmatched value. For
169//! that, we can think of the `_` pattern as a big OR-pattern that covers all
170//! possible constructors. For `Option`, that would mean `_ = None | Some(_)` for
171//! example. The wildcard pattern is useful in this case if it is useful when
172//! specialized to one of the possible constructors. So we compute:
173//! `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
174//!
175//! For example, if `P` is:
176//! [
177//! [Some(true), _],
178//! [None, false],
179//! ]
180//! and `p` is [_, false], both `None` and `Some` constructors appear in the first
181//! components of `P`. We will therefore try popping both constructors in turn: we
182//! compute U([[true, _]], [_, false]) for the `Some` constructor, and U([[false]],
183//! [false]) for the `None` constructor. The first case returns true, so we know that
184//! `p` is useful for `P`. Indeed, it matches `[Some(false), _]` that wasn't matched
185//! before.
186//!
187//! - If `p_1 == r_1 | r_2`, then the usefulness depends on each `r_i` separately:
188//! `U(P, p) := U(P, (r_1, p_2, .., p_n))
189//! || U(P, (r_2, p_2, .., p_n))`
190use std::sync::Arc;
191
192use smallvec::{smallvec, SmallVec};
193
194use crate::{
195 db::HirDatabase,
196 expr::{Body, Expr, Literal, Pat, PatId},
197 InferenceResult,
198};
199use hir_def::{adt::VariantData, EnumVariantId, VariantId};
200
201#[derive(Debug, Clone, Copy)]
202/// Either a pattern from the source code being analyzed, represented as
203/// as `PatId`, or a `Wild` pattern which is created as an intermediate
204/// step in the match checking algorithm and thus is not backed by a
205/// real `PatId`.
206///
207/// Note that it is totally valid for the `PatId` variant to contain
208/// a `PatId` which resolves to a `Wild` pattern, if that wild pattern
209/// exists in the source code being analyzed.
210enum PatIdOrWild {
211 PatId(PatId),
212 Wild,
213}
214
215impl PatIdOrWild {
216 fn as_pat(self, cx: &MatchCheckCtx) -> Pat {
217 match self {
218 PatIdOrWild::PatId(id) => cx.body.pats[id].clone(),
219 PatIdOrWild::Wild => Pat::Wild,
220 }
221 }
222
223 fn as_id(self) -> Option<PatId> {
224 match self {
225 PatIdOrWild::PatId(id) => Some(id),
226 PatIdOrWild::Wild => None,
227 }
228 }
229}
230
231impl From<PatId> for PatIdOrWild {
232 fn from(pat_id: PatId) -> Self {
233 Self::PatId(pat_id)
234 }
235}
236
237#[derive(Debug, Clone, Copy, PartialEq)]
238pub struct MatchCheckNotImplemented;
239
240/// The return type of `is_useful` is either an indication of usefulness
241/// of the match arm, or an error in the case the match statement
242/// is made up of types for which exhaustiveness checking is currently
243/// not completely implemented.
244///
245/// The `std::result::Result` type is used here rather than a custom enum
246/// to allow the use of `?`.
247pub type MatchCheckResult<T> = Result<T, MatchCheckNotImplemented>;
248
249#[derive(Debug)]
250/// A row in a Matrix.
251///
252/// This type is modeled from the struct of the same name in `rustc`.
253pub(crate) struct PatStack(PatStackInner);
254type PatStackInner = SmallVec<[PatIdOrWild; 2]>;
255
256impl PatStack {
257 pub(crate) fn from_pattern(pat_id: PatId) -> PatStack {
258 Self(smallvec!(pat_id.into()))
259 }
260
261 pub(crate) fn from_wild() -> PatStack {
262 Self(smallvec!(PatIdOrWild::Wild))
263 }
264
265 fn from_slice(slice: &[PatIdOrWild]) -> PatStack {
266 Self(SmallVec::from_slice(slice))
267 }
268
269 fn from_vec(v: PatStackInner) -> PatStack {
270 Self(v)
271 }
272
273 fn is_empty(&self) -> bool {
274 self.0.is_empty()
275 }
276
277 fn head(&self) -> PatIdOrWild {
278 self.0[0]
279 }
280
281 fn get_head(&self) -> Option<PatIdOrWild> {
282 self.0.first().copied()
283 }
284
285 fn to_tail(&self) -> PatStack {
286 Self::from_slice(&self.0[1..])
287 }
288
289 fn replace_head_with(&self, pat_ids: &[PatId]) -> PatStack {
290 let mut patterns: PatStackInner = smallvec![];
291 for pat in pat_ids {
292 patterns.push((*pat).into());
293 }
294 for pat in &self.0[1..] {
295 patterns.push(*pat);
296 }
297 PatStack::from_vec(patterns)
298 }
299
300 /// Computes `D(self)`.
301 ///
302 /// See the module docs and the associated documentation in rustc for details.
303 fn specialize_wildcard(&self, cx: &MatchCheckCtx) -> Option<PatStack> {
304 if matches!(self.head().as_pat(cx), Pat::Wild) {
305 Some(self.to_tail())
306 } else {
307 None
308 }
309 }
310
311 /// Computes `S(constructor, self)`.
312 ///
313 /// See the module docs and the associated documentation in rustc for details.
314 fn specialize_constructor(
315 &self,
316 cx: &MatchCheckCtx,
317 constructor: &Constructor,
318 ) -> MatchCheckResult<Option<PatStack>> {
319 let result = match (self.head().as_pat(cx), constructor) {
320 (Pat::Tuple(ref pat_ids), Constructor::Tuple { arity }) => {
321 debug_assert_eq!(
322 pat_ids.len(),
323 *arity,
324 "we type check before calling this code, so we should never hit this case",
325 );
326
327 Some(self.replace_head_with(pat_ids))
328 }
329 (Pat::Lit(lit_expr), Constructor::Bool(constructor_val)) => {
330 match cx.body.exprs[lit_expr] {
331 Expr::Literal(Literal::Bool(pat_val)) if *constructor_val == pat_val => {
332 Some(self.to_tail())
333 }
334 // it was a bool but the value doesn't match
335 Expr::Literal(Literal::Bool(_)) => None,
336 // perhaps this is actually unreachable given we have
337 // already checked that these match arms have the appropriate type?
338 _ => return Err(MatchCheckNotImplemented),
339 }
340 }
341 (Pat::Wild, constructor) => Some(self.expand_wildcard(cx, constructor)?),
342 (Pat::Path(_), Constructor::Enum(constructor)) => {
343 // enums with no associated data become `Pat::Path`
344 let pat_id = self.head().as_id().expect("we know this isn't a wild");
345 if !enum_variant_matches(cx, pat_id, *constructor) {
346 None
347 } else {
348 Some(self.to_tail())
349 }
350 }
351 (Pat::TupleStruct { args: ref pat_ids, .. }, Constructor::Enum(constructor)) => {
352 let pat_id = self.head().as_id().expect("we know this isn't a wild");
353 if !enum_variant_matches(cx, pat_id, *constructor) {
354 None
355 } else {
356 Some(self.replace_head_with(pat_ids))
357 }
358 }
359 (Pat::Or(_), _) => return Err(MatchCheckNotImplemented),
360 (_, _) => return Err(MatchCheckNotImplemented),
361 };
362
363 Ok(result)
364 }
365
366 /// A special case of `specialize_constructor` where the head of the pattern stack
367 /// is a Wild pattern.
368 ///
369 /// Replaces the Wild pattern at the head of the pattern stack with N Wild patterns
370 /// (N >= 0), where N is the arity of the given constructor.
371 fn expand_wildcard(
372 &self,
373 cx: &MatchCheckCtx,
374 constructor: &Constructor,
375 ) -> MatchCheckResult<PatStack> {
376 assert_eq!(
377 Pat::Wild,
378 self.head().as_pat(cx),
379 "expand_wildcard must only be called on PatStack with wild at head",
380 );
381
382 let mut patterns: PatStackInner = smallvec![];
383
384 for _ in 0..constructor.arity(cx)? {
385 patterns.push(PatIdOrWild::Wild);
386 }
387
388 for pat in &self.0[1..] {
389 patterns.push(*pat);
390 }
391
392 Ok(PatStack::from_vec(patterns))
393 }
394}
395
396#[derive(Debug)]
397/// A collection of PatStack.
398///
399/// This type is modeled from the struct of the same name in `rustc`.
400pub(crate) struct Matrix(Vec<PatStack>);
401
402impl Matrix {
403 pub(crate) fn empty() -> Self {
404 Self(vec![])
405 }
406
407 pub(crate) fn push(&mut self, cx: &MatchCheckCtx, row: PatStack) {
408 if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) {
409 // Or patterns are expanded here
410 for pat_id in pat_ids {
411 self.0.push(PatStack::from_pattern(pat_id));
412 }
413 } else {
414 self.0.push(row);
415 }
416 }
417
418 fn is_empty(&self) -> bool {
419 self.0.is_empty()
420 }
421
422 fn heads(&self) -> Vec<PatIdOrWild> {
423 self.0.iter().map(|p| p.head()).collect()
424 }
425
426 /// Computes `D(self)` for each contained PatStack.
427 ///
428 /// See the module docs and the associated documentation in rustc for details.
429 fn specialize_wildcard(&self, cx: &MatchCheckCtx) -> Self {
430 Self::collect(cx, self.0.iter().filter_map(|r| r.specialize_wildcard(cx)))
431 }
432
433 /// Computes `S(constructor, self)` for each contained PatStack.
434 ///
435 /// See the module docs and the associated documentation in rustc for details.
436 fn specialize_constructor(
437 &self,
438 cx: &MatchCheckCtx,
439 constructor: &Constructor,
440 ) -> MatchCheckResult<Self> {
441 let mut new_matrix = Matrix::empty();
442 for pat in &self.0 {
443 if let Some(pat) = pat.specialize_constructor(cx, constructor)? {
444 new_matrix.push(cx, pat);
445 }
446 }
447
448 Ok(new_matrix)
449 }
450
451 fn collect<T: IntoIterator<Item = PatStack>>(cx: &MatchCheckCtx, iter: T) -> Self {
452 let mut matrix = Matrix::empty();
453
454 for pat in iter {
455 // using push ensures we expand or-patterns
456 matrix.push(cx, pat);
457 }
458
459 matrix
460 }
461}
462
463#[derive(Clone, Debug, PartialEq)]
464/// An indication of the usefulness of a given match arm, where
465/// usefulness is defined as matching some patterns which were
466/// not matched by an prior match arms.
467///
468/// We may eventually need an `Unknown` variant here.
469pub enum Usefulness {
470 Useful,
471 NotUseful,
472}
473
474pub struct MatchCheckCtx<'a> {
475 pub body: Arc<Body>,
476 pub infer: Arc<InferenceResult>,
477 pub db: &'a dyn HirDatabase,
478}
479
480/// Given a set of patterns `matrix`, and pattern to consider `v`, determines
481/// whether `v` is useful. A pattern is useful if it covers cases which were
482/// not previously covered.
483///
484/// When calling this function externally (that is, not the recursive calls) it
485/// expected that you have already type checked the match arms. All patterns in
486/// matrix should be the same type as v, as well as they should all be the same
487/// type as the match expression.
488pub(crate) fn is_useful(
489 cx: &MatchCheckCtx,
490 matrix: &Matrix,
491 v: &PatStack,
492) -> MatchCheckResult<Usefulness> {
493 if v.is_empty() {
494 let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful };
495
496 return Ok(result);
497 }
498
499 if let Pat::Or(pat_ids) = v.head().as_pat(cx) {
500 let mut found_unimplemented = false;
501 let any_useful = pat_ids.iter().any(|&pat_id| {
502 let v = PatStack::from_pattern(pat_id);
503
504 match is_useful(cx, matrix, &v) {
505 Ok(Usefulness::Useful) => true,
506 Ok(Usefulness::NotUseful) => false,
507 _ => {
508 found_unimplemented = true;
509 false
510 }
511 }
512 });
513
514 return if any_useful {
515 Ok(Usefulness::Useful)
516 } else if found_unimplemented {
517 Err(MatchCheckNotImplemented)
518 } else {
519 Ok(Usefulness::NotUseful)
520 };
521 }
522
523 if let Some(constructor) = pat_constructor(cx, v.head())? {
524 let matrix = matrix.specialize_constructor(&cx, &constructor)?;
525 let v = v
526 .specialize_constructor(&cx, &constructor)?
527 .expect("we know this can't fail because we get the constructor from `v.head()` above");
528
529 is_useful(&cx, &matrix, &v)
530 } else {
531 // expanding wildcard
532 let mut used_constructors: Vec<Constructor> = vec![];
533 for pat in matrix.heads() {
534 if let Some(constructor) = pat_constructor(cx, pat)? {
535 used_constructors.push(constructor);
536 }
537 }
538
539 // We assume here that the first constructor is the "correct" type. Since we
540 // only care about the "type" of the constructor (i.e. if it is a bool we
541 // don't care about the value), this assumption should be valid as long as
542 // the match statement is well formed. We currently uphold this invariant by
543 // filtering match arms before calling `is_useful`, only passing in match arms
544 // whose type matches the type of the match expression.
545 match &used_constructors.first() {
546 Some(constructor) if all_constructors_covered(&cx, constructor, &used_constructors) => {
547 // If all constructors are covered, then we need to consider whether
548 // any values are covered by this wildcard.
549 //
550 // For example, with matrix '[[Some(true)], [None]]', all
551 // constructors are covered (`Some`/`None`), so we need
552 // to perform specialization to see that our wildcard will cover
553 // the `Some(false)` case.
554 //
555 // Here we create a constructor for each variant and then check
556 // usefulness after specializing for that constructor.
557 let mut found_unimplemented = false;
558 for constructor in constructor.all_constructors(cx) {
559 let matrix = matrix.specialize_constructor(&cx, &constructor)?;
560 let v = v.expand_wildcard(&cx, &constructor)?;
561
562 match is_useful(&cx, &matrix, &v) {
563 Ok(Usefulness::Useful) => return Ok(Usefulness::Useful),
564 Ok(Usefulness::NotUseful) => continue,
565 _ => found_unimplemented = true,
566 };
567 }
568
569 if found_unimplemented {
570 Err(MatchCheckNotImplemented)
571 } else {
572 Ok(Usefulness::NotUseful)
573 }
574 }
575 _ => {
576 // Either not all constructors are covered, or the only other arms
577 // are wildcards. Either way, this pattern is useful if it is useful
578 // when compared to those arms with wildcards.
579 let matrix = matrix.specialize_wildcard(&cx);
580 let v = v.to_tail();
581
582 is_useful(&cx, &matrix, &v)
583 }
584 }
585 }
586}
587
588#[derive(Debug, Clone, Copy)]
589/// Similar to TypeCtor, but includes additional information about the specific
590/// value being instantiated. For example, TypeCtor::Bool doesn't contain the
591/// boolean value.
592enum Constructor {
593 Bool(bool),
594 Tuple { arity: usize },
595 Enum(EnumVariantId),
596}
597
598impl Constructor {
599 fn arity(&self, cx: &MatchCheckCtx) -> MatchCheckResult<usize> {
600 let arity = match self {
601 Constructor::Bool(_) => 0,
602 Constructor::Tuple { arity } => *arity,
603 Constructor::Enum(e) => {
604 match cx.db.enum_data(e.parent).variants[e.local_id].variant_data.as_ref() {
605 VariantData::Tuple(struct_field_data) => struct_field_data.len(),
606 VariantData::Unit => 0,
607 _ => return Err(MatchCheckNotImplemented),
608 }
609 }
610 };
611
612 Ok(arity)
613 }
614
615 fn all_constructors(&self, cx: &MatchCheckCtx) -> Vec<Constructor> {
616 match self {
617 Constructor::Bool(_) => vec![Constructor::Bool(true), Constructor::Bool(false)],
618 Constructor::Tuple { .. } => vec![*self],
619 Constructor::Enum(e) => cx
620 .db
621 .enum_data(e.parent)
622 .variants
623 .iter()
624 .map(|(local_id, _)| {
625 Constructor::Enum(EnumVariantId { parent: e.parent, local_id })
626 })
627 .collect(),
628 }
629 }
630}
631
632/// Returns the constructor for the given pattern. Should only return None
633/// in the case of a Wild pattern.
634fn pat_constructor(cx: &MatchCheckCtx, pat: PatIdOrWild) -> MatchCheckResult<Option<Constructor>> {
635 let res = match pat.as_pat(cx) {
636 Pat::Wild => None,
637 Pat::Tuple(pats) => Some(Constructor::Tuple { arity: pats.len() }),
638 Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] {
639 Expr::Literal(Literal::Bool(val)) => Some(Constructor::Bool(val)),
640 _ => return Err(MatchCheckNotImplemented),
641 },
642 Pat::TupleStruct { .. } | Pat::Path(_) => {
643 let pat_id = pat.as_id().expect("we already know this pattern is not a wild");
644 let variant_id =
645 cx.infer.variant_resolution_for_pat(pat_id).ok_or(MatchCheckNotImplemented)?;
646 match variant_id {
647 VariantId::EnumVariantId(enum_variant_id) => {
648 Some(Constructor::Enum(enum_variant_id))
649 }
650 _ => return Err(MatchCheckNotImplemented),
651 }
652 }
653 _ => return Err(MatchCheckNotImplemented),
654 };
655
656 Ok(res)
657}
658
659fn all_constructors_covered(
660 cx: &MatchCheckCtx,
661 constructor: &Constructor,
662 used_constructors: &[Constructor],
663) -> bool {
664 match constructor {
665 Constructor::Tuple { arity } => {
666 used_constructors.iter().any(|constructor| match constructor {
667 Constructor::Tuple { arity: used_arity } => arity == used_arity,
668 _ => false,
669 })
670 }
671 Constructor::Bool(_) => {
672 if used_constructors.is_empty() {
673 return false;
674 }
675
676 let covers_true =
677 used_constructors.iter().any(|c| matches!(c, Constructor::Bool(true)));
678 let covers_false =
679 used_constructors.iter().any(|c| matches!(c, Constructor::Bool(false)));
680
681 covers_true && covers_false
682 }
683 Constructor::Enum(e) => cx.db.enum_data(e.parent).variants.iter().all(|(id, _)| {
684 for constructor in used_constructors {
685 if let Constructor::Enum(e) = constructor {
686 if id == e.local_id {
687 return true;
688 }
689 }
690 }
691
692 false
693 }),
694 }
695}
696
697fn enum_variant_matches(cx: &MatchCheckCtx, pat_id: PatId, enum_variant_id: EnumVariantId) -> bool {
698 Some(enum_variant_id.into()) == cx.infer.variant_resolution_for_pat(pat_id)
699}
700
701#[cfg(test)]
702mod tests {
703 pub(super) use insta::assert_snapshot;
704 pub(super) use ra_db::fixture::WithFixture;
705
706 pub(super) use crate::test_db::TestDB;
707
708 pub(super) fn check_diagnostic_message(content: &str) -> String {
709 TestDB::with_single_file(content).0.diagnostics().0
710 }
711
712 pub(super) fn check_diagnostic(content: &str) {
713 let diagnostic_count = TestDB::with_single_file(content).0.diagnostics().1;
714
715 assert_eq!(1, diagnostic_count, "no diagnostic reported");
716 }
717
718 pub(super) fn check_no_diagnostic(content: &str) {
719 let diagnostic_count = TestDB::with_single_file(content).0.diagnostics().1;
720
721 assert_eq!(0, diagnostic_count, "expected no diagnostic, found one");
722 }
723
724 #[test]
725 fn empty_tuple_no_arms_diagnostic_message() {
726 let content = r"
727 fn test_fn() {
728 match () {
729 }
730 }
731 ";
732
733 assert_snapshot!(
734 check_diagnostic_message(content),
735 @"\"()\": Missing match arm\n"
736 );
737 }
738
739 #[test]
740 fn empty_tuple_no_arms() {
741 let content = r"
742 fn test_fn() {
743 match () {
744 }
745 }
746 ";
747
748 check_diagnostic(content);
749 }
750
751 #[test]
752 fn empty_tuple_wild() {
753 let content = r"
754 fn test_fn() {
755 match () {
756 _ => {}
757 }
758 }
759 ";
760
761 check_no_diagnostic(content);
762 }
763
764 #[test]
765 fn empty_tuple_no_diagnostic() {
766 let content = r"
767 fn test_fn() {
768 match () {
769 () => {}
770 }
771 }
772 ";
773
774 check_no_diagnostic(content);
775 }
776
777 #[test]
778 fn tuple_of_empty_tuple_no_arms() {
779 let content = r"
780 fn test_fn() {
781 match (()) {
782 }
783 }
784 ";
785
786 check_diagnostic(content);
787 }
788
789 #[test]
790 fn tuple_of_empty_tuple_no_diagnostic() {
791 let content = r"
792 fn test_fn() {
793 match (()) {
794 (()) => {}
795 }
796 }
797 ";
798
799 check_no_diagnostic(content);
800 }
801
802 #[test]
803 fn tuple_of_two_empty_tuple_no_arms() {
804 let content = r"
805 fn test_fn() {
806 match ((), ()) {
807 }
808 }
809 ";
810
811 check_diagnostic(content);
812 }
813
814 #[test]
815 fn tuple_of_two_empty_tuple_no_diagnostic() {
816 let content = r"
817 fn test_fn() {
818 match ((), ()) {
819 ((), ()) => {}
820 }
821 }
822 ";
823
824 check_no_diagnostic(content);
825 }
826
827 #[test]
828 fn bool_no_arms() {
829 let content = r"
830 fn test_fn() {
831 match false {
832 }
833 }
834 ";
835
836 check_diagnostic(content);
837 }
838
839 #[test]
840 fn bool_missing_arm() {
841 let content = r"
842 fn test_fn() {
843 match false {
844 true => {}
845 }
846 }
847 ";
848
849 check_diagnostic(content);
850 }
851
852 #[test]
853 fn bool_no_diagnostic() {
854 let content = r"
855 fn test_fn() {
856 match false {
857 true => {}
858 false => {}
859 }
860 }
861 ";
862
863 check_no_diagnostic(content);
864 }
865
866 #[test]
867 fn tuple_of_bools_no_arms() {
868 let content = r"
869 fn test_fn() {
870 match (false, true) {
871 }
872 }
873 ";
874
875 check_diagnostic(content);
876 }
877
878 #[test]
879 fn tuple_of_bools_missing_arms() {
880 let content = r"
881 fn test_fn() {
882 match (false, true) {
883 (true, true) => {},
884 }
885 }
886 ";
887
888 check_diagnostic(content);
889 }
890
891 #[test]
892 fn tuple_of_bools_missing_arm() {
893 let content = r"
894 fn test_fn() {
895 match (false, true) {
896 (false, true) => {},
897 (false, false) => {},
898 (true, false) => {},
899 }
900 }
901 ";
902
903 check_diagnostic(content);
904 }
905
906 #[test]
907 fn tuple_of_bools_with_wilds() {
908 let content = r"
909 fn test_fn() {
910 match (false, true) {
911 (false, _) => {},
912 (true, false) => {},
913 (_, true) => {},
914 }
915 }
916 ";
917
918 check_no_diagnostic(content);
919 }
920
921 #[test]
922 fn tuple_of_bools_no_diagnostic() {
923 let content = r"
924 fn test_fn() {
925 match (false, true) {
926 (true, true) => {},
927 (true, false) => {},
928 (false, true) => {},
929 (false, false) => {},
930 }
931 }
932 ";
933
934 check_no_diagnostic(content);
935 }
936
937 #[test]
938 fn tuple_of_bools_binding_missing_arms() {
939 let content = r"
940 fn test_fn() {
941 match (false, true) {
942 (true, _x) => {},
943 }
944 }
945 ";
946
947 check_diagnostic(content);
948 }
949
950 #[test]
951 fn tuple_of_bools_binding_no_diagnostic() {
952 let content = r"
953 fn test_fn() {
954 match (false, true) {
955 (true, _x) => {},
956 (false, true) => {},
957 (false, false) => {},
958 }
959 }
960 ";
961
962 check_no_diagnostic(content);
963 }
964
965 #[test]
966 fn tuple_of_tuple_and_bools_no_arms() {
967 let content = r"
968 fn test_fn() {
969 match (false, ((), false)) {
970 }
971 }
972 ";
973
974 check_diagnostic(content);
975 }
976
977 #[test]
978 fn tuple_of_tuple_and_bools_missing_arms() {
979 let content = r"
980 fn test_fn() {
981 match (false, ((), false)) {
982 (true, ((), true)) => {},
983 }
984 }
985 ";
986
987 check_diagnostic(content);
988 }
989
990 #[test]
991 fn tuple_of_tuple_and_bools_no_diagnostic() {
992 let content = r"
993 fn test_fn() {
994 match (false, ((), false)) {
995 (true, ((), true)) => {},
996 (true, ((), false)) => {},
997 (false, ((), true)) => {},
998 (false, ((), false)) => {},
999 }
1000 }
1001 ";
1002
1003 check_no_diagnostic(content);
1004 }
1005
1006 #[test]
1007 fn tuple_of_tuple_and_bools_wildcard_missing_arms() {
1008 let content = r"
1009 fn test_fn() {
1010 match (false, ((), false)) {
1011 (true, _) => {},
1012 }
1013 }
1014 ";
1015
1016 check_diagnostic(content);
1017 }
1018
1019 #[test]
1020 fn tuple_of_tuple_and_bools_wildcard_no_diagnostic() {
1021 let content = r"
1022 fn test_fn() {
1023 match (false, ((), false)) {
1024 (true, ((), true)) => {},
1025 (true, ((), false)) => {},
1026 (false, _) => {},
1027 }
1028 }
1029 ";
1030
1031 check_no_diagnostic(content);
1032 }
1033
1034 #[test]
1035 fn enum_no_arms() {
1036 let content = r"
1037 enum Either {
1038 A,
1039 B,
1040 }
1041 fn test_fn() {
1042 match Either::A {
1043 }
1044 }
1045 ";
1046
1047 check_diagnostic(content);
1048 }
1049
1050 #[test]
1051 fn enum_missing_arms() {
1052 let content = r"
1053 enum Either {
1054 A,
1055 B,
1056 }
1057 fn test_fn() {
1058 match Either::B {
1059 Either::A => {},
1060 }
1061 }
1062 ";
1063
1064 check_diagnostic(content);
1065 }
1066
1067 #[test]
1068 fn enum_no_diagnostic() {
1069 let content = r"
1070 enum Either {
1071 A,
1072 B,
1073 }
1074 fn test_fn() {
1075 match Either::B {
1076 Either::A => {},
1077 Either::B => {},
1078 }
1079 }
1080 ";
1081
1082 check_no_diagnostic(content);
1083 }
1084
1085 #[test]
1086 fn enum_ref_missing_arms() {
1087 let content = r"
1088 enum Either {
1089 A,
1090 B,
1091 }
1092 fn test_fn() {
1093 match &Either::B {
1094 Either::A => {},
1095 }
1096 }
1097 ";
1098
1099 check_diagnostic(content);
1100 }
1101
1102 #[test]
1103 fn enum_ref_no_diagnostic() {
1104 let content = r"
1105 enum Either {
1106 A,
1107 B,
1108 }
1109 fn test_fn() {
1110 match &Either::B {
1111 Either::A => {},
1112 Either::B => {},
1113 }
1114 }
1115 ";
1116
1117 check_no_diagnostic(content);
1118 }
1119
1120 #[test]
1121 fn enum_containing_bool_no_arms() {
1122 let content = r"
1123 enum Either {
1124 A(bool),
1125 B,
1126 }
1127 fn test_fn() {
1128 match Either::B {
1129 }
1130 }
1131 ";
1132
1133 check_diagnostic(content);
1134 }
1135
1136 #[test]
1137 fn enum_containing_bool_missing_arms() {
1138 let content = r"
1139 enum Either {
1140 A(bool),
1141 B,
1142 }
1143 fn test_fn() {
1144 match Either::B {
1145 Either::A(true) => (),
1146 Either::B => (),
1147 }
1148 }
1149 ";
1150
1151 check_diagnostic(content);
1152 }
1153
1154 #[test]
1155 fn enum_containing_bool_no_diagnostic() {
1156 let content = r"
1157 enum Either {
1158 A(bool),
1159 B,
1160 }
1161 fn test_fn() {
1162 match Either::B {
1163 Either::A(true) => (),
1164 Either::A(false) => (),
1165 Either::B => (),
1166 }
1167 }
1168 ";
1169
1170 check_no_diagnostic(content);
1171 }
1172
1173 #[test]
1174 fn enum_containing_bool_with_wild_no_diagnostic() {
1175 let content = r"
1176 enum Either {
1177 A(bool),
1178 B,
1179 }
1180 fn test_fn() {
1181 match Either::B {
1182 Either::B => (),
1183 _ => (),
1184 }
1185 }
1186 ";
1187
1188 check_no_diagnostic(content);
1189 }
1190
1191 #[test]
1192 fn enum_containing_bool_with_wild_2_no_diagnostic() {
1193 let content = r"
1194 enum Either {
1195 A(bool),
1196 B,
1197 }
1198 fn test_fn() {
1199 match Either::B {
1200 Either::A(_) => (),
1201 Either::B => (),
1202 }
1203 }
1204 ";
1205
1206 check_no_diagnostic(content);
1207 }
1208
1209 #[test]
1210 fn enum_different_sizes_missing_arms() {
1211 let content = r"
1212 enum Either {
1213 A(bool),
1214 B(bool, bool),
1215 }
1216 fn test_fn() {
1217 match Either::A(false) {
1218 Either::A(_) => (),
1219 Either::B(false, _) => (),
1220 }
1221 }
1222 ";
1223
1224 check_diagnostic(content);
1225 }
1226
1227 #[test]
1228 fn enum_different_sizes_no_diagnostic() {
1229 let content = r"
1230 enum Either {
1231 A(bool),
1232 B(bool, bool),
1233 }
1234 fn test_fn() {
1235 match Either::A(false) {
1236 Either::A(_) => (),
1237 Either::B(true, _) => (),
1238 Either::B(false, _) => (),
1239 }
1240 }
1241 ";
1242
1243 check_no_diagnostic(content);
1244 }
1245
1246 #[test]
1247 fn or_no_diagnostic() {
1248 let content = r"
1249 enum Either {
1250 A(bool),
1251 B(bool, bool),
1252 }
1253 fn test_fn() {
1254 match Either::A(false) {
1255 Either::A(true) | Either::A(false) => (),
1256 Either::B(true, _) => (),
1257 Either::B(false, _) => (),
1258 }
1259 }
1260 ";
1261
1262 check_no_diagnostic(content);
1263 }
1264
1265 #[test]
1266 fn tuple_of_enum_no_diagnostic() {
1267 let content = r"
1268 enum Either {
1269 A(bool),
1270 B(bool, bool),
1271 }
1272 enum Either2 {
1273 C,
1274 D,
1275 }
1276 fn test_fn() {
1277 match (Either::A(false), Either2::C) {
1278 (Either::A(true), _) | (Either::A(false), _) => (),
1279 (Either::B(true, _), Either2::C) => (),
1280 (Either::B(false, _), Either2::C) => (),
1281 (Either::B(_, _), Either2::D) => (),
1282 }
1283 }
1284 ";
1285
1286 check_no_diagnostic(content);
1287 }
1288
1289 #[test]
1290 fn mismatched_types() {
1291 let content = r"
1292 enum Either {
1293 A,
1294 B,
1295 }
1296 enum Either2 {
1297 C,
1298 D,
1299 }
1300 fn test_fn() {
1301 match Either::A {
1302 Either2::C => (),
1303 Either2::D => (),
1304 }
1305 }
1306 ";
1307
1308 // Match arms with the incorrect type are filtered out.
1309 check_diagnostic(content);
1310 }
1311
1312 #[test]
1313 fn mismatched_types_with_different_arity() {
1314 let content = r"
1315 fn test_fn() {
1316 match (true, false) {
1317 (true, false, true) => (),
1318 (true) => (),
1319 }
1320 }
1321 ";
1322
1323 // Match arms with the incorrect type are filtered out.
1324 check_diagnostic(content);
1325 }
1326
1327 #[test]
1328 fn enum_not_in_scope() {
1329 let content = r"
1330 fn test_fn() {
1331 match Foo::Bar {
1332 Foo::Baz => (),
1333 }
1334 }
1335 ";
1336
1337 // The enum is not in scope so we don't perform exhaustiveness
1338 // checking, but we want to be sure we don't panic here (and
1339 // we don't create a diagnostic).
1340 check_no_diagnostic(content);
1341 }
1342}
1343
1344#[cfg(test)]
1345mod false_negatives {
1346 //! The implementation of match checking here is a work in progress. As we roll this out, we
1347 //! prefer false negatives to false positives (ideally there would be no false positives). This
1348 //! test module should document known false negatives. Eventually we will have a complete
1349 //! implementation of match checking and this module will be empty.
1350 //!
1351 //! The reasons for documenting known false negatives:
1352 //!
1353 //! 1. It acts as a backlog of work that can be done to improve the behavior of the system.
1354 //! 2. It ensures the code doesn't panic when handling these cases.
1355
1356 use super::tests::*;
1357
1358 #[test]
1359 fn integers() {
1360 let content = r"
1361 fn test_fn() {
1362 match 5 {
1363 10 => (),
1364 11..20 => (),
1365 }
1366 }
1367 ";
1368
1369 // This is a false negative.
1370 // We don't currently check integer exhaustiveness.
1371 check_no_diagnostic(content);
1372 }
1373
1374 #[test]
1375 fn enum_record() {
1376 let content = r"
1377 enum Either {
1378 A { foo: u32 },
1379 B,
1380 }
1381 fn test_fn() {
1382 match Either::B {
1383 Either::A { foo: 5 } => (),
1384 }
1385 }
1386 ";
1387
1388 // This is a false negative.
1389 // We don't currently handle enum record types.
1390 check_no_diagnostic(content);
1391 }
1392
1393 #[test]
1394 fn internal_or() {
1395 let content = r"
1396 fn test_fn() {
1397 enum Either {
1398 A(bool),
1399 B,
1400 }
1401 match Either::B {
1402 Either::A(true | false) => (),
1403 }
1404 }
1405 ";
1406
1407 // This is a false negative.
1408 // We do not currently handle patterns with internal `or`s.
1409 check_no_diagnostic(content);
1410 }
1411}
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 0f8522021..8cbce1168 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -6,7 +6,7 @@ use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; 6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
7use stdx::format_to; 7use stdx::format_to;
8 8
9pub use hir_def::diagnostics::UnresolvedModule; 9pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm};
10pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 10pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
11 11
12#[derive(Debug)] 12#[derive(Debug)]
@@ -63,6 +63,25 @@ impl AstDiagnostic for MissingFields {
63} 63}
64 64
65#[derive(Debug)] 65#[derive(Debug)]
66pub struct MissingMatchArms {
67 pub file: HirFileId,
68 pub match_expr: AstPtr<ast::Expr>,
69 pub arms: AstPtr<ast::MatchArmList>,
70}
71
72impl Diagnostic for MissingMatchArms {
73 fn message(&self) -> String {
74 String::from("Missing match arm")
75 }
76 fn source(&self) -> InFile<SyntaxNodePtr> {
77 InFile { file_id: self.file, value: self.match_expr.into() }
78 }
79 fn as_any(&self) -> &(dyn Any + Send + 'static) {
80 self
81 }
82}
83
84#[derive(Debug)]
66pub struct MissingOkInTailExpr { 85pub struct MissingOkInTailExpr {
67 pub file: HirFileId, 86 pub file: HirFileId,
68 pub expr: AstPtr<ast::Expr>, 87 pub expr: AstPtr<ast::Expr>,
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index eb1209d08..6547eedae 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -13,9 +13,10 @@ use rustc_hash::FxHashSet;
13 13
14use crate::{ 14use crate::{
15 db::HirDatabase, 15 db::HirDatabase,
16 diagnostics::{MissingFields, MissingOkInTailExpr}, 16 diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr},
17 utils::variant_data, 17 utils::variant_data,
18 ApplicationTy, InferenceResult, Ty, TypeCtor, 18 ApplicationTy, InferenceResult, Ty, TypeCtor,
19 _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
19}; 20};
20 21
21pub use hir_def::{ 22pub use hir_def::{
@@ -51,15 +52,99 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
51 for e in body.exprs.iter() { 52 for e in body.exprs.iter() {
52 if let (id, Expr::RecordLit { path, fields, spread }) = e { 53 if let (id, Expr::RecordLit { path, fields, spread }) = e {
53 self.validate_record_literal(id, path, fields, *spread, db); 54 self.validate_record_literal(id, path, fields, *spread, db);
55 } else if let (id, Expr::Match { expr, arms }) = e {
56 self.validate_match(id, *expr, arms, db, self.infer.clone());
54 } 57 }
55 } 58 }
56 59
57 let body_expr = &body[body.body_expr]; 60 let body_expr = &body[body.body_expr];
58 if let Expr::Block { statements: _, tail: Some(t) } = body_expr { 61 if let Expr::Block { tail: Some(t), .. } = body_expr {
59 self.validate_results_in_tail_expr(body.body_expr, *t, db); 62 self.validate_results_in_tail_expr(body.body_expr, *t, db);
60 } 63 }
61 } 64 }
62 65
66 fn validate_match(
67 &mut self,
68 id: ExprId,
69 match_expr: ExprId,
70 arms: &[MatchArm],
71 db: &dyn HirDatabase,
72 infer: Arc<InferenceResult>,
73 ) {
74 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
75 db.body_with_source_map(self.func.into());
76
77 let match_expr_ty = match infer.type_of_expr.get(match_expr) {
78 Some(ty) => ty,
79 // If we can't resolve the type of the match expression
80 // we cannot perform exhaustiveness checks.
81 None => return,
82 };
83
84 let cx = MatchCheckCtx { body, infer: infer.clone(), db };
85 let pats = arms.iter().map(|arm| arm.pat);
86
87 let mut seen = Matrix::empty();
88 for pat in pats {
89 // We skip any patterns whose type we cannot resolve.
90 //
91 // This could lead to false positives in this diagnostic, so
92 // it might be better to skip the entire diagnostic if we either
93 // cannot resolve a match arm or determine that the match arm has
94 // the wrong type.
95 if let Some(pat_ty) = infer.type_of_pat.get(pat) {
96 // We only include patterns whose type matches the type
97 // of the match expression. If we had a InvalidMatchArmPattern
98 // diagnostic or similar we could raise that in an else
99 // block here.
100 //
101 // When comparing the types, we also have to consider that rustc
102 // will automatically de-reference the match expression type if
103 // necessary.
104 //
105 // FIXME we should use the type checker for this.
106 if pat_ty == match_expr_ty
107 || match_expr_ty
108 .as_reference()
109 .map(|(match_expr_ty, _)| match_expr_ty == pat_ty)
110 .unwrap_or(false)
111 {
112 // If we had a NotUsefulMatchArm diagnostic, we could
113 // check the usefulness of each pattern as we added it
114 // to the matrix here.
115 let v = PatStack::from_pattern(pat);
116 seen.push(&cx, v);
117 }
118 }
119 }
120
121 match is_useful(&cx, &seen, &PatStack::from_wild()) {
122 Ok(Usefulness::Useful) => (),
123 // if a wildcard pattern is not useful, then all patterns are covered
124 Ok(Usefulness::NotUseful) => return,
125 // this path is for unimplemented checks, so we err on the side of not
126 // reporting any errors
127 _ => return,
128 }
129
130 if let Ok(source_ptr) = source_map.expr_syntax(id) {
131 if let Some(expr) = source_ptr.value.left() {
132 let root = source_ptr.file_syntax(db.upcast());
133 if let ast::Expr::MatchExpr(match_expr) = expr.to_node(&root) {
134 if let (Some(match_expr), Some(arms)) =
135 (match_expr.expr(), match_expr.match_arm_list())
136 {
137 self.sink.push(MissingMatchArms {
138 file: source_ptr.file_id,
139 match_expr: AstPtr::new(&match_expr),
140 arms: AstPtr::new(&arms),
141 })
142 }
143 }
144 }
145 }
146 }
147
63 fn validate_record_literal( 148 fn validate_record_literal(
64 &mut self, 149 &mut self,
65 id: ExprId, 150 id: ExprId,
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index 86acd27f8..69bbb4307 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -21,9 +21,13 @@ impl<'a> InferenceContext<'a> {
21 subpats: &[PatId], 21 subpats: &[PatId],
22 expected: &Ty, 22 expected: &Ty,
23 default_bm: BindingMode, 23 default_bm: BindingMode,
24 id: PatId,
24 ) -> Ty { 25 ) -> Ty {
25 let (ty, def) = self.resolve_variant(path); 26 let (ty, def) = self.resolve_variant(path);
26 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 27 let var_data = def.map(|it| variant_data(self.db.upcast(), it));
28 if let Some(variant) = def {
29 self.write_variant_resolution(id.into(), variant);
30 }
27 self.unify(&ty, expected); 31 self.unify(&ty, expected);
28 32
29 let substs = ty.substs().unwrap_or_else(Substs::empty); 33 let substs = ty.substs().unwrap_or_else(Substs::empty);
@@ -152,7 +156,7 @@ impl<'a> InferenceContext<'a> {
152 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 156 Ty::apply_one(TypeCtor::Ref(*mutability), subty)
153 } 157 }
154 Pat::TupleStruct { path: p, args: subpats } => { 158 Pat::TupleStruct { path: p, args: subpats } => {
155 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) 159 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm, pat)
156 } 160 }
157 Pat::Record { path: p, args: fields } => { 161 Pat::Record { path: p, args: fields } => {
158 self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat) 162 self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat)
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 318652c61..2b6bc0f79 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -67,8 +67,16 @@ impl<'a> InferenceContext<'a> {
67 ValueNs::FunctionId(it) => it.into(), 67 ValueNs::FunctionId(it) => it.into(),
68 ValueNs::ConstId(it) => it.into(), 68 ValueNs::ConstId(it) => it.into(),
69 ValueNs::StaticId(it) => it.into(), 69 ValueNs::StaticId(it) => it.into(),
70 ValueNs::StructId(it) => it.into(), 70 ValueNs::StructId(it) => {
71 ValueNs::EnumVariantId(it) => it.into(), 71 self.write_variant_resolution(id, it.into());
72
73 it.into()
74 }
75 ValueNs::EnumVariantId(it) => {
76 self.write_variant_resolution(id, it.into());
77
78 it.into()
79 }
72 }; 80 };
73 81
74 let ty = self.db.value_ty(typable); 82 let ty = self.db.value_ty(typable);
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index a9022dee7..18f74d3b1 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -1,6 +1,11 @@
1//! The type system. We currently use this to infer types for completion, hover 1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists. 2//! information and various assists.
3 3
4#[allow(unused)]
5macro_rules! eprintln {
6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
7}
8
4macro_rules! impl_froms { 9macro_rules! impl_froms {
5 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { 10 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
6 $( 11 $(
@@ -38,6 +43,7 @@ mod tests;
38#[cfg(test)] 43#[cfg(test)]
39mod test_db; 44mod test_db;
40mod marks; 45mod marks;
46mod _match;
41 47
42use std::ops::Deref; 48use std::ops::Deref;
43use std::sync::Arc; 49use std::sync::Arc;
@@ -855,7 +861,8 @@ pub trait TypeWalk {
855 ); 861 );
856 self 862 self
857 } 863 }
858 // /// Shifts up debruijn indices of `Ty::Bound` vars by `n`. 864
865 /// Shifts up debruijn indices of `Ty::Bound` vars by `n`.
859 fn shift_bound_vars(self, n: DebruijnIndex) -> Self 866 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
860 where 867 where
861 Self: Sized, 868 Self: Sized,
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index 208096aab..3a4d58bf9 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -105,8 +105,9 @@ impl TestDB {
105 } 105 }
106 106
107 // FIXME: don't duplicate this 107 // FIXME: don't duplicate this
108 pub fn diagnostics(&self) -> String { 108 pub fn diagnostics(&self) -> (String, u32) {
109 let mut buf = String::new(); 109 let mut buf = String::new();
110 let mut count = 0;
110 let crate_graph = self.crate_graph(); 111 let crate_graph = self.crate_graph();
111 for krate in crate_graph.iter() { 112 for krate in crate_graph.iter() {
112 let crate_def_map = self.crate_def_map(krate); 113 let crate_def_map = self.crate_def_map(krate);
@@ -133,13 +134,14 @@ impl TestDB {
133 let infer = self.infer(f.into()); 134 let infer = self.infer(f.into());
134 let mut sink = DiagnosticSink::new(|d| { 135 let mut sink = DiagnosticSink::new(|d| {
135 format_to!(buf, "{:?}: {}\n", d.syntax_node(self).text(), d.message()); 136 format_to!(buf, "{:?}: {}\n", d.syntax_node(self).text(), d.message());
137 count += 1;
136 }); 138 });
137 infer.add_diagnostics(self, f, &mut sink); 139 infer.add_diagnostics(self, f, &mut sink);
138 let mut validator = ExprValidator::new(f, infer, &mut sink); 140 let mut validator = ExprValidator::new(f, infer, &mut sink);
139 validator.validate_body(self); 141 validator.validate_body(self);
140 } 142 }
141 } 143 }
142 buf 144 (buf, count)
143 } 145 }
144} 146}
145 147
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index c3d793cc2..e6ac0aec3 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -309,7 +309,8 @@ fn no_such_field_diagnostics() {
309 } 309 }
310 ", 310 ",
311 ) 311 )
312 .diagnostics(); 312 .diagnostics()
313 .0;
313 314
314 assert_snapshot!(diagnostics, @r###" 315 assert_snapshot!(diagnostics, @r###"
315 "baz: 62": no such field 316 "baz: 62": no such field
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 081aa943a..22ae6ca90 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -2021,3 +2021,28 @@ fn main() {
2021 "### 2021 "###
2022 ); 2022 );
2023} 2023}
2024
2025#[test]
2026fn dyn_trait_through_chalk() {
2027 let t = type_at(
2028 r#"
2029//- /main.rs
2030struct Box<T> {}
2031#[lang = "deref"]
2032trait Deref {
2033 type Target;
2034}
2035impl<T> Deref for Box<T> {
2036 type Target = T;
2037}
2038trait Trait {
2039 fn foo(&self);
2040}
2041
2042fn test(x: Box<dyn Trait>) {
2043 x.foo()<|>;
2044}
2045"#,
2046 );
2047 assert_eq!(t, "()");
2048}
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 53ce362ea..1bc0f0713 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -427,7 +427,12 @@ impl ToChalk for GenericPredicate {
427 db: &dyn HirDatabase, 427 db: &dyn HirDatabase,
428 where_clause: chalk_ir::QuantifiedWhereClause<Interner>, 428 where_clause: chalk_ir::QuantifiedWhereClause<Interner>,
429 ) -> GenericPredicate { 429 ) -> GenericPredicate {
430 match where_clause.value { 430 // we don't produce any where clauses with binders and can't currently deal with them
431 match where_clause
432 .value
433 .shifted_out(&Interner)
434 .expect("unexpected bound vars in where clause")
435 {
431 chalk_ir::WhereClause::Implemented(tr) => { 436 chalk_ir::WhereClause::Implemented(tr) => {
432 GenericPredicate::Implemented(from_chalk(db, tr)) 437 GenericPredicate::Implemented(from_chalk(db, tr))
433 } 438 }
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 39d09a07f..ca57eceff 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -109,7 +109,7 @@ impl FnCallNode {
109 syntax.ancestors().find_map(|node| { 109 syntax.ancestors().find_map(|node| {
110 match_ast! { 110 match_ast! {
111 match node { 111 match node {
112 ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, 112 ast::CallExpr(it) => Some(FnCallNode::CallExpr(it)),
113 ast::MethodCallExpr(it) => { 113 ast::MethodCallExpr(it) => {
114 let arg_list = it.arg_list()?; 114 let arg_list = it.arg_list()?;
115 if !syntax.text_range().is_subrange(&arg_list.syntax().text_range()) { 115 if !syntax.text_range().is_subrange(&arg_list.syntax().text_range()) {
@@ -117,8 +117,8 @@ impl FnCallNode {
117 } 117 }
118 Some(FnCallNode::MethodCallExpr(it)) 118 Some(FnCallNode::MethodCallExpr(it))
119 }, 119 },
120 ast::MacroCall(it) => { Some(FnCallNode::MacroCallExpr(it)) }, 120 ast::MacroCall(it) => Some(FnCallNode::MacroCallExpr(it)),
121 _ => { None }, 121 _ => None,
122 } 122 }
123 } 123 }
124 }) 124 })
@@ -127,10 +127,10 @@ impl FnCallNode {
127 pub(crate) fn with_node_exact(node: &SyntaxNode) -> Option<FnCallNode> { 127 pub(crate) fn with_node_exact(node: &SyntaxNode) -> Option<FnCallNode> {
128 match_ast! { 128 match_ast! {
129 match node { 129 match node {
130 ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, 130 ast::CallExpr(it) => Some(FnCallNode::CallExpr(it)),
131 ast::MethodCallExpr(it) => { Some(FnCallNode::MethodCallExpr(it)) }, 131 ast::MethodCallExpr(it) => Some(FnCallNode::MethodCallExpr(it)),
132 ast::MacroCall(it) => { Some(FnCallNode::MacroCallExpr(it)) }, 132 ast::MacroCall(it) => Some(FnCallNode::MacroCallExpr(it)),
133 _ => { None }, 133 _ => None,
134 } 134 }
135 } 135 }
136 } 136 }
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs
index 93157bbba..4a1a2a04a 100644
--- a/crates/ra_ide/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
@@ -10,8 +10,8 @@ mod complete_pattern;
10mod complete_fn_param; 10mod complete_fn_param;
11mod complete_keyword; 11mod complete_keyword;
12mod complete_snippet; 12mod complete_snippet;
13mod complete_path; 13mod complete_qualified_path;
14mod complete_scope; 14mod complete_unqualified_path;
15mod complete_postfix; 15mod complete_postfix;
16mod complete_macro_in_item_position; 16mod complete_macro_in_item_position;
17mod complete_trait_impl; 17mod complete_trait_impl;
@@ -85,8 +85,8 @@ pub(crate) fn completions(
85 complete_keyword::complete_use_tree_keyword(&mut acc, &ctx); 85 complete_keyword::complete_use_tree_keyword(&mut acc, &ctx);
86 complete_snippet::complete_expr_snippet(&mut acc, &ctx); 86 complete_snippet::complete_expr_snippet(&mut acc, &ctx);
87 complete_snippet::complete_item_snippet(&mut acc, &ctx); 87 complete_snippet::complete_item_snippet(&mut acc, &ctx);
88 complete_path::complete_path(&mut acc, &ctx); 88 complete_qualified_path::complete_qualified_path(&mut acc, &ctx);
89 complete_scope::complete_scope(&mut acc, &ctx); 89 complete_unqualified_path::complete_unqualified_path(&mut acc, &ctx);
90 complete_dot::complete_dot(&mut acc, &ctx); 90 complete_dot::complete_dot(&mut acc, &ctx);
91 complete_record::complete_record(&mut acc, &ctx); 91 complete_record::complete_record(&mut acc, &ctx);
92 complete_pattern::complete_pattern(&mut acc, &ctx); 92 complete_pattern::complete_pattern(&mut acc, &ctx);
diff --git a/crates/ra_ide/src/completion/complete_fn_param.rs b/crates/ra_ide/src/completion/complete_fn_param.rs
index 9226ac055..62ae5ccb4 100644
--- a/crates/ra_ide/src/completion/complete_fn_param.rs
+++ b/crates/ra_ide/src/completion/complete_fn_param.rs
@@ -18,8 +18,8 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
18 for node in ctx.token.parent().ancestors() { 18 for node in ctx.token.parent().ancestors() {
19 match_ast! { 19 match_ast! {
20 match node { 20 match node {
21 ast::SourceFile(it) => { process(it, &mut params) }, 21 ast::SourceFile(it) => process(it, &mut params),
22 ast::ItemList(it) => { process(it, &mut params) }, 22 ast::ItemList(it) => process(it, &mut params),
23 _ => (), 23 _ => (),
24 } 24 }
25 } 25 }
diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs
index 1e053ea4a..38f9c34e7 100644
--- a/crates/ra_ide/src/completion/complete_keyword.rs
+++ b/crates/ra_ide/src/completion/complete_keyword.rs
@@ -86,9 +86,9 @@ fn is_in_loop_body(leaf: &SyntaxToken) -> bool {
86 } 86 }
87 let loop_body = match_ast! { 87 let loop_body = match_ast! {
88 match node { 88 match node {
89 ast::ForExpr(it) => { it.loop_body() }, 89 ast::ForExpr(it) => it.loop_body(),
90 ast::WhileExpr(it) => { it.loop_body() }, 90 ast::WhileExpr(it) => it.loop_body(),
91 ast::LoopExpr(it) => { it.loop_body() }, 91 ast::LoopExpr(it) => it.loop_body(),
92 _ => None, 92 _ => None,
93 } 93 }
94 }; 94 };
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs
index 3ed2ae2b6..d98523406 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_qualified_path.rs
@@ -6,7 +6,7 @@ use test_utils::tested_by;
6 6
7use crate::completion::{CompletionContext, Completions}; 7use crate::completion::{CompletionContext, Completions};
8 8
9pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { 9pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
10 let path = match &ctx.path_prefix { 10 let path = match &ctx.path_prefix {
11 Some(path) => path.clone(), 11 Some(path) => path.clone(),
12 _ => return, 12 _ => return,
diff --git a/crates/ra_ide/src/completion/complete_record.rs b/crates/ra_ide/src/completion/complete_record.rs
index 01dd8c6db..79f5c8c8f 100644
--- a/crates/ra_ide/src/completion/complete_record.rs
+++ b/crates/ra_ide/src/completion/complete_record.rs
@@ -1,12 +1,13 @@
1//! Complete fields in record literals and patterns. 1//! Complete fields in record literals and patterns.
2use crate::completion::{CompletionContext, Completions};
3use ra_syntax::{ast, ast::NameOwner, SmolStr}; 2use ra_syntax::{ast, ast::NameOwner, SmolStr};
4 3
4use crate::completion::{CompletionContext, Completions};
5
5pub(super) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { 6pub(super) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
6 let (ty, variant, already_present_fields) = 7 let (ty, variant, already_present_fields) =
7 match (ctx.record_lit_pat.as_ref(), ctx.record_lit_syntax.as_ref()) { 8 match (ctx.record_lit_pat.as_ref(), ctx.record_lit_syntax.as_ref()) {
8 (None, None) => return None, 9 (None, None) => return None,
9 (Some(_), Some(_)) => panic!("A record cannot be both a literal and a pattern"), 10 (Some(_), Some(_)) => unreachable!("A record cannot be both a literal and a pattern"),
10 (Some(record_pat), _) => ( 11 (Some(record_pat), _) => (
11 ctx.sema.type_of_pat(&record_pat.clone().into())?, 12 ctx.sema.type_of_pat(&record_pat.clone().into())?,
12 ctx.sema.resolve_record_pattern(record_pat)?, 13 ctx.sema.resolve_record_pattern(record_pat)?,
@@ -59,9 +60,10 @@ fn pattern_ascribed_fields(record_pat: &ast::RecordPat) -> Vec<SmolStr> {
59#[cfg(test)] 60#[cfg(test)]
60mod tests { 61mod tests {
61 mod record_lit_tests { 62 mod record_lit_tests {
62 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
63 use insta::assert_debug_snapshot; 63 use insta::assert_debug_snapshot;
64 64
65 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
66
65 fn complete(code: &str) -> Vec<CompletionItem> { 67 fn complete(code: &str) -> Vec<CompletionItem> {
66 do_completion(code, CompletionKind::Reference) 68 do_completion(code, CompletionKind::Reference)
67 } 69 }
@@ -204,9 +206,10 @@ mod tests {
204 } 206 }
205 207
206 mod record_pat_tests { 208 mod record_pat_tests {
207 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
208 use insta::assert_debug_snapshot; 209 use insta::assert_debug_snapshot;
209 210
211 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
212
210 fn complete(code: &str) -> Vec<CompletionItem> { 213 fn complete(code: &str) -> Vec<CompletionItem> {
211 do_completion(code, CompletionKind::Reference) 214 do_completion(code, CompletionKind::Reference)
212 } 215 }
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs
index 665597e4c..efde9bf73 100644
--- a/crates/ra_ide/src/completion/complete_scope.rs
+++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs
@@ -2,7 +2,7 @@
2 2
3use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
4 4
5pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { 5pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
6 if !(ctx.is_trivial_path && !ctx.is_pat_binding_or_const) { 6 if !(ctx.is_trivial_path && !ctx.is_pat_binding_or_const) {
7 return; 7 return;
8 } 8 }
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index b8213d62f..f833d2a9a 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -50,6 +50,8 @@ pub(crate) struct CompletionContext<'a> {
50 pub(super) dot_receiver_is_ambiguous_float_literal: bool, 50 pub(super) dot_receiver_is_ambiguous_float_literal: bool,
51 /// If this is a call (method or function) in particular, i.e. the () are already there. 51 /// If this is a call (method or function) in particular, i.e. the () are already there.
52 pub(super) is_call: bool, 52 pub(super) is_call: bool,
53 /// If this is a macro call, i.e. the () are already there.
54 pub(super) is_macro_call: bool,
53 pub(super) is_path_type: bool, 55 pub(super) is_path_type: bool,
54 pub(super) has_type_args: bool, 56 pub(super) has_type_args: bool,
55} 57}
@@ -102,6 +104,7 @@ impl<'a> CompletionContext<'a> {
102 is_new_item: false, 104 is_new_item: false,
103 dot_receiver: None, 105 dot_receiver: None,
104 is_call: false, 106 is_call: false,
107 is_macro_call: false,
105 is_path_type: false, 108 is_path_type: false,
106 has_type_args: false, 109 has_type_args: false,
107 dot_receiver_is_ambiguous_float_literal: false, 110 dot_receiver_is_ambiguous_float_literal: false,
@@ -269,6 +272,7 @@ impl<'a> CompletionContext<'a> {
269 .and_then(ast::PathExpr::cast) 272 .and_then(ast::PathExpr::cast)
270 .and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast)) 273 .and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast))
271 .is_some(); 274 .is_some();
275 self.is_macro_call = path.syntax().parent().and_then(ast::MacroCall::cast).is_some();
272 276
273 self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); 277 self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
274 self.has_type_args = segment.type_arg_list().is_some(); 278 self.has_type_args = segment.type_arg_list().is_some();
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index cdfd7bc32..55f75b15a 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -174,7 +174,8 @@ impl Completions {
174 .set_deprecated(is_deprecated(macro_, ctx.db)) 174 .set_deprecated(is_deprecated(macro_, ctx.db))
175 .detail(detail); 175 .detail(detail);
176 176
177 builder = if ctx.use_item_syntax.is_some() { 177 builder = if ctx.use_item_syntax.is_some() || ctx.is_macro_call {
178 tested_by!(dont_insert_macro_call_parens_unncessary);
178 builder.insert_text(name) 179 builder.insert_text(name)
179 } else { 180 } else {
180 let macro_braces_to_insert = 181 let macro_braces_to_insert =
@@ -960,7 +961,8 @@ mod tests {
960 } 961 }
961 962
962 #[test] 963 #[test]
963 fn dont_insert_macro_call_braces_in_use() { 964 fn dont_insert_macro_call_parens_unncessary() {
965 covers!(dont_insert_macro_call_parens_unncessary);
964 assert_debug_snapshot!( 966 assert_debug_snapshot!(
965 do_reference_completion( 967 do_reference_completion(
966 r" 968 r"
@@ -986,6 +988,41 @@ mod tests {
986 }, 988 },
987 ] 989 ]
988 "### 990 "###
989 ) 991 );
992
993 assert_debug_snapshot!(
994 do_reference_completion(
995 r"
996 //- /main.rs
997 macro_rules frobnicate {
998 () => ()
999 }
1000 fn main() {
1001 frob<|>!();
1002 }
1003 "
1004 ),
1005 @r###"
1006 [
1007 CompletionItem {
1008 label: "frobnicate!",
1009 source_range: [56; 60),
1010 delete: [56; 60),
1011 insert: "frobnicate",
1012 kind: Macro,
1013 detail: "macro_rules! frobnicate",
1014 },
1015 CompletionItem {
1016 label: "main()",
1017 source_range: [56; 60),
1018 delete: [56; 60),
1019 insert: "main()$0",
1020 kind: Function,
1021 lookup: "main",
1022 detail: "fn main()",
1023 },
1024 ]
1025 "###
1026 );
990 } 1027 }
991} 1028}
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index c1d7ddaf2..901ad104c 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -101,6 +101,14 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
101 fix, 101 fix,
102 }) 102 })
103 }) 103 })
104 .on::<hir::diagnostics::MissingMatchArms, _>(|d| {
105 res.borrow_mut().push(Diagnostic {
106 range: d.highlight_range(),
107 message: d.message(),
108 severity: Severity::Error,
109 fix: None,
110 })
111 })
104 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { 112 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
105 let node = d.ast(db); 113 let node = d.ast(db);
106 let replacement = format!("Ok({})", node.syntax()); 114 let replacement = format!("Ok({})", node.syntax());
@@ -291,7 +299,7 @@ mod tests {
291 fn check_no_diagnostic(content: &str) { 299 fn check_no_diagnostic(content: &str) {
292 let (analysis, file_id) = single_file(content); 300 let (analysis, file_id) = single_file(content);
293 let diagnostics = analysis.diagnostics(file_id).unwrap(); 301 let diagnostics = analysis.diagnostics(file_id).unwrap();
294 assert_eq!(diagnostics.len(), 0); 302 assert_eq!(diagnostics.len(), 0, "expected no diagnostic, found one");
295 } 303 }
296 304
297 #[test] 305 #[test]
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index d57451cc8..e61846995 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -399,17 +399,17 @@ pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option
399 399
400 match_ast! { 400 match_ast! {
401 match node { 401 match node {
402 ast::FnDef(it) => { it.doc_comment_text() }, 402 ast::FnDef(it) => it.doc_comment_text(),
403 ast::StructDef(it) => { it.doc_comment_text() }, 403 ast::StructDef(it) => it.doc_comment_text(),
404 ast::EnumDef(it) => { it.doc_comment_text() }, 404 ast::EnumDef(it) => it.doc_comment_text(),
405 ast::TraitDef(it) => { it.doc_comment_text() }, 405 ast::TraitDef(it) => it.doc_comment_text(),
406 ast::Module(it) => { it.doc_comment_text() }, 406 ast::Module(it) => it.doc_comment_text(),
407 ast::TypeAliasDef(it) => { it.doc_comment_text() }, 407 ast::TypeAliasDef(it) => it.doc_comment_text(),
408 ast::ConstDef(it) => { it.doc_comment_text() }, 408 ast::ConstDef(it) => it.doc_comment_text(),
409 ast::StaticDef(it) => { it.doc_comment_text() }, 409 ast::StaticDef(it) => it.doc_comment_text(),
410 ast::RecordFieldDef(it) => { it.doc_comment_text() }, 410 ast::RecordFieldDef(it) => it.doc_comment_text(),
411 ast::EnumVariant(it) => { it.doc_comment_text() }, 411 ast::EnumVariant(it) => it.doc_comment_text(),
412 ast::MacroCall(it) => { it.doc_comment_text() }, 412 ast::MacroCall(it) => it.doc_comment_text(),
413 _ => None, 413 _ => None,
414 } 414 }
415 } 415 }
@@ -424,16 +424,16 @@ pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) ->
424 424
425 match_ast! { 425 match_ast! {
426 match node { 426 match node {
427 ast::FnDef(it) => { it.short_label() }, 427 ast::FnDef(it) => it.short_label(),
428 ast::StructDef(it) => { it.short_label() }, 428 ast::StructDef(it) => it.short_label(),
429 ast::EnumDef(it) => { it.short_label() }, 429 ast::EnumDef(it) => it.short_label(),
430 ast::TraitDef(it) => { it.short_label() }, 430 ast::TraitDef(it) => it.short_label(),
431 ast::Module(it) => { it.short_label() }, 431 ast::Module(it) => it.short_label(),
432 ast::TypeAliasDef(it) => { it.short_label() }, 432 ast::TypeAliasDef(it) => it.short_label(),
433 ast::ConstDef(it) => { it.short_label() }, 433 ast::ConstDef(it) => it.short_label(),
434 ast::StaticDef(it) => { it.short_label() }, 434 ast::StaticDef(it) => it.short_label(),
435 ast::RecordFieldDef(it) => { it.short_label() }, 435 ast::RecordFieldDef(it) => it.short_label(),
436 ast::EnumVariant(it) => { it.short_label() }, 436 ast::EnumVariant(it) => it.short_label(),
437 _ => None, 437 _ => None,
438 } 438 }
439 } 439 }
diff --git a/crates/ra_ide/src/display/structure.rs b/crates/ra_ide/src/display/structure.rs
index 5774e9a8b..7a774785c 100644
--- a/crates/ra_ide/src/display/structure.rs
+++ b/crates/ra_ide/src/display/structure.rs
@@ -117,18 +117,18 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
117 117
118 decl_with_detail(it, Some(detail)) 118 decl_with_detail(it, Some(detail))
119 }, 119 },
120 ast::StructDef(it) => { decl(it) }, 120 ast::StructDef(it) => decl(it),
121 ast::EnumDef(it) => { decl(it) }, 121 ast::EnumDef(it) => decl(it),
122 ast::EnumVariant(it) => { decl(it) }, 122 ast::EnumVariant(it) => decl(it),
123 ast::TraitDef(it) => { decl(it) }, 123 ast::TraitDef(it) => decl(it),
124 ast::Module(it) => { decl(it) }, 124 ast::Module(it) => decl(it),
125 ast::TypeAliasDef(it) => { 125 ast::TypeAliasDef(it) => {
126 let ty = it.type_ref(); 126 let ty = it.type_ref();
127 decl_with_type_ref(it, ty) 127 decl_with_type_ref(it, ty)
128 }, 128 },
129 ast::RecordFieldDef(it) => { decl_with_ascription(it) }, 129 ast::RecordFieldDef(it) => decl_with_ascription(it),
130 ast::ConstDef(it) => { decl_with_ascription(it) }, 130 ast::ConstDef(it) => decl_with_ascription(it),
131 ast::StaticDef(it) => { decl_with_ascription(it) }, 131 ast::StaticDef(it) => decl_with_ascription(it),
132 ast::ImplDef(it) => { 132 ast::ImplDef(it) => {
133 let target_type = it.target_type()?; 133 let target_type = it.target_type()?;
134 let target_trait = it.target_trait(); 134 let target_trait = it.target_trait();
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs
index 869a4708b..bd2688df1 100644
--- a/crates/ra_ide/src/goto_type_definition.rs
+++ b/crates/ra_ide/src/goto_type_definition.rs
@@ -18,9 +18,9 @@ pub(crate) fn goto_type_definition(
18 let (ty, node) = sema.ancestors_with_macros(token.parent()).find_map(|node| { 18 let (ty, node) = sema.ancestors_with_macros(token.parent()).find_map(|node| {
19 let ty = match_ast! { 19 let ty = match_ast! {
20 match node { 20 match node {
21 ast::Expr(expr) => { sema.type_of_expr(&expr)? }, 21 ast::Expr(expr) => sema.type_of_expr(&expr)?,
22 ast::Pat(pat) => { sema.type_of_pat(&pat)? }, 22 ast::Pat(pat) => sema.type_of_pat(&pat)?,
23 _ => { return None }, 23 _ => return None,
24 } 24 }
25 }; 25 };
26 26
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 285381086..5599f143f 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -10,6 +10,11 @@
10// For proving that RootDatabase is RefUnwindSafe. 10// For proving that RootDatabase is RefUnwindSafe.
11#![recursion_limit = "128"] 11#![recursion_limit = "128"]
12 12
13#[allow(unused)]
14macro_rules! eprintln {
15 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
16}
17
13pub mod mock_analysis; 18pub mod mock_analysis;
14mod source_change; 19mod source_change;
15 20
diff --git a/crates/ra_ide/src/marks.rs b/crates/ra_ide/src/marks.rs
index 1236cb773..5e1f135c5 100644
--- a/crates/ra_ide/src/marks.rs
+++ b/crates/ra_ide/src/marks.rs
@@ -7,4 +7,5 @@ test_utils::marks!(
7 dont_complete_current_use 7 dont_complete_current_use
8 test_resolve_parent_module_on_module_decl 8 test_resolve_parent_module_on_module_decl
9 search_filters_by_range 9 search_filters_by_range
10 dont_insert_macro_call_parens_unncessary
10); 11);
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 74877e90f..9433f3a24 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -49,8 +49,8 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
49fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { 49fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> {
50 match_ast! { 50 match_ast! {
51 match item { 51 match item {
52 ast::FnDef(it) => { runnable_fn(sema, it) }, 52 ast::FnDef(it) => runnable_fn(sema, it),
53 ast::Module(it) => { runnable_mod(sema, it) }, 53 ast::Module(it) => runnable_mod(sema, it),
54 _ => None, 54 _ => None,
55 } 55 }
56 } 56 }
diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs
index 05a0eed30..1bf014149 100644
--- a/crates/ra_ide_db/src/search.rs
+++ b/crates/ra_ide_db/src/search.rs
@@ -286,7 +286,7 @@ fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<Referen
286 } 286 }
287 Some(ReferenceAccess::Read) 287 Some(ReferenceAccess::Read)
288 }, 288 },
289 _ => {None} 289 _ => None
290 } 290 }
291 } 291 }
292 }); 292 });
diff --git a/crates/ra_ide_db/src/symbol_index.rs b/crates/ra_ide_db/src/symbol_index.rs
index 0f46f93c1..d30458d86 100644
--- a/crates/ra_ide_db/src/symbol_index.rs
+++ b/crates/ra_ide_db/src/symbol_index.rs
@@ -354,14 +354,14 @@ fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
354 } 354 }
355 match_ast! { 355 match_ast! {
356 match node { 356 match node {
357 ast::FnDef(it) => { decl(it) }, 357 ast::FnDef(it) => decl(it),
358 ast::StructDef(it) => { decl(it) }, 358 ast::StructDef(it) => decl(it),
359 ast::EnumDef(it) => { decl(it) }, 359 ast::EnumDef(it) => decl(it),
360 ast::TraitDef(it) => { decl(it) }, 360 ast::TraitDef(it) => decl(it),
361 ast::Module(it) => { decl(it) }, 361 ast::Module(it) => decl(it),
362 ast::TypeAliasDef(it) => { decl(it) }, 362 ast::TypeAliasDef(it) => decl(it),
363 ast::ConstDef(it) => { decl(it) }, 363 ast::ConstDef(it) => decl(it),
364 ast::StaticDef(it) => { decl(it) }, 364 ast::StaticDef(it) => decl(it),
365 ast::MacroCall(it) => { 365 ast::MacroCall(it) => {
366 if it.is_macro_rules().is_some() { 366 if it.is_macro_rules().is_some() {
367 decl(it) 367 decl(it)
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs
index 6a8cb6bb5..355843b94 100644
--- a/crates/ra_syntax/src/tests.rs
+++ b/crates/ra_syntax/src/tests.rs
@@ -3,7 +3,7 @@ use std::{
3 path::{Component, Path, PathBuf}, 3 path::{Component, Path, PathBuf},
4}; 4};
5 5
6use test_utils::{collect_tests, dir_tests, project_dir, read_text}; 6use test_utils::{collect_rust_files, dir_tests, project_dir, read_text};
7 7
8use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token}; 8use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token};
9 9
@@ -13,12 +13,12 @@ fn lexer_tests() {
13 // * Add tests for unicode escapes in byte-character and [raw]-byte-string literals 13 // * Add tests for unicode escapes in byte-character and [raw]-byte-string literals
14 // * Add tests for unescape errors 14 // * Add tests for unescape errors
15 15
16 dir_tests(&test_data_dir(), &["lexer/ok"], |text, path| { 16 dir_tests(&test_data_dir(), &["lexer/ok"], "txt", |text, path| {
17 let (tokens, errors) = tokenize(text); 17 let (tokens, errors) = tokenize(text);
18 assert_errors_are_absent(&errors, path); 18 assert_errors_are_absent(&errors, path);
19 dump_tokens_and_errors(&tokens, &errors, text) 19 dump_tokens_and_errors(&tokens, &errors, text)
20 }); 20 });
21 dir_tests(&test_data_dir(), &["lexer/err"], |text, path| { 21 dir_tests(&test_data_dir(), &["lexer/err"], "txt", |text, path| {
22 let (tokens, errors) = tokenize(text); 22 let (tokens, errors) = tokenize(text);
23 assert_errors_are_present(&errors, path); 23 assert_errors_are_present(&errors, path);
24 dump_tokens_and_errors(&tokens, &errors, text) 24 dump_tokens_and_errors(&tokens, &errors, text)
@@ -40,13 +40,13 @@ fn main() {
40 40
41#[test] 41#[test]
42fn parser_tests() { 42fn parser_tests() {
43 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| { 43 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], "rast", |text, path| {
44 let parse = SourceFile::parse(text); 44 let parse = SourceFile::parse(text);
45 let errors = parse.errors(); 45 let errors = parse.errors();
46 assert_errors_are_absent(&errors, path); 46 assert_errors_are_absent(&errors, path);
47 parse.debug_dump() 47 parse.debug_dump()
48 }); 48 });
49 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { 49 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], "rast", |text, path| {
50 let parse = SourceFile::parse(text); 50 let parse = SourceFile::parse(text);
51 let errors = parse.errors(); 51 let errors = parse.errors();
52 assert_errors_are_present(&errors, path); 52 assert_errors_are_present(&errors, path);
@@ -56,14 +56,14 @@ fn parser_tests() {
56 56
57#[test] 57#[test]
58fn parser_fuzz_tests() { 58fn parser_fuzz_tests() {
59 for (_, text) in collect_tests(&test_data_dir(), &["parser/fuzz-failures"]) { 59 for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) {
60 fuzz::check_parser(&text) 60 fuzz::check_parser(&text)
61 } 61 }
62} 62}
63 63
64#[test] 64#[test]
65fn reparse_fuzz_tests() { 65fn reparse_fuzz_tests() {
66 for (_, text) in collect_tests(&test_data_dir(), &["reparse/fuzz-failures"]) { 66 for (_, text) in collect_rust_files(&test_data_dir(), &["reparse/fuzz-failures"]) {
67 let check = fuzz::CheckReparse::from_data(text.as_bytes()).unwrap(); 67 let check = fuzz::CheckReparse::from_data(text.as_bytes()).unwrap();
68 println!("{:?}", check); 68 println!("{:?}", check);
69 check.run(); 69 check.run();
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index 7915cf8cb..f85b3e61b 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -88,12 +88,12 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
88 for node in root.descendants() { 88 for node in root.descendants() {
89 match_ast! { 89 match_ast! {
90 match node { 90 match node {
91 ast::Literal(it) => { validate_literal(it, &mut errors) }, 91 ast::Literal(it) => validate_literal(it, &mut errors),
92 ast::BlockExpr(it) => { block::validate_block_expr(it, &mut errors) }, 92 ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors),
93 ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, 93 ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors),
94 ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, 94 ast::RecordField(it) => validate_numeric_name(it.name_ref(), &mut errors),
95 ast::Visibility(it) => { validate_visibility(it, &mut errors) }, 95 ast::Visibility(it) => validate_visibility(it, &mut errors),
96 ast::RangeExpr(it) => { validate_range_expr(it, &mut errors) }, 96 ast::RangeExpr(it) => validate_range_expr(it, &mut errors),
97 _ => (), 97 _ => (),
98 } 98 }
99 } 99 }
diff --git a/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt b/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.rast
index edcd936b0..edcd936b0 100644
--- a/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.txt
+++ b/crates/ra_syntax/test_data/parser/err/0000_struct_field_missing_comma.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt b/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.rast
index 2d653715e..2d653715e 100644
--- a/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.txt
+++ b/crates/ra_syntax/test_data/parser/err/0001_item_recovery_in_file.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt b/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.rast
index 002680583..002680583 100644
--- a/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt
+++ b/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt b/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.rast
index 8039a8913..8039a8913 100644
--- a/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.txt
+++ b/crates/ra_syntax/test_data/parser/err/0003_C++_semicolon.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt b/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.rast
index 5f6e10986..5f6e10986 100644
--- a/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.txt
+++ b/crates/ra_syntax/test_data/parser/err/0004_use_path_bad_segment.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt b/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.rast
index cc11421a9..cc11421a9 100644
--- a/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.txt
+++ b/crates/ra_syntax/test_data/parser/err/0005_attribute_recover.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt b/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.rast
index 84fd92862..84fd92862 100644
--- a/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.txt
+++ b/crates/ra_syntax/test_data/parser/err/0006_named_field_recovery.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt b/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.rast
index 1978f30fa..1978f30fa 100644
--- a/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.txt
+++ b/crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt b/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.rast
index 98248227d..98248227d 100644
--- a/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.txt
+++ b/crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt b/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast
index ca508ac7c..ca508ac7c 100644
--- a/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.txt
+++ b/crates/ra_syntax/test_data/parser/err/0009_broken_struct_type_parameter.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.rast
index 0ffbd25aa..0ffbd25aa 100644
--- a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt
+++ b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt b/crates/ra_syntax/test_data/parser/err/0011_extern_struct.rast
index 900894dcf..900894dcf 100644
--- a/crates/ra_syntax/test_data/parser/err/0011_extern_struct.txt
+++ b/crates/ra_syntax/test_data/parser/err/0011_extern_struct.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.txt b/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast
index 12ebc2a3a..12ebc2a3a 100644
--- a/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.txt
+++ b/crates/ra_syntax/test_data/parser/err/0012_broken_lambda.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt b/crates/ra_syntax/test_data/parser/err/0013_invalid_type.rast
index 7a934cf66..7a934cf66 100644
--- a/crates/ra_syntax/test_data/parser/err/0013_invalid_type.txt
+++ b/crates/ra_syntax/test_data/parser/err/0013_invalid_type.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt b/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.rast
index a25d641b8..a25d641b8 100644
--- a/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.txt
+++ b/crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt b/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.rast
index 36b848be3..36b848be3 100644
--- a/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.txt
+++ b/crates/ra_syntax/test_data/parser/err/0015_curly_in_params.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt b/crates/ra_syntax/test_data/parser/err/0016_missing_semi.rast
index 6343580e0..6343580e0 100644
--- a/crates/ra_syntax/test_data/parser/err/0016_missing_semi.txt
+++ b/crates/ra_syntax/test_data/parser/err/0016_missing_semi.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt b/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.rast
index 59480e999..59480e999 100644
--- a/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.txt
+++ b/crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt b/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.rast
index 4b13a7236..4b13a7236 100644
--- a/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.txt
+++ b/crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0019_let_recover.txt b/crates/ra_syntax/test_data/parser/err/0019_let_recover.rast
index 97e91a94f..97e91a94f 100644
--- a/crates/ra_syntax/test_data/parser/err/0019_let_recover.txt
+++ b/crates/ra_syntax/test_data/parser/err/0019_let_recover.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt b/crates/ra_syntax/test_data/parser/err/0020_fn_recover.rast
index c11dc23f5..c11dc23f5 100644
--- a/crates/ra_syntax/test_data/parser/err/0020_fn_recover.txt
+++ b/crates/ra_syntax/test_data/parser/err/0020_fn_recover.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt b/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.rast
index ae04122d8..ae04122d8 100644
--- a/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.txt
+++ b/crates/ra_syntax/test_data/parser/err/0021_incomplete_param.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.rast
index 9f50c85e5..9f50c85e5 100644
--- a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt b/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.rast
index 775e4b0da..775e4b0da 100644
--- a/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.txt
+++ b/crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast
index c5c8a29ba..c5c8a29ba 100644
--- a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt
+++ b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0025_nope.txt b/crates/ra_syntax/test_data/parser/err/0025_nope.rast
index ca7f2d255..ca7f2d255 100644
--- a/crates/ra_syntax/test_data/parser/err/0025_nope.txt
+++ b/crates/ra_syntax/test_data/parser/err/0025_nope.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt b/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.rast
index f239b7b1e..f239b7b1e 100644
--- a/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.txt
+++ b/crates/ra_syntax/test_data/parser/err/0026_imp_recovery.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt b/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.rast
index 4a28bcabf..4a28bcabf 100644
--- a/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.txt
+++ b/crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0029_field_completion.txt b/crates/ra_syntax/test_data/parser/err/0029_field_completion.rast
index 177849476..177849476 100644
--- a/crates/ra_syntax/test_data/parser/err/0029_field_completion.txt
+++ b/crates/ra_syntax/test_data/parser/err/0029_field_completion.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt b/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.rast
index 522a0d0e0..522a0d0e0 100644
--- a/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast
index c36e2f770..c36e2f770 100644
--- a/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast
index e914e688b..e914e688b 100644
--- a/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt b/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.rast
index 2c91b6841..2c91b6841 100644
--- a/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.txt
+++ b/crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt b/crates/ra_syntax/test_data/parser/err/0035_use_recover.rast
index 8cb4ea796..8cb4ea796 100644
--- a/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt
+++ b/crates/ra_syntax/test_data/parser/err/0035_use_recover.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rast
index f5490fbe8..f5490fbe8 100644
--- a/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt
+++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rast
index d8622d45f..d8622d45f 100644
--- a/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt
+++ b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rast
index 3810b9680..3810b9680 100644
--- a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt
+++ b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rast
diff --git a/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt b/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.rast
index 4a2f0a696..4a2f0a696 100644
--- a/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.txt
+++ b/crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt b/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.rast
index 530533b71..530533b71 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0001_array_type_missing_semi.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt b/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast
index 01a853d63..01a853d63 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt b/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast
index 2ab29eecc..2ab29eecc 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt b/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.rast
index 124f0a891..124f0a891 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0004_impl_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt b/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rast
index 9e9186ad4..9e9186ad4 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt b/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.rast
index 690acdca3..690acdca3 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt b/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.rast
index a4002a998..a4002a998 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt b/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.rast
index 6f45a4fa6..6f45a4fa6 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt b/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast
index e6d3a5c95..e6d3a5c95 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt b/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.rast
index 8ad2a588f..8ad2a588f 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt b/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast
index f6ac0feaf..f6ac0feaf 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt b/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.rast
index 5b3dc5af2..5b3dc5af2 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0013_static_underscore.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt b/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.rast
index 25d80be1d..25d80be1d 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.rast
index ad9f0965e..ad9f0965e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0002_use_tree_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0002_use_tree_list.rast
index 1b318dfb9..1b318dfb9 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0002_use_tree_list.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0002_use_tree_list.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.txt b/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
index e3f5a7f04..e3f5a7f04 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast
index 9241f6fb2..9241f6fb2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.txt b/crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.rast
index 8ae7909f9..8ae7909f9 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.txt b/crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.rast
index 757ac092a..757ac092a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0007_type_param_bounds.txt b/crates/ra_syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast
index a7186c7a8..a7186c7a8 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0007_type_param_bounds.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.txt b/crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.rast
index 3812adc9e..3812adc9e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.rast
index 2d8872022..2d8872022 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0010_extern_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0010_extern_block.rast
index 506f56fff..506f56fff 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0010_extern_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0010_extern_block.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.rast
index 29b268b55..29b268b55 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0012_type_item_where_clause.txt b/crates/ra_syntax/test_data/parser/inline/ok/0012_type_item_where_clause.rast
index da04dac5c..da04dac5c 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0012_type_item_where_clause.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0012_type_item_where_clause.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.txt b/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast
index c05f873d6..c05f873d6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0013_pointer_type_mut.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0014_never_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0014_never_type.rast
index ac53e4fd3..ac53e4fd3 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0014_never_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0014_never_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.rast
index c051c1c86..c051c1c86 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0016_unsafe_trait.txt b/crates/ra_syntax/test_data/parser/inline/ok/0016_unsafe_trait.rast
index 7b43f1294..7b43f1294 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0016_unsafe_trait.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0016_unsafe_trait.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0017_array_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0017_array_type.rast
index b4055c9f0..b4055c9f0 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0017_array_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0017_array_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.txt b/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast
index 89caee543..89caee543 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rast
index 2d71efd86..2d71efd86 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0020_use_star.txt b/crates/ra_syntax/test_data/parser/inline/ok/0020_use_star.rast
index dd2095d90..dd2095d90 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0020_use_star.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0020_use_star.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.rast
index b1af67976..b1af67976 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0022_crate_visibility.txt b/crates/ra_syntax/test_data/parser/inline/ok/0022_crate_visibility.rast
index 891943f6e..891943f6e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0022_crate_visibility.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0022_crate_visibility.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0023_placeholder_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0023_placeholder_type.rast
index 0f32aec9e..0f32aec9e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0023_placeholder_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0023_placeholder_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.rast
index 48aaeaf07..48aaeaf07 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0025_slice_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0025_slice_type.rast
index b3a24281e..b3a24281e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0025_slice_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0025_slice_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.txt b/crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.rast
index 666386d31..666386d31 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.rast
index 0f1a367f7..0f1a367f7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0028_impl_trait_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast
index f07027fa7..f07027fa7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0028_impl_trait_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.rast
index b17a2c257..b17a2c257 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt b/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.rast
index 6fd49c7bc..6fd49c7bc 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rast
index a6e14a114..a6e14a114 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast
index 4c17f0db8..4c17f0db8 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.txt b/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast
index 7642ea659..7642ea659 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0033_reference_type;.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.rast
index 67ffdfd67..67ffdfd67 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.txt b/crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.rast
index a7dfe167c..a7dfe167c 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.txt b/crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.rast
index 6e226de4b..6e226de4b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.rast
index 042cee879..042cee879 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rast
index 025faf5ca..025faf5ca 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.txt b/crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.rast
index d180fcf20..d180fcf20 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0041_trait_item.txt b/crates/ra_syntax/test_data/parser/inline/ok/0041_trait_item.rast
index 578361715..578361715 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0041_trait_item.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0041_trait_item.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.rast
index e8003bf91..e8003bf91 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0043_use_alias.txt b/crates/ra_syntax/test_data/parser/inline/ok/0043_use_alias.rast
index 18d8a151f..18d8a151f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0043_use_alias.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0043_use_alias.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.rast
index e75d569f0..e75d569f0 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.txt b/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
index 33886154d..33886154d 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0046_singleton_tuple_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0046_singleton_tuple_type.rast
index c7b4e614d..c7b4e614d 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0046_singleton_tuple_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0046_singleton_tuple_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0047_unsafe_default_impl.txt b/crates/ra_syntax/test_data/parser/inline/ok/0047_unsafe_default_impl.rast
index 0a768a8e3..0a768a8e3 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0047_unsafe_default_impl.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0047_unsafe_default_impl.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.txt b/crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast
index 02f2a9db6..02f2a9db6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0050_fn_decl.txt b/crates/ra_syntax/test_data/parser/inline/ok/0050_fn_decl.rast
index 19f961e29..19f961e29 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0050_fn_decl.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0050_fn_decl.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0051_unit_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0051_unit_type.rast
index 6a469f8aa..6a469f8aa 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0051_unit_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0051_unit_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0052_path_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0052_path_type.rast
index ee55ee219..ee55ee219 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0052_path_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0052_path_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.rast
index f1018fcab..f1018fcab 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt b/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.rast
index 731c31f76..731c31f76 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0054_record_field_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.txt b/crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.rast
index 2b28cec67..2b28cec67 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.txt b/crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.rast
index 9a9a13370..9a9a13370 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.txt b/crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.rast
index 9788197be..9788197be 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.rast
index 3d659ce10..3d659ce10 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.txt b/crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.rast
index efcd89c4c..efcd89c4c 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0060_extern_crate.txt b/crates/ra_syntax/test_data/parser/inline/ok/0060_extern_crate.rast
index 7667201ba..7667201ba 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0060_extern_crate.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0060_extern_crate.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.txt b/crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.rast
index dcf527639..dcf527639 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.txt b/crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.rast
index 6b528c252..6b528c252 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0063_impl_def_neg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0063_impl_def_neg.rast
index 0cc3ac085..0cc3ac085 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0063_impl_def_neg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0063_impl_def_neg.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rast
index 2ace3c8ee..2ace3c8ee 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0065_dyn_trait_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast
index 2ee0dc199..2ee0dc199 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0065_dyn_trait_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt b/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.rast
index 2f07af4e1..2f07af4e1 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0067_crate_path.txt b/crates/ra_syntax/test_data/parser/inline/ok/0067_crate_path.rast
index f2ba4e909..f2ba4e909 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0067_crate_path.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0067_crate_path.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.rast
index 9d7982684..9d7982684 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0069_use_tree_list_after_path.txt b/crates/ra_syntax/test_data/parser/inline/ok/0069_use_tree_list_after_path.rast
index 86afc9362..86afc9362 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0069_use_tree_list_after_path.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0069_use_tree_list_after_path.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.txt b/crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rast
index cd63d10f7..cd63d10f7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rast
index 0af668056..0af668056 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.rast
index 4a83a7200..4a83a7200 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0073_type_item_type_params.txt b/crates/ra_syntax/test_data/parser/inline/ok/0073_type_item_type_params.rast
index 2dd6db28f..2dd6db28f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0073_type_item_type_params.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0073_type_item_type_params.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.txt b/crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rast
index cbd2d5fbf..cbd2d5fbf 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0075_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0075_block.rast
index 28d1bad97..28d1bad97 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0075_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0075_block.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.txt b/crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.rast
index 8e4b63f02..8e4b63f02 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.rast
index 18ccfe9ef..18ccfe9ef 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0078_type_item.txt b/crates/ra_syntax/test_data/parser/inline/ok/0078_type_item.rast
index 4bc0b1858..4bc0b1858 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0078_type_item.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0078_type_item.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0079_impl_def.txt b/crates/ra_syntax/test_data/parser/inline/ok/0079_impl_def.rast
index 4c2863ba7..4c2863ba7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0079_impl_def.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0079_impl_def.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt b/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rast
index 9f8a6b0f6..9f8a6b0f6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast
index b1353c2c6..b1353c2c6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast
index 8f34afe76..8f34afe76 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0083_struct_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0083_struct_items.rast
index e909f2b78..e909f2b78 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0083_struct_items.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0083_struct_items.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0084_paren_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0084_paren_type.rast
index c0cf48af5..c0cf48af5 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0084_paren_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0084_paren_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.txt b/crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.rast
index 2903c6f9a..2903c6f9a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.rast
index ca1a97161..ca1a97161 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0087_unsafe_impl.txt b/crates/ra_syntax/test_data/parser/inline/ok/0087_unsafe_impl.rast
index e614acc6f..e614acc6f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0087_unsafe_impl.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0087_unsafe_impl.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.txt b/crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.rast
index b23f43b46..b23f43b46 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.txt b/crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.rast
index b494f6c59..b494f6c59 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0090_type_param_default.txt b/crates/ra_syntax/test_data/parser/inline/ok/0090_type_param_default.rast
index 8d2579cd6..8d2579cd6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0090_type_param_default.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0090_type_param_default.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0091_auto_trait.txt b/crates/ra_syntax/test_data/parser/inline/ok/0091_auto_trait.rast
index 7093c2b1f..7093c2b1f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0091_auto_trait.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0091_auto_trait.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.txt b/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast
index fae822367..fae822367 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.rast
index 1a979e597..1a979e597 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0094_unsafe_auto_trait.txt b/crates/ra_syntax/test_data/parser/inline/ok/0094_unsafe_auto_trait.rast
index 3da3beaf4..3da3beaf4 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0094_unsafe_auto_trait.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0094_unsafe_auto_trait.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.rast
index fe86894a9..fe86894a9 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast
index 157aa29f5..157aa29f5 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0097_default_impl.txt b/crates/ra_syntax/test_data/parser/inline/ok/0097_default_impl.rast
index af9077270..af9077270 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0097_default_impl.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0097_default_impl.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.txt b/crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.rast
index 072dc9d16..072dc9d16 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.rast
index ed57a9eea..ed57a9eea 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.rast
index 83c58d25f..83c58d25f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.txt b/crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.rast
index b7979fbf5..b7979fbf5 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rast
index d8e04bd90..d8e04bd90 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.rast
index 0db62a1f5..0db62a1f5 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt b/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rast
index a983d5954..a983d5954 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0104_path_fn_trait_args.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.rast
index 6bce37a4f..6bce37a4f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.rast
index 0216123f0..0216123f0 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.rast
index ba478528c..ba478528c 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.rast
index 6f685ca8d..6f685ca8d 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0109_label.txt b/crates/ra_syntax/test_data/parser/inline/ok/0109_label.rast
index 3376a90cb..3376a90cb 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0109_label.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0109_label.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0110_use_path.txt b/crates/ra_syntax/test_data/parser/inline/ok/0110_use_path.rast
index 7dbcd3927..7dbcd3927 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0110_use_path.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0110_use_path.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rast
index 4680c267e..4680c267e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.rast
index ad1d47b0e..ad1d47b0e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.rast
index 5db1ff2af..5db1ff2af 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0114_tuple_struct_where.txt b/crates/ra_syntax/test_data/parser/inline/ok/0114_tuple_struct_where.rast
index f5de01405..f5de01405 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0114_tuple_struct_where.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0114_tuple_struct_where.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt b/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.rast
index 8fe15d8e2..8fe15d8e2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0115_tuple_field_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0117_macro_call_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0117_macro_call_type.rast
index 892dc813a..892dc813a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0117_macro_call_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0117_macro_call_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.rast
index 5053ebde7..5053ebde7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0118_impl_inner_attributes.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.txt b/crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.rast
index 852e4e489..852e4e489 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt b/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rast
index 640e0640f..640e0640f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rast
index ff380b448..ff380b448 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt b/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
index a73ff9c90..a73ff9c90 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast
index 6c3b17868..6c3b17868 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.txt b/crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.rast
index 9c4bd7f11..9c4bd7f11 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.txt b/crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.rast
index 6a9f3bf72..6a9f3bf72 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rast
index a36c3df0e..a36c3df0e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt b/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast
index 5c311d18a..5c311d18a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast
index 21f49690a..21f49690a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.txt b/crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.rast
index 8a972cdb2..8a972cdb2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.rast
index 36d8f4a5f..36d8f4a5f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.txt b/crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.rast
index 17739dfbd..17739dfbd 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.rast
index d6df1aba2..d6df1aba2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0131_existential_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0131_existential_type.rast
index 6bfac985a..6bfac985a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0131_existential_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0131_existential_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.rast
index 12294210e..12294210e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.rast
index e1734224b..e1734224b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.txt b/crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rast
index 14655d332..14655d332 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.rast
index a6ac0dbd8..a6ac0dbd8 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.txt b/crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.rast
index d18096b47..d18096b47 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.rast
index df4c04149..df4c04149 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast
index e627b9746..e627b9746 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
index cf202c94b..cf202c94b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.txt b/crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.rast
index eec1cba1e..eec1cba1e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.rast
index 4d2048711..4d2048711 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.rast
index 325b1bd08..325b1bd08 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rast
index 06fbdfabf..06fbdfabf 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast
index 9e3767fb7..9e3767fb7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0147_const_param.txt b/crates/ra_syntax/test_data/parser/inline/ok/0147_const_param.rast
index f81de7bac..f81de7bac 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0147_const_param.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0147_const_param.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt b/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.rast
index 3556099bd..3556099bd 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt b/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.rast
index cfd79d9c2..cfd79d9c2 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.txt b/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast
index 78e296f88..78e296f88 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0150_array_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt b/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rast
index 2d46eebb3..2d46eebb3 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0151_trait_alias.txt b/crates/ra_syntax/test_data/parser/inline/ok/0151_trait_alias.rast
index de1536ef0..de1536ef0 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0151_trait_alias.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0151_trait_alias.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rast
index 8092d7009..8092d7009 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast
index cb686854a..cb686854a 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.txt b/crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.rast
index 98727ae98..98727ae98 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt b/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rast
index 103e254a6..103e254a6 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.txt b/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rast
index 3a196d3c0..3a196d3c0 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast
index 52d8f21a4..52d8f21a4 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0157_variant_discriminant.txt b/crates/ra_syntax/test_data/parser/inline/ok/0157_variant_discriminant.rast
index a378dd80b..a378dd80b 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0157_variant_discriminant.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0157_variant_discriminant.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.txt b/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rast
index d568a1d45..d568a1d45 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rast
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rast
index ba8779094..ba8779094 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0000_empty.txt b/crates/ra_syntax/test_data/parser/ok/0000_empty.rast
index 08f5a942f..08f5a942f 100644
--- a/crates/ra_syntax/test_data/parser/ok/0000_empty.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0000_empty.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0001_struct_item.txt b/crates/ra_syntax/test_data/parser/ok/0001_struct_item.rast
index fdc2d6768..fdc2d6768 100644
--- a/crates/ra_syntax/test_data/parser/ok/0001_struct_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0001_struct_item.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0002_struct_item_field.txt b/crates/ra_syntax/test_data/parser/ok/0002_struct_item_field.rast
index ef34702fd..ef34702fd 100644
--- a/crates/ra_syntax/test_data/parser/ok/0002_struct_item_field.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0002_struct_item_field.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0004_file_shebang.txt b/crates/ra_syntax/test_data/parser/ok/0004_file_shebang.rast
index e3915c2df..e3915c2df 100644
--- a/crates/ra_syntax/test_data/parser/ok/0004_file_shebang.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0004_file_shebang.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0005_fn_item.txt b/crates/ra_syntax/test_data/parser/ok/0005_fn_item.rast
index 955b789b5..955b789b5 100644
--- a/crates/ra_syntax/test_data/parser/ok/0005_fn_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0005_fn_item.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt b/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.rast
index d72b72561..d72b72561 100644
--- a/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0006_inner_attributes.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0007_extern_crate.txt b/crates/ra_syntax/test_data/parser/ok/0007_extern_crate.rast
index 1ffa36c7e..1ffa36c7e 100644
--- a/crates/ra_syntax/test_data/parser/ok/0007_extern_crate.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0007_extern_crate.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt b/crates/ra_syntax/test_data/parser/ok/0008_mod_item.rast
index 061019a73..061019a73 100644
--- a/crates/ra_syntax/test_data/parser/ok/0008_mod_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0008_mod_item.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0009_use_item.txt b/crates/ra_syntax/test_data/parser/ok/0009_use_item.rast
index 41db9dbb7..41db9dbb7 100644
--- a/crates/ra_syntax/test_data/parser/ok/0009_use_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0009_use_item.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0010_use_path_segments.txt b/crates/ra_syntax/test_data/parser/ok/0010_use_path_segments.rast
index 09871b84d..09871b84d 100644
--- a/crates/ra_syntax/test_data/parser/ok/0010_use_path_segments.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0010_use_path_segments.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt b/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rast
index f7aa8afe4..f7aa8afe4 100644
--- a/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0012_visibility.txt b/crates/ra_syntax/test_data/parser/ok/0012_visibility.rast
index 68e692fd0..68e692fd0 100644
--- a/crates/ra_syntax/test_data/parser/ok/0012_visibility.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0012_visibility.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.txt b/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast
index 50730e958..50730e958 100644
--- a/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0014_use_tree.txt b/crates/ra_syntax/test_data/parser/ok/0014_use_tree.rast
index 3fe34d001..3fe34d001 100644
--- a/crates/ra_syntax/test_data/parser/ok/0014_use_tree.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0014_use_tree.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0015_use_tree.txt b/crates/ra_syntax/test_data/parser/ok/0015_use_tree.rast
index e63f14253..e63f14253 100644
--- a/crates/ra_syntax/test_data/parser/ok/0015_use_tree.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0015_use_tree.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0016_struct_flavors.txt b/crates/ra_syntax/test_data/parser/ok/0016_struct_flavors.rast
index 3fbd14d7b..3fbd14d7b 100644
--- a/crates/ra_syntax/test_data/parser/ok/0016_struct_flavors.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0016_struct_flavors.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt b/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.rast
index 1d65b0d6e..1d65b0d6e 100644
--- a/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0018_struct_type_params.txt b/crates/ra_syntax/test_data/parser/ok/0018_struct_type_params.rast
index 1e4e58dd3..1e4e58dd3 100644
--- a/crates/ra_syntax/test_data/parser/ok/0018_struct_type_params.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0018_struct_type_params.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0019_enums.txt b/crates/ra_syntax/test_data/parser/ok/0019_enums.rast
index 9d4a47a51..9d4a47a51 100644
--- a/crates/ra_syntax/test_data/parser/ok/0019_enums.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0019_enums.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0020_type_param_bounds.txt b/crates/ra_syntax/test_data/parser/ok/0020_type_param_bounds.rast
index 18a5fd784..18a5fd784 100644
--- a/crates/ra_syntax/test_data/parser/ok/0020_type_param_bounds.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0020_type_param_bounds.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0021_extern_fn.txt b/crates/ra_syntax/test_data/parser/ok/0021_extern_fn.rast
index 974fb9c44..974fb9c44 100644
--- a/crates/ra_syntax/test_data/parser/ok/0021_extern_fn.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0021_extern_fn.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0022_empty_extern_block.txt b/crates/ra_syntax/test_data/parser/ok/0022_empty_extern_block.rast
index bbbd95fd9..bbbd95fd9 100644
--- a/crates/ra_syntax/test_data/parser/ok/0022_empty_extern_block.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0022_empty_extern_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0023_static_items.txt b/crates/ra_syntax/test_data/parser/ok/0023_static_items.rast
index 5591f95eb..5591f95eb 100644
--- a/crates/ra_syntax/test_data/parser/ok/0023_static_items.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0023_static_items.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0024_const_item.txt b/crates/ra_syntax/test_data/parser/ok/0024_const_item.rast
index abe9f851b..abe9f851b 100644
--- a/crates/ra_syntax/test_data/parser/ok/0024_const_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0024_const_item.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.txt b/crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.rast
index f5a7a1a5a..f5a7a1a5a 100644
--- a/crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.txt b/crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.rast
index f9b1dcf1a..f9b1dcf1a 100644
--- a/crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.txt b/crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast
index 9fb7b70a0..9fb7b70a0 100644
--- a/crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.txt b/crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.rast
index afca1fba2..afca1fba2 100644
--- a/crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0029_range_forms.txt b/crates/ra_syntax/test_data/parser/ok/0029_range_forms.rast
index 95dae4870..95dae4870 100644
--- a/crates/ra_syntax/test_data/parser/ok/0029_range_forms.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0029_range_forms.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.txt b/crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.rast
index cdc9f05ae..cdc9f05ae 100644
--- a/crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0030_traits.txt b/crates/ra_syntax/test_data/parser/ok/0030_traits.rast
index ac314ae50..ac314ae50 100644
--- a/crates/ra_syntax/test_data/parser/ok/0030_traits.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0030_traits.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0031_extern.txt b/crates/ra_syntax/test_data/parser/ok/0031_extern.rast
index badbf76c5..badbf76c5 100644
--- a/crates/ra_syntax/test_data/parser/ok/0031_extern.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0031_extern.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0032_where_for.txt b/crates/ra_syntax/test_data/parser/ok/0032_where_for.rast
index 3a333480e..3a333480e 100644
--- a/crates/ra_syntax/test_data/parser/ok/0032_where_for.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0032_where_for.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0033_label_break.txt b/crates/ra_syntax/test_data/parser/ok/0033_label_break.rast
index bd9e3fd85..bd9e3fd85 100644
--- a/crates/ra_syntax/test_data/parser/ok/0033_label_break.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0033_label_break.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.txt b/crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.rast
index fc0d452f4..fc0d452f4 100644
--- a/crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast
index 90538b90d..90538b90d 100644
--- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.txt b/crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.rast
index ac5444087..ac5444087 100644
--- a/crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0037_mod.txt b/crates/ra_syntax/test_data/parser/ok/0037_mod.rast
index 3af40a104..3af40a104 100644
--- a/crates/ra_syntax/test_data/parser/ok/0037_mod.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0037_mod.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.txt b/crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.rast
index 377367914..377367914 100644
--- a/crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.txt b/crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.rast
index 9936892e9..9936892e9 100644
--- a/crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0040_raw_struct_item_field.txt b/crates/ra_syntax/test_data/parser/ok/0040_raw_struct_item_field.rast
index 05f2c656f..05f2c656f 100644
--- a/crates/ra_syntax/test_data/parser/ok/0040_raw_struct_item_field.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0040_raw_struct_item_field.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.txt b/crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.rast
index 64c70e196..64c70e196 100644
--- a/crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.txt b/crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.rast
index 341e02704..341e02704 100644
--- a/crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.txt b/crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.rast
index c5821afd0..c5821afd0 100644
--- a/crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.rast
index bfc793dc1..bfc793dc1 100644
--- a/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0044_let_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.rast
index e15447ca7..e15447ca7 100644
--- a/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt b/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.rast
index 8f192124b..8f192124b 100644
--- a/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0046_extern_inner_attributes.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.txt b/crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast
index 07a5fbf2d..07a5fbf2d 100644
--- a/crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.txt b/crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.rast
index c9cf84ffd..c9cf84ffd 100644
--- a/crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0049_async_block.txt b/crates/ra_syntax/test_data/parser/ok/0049_async_block.rast
index aa6daff7d..aa6daff7d 100644
--- a/crates/ra_syntax/test_data/parser/ok/0049_async_block.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0049_async_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.txt b/crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.rast
index 435f27970..435f27970 100644
--- a/crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast
index 254eafc36..254eafc36 100644
--- a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0052_for_range_block.txt b/crates/ra_syntax/test_data/parser/ok/0052_for_range_block.rast
index 374c58670..374c58670 100644
--- a/crates/ra_syntax/test_data/parser/ok/0052_for_range_block.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0052_for_range_block.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt b/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast
index 04ff0e2ff..04ff0e2ff 100644
--- a/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.txt b/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast
index 7e1af254c..7e1af254c 100644
--- a/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.txt b/crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.rast
index d656e74b1..d656e74b1 100644
--- a/crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt b/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rast
index 4a4ad84ca..4a4ad84ca 100644
--- a/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt b/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rast
index cc8c3f7ec..cc8c3f7ec 100644
--- a/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt b/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rast
index d30cb63ff..d30cb63ff 100644
--- a/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt b/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rast
index c011187ea..c011187ea 100644
--- a/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0060_as_range.txt b/crates/ra_syntax/test_data/parser/ok/0060_as_range.rast
index ad0c4a3fe..ad0c4a3fe 100644
--- a/crates/ra_syntax/test_data/parser/ok/0060_as_range.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0060_as_range.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0061_match_full_range.txt b/crates/ra_syntax/test_data/parser/ok/0061_match_full_range.rast
index bdfac9b76..bdfac9b76 100644
--- a/crates/ra_syntax/test_data/parser/ok/0061_match_full_range.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0061_match_full_range.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt b/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.rast
index 2be523fc3..2be523fc3 100644
--- a/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.txt b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast
index eb2e3a503..eb2e3a503 100644
--- a/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast
index 186f03626..186f03626 100644
--- a/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.txt b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast
index b30030de3..b30030de3 100644
--- a/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast
diff --git a/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.txt b/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rast
index 91d0c3736..91d0c3736 100644
--- a/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rast
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index b6a015790..4734df16a 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -131,37 +131,47 @@ impl Config {
131 set(value, "/cargo/allFeatures", &mut self.cargo.all_features); 131 set(value, "/cargo/allFeatures", &mut self.cargo.all_features);
132 set(value, "/cargo/features", &mut self.cargo.features); 132 set(value, "/cargo/features", &mut self.cargo.features);
133 set(value, "/cargo/loadOutDirsFromCheck", &mut self.cargo.load_out_dirs_from_check); 133 set(value, "/cargo/loadOutDirsFromCheck", &mut self.cargo.load_out_dirs_from_check);
134 if let Some(mut args) = get::<Vec<String>>(value, "/rustfmt/overrideCommand") { 134 match get::<Vec<String>>(value, "/rustfmt/overrideCommand") {
135 if !args.is_empty() { 135 Some(mut args) if !args.is_empty() => {
136 let command = args.remove(0); 136 let command = args.remove(0);
137 self.rustfmt = RustfmtConfig::CustomCommand { 137 self.rustfmt = RustfmtConfig::CustomCommand {
138 command, 138 command,
139 args, 139 args,
140 } 140 }
141 } 141 }
142 } else if let RustfmtConfig::Rustfmt { extra_args } = &mut self.rustfmt { 142 _ => {
143 set(value, "/rustfmt/extraArgs", extra_args); 143 if let RustfmtConfig::Rustfmt { extra_args } = &mut self.rustfmt {
144 } 144 set(value, "/rustfmt/extraArgs", extra_args);
145 }
146 }
147 };
145 148
146 if let Some(false) = get(value, "/checkOnSave/enable") { 149 if let Some(false) = get(value, "/checkOnSave/enable") {
150 // check is disabled
147 self.check = None; 151 self.check = None;
148 } else { 152 } else {
149 if let Some(mut args) = get::<Vec<String>>(value, "/checkOnSave/overrideCommand") { 153 // check is enabled
150 if !args.is_empty() { 154 match get::<Vec<String>>(value, "/checkOnSave/overrideCommand") {
155 // first see if the user has completely overridden the command
156 Some(mut args) if !args.is_empty() => {
151 let command = args.remove(0); 157 let command = args.remove(0);
152 self.check = Some(FlycheckConfig::CustomCommand { 158 self.check = Some(FlycheckConfig::CustomCommand {
153 command, 159 command,
154 args, 160 args,
155 }); 161 });
156 } 162 }
157 163 // otherwise configure command customizations
158 } else if let Some(FlycheckConfig::CargoCommand { command, extra_args, all_targets }) = &mut self.check 164 _ => {
159 { 165 if let Some(FlycheckConfig::CargoCommand { command, extra_args, all_targets })
160 set(value, "/checkOnSave/extraArgs", extra_args); 166 = &mut self.check
161 set(value, "/checkOnSave/command", command); 167 {
162 set(value, "/checkOnSave/allTargets", all_targets); 168 set(value, "/checkOnSave/extraArgs", extra_args);
163 } 169 set(value, "/checkOnSave/command", command);
164 }; 170 set(value, "/checkOnSave/allTargets", all_targets);
171 }
172 }
173 };
174 }
165 175
166 set(value, "/inlayHints/typeHints", &mut self.inlay_hints.type_hints); 176 set(value, "/inlayHints/typeHints", &mut self.inlay_hints.type_hints);
167 set(value, "/inlayHints/parameterHints", &mut self.inlay_hints.parameter_hints); 177 set(value, "/inlayHints/parameterHints", &mut self.inlay_hints.parameter_hints);
diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs
index 02953be30..036bf62a7 100644
--- a/crates/rust-analyzer/src/lib.rs
+++ b/crates/rust-analyzer/src/lib.rs
@@ -13,17 +13,8 @@
13pub mod cli; 13pub mod cli;
14 14
15#[allow(unused)] 15#[allow(unused)]
16macro_rules! println { 16macro_rules! eprintln {
17 ($($tt:tt)*) => { 17 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
18 compile_error!("stdout is locked, use eprintln")
19 };
20}
21
22#[allow(unused)]
23macro_rules! print {
24 ($($tt:tt)*) => {
25 compile_error!("stdout is locked, use eprint")
26 };
27} 18}
28 19
29mod vfs_glob; 20mod vfs_glob;
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index d2efa2236..401a568bd 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -2,6 +2,21 @@
2 2
3use std::{cell::Cell, fmt}; 3use std::{cell::Cell, fmt};
4 4
5#[inline(always)]
6pub fn is_ci() -> bool {
7 option_env!("CI").is_some()
8}
9
10#[macro_export]
11macro_rules! eprintln {
12 ($($tt:tt)*) => {{
13 if $crate::is_ci() {
14 panic!("Forgot to remove debug-print?")
15 }
16 std::eprintln!($($tt)*)
17 }}
18}
19
5/// Appends formatted string to a `String`. 20/// Appends formatted string to a `String`.
6#[macro_export] 21#[macro_export]
7macro_rules! format_to { 22macro_rules! format_to {
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index db03df1c4..4164bfd5e 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -302,42 +302,40 @@ pub fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a
302 } 302 }
303} 303}
304 304
305/// Calls callback `f` with input code and file paths of all `.rs` files from `test_data_dir` 305/// Calls callback `f` with input code and file paths for each `.rs` file in `test_data_dir`
306/// subdirectories defined by `paths`. 306/// subdirectories defined by `paths`.
307/// 307///
308/// If the content of the matching `.txt` file differs from the output of `f()` 308/// If the content of the matching output file differs from the output of `f()`
309/// the test will fail. 309/// the test will fail.
310/// 310///
311/// If there is no matching `.txt` file it will be created and filled with the 311/// If there is no matching output file it will be created and filled with the
312/// output of `f()`, but the test will fail. 312/// output of `f()`, but the test will fail.
313pub fn dir_tests<F>(test_data_dir: &Path, paths: &[&str], f: F) 313pub fn dir_tests<F>(test_data_dir: &Path, paths: &[&str], outfile_extension: &str, f: F)
314where 314where
315 F: Fn(&str, &Path) -> String, 315 F: Fn(&str, &Path) -> String,
316{ 316{
317 for (path, input_code) in collect_tests(test_data_dir, paths) { 317 for (path, input_code) in collect_rust_files(test_data_dir, paths) {
318 let parse_tree = f(&input_code, &path); 318 let actual = f(&input_code, &path);
319 let path = path.with_extension("txt"); 319 let path = path.with_extension(outfile_extension);
320 if !path.exists() { 320 if !path.exists() {
321 println!("\nfile: {}", path.display()); 321 println!("\nfile: {}", path.display());
322 println!("No .txt file with expected result, creating...\n"); 322 println!("No .txt file with expected result, creating...\n");
323 println!("{}\n{}", input_code, parse_tree); 323 println!("{}\n{}", input_code, actual);
324 fs::write(&path, &parse_tree).unwrap(); 324 fs::write(&path, &actual).unwrap();
325 panic!("No expected result") 325 panic!("No expected result");
326 } 326 }
327 let expected = read_text(&path); 327 let expected = read_text(&path);
328 let expected = expected.as_str(); 328 assert_equal_text(&expected, &actual, &path);
329 let parse_tree = parse_tree.as_str();
330 assert_equal_text(expected, parse_tree, &path);
331 } 329 }
332} 330}
333 331
334/// Collects all `.rs` files from `test_data_dir` subdirectories defined by `paths`. 332/// Collects all `.rs` files from `dir` subdirectories defined by `paths`.
335pub fn collect_tests(test_data_dir: &Path, paths: &[&str]) -> Vec<(PathBuf, String)> { 333pub fn collect_rust_files(root_dir: &Path, paths: &[&str]) -> Vec<(PathBuf, String)> {
336 paths 334 paths
337 .iter() 335 .iter()
338 .flat_map(|path| { 336 .flat_map(|path| {
339 let path = test_data_dir.to_owned().join(path); 337 let path = root_dir.to_owned().join(path);
340 test_from_dir(&path).into_iter() 338 rust_files_in_dir(&path).into_iter()
341 }) 339 })
342 .map(|path| { 340 .map(|path| {
343 let text = read_text(&path); 341 let text = read_text(&path);
@@ -347,7 +345,7 @@ pub fn collect_tests(test_data_dir: &Path, paths: &[&str]) -> Vec<(PathBuf, Stri
347} 345}
348 346
349/// Collects paths to all `.rs` files from `dir` in a sorted `Vec<PathBuf>`. 347/// Collects paths to all `.rs` files from `dir` in a sorted `Vec<PathBuf>`.
350fn test_from_dir(dir: &Path) -> Vec<PathBuf> { 348fn rust_files_in_dir(dir: &Path) -> Vec<PathBuf> {
351 let mut acc = Vec::new(); 349 let mut acc = Vec::new();
352 for file in fs::read_dir(&dir).unwrap() { 350 for file in fs::read_dir(&dir).unwrap() {
353 let file = file.unwrap(); 351 let file = file.unwrap();
diff --git a/editors/code/package.json b/editors/code/package.json
index 60ca0c69c..8ae8ea414 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -251,11 +251,15 @@
251 "description": "Additional arguments to rustfmt" 251 "description": "Additional arguments to rustfmt"
252 }, 252 },
253 "rust-analyzer.rustfmt.overrideCommand": { 253 "rust-analyzer.rustfmt.overrideCommand": {
254 "type": "array", 254 "type": [
255 "null",
256 "array"
257 ],
255 "items": { 258 "items": {
256 "type": "string" 259 "type": "string",
260 "minItems": 1
257 }, 261 },
258 "default": [], 262 "default": null,
259 "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for formatting." 263 "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for formatting."
260 }, 264 },
261 "rust-analyzer.checkOnSave.enable": { 265 "rust-analyzer.checkOnSave.enable": {
@@ -277,11 +281,15 @@
277 "markdownDescription": "Cargo command to use for `cargo check`" 281 "markdownDescription": "Cargo command to use for `cargo check`"
278 }, 282 },
279 "rust-analyzer.checkOnSave.overrideCommand": { 283 "rust-analyzer.checkOnSave.overrideCommand": {
280 "type": "array", 284 "type": [
285 "null",
286 "array"
287 ],
281 "items": { 288 "items": {
282 "type": "string" 289 "type": "string",
290 "minItems": 1
283 }, 291 },
284 "default": [], 292 "default": null,
285 "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for checking. The command should include `--message=format=json` or similar option." 293 "markdownDescription": "Advanced option, fully override the command rust-analyzer uses for checking. The command should include `--message=format=json` or similar option."
286 }, 294 },
287 "rust-analyzer.checkOnSave.allTargets": { 295 "rust-analyzer.checkOnSave.allTargets": {
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 4f01f84fb..0b8243f62 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -172,8 +172,8 @@ pub fn run_pre_cache() -> Result<()> {
172pub fn run_release(dry_run: bool) -> Result<()> { 172pub fn run_release(dry_run: bool) -> Result<()> {
173 if !dry_run { 173 if !dry_run {
174 run!("git switch release")?; 174 run!("git switch release")?;
175 run!("git fetch upstream")?; 175 run!("git fetch upstream --tags --force")?;
176 run!("git reset --hard upstream/master")?; 176 run!("git reset --hard tags/nightly")?;
177 run!("git push")?; 177 run!("git push")?;
178 } 178 }
179 179