diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index f54c8dd8b0fc..61281f8cfb8f 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -304,19 +304,19 @@ impl CompletionRelevance { // only applicable for completions within use items // lower rank for conflicting import names if is_name_already_imported { - score -= 1; + score -= 15; } // slightly prefer locals if is_local { - score += 1; + score += 2; } if is_missing { - score += 1; + score += 2; } // lower rank private things if !is_private_editable { - score += 1; + score += 10; } if let Some(trait_) = trait_ { @@ -337,10 +337,10 @@ impl CompletionRelevance { // lower rank for items that need an import if requires_import { - score -= 1; + score -= 12; } if exact_name_match { - score += 20; + score += 40; } match postfix_match { Some(CompletionRelevancePostfixMatch::Exact) => score += 100, @@ -348,16 +348,26 @@ impl CompletionRelevance { None => (), }; score += match type_match { - Some(CompletionRelevanceTypeMatch::Exact) => 18, - Some(CompletionRelevanceTypeMatch::CouldUnify) => 5, + Some(CompletionRelevanceTypeMatch::Exact) => 35, + Some(CompletionRelevanceTypeMatch::CouldUnify) => 15, None => 0, }; if let Some(function) = function { - let mut fn_score = match function.return_type { - CompletionRelevanceReturnType::DirectConstructor => 15, - CompletionRelevanceReturnType::Builder => 10, - CompletionRelevanceReturnType::Constructor => 5, - CompletionRelevanceReturnType::Other => 0u32, + let mut fn_score = if requires_import { + // Rank constructors that require imports lower than those who don't. + match function.return_type { + CompletionRelevanceReturnType::DirectConstructor => 8, + CompletionRelevanceReturnType::Builder => 5, + CompletionRelevanceReturnType::Constructor => 3, + CompletionRelevanceReturnType::Other => 0u32, + } + } else { + match function.return_type { + CompletionRelevanceReturnType::DirectConstructor => 15, + CompletionRelevanceReturnType::Builder => 10, + CompletionRelevanceReturnType::Constructor => 5, + CompletionRelevanceReturnType::Other => 0u32, + } }; // When a fn is bumped due to return type: @@ -375,12 +385,12 @@ impl CompletionRelevance { }; if has_local_inherent_impl { - score -= 5; + score -= 8; } // lower rank for deprecated items if is_deprecated { - score -= 5; + score -= 15; } score @@ -831,15 +841,17 @@ mod tests { is_private_editable: true, ..default }], - vec![Cr { - trait_: Some(crate::item::CompletionRelevanceTraitInfo { - notable_trait: false, - is_op_method: true, - }), - ..default - }], + vec![ + Cr { + trait_: Some(crate::item::CompletionRelevanceTraitInfo { + notable_trait: false, + is_op_method: true, + }), + ..default + }, + Cr { is_private_editable: true, ..default }, + ], vec![Cr { postfix_match: Some(CompletionRelevancePostfixMatch::NonExact), ..default }], - vec![Cr { is_private_editable: true, ..default }], vec![default], vec![Cr { is_local: true, ..default }], vec![Cr { type_match: Some(CompletionRelevanceTypeMatch::CouldUnify), ..default }], diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index bb92aad1841e..e48847c983b4 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -1071,12 +1071,12 @@ fn main() { "#, expect![[r#" ev dep::test_mod_b::Enum::Variant dep::test_mod_b::Enum::Variant [type] - ev Variant Variant [type+requires_import] ex dep::test_mod_b::Enum::Variant [type] - ev Variant Variant [requires_import] + ev Variant Variant [type+requires_import] md dep:: [] fn main() fn() [] fn test(…) fn(Enum) [] + ev Variant Variant [requires_import] "#]], ); } @@ -3989,11 +3989,11 @@ fn foo() { } "#, expect![[r#" - ev Foo::B Foo::B [type_could_unify] - ev Foo::A(…) Foo::A(T) [type_could_unify] lc foo Foo [type+local] ex Foo::B [type] ex foo [type] + ev Foo::B Foo::B [type_could_unify] + ev Foo::A(…) Foo::A(T) [type_could_unify] en Foo Foo [type_could_unify] fn baz() fn() -> Foo [type_could_unify] fn bar() fn() -> Foo [] diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs index 3d4ad78c3433..e49afa66ad73 100644 --- a/crates/ide-completion/src/tests/expression.rs +++ b/crates/ide-completion/src/tests/expression.rs @@ -4055,3 +4055,57 @@ fn test(test: H) { expect![""], ); } + +#[test] +fn imported_enum_variant_has_lower_priority() { + check( + r#" +pub struct String {} +mod foo { + pub enum Foo { String } +} +fn main() { + Strin$0 +} + "#, + expect![[r#" + fn main() fn() + md foo:: + st String String + ev String (use foo::Foo::String) String + bt u32 u32 + kw async + kw const + kw crate:: + kw enum + kw extern + kw false + kw fn + kw for + kw if + kw if let + kw impl + kw impl for + kw let + kw letm + kw loop + kw match + kw mod + kw return + kw self:: + kw static + kw struct + kw trait + kw true + kw type + kw union + kw unsafe + kw use + kw while + kw while let + sn macro_rules + sn pd + sn ppd + "#]], + ); +} diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index f3cf823efe68..5a1856c89df3 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -120,6 +120,22 @@ fn add_or_fix_reference( return None; } + let expr = expr_ptr.to_node(ctx.db()); + let assign = expr + .syntax() + .parent() + .and_then(ast::BinExpr::cast) + .filter(|it| it.op_kind() == Some(ast::BinaryOp::Assignment { op: None })); + if let Some(assign) = assign + && expected_mutability.is_mut() + && let Some(range) = ctx.sema.original_range_opt(assign.syntax()) + { + let edit = TextEdit::insert(range.range.start(), "*".to_owned()); + let source_change = SourceChange::from_text_edit(range.file_id.file_id(ctx.db()), edit); + acc.push(fix("add_deref_here", "Add deref here", source_change, range.range)); + return Some(()); + } + let ampersands = format!("&{}", expected_mutability.as_keyword_for_ref()); let edit = TextEdit::insert(range.range.start(), ampersands); @@ -507,6 +523,22 @@ fn test(_arg: &mut i32) {} ); } + #[test] + fn add_deref_in_assign() { + check_fix( + r#" +fn test(arg: &mut i32) { + arg = $02; +} + "#, + r#" +fn test(arg: &mut i32) { + *arg = 2; +} + "#, + ); + } + #[test] fn add_reference_to_array() { check_fix( diff --git a/crates/proc-macro-srv/Cargo.toml b/crates/proc-macro-srv/Cargo.toml index c3cd447c85f1..466754209043 100644 --- a/crates/proc-macro-srv/Cargo.toml +++ b/crates/proc-macro-srv/Cargo.toml @@ -36,7 +36,11 @@ proc-macro-test.path = "./proc-macro-test" [features] default = [] +# default = ["sysroot-abi"] sysroot-abi = [] [lints] workspace = true + +[package.metadata.rust-analyzer] +rustc_private=true diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 5ed522ceee4c..92d5323e9680 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -1267,6 +1267,10 @@ impl GlobalState { let mut dispatcher = RequestDispatcher { req: Some(req), global_state: self }; dispatcher.on_sync_mut::(|s, ()| { s.shutdown_requested = true; + s.proc_macro_clients = + std::iter::repeat_with(|| None).take(s.proc_macro_clients.len()).collect(); + s.flycheck.iter().for_each(|handle| handle.cancel()); + s.discover_handles.clear(); Ok(()) });