aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock80
-rw-r--r--crates/ra_assists/src/ast_transform.rs2
-rw-r--r--crates/ra_assists/src/doc_tests/generated.rs4
-rw-r--r--crates/ra_assists/src/handlers/add_missing_impl_members.rs194
-rw-r--r--crates/ra_assists/src/handlers/early_return.rs16
-rw-r--r--crates/ra_assists/src/handlers/inline_local_variable.rs1
-rw-r--r--crates/ra_assists/src/handlers/introduce_variable.rs2
-rw-r--r--crates/ra_assists/src/handlers/move_guard.rs4
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/ra_fmt/src/lib.rs1
-rw-r--r--crates/ra_hir/src/lib.rs3
-rw-r--r--crates/ra_hir/src/semantics.rs7
-rw-r--r--crates/ra_hir/src/source_analyzer.rs3
-rw-r--r--crates/ra_hir_def/src/adt.rs18
-rw-r--r--crates/ra_hir_def/src/body.rs2
-rw-r--r--crates/ra_hir_def/src/body/lower.rs62
-rw-r--r--crates/ra_hir_def/src/data.rs21
-rw-r--r--crates/ra_hir_def/src/expr.rs4
-rw-r--r--crates/ra_hir_def/src/generics.rs68
-rw-r--r--crates/ra_hir_def/src/path.rs5
-rw-r--r--crates/ra_hir_def/src/path/lower.rs23
-rw-r--r--crates/ra_hir_def/src/type_ref.rs52
-rw-r--r--crates/ra_hir_expand/src/db.rs3
-rw-r--r--crates/ra_hir_expand/src/hygiene.rs2
-rw-r--r--crates/ra_hir_ty/Cargo.toml2
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs5
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs40
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs32
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs2
-rw-r--r--crates/ra_ide/src/display/short_label.rs6
-rw-r--r--crates/ra_ide/src/folding_ranges.rs2
-rw-r--r--crates/ra_ide/src/hover.rs11
-rw-r--r--crates/ra_ide/src/join_lines.rs3
-rw-r--r--crates/ra_ide/src/syntax_tree.rs77
-rw-r--r--crates/ra_mbe/src/tests.rs152
-rw-r--r--crates/ra_parser/src/grammar.rs2
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs13
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs39
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs2
-rw-r--r--crates/ra_proc_macro_srv/Cargo.toml2
-rw-r--r--crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt7
-rw-r--r--crates/ra_proc_macro_srv/src/tests/mod.rs6
-rw-r--r--crates/ra_project_model/Cargo.toml2
-rw-r--r--crates/ra_syntax/Cargo.toml4
-rw-r--r--crates/ra_syntax/src/ast.rs4
-rw-r--r--crates/ra_syntax/src/ast/edit.rs2
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs31
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs2
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs83
-rw-r--r--crates/ra_syntax/src/ast/make.rs8
-rw-r--r--crates/ra_syntax/src/lib.rs7
-rw-r--r--crates/ra_syntax/src/parsing/lexer.rs37
-rw-r--r--crates/ra_syntax/src/validation.rs119
-rw-r--r--crates/ra_syntax/src/validation/block.rs20
-rw-r--r--crates/ra_syntax/test_data/parser/err/0005_attribute_recover.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/err/0007_stray_curly_in_file.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/err/0008_item_block_recovery.rast52
-rw-r--r--crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.rast61
-rw-r--r--crates/ra_syntax/test_data/parser/err/0014_where_no_bounds.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/err/0016_missing_semi.rast61
-rw-r--r--crates/ra_syntax/test_data/parser/err/0017_incomplete_binexpr.rast45
-rw-r--r--crates/ra_syntax/test_data/parser/err/0018_incomplete_fn.rast165
-rw-r--r--crates/ra_syntax/test_data/parser/err/0019_let_recover.rast166
-rw-r--r--crates/ra_syntax/test_data/parser/err/0020_fn_recover.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/err/0021_incomplete_param.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/err/0022_bad_exprs.rast229
-rw-r--r--crates/ra_syntax/test_data/parser/err/0023_mismatched_paren.rast49
-rw-r--r--crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast430
-rw-r--r--crates/ra_syntax/test_data/parser/err/0025_nope.rast360
-rw-r--r--crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/err/0029_field_completion.rast23
-rw-r--r--crates/ra_syntax/test_data/parser/err/0031_block_inner_attrs.rast214
-rw-r--r--crates/ra_syntax/test_data/parser/err/0032_match_arms_inner_attrs.rast361
-rw-r--r--crates/ra_syntax/test_data/parser/err/0033_match_arms_outer_attrs.rast103
-rw-r--r--crates/ra_syntax/test_data/parser/err/0034_bad_box_pattern.rast155
-rw-r--r--crates/ra_syntax/test_data/parser/err/0035_use_recover.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.rast31
-rw-r--r--crates/ra_syntax/test_data/parser/err/0039_lambda_recovery.rast121
-rw-r--r--crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rast70
-rw-r--r--crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rs4
-rw-r--r--crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rast27
-rw-r--r--crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast25
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0006_unsafe_block_in_mod.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0007_async_without_semicolon.rast37
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0008_pub_expr.rast25
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0009_attr_on_expr_not_allowed.rast92
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.rast77
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0010_wrong_order_fns.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0014_default_fn_type.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast71
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0001_trait_item_list.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0003_where_pred_for.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0005_function_type_params.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0006_self_param.rast25
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0008_path_part.rast169
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0009_loop_expr.rast26
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.rast95
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0015_continue_expr.rast48
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0018_arb_self_types.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rast65
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0021_impl_item_list.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0024_slice_pat.rast59
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0026_tuple_pat_fields.rast185
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0027_ref_pat.rast75
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0029_cast_expr.rast155
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0030_cond.rast365
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0031_while_expr.rast149
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0034_break_expr.rast84
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0036_unsafe_extern_fn.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0037_qual_paths.rast67
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0038_full_range_expr.rast33
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rast13
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0040_crate_keyword_vis.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0042_call_expr.rast271
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0044_block_items.rast34
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0053_path_expr.rast167
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0055_literal_pattern.rast129
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0056_where_clause.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0057_const_fn.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0058_range_pat.rast141
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0059_match_arms_commas.rast94
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0061_record_lit.rast225
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0062_mod_contents.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0064_if_expr.rast229
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.rast279
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rast79
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0071_match_expr.rast165
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0072_return_expr.rast33
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rast98
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0075_block.rast86
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0076_function_where_clause.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0077_try_expr.rast27
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0080_postfix_range.rast167
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0081_for_type.rast15
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast85
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0085_expr_literals.rast247
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0086_function_ret_type.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0088_break_ambiguity.rast112
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0089_extern_fn.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0093_index_expr.rast43
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0095_placeholder_pat.rast33
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast229
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0098_const_unsafe_fn.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0099_param_list.rast20
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0100_for_expr.rast46
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0101_unsafe_fn.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rast241
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0103_array_expr.rast85
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.rast48
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0105_block_expr.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0106_lambda_expr.rast251
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0107_method_call_expr.rast101
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0108_tuple_expr.rast53
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0109_label.rast108
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rast155
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0112_bind_pat.rast231
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0113_nocontentexpr.rast90
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0118_match_guard.rast71
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rast137
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rast267
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0124_async_fn.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0125_crate_keyword_path.rast39
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rast71
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast172
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0127_attr_on_last_expr_in_block.rast92
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0128_combined_fns.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.rast49
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0130_let_stmt.rast231
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0130_try_block_expr.rast40
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0132_box_expr.rast155
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0132_default_fn_type.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rast102
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.rast115
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_associated_type_bounds.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_expression_after_block.rast106
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0138_self_param_outer_attr.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0142_for_range_from.rast58
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0143_box_pat.rast197
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0144_dot_dot_pat.rast887
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rast127
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0146_as_precedence.rast61
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rast49
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0155_closure_params.rast115
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rast199
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rast50
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rast64
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0159_try_macro_fallback.rast45
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0161_labeled_block.rast26
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0161_labeled_block.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0162_unsafe_block.rast23
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0162_unsafe_block.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0005_fn_item.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0008_mod_item.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0011_outer_attribute.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0012_visibility.rast25
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast26
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0017_attr_trailing_comma.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0021_extern_fn.rast21
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0025_extern_fn_in_block.rast40
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0026_const_fn_in_block.rast38
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0027_unsafe_fn_in_block.rast60
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0028_operator_binding_power.rast347
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0029_range_forms.rast279
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0030_string_suffixes.rast103
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0032_where_for.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0033_label_break.rast407
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0034_crate_path_in_call.rast59
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.rast3912
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0036_fully_qualified.rast27
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0038_where_pred_type.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0039_raw_fn_item.rast7
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0041_raw_keywords.rast77
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0042_ufcs_call_list.rast97
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0043_complex_assignment.rast133
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0044_let_attrs.rast123
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0045_block_inner_attrs.rast196
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0047_minus_in_inner_pattern.rast495
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0048_compound_assignment.rast373
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0049_async_block.rast47
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0050_async_block_as_argument.rast56
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.rast55
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0052_for_range_block.rast135
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0054_qual_path_in_type_arg.rast15
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0055_dot_dot_dot.rast49
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0056_neq_in_type.rast106
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0057_loop_in_call.rast49
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0058_unary_expr_precedence.rast169
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rast174
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0060_as_range.rast87
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0061_match_full_range.rast29
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.rast205
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rast20
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rast20
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rast5
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast5
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/caps.rs29
-rw-r--r--crates/rust-analyzer/src/config.rs6
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs38
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/main.rs4
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/support.rs6
-rw-r--r--docs/dev/architecture.md4
-rw-r--r--docs/dev/guide.md8
-rw-r--r--docs/user/assists.md4
-rw-r--r--docs/user/readme.adoc11
-rw-r--r--xtask/src/ast_src.rs18
-rw-r--r--xtask/src/codegen/gen_syntax.rs1
255 files changed, 11241 insertions, 11165 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 522ecf2ee..5d50a766f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -58,9 +58,9 @@ dependencies = [
58 58
59[[package]] 59[[package]]
60name = "backtrace-sys" 60name = "backtrace-sys"
61version = "0.1.36" 61version = "0.1.37"
62source = "registry+https://github.com/rust-lang/crates.io-index" 62source = "registry+https://github.com/rust-lang/crates.io-index"
63checksum = "78848718ee1255a2485d1309ad9cdecfc2e7d0362dd11c6829364c6b35ae1bc7" 63checksum = "18fbebbe1c9d1f383a9cc7e8ccdb471b91c8d024ee9c2ca5b5346121fe8b4399"
64dependencies = [ 64dependencies = [
65 "cc", 65 "cc",
66 "libc", 66 "libc",
@@ -170,7 +170,7 @@ dependencies = [
170 "chalk-ir", 170 "chalk-ir",
171 "chalk-macros", 171 "chalk-macros",
172 "chalk-rust-ir", 172 "chalk-rust-ir",
173 "ena", 173 "ena 0.13.1",
174 "itertools", 174 "itertools",
175 "petgraph", 175 "petgraph",
176 "rustc-hash", 176 "rustc-hash",
@@ -199,14 +199,15 @@ dependencies = [
199 199
200[[package]] 200[[package]]
201name = "console" 201name = "console"
202version = "0.10.0" 202version = "0.10.3"
203source = "registry+https://github.com/rust-lang/crates.io-index" 203source = "registry+https://github.com/rust-lang/crates.io-index"
204checksum = "6728a28023f207181b193262711102bfbaf47cc9d13bc71d0736607ef8efe88c" 204checksum = "2586208b33573b7f76ccfbe5adb076394c88deaf81b84d7213969805b0a952a7"
205dependencies = [ 205dependencies = [
206 "clicolors-control", 206 "clicolors-control",
207 "encode_unicode", 207 "encode_unicode",
208 "lazy_static", 208 "lazy_static",
209 "libc", 209 "libc",
210 "terminal_size",
210 "termios", 211 "termios",
211 "winapi 0.3.8", 212 "winapi 0.3.8",
212] 213]
@@ -316,6 +317,15 @@ dependencies = [
316] 317]
317 318
318[[package]] 319[[package]]
320name = "ena"
321version = "0.14.0"
322source = "registry+https://github.com/rust-lang/crates.io-index"
323checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
324dependencies = [
325 "log",
326]
327
328[[package]]
319name = "encode_unicode" 329name = "encode_unicode"
320version = "0.3.6" 330version = "0.3.6"
321source = "registry+https://github.com/rust-lang/crates.io-index" 331source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -381,9 +391,9 @@ dependencies = [
381 391
382[[package]] 392[[package]]
383name = "fst" 393name = "fst"
384version = "0.4.1" 394version = "0.4.3"
385source = "registry+https://github.com/rust-lang/crates.io-index" 395source = "registry+https://github.com/rust-lang/crates.io-index"
386checksum = "4eaf9ea41cc964d742f7fc7861db75d2d6e83a3ce0d897d5c6f8b621f015ddc8" 396checksum = "81f9cac32c1741cdf6b66be7dcf0d9c7f25ccf12f8aa84c16cfa31f9f14513b3"
387 397
388[[package]] 398[[package]]
389name = "fuchsia-zircon" 399name = "fuchsia-zircon"
@@ -447,9 +457,9 @@ dependencies = [
447 457
448[[package]] 458[[package]]
449name = "hermit-abi" 459name = "hermit-abi"
450version = "0.1.11" 460version = "0.1.12"
451source = "registry+https://github.com/rust-lang/crates.io-index" 461source = "registry+https://github.com/rust-lang/crates.io-index"
452checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15" 462checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
453dependencies = [ 463dependencies = [
454 "libc", 464 "libc",
455] 465]
@@ -645,9 +655,9 @@ dependencies = [
645 655
646[[package]] 656[[package]]
647name = "lsp-types" 657name = "lsp-types"
648version = "0.74.0" 658version = "0.74.1"
649source = "registry+https://github.com/rust-lang/crates.io-index" 659source = "registry+https://github.com/rust-lang/crates.io-index"
650checksum = "820f746e5716ab9a2d664794636188bd003023b72e55404ee27105dc22869922" 660checksum = "57c0e6a2b8837d27b29deb3f3e6dc1c6d2f57947677f9be1024e482ec5b59525"
651dependencies = [ 661dependencies = [
652 "base64", 662 "base64",
653 "bitflags", 663 "bitflags",
@@ -696,9 +706,9 @@ dependencies = [
696 706
697[[package]] 707[[package]]
698name = "mio" 708name = "mio"
699version = "0.6.21" 709version = "0.6.22"
700source = "registry+https://github.com/rust-lang/crates.io-index" 710source = "registry+https://github.com/rust-lang/crates.io-index"
701checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" 711checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
702dependencies = [ 712dependencies = [
703 "cfg-if", 713 "cfg-if",
704 "fuchsia-zircon", 714 "fuchsia-zircon",
@@ -739,9 +749,9 @@ dependencies = [
739 749
740[[package]] 750[[package]]
741name = "net2" 751name = "net2"
742version = "0.2.33" 752version = "0.2.34"
743source = "registry+https://github.com/rust-lang/crates.io-index" 753source = "registry+https://github.com/rust-lang/crates.io-index"
744checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 754checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
745dependencies = [ 755dependencies = [
746 "cfg-if", 756 "cfg-if",
747 "libc", 757 "libc",
@@ -814,9 +824,9 @@ dependencies = [
814 824
815[[package]] 825[[package]]
816name = "paste" 826name = "paste"
817version = "0.1.10" 827version = "0.1.11"
818source = "registry+https://github.com/rust-lang/crates.io-index" 828source = "registry+https://github.com/rust-lang/crates.io-index"
819checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" 829checksum = "a3c897744f63f34f7ae3a024d9162bb5001f4ad661dd24bea0dc9f075d2de1c6"
820dependencies = [ 830dependencies = [
821 "paste-impl", 831 "paste-impl",
822 "proc-macro-hack", 832 "proc-macro-hack",
@@ -824,9 +834,9 @@ dependencies = [
824 834
825[[package]] 835[[package]]
826name = "paste-impl" 836name = "paste-impl"
827version = "0.1.10" 837version = "0.1.11"
828source = "registry+https://github.com/rust-lang/crates.io-index" 838source = "registry+https://github.com/rust-lang/crates.io-index"
829checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" 839checksum = "66fd6f92e3594f2dd7b3fc23e42d82e292f7bcda6d8e5dcd167072327234ab89"
830dependencies = [ 840dependencies = [
831 "proc-macro-hack", 841 "proc-macro-hack",
832 "proc-macro2", 842 "proc-macro2",
@@ -885,9 +895,9 @@ dependencies = [
885 895
886[[package]] 896[[package]]
887name = "quote" 897name = "quote"
888version = "1.0.3" 898version = "1.0.4"
889source = "registry+https://github.com/rust-lang/crates.io-index" 899source = "registry+https://github.com/rust-lang/crates.io-index"
890checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" 900checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7"
891dependencies = [ 901dependencies = [
892 "proc-macro2", 902 "proc-macro2",
893] 903]
@@ -1023,7 +1033,7 @@ dependencies = [
1023 "chalk-ir", 1033 "chalk-ir",
1024 "chalk-rust-ir", 1034 "chalk-rust-ir",
1025 "chalk-solve", 1035 "chalk-solve",
1026 "ena", 1036 "ena 0.14.0",
1027 "insta", 1037 "insta",
1028 "itertools", 1038 "itertools",
1029 "log", 1039 "log",
@@ -1374,9 +1384,9 @@ dependencies = [
1374 1384
1375[[package]] 1385[[package]]
1376name = "rustc-ap-rustc_lexer" 1386name = "rustc-ap-rustc_lexer"
1377version = "652.0.0" 1387version = "656.0.0"
1378source = "registry+https://github.com/rust-lang/crates.io-index" 1388source = "registry+https://github.com/rust-lang/crates.io-index"
1379checksum = "3a6a43c4d0889218c5e2ae68ffea239f303fc05ab1078c73f74e63feb87f7889" 1389checksum = "9cbba98ec46e96a4663197dfa8c0378752de2006e314e5400c0ca74929d6692f"
1380dependencies = [ 1390dependencies = [
1381 "unicode-xid", 1391 "unicode-xid",
1382] 1392]
@@ -1486,18 +1496,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
1486 1496
1487[[package]] 1497[[package]]
1488name = "serde" 1498name = "serde"
1489version = "1.0.104" 1499version = "1.0.106"
1490source = "registry+https://github.com/rust-lang/crates.io-index" 1500source = "registry+https://github.com/rust-lang/crates.io-index"
1491checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" 1501checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
1492dependencies = [ 1502dependencies = [
1493 "serde_derive", 1503 "serde_derive",
1494] 1504]
1495 1505
1496[[package]] 1506[[package]]
1497name = "serde_derive" 1507name = "serde_derive"
1498version = "1.0.104" 1508version = "1.0.106"
1499source = "registry+https://github.com/rust-lang/crates.io-index" 1509source = "registry+https://github.com/rust-lang/crates.io-index"
1500checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" 1510checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
1501dependencies = [ 1511dependencies = [
1502 "proc-macro2", 1512 "proc-macro2",
1503 "quote", 1513 "quote",
@@ -1506,9 +1516,9 @@ dependencies = [
1506 1516
1507[[package]] 1517[[package]]
1508name = "serde_json" 1518name = "serde_json"
1509version = "1.0.51" 1519version = "1.0.52"
1510source = "registry+https://github.com/rust-lang/crates.io-index" 1520source = "registry+https://github.com/rust-lang/crates.io-index"
1511checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" 1521checksum = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd"
1512dependencies = [ 1522dependencies = [
1513 "itoa", 1523 "itoa",
1514 "ryu", 1524 "ryu",
@@ -1607,6 +1617,16 @@ dependencies = [
1607] 1617]
1608 1618
1609[[package]] 1619[[package]]
1620name = "terminal_size"
1621version = "0.1.12"
1622source = "registry+https://github.com/rust-lang/crates.io-index"
1623checksum = "8038f95fc7a6f351163f4b964af631bd26c9e828f7db085f2a84aca56f70d13b"
1624dependencies = [
1625 "libc",
1626 "winapi 0.3.8",
1627]
1628
1629[[package]]
1610name = "termios" 1630name = "termios"
1611version = "0.3.2" 1631version = "0.3.2"
1612source = "registry+https://github.com/rust-lang/crates.io-index" 1632source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs
index 52b4c82db..9ac65ab39 100644
--- a/crates/ra_assists/src/ast_transform.rs
+++ b/crates/ra_assists/src/ast_transform.rs
@@ -85,6 +85,7 @@ impl<'a> SubstituteTypeParams<'a> {
85 ast::TypeRef::PathType(path_type) => path_type.path()?, 85 ast::TypeRef::PathType(path_type) => path_type.path()?,
86 _ => return None, 86 _ => return None,
87 }; 87 };
88 // FIXME: use `hir::Path::from_src` instead.
88 let path = hir::Path::from_ast(path)?; 89 let path = hir::Path::from_ast(path)?;
89 let resolution = self.source_scope.resolve_hir_path(&path)?; 90 let resolution = self.source_scope.resolve_hir_path(&path)?;
90 match resolution { 91 match resolution {
@@ -128,6 +129,7 @@ impl<'a> QualifyPaths<'a> {
128 // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway 129 // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
129 return None; 130 return None;
130 } 131 }
132 // FIXME: use `hir::Path::from_src` instead.
131 let hir_path = hir::Path::from_ast(p.clone()); 133 let hir_path = hir::Path::from_ast(p.clone());
132 let resolution = self.source_scope.resolve_hir_path(&hir_path?)?; 134 let resolution = self.source_scope.resolve_hir_path(&hir_path?)?;
133 match resolution { 135 match resolution {
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs
index b53b97e89..6696cc832 100644
--- a/crates/ra_assists/src/doc_tests/generated.rs
+++ b/crates/ra_assists/src/doc_tests/generated.rs
@@ -180,7 +180,9 @@ trait Trait<T> {
180} 180}
181 181
182impl Trait<u32> for () { 182impl Trait<u32> for () {
183 fn foo(&self) -> u32 { todo!() } 183 fn foo(&self) -> u32 {
184 todo!()
185 }
184 186
185} 187}
186"#####, 188"#####,
diff --git a/crates/ra_assists/src/handlers/add_missing_impl_members.rs b/crates/ra_assists/src/handlers/add_missing_impl_members.rs
index 2d6d44980..e466c9a86 100644
--- a/crates/ra_assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/handlers/add_missing_impl_members.rs
@@ -1,6 +1,10 @@
1use hir::HasSource; 1use hir::HasSource;
2use ra_syntax::{ 2use ra_syntax::{
3 ast::{self, edit, make, AstNode, NameOwner}, 3 ast::{
4 self,
5 edit::{self, IndentLevel},
6 make, AstNode, NameOwner,
7 },
4 SmolStr, 8 SmolStr,
5}; 9};
6 10
@@ -40,7 +44,9 @@ enum AddMissingImplMembersMode {
40// } 44// }
41// 45//
42// impl Trait<u32> for () { 46// impl Trait<u32> for () {
43// fn foo(&self) -> u32 { todo!() } 47// fn foo(&self) -> u32 {
48// todo!()
49// }
44// 50//
45// } 51// }
46// ``` 52// ```
@@ -165,7 +171,9 @@ fn add_missing_impl_members_inner(
165 171
166fn add_body(fn_def: ast::FnDef) -> ast::FnDef { 172fn add_body(fn_def: ast::FnDef) -> ast::FnDef {
167 if fn_def.body().is_none() { 173 if fn_def.body().is_none() {
168 fn_def.with_body(make::block_from_expr(make::expr_todo())) 174 let body = make::block_expr(None, Some(make::expr_todo()));
175 let body = IndentLevel(1).increase_indent(body);
176 fn_def.with_body(body)
169 } else { 177 } else {
170 fn_def 178 fn_def
171 } 179 }
@@ -181,7 +189,7 @@ mod tests {
181 fn test_add_missing_impl_members() { 189 fn test_add_missing_impl_members() {
182 check_assist( 190 check_assist(
183 add_missing_impl_members, 191 add_missing_impl_members,
184 " 192 r#"
185trait Foo { 193trait Foo {
186 type Output; 194 type Output;
187 195
@@ -197,8 +205,8 @@ struct S;
197impl Foo for S { 205impl Foo for S {
198 fn bar(&self) {} 206 fn bar(&self) {}
199<|> 207<|>
200}", 208}"#,
201 " 209 r#"
202trait Foo { 210trait Foo {
203 type Output; 211 type Output;
204 212
@@ -215,10 +223,14 @@ impl Foo for S {
215 fn bar(&self) {} 223 fn bar(&self) {}
216 <|>type Output; 224 <|>type Output;
217 const CONST: usize = 42; 225 const CONST: usize = 42;
218 fn foo(&self) { todo!() } 226 fn foo(&self) {
219 fn baz(&self) { todo!() } 227 todo!()
228 }
229 fn baz(&self) {
230 todo!()
231 }
220 232
221}", 233}"#,
222 ); 234 );
223 } 235 }
224 236
@@ -226,7 +238,7 @@ impl Foo for S {
226 fn test_copied_overriden_members() { 238 fn test_copied_overriden_members() {
227 check_assist( 239 check_assist(
228 add_missing_impl_members, 240 add_missing_impl_members,
229 " 241 r#"
230trait Foo { 242trait Foo {
231 fn foo(&self); 243 fn foo(&self);
232 fn bar(&self) -> bool { true } 244 fn bar(&self) -> bool { true }
@@ -238,8 +250,8 @@ struct S;
238impl Foo for S { 250impl Foo for S {
239 fn bar(&self) {} 251 fn bar(&self) {}
240<|> 252<|>
241}", 253}"#,
242 " 254 r#"
243trait Foo { 255trait Foo {
244 fn foo(&self); 256 fn foo(&self);
245 fn bar(&self) -> bool { true } 257 fn bar(&self) -> bool { true }
@@ -250,9 +262,11 @@ struct S;
250 262
251impl Foo for S { 263impl Foo for S {
252 fn bar(&self) {} 264 fn bar(&self) {}
253 <|>fn foo(&self) { todo!() } 265 <|>fn foo(&self) {
266 todo!()
267 }
254 268
255}", 269}"#,
256 ); 270 );
257 } 271 }
258 272
@@ -260,16 +274,18 @@ impl Foo for S {
260 fn test_empty_impl_def() { 274 fn test_empty_impl_def() {
261 check_assist( 275 check_assist(
262 add_missing_impl_members, 276 add_missing_impl_members,
263 " 277 r#"
264trait Foo { fn foo(&self); } 278trait Foo { fn foo(&self); }
265struct S; 279struct S;
266impl Foo for S { <|> }", 280impl Foo for S { <|> }"#,
267 " 281 r#"
268trait Foo { fn foo(&self); } 282trait Foo { fn foo(&self); }
269struct S; 283struct S;
270impl Foo for S { 284impl Foo for S {
271 <|>fn foo(&self) { todo!() } 285 <|>fn foo(&self) {
272}", 286 todo!()
287 }
288}"#,
273 ); 289 );
274 } 290 }
275 291
@@ -277,16 +293,18 @@ impl Foo for S {
277 fn fill_in_type_params_1() { 293 fn fill_in_type_params_1() {
278 check_assist( 294 check_assist(
279 add_missing_impl_members, 295 add_missing_impl_members,
280 " 296 r#"
281trait Foo<T> { fn foo(&self, t: T) -> &T; } 297trait Foo<T> { fn foo(&self, t: T) -> &T; }
282struct S; 298struct S;
283impl Foo<u32> for S { <|> }", 299impl Foo<u32> for S { <|> }"#,
284 " 300 r#"
285trait Foo<T> { fn foo(&self, t: T) -> &T; } 301trait Foo<T> { fn foo(&self, t: T) -> &T; }
286struct S; 302struct S;
287impl Foo<u32> for S { 303impl Foo<u32> for S {
288 <|>fn foo(&self, t: u32) -> &u32 { todo!() } 304 <|>fn foo(&self, t: u32) -> &u32 {
289}", 305 todo!()
306 }
307}"#,
290 ); 308 );
291 } 309 }
292 310
@@ -294,16 +312,18 @@ impl Foo<u32> for S {
294 fn fill_in_type_params_2() { 312 fn fill_in_type_params_2() {
295 check_assist( 313 check_assist(
296 add_missing_impl_members, 314 add_missing_impl_members,
297 " 315 r#"
298trait Foo<T> { fn foo(&self, t: T) -> &T; } 316trait Foo<T> { fn foo(&self, t: T) -> &T; }
299struct S; 317struct S;
300impl<U> Foo<U> for S { <|> }", 318impl<U> Foo<U> for S { <|> }"#,
301 " 319 r#"
302trait Foo<T> { fn foo(&self, t: T) -> &T; } 320trait Foo<T> { fn foo(&self, t: T) -> &T; }
303struct S; 321struct S;
304impl<U> Foo<U> for S { 322impl<U> Foo<U> for S {
305 <|>fn foo(&self, t: U) -> &U { todo!() } 323 <|>fn foo(&self, t: U) -> &U {
306}", 324 todo!()
325 }
326}"#,
307 ); 327 );
308 } 328 }
309 329
@@ -311,16 +331,18 @@ impl<U> Foo<U> for S {
311 fn test_cursor_after_empty_impl_def() { 331 fn test_cursor_after_empty_impl_def() {
312 check_assist( 332 check_assist(
313 add_missing_impl_members, 333 add_missing_impl_members,
314 " 334 r#"
315trait Foo { fn foo(&self); } 335trait Foo { fn foo(&self); }
316struct S; 336struct S;
317impl Foo for S {}<|>", 337impl Foo for S {}<|>"#,
318 " 338 r#"
319trait Foo { fn foo(&self); } 339trait Foo { fn foo(&self); }
320struct S; 340struct S;
321impl Foo for S { 341impl Foo for S {
322 <|>fn foo(&self) { todo!() } 342 <|>fn foo(&self) {
323}", 343 todo!()
344 }
345}"#,
324 ) 346 )
325 } 347 }
326 348
@@ -328,22 +350,24 @@ impl Foo for S {
328 fn test_qualify_path_1() { 350 fn test_qualify_path_1() {
329 check_assist( 351 check_assist(
330 add_missing_impl_members, 352 add_missing_impl_members,
331 " 353 r#"
332mod foo { 354mod foo {
333 pub struct Bar; 355 pub struct Bar;
334 trait Foo { fn foo(&self, bar: Bar); } 356 trait Foo { fn foo(&self, bar: Bar); }
335} 357}
336struct S; 358struct S;
337impl foo::Foo for S { <|> }", 359impl foo::Foo for S { <|> }"#,
338 " 360 r#"
339mod foo { 361mod foo {
340 pub struct Bar; 362 pub struct Bar;
341 trait Foo { fn foo(&self, bar: Bar); } 363 trait Foo { fn foo(&self, bar: Bar); }
342} 364}
343struct S; 365struct S;
344impl foo::Foo for S { 366impl foo::Foo for S {
345 <|>fn foo(&self, bar: foo::Bar) { todo!() } 367 <|>fn foo(&self, bar: foo::Bar) {
346}", 368 todo!()
369 }
370}"#,
347 ); 371 );
348 } 372 }
349 373
@@ -351,22 +375,24 @@ impl foo::Foo for S {
351 fn test_qualify_path_generic() { 375 fn test_qualify_path_generic() {
352 check_assist( 376 check_assist(
353 add_missing_impl_members, 377 add_missing_impl_members,
354 " 378 r#"
355mod foo { 379mod foo {
356 pub struct Bar<T>; 380 pub struct Bar<T>;
357 trait Foo { fn foo(&self, bar: Bar<u32>); } 381 trait Foo { fn foo(&self, bar: Bar<u32>); }
358} 382}
359struct S; 383struct S;
360impl foo::Foo for S { <|> }", 384impl foo::Foo for S { <|> }"#,
361 " 385 r#"
362mod foo { 386mod foo {
363 pub struct Bar<T>; 387 pub struct Bar<T>;
364 trait Foo { fn foo(&self, bar: Bar<u32>); } 388 trait Foo { fn foo(&self, bar: Bar<u32>); }
365} 389}
366struct S; 390struct S;
367impl foo::Foo for S { 391impl foo::Foo for S {
368 <|>fn foo(&self, bar: foo::Bar<u32>) { todo!() } 392 <|>fn foo(&self, bar: foo::Bar<u32>) {
369}", 393 todo!()
394 }
395}"#,
370 ); 396 );
371 } 397 }
372 398
@@ -374,22 +400,24 @@ impl foo::Foo for S {
374 fn test_qualify_path_and_substitute_param() { 400 fn test_qualify_path_and_substitute_param() {
375 check_assist( 401 check_assist(
376 add_missing_impl_members, 402 add_missing_impl_members,
377 " 403 r#"
378mod foo { 404mod foo {
379 pub struct Bar<T>; 405 pub struct Bar<T>;
380 trait Foo<T> { fn foo(&self, bar: Bar<T>); } 406 trait Foo<T> { fn foo(&self, bar: Bar<T>); }
381} 407}
382struct S; 408struct S;
383impl foo::Foo<u32> for S { <|> }", 409impl foo::Foo<u32> for S { <|> }"#,
384 " 410 r#"
385mod foo { 411mod foo {
386 pub struct Bar<T>; 412 pub struct Bar<T>;
387 trait Foo<T> { fn foo(&self, bar: Bar<T>); } 413 trait Foo<T> { fn foo(&self, bar: Bar<T>); }
388} 414}
389struct S; 415struct S;
390impl foo::Foo<u32> for S { 416impl foo::Foo<u32> for S {
391 <|>fn foo(&self, bar: foo::Bar<u32>) { todo!() } 417 <|>fn foo(&self, bar: foo::Bar<u32>) {
392}", 418 todo!()
419 }
420}"#,
393 ); 421 );
394 } 422 }
395 423
@@ -398,15 +426,15 @@ impl foo::Foo<u32> for S {
398 // when substituting params, the substituted param should not be qualified! 426 // when substituting params, the substituted param should not be qualified!
399 check_assist( 427 check_assist(
400 add_missing_impl_members, 428 add_missing_impl_members,
401 " 429 r#"
402mod foo { 430mod foo {
403 trait Foo<T> { fn foo(&self, bar: T); } 431 trait Foo<T> { fn foo(&self, bar: T); }
404 pub struct Param; 432 pub struct Param;
405} 433}
406struct Param; 434struct Param;
407struct S; 435struct S;
408impl foo::Foo<Param> for S { <|> }", 436impl foo::Foo<Param> for S { <|> }"#,
409 " 437 r#"
410mod foo { 438mod foo {
411 trait Foo<T> { fn foo(&self, bar: T); } 439 trait Foo<T> { fn foo(&self, bar: T); }
412 pub struct Param; 440 pub struct Param;
@@ -414,8 +442,10 @@ mod foo {
414struct Param; 442struct Param;
415struct S; 443struct S;
416impl foo::Foo<Param> for S { 444impl foo::Foo<Param> for S {
417 <|>fn foo(&self, bar: Param) { todo!() } 445 <|>fn foo(&self, bar: Param) {
418}", 446 todo!()
447 }
448}"#,
419 ); 449 );
420 } 450 }
421 451
@@ -423,15 +453,15 @@ impl foo::Foo<Param> for S {
423 fn test_qualify_path_associated_item() { 453 fn test_qualify_path_associated_item() {
424 check_assist( 454 check_assist(
425 add_missing_impl_members, 455 add_missing_impl_members,
426 " 456 r#"
427mod foo { 457mod foo {
428 pub struct Bar<T>; 458 pub struct Bar<T>;
429 impl Bar<T> { type Assoc = u32; } 459 impl Bar<T> { type Assoc = u32; }
430 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } 460 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
431} 461}
432struct S; 462struct S;
433impl foo::Foo for S { <|> }", 463impl foo::Foo for S { <|> }"#,
434 " 464 r#"
435mod foo { 465mod foo {
436 pub struct Bar<T>; 466 pub struct Bar<T>;
437 impl Bar<T> { type Assoc = u32; } 467 impl Bar<T> { type Assoc = u32; }
@@ -439,8 +469,10 @@ mod foo {
439} 469}
440struct S; 470struct S;
441impl foo::Foo for S { 471impl foo::Foo for S {
442 <|>fn foo(&self, bar: foo::Bar<u32>::Assoc) { todo!() } 472 <|>fn foo(&self, bar: foo::Bar<u32>::Assoc) {
443}", 473 todo!()
474 }
475}"#,
444 ); 476 );
445 } 477 }
446 478
@@ -448,15 +480,15 @@ impl foo::Foo for S {
448 fn test_qualify_path_nested() { 480 fn test_qualify_path_nested() {
449 check_assist( 481 check_assist(
450 add_missing_impl_members, 482 add_missing_impl_members,
451 " 483 r#"
452mod foo { 484mod foo {
453 pub struct Bar<T>; 485 pub struct Bar<T>;
454 pub struct Baz; 486 pub struct Baz;
455 trait Foo { fn foo(&self, bar: Bar<Baz>); } 487 trait Foo { fn foo(&self, bar: Bar<Baz>); }
456} 488}
457struct S; 489struct S;
458impl foo::Foo for S { <|> }", 490impl foo::Foo for S { <|> }"#,
459 " 491 r#"
460mod foo { 492mod foo {
461 pub struct Bar<T>; 493 pub struct Bar<T>;
462 pub struct Baz; 494 pub struct Baz;
@@ -464,8 +496,10 @@ mod foo {
464} 496}
465struct S; 497struct S;
466impl foo::Foo for S { 498impl foo::Foo for S {
467 <|>fn foo(&self, bar: foo::Bar<foo::Baz>) { todo!() } 499 <|>fn foo(&self, bar: foo::Bar<foo::Baz>) {
468}", 500 todo!()
501 }
502}"#,
469 ); 503 );
470 } 504 }
471 505
@@ -473,22 +507,24 @@ impl foo::Foo for S {
473 fn test_qualify_path_fn_trait_notation() { 507 fn test_qualify_path_fn_trait_notation() {
474 check_assist( 508 check_assist(
475 add_missing_impl_members, 509 add_missing_impl_members,
476 " 510 r#"
477mod foo { 511mod foo {
478 pub trait Fn<Args> { type Output; } 512 pub trait Fn<Args> { type Output; }
479 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } 513 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
480} 514}
481struct S; 515struct S;
482impl foo::Foo for S { <|> }", 516impl foo::Foo for S { <|> }"#,
483 " 517 r#"
484mod foo { 518mod foo {
485 pub trait Fn<Args> { type Output; } 519 pub trait Fn<Args> { type Output; }
486 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } 520 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
487} 521}
488struct S; 522struct S;
489impl foo::Foo for S { 523impl foo::Foo for S {
490 <|>fn foo(&self, bar: dyn Fn(u32) -> i32) { todo!() } 524 <|>fn foo(&self, bar: dyn Fn(u32) -> i32) {
491}", 525 todo!()
526 }
527}"#,
492 ); 528 );
493 } 529 }
494 530
@@ -496,10 +532,10 @@ impl foo::Foo for S {
496 fn test_empty_trait() { 532 fn test_empty_trait() {
497 check_assist_not_applicable( 533 check_assist_not_applicable(
498 add_missing_impl_members, 534 add_missing_impl_members,
499 " 535 r#"
500trait Foo; 536trait Foo;
501struct S; 537struct S;
502impl Foo for S { <|> }", 538impl Foo for S { <|> }"#,
503 ) 539 )
504 } 540 }
505 541
@@ -507,13 +543,13 @@ impl Foo for S { <|> }",
507 fn test_ignore_unnamed_trait_members_and_default_methods() { 543 fn test_ignore_unnamed_trait_members_and_default_methods() {
508 check_assist_not_applicable( 544 check_assist_not_applicable(
509 add_missing_impl_members, 545 add_missing_impl_members,
510 " 546 r#"
511trait Foo { 547trait Foo {
512 fn (arg: u32); 548 fn (arg: u32);
513 fn valid(some: u32) -> bool { false } 549 fn valid(some: u32) -> bool { false }
514} 550}
515struct S; 551struct S;
516impl Foo for S { <|> }", 552impl Foo for S { <|> }"#,
517 ) 553 )
518 } 554 }
519 555
@@ -544,7 +580,9 @@ trait Foo {
544struct S; 580struct S;
545impl Foo for S { 581impl Foo for S {
546 <|>type Output; 582 <|>type Output;
547 fn foo(&self) { todo!() } 583 fn foo(&self) {
584 todo!()
585 }
548}"#, 586}"#,
549 ) 587 )
550 } 588 }
@@ -553,7 +591,7 @@ impl Foo for S {
553 fn test_default_methods() { 591 fn test_default_methods() {
554 check_assist( 592 check_assist(
555 add_missing_default_members, 593 add_missing_default_members,
556 " 594 r#"
557trait Foo { 595trait Foo {
558 type Output; 596 type Output;
559 597
@@ -563,8 +601,8 @@ trait Foo {
563 fn foo(some: u32) -> bool; 601 fn foo(some: u32) -> bool;
564} 602}
565struct S; 603struct S;
566impl Foo for S { <|> }", 604impl Foo for S { <|> }"#,
567 " 605 r#"
568trait Foo { 606trait Foo {
569 type Output; 607 type Output;
570 608
@@ -576,7 +614,7 @@ trait Foo {
576struct S; 614struct S;
577impl Foo for S { 615impl Foo for S {
578 <|>fn valid(some: u32) -> bool { false } 616 <|>fn valid(some: u32) -> bool { false }
579}", 617}"#,
580 ) 618 )
581 } 619 }
582} 620}
diff --git a/crates/ra_assists/src/handlers/early_return.rs b/crates/ra_assists/src/handlers/early_return.rs
index ea6c56f8c..eede2fe91 100644
--- a/crates/ra_assists/src/handlers/early_return.rs
+++ b/crates/ra_assists/src/handlers/early_return.rs
@@ -2,7 +2,7 @@ use std::{iter::once, ops::RangeInclusive};
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 algo::replace_children, 4 algo::replace_children,
5 ast::{self, edit::IndentLevel, make, Block, Pat::TupleStructPat}, 5 ast::{self, edit::IndentLevel, make},
6 AstNode, 6 AstNode,
7 SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, 7 SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE},
8 SyntaxNode, 8 SyntaxNode,
@@ -47,7 +47,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
47 // Check if there is an IfLet that we can handle. 47 // Check if there is an IfLet that we can handle.
48 let if_let_pat = match cond.pat() { 48 let if_let_pat = match cond.pat() {
49 None => None, // No IfLet, supported. 49 None => None, // No IfLet, supported.
50 Some(TupleStructPat(pat)) if pat.args().count() == 1 => { 50 Some(ast::Pat::TupleStructPat(pat)) if pat.args().count() == 1 => {
51 let path = pat.path()?; 51 let path = pat.path()?;
52 match path.qualifier() { 52 match path.qualifier() {
53 None => { 53 None => {
@@ -61,9 +61,9 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
61 }; 61 };
62 62
63 let cond_expr = cond.expr()?; 63 let cond_expr = cond.expr()?;
64 let then_block = if_expr.then_branch()?.block()?; 64 let then_block = if_expr.then_branch()?;
65 65
66 let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::Block::cast)?; 66 let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?;
67 67
68 if parent_block.expr()? != if_expr.clone().into() { 68 if parent_block.expr()? != if_expr.clone().into() {
69 return None; 69 return None;
@@ -80,7 +80,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
80 return None; 80 return None;
81 } 81 }
82 82
83 let parent_container = parent_block.syntax().parent()?.parent()?; 83 let parent_container = parent_block.syntax().parent()?;
84 84
85 let early_expression: ast::Expr = match parent_container.kind() { 85 let early_expression: ast::Expr = match parent_container.kind() {
86 WHILE_EXPR | LOOP_EXPR => make::expr_continue(), 86 WHILE_EXPR | LOOP_EXPR => make::expr_continue(),
@@ -144,13 +144,13 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
144 } 144 }
145 }; 145 };
146 edit.target(if_expr.syntax().text_range()); 146 edit.target(if_expr.syntax().text_range());
147 edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap()); 147 edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap());
148 edit.set_cursor(cursor_position); 148 edit.set_cursor(cursor_position);
149 149
150 fn replace( 150 fn replace(
151 new_expr: &SyntaxNode, 151 new_expr: &SyntaxNode,
152 then_block: &Block, 152 then_block: &ast::BlockExpr,
153 parent_block: &Block, 153 parent_block: &ast::BlockExpr,
154 if_expr: &ast::IfExpr, 154 if_expr: &ast::IfExpr,
155 ) -> SyntaxNode { 155 ) -> SyntaxNode {
156 let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); 156 let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone());
diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs
index f5702f6e0..60ec536a7 100644
--- a/crates/ra_assists/src/handlers/inline_local_variable.rs
+++ b/crates/ra_assists/src/handlers/inline_local_variable.rs
@@ -89,6 +89,7 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> {
89 | (ast::Expr::ParenExpr(_), _) 89 | (ast::Expr::ParenExpr(_), _)
90 | (ast::Expr::PathExpr(_), _) 90 | (ast::Expr::PathExpr(_), _)
91 | (ast::Expr::BlockExpr(_), _) 91 | (ast::Expr::BlockExpr(_), _)
92 | (ast::Expr::EffectExpr(_), _)
92 | (_, ast::Expr::CallExpr(_)) 93 | (_, ast::Expr::CallExpr(_))
93 | (_, ast::Expr::TupleExpr(_)) 94 | (_, ast::Expr::TupleExpr(_))
94 | (_, ast::Expr::ArrayExpr(_)) 95 | (_, ast::Expr::ArrayExpr(_))
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs
index eda9ac296..39c656305 100644
--- a/crates/ra_assists/src/handlers/introduce_variable.rs
+++ b/crates/ra_assists/src/handlers/introduce_variable.rs
@@ -111,7 +111,7 @@ fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> {
111/// expression like a lambda or match arm. 111/// expression like a lambda or match arm.
112fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { 112fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
113 expr.syntax().ancestors().find_map(|node| { 113 expr.syntax().ancestors().find_map(|node| {
114 if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { 114 if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) {
115 if expr.syntax() == &node { 115 if expr.syntax() == &node {
116 tested_by!(test_introduce_var_last_expr); 116 tested_by!(test_introduce_var_last_expr);
117 return Some((node, false)); 117 return Some((node, false));
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs
index d5ccdd91c..b084dd9ee 100644
--- a/crates/ra_assists/src/handlers/move_guard.rs
+++ b/crates/ra_assists/src/handlers/move_guard.rs
@@ -113,9 +113,9 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
113 "Move condition to match guard", 113 "Move condition to match guard",
114 |edit| { 114 |edit| {
115 edit.target(if_expr.syntax().text_range()); 115 edit.target(if_expr.syntax().text_range());
116 let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none(); 116 let then_only_expr = then_block.statements().next().is_none();
117 117
118 match &then_block.block().and_then(|it| it.expr()) { 118 match &then_block.expr() {
119 Some(then_expr) if then_only_expr => { 119 Some(then_expr) if then_only_expr => {
120 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text()) 120 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text())
121 } 121 }
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 2f02df303..918e8dd8d 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -27,7 +27,7 @@ pub(crate) fn replace_qualified_name_with_use(ctx: AssistCtx) -> Option<Assist>
27 return None; 27 return None;
28 } 28 }
29 29
30 let hir_path = hir::Path::from_ast(path.clone())?; 30 let hir_path = ctx.sema.lower_path(&path)?;
31 let segments = collect_hir_path_segments(&hir_path)?; 31 let segments = collect_hir_path_segments(&hir_path)?;
32 if segments.len() < 2 { 32 if segments.len() < 2 {
33 return None; 33 return None;
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
index 1a30b2b3a..f910ded9d 100644
--- a/crates/ra_fmt/src/lib.rs
+++ b/crates/ra_fmt/src/lib.rs
@@ -42,7 +42,6 @@ pub fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
42} 42}
43 43
44pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { 44pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
45 let block = block.block()?;
46 let has_anything_else = |thing: &SyntaxNode| -> bool { 45 let has_anything_else = |thing: &SyntaxNode| -> bool {
47 let mut non_trivial_children = 46 let mut non_trivial_children =
48 block.syntax().children_with_tokens().filter(|it| match it.kind() { 47 block.syntax().children_with_tokens().filter(|it| match it.kind() {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 312ef3814..c5df4ac24 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -70,6 +70,7 @@ pub use hir_def::{
70 type_ref::Mutability, 70 type_ref::Mutability,
71}; 71};
72pub use hir_expand::{ 72pub use hir_expand::{
73 name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, 73 hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId,
74 MacroFile, Origin,
74}; 75};
75pub use hir_ty::{display::HirDisplay, CallableDef}; 76pub use hir_ty::{display::HirDisplay, CallableDef};
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index a0a0f234b..515e5eb17 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -8,7 +8,7 @@ use hir_def::{
8 resolver::{self, HasResolver, Resolver}, 8 resolver::{self, HasResolver, Resolver},
9 AsMacroCall, TraitId, 9 AsMacroCall, TraitId,
10}; 10};
11use hir_expand::ExpansionInfo; 11use hir_expand::{hygiene::Hygiene, ExpansionInfo};
12use hir_ty::associated_type_shorthand_candidates; 12use hir_ty::associated_type_shorthand_candidates;
13use itertools::Itertools; 13use itertools::Itertools;
14use ra_db::{FileId, FileRange}; 14use ra_db::{FileId, FileRange};
@@ -246,6 +246,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
246 self.analyze(path.syntax()).resolve_path(self.db, path) 246 self.analyze(path.syntax()).resolve_path(self.db, path)
247 } 247 }
248 248
249 pub fn lower_path(&self, path: &ast::Path) -> Option<Path> {
250 let src = self.find_file(path.syntax().clone());
251 Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into()))
252 }
253
249 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { 254 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
250 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) 255 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
251 } 256 }
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index 74d64c97d..c63d1b847 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -224,7 +224,8 @@ impl SourceAnalyzer {
224 } 224 }
225 } 225 }
226 // This must be a normal source file rather than macro file. 226 // This must be a normal source file rather than macro file.
227 let hir_path = crate::Path::from_ast(path.clone())?; 227 let hir_path =
228 crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?;
228 resolve_hir_path(db, &self.resolver, &hir_path) 229 resolve_hir_path(db, &self.resolver, &hir_path)
229 } 230 }
230 231
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 753becc3d..8eef51828 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -12,9 +12,15 @@ use ra_prof::profile;
12use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; 12use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner};
13 13
14use crate::{ 14use crate::{
15 body::CfgExpander, db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, 15 body::{CfgExpander, LowerCtx},
16 type_ref::TypeRef, visibility::RawVisibility, EnumId, HasModule, LocalEnumVariantId, 16 db::DefDatabase,
17 LocalFieldId, Lookup, ModuleId, StructId, UnionId, VariantId, 17 src::HasChildSource,
18 src::HasSource,
19 trace::Trace,
20 type_ref::TypeRef,
21 visibility::RawVisibility,
22 EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId,
23 VariantId,
18}; 24};
19 25
20/// Note that we use `StructData` for unions as well! 26/// Note that we use `StructData` for unions as well!
@@ -198,6 +204,8 @@ fn lower_struct(
198 trace: &mut Trace<FieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>, 204 trace: &mut Trace<FieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>,
199 ast: &InFile<ast::StructKind>, 205 ast: &InFile<ast::StructKind>,
200) -> StructKind { 206) -> StructKind {
207 let ctx = LowerCtx::new(db, ast.file_id);
208
201 match &ast.value { 209 match &ast.value {
202 ast::StructKind::Tuple(fl) => { 210 ast::StructKind::Tuple(fl) => {
203 for (i, fd) in fl.fields().enumerate() { 211 for (i, fd) in fl.fields().enumerate() {
@@ -210,7 +218,7 @@ fn lower_struct(
210 || Either::Left(fd.clone()), 218 || Either::Left(fd.clone()),
211 || FieldData { 219 || FieldData {
212 name: Name::new_tuple_field(i), 220 name: Name::new_tuple_field(i),
213 type_ref: TypeRef::from_ast_opt(fd.type_ref()), 221 type_ref: TypeRef::from_ast_opt(&ctx, fd.type_ref()),
214 visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), 222 visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
215 }, 223 },
216 ); 224 );
@@ -228,7 +236,7 @@ fn lower_struct(
228 || Either::Right(fd.clone()), 236 || Either::Right(fd.clone()),
229 || FieldData { 237 || FieldData {
230 name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), 238 name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
231 type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), 239 type_ref: TypeRef::from_ast_opt(&ctx, fd.ascribed_type()),
232 visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), 240 visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
233 }, 241 },
234 ); 242 );
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 890cefcaf..4edaad960 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -15,6 +15,8 @@ use ra_prof::profile;
15use ra_syntax::{ast, AstNode, AstPtr}; 15use ra_syntax::{ast, AstNode, AstPtr};
16use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
17 17
18pub(crate) use lower::LowerCtx;
19
18use crate::{ 20use crate::{
19 attr::Attrs, 21 attr::Attrs,
20 db::DefDatabase, 22 db::DefDatabase,
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index f467ed3fe..58b3d10d8 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -3,8 +3,9 @@
3 3
4use either::Either; 4use either::Either;
5use hir_expand::{ 5use hir_expand::{
6 hygiene::Hygiene,
6 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
7 MacroDefId, MacroDefKind, 8 HirFileId, MacroDefId, MacroDefKind,
8}; 9};
9use ra_arena::Arena; 10use ra_arena::Arena;
10use ra_syntax::{ 11use ra_syntax::{
@@ -26,7 +27,7 @@ use crate::{
26 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
27 }, 28 },
28 item_scope::BuiltinShadowMode, 29 item_scope::BuiltinShadowMode,
29 path::GenericArgs, 30 path::{GenericArgs, Path},
30 type_ref::{Mutability, TypeRef}, 31 type_ref::{Mutability, TypeRef},
31 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, 32 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
32 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, 33 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
@@ -35,6 +36,23 @@ use crate::{
35use super::{ExprSource, PatSource}; 36use super::{ExprSource, PatSource};
36use ast::AstChildren; 37use ast::AstChildren;
37 38
39pub(crate) struct LowerCtx {
40 hygiene: Hygiene,
41}
42
43impl LowerCtx {
44 pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self {
45 LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) }
46 }
47 pub fn with_hygiene(hygiene: &Hygiene) -> Self {
48 LowerCtx { hygiene: hygiene.clone() }
49 }
50
51 pub fn lower_path(&self, ast: ast::Path) -> Option<Path> {
52 Path::from_src(ast, &self.hygiene)
53 }
54}
55
38pub(super) fn lower( 56pub(super) fn lower(
39 db: &dyn DefDatabase, 57 db: &dyn DefDatabase,
40 def: DefWithBodyId, 58 def: DefWithBodyId,
@@ -42,10 +60,13 @@ pub(super) fn lower(
42 params: Option<ast::ParamList>, 60 params: Option<ast::ParamList>,
43 body: Option<ast::Expr>, 61 body: Option<ast::Expr>,
44) -> (Body, BodySourceMap) { 62) -> (Body, BodySourceMap) {
63 let ctx = LowerCtx::new(db, expander.current_file_id.clone());
64
45 ExprCollector { 65 ExprCollector {
46 db, 66 db,
47 def, 67 def,
48 expander, 68 expander,
69 ctx,
49 source_map: BodySourceMap::default(), 70 source_map: BodySourceMap::default(),
50 body: Body { 71 body: Body {
51 exprs: Arena::default(), 72 exprs: Arena::default(),
@@ -62,7 +83,7 @@ struct ExprCollector<'a> {
62 db: &'a dyn DefDatabase, 83 db: &'a dyn DefDatabase,
63 def: DefWithBodyId, 84 def: DefWithBodyId,
64 expander: Expander, 85 expander: Expander,
65 86 ctx: LowerCtx,
66 body: Body, 87 body: Body,
67 source_map: BodySourceMap, 88 source_map: BodySourceMap,
68} 89}
@@ -182,6 +203,16 @@ impl ExprCollector<'_> {
182 203
183 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 204 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
184 } 205 }
206 ast::Expr::EffectExpr(e) => match e.effect() {
207 ast::Effect::Try(_) => {
208 let body = self.collect_block_opt(e.block_expr());
209 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
210 }
211 // FIXME: we need to record these effects somewhere...
212 ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => {
213 self.collect_block_opt(e.block_expr())
214 }
215 },
185 ast::Expr::BlockExpr(e) => self.collect_block(e), 216 ast::Expr::BlockExpr(e) => self.collect_block(e),
186 ast::Expr::LoopExpr(e) => { 217 ast::Expr::LoopExpr(e) => {
187 let body = self.collect_block_opt(e.loop_body()); 218 let body = self.collect_block_opt(e.loop_body());
@@ -237,7 +268,8 @@ impl ExprCollector<'_> {
237 Vec::new() 268 Vec::new()
238 }; 269 };
239 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 270 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
240 let generic_args = e.type_arg_list().and_then(GenericArgs::from_ast); 271 let generic_args =
272 e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it));
241 self.alloc_expr( 273 self.alloc_expr(
242 Expr::MethodCall { receiver, method_name, args, generic_args }, 274 Expr::MethodCall { receiver, method_name, args, generic_args },
243 syntax_ptr, 275 syntax_ptr,
@@ -343,7 +375,7 @@ impl ExprCollector<'_> {
343 } 375 }
344 ast::Expr::CastExpr(e) => { 376 ast::Expr::CastExpr(e) => {
345 let expr = self.collect_expr_opt(e.expr()); 377 let expr = self.collect_expr_opt(e.expr());
346 let type_ref = TypeRef::from_ast_opt(e.type_ref()); 378 let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref());
347 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) 379 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
348 } 380 }
349 ast::Expr::RefExpr(e) => { 381 ast::Expr::RefExpr(e) => {
@@ -365,12 +397,16 @@ impl ExprCollector<'_> {
365 if let Some(pl) = e.param_list() { 397 if let Some(pl) = e.param_list() {
366 for param in pl.params() { 398 for param in pl.params() {
367 let pat = self.collect_pat_opt(param.pat()); 399 let pat = self.collect_pat_opt(param.pat());
368 let type_ref = param.ascribed_type().map(TypeRef::from_ast); 400 let type_ref =
401 param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it));
369 args.push(pat); 402 args.push(pat);
370 arg_types.push(type_ref); 403 arg_types.push(type_ref);
371 } 404 }
372 } 405 }
373 let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); 406 let ret_type = e
407 .ret_type()
408 .and_then(|r| r.type_ref())
409 .map(|it| TypeRef::from_ast(&self.ctx, it));
374 let body = self.collect_expr_opt(e.body()); 410 let body = self.collect_expr_opt(e.body());
375 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) 411 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
376 } 412 }
@@ -464,19 +500,15 @@ impl ExprCollector<'_> {
464 } 500 }
465 } 501 }
466 502
467 fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { 503 fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
468 let syntax_node_ptr = AstPtr::new(&expr.clone().into()); 504 let syntax_node_ptr = AstPtr::new(&block.clone().into());
469 let block = match expr.block() {
470 Some(block) => block,
471 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
472 };
473 self.collect_block_items(&block); 505 self.collect_block_items(&block);
474 let statements = block 506 let statements = block
475 .statements() 507 .statements()
476 .map(|s| match s { 508 .map(|s| match s {
477 ast::Stmt::LetStmt(stmt) => { 509 ast::Stmt::LetStmt(stmt) => {
478 let pat = self.collect_pat_opt(stmt.pat()); 510 let pat = self.collect_pat_opt(stmt.pat());
479 let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); 511 let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it));
480 let initializer = stmt.initializer().map(|e| self.collect_expr(e)); 512 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
481 Statement::Let { pat, type_ref, initializer } 513 Statement::Let { pat, type_ref, initializer }
482 } 514 }
@@ -487,7 +519,7 @@ impl ExprCollector<'_> {
487 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 519 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
488 } 520 }
489 521
490 fn collect_block_items(&mut self, block: &ast::Block) { 522 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
491 let container = ContainerId::DefWithBodyId(self.def); 523 let container = ContainerId::DefWithBodyId(self.def);
492 for item in block.items() { 524 for item in block.items() {
493 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 525 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index ccb682f9a..7a2067e49 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -15,6 +15,7 @@ use ra_syntax::ast::{
15 15
16use crate::{ 16use crate::{
17 attr::Attrs, 17 attr::Attrs,
18 body::LowerCtx,
18 db::DefDatabase, 19 db::DefDatabase,
19 path::{path, AssociatedTypeBinding, GenericArgs, Path}, 20 path::{path, AssociatedTypeBinding, GenericArgs, Path},
20 src::HasSource, 21 src::HasSource,
@@ -40,13 +41,14 @@ impl FunctionData {
40 pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> { 41 pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> {
41 let loc = func.lookup(db); 42 let loc = func.lookup(db);
42 let src = loc.source(db); 43 let src = loc.source(db);
44 let ctx = LowerCtx::new(db, src.file_id);
43 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); 45 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
44 let mut params = Vec::new(); 46 let mut params = Vec::new();
45 let mut has_self_param = false; 47 let mut has_self_param = false;
46 if let Some(param_list) = src.value.param_list() { 48 if let Some(param_list) = src.value.param_list() {
47 if let Some(self_param) = param_list.self_param() { 49 if let Some(self_param) = param_list.self_param() {
48 let self_type = if let Some(type_ref) = self_param.ascribed_type() { 50 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
49 TypeRef::from_ast(type_ref) 51 TypeRef::from_ast(&ctx, type_ref)
50 } else { 52 } else {
51 let self_type = TypeRef::Path(name![Self].into()); 53 let self_type = TypeRef::Path(name![Self].into());
52 match self_param.kind() { 54 match self_param.kind() {
@@ -63,14 +65,14 @@ impl FunctionData {
63 has_self_param = true; 65 has_self_param = true;
64 } 66 }
65 for param in param_list.params() { 67 for param in param_list.params() {
66 let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); 68 let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type());
67 params.push(type_ref); 69 params.push(type_ref);
68 } 70 }
69 } 71 }
70 let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); 72 let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id));
71 73
72 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { 74 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
73 TypeRef::from_ast(type_ref) 75 TypeRef::from_ast(&ctx, type_ref)
74 } else { 76 } else {
75 TypeRef::unit() 77 TypeRef::unit()
76 }; 78 };
@@ -122,7 +124,8 @@ impl TypeAliasData {
122 let loc = typ.lookup(db); 124 let loc = typ.lookup(db);
123 let node = loc.source(db); 125 let node = loc.source(db);
124 let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); 126 let name = node.value.name().map_or_else(Name::missing, |n| n.as_name());
125 let type_ref = node.value.type_ref().map(TypeRef::from_ast); 127 let lower_ctx = LowerCtx::new(db, node.file_id);
128 let type_ref = node.value.type_ref().map(|it| TypeRef::from_ast(&lower_ctx, it));
126 let vis_default = RawVisibility::default_for_container(loc.container); 129 let vis_default = RawVisibility::default_for_container(loc.container);
127 let visibility = RawVisibility::from_ast_with_default( 130 let visibility = RawVisibility::from_ast_with_default(
128 db, 131 db,
@@ -130,7 +133,7 @@ impl TypeAliasData {
130 node.as_ref().map(|n| n.visibility()), 133 node.as_ref().map(|n| n.visibility()),
131 ); 134 );
132 let bounds = if let Some(bound_list) = node.value.type_bound_list() { 135 let bounds = if let Some(bound_list) = node.value.type_bound_list() {
133 bound_list.bounds().map(TypeBound::from_ast).collect() 136 bound_list.bounds().map(|it| TypeBound::from_ast(&lower_ctx, it)).collect()
134 } else { 137 } else {
135 Vec::new() 138 Vec::new()
136 }; 139 };
@@ -223,9 +226,10 @@ impl ImplData {
223 let _p = profile("impl_data_query"); 226 let _p = profile("impl_data_query");
224 let impl_loc = id.lookup(db); 227 let impl_loc = id.lookup(db);
225 let src = impl_loc.source(db); 228 let src = impl_loc.source(db);
229 let lower_ctx = LowerCtx::new(db, src.file_id);
226 230
227 let target_trait = src.value.target_trait().map(TypeRef::from_ast); 231 let target_trait = src.value.target_trait().map(|it| TypeRef::from_ast(&lower_ctx, it));
228 let target_type = TypeRef::from_ast_opt(src.value.target_type()); 232 let target_type = TypeRef::from_ast_opt(&lower_ctx, src.value.target_type());
229 let is_negative = src.value.excl_token().is_some(); 233 let is_negative = src.value.excl_token().is_some();
230 let module_id = impl_loc.container.module(db); 234 let module_id = impl_loc.container.module(db);
231 235
@@ -279,8 +283,9 @@ impl ConstData {
279 vis_default: RawVisibility, 283 vis_default: RawVisibility,
280 node: InFile<N>, 284 node: InFile<N>,
281 ) -> ConstData { 285 ) -> ConstData {
286 let ctx = LowerCtx::new(db, node.file_id);
282 let name = node.value.name().map(|n| n.as_name()); 287 let name = node.value.name().map(|n| n.as_name());
283 let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type()); 288 let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type());
284 let visibility = 289 let visibility =
285 RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); 290 RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility()));
286 ConstData { name, type_ref, visibility } 291 ConstData { name, type_ref, visibility }
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index aad12e123..a0cdad529 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -101,6 +101,9 @@ pub enum Expr {
101 Try { 101 Try {
102 expr: ExprId, 102 expr: ExprId,
103 }, 103 },
104 TryBlock {
105 body: ExprId,
106 },
104 Cast { 107 Cast {
105 expr: ExprId, 108 expr: ExprId,
106 type_ref: TypeRef, 109 type_ref: TypeRef,
@@ -236,6 +239,7 @@ impl Expr {
236 f(*expr); 239 f(*expr);
237 } 240 }
238 } 241 }
242 Expr::TryBlock { body } => f(*body),
239 Expr::Loop { body } => f(*body), 243 Expr::Loop { body } => f(*body),
240 Expr::While { condition, body } => { 244 Expr::While { condition, body } => {
241 f(*condition); 245 f(*condition);
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index d850244c4..09a5241f7 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -15,6 +15,7 @@ use ra_prof::profile;
15use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 15use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
16 16
17use crate::{ 17use crate::{
18 body::LowerCtx,
18 child_by_source::ChildBySource, 19 child_by_source::ChildBySource,
19 db::DefDatabase, 20 db::DefDatabase,
20 dyn_map::DynMap, 21 dyn_map::DynMap,
@@ -80,11 +81,13 @@ impl GenericParams {
80 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { 81 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {
81 let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() }; 82 let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() };
82 let mut sm = ArenaMap::default(); 83 let mut sm = ArenaMap::default();
84
83 // FIXME: add `: Sized` bound for everything except for `Self` in traits 85 // FIXME: add `: Sized` bound for everything except for `Self` in traits
84 let file_id = match def { 86 let file_id = match def {
85 GenericDefId::FunctionId(it) => { 87 GenericDefId::FunctionId(it) => {
86 let src = it.lookup(db).source(db); 88 let src = it.lookup(db).source(db);
87 generics.fill(&mut sm, &src.value); 89 let lower_ctx = LowerCtx::new(db, src.file_id);
90 generics.fill(&lower_ctx, &mut sm, &src.value);
88 // lower `impl Trait` in arguments 91 // lower `impl Trait` in arguments
89 let data = db.function_data(it); 92 let data = db.function_data(it);
90 for param in &data.params { 93 for param in &data.params {
@@ -94,21 +97,25 @@ impl GenericParams {
94 } 97 }
95 GenericDefId::AdtId(AdtId::StructId(it)) => { 98 GenericDefId::AdtId(AdtId::StructId(it)) => {
96 let src = it.lookup(db).source(db); 99 let src = it.lookup(db).source(db);
97 generics.fill(&mut sm, &src.value); 100 let lower_ctx = LowerCtx::new(db, src.file_id);
101 generics.fill(&lower_ctx, &mut sm, &src.value);
98 src.file_id 102 src.file_id
99 } 103 }
100 GenericDefId::AdtId(AdtId::UnionId(it)) => { 104 GenericDefId::AdtId(AdtId::UnionId(it)) => {
101 let src = it.lookup(db).source(db); 105 let src = it.lookup(db).source(db);
102 generics.fill(&mut sm, &src.value); 106 let lower_ctx = LowerCtx::new(db, src.file_id);
107 generics.fill(&lower_ctx, &mut sm, &src.value);
103 src.file_id 108 src.file_id
104 } 109 }
105 GenericDefId::AdtId(AdtId::EnumId(it)) => { 110 GenericDefId::AdtId(AdtId::EnumId(it)) => {
106 let src = it.lookup(db).source(db); 111 let src = it.lookup(db).source(db);
107 generics.fill(&mut sm, &src.value); 112 let lower_ctx = LowerCtx::new(db, src.file_id);
113 generics.fill(&lower_ctx, &mut sm, &src.value);
108 src.file_id 114 src.file_id
109 } 115 }
110 GenericDefId::TraitId(it) => { 116 GenericDefId::TraitId(it) => {
111 let src = it.lookup(db).source(db); 117 let src = it.lookup(db).source(db);
118 let lower_ctx = LowerCtx::new(db, src.file_id);
112 119
113 // traits get the Self type as an implicit first type parameter 120 // traits get the Self type as an implicit first type parameter
114 let self_param_id = generics.types.alloc(TypeParamData { 121 let self_param_id = generics.types.alloc(TypeParamData {
@@ -120,14 +127,16 @@ impl GenericParams {
120 // add super traits as bounds on Self 127 // add super traits as bounds on Self
121 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 128 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
122 let self_param = TypeRef::Path(name![Self].into()); 129 let self_param = TypeRef::Path(name![Self].into());
123 generics.fill_bounds(&src.value, self_param); 130 generics.fill_bounds(&lower_ctx, &src.value, self_param);
124 131
125 generics.fill(&mut sm, &src.value); 132 generics.fill(&lower_ctx, &mut sm, &src.value);
126 src.file_id 133 src.file_id
127 } 134 }
128 GenericDefId::TypeAliasId(it) => { 135 GenericDefId::TypeAliasId(it) => {
129 let src = it.lookup(db).source(db); 136 let src = it.lookup(db).source(db);
130 generics.fill(&mut sm, &src.value); 137 let lower_ctx = LowerCtx::new(db, src.file_id);
138
139 generics.fill(&lower_ctx, &mut sm, &src.value);
131 src.file_id 140 src.file_id
132 } 141 }
133 // Note that we don't add `Self` here: in `impl`s, `Self` is not a 142 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
@@ -135,7 +144,9 @@ impl GenericParams {
135 // type, so this is handled by the resolver. 144 // type, so this is handled by the resolver.
136 GenericDefId::ImplId(it) => { 145 GenericDefId::ImplId(it) => {
137 let src = it.lookup(db).source(db); 146 let src = it.lookup(db).source(db);
138 generics.fill(&mut sm, &src.value); 147 let lower_ctx = LowerCtx::new(db, src.file_id);
148
149 generics.fill(&lower_ctx, &mut sm, &src.value);
139 src.file_id 150 src.file_id
140 } 151 }
141 // We won't be using this ID anyway 152 // We won't be using this ID anyway
@@ -145,28 +156,38 @@ impl GenericParams {
145 (generics, InFile::new(file_id, sm)) 156 (generics, InFile::new(file_id, sm))
146 } 157 }
147 158
148 fn fill(&mut self, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { 159 fn fill(&mut self, lower_ctx: &LowerCtx, sm: &mut SourceMap, node: &dyn TypeParamsOwner) {
149 if let Some(params) = node.type_param_list() { 160 if let Some(params) = node.type_param_list() {
150 self.fill_params(sm, params) 161 self.fill_params(lower_ctx, sm, params)
151 } 162 }
152 if let Some(where_clause) = node.where_clause() { 163 if let Some(where_clause) = node.where_clause() {
153 self.fill_where_predicates(where_clause); 164 self.fill_where_predicates(lower_ctx, where_clause);
154 } 165 }
155 } 166 }
156 167
157 fn fill_bounds(&mut self, node: &dyn ast::TypeBoundsOwner, type_ref: TypeRef) { 168 fn fill_bounds(
169 &mut self,
170 lower_ctx: &LowerCtx,
171 node: &dyn ast::TypeBoundsOwner,
172 type_ref: TypeRef,
173 ) {
158 for bound in 174 for bound in
159 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) 175 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
160 { 176 {
161 self.add_where_predicate_from_bound(bound, type_ref.clone()); 177 self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone());
162 } 178 }
163 } 179 }
164 180
165 fn fill_params(&mut self, sm: &mut SourceMap, params: ast::TypeParamList) { 181 fn fill_params(
182 &mut self,
183 lower_ctx: &LowerCtx,
184 sm: &mut SourceMap,
185 params: ast::TypeParamList,
186 ) {
166 for type_param in params.type_params() { 187 for type_param in params.type_params() {
167 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); 188 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
168 // FIXME: Use `Path::from_src` 189 // FIXME: Use `Path::from_src`
169 let default = type_param.default_type().map(TypeRef::from_ast); 190 let default = type_param.default_type().map(|it| TypeRef::from_ast(lower_ctx, it));
170 let param = TypeParamData { 191 let param = TypeParamData {
171 name: Some(name.clone()), 192 name: Some(name.clone()),
172 default, 193 default,
@@ -176,29 +197,34 @@ impl GenericParams {
176 sm.insert(param_id, Either::Right(type_param.clone())); 197 sm.insert(param_id, Either::Right(type_param.clone()));
177 198
178 let type_ref = TypeRef::Path(name.into()); 199 let type_ref = TypeRef::Path(name.into());
179 self.fill_bounds(&type_param, type_ref); 200 self.fill_bounds(&lower_ctx, &type_param, type_ref);
180 } 201 }
181 } 202 }
182 203
183 fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { 204 fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) {
184 for pred in where_clause.predicates() { 205 for pred in where_clause.predicates() {
185 let type_ref = match pred.type_ref() { 206 let type_ref = match pred.type_ref() {
186 Some(type_ref) => type_ref, 207 Some(type_ref) => type_ref,
187 None => continue, 208 None => continue,
188 }; 209 };
189 let type_ref = TypeRef::from_ast(type_ref); 210 let type_ref = TypeRef::from_ast(lower_ctx, type_ref);
190 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { 211 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
191 self.add_where_predicate_from_bound(bound, type_ref.clone()); 212 self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone());
192 } 213 }
193 } 214 }
194 } 215 }
195 216
196 fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { 217 fn add_where_predicate_from_bound(
218 &mut self,
219 lower_ctx: &LowerCtx,
220 bound: ast::TypeBound,
221 type_ref: TypeRef,
222 ) {
197 if bound.question_token().is_some() { 223 if bound.question_token().is_some() {
198 // FIXME: remove this bound 224 // FIXME: remove this bound
199 return; 225 return;
200 } 226 }
201 let bound = TypeBound::from_ast(bound); 227 let bound = TypeBound::from_ast(lower_ctx, bound);
202 self.where_predicates 228 self.where_predicates
203 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); 229 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound });
204 } 230 }
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 162b3c8c7..e84efe2ab 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -7,6 +7,7 @@ use std::{
7 sync::Arc, 7 sync::Arc,
8}; 8};
9 9
10use crate::body::LowerCtx;
10use hir_expand::{ 11use hir_expand::{
11 hygiene::Hygiene, 12 hygiene::Hygiene,
12 name::{AsName, Name}, 13 name::{AsName, Name},
@@ -244,8 +245,8 @@ impl<'a> PathSegments<'a> {
244} 245}
245 246
246impl GenericArgs { 247impl GenericArgs {
247 pub(crate) fn from_ast(node: ast::TypeArgList) -> Option<GenericArgs> { 248 pub(crate) fn from_ast(lower_ctx: &LowerCtx, node: ast::TypeArgList) -> Option<GenericArgs> {
248 lower::lower_generic_args(node) 249 lower::lower_generic_args(lower_ctx, node)
249 } 250 }
250 251
251 pub(crate) fn empty() -> GenericArgs { 252 pub(crate) fn empty() -> GenericArgs {
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index 9ec2e0dcd..e3d237a0a 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -13,6 +13,7 @@ use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner};
13 13
14use super::AssociatedTypeBinding; 14use super::AssociatedTypeBinding;
15use crate::{ 15use crate::{
16 body::LowerCtx,
16 path::{GenericArg, GenericArgs, ModPath, Path, PathKind}, 17 path::{GenericArg, GenericArgs, ModPath, Path, PathKind},
17 type_ref::{TypeBound, TypeRef}, 18 type_ref::{TypeBound, TypeRef},
18}; 19};
@@ -26,6 +27,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
26 let mut type_anchor = None; 27 let mut type_anchor = None;
27 let mut segments = Vec::new(); 28 let mut segments = Vec::new();
28 let mut generic_args = Vec::new(); 29 let mut generic_args = Vec::new();
30 let ctx = LowerCtx::with_hygiene(hygiene);
29 loop { 31 loop {
30 let segment = path.segment()?; 32 let segment = path.segment()?;
31 33
@@ -40,9 +42,10 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
40 Either::Left(name) => { 42 Either::Left(name) => {
41 let args = segment 43 let args = segment
42 .type_arg_list() 44 .type_arg_list()
43 .and_then(lower_generic_args) 45 .and_then(|it| lower_generic_args(&ctx, it))
44 .or_else(|| { 46 .or_else(|| {
45 lower_generic_args_from_fn_path( 47 lower_generic_args_from_fn_path(
48 &ctx,
46 segment.param_list(), 49 segment.param_list(),
47 segment.ret_type(), 50 segment.ret_type(),
48 ) 51 )
@@ -60,7 +63,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
60 ast::PathSegmentKind::Type { type_ref, trait_ref } => { 63 ast::PathSegmentKind::Type { type_ref, trait_ref } => {
61 assert!(path.qualifier().is_none()); // this can only occur at the first segment 64 assert!(path.qualifier().is_none()); // this can only occur at the first segment
62 65
63 let self_type = TypeRef::from_ast(type_ref?); 66 let self_type = TypeRef::from_ast(&ctx, type_ref?);
64 67
65 match trait_ref { 68 match trait_ref {
66 // <T>::foo 69 // <T>::foo
@@ -128,10 +131,13 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
128 } 131 }
129} 132}
130 133
131pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> { 134pub(super) fn lower_generic_args(
135 lower_ctx: &LowerCtx,
136 node: ast::TypeArgList,
137) -> Option<GenericArgs> {
132 let mut args = Vec::new(); 138 let mut args = Vec::new();
133 for type_arg in node.type_args() { 139 for type_arg in node.type_args() {
134 let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); 140 let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.type_ref());
135 args.push(GenericArg::Type(type_ref)); 141 args.push(GenericArg::Type(type_ref));
136 } 142 }
137 // lifetimes ignored for now 143 // lifetimes ignored for now
@@ -140,9 +146,9 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs>
140 let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; 146 let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg;
141 if let Some(name_ref) = assoc_type_arg.name_ref() { 147 if let Some(name_ref) = assoc_type_arg.name_ref() {
142 let name = name_ref.as_name(); 148 let name = name_ref.as_name();
143 let type_ref = assoc_type_arg.type_ref().map(TypeRef::from_ast); 149 let type_ref = assoc_type_arg.type_ref().map(|it| TypeRef::from_ast(lower_ctx, it));
144 let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { 150 let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
145 l.bounds().map(TypeBound::from_ast).collect() 151 l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
146 } else { 152 } else {
147 Vec::new() 153 Vec::new()
148 }; 154 };
@@ -159,6 +165,7 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs>
159/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) 165/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
160/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). 166/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
161fn lower_generic_args_from_fn_path( 167fn lower_generic_args_from_fn_path(
168 ctx: &LowerCtx,
162 params: Option<ast::ParamList>, 169 params: Option<ast::ParamList>,
163 ret_type: Option<ast::RetType>, 170 ret_type: Option<ast::RetType>,
164) -> Option<GenericArgs> { 171) -> Option<GenericArgs> {
@@ -167,14 +174,14 @@ fn lower_generic_args_from_fn_path(
167 if let Some(params) = params { 174 if let Some(params) = params {
168 let mut param_types = Vec::new(); 175 let mut param_types = Vec::new();
169 for param in params.params() { 176 for param in params.params() {
170 let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); 177 let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type());
171 param_types.push(type_ref); 178 param_types.push(type_ref);
172 } 179 }
173 let arg = GenericArg::Type(TypeRef::Tuple(param_types)); 180 let arg = GenericArg::Type(TypeRef::Tuple(param_types));
174 args.push(arg); 181 args.push(arg);
175 } 182 }
176 if let Some(ret_type) = ret_type { 183 if let Some(ret_type) = ret_type {
177 let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); 184 let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.type_ref());
178 bindings.push(AssociatedTypeBinding { 185 bindings.push(AssociatedTypeBinding {
179 name: name![Output], 186 name: name![Output],
180 type_ref: Some(type_ref), 187 type_ref: Some(type_ref),
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index f308c6bdf..5bdad9efd 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -3,7 +3,7 @@
3 3
4use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner}; 4use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner};
5 5
6use crate::path::Path; 6use crate::{body::LowerCtx, path::Path};
7 7
8#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] 8#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
9pub enum Mutability { 9pub enum Mutability {
@@ -64,30 +64,34 @@ pub enum TypeBound {
64 64
65impl TypeRef { 65impl TypeRef {
66 /// Converts an `ast::TypeRef` to a `hir::TypeRef`. 66 /// Converts an `ast::TypeRef` to a `hir::TypeRef`.
67 pub(crate) fn from_ast(node: ast::TypeRef) -> Self { 67 pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeRef) -> Self {
68 match node { 68 match node {
69 ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), 69 ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()),
70 ast::TypeRef::TupleType(inner) => { 70 ast::TypeRef::TupleType(inner) => {
71 TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()) 71 TypeRef::Tuple(inner.fields().map(|it| TypeRef::from_ast(ctx, it)).collect())
72 } 72 }
73 ast::TypeRef::NeverType(..) => TypeRef::Never, 73 ast::TypeRef::NeverType(..) => TypeRef::Never,
74 ast::TypeRef::PathType(inner) => { 74 ast::TypeRef::PathType(inner) => {
75 // FIXME: Use `Path::from_src` 75 // FIXME: Use `Path::from_src`
76 inner.path().and_then(Path::from_ast).map(TypeRef::Path).unwrap_or(TypeRef::Error) 76 inner
77 .path()
78 .and_then(|it| ctx.lower_path(it))
79 .map(TypeRef::Path)
80 .unwrap_or(TypeRef::Error)
77 } 81 }
78 ast::TypeRef::PointerType(inner) => { 82 ast::TypeRef::PointerType(inner) => {
79 let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); 83 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref());
80 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 84 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
81 TypeRef::RawPtr(Box::new(inner_ty), mutability) 85 TypeRef::RawPtr(Box::new(inner_ty), mutability)
82 } 86 }
83 ast::TypeRef::ArrayType(inner) => { 87 ast::TypeRef::ArrayType(inner) => {
84 TypeRef::Array(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) 88 TypeRef::Array(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref())))
85 } 89 }
86 ast::TypeRef::SliceType(inner) => { 90 ast::TypeRef::SliceType(inner) => {
87 TypeRef::Slice(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) 91 TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref())))
88 } 92 }
89 ast::TypeRef::ReferenceType(inner) => { 93 ast::TypeRef::ReferenceType(inner) => {
90 let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); 94 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref());
91 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 95 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
92 TypeRef::Reference(Box::new(inner_ty), mutability) 96 TypeRef::Reference(Box::new(inner_ty), mutability)
93 } 97 }
@@ -96,10 +100,13 @@ impl TypeRef {
96 let ret_ty = inner 100 let ret_ty = inner
97 .ret_type() 101 .ret_type()
98 .and_then(|rt| rt.type_ref()) 102 .and_then(|rt| rt.type_ref())
99 .map(TypeRef::from_ast) 103 .map(|it| TypeRef::from_ast(ctx, it))
100 .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); 104 .unwrap_or_else(|| TypeRef::Tuple(Vec::new()));
101 let mut params = if let Some(pl) = inner.param_list() { 105 let mut params = if let Some(pl) = inner.param_list() {
102 pl.params().map(|p| p.ascribed_type()).map(TypeRef::from_ast_opt).collect() 106 pl.params()
107 .map(|p| p.ascribed_type())
108 .map(|it| TypeRef::from_ast_opt(&ctx, it))
109 .collect()
103 } else { 110 } else {
104 Vec::new() 111 Vec::new()
105 }; 112 };
@@ -107,19 +114,19 @@ impl TypeRef {
107 TypeRef::Fn(params) 114 TypeRef::Fn(params)
108 } 115 }
109 // for types are close enough for our purposes to the inner type for now... 116 // for types are close enough for our purposes to the inner type for now...
110 ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()), 117 ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()),
111 ast::TypeRef::ImplTraitType(inner) => { 118 ast::TypeRef::ImplTraitType(inner) => {
112 TypeRef::ImplTrait(type_bounds_from_ast(inner.type_bound_list())) 119 TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
113 } 120 }
114 ast::TypeRef::DynTraitType(inner) => { 121 ast::TypeRef::DynTraitType(inner) => {
115 TypeRef::DynTrait(type_bounds_from_ast(inner.type_bound_list())) 122 TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
116 } 123 }
117 } 124 }
118 } 125 }
119 126
120 pub(crate) fn from_ast_opt(node: Option<ast::TypeRef>) -> Self { 127 pub(crate) fn from_ast_opt(ctx: &LowerCtx, node: Option<ast::TypeRef>) -> Self {
121 if let Some(node) = node { 128 if let Some(node) = node {
122 TypeRef::from_ast(node) 129 TypeRef::from_ast(ctx, node)
123 } else { 130 } else {
124 TypeRef::Error 131 TypeRef::Error
125 } 132 }
@@ -180,24 +187,27 @@ impl TypeRef {
180 } 187 }
181} 188}
182 189
183pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option<ast::TypeBoundList>) -> Vec<TypeBound> { 190pub(crate) fn type_bounds_from_ast(
191 lower_ctx: &LowerCtx,
192 type_bounds_opt: Option<ast::TypeBoundList>,
193) -> Vec<TypeBound> {
184 if let Some(type_bounds) = type_bounds_opt { 194 if let Some(type_bounds) = type_bounds_opt {
185 type_bounds.bounds().map(TypeBound::from_ast).collect() 195 type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
186 } else { 196 } else {
187 vec![] 197 vec![]
188 } 198 }
189} 199}
190 200
191impl TypeBound { 201impl TypeBound {
192 pub(crate) fn from_ast(node: ast::TypeBound) -> Self { 202 pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeBound) -> Self {
193 match node.kind() { 203 match node.kind() {
194 ast::TypeBoundKind::PathType(path_type) => { 204 ast::TypeBoundKind::PathType(path_type) => {
195 let path = match path_type.path() { 205 let path = match path_type.path() {
196 Some(p) => p, 206 Some(p) => p,
197 None => return TypeBound::Error, 207 None => return TypeBound::Error,
198 }; 208 };
199 // FIXME: Use `Path::from_src` 209
200 let path = match Path::from_ast(path) { 210 let path = match ctx.lower_path(path) {
201 Some(p) => p, 211 Some(p) => p,
202 None => return TypeBound::Error, 212 None => return TypeBound::Error,
203 }; 213 };
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index 047452306..4c12d0a15 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -330,7 +330,7 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
330 FragmentKind::Expr 330 FragmentKind::Expr
331 } 331 }
332 // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that 332 // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that
333 EXPR_STMT | BLOCK => FragmentKind::Expr, 333 EXPR_STMT | BLOCK_EXPR => FragmentKind::Expr,
334 ARG_LIST => FragmentKind::Expr, 334 ARG_LIST => FragmentKind::Expr,
335 TRY_EXPR => FragmentKind::Expr, 335 TRY_EXPR => FragmentKind::Expr,
336 TUPLE_EXPR => FragmentKind::Expr, 336 TUPLE_EXPR => FragmentKind::Expr,
@@ -342,7 +342,6 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
342 CONDITION => FragmentKind::Expr, 342 CONDITION => FragmentKind::Expr,
343 BREAK_EXPR => FragmentKind::Expr, 343 BREAK_EXPR => FragmentKind::Expr,
344 RETURN_EXPR => FragmentKind::Expr, 344 RETURN_EXPR => FragmentKind::Expr,
345 BLOCK_EXPR => FragmentKind::Expr,
346 MATCH_EXPR => FragmentKind::Expr, 345 MATCH_EXPR => FragmentKind::Expr,
347 MATCH_ARM => FragmentKind::Expr, 346 MATCH_ARM => FragmentKind::Expr,
348 MATCH_GUARD => FragmentKind::Expr, 347 MATCH_GUARD => FragmentKind::Expr,
diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs
index 0b41d0e95..53866bbcb 100644
--- a/crates/ra_hir_expand/src/hygiene.rs
+++ b/crates/ra_hir_expand/src/hygiene.rs
@@ -12,7 +12,7 @@ use crate::{
12 HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind, 12 HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind,
13}; 13};
14 14
15#[derive(Debug)] 15#[derive(Clone, Debug)]
16pub struct Hygiene { 16pub struct Hygiene {
17 // This is what `$crate` expands to 17 // This is what `$crate` expands to
18 def_crate: Option<CrateId>, 18 def_crate: Option<CrateId>,
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 04d3cd6a2..65db6d1b0 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -11,7 +11,7 @@ doctest = false
11itertools = "0.9.0" 11itertools = "0.9.0"
12arrayvec = "0.5.1" 12arrayvec = "0.5.1"
13smallvec = "1.2.0" 13smallvec = "1.2.0"
14ena = "0.13.1" 14ena = "0.14.0"
15log = "0.4.8" 15log = "0.4.8"
16rustc-hash = "1.1.0" 16rustc-hash = "1.1.0"
17 17
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index efc60986b..83f946eee 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -73,6 +73,11 @@ impl<'a> InferenceContext<'a> {
73 self.coerce_merge_branch(&then_ty, &else_ty) 73 self.coerce_merge_branch(&then_ty, &else_ty)
74 } 74 }
75 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 75 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
76 Expr::TryBlock { body } => {
77 let _inner = self.infer_expr(*body, expected);
78 // FIXME should be std::result::Result<{inner}, _>
79 Ty::Unknown
80 }
76 Expr::Loop { body } => { 81 Expr::Loop { body } => {
77 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 82 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
78 // FIXME handle break with value 83 // FIXME handle break with value
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index 5ddecbdc6..1f796876d 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -339,6 +339,46 @@ pub fn baz() -> usize { 31usize }
339} 339}
340 340
341#[test] 341#[test]
342fn infer_macro_with_dollar_crate_is_correct_in_trait_associate_type() {
343 let (db, pos) = TestDB::with_position(
344 r#"
345//- /main.rs crate:main deps:foo
346use foo::Trait;
347
348fn test() {
349 let msg = foo::Message(foo::MessageRef);
350 let r = msg.deref();
351 r<|>;
352}
353
354//- /lib.rs crate:foo
355pub struct MessageRef;
356pub struct Message(MessageRef);
357
358pub trait Trait {
359 type Target;
360 fn deref(&self) -> &Self::Target;
361}
362
363#[macro_export]
364macro_rules! expand {
365 () => {
366 impl Trait for Message {
367 type Target = $crate::MessageRef;
368 fn deref(&self) -> &Self::Target {
369 &self.0
370 }
371 }
372 }
373}
374
375expand!();
376"#,
377 );
378 assert_eq!("&MessageRef", type_at_pos(&db, pos));
379}
380
381#[test]
342fn infer_type_value_non_legacy_macro_use_as() { 382fn infer_type_value_non_legacy_macro_use_as() {
343 assert_snapshot!( 383 assert_snapshot!(
344 infer(r#" 384 infer(r#"
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 56abc65b8..3d3088965 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -1755,3 +1755,35 @@ fn main() {
1755 "### 1755 "###
1756 ); 1756 );
1757} 1757}
1758
1759#[test]
1760fn effects_smoke_test() {
1761 assert_snapshot!(
1762 infer(r#"
1763fn main() {
1764 let x = unsafe { 92 };
1765 let y = async { async { () }.await };
1766 let z = try { () };
1767 let t = 'a: { 92 };
1768}
1769"#),
1770 @r###"
1771 11..131 '{ ...2 }; }': ()
1772 21..22 'x': i32
1773 32..38 '{ 92 }': i32
1774 34..36 '92': i32
1775 48..49 'y': {unknown}
1776 58..80 '{ asyn...wait }': {unknown}
1777 60..78 'async ....await': {unknown}
1778 66..72 '{ () }': ()
1779 68..70 '()': ()
1780 90..91 'z': {unknown}
1781 94..104 'try { () }': {unknown}
1782 98..104 '{ () }': ()
1783 100..102 '()': ()
1784 114..115 't': i32
1785 122..128 '{ 92 }': i32
1786 124..126 '92': i32
1787 "###
1788 )
1789}
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index 118fceb2e..c529752d4 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -344,7 +344,7 @@ impl<'a> CompletionContext<'a> {
344 stmt.syntax().text_range() == name_ref.syntax().text_range(), 344 stmt.syntax().text_range() == name_ref.syntax().text_range(),
345 ); 345 );
346 } 346 }
347 if let Some(block) = ast::Block::cast(node) { 347 if let Some(block) = ast::BlockExpr::cast(node) {
348 return Some( 348 return Some(
349 block.expr().map(|e| e.syntax().text_range()) 349 block.expr().map(|e| e.syntax().text_range())
350 == Some(name_ref.syntax().text_range()), 350 == Some(name_ref.syntax().text_range()),
diff --git a/crates/ra_ide/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs
index 4b081bf6c..d37260e96 100644
--- a/crates/ra_ide/src/display/short_label.rs
+++ b/crates/ra_ide/src/display/short_label.rs
@@ -33,7 +33,11 @@ impl ShortLabel for ast::EnumDef {
33 33
34impl ShortLabel for ast::TraitDef { 34impl ShortLabel for ast::TraitDef {
35 fn short_label(&self) -> Option<String> { 35 fn short_label(&self) -> Option<String> {
36 short_label_from_node(self, "trait ") 36 if self.unsafe_token().is_some() {
37 short_label_from_node(self, "unsafe trait ")
38 } else {
39 short_label_from_node(self, "trait ")
40 }
37 } 41 }
38} 42}
39 43
diff --git a/crates/ra_ide/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs
index 4379005aa..8657377de 100644
--- a/crates/ra_ide/src/folding_ranges.rs
+++ b/crates/ra_ide/src/folding_ranges.rs
@@ -88,7 +88,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
88 | ITEM_LIST 88 | ITEM_LIST
89 | EXTERN_ITEM_LIST 89 | EXTERN_ITEM_LIST
90 | USE_TREE_LIST 90 | USE_TREE_LIST
91 | BLOCK 91 | BLOCK_EXPR
92 | MATCH_ARM_LIST 92 | MATCH_ARM_LIST
93 | ENUM_VARIANT_LIST 93 | ENUM_VARIANT_LIST
94 | TOKEN_TREE => Some(FoldKind::Block), 94 | TOKEN_TREE => Some(FoldKind::Block),
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index a62f598f0..54d318858 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -869,4 +869,15 @@ fn func(foo: i32) { if true { <|>foo; }; }
869 &[r#"pub(crate) async unsafe extern "C" fn foo()"#], 869 &[r#"pub(crate) async unsafe extern "C" fn foo()"#],
870 ); 870 );
871 } 871 }
872
873 #[test]
874 fn test_hover_trait_show_qualifiers() {
875 check_hover_result(
876 "
877 //- /lib.rs
878 unsafe trait foo<|>() {}
879 ",
880 &["unsafe trait foo"],
881 );
882 }
872} 883}
diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs
index d0def7eaa..63fd6b3e4 100644
--- a/crates/ra_ide/src/join_lines.rs
+++ b/crates/ra_ide/src/join_lines.rs
@@ -129,8 +129,7 @@ fn has_comma_after(node: &SyntaxNode) -> bool {
129} 129}
130 130
131fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { 131fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> {
132 let block = ast::Block::cast(token.parent())?; 132 let block_expr = ast::BlockExpr::cast(token.parent())?;
133 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
134 if !block_expr.is_standalone() { 133 if !block_expr.is_standalone() {
135 return None; 134 return None;
136 } 135 }
diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs
index bf97f8c56..86c70ff83 100644
--- a/crates/ra_ide/src/syntax_tree.rs
+++ b/crates/ra_ide/src/syntax_tree.rs
@@ -120,9 +120,8 @@ [email protected]
120 [email protected] ")" 120 [email protected] ")"
121 [email protected] " " 121 [email protected] " "
122 [email protected] 122 [email protected]
123 [email protected] 123 [email protected] "{"
124 [email protected] "{" 124 [email protected] "}"
125 [email protected] "}"
126"# 125"#
127 .trim() 126 .trim()
128 ); 127 );
@@ -153,26 +152,25 @@ [email protected]
153 [email protected] ")" 152 [email protected] ")"
154 [email protected] " " 153 [email protected] " "
155 [email protected] 154 [email protected]
156 [email protected] 155 [email protected] "{"
157 [email protected] "{" 156 [email protected] "\n "
158 [email protected] "\n " 157 [email protected]
159 [email protected] 158 [email protected]
160 [email protected] 159 [email protected]
161 [email protected] 160 [email protected]
162 [email protected] 161 [email protected]
163 [email protected] 162 [email protected] "assert"
164 [email protected] "assert" 163 [email protected] "!"
165 [email protected] "!" 164 [email protected]
166 [email protected] 165 [email protected] "("
167 [email protected] "(" 166 [email protected] "\"\n fn foo() {\n ..."
168 [email protected] "\"\n fn foo() {\n ..." 167 [email protected] ","
169 [email protected] "," 168 [email protected] " "
170 [email protected] " " 169 [email protected] "\"\""
171 [email protected] "\"\"" 170 [email protected] ")"
172 [email protected] ")" 171 [email protected] ";"
173 [email protected] ";" 172 [email protected] "\n"
174 [email protected] "\n" 173 [email protected] "}"
175 [email protected] "}"
176"# 174"#
177 .trim() 175 .trim()
178 ); 176 );
@@ -196,9 +194,8 @@ [email protected]
196 [email protected] ")" 194 [email protected] ")"
197 [email protected] " " 195 [email protected] " "
198 [email protected] 196 [email protected]
199 [email protected] 197 [email protected] "{"
200 [email protected] "{" 198 [email protected] "}"
201 [email protected] "}"
202"# 199"#
203 .trim() 200 .trim()
204 ); 201 );
@@ -265,10 +262,9 @@ [email protected]
265 [email protected] ")" 262 [email protected] ")"
266 [email protected] " " 263 [email protected] " "
267 [email protected] 264 [email protected]
268 [email protected] 265 [email protected] "{"
269 [email protected] "{" 266 [email protected] "\n"
270 [email protected] "\n" 267 [email protected] "}"
271 [email protected] "}"
272"# 268"#
273 .trim() 269 .trim()
274 ); 270 );
@@ -300,10 +296,9 @@ [email protected]
300 [email protected] ")" 296 [email protected] ")"
301 [email protected] " " 297 [email protected] " "
302 [email protected] 298 [email protected]
303 [email protected] 299 [email protected] "{"
304 [email protected] "{" 300 [email protected] "\n"
305 [email protected] "\n" 301 [email protected] "}"
306 [email protected] "}"
307"# 302"#
308 .trim() 303 .trim()
309 ); 304 );
@@ -334,10 +329,9 @@ [email protected]
334 [email protected] ")" 329 [email protected] ")"
335 [email protected] " " 330 [email protected] " "
336 [email protected] 331 [email protected]
337 [email protected] 332 [email protected] "{"
338 [email protected] "{" 333 [email protected] "\n"
339 [email protected] "\n" 334 [email protected] "}"
340 [email protected] "}"
341 [email protected] "\n" 335 [email protected] "\n"
342 [email protected] 336 [email protected]
343 [email protected] "fn" 337 [email protected] "fn"
@@ -349,10 +343,9 @@ [email protected]
349 [email protected] ")" 343 [email protected] ")"
350 [email protected] " " 344 [email protected] " "
351 [email protected] 345 [email protected]
352 [email protected] 346 [email protected] "{"
353 [email protected] "{" 347 [email protected] "\n"
354 [email protected] "\n" 348 [email protected] "}"
355 [email protected] "}"
356"# 349"#
357 .trim() 350 .trim()
358 ); 351 );
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs
index 0d924ce58..c43003fd6 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/ra_mbe/src/tests.rs
@@ -266,21 +266,20 @@ fn test_expr_order() {
266 [email protected] "(" 266 [email protected] "("
267 [email protected] ")" 267 [email protected] ")"
268 [email protected] 268 [email protected]
269 [email protected] 269 [email protected] "{"
270 [email protected] "{" 270 [email protected]
271 [email protected] 271 [email protected]
272 [email protected] 272 [email protected]
273 [email protected] 273 [email protected]
274 [email protected] 274 [email protected] "1"
275 [email protected] "1" 275 [email protected] "+"
276 [email protected] "+" 276 [email protected]
277 [email protected] 277 [email protected] "1"
278 [email protected] "1" 278 [email protected] "*"
279 [email protected] "*" 279 [email protected]
280 [email protected] 280 [email protected] "2"
281 [email protected] "2" 281 [email protected] ";"
282 [email protected] ";" 282 [email protected] "}""#,
283 [email protected] "}""#,
284 ); 283 );
285} 284}
286 285
@@ -1114,68 +1113,67 @@ fn test_vec() {
1114 assert_eq!( 1113 assert_eq!(
1115 format!("{:#?}", tree).trim(), 1114 format!("{:#?}", tree).trim(),
1116 r#"[email protected] 1115 r#"[email protected]
1117 [email protected] 1116 [email protected] "{"
1118 [email protected] "{" 1117 [email protected]
1119 [email protected] 1118 [email protected] "let"
1120 [email protected] "let" 1119 [email protected]
1121 [email protected] 1120 [email protected] "mut"
1122 [email protected] "mut" 1121 [email protected]
1123 [email protected] 1122 [email protected] "v"
1124 [email protected] "v" 1123 [email protected] "="
1125 [email protected] "=" 1124 [email protected]
1126 [email protected] 1125 [email protected]
1127 [email protected] 1126 [email protected]
1128 [email protected] 1127 [email protected]
1129 [email protected] 1128 [email protected]
1130 [email protected] 1129 [email protected]
1131 [email protected] 1130 [email protected] "Vec"
1132 [email protected] "Vec" 1131 [email protected] "::"
1133 [email protected] "::" 1132 [email protected]
1134 [email protected] 1133 [email protected]
1135 [email protected] 1134 [email protected] "new"
1136 [email protected] "new" 1135 [email protected]
1137 [email protected] 1136 [email protected] "("
1138 [email protected] "(" 1137 [email protected] ")"
1139 [email protected] ")" 1138 [email protected] ";"
1140 [email protected] ";" 1139 [email protected]
1141 [email protected] 1140 [email protected]
1142 [email protected] 1141 [email protected]
1143 [email protected] 1142 [email protected]
1144 [email protected] 1143 [email protected]
1145 [email protected] 1144 [email protected]
1146 [email protected] 1145 [email protected] "v"
1147 [email protected] "v" 1146 [email protected] "."
1148 [email protected] "." 1147 [email protected]
1149 [email protected] 1148 [email protected] "push"
1150 [email protected] "push" 1149 [email protected]
1151 [email protected] 1150 [email protected] "("
1152 [email protected] "(" 1151 [email protected]
1153 [email protected] 1152 [email protected] "1u32"
1154 [email protected] "1u32" 1153 [email protected] ")"
1155 [email protected] ")" 1154 [email protected] ";"
1156 [email protected] ";" 1155 [email protected]
1157 [email protected] 1156 [email protected]
1158 [email protected] 1157 [email protected]
1159 [email protected] 1158 [email protected]
1160 [email protected] 1159 [email protected]
1161 [email protected] 1160 [email protected]
1162 [email protected] 1161 [email protected] "v"
1163 [email protected] "v" 1162 [email protected] "."
1164 [email protected] "." 1163 [email protected]
1165 [email protected] 1164 [email protected] "push"
1166 [email protected] "push" 1165 [email protected]
1167 [email protected] 1166 [email protected] "("
1168 [email protected] "(" 1167 [email protected]
1169 [email protected] 1168 [email protected] "2"
1170 [email protected] "2" 1169 [email protected] ")"
1171 [email protected] ")" 1170 [email protected] ";"
1172 [email protected] ";" 1171 [email protected]
1173 [email protected] 1172 [email protected]
1174 [email protected] 1173 [email protected]
1175 [email protected] 1174 [email protected]
1176 [email protected] 1175 [email protected] "v"
1177 [email protected] "v" 1176 [email protected] "}""#
1178 [email protected] "}""#
1179 ); 1177 );
1180} 1178}
1181 1179
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index c2a6e82e9..d9824ff9b 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -143,7 +143,7 @@ pub(crate) fn reparser(
143 parent: Option<SyntaxKind>, 143 parent: Option<SyntaxKind>,
144) -> Option<fn(&mut Parser)> { 144) -> Option<fn(&mut Parser)> {
145 let res = match node { 145 let res = match node {
146 BLOCK => expressions::naked_block, 146 BLOCK_EXPR => expressions::block,
147 RECORD_FIELD_DEF_LIST => items::record_field_def_list, 147 RECORD_FIELD_DEF_LIST => items::record_field_def_list,
148 RECORD_FIELD_LIST => items::record_field_list, 148 RECORD_FIELD_LIST => items::record_field_list,
149 ENUM_VARIANT_LIST => items::enum_variant_list, 149 ENUM_VARIANT_LIST => items::enum_variant_list,
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index cb30b25a8..a23dbcacf 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -59,16 +59,7 @@ pub(crate) fn block(p: &mut Parser) {
59 p.error("expected a block"); 59 p.error("expected a block");
60 return; 60 return;
61 } 61 }
62 atom::block_expr(p, None); 62 atom::block_expr(p);
63}
64
65pub(crate) fn naked_block(p: &mut Parser) {
66 assert!(p.at(T!['{']));
67 let m = p.start();
68 p.bump(T!['{']);
69 expr_block_contents(p);
70 p.expect(T!['}']);
71 m.complete(p, BLOCK);
72} 63}
73 64
74fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { 65fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
@@ -197,7 +188,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
197 } 188 }
198} 189}
199 190
200pub(crate) fn expr_block_contents(p: &mut Parser) { 191pub(super) fn expr_block_contents(p: &mut Parser) {
201 // This is checked by a validator 192 // This is checked by a validator
202 attributes::inner_attributes(p); 193 attributes::inner_attributes(p);
203 194
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 76aa601cb..efb424dae 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -84,7 +84,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
84 T![box] => box_expr(p, None), 84 T![box] => box_expr(p, None),
85 T![for] => for_expr(p, None), 85 T![for] => for_expr(p, None),
86 T![while] => while_expr(p, None), 86 T![while] => while_expr(p, None),
87 T![try] => try_expr(p, None), 87 T![try] => try_block_expr(p, None),
88 LIFETIME if la == T![:] => { 88 LIFETIME if la == T![:] => {
89 let m = p.start(); 89 let m = p.start();
90 label(p); 90 label(p);
@@ -92,7 +92,12 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
92 T![loop] => loop_expr(p, Some(m)), 92 T![loop] => loop_expr(p, Some(m)),
93 T![for] => for_expr(p, Some(m)), 93 T![for] => for_expr(p, Some(m)),
94 T![while] => while_expr(p, Some(m)), 94 T![while] => while_expr(p, Some(m)),
95 T!['{'] => block_expr(p, Some(m)), 95 // test labeled_block
96 // fn f() { 'label: {}; }
97 T!['{'] => {
98 block_expr(p);
99 m.complete(p, EFFECT_EXPR)
100 }
96 _ => { 101 _ => {
97 // test_err misplaced_label_err 102 // test_err misplaced_label_err
98 // fn main() { 103 // fn main() {
@@ -108,13 +113,17 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
108 let m = p.start(); 113 let m = p.start();
109 p.bump(T![async]); 114 p.bump(T![async]);
110 p.eat(T![move]); 115 p.eat(T![move]);
111 block_expr(p, Some(m)) 116 block_expr(p);
117 m.complete(p, EFFECT_EXPR)
112 } 118 }
113 T![match] => match_expr(p), 119 T![match] => match_expr(p),
120 // test unsafe_block
121 // fn f() { unsafe { } }
114 T![unsafe] if la == T!['{'] => { 122 T![unsafe] if la == T!['{'] => {
115 let m = p.start(); 123 let m = p.start();
116 p.bump(T![unsafe]); 124 p.bump(T![unsafe]);
117 block_expr(p, Some(m)) 125 block_expr(p);
126 m.complete(p, EFFECT_EXPR)
118 } 127 }
119 T!['{'] => { 128 T!['{'] => {
120 // test for_range_from 129 // test for_range_from
@@ -123,7 +132,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
123 // break; 132 // break;
124 // } 133 // }
125 // } 134 // }
126 block_expr(p, None) 135 block_expr(p)
127 } 136 }
128 T![return] => return_expr(p), 137 T![return] => return_expr(p),
129 T![continue] => continue_expr(p), 138 T![continue] => continue_expr(p),
@@ -134,7 +143,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
134 } 143 }
135 }; 144 };
136 let blocklike = match done.kind() { 145 let blocklike = match done.kind() {
137 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_EXPR => { 146 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | EFFECT_EXPR => {
138 BlockLike::Block 147 BlockLike::Block
139 } 148 }
140 _ => BlockLike::NotBlock, 149 _ => BlockLike::NotBlock,
@@ -234,7 +243,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
234 if p.at(T!['{']) { 243 if p.at(T!['{']) {
235 // test lambda_ret_block 244 // test lambda_ret_block
236 // fn main() { || -> i32 { 92 }(); } 245 // fn main() { || -> i32 { 92 }(); }
237 block_expr(p, None); 246 block_expr(p);
238 } else { 247 } else {
239 p.error("expected `{`"); 248 p.error("expected `{`");
240 } 249 }
@@ -461,13 +470,13 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
461// test block_expr 470// test block_expr
462// fn foo() { 471// fn foo() {
463// {}; 472// {};
464// unsafe {};
465// 'label: {};
466// } 473// }
467pub(super) fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 474pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
468 assert!(p.at(T!['{'])); 475 assert!(p.at(T!['{']));
469 let m = m.unwrap_or_else(|| p.start()); 476 let m = p.start();
470 naked_block(p); 477 p.bump(T!['{']);
478 expr_block_contents(p);
479 p.expect(T!['}']);
471 m.complete(p, BLOCK_EXPR) 480 m.complete(p, BLOCK_EXPR)
472} 481}
473 482
@@ -532,7 +541,7 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
532// fn foo() { 541// fn foo() {
533// let _ = try {}; 542// let _ = try {};
534// } 543// }
535fn try_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 544fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
536 assert!(p.at(T![try])); 545 assert!(p.at(T![try]));
537 let m = m.unwrap_or_else(|| p.start()); 546 let m = m.unwrap_or_else(|| p.start());
538 // Special-case `try!` as macro. 547 // Special-case `try!` as macro.
@@ -552,8 +561,8 @@ fn try_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
552 } 561 }
553 562
554 p.bump(T![try]); 563 p.bump(T![try]);
555 block(p); 564 block_expr(p);
556 m.complete(p, TRY_EXPR) 565 m.complete(p, EFFECT_EXPR)
557} 566}
558 567
559// test box_expr 568// test box_expr
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index ab727ed7e..e7404492a 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -191,6 +191,7 @@ pub enum SyntaxKind {
191 RECORD_LIT, 191 RECORD_LIT,
192 RECORD_FIELD_LIST, 192 RECORD_FIELD_LIST,
193 RECORD_FIELD, 193 RECORD_FIELD,
194 EFFECT_EXPR,
194 BOX_EXPR, 195 BOX_EXPR,
195 CALL_EXPR, 196 CALL_EXPR,
196 INDEX_EXPR, 197 INDEX_EXPR,
@@ -203,7 +204,6 @@ pub enum SyntaxKind {
203 PREFIX_EXPR, 204 PREFIX_EXPR,
204 RANGE_EXPR, 205 RANGE_EXPR,
205 BIN_EXPR, 206 BIN_EXPR,
206 BLOCK,
207 EXTERN_BLOCK, 207 EXTERN_BLOCK,
208 EXTERN_ITEM_LIST, 208 EXTERN_ITEM_LIST,
209 ENUM_VARIANT, 209 ENUM_VARIANT,
diff --git a/crates/ra_proc_macro_srv/Cargo.toml b/crates/ra_proc_macro_srv/Cargo.toml
index ac2d156dc..886e14870 100644
--- a/crates/ra_proc_macro_srv/Cargo.toml
+++ b/crates/ra_proc_macro_srv/Cargo.toml
@@ -21,4 +21,4 @@ test_utils = { path = "../test_utils" }
21cargo_metadata = "0.9.1" 21cargo_metadata = "0.9.1"
22difference = "2.0.0" 22difference = "2.0.0"
23# used as proc macro test target 23# used as proc macro test target
24serde_derive = "=1.0.104" 24serde_derive = "=1.0.106"
diff --git a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
index 1f5d940fa..6776f5231 100644
--- a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
+++ b/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
@@ -1,6 +1,11 @@
1SUBTREE $ 1SUBTREE $
2 PUNCH # [alone] 4294967295 2 PUNCH # [alone] 4294967295
3 SUBTREE [] 4294967295 3 SUBTREE [] 4294967295
4 IDENT doc 4294967295
5 SUBTREE () 4294967295
6 IDENT hidden 4294967295
7 PUNCH # [alone] 4294967295
8 SUBTREE [] 4294967295
4 IDENT allow 4294967295 9 IDENT allow 4294967295
5 SUBTREE () 4294967295 10 SUBTREE () 4294967295
6 IDENT non_upper_case_globals 4294967295 11 IDENT non_upper_case_globals 4294967295
@@ -184,4 +189,4 @@ SUBTREE $
184 IDENT end 4294967295 189 IDENT end 4294967295
185 SUBTREE () 4294967295 190 SUBTREE () 4294967295
186 IDENT __serde_state 4294967295 191 IDENT __serde_state 4294967295
187 PUNCH ; [alone] 4294967295 \ No newline at end of file 192 PUNCH ; [alone] 4294967295
diff --git a/crates/ra_proc_macro_srv/src/tests/mod.rs b/crates/ra_proc_macro_srv/src/tests/mod.rs
index 03f79bc5d..9cf58511c 100644
--- a/crates/ra_proc_macro_srv/src/tests/mod.rs
+++ b/crates/ra_proc_macro_srv/src/tests/mod.rs
@@ -10,7 +10,7 @@ fn test_derive_serialize_proc_macro() {
10 assert_expand( 10 assert_expand(
11 "serde_derive", 11 "serde_derive",
12 "Serialize", 12 "Serialize",
13 "1.0.104", 13 "1.0.106",
14 r##"struct Foo {}"##, 14 r##"struct Foo {}"##,
15 include_str!("fixtures/test_serialize_proc_macro.txt"), 15 include_str!("fixtures/test_serialize_proc_macro.txt"),
16 ); 16 );
@@ -21,7 +21,7 @@ fn test_derive_serialize_proc_macro_failed() {
21 assert_expand( 21 assert_expand(
22 "serde_derive", 22 "serde_derive",
23 "Serialize", 23 "Serialize",
24 "1.0.104", 24 "1.0.106",
25 r##" 25 r##"
26 struct {} 26 struct {}
27"##, 27"##,
@@ -37,7 +37,7 @@ SUBTREE $
37 37
38#[test] 38#[test]
39fn test_derive_proc_macro_list() { 39fn test_derive_proc_macro_list() {
40 let res = list("serde_derive", "1.0.104").join("\n"); 40 let res = list("serde_derive", "1.0.106").join("\n");
41 41
42 assert_eq_text!( 42 assert_eq_text!(
43 &res, 43 &res,
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index b10644b4b..5e651fe70 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -18,7 +18,7 @@ ra_db = { path = "../ra_db" }
18ra_cfg = { path = "../ra_cfg" } 18ra_cfg = { path = "../ra_cfg" }
19ra_proc_macro = { path = "../ra_proc_macro" } 19ra_proc_macro = { path = "../ra_proc_macro" }
20 20
21serde = { version = "1.0.104", features = ["derive"] } 21serde = { version = "1.0.106", features = ["derive"] }
22serde_json = "1.0.48" 22serde_json = "1.0.48"
23 23
24anyhow = "1.0.26" 24anyhow = "1.0.26"
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index 7ffe46c69..c07ff488e 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
13[dependencies] 13[dependencies]
14itertools = "0.9.0" 14itertools = "0.9.0"
15rowan = "0.10.0" 15rowan = "0.10.0"
16rustc_lexer = { version = "652.0.0", package = "rustc-ap-rustc_lexer" } 16rustc_lexer = { version = "656.0.0", package = "rustc-ap-rustc_lexer" }
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18arrayvec = "0.5.1" 18arrayvec = "0.5.1"
19once_cell = "1.3.1" 19once_cell = "1.3.1"
@@ -27,7 +27,7 @@ ra_parser = { path = "../ra_parser" }
27# ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here 27# ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here
28# to reduce number of compilations 28# to reduce number of compilations
29smol_str = { version = "0.1.15", features = ["serde"] } 29smol_str = { version = "0.1.15", features = ["serde"] }
30serde = { version = "1.0.104", features = ["derive"] } 30serde = { version = "1.0.106", features = ["derive"] }
31 31
32[dev-dependencies] 32[dev-dependencies]
33test_utils = { path = "../test_utils" } 33test_utils = { path = "../test_utils" }
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 521ca8ab8..1876afe95 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -16,9 +16,7 @@ use crate::{
16}; 16};
17 17
18pub use self::{ 18pub use self::{
19 expr_extensions::{ 19 expr_extensions::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 ArrayExprKind, BinOp, BlockModifier, ElseBranch, LiteralKind, PrefixOp, RangeOp,
21 },
22 extensions::{ 20 extensions::{
23 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, 21 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
24 StructKind, TypeBoundKind, VisibilityKind, 22 StructKind, TypeBoundKind, VisibilityKind,
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index 26e4576ff..c507dc683 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -28,7 +28,7 @@ impl ast::BinExpr {
28 28
29impl ast::FnDef { 29impl ast::FnDef {
30 #[must_use] 30 #[must_use]
31 pub fn with_body(&self, body: ast::Block) -> ast::FnDef { 31 pub fn with_body(&self, body: ast::BlockExpr) -> ast::FnDef {
32 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); 32 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
33 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() { 33 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
34 old_body.syntax().clone().into() 34 old_body.syntax().clone().into()
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index 329c80749..7771d6759 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -16,7 +16,7 @@ impl ast::Expr {
16 | ast::Expr::WhileExpr(_) 16 | ast::Expr::WhileExpr(_)
17 | ast::Expr::BlockExpr(_) 17 | ast::Expr::BlockExpr(_)
18 | ast::Expr::MatchExpr(_) 18 | ast::Expr::MatchExpr(_)
19 | ast::Expr::TryExpr(_) => true, 19 | ast::Expr::EffectExpr(_) => true,
20 _ => false, 20 _ => false,
21 } 21 }
22 } 22 }
@@ -359,22 +359,34 @@ impl ast::Literal {
359 } 359 }
360} 360}
361 361
362pub enum BlockModifier { 362#[derive(Debug, Clone, PartialEq, Eq)]
363pub enum Effect {
363 Async(SyntaxToken), 364 Async(SyntaxToken),
364 Unsafe(SyntaxToken), 365 Unsafe(SyntaxToken),
366 Try(SyntaxToken),
367 // Very much not an effect, but we stuff it into this node anyway
368 Label(ast::Label),
365} 369}
366 370
367impl ast::BlockExpr { 371impl ast::EffectExpr {
368 pub fn modifier(&self) -> Option<BlockModifier> { 372 pub fn effect(&self) -> Effect {
369 if let Some(token) = self.async_token() { 373 if let Some(token) = self.async_token() {
370 return Some(BlockModifier::Async(token)); 374 return Effect::Async(token);
371 } 375 }
372 if let Some(token) = self.unsafe_token() { 376 if let Some(token) = self.unsafe_token() {
373 return Some(BlockModifier::Unsafe(token)); 377 return Effect::Unsafe(token);
378 }
379 if let Some(token) = self.try_token() {
380 return Effect::Try(token);
381 }
382 if let Some(label) = self.label() {
383 return Effect::Label(label);
374 } 384 }
375 None 385 unreachable!("ast::EffectExpr without Effect")
376 } 386 }
387}
377 388
389impl ast::BlockExpr {
378 /// false if the block is an intrinsic part of the syntax and can't be 390 /// false if the block is an intrinsic part of the syntax and can't be
379 /// replaced with arbitrary expression. 391 /// replaced with arbitrary expression.
380 /// 392 ///
@@ -383,15 +395,12 @@ impl ast::BlockExpr {
383 /// const FOO: () = { stand_alone }; 395 /// const FOO: () = { stand_alone };
384 /// ``` 396 /// ```
385 pub fn is_standalone(&self) -> bool { 397 pub fn is_standalone(&self) -> bool {
386 if self.modifier().is_some() {
387 return false;
388 }
389 let parent = match self.syntax().parent() { 398 let parent = match self.syntax().parent() {
390 Some(it) => it, 399 Some(it) => it,
391 None => return true, 400 None => return true,
392 }; 401 };
393 match parent.kind() { 402 match parent.kind() {
394 FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR => false, 403 FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | EFFECT_EXPR => false,
395 _ => true, 404 _ => true,
396 } 405 }
397 } 406 }
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index f2ea5088e..45e3dd2d3 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -407,7 +407,7 @@ impl ast::Visibility {
407 } else if self.super_token().is_some() { 407 } else if self.super_token().is_some() {
408 VisibilityKind::PubSuper 408 VisibilityKind::PubSuper
409 } else if self.self_token().is_some() { 409 } else if self.self_token().is_some() {
410 VisibilityKind::PubSuper 410 VisibilityKind::PubSelf
411 } else { 411 } else {
412 VisibilityKind::Pub 412 VisibilityKind::Pub
413 } 413 }
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 81260680f..5e844d5ae 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -476,6 +476,19 @@ impl LoopExpr {
476} 476}
477 477
478#[derive(Debug, Clone, PartialEq, Eq, Hash)] 478#[derive(Debug, Clone, PartialEq, Eq, Hash)]
479pub struct EffectExpr {
480 pub(crate) syntax: SyntaxNode,
481}
482impl ast::AttrsOwner for EffectExpr {}
483impl EffectExpr {
484