Merge #11974
11974: minor: prepare CI for rust-lang move r=Veykril a=Veykril
bors r+
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
diff --git a/Cargo.lock b/Cargo.lock
index aeea1d9..cea8540 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -171,9 +171,9 @@
[[package]]
name = "chalk-derive"
-version = "0.81.0"
+version = "0.82.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb2ca8aa9da8210effebb51e49b4bd8bc25c06df38220d58a60df35a08a84af"
+checksum = "ee9cd790d543c29ce953abcb28d54b9fbaf9c4033bfd3024de99b1aa0f3c3ada"
dependencies = [
"proc-macro2",
"quote",
@@ -183,9 +183,9 @@
[[package]]
name = "chalk-ir"
-version = "0.81.0"
+version = "0.82.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e128fa3652ef2cdd5a7e64e0cc5a89f40170f80dd9f6357ba4a82cf027abd0d5"
+checksum = "dddf2c11f9de666c08c7591eb113efcdc740bd8ac602915475b045bcbe7f27a5"
dependencies = [
"bitflags",
"chalk-derive",
@@ -194,9 +194,9 @@
[[package]]
name = "chalk-recursive"
-version = "0.81.0"
+version = "0.82.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6fcba1e8b66a291430b6aa18368a95da0577d7f126653baae71c0cb0f3d093"
+checksum = "a60d5b35598702963ffd145b8bfa0d8d8ae9da3a731e4e0814aa21541b85c2d5"
dependencies = [
"chalk-derive",
"chalk-ir",
@@ -207,9 +207,9 @@
[[package]]
name = "chalk-solve"
-version = "0.81.0"
+version = "0.82.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43151ddc627d8dfbde6af44405cb8e98a15828f66a3d4a3da6a1fad6c5dc4687"
+checksum = "d99da4fa3b224c07f6c2506e6905bca9d6aad665f11d25364e6818a7ea149215"
dependencies = [
"chalk-derive",
"chalk-ir",
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index efcd5ff..1fe5788 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -18,9 +18,9 @@
tracing = "0.1.32"
rustc-hash = "1.1.0"
scoped-tls = "1.0.0"
-chalk-solve = { version = "0.81.0", default-features = false }
-chalk-ir = "0.81.0"
-chalk-recursive = { version = "0.81.0", default-features = false }
+chalk-solve = { version = "0.82.0", default-features = false }
+chalk-ir = "0.82.0"
+chalk-recursive = { version = "0.82.0", default-features = false }
la-arena = { version = "0.3.0", path = "../../lib/arena" }
once_cell = "1.10.0"
typed-arena = "2.0.1"
diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs
index 1bb3cdb..f5bff5f 100644
--- a/crates/ide/src/rename.rs
+++ b/crates/ide/src/rename.rs
@@ -968,15 +968,21 @@
},
},
file_system_edits: [
- MoveFile {
- src: FileId(
+ MoveDir {
+ src: AnchoredPathBuf {
+ anchor: FileId(
+ 1,
+ ),
+ path: "foo",
+ },
+ src_id: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
- path: "../foo2/mod.rs",
+ path: "foo2",
},
},
],
@@ -1114,6 +1120,68 @@
}
#[test]
+ fn test_rename_mod_recursive() {
+ check_expect(
+ "foo2",
+ r#"
+//- /lib.rs
+mod foo$0;
+
+//- /foo.rs
+mod bar;
+mod corge;
+
+//- /foo/bar.rs
+mod qux;
+
+//- /foo/bar/qux.rs
+mod quux;
+
+//- /foo/bar/qux/quux/mod.rs
+// empty
+
+//- /foo/corge.rs
+// empty
+"#,
+ expect![[r#"
+ SourceChange {
+ source_file_edits: {
+ FileId(
+ 0,
+ ): TextEdit {
+ indels: [
+ Indel {
+ insert: "foo2",
+ delete: 4..7,
+ },
+ ],
+ },
+ },
+ file_system_edits: [
+ MoveDir {
+ src: AnchoredPathBuf {
+ anchor: FileId(
+ 1,
+ ),
+ path: "foo",
+ },
+ src_id: FileId(
+ 1,
+ ),
+ dst: AnchoredPathBuf {
+ anchor: FileId(
+ 1,
+ ),
+ path: "foo2",
+ },
+ },
+ ],
+ is_snippet: false,
+ }
+ "#]],
+ )
+ }
+ #[test]
fn test_rename_mod_ref_by_super() {
check(
"baz",
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 09260c1..b3a0bd2 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -162,6 +162,10 @@
FileSystemEdit::MoveFile { src, dst } => {
(dst, db.file_text(src).as_ref().to_owned())
}
+ FileSystemEdit::MoveDir { src, src_id, dst } => {
+ // temporary placeholder for MoveDir since we are not using MoveDir in ide assists yet.
+ (dst, format!("{:?}\n{:?}", src_id, src))
+ }
};
let sr = db.file_source_root(dst.anchor);
let sr = db.source_root(sr);
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 7dbc511..b8a904a 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -126,7 +126,7 @@
cov_mark::hit!(qualified_path_doc_hidden);
return;
}
- self.add(render_resolution(RenderContext::new(ctx), local_name, resolution));
+ self.add(render_resolution(RenderContext::new(ctx), local_name, resolution).build());
}
pub(crate) fn add_resolution_simple(
@@ -138,7 +138,7 @@
if ctx.is_scope_def_hidden(resolution) {
return;
}
- self.add(render_resolution_simple(RenderContext::new(ctx), local_name, resolution));
+ self.add(render_resolution_simple(RenderContext::new(ctx), local_name, resolution).build());
}
pub(crate) fn add_macro(
@@ -152,11 +152,14 @@
Visible::Editable => true,
Visible::No => return,
};
- self.add(render_macro(
- RenderContext::new(ctx).private_editable(is_private_editable),
- local_name,
- mac,
- ));
+ self.add(
+ render_macro(
+ RenderContext::new(ctx).private_editable(is_private_editable),
+ local_name,
+ mac,
+ )
+ .build(),
+ );
}
pub(crate) fn add_function(
@@ -170,11 +173,14 @@
Visible::Editable => true,
Visible::No => return,
};
- self.add(render_fn(
- RenderContext::new(ctx).private_editable(is_private_editable),
- local_name,
- func,
- ));
+ self.add(
+ render_fn(
+ RenderContext::new(ctx).private_editable(is_private_editable),
+ local_name,
+ func,
+ )
+ .build(),
+ );
}
pub(crate) fn add_method(
@@ -189,12 +195,15 @@
Visible::Editable => true,
Visible::No => return,
};
- self.add(render_method(
- RenderContext::new(ctx).private_editable(is_private_editable),
- receiver,
- local_name,
- func,
- ));
+ self.add(
+ render_method(
+ RenderContext::new(ctx).private_editable(is_private_editable),
+ receiver,
+ local_name,
+ func,
+ )
+ .build(),
+ );
}
pub(crate) fn add_const(&mut self, ctx: &CompletionContext, konst: hir::Const) {
@@ -235,7 +244,11 @@
variant: hir::Variant,
path: hir::ModPath,
) {
- self.add_opt(render_variant_lit(RenderContext::new(ctx), None, variant, Some(path)));
+ if let Some(builder) =
+ render_variant_lit(RenderContext::new(ctx), None, variant, Some(path))
+ {
+ self.add(builder.build());
+ }
}
pub(crate) fn add_enum_variant(
@@ -244,7 +257,11 @@
variant: hir::Variant,
local_name: Option<hir::Name>,
) {
- self.add_opt(render_variant_lit(RenderContext::new(ctx), local_name, variant, None));
+ if let Some(builder) =
+ render_variant_lit(RenderContext::new(ctx), local_name, variant, None)
+ {
+ self.add(builder.build());
+ }
}
pub(crate) fn add_field(
@@ -275,8 +292,11 @@
path: Option<hir::ModPath>,
local_name: Option<hir::Name>,
) {
- let item = render_struct_literal(RenderContext::new(ctx), strukt, path, local_name);
- self.add_opt(item);
+ if let Some(builder) =
+ render_struct_literal(RenderContext::new(ctx), strukt, path, local_name)
+ {
+ self.add(builder.build());
+ }
}
pub(crate) fn add_union_literal(
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index fb857ae..76d708a 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -205,7 +205,8 @@
&user_input_lowercased,
)
})
- .filter_map(|import| render_resolution_with_import(RenderContext::new(ctx), import)),
+ .filter_map(|import| render_resolution_with_import(RenderContext::new(ctx), import))
+ .map(|builder| builder.build()),
);
Some(())
}
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs
index 13e0504..43428f7 100644
--- a/crates/ide_completion/src/completions/trait_impl.rs
+++ b/crates/ide_completion/src/completions/trait_impl.rs
@@ -167,7 +167,7 @@
};
let mut item = CompletionItem::new(completion_kind, replacement_range, label);
- item.lookup_by(fn_name)
+ item.lookup_by(format!("fn {}", fn_name))
.set_documentation(func.docs(ctx.db))
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
@@ -228,13 +228,17 @@
let alias_name = type_alias.name(ctx.db).to_smol_str();
let label = format!("type {} =", alias_name);
- let snippet = format!("type {} = ", alias_name);
+ let replacement = format!("type {} = ", alias_name);
let mut item = CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label);
- item.text_edit(TextEdit::replace(replacement_range, snippet))
- .lookup_by(alias_name)
+ item.lookup_by(format!("type {}", alias_name))
.set_documentation(type_alias.docs(ctx.db))
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
+ match ctx.config.snippet_cap {
+ Some(cap) => item
+ .snippet_edit(cap, TextEdit::replace(replacement_range, format!("{}$0;", replacement))),
+ None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
+ };
item.add_to(acc);
}
@@ -257,16 +261,22 @@
};
let label = make_const_compl_syntax(&transformed_const);
- let snippet = format!("{} ", label);
+ let replacement = format!("{} ", label);
let mut item = CompletionItem::new(SymbolKind::Const, replacement_range, label);
- item.text_edit(TextEdit::replace(replacement_range, snippet))
- .lookup_by(const_name)
+ item.lookup_by(format!("const {}", const_name))
.set_documentation(const_.docs(ctx.db))
.set_relevance(CompletionRelevance {
is_item_from_trait: true,
..Default::default()
});
+ match ctx.config.snippet_cap {
+ Some(cap) => item.snippet_edit(
+ cap,
+ TextEdit::replace(replacement_range, format!("{}$0;", replacement)),
+ ),
+ None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
+ };
item.add_to(acc);
}
}
@@ -549,7 +559,7 @@
#[test]
fn name_ref_single_function() {
check_edit(
- "test",
+ "fn test",
r#"
trait Test {
fn test();
@@ -578,7 +588,7 @@
#[test]
fn single_function() {
check_edit(
- "test",
+ "fn test",
r#"
trait Test {
fn test();
@@ -607,7 +617,7 @@
#[test]
fn generic_fn() {
check_edit(
- "foo",
+ "fn foo",
r#"
trait Test {
fn foo<T>();
@@ -632,7 +642,7 @@
"#,
);
check_edit(
- "foo",
+ "fn foo",
r#"
trait Test {
fn foo<T>() where T: Into<String>;
@@ -662,7 +672,7 @@
#[test]
fn associated_type() {
check_edit(
- "SomeType",
+ "type SomeType",
r#"
trait Test {
type SomeType;
@@ -678,7 +688,7 @@
}
impl Test for () {
- type SomeType = \n\
+ type SomeType = $0;\n\
}
",
);
@@ -687,7 +697,7 @@
#[test]
fn associated_const() {
check_edit(
- "SOME_CONST",
+ "const SOME_CONST",
r#"
trait Test {
const SOME_CONST: u16;
@@ -703,13 +713,13 @@
}
impl Test for () {
- const SOME_CONST: u16 = \n\
+ const SOME_CONST: u16 = $0;\n\
}
",
);
check_edit(
- "SOME_CONST",
+ "const SOME_CONST",
r#"
trait Test {
const SOME_CONST: u16 = 92;
@@ -725,7 +735,7 @@
}
impl Test for () {
- const SOME_CONST: u16 = \n\
+ const SOME_CONST: u16 = $0;\n\
}
",
);
@@ -783,9 +793,9 @@
"default type OtherType = i32;",
"default const OTHER_CONST: i32 = 0;",
] {
- test("bar", "fn $0", "fn bar() {\n $0\n}", next_sibling);
- test("Foo", "type $0", "type Foo = ", next_sibling);
- test("CONST", "const $0", "const CONST: u16 = ", next_sibling);
+ test("fn bar", "fn $0", "fn bar() {\n $0\n}", next_sibling);
+ test("type Foo", "type $0", "type Foo = $0;", next_sibling);
+ test("const CONST", "const $0", "const CONST: u16 = $0;", next_sibling);
}
}
@@ -830,15 +840,15 @@
),
)
};
- test("function", "fn f$0", "fn function() {\n $0\n}");
- test("Type", "type T$0", "type Type = ");
- test("CONST", "const C$0", "const CONST: i32 = ");
+ test("fn function", "fn f$0", "fn function() {\n $0\n}");
+ test("type Type", "type T$0", "type Type = $0;");
+ test("const CONST", "const C$0", "const CONST: i32 = $0;");
}
#[test]
fn generics_are_inlined_in_return_type() {
check_edit(
- "function",
+ "fn function",
r#"
trait Foo<T> {
fn function() -> T;
@@ -867,7 +877,7 @@
#[test]
fn generics_are_inlined_in_parameter() {
check_edit(
- "function",
+ "fn function",
r#"
trait Foo<T> {
fn function(bar: T);
@@ -896,7 +906,7 @@
#[test]
fn generics_are_inlined_when_part_of_other_types() {
check_edit(
- "function",
+ "fn function",
r#"
trait Foo<T> {
fn function(bar: Vec<T>);
@@ -925,7 +935,7 @@
#[test]
fn generics_are_inlined_complex() {
check_edit(
- "function",
+ "fn function",
r#"
trait Foo<T, U, V> {
fn function(bar: Vec<T>, baz: U) -> Arc<Vec<V>>;
@@ -954,7 +964,7 @@
#[test]
fn generics_are_inlined_in_associated_const() {
check_edit(
- "BAR",
+ "const BAR",
r#"
trait Foo<T> {
const BAR: T;
@@ -962,7 +972,7 @@
struct Bar;
impl Foo<u32> for Bar {
- const B$0;
+ const B$0
}
"#,
r#"
@@ -972,7 +982,7 @@
struct Bar;
impl Foo<u32> for Bar {
- const BAR: u32 = ;
+ const BAR: u32 = $0;
}
"#,
)
@@ -981,7 +991,7 @@
#[test]
fn generics_are_inlined_in_where_clause() {
check_edit(
- "function",
+ "fn function",
r#"
trait SomeTrait<T> {}
diff --git a/crates/ide_completion/src/completions/use_.rs b/crates/ide_completion/src/completions/use_.rs
index d7c279f..3f757f9 100644
--- a/crates/ide_completion/src/completions/use_.rs
+++ b/crates/ide_completion/src/completions/use_.rs
@@ -1,11 +1,13 @@
//! Completion for use trees
use hir::ScopeDef;
+use rustc_hash::FxHashSet;
use syntax::{ast, AstNode};
use crate::{
context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx},
- Completions,
+ item::Builder,
+ CompletionRelevance, Completions,
};
pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext) {
@@ -39,6 +41,22 @@
None => return,
};
+ let mut already_imported_names = FxHashSet::default();
+ if let Some(list) = ctx.token.ancestors().find_map(ast::UseTreeList::cast) {
+ let use_tree = list.parent_use_tree();
+ if use_tree.path().as_ref() == Some(path) {
+ for tree in list.use_trees() {
+ if tree.is_simple_path() {
+ if let Some(name) =
+ tree.path().and_then(|path| path.as_single_name_ref())
+ {
+ already_imported_names.insert(name.to_string());
+ }
+ }
+ }
+ }
+ }
+
match resolution {
hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
let module_scope = module.scope(ctx.db, Some(ctx.module));
@@ -50,6 +68,9 @@
)
};
for (name, def) in module_scope {
+ let is_name_already_imported =
+ already_imported_names.contains(name.as_text().unwrap().as_str());
+
let add_resolution = match def {
ScopeDef::Unknown if unknown_is_current(&name) => {
// for `use self::foo$0`, don't suggest `foo` as a completion
@@ -61,7 +82,12 @@
};
if add_resolution {
- acc.add_resolution(ctx, name, def);
+ let mut builder = Builder::from_resolution(ctx, name, def);
+ builder.set_relevance(CompletionRelevance {
+ is_name_already_imported,
+ ..Default::default()
+ });
+ acc.add(builder.build());
}
}
}
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 2fa8f77..41fae38 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -9,6 +9,11 @@
use syntax::{SmolStr, TextRange};
use text_edit::TextEdit;
+use crate::{
+ context::CompletionContext,
+ render::{render_resolution, RenderContext},
+};
+
/// `CompletionItem` describes a single completion variant in the editor pop-up.
/// It is basically a POD with various properties. To construct a
/// `CompletionItem`, use `new` method and the `Builder` struct.
@@ -134,6 +139,8 @@
pub is_local: bool,
/// This is set when trait items are completed in an impl of that trait.
pub is_item_from_trait: bool,
+ /// This is set when an import is suggested whose name is already imported.
+ pub is_name_already_imported: bool,
/// Set for method completions of the `core::ops` and `core::cmp` family.
pub is_op_method: bool,
/// Set for item completions that are private but in the workspace.
@@ -200,6 +207,7 @@
type_match,
is_local,
is_item_from_trait,
+ is_name_already_imported,
is_op_method,
is_private_editable,
postfix_match,
@@ -214,6 +222,10 @@
if !is_op_method {
score += 10;
}
+ // lower rank for conflicting import names
+ if !is_name_already_imported {
+ score += 1;
+ }
if exact_name_match {
score += 10;
}
@@ -324,7 +336,7 @@
kind: kind.into(),
text_edit: None,
deprecated: false,
- trigger_call_info: None,
+ trigger_call_info: false,
relevance: CompletionRelevance::default(),
ref_match: None,
imports_to_add: Default::default(),
@@ -407,12 +419,20 @@
kind: CompletionItemKind,
text_edit: Option<TextEdit>,
deprecated: bool,
- trigger_call_info: Option<bool>,
+ trigger_call_info: bool,
relevance: CompletionRelevance,
ref_match: Option<Mutability>,
}
impl Builder {
+ pub(crate) fn from_resolution(
+ ctx: &CompletionContext,
+ local_name: hir::Name,
+ resolution: hir::ScopeDef,
+ ) -> Self {
+ render_resolution(RenderContext::new(ctx), local_name, resolution)
+ }
+
pub(crate) fn build(self) -> CompletionItem {
let _p = profile::span("item::Builder::build");
@@ -445,7 +465,7 @@
lookup,
kind: self.kind,
deprecated: self.deprecated,
- trigger_call_info: self.trigger_call_info.unwrap_or(false),
+ trigger_call_info: self.trigger_call_info,
relevance: self.relevance,
ref_match: self.ref_match,
import_to_add: self.imports_to_add,
@@ -513,7 +533,7 @@
self
}
pub(crate) fn trigger_call_info(&mut self) -> &mut Builder {
- self.trigger_call_info = Some(true);
+ self.trigger_call_info = true;
self
}
pub(crate) fn add_import(&mut self, import_to_add: LocatedImport) -> &mut Builder {
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 5b0257f..810ef63 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -18,7 +18,7 @@
use crate::{
context::{PathCompletionCtx, PathKind},
- item::CompletionRelevanceTypeMatch,
+ item::{Builder, CompletionRelevanceTypeMatch},
render::{function::render_fn, literal::render_variant_lit, macro_::render_macro},
CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
};
@@ -144,7 +144,7 @@
ctx: RenderContext<'_>,
local_name: hir::Name,
resolution: ScopeDef,
-) -> CompletionItem {
+) -> Builder {
render_resolution_(ctx, local_name, None, resolution)
}
@@ -152,14 +152,14 @@
ctx: RenderContext<'_>,
local_name: hir::Name,
resolution: ScopeDef,
-) -> CompletionItem {
+) -> Builder {
render_resolution_simple_(ctx, local_name, None, resolution)
}
pub(crate) fn render_resolution_with_import(
ctx: RenderContext<'_>,
import_edit: LocatedImport,
-) -> Option<CompletionItem> {
+) -> Option<Builder> {
let resolution = ScopeDef::from(import_edit.original_item);
let local_name = match resolution {
ScopeDef::ModuleDef(hir::ModuleDef::Function(f)) => f.name(ctx.completion.db),
@@ -182,7 +182,7 @@
local_name: hir::Name,
import_to_add: Option<LocatedImport>,
resolution: ScopeDef,
-) -> CompletionItem {
+) -> Builder {
let _p = profile::span("render_resolution");
use hir::ModuleDef::*;
@@ -211,7 +211,7 @@
local_name: hir::Name,
import_to_add: Option<LocatedImport>,
resolution: ScopeDef,
-) -> CompletionItem {
+) -> Builder {
let _p = profile::span("render_resolution");
use hir::ModuleDef::*;
@@ -292,7 +292,7 @@
if let Some(import_to_add) = ctx.import_to_add {
item.add_import(import_to_add);
}
- item.build()
+ item
}
fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<hir::Documentation> {
@@ -625,6 +625,7 @@
),
is_local: false,
is_item_from_trait: false,
+ is_name_already_imported: false,
is_op_method: false,
is_private_editable: false,
postfix_match: None,
@@ -648,6 +649,7 @@
),
is_local: false,
is_item_from_trait: false,
+ is_name_already_imported: false,
is_op_method: false,
is_private_editable: false,
postfix_match: None,
@@ -737,6 +739,7 @@
),
is_local: false,
is_item_from_trait: false,
+ is_name_already_imported: false,
is_op_method: false,
is_private_editable: false,
postfix_match: None,
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 211aa43..38520e1 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -22,7 +22,7 @@
ctx: RenderContext<'_>,
local_name: Option<hir::Name>,
func: hir::Function,
-) -> CompletionItem {
+) -> Builder {
let _p = profile::span("render_fn");
render(ctx, local_name, func, FuncKind::Function)
}
@@ -32,7 +32,7 @@
receiver: Option<hir::Name>,
local_name: Option<hir::Name>,
func: hir::Function,
-) -> CompletionItem {
+) -> Builder {
let _p = profile::span("render_method");
render(ctx, local_name, func, FuncKind::Method(receiver))
}
@@ -42,7 +42,7 @@
local_name: Option<hir::Name>,
func: hir::Function,
func_kind: FuncKind,
-) -> CompletionItem {
+) -> Builder {
let db = completion.db;
let name = local_name.unwrap_or_else(|| func.name(db));
@@ -107,7 +107,7 @@
}
}
}
- item.build()
+ item
}
pub(super) fn add_call_parens<'b>(
diff --git a/crates/ide_completion/src/render/literal.rs b/crates/ide_completion/src/render/literal.rs
index e656317..f177313 100644
--- a/crates/ide_completion/src/render/literal.rs
+++ b/crates/ide_completion/src/render/literal.rs
@@ -5,7 +5,7 @@
use crate::{
context::{CompletionContext, PathCompletionCtx},
- item::CompletionItem,
+ item::{Builder, CompletionItem},
render::{
compute_ref_match, compute_type_match,
variant::{
@@ -22,7 +22,7 @@
local_name: Option<hir::Name>,
variant: hir::Variant,
path: Option<hir::ModPath>,
-) -> Option<CompletionItem> {
+) -> Option<Builder> {
let _p = profile::span("render_enum_variant");
let db = ctx.db();
@@ -35,7 +35,7 @@
strukt: hir::Struct,
path: Option<hir::ModPath>,
local_name: Option<hir::Name>,
-) -> Option<CompletionItem> {
+) -> Option<Builder> {
let _p = profile::span("render_struct_literal");
let db = ctx.db();
@@ -48,7 +48,7 @@
thing: Variant,
name: hir::Name,
path: Option<hir::ModPath>,
-) -> Option<CompletionItem> {
+) -> Option<Builder> {
let db = completion.db;
let kind = thing.kind(db);
let has_call_parens =
@@ -112,7 +112,7 @@
if let Some(import_to_add) = ctx.import_to_add {
item.add_import(import_to_add);
}
- Some(item.build())
+ Some(item)
}
#[derive(Clone, Copy)]
diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs
index 9f848fe..ba18e5d 100644
--- a/crates/ide_completion/src/render/macro_.rs
+++ b/crates/ide_completion/src/render/macro_.rs
@@ -4,13 +4,13 @@
use ide_db::SymbolKind;
use syntax::SmolStr;
-use crate::{context::PathKind, item::CompletionItem, render::RenderContext};
+use crate::{
+ context::PathKind,
+ item::{Builder, CompletionItem},
+ render::RenderContext,
+};
-pub(crate) fn render_macro(
- ctx: RenderContext<'_>,
- name: hir::Name,
- macro_: hir::Macro,
-) -> CompletionItem {
+pub(crate) fn render_macro(ctx: RenderContext<'_>, name: hir::Name, macro_: hir::Macro) -> Builder {
let _p = profile::span("render_macro");
render(ctx, name, macro_)
}
@@ -19,7 +19,7 @@
ctx @ RenderContext { completion, .. }: RenderContext<'_>,
name: hir::Name,
macro_: hir::Macro,
-) -> CompletionItem {
+) -> Builder {
let source_range = if completion.is_immediately_after_macro_bang() {
cov_mark::hit!(completes_macro_call_if_cursor_at_bang_token);
completion.token.parent().map_or_else(|| ctx.source_range(), |it| it.text_range())
@@ -66,7 +66,7 @@
item.add_import(import_to_add);
}
- item.build()
+ item
}
fn label(
diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs
index 13234a8..5899754 100644
--- a/crates/ide_db/src/rename.rs
+++ b/crates/ide_db/src/rename.rs
@@ -178,17 +178,23 @@
let mut source_change = SourceChange::default();
let InFile { file_id, value: def_source } = module.definition_source(sema.db);
- let file_id = file_id.original_file(sema.db);
if let ModuleSource::SourceFile(..) = def_source {
- // mod is defined in path/to/dir/mod.rs
- let path = if module.is_mod_rs(sema.db) {
- format!("../{}/mod.rs", new_name)
- } else {
- format!("{}.rs", new_name)
- };
- let dst = AnchoredPathBuf { anchor: file_id, path };
- let move_file = FileSystemEdit::MoveFile { src: file_id, dst };
- source_change.push_file_system_edit(move_file);
+ let anchor = file_id.original_file(sema.db);
+ // not mod.rs and doesn't has children, rename file only
+ if !module.is_mod_rs(sema.db) && module.children(sema.db).next().is_none() {
+ let path = format!("{}.rs", new_name);
+ let dst = AnchoredPathBuf { anchor, path };
+ source_change.push_file_system_edit(FileSystemEdit::MoveFile { src: anchor, dst })
+ } else if let Some(mod_name) = module.name(sema.db) {
+ // is mod.rs or has children, rename dir
+ let src = AnchoredPathBuf { anchor, path: mod_name.to_string() };
+ let dst = AnchoredPathBuf { anchor, path: new_name.to_string() };
+ source_change.push_file_system_edit(FileSystemEdit::MoveDir {
+ src,
+ src_id: anchor,
+ dst,
+ })
+ }
}
if let Some(src) = module.declaration_source(sema.db) {
diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs
index aa910eb..8132c73 100644
--- a/crates/ide_db/src/source_change.rs
+++ b/crates/ide_db/src/source_change.rs
@@ -85,6 +85,7 @@
pub enum FileSystemEdit {
CreateFile { dst: AnchoredPathBuf, initial_contents: String },
MoveFile { src: FileId, dst: AnchoredPathBuf },
+ MoveDir { src: AnchoredPathBuf, src_id: FileId, dst: AnchoredPathBuf },
}
impl From<FileSystemEdit> for SourceChange {
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 0588f00..3d83f09 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -866,6 +866,20 @@
rename_file,
)))
}
+ FileSystemEdit::MoveDir { src, src_id, dst } => {
+ let old_uri = snap.anchored_path(&src);
+ let new_uri = snap.anchored_path(&dst);
+ let mut rename_file =
+ lsp_types::RenameFile { old_uri, new_uri, options: None, annotation_id: None };
+ if snap.analysis.is_library_file(src_id).ok() == Some(true)
+ && snap.config.change_annotation_support()
+ {
+ rename_file.annotation_id = Some(outside_workspace_annotation_id())
+ }
+ ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename(
+ rename_file,
+ )))
+ }
}
Ok(ops)
}