From 68fd1ce3139ca6517f2c46ad12866147aca6b178 Mon Sep 17 00:00:00 2001 From: feniljain Date: Mon, 12 Dec 2022 16:48:55 +0530 Subject: [PATCH 01/54] feat: bump variant suggestion for enums in patterns completion --- crates/ide-completion/src/completions.rs | 2 ++ crates/ide-completion/src/render/pattern.rs | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 296dfc1425..cac5dccde2 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -496,6 +496,7 @@ impl Completions { variant, local_name.clone(), None, + false, )); } @@ -514,6 +515,7 @@ impl Completions { variant, None, path, + true, )); } diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index c845ff21aa..edb727b57d 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -7,6 +7,7 @@ use syntax::SmolStr; use crate::{ context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext}, + item::CompletionRelevanceTypeMatch, render::{ variant::{format_literal_label, format_literal_lookup, visible_fields}, RenderContext, @@ -37,7 +38,7 @@ pub(crate) fn render_struct_pat( let lookup = format_literal_lookup(name.as_str(), kind); let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?; - Some(build_completion(ctx, label, lookup, pat, strukt)) + Some(build_completion(ctx, label, lookup, pat, strukt, false)) } pub(crate) fn render_variant_pat( @@ -47,6 +48,7 @@ pub(crate) fn render_variant_pat( variant: hir::Variant, local_name: Option, path: Option<&hir::ModPath>, + is_exact_type_match: bool, ) -> Option { let _p = profile::span("render_variant_pat"); @@ -81,7 +83,7 @@ pub(crate) fn render_variant_pat( } }; - Some(build_completion(ctx, label, lookup, pat, variant)) + Some(build_completion(ctx, label, lookup, pat, variant, is_exact_type_match)) } fn build_completion( @@ -90,13 +92,20 @@ fn build_completion( lookup: SmolStr, pat: String, def: impl HasAttrs + Copy, + is_exact_type_match: bool, ) -> CompletionItem { + let mut relevance = ctx.completion_relevance(); + + if is_exact_type_match { + relevance.type_match = Some(CompletionRelevanceTypeMatch::Exact); + } + let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label); item.set_documentation(ctx.docs(def)) .set_deprecated(ctx.is_deprecated(def)) .detail(&pat) .lookup_by(lookup) - .set_relevance(ctx.completion_relevance()); + .set_relevance(relevance); match ctx.snippet_cap() { Some(snippet_cap) => item.insert_snippet(snippet_cap, pat), None => item.insert_text(pat), From 794988c53b2ae41cabc23ee1dfb20e7d13b7dc3f Mon Sep 17 00:00:00 2001 From: feniljain Date: Sat, 17 Dec 2022 16:58:42 +0530 Subject: [PATCH 02/54] feat: filter already present enum variants in match arms --- crates/ide-completion/src/completions.rs | 25 +++++---- crates/ide-completion/src/completions/expr.rs | 1 + .../src/completions/flyimport.rs | 5 +- .../ide-completion/src/completions/pattern.rs | 1 + crates/ide-completion/src/context.rs | 2 + crates/ide-completion/src/context/analysis.rs | 53 ++++++++++++++++++- crates/ide-completion/src/render/pattern.rs | 2 +- crates/ide-completion/src/tests/record.rs | 41 ++++++++++++++ 8 files changed, 114 insertions(+), 16 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index cac5dccde2..fddd02fc13 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -23,7 +23,7 @@ pub(crate) mod env_vars; use std::iter; -use hir::{known, ScopeDef}; +use hir::{known, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, SymbolKind}; use syntax::ast; @@ -538,18 +538,25 @@ fn enum_variants_with_paths( enum_: hir::Enum, impl_: &Option, cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), + missing_variants: Option>, ) { - let variants = enum_.variants(ctx.db); + let mut process_variant = |variant: Variant| { + let self_path = hir::ModPath::from_segments( + hir::PathKind::Plain, + iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))), + ); + + cb(acc, ctx, variant, self_path); + }; + + let variants = match missing_variants { + Some(missing_variants) => missing_variants, + None => enum_.variants(ctx.db), + }; if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) { if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) { - for &variant in &variants { - let self_path = hir::ModPath::from_segments( - hir::PathKind::Plain, - iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))), - ); - cb(acc, ctx, variant, self_path); - } + variants.iter().for_each(|variant| process_variant(*variant)); } } diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 3192b21cfb..8946011280 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -208,6 +208,7 @@ pub(crate) fn complete_expr_path( |acc, ctx, variant, path| { acc.add_qualified_enum_variant(ctx, path_ctx, variant, path) }, + None, ); } } diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 364969af9c..0979f6a6df 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -5,10 +5,7 @@ use ide_db::imports::{ insert_use::ImportScope, }; use itertools::Itertools; -use syntax::{ - ast::{self}, - AstNode, SyntaxNode, T, -}; +use syntax::{ast, AstNode, SyntaxNode, T}; use crate::{ context::{ diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index 58d5bf114c..6ad6a06f11 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -58,6 +58,7 @@ pub(crate) fn complete_pattern( |acc, ctx, variant, path| { acc.add_qualified_variant_pat(ctx, pattern_ctx, variant, path); }, + Some(pattern_ctx.missing_variants.clone()), ); } } diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index aa77f44953..954e88e093 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -220,6 +220,8 @@ pub(super) struct PatternContext { /// The record pattern this name or ref is a field of pub(super) record_pat: Option, pub(super) impl_: Option, + /// List of missing variants in a match expr + pub(super) missing_variants: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index c142a7305f..73375250b5 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -1,7 +1,7 @@ //! Module responsible for analyzing the code surrounding the cursor for completion. use std::iter; -use hir::{Semantics, Type, TypeInfo}; +use hir::{Semantics, Type, TypeInfo, Variant}; use ide_db::{active_parameter::ActiveParameter, RootDatabase}; use syntax::{ algo::{find_node_at_offset, non_trivia_sibling}, @@ -1111,6 +1111,9 @@ fn pattern_context_for( pat: ast::Pat, ) -> PatternContext { let mut param_ctx = None; + + let mut missing_variants = vec![]; + let (refutability, has_type_ascription) = pat .syntax() @@ -1140,7 +1143,52 @@ fn pattern_context_for( })(); return (PatternRefutability::Irrefutable, has_type_ascription) }, - ast::MatchArm(_) => PatternRefutability::Refutable, + ast::MatchArm(match_arm) => { + let missing_variants_opt = match_arm + .syntax() + .parent() + .and_then(ast::MatchArmList::cast) + .and_then(|match_arm_list| { + match_arm_list + .syntax() + .parent() + .and_then(ast::MatchExpr::cast) + .and_then(|match_expr| { + let expr_opt = find_opt_node_in_file(&original_file, match_expr.expr()); + + expr_opt.and_then(|expr| { + sema.type_of_expr(&expr)? + .adjusted() + .autoderef(sema.db) + .find_map(|ty| match ty.as_adt() { + Some(hir::Adt::Enum(e)) => Some(e), + _ => None, + }).and_then(|enum_| { + Some(enum_.variants(sema.db)) + }) + }) + }).and_then(|variants| { + Some(variants.iter().filter_map(|variant| { + let variant_name = variant.name(sema.db).to_string(); + + let variant_already_present = match_arm_list.arms().any(|arm| { + arm.pat().and_then(|pat| { + let pat_already_present = pat.syntax().to_string().contains(&variant_name); + pat_already_present.then(|| pat_already_present) + }).is_some() + }); + + (!variant_already_present).then_some(variant.clone()) + }).collect::>()) + }) + }); + + if let Some(missing_variants_) = missing_variants_opt { + missing_variants = missing_variants_; + }; + + PatternRefutability::Refutable + }, ast::LetExpr(_) => PatternRefutability::Refutable, ast::ForExpr(_) => PatternRefutability::Irrefutable, _ => PatternRefutability::Irrefutable, @@ -1162,6 +1210,7 @@ fn pattern_context_for( ref_token, record_pat: None, impl_: fetch_immediate_impl(sema, original_file, pat.syntax()), + missing_variants, } } diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index edb727b57d..9cf766ce66 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -38,7 +38,7 @@ pub(crate) fn render_struct_pat( let lookup = format_literal_lookup(name.as_str(), kind); let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?; - Some(build_completion(ctx, label, lookup, pat, strukt, false)) + Some(build_completion(ctx, label, lookup, pat, strukt, true)) } pub(crate) fn render_variant_pat( diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs index 328faaa060..8b8c56d1d5 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs @@ -46,6 +46,47 @@ fn foo(s: Struct) { ); } +#[test] +fn record_pattern_field_enum() { + check( + r#" +enum Baz { FOO, BAR } + +fn foo(baz: Baz) { + match baz { + Baz::FOO => (), + $0 + } +} +"#, + expect![[r#" + en Baz + bn Baz::BAR Baz::BAR$0 + kw mut + kw ref + "#]], + ); + + check( + r#" +enum Baz { FOO, BAR } + +fn foo(baz: Baz) { + match baz { + FOO => (), + $0 + } +} +"#, + expect![[r#" + en Baz + bn Baz::BAR Baz::BAR$0 + kw mut + kw ref + "#]], + ); +} + #[test] fn pattern_enum_variant() { check( From c6da2f9d96a71bee04d194a85ed76edb0259db5b Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Feb 2023 13:07:44 +0000 Subject: [PATCH 03/54] Remove uses of `box_syntax` in rustc and tools --- crates/ide-completion/src/tests/attribute.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ide-completion/src/tests/attribute.rs b/crates/ide-completion/src/tests/attribute.rs index 4e60820dd6..c97144b61b 100644 --- a/crates/ide-completion/src/tests/attribute.rs +++ b/crates/ide-completion/src/tests/attribute.rs @@ -857,9 +857,9 @@ mod lint { #[test] fn lint_feature() { check_edit( - "box_syntax", + "box_patterns", r#"#[feature(box_$0)] struct Test;"#, - r#"#[feature(box_syntax)] struct Test;"#, + r#"#[feature(box_patterns)] struct Test;"#, ) } From b2f6fd4f961fc7e4fbfdb80cae2e6065f8436f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 13 Mar 2023 10:42:24 +0200 Subject: [PATCH 04/54] :arrow_up: rust-analyzer --- Cargo.lock | 2 + crates/flycheck/src/lib.rs | 109 +- crates/hir-def/src/attr.rs | 48 +- crates/hir-def/src/body.rs | 31 +- crates/hir-def/src/body/lower.rs | 200 ++- crates/hir-def/src/body/pretty.rs | 95 +- crates/hir-def/src/body/scope.rs | 50 +- crates/hir-def/src/body/tests/block.rs | 22 + crates/hir-def/src/child_by_source.rs | 3 +- crates/hir-def/src/data.rs | 37 +- crates/hir-def/src/db.rs | 11 +- crates/hir-def/src/expr.rs | 69 +- crates/hir-def/src/generics.rs | 44 +- crates/hir-def/src/import_map.rs | 2 + crates/hir-def/src/item_scope.rs | 1 + crates/hir-def/src/item_tree.rs | 17 +- crates/hir-def/src/item_tree/lower.rs | 137 +- crates/hir-def/src/item_tree/pretty.rs | 29 +- crates/hir-def/src/keys.rs | 5 +- crates/hir-def/src/lang_item.rs | 6 +- crates/hir-def/src/lib.rs | 17 +- .../macro_expansion_tests/builtin_fn_macro.rs | 2 +- .../macro_expansion_tests/mbe/regression.rs | 1 + crates/hir-def/src/nameres.rs | 18 +- crates/hir-def/src/nameres/collector.rs | 29 +- crates/hir-def/src/nameres/path_resolution.rs | 4 +- .../hir-def/src/nameres/tests/incremental.rs | 1 + crates/hir-def/src/path.rs | 4 +- crates/hir-def/src/path/lower.rs | 4 +- crates/hir-def/src/resolver.rs | 258 ++- crates/hir-def/src/type_ref.rs | 62 +- crates/hir-def/src/visibility.rs | 7 +- crates/hir-expand/src/builtin_fn_macro.rs | 2 +- crates/hir-expand/src/lib.rs | 26 +- crates/hir-ty/Cargo.toml | 1 + crates/hir-ty/src/builder.rs | 9 + crates/hir-ty/src/chalk_db.rs | 3 +- crates/hir-ty/src/chalk_ext.rs | 7 +- crates/hir-ty/src/consteval.rs | 503 ++---- crates/hir-ty/src/consteval/tests.rs | 965 +++++++++- crates/hir-ty/src/db.rs | 25 +- crates/hir-ty/src/diagnostics/decl_check.rs | 5 +- crates/hir-ty/src/diagnostics/expr.rs | 31 +- crates/hir-ty/src/diagnostics/match_check.rs | 3 +- crates/hir-ty/src/diagnostics/unsafe_check.rs | 6 +- crates/hir-ty/src/display.rs | 187 +- crates/hir-ty/src/infer.rs | 215 ++- crates/hir-ty/src/infer/coerce.rs | 60 +- crates/hir-ty/src/infer/expr.rs | 772 +++++--- crates/hir-ty/src/infer/pat.rs | 345 ++-- crates/hir-ty/src/infer/path.rs | 147 +- crates/hir-ty/src/infer/unify.rs | 5 +- crates/hir-ty/src/inhabitedness.rs | 19 +- crates/hir-ty/src/interner.rs | 4 +- crates/hir-ty/src/layout.rs | 16 +- crates/hir-ty/src/layout/adt.rs | 13 +- crates/hir-ty/src/layout/tests.rs | 21 +- crates/hir-ty/src/lib.rs | 49 +- crates/hir-ty/src/lower.rs | 30 +- crates/hir-ty/src/method_resolution.rs | 121 +- crates/hir-ty/src/mir.rs | 863 +++++++++ crates/hir-ty/src/mir/borrowck.rs | 223 +++ crates/hir-ty/src/mir/eval.rs | 1253 +++++++++++++ crates/hir-ty/src/mir/lower.rs | 1577 +++++++++++++++++ crates/hir-ty/src/mir/lower/as_place.rs | 237 +++ crates/hir-ty/src/mir/pretty.rs | 348 ++++ crates/hir-ty/src/tests.rs | 38 +- crates/hir-ty/src/tests/coercion.rs | 3 +- crates/hir-ty/src/tests/diagnostics.rs | 21 + crates/hir-ty/src/tests/method_resolution.rs | 4 +- crates/hir-ty/src/tests/patterns.rs | 30 +- crates/hir-ty/src/tests/regression.rs | 20 +- crates/hir-ty/src/tests/simple.rs | 24 +- crates/hir-ty/src/utils.rs | 7 +- crates/hir/src/attrs.rs | 5 +- crates/hir/src/db.rs | 5 +- crates/hir/src/diagnostics.rs | 47 +- crates/hir/src/display.rs | 49 +- crates/hir/src/from_id.rs | 13 +- crates/hir/src/has_source.rs | 21 +- crates/hir/src/lib.rs | 512 ++++-- crates/hir/src/semantics.rs | 36 +- crates/hir/src/semantics/source_to_def.rs | 38 +- crates/hir/src/source_analyzer.rs | 42 +- crates/hir/src/symbols.rs | 4 + .../src/handlers/add_explicit_type.rs | 4 +- .../handlers/convert_iter_for_each_to_for.rs | 19 +- .../src/handlers/convert_match_to_let_else.rs | 83 +- .../src/handlers/extract_function.rs | 25 +- .../src/handlers/extract_variable.rs | 2 +- .../src/handlers/fix_visibility.rs | 4 + .../src/handlers/generate_function.rs | 148 +- .../handlers/generate_is_empty_from_len.rs | 9 +- .../ide-assists/src/handlers/generate_new.rs | 2 +- .../src/handlers/inline_local_variable.rs | 11 +- crates/ide-assists/src/handlers/remove_dbg.rs | 134 +- .../src/handlers/replace_if_let_with_match.rs | 27 +- .../src/handlers/replace_method_eager_lazy.rs | 310 ++++ .../src/handlers/replace_or_with_or_else.rs | 364 ---- crates/ide-assists/src/lib.rs | 6 +- crates/ide-assists/src/tests/generated.rs | 84 +- crates/ide-completion/src/completions/dot.rs | 2 +- .../src/completions/flyimport.rs | 5 +- crates/ide-completion/src/completions/type.rs | 4 +- crates/ide-completion/src/context.rs | 15 +- crates/ide-completion/src/item.rs | 3 +- crates/ide-completion/src/render.rs | 3 + crates/ide-completion/src/render/macro_.rs | 59 + crates/ide-db/src/active_parameter.rs | 1 + crates/ide-db/src/apply_change.rs | 64 +- crates/ide-db/src/defs.rs | 21 +- crates/ide-db/src/helpers.rs | 10 +- crates/ide-db/src/imports/import_assets.rs | 2 +- crates/ide-db/src/lib.rs | 4 +- crates/ide-db/src/rename.rs | 105 +- crates/ide-db/src/search.rs | 50 +- crates/ide-db/src/source_change.rs | 8 + ...ntructor.rs => use_trivial_constructor.rs} | 0 .../src/handlers/break_outside_of_loop.rs | 23 +- .../src/handlers/expected_function.rs | 39 + .../src/handlers/missing_fields.rs | 2 +- .../src/handlers/missing_match_arms.rs | 5 +- .../src/handlers/mutability_errors.rs | 625 +++++++ .../src/handlers/private_assoc_item.rs | 38 + .../replace_filter_map_next_with_find_map.rs | 13 +- .../src/handlers/type_mismatch.rs | 86 +- .../src/handlers/unresolved_field.rs | 148 ++ .../src/handlers/unresolved_method.rs | 131 ++ crates/ide-diagnostics/src/lib.rs | 10 +- crates/ide-ssr/src/matching.rs | 2 +- crates/ide/src/doc_links.rs | 15 +- crates/ide/src/file_structure.rs | 79 +- crates/ide/src/goto_definition.rs | 25 +- crates/ide/src/highlight_related.rs | 57 +- crates/ide/src/hover.rs | 1 + crates/ide/src/hover/render.rs | 31 +- crates/ide/src/hover/tests.rs | 350 +++- crates/ide/src/inlay_hints/adjustment.rs | 5 +- crates/ide/src/inlay_hints/bind_pat.rs | 117 +- crates/ide/src/inlay_hints/chaining.rs | 12 +- crates/ide/src/inlay_hints/discriminant.rs | 10 +- crates/ide/src/lib.rs | 5 + crates/ide/src/markup.rs | 2 +- crates/ide/src/moniker.rs | 3 + crates/ide/src/move_item.rs | 1 + crates/ide/src/navigation_target.rs | 26 +- crates/ide/src/references.rs | 32 + crates/ide/src/rename.rs | 22 + crates/ide/src/runnables.rs | 290 ++- crates/ide/src/signature_help.rs | 6 +- crates/ide/src/static_index.rs | 1 + .../ide/src/syntax_highlighting/highlight.rs | 5 +- crates/ide/src/syntax_highlighting/inject.rs | 1 + crates/ide/src/syntax_highlighting/tags.rs | 1 + .../test_data/highlight_attributes.html | 2 +- crates/ide/src/syntax_highlighting/tests.rs | 2 +- crates/ide/src/view_mir.rs | 29 + crates/parser/src/grammar.rs | 4 + crates/parser/src/grammar/attributes.rs | 2 +- crates/parser/src/grammar/expressions.rs | 28 +- crates/parser/src/grammar/expressions/atom.rs | 10 +- crates/parser/src/grammar/items/traits.rs | 2 +- crates/parser/src/grammar/paths.rs | 6 + crates/parser/src/syntax_kind/generated.rs | 1 + .../0049_let_else_right_curly_brace_for.rast | 58 + .../0049_let_else_right_curly_brace_for.rs | 6 + .../0050_let_else_right_curly_brace_loop.rast | 46 + .../0050_let_else_right_curly_brace_loop.rs | 6 + ...0051_let_else_right_curly_brace_match.rast | 85 + .../0051_let_else_right_curly_brace_match.rs | 8 + ...0052_let_else_right_curly_brace_while.rast | 49 + .../0052_let_else_right_curly_brace_while.rs | 6 + .../0053_let_else_right_curly_brace_if.rast | 57 + .../err/0053_let_else_right_curly_brace_if.rs | 7 + .../err/0016_angled_path_without_qual.rast | 49 + .../err/0016_angled_path_without_qual.rs | 2 + .../err/0017_let_else_right_curly_brace.rast | 69 + .../err/0017_let_else_right_curly_brace.rs | 1 + .../parser/inline/ok/0151_trait_alias.rast | 2 +- .../ok/0177_trait_alias_where_clause.rast | 4 +- crates/project-model/src/build_scripts.rs | 84 +- crates/project-model/src/cargo_workspace.rs | 2 + crates/project-model/src/sysroot.rs | 21 +- crates/project-model/src/tests.rs | 9 + crates/project-model/src/workspace.rs | 60 +- .../default_12483297303756020505_0.profraw | Bin 25152 -> 0 bytes .../rust-analyzer/src/cli/analysis_stats.rs | 187 +- crates/rust-analyzer/src/cli/diagnostics.rs | 4 +- crates/rust-analyzer/src/cli/lsif.rs | 5 +- crates/rust-analyzer/src/cli/scip.rs | 5 +- crates/rust-analyzer/src/cli/ssr.rs | 5 +- crates/rust-analyzer/src/config.rs | 51 +- crates/rust-analyzer/src/handlers.rs | 10 + crates/rust-analyzer/src/lsp_ext.rs | 8 + crates/rust-analyzer/src/main_loop.rs | 71 +- crates/rust-analyzer/src/reload.rs | 99 +- crates/rust-analyzer/src/to_proto.rs | 4 +- crates/syntax/Cargo.toml | 1 + crates/syntax/rust.ungram | 10 +- crates/syntax/src/ast.rs | 12 +- crates/syntax/src/ast/generated/nodes.rs | 43 +- crates/syntax/src/ast/node_ext.rs | 75 + crates/syntax/src/ast/traits.rs | 4 +- crates/syntax/src/tests/ast_src.rs | 1 + crates/syntax/src/tests/sourcegen_ast.rs | 1 + crates/test-utils/src/fixture.rs | 4 +- crates/test-utils/src/minicore.rs | 49 + crates/toolchain/src/lib.rs | 21 +- docs/dev/lsp-extensions.md | 13 +- docs/user/generated_config.adoc | 15 +- editors/code/package.json | 31 +- editors/code/src/commands.ts | 35 +- editors/code/src/ctx.ts | 34 +- editors/code/src/lsp_ext.ts | 3 + editors/code/src/main.ts | 2 + editors/code/src/toolchain.ts | 30 +- lib/la-arena/src/map.rs | 6 + 217 files changed, 12639 insertions(+), 3059 deletions(-) create mode 100644 crates/hir-ty/src/mir.rs create mode 100644 crates/hir-ty/src/mir/borrowck.rs create mode 100644 crates/hir-ty/src/mir/eval.rs create mode 100644 crates/hir-ty/src/mir/lower.rs create mode 100644 crates/hir-ty/src/mir/lower/as_place.rs create mode 100644 crates/hir-ty/src/mir/pretty.rs create mode 100644 crates/ide-assists/src/handlers/replace_method_eager_lazy.rs delete mode 100644 crates/ide-assists/src/handlers/replace_or_with_or_else.rs rename crates/ide-db/src/{use_trivial_contructor.rs => use_trivial_constructor.rs} (100%) create mode 100644 crates/ide-diagnostics/src/handlers/expected_function.rs create mode 100644 crates/ide-diagnostics/src/handlers/mutability_errors.rs create mode 100644 crates/ide-diagnostics/src/handlers/unresolved_field.rs create mode 100644 crates/ide-diagnostics/src/handlers/unresolved_method.rs create mode 100644 crates/ide/src/view_mir.rs create mode 100644 crates/parser/test_data/parser/err/0049_let_else_right_curly_brace_for.rast create mode 100644 crates/parser/test_data/parser/err/0049_let_else_right_curly_brace_for.rs create mode 100644 crates/parser/test_data/parser/err/0050_let_else_right_curly_brace_loop.rast create mode 100644 crates/parser/test_data/parser/err/0050_let_else_right_curly_brace_loop.rs create mode 100644 crates/parser/test_data/parser/err/0051_let_else_right_curly_brace_match.rast create mode 100644 crates/parser/test_data/parser/err/0051_let_else_right_curly_brace_match.rs create mode 100644 crates/parser/test_data/parser/err/0052_let_else_right_curly_brace_while.rast create mode 100644 crates/parser/test_data/parser/err/0052_let_else_right_curly_brace_while.rs create mode 100644 crates/parser/test_data/parser/err/0053_let_else_right_curly_brace_if.rast create mode 100644 crates/parser/test_data/parser/err/0053_let_else_right_curly_brace_if.rs create mode 100644 crates/parser/test_data/parser/inline/err/0016_angled_path_without_qual.rast create mode 100644 crates/parser/test_data/parser/inline/err/0016_angled_path_without_qual.rs create mode 100644 crates/parser/test_data/parser/inline/err/0017_let_else_right_curly_brace.rast create mode 100644 crates/parser/test_data/parser/inline/err/0017_let_else_right_curly_brace.rs delete mode 100644 crates/rust-analyzer/default_12483297303756020505_0.profraw diff --git a/Cargo.lock b/Cargo.lock index ec19776725..fc77515b63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -572,6 +572,7 @@ dependencies = [ "chalk-recursive", "chalk-solve", "cov-mark", + "either", "ena", "expect-test", "hir-def", @@ -1714,6 +1715,7 @@ name = "syntax" version = "0.0.0" dependencies = [ "cov-mark", + "either", "expect-test", "indexmap", "itertools", diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index 11f7b068ec..accb14a51d 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs @@ -76,7 +76,7 @@ impl fmt::Display for FlycheckConfig { #[derive(Debug)] pub struct FlycheckHandle { // XXX: drop order is significant - sender: Sender, + sender: Sender, _thread: jod_thread::JoinHandle, id: usize, } @@ -89,7 +89,7 @@ impl FlycheckHandle { workspace_root: AbsPathBuf, ) -> FlycheckHandle { let actor = FlycheckActor::new(id, sender, config, workspace_root); - let (sender, receiver) = unbounded::(); + let (sender, receiver) = unbounded::(); let thread = jod_thread::Builder::new() .name("Flycheck".to_owned()) .spawn(move || actor.run(receiver)) @@ -99,12 +99,12 @@ impl FlycheckHandle { /// Schedule a re-start of the cargo check worker. pub fn restart(&self) { - self.sender.send(Restart::Yes).unwrap(); + self.sender.send(StateChange::Restart).unwrap(); } /// Stop this cargo check worker. pub fn cancel(&self) { - self.sender.send(Restart::No).unwrap(); + self.sender.send(StateChange::Cancel).unwrap(); } pub fn id(&self) -> usize { @@ -149,9 +149,9 @@ pub enum Progress { DidFailToRestart(String), } -enum Restart { - Yes, - No, +enum StateChange { + Restart, + Cancel, } /// A [`FlycheckActor`] is a single check instance of a workspace. @@ -172,7 +172,7 @@ struct FlycheckActor { } enum Event { - Restart(Restart), + RequestStateChange(StateChange), CheckEvent(Option), } @@ -191,30 +191,31 @@ impl FlycheckActor { self.send(Message::Progress { id: self.id, progress }); } - fn next_event(&self, inbox: &Receiver) -> Option { + fn next_event(&self, inbox: &Receiver) -> Option { let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver); if let Ok(msg) = inbox.try_recv() { // give restarts a preference so check outputs don't block a restart or stop - return Some(Event::Restart(msg)); + return Some(Event::RequestStateChange(msg)); } select! { - recv(inbox) -> msg => msg.ok().map(Event::Restart), + recv(inbox) -> msg => msg.ok().map(Event::RequestStateChange), recv(check_chan.unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())), } } - fn run(mut self, inbox: Receiver) { + fn run(mut self, inbox: Receiver) { 'event: while let Some(event) = self.next_event(&inbox) { match event { - Event::Restart(Restart::No) => { + Event::RequestStateChange(StateChange::Cancel) => { + tracing::debug!(flycheck_id = self.id, "flycheck cancelled"); self.cancel_check_process(); } - Event::Restart(Restart::Yes) => { + Event::RequestStateChange(StateChange::Restart) => { // Cancel the previously spawned process self.cancel_check_process(); while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) { // restart chained with a stop, so just cancel - if let Restart::No = restart { + if let StateChange::Cancel = restart { continue 'event; } } @@ -255,10 +256,20 @@ impl FlycheckActor { } Event::CheckEvent(Some(message)) => match message { CargoMessage::CompilerArtifact(msg) => { + tracing::trace!( + flycheck_id = self.id, + artifact = msg.target.name, + "artifact received" + ); self.report_progress(Progress::DidCheckCrate(msg.target.name)); } CargoMessage::Diagnostic(msg) => { + tracing::trace!( + flycheck_id = self.id, + message = msg.message, + "diagnostic received" + ); self.send(Message::AddDiagnostic { id: self.id, workspace_root: self.root.clone(), @@ -445,42 +456,56 @@ impl CargoActor { // simply skip a line if it doesn't parse, which just ignores any // erroneous output. - let mut error = String::new(); - let mut read_at_least_one_message = false; + let mut stdout_errors = String::new(); + let mut stderr_errors = String::new(); + let mut read_at_least_one_stdout_message = false; + let mut read_at_least_one_stderr_message = false; + let process_line = |line: &str, error: &mut String| { + // Try to deserialize a message from Cargo or Rustc. + let mut deserializer = serde_json::Deserializer::from_str(line); + deserializer.disable_recursion_limit(); + if let Ok(message) = JsonMessage::deserialize(&mut deserializer) { + match message { + // Skip certain kinds of messages to only spend time on what's useful + JsonMessage::Cargo(message) => match message { + cargo_metadata::Message::CompilerArtifact(artifact) if !artifact.fresh => { + self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap(); + } + cargo_metadata::Message::CompilerMessage(msg) => { + self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap(); + } + _ => (), + }, + JsonMessage::Rustc(message) => { + self.sender.send(CargoMessage::Diagnostic(message)).unwrap(); + } + } + return true; + } + + error.push_str(line); + error.push('\n'); + return false; + }; let output = streaming_output( self.stdout, self.stderr, &mut |line| { - read_at_least_one_message = true; - - // Try to deserialize a message from Cargo or Rustc. - let mut deserializer = serde_json::Deserializer::from_str(line); - deserializer.disable_recursion_limit(); - if let Ok(message) = JsonMessage::deserialize(&mut deserializer) { - match message { - // Skip certain kinds of messages to only spend time on what's useful - JsonMessage::Cargo(message) => match message { - cargo_metadata::Message::CompilerArtifact(artifact) - if !artifact.fresh => - { - self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap(); - } - cargo_metadata::Message::CompilerMessage(msg) => { - self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap(); - } - _ => (), - }, - JsonMessage::Rustc(message) => { - self.sender.send(CargoMessage::Diagnostic(message)).unwrap(); - } - } + if process_line(line, &mut stdout_errors) { + read_at_least_one_stdout_message = true; } }, &mut |line| { - error.push_str(line); - error.push('\n'); + if process_line(line, &mut stderr_errors) { + read_at_least_one_stderr_message = true; + } }, ); + + let read_at_least_one_message = + read_at_least_one_stdout_message || read_at_least_one_stderr_message; + let mut error = stdout_errors; + error.push_str(&stderr_errors); match output { Ok(_) => Ok((read_at_least_one_message, error)), Err(e) => Err(io::Error::new(e.kind(), format!("{e:?}: {error}"))), diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index fcd92ad338..200072c172 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -300,6 +300,7 @@ impl AttrsWithOwner { AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db), }, AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AttrDefId::TraitAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), AttrDefId::MacroId(it) => match it { MacroId::Macro2Id(it) => attrs_from_item_tree(it.lookup(db).id, db), MacroId::MacroRulesId(it) => attrs_from_item_tree(it.lookup(db).id, db), @@ -315,26 +316,14 @@ impl AttrsWithOwner { let src = it.parent().child_source(db); RawAttrs::from_attrs_owner( db.upcast(), - src.with_value(src.value[it.local_id()].as_ref().either( - |it| match it { - ast::TypeOrConstParam::Type(it) => it as _, - ast::TypeOrConstParam::Const(it) => it as _, - }, - |it| it as _, - )), + src.with_value(&src.value[it.local_id()]), ) } GenericParamId::TypeParamId(it) => { let src = it.parent().child_source(db); RawAttrs::from_attrs_owner( db.upcast(), - src.with_value(src.value[it.local_id()].as_ref().either( - |it| match it { - ast::TypeOrConstParam::Type(it) => it as _, - ast::TypeOrConstParam::Const(it) => it as _, - }, - |it| it as _, - )), + src.with_value(&src.value[it.local_id()]), ) } GenericParamId::LifetimeParamId(it) => { @@ -404,6 +393,7 @@ impl AttrsWithOwner { AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), + AttrDefId::TraitAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), AttrDefId::MacroId(id) => match id { MacroId::Macro2Id(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), @@ -412,28 +402,14 @@ impl AttrsWithOwner { }, AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), AttrDefId::GenericParamId(id) => match id { - GenericParamId::ConstParamId(id) => { - id.parent().child_source(db).map(|source| match &source[id.local_id()] { - Either::Left(ast::TypeOrConstParam::Type(id)) => { - ast::AnyHasAttrs::new(id.clone()) - } - Either::Left(ast::TypeOrConstParam::Const(id)) => { - ast::AnyHasAttrs::new(id.clone()) - } - Either::Right(id) => ast::AnyHasAttrs::new(id.clone()), - }) - } - GenericParamId::TypeParamId(id) => { - id.parent().child_source(db).map(|source| match &source[id.local_id()] { - Either::Left(ast::TypeOrConstParam::Type(id)) => { - ast::AnyHasAttrs::new(id.clone()) - } - Either::Left(ast::TypeOrConstParam::Const(id)) => { - ast::AnyHasAttrs::new(id.clone()) - } - Either::Right(id) => ast::AnyHasAttrs::new(id.clone()), - }) - } + GenericParamId::ConstParamId(id) => id + .parent() + .child_source(db) + .map(|source| ast::AnyHasAttrs::new(source[id.local_id()].clone())), + GenericParamId::TypeParamId(id) => id + .parent() + .child_source(db) + .map(|source| ast::AnyHasAttrs::new(source[id.local_id()].clone())), GenericParamId::LifetimeParamId(id) => id .parent .child_source(db) diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index 8fd9255b8b..3be477d487 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -24,7 +24,7 @@ use syntax::{ast, AstPtr, SyntaxNode, SyntaxNodePtr}; use crate::{ attr::Attrs, db::DefDatabase, - expr::{dummy_expr_id, Expr, ExprId, Label, LabelId, Pat, PatId}, + expr::{dummy_expr_id, Binding, BindingId, Expr, ExprId, Label, LabelId, Pat, PatId}, item_scope::BuiltinShadowMode, macro_id_to_def_id, nameres::DefMap, @@ -270,7 +270,7 @@ pub struct Mark { pub struct Body { pub exprs: Arena, pub pats: Arena, - pub or_pats: FxHashMap>, + pub bindings: Arena, pub labels: Arena