Skip to content

Commit d9666ce

Browse files
bors[bot]Veykril
andauthored
9334: feat: Allow to disable import insertion on single path glob imports r=Veykril a=Veykril On by default as I feel like this is something the majority would prefer. Closes rust-lang#8490 Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 4f6301b + 2ee090f commit d9666ce

File tree

14 files changed

+99
-17
lines changed

14 files changed

+99
-17
lines changed

crates/ide_assists/src/handlers/auto_import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
104104
ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
105105
ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
106106
};
107-
insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use);
107+
insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
108108
},
109109
);
110110
}

crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ fn apply_references(
236236
import: Option<(ImportScope, hir::ModPath)>,
237237
) {
238238
if let Some((scope, path)) = import {
239-
insert_use(&scope, mod_path_to_ast(&path), insert_use_cfg);
239+
insert_use(&scope, mod_path_to_ast(&path), &insert_use_cfg);
240240
}
241241
// deep clone to prevent cycle
242242
let path = make::path_from_segments(iter::once(segment.clone_subtree()), false);

crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub(crate) fn replace_qualified_name_with_use(
4343
let syntax = builder.make_syntax_mut(syntax.clone());
4444
if let Some(ref import_scope) = ImportScope::from(syntax.clone()) {
4545
shorten_paths(&syntax, &path.clone_for_update());
46-
insert_use(import_scope, path, ctx.config.insert_use);
46+
insert_use(import_scope, path, &ctx.config.insert_use);
4747
}
4848
},
4949
)

crates/ide_assists/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
2828
prefix_kind: hir::PrefixKind::Plain,
2929
enforce_granularity: true,
3030
group: true,
31+
skip_glob_imports: true,
3132
},
3233
};
3334

crates/ide_completion/src/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ impl ImportEdit {
378378
let _p = profile::span("ImportEdit::to_text_edit");
379379

380380
let new_ast = self.scope.clone_for_update();
381-
insert_use::insert_use(&new_ast, mod_path_to_ast(&self.import.import_path), cfg);
381+
insert_use::insert_use(&new_ast, mod_path_to_ast(&self.import.import_path), &cfg);
382382
let mut import_insert = TextEdit::builder();
383383
algo::diff(self.scope.as_syntax_node(), new_ast.as_syntax_node())
384384
.into_text_edit(&mut import_insert);

crates/ide_completion/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
3636
prefix_kind: PrefixKind::Plain,
3737
enforce_granularity: true,
3838
group: true,
39+
skip_glob_imports: true,
3940
},
4041
};
4142

crates/ide_db/src/helpers/insert_use.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct InsertUseConfig {
3636
pub enforce_granularity: bool,
3737
pub prefix_kind: PrefixKind,
3838
pub group: bool,
39+
pub skip_glob_imports: bool,
3940
}
4041

4142
#[derive(Debug, Clone)]
@@ -153,7 +154,7 @@ enum ImportGranularityGuess {
153154
}
154155

155156
/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
156-
pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig) {
157+
pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
157158
let _p = profile::span("insert_use");
158159
let mut mb = match cfg.granularity {
159160
ImportGranularity::Crate => Some(MergeBehavior::Crate),
@@ -175,7 +176,10 @@ pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig
175176
make::use_(None, make::use_tree(path.clone(), None, None, false)).clone_for_update();
176177
// merge into existing imports if possible
177178
if let Some(mb) = mb {
178-
for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) {
179+
let filter = |it: &_| !(cfg.skip_glob_imports && ast::Use::is_simple_glob(it));
180+
for existing_use in
181+
scope.as_syntax_node().children().filter_map(ast::Use::cast).filter(filter)
182+
{
179183
if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) {
180184
ted::replace(existing_use.syntax(), merged.syntax());
181185
return;

crates/ide_db/src/helpers/insert_use/tests.rs

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@ use super::*;
33
use hir::PrefixKind;
44
use test_utils::assert_eq_text;
55

6+
#[test]
7+
fn insert_skips_lone_glob_imports() {
8+
check(
9+
"use foo::baz::A",
10+
r"
11+
use foo::bar::*;
12+
",
13+
r"
14+
use foo::bar::*;
15+
use foo::baz::A;
16+
",
17+
ImportGranularity::Crate,
18+
false,
19+
false,
20+
);
21+
}
22+
623
#[test]
724
fn insert_not_group() {
825
cov_mark::check!(insert_no_grouping_last);
@@ -534,17 +551,37 @@ fn merge_groups_self() {
534551

535552
#[test]
536553
fn merge_mod_into_glob() {
537-
check_crate(
554+
check_with_config(
538555
"token::TokenKind",
539556
r"use token::TokenKind::*;",
540557
r"use token::TokenKind::{*, self};",
558+
false,
559+
&InsertUseConfig {
560+
granularity: ImportGranularity::Crate,
561+
enforce_granularity: true,
562+
prefix_kind: PrefixKind::Plain,
563+
group: false,
564+
skip_glob_imports: false,
565+
},
541566
)
542567
// FIXME: have it emit `use token::TokenKind::{self, *}`?
543568
}
544569

545570
#[test]
546571
fn merge_self_glob() {
547-
check_crate("self", r"use self::*;", r"use self::{*, self};")
572+
check_with_config(
573+
"self",
574+
r"use self::*;",
575+
r"use self::{*, self};",
576+
false,
577+
&InsertUseConfig {
578+
granularity: ImportGranularity::Crate,
579+
enforce_granularity: true,
580+
prefix_kind: PrefixKind::Plain,
581+
group: false,
582+
skip_glob_imports: false,
583+
},
584+
)
548585
// FIXME: have it emit `use {self, *}`?
549586
}
550587

@@ -757,13 +794,12 @@ use foo::bar::qux;
757794
);
758795
}
759796

760-
fn check(
797+
fn check_with_config(
761798
path: &str,
762799
ra_fixture_before: &str,
763800
ra_fixture_after: &str,
764-
granularity: ImportGranularity,
765801
module: bool,
766-
group: bool,
802+
config: &InsertUseConfig,
767803
) {
768804
let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone();
769805
if module {
@@ -777,18 +813,32 @@ fn check(
777813
.find_map(ast::Path::cast)
778814
.unwrap();
779815

780-
insert_use(
781-
&file,
816+
insert_use(&file, path, config);
817+
let result = file.as_syntax_node().to_string();
818+
assert_eq_text!(ra_fixture_after, &result);
819+
}
820+
821+
fn check(
822+
path: &str,
823+
ra_fixture_before: &str,
824+
ra_fixture_after: &str,
825+
granularity: ImportGranularity,
826+
module: bool,
827+
group: bool,
828+
) {
829+
check_with_config(
782830
path,
783-
InsertUseConfig {
831+
ra_fixture_before,
832+
ra_fixture_after,
833+
module,
834+
&InsertUseConfig {
784835
granularity,
785836
enforce_granularity: true,
786837
prefix_kind: PrefixKind::Plain,
787838
group,
839+
skip_glob_imports: true,
788840
},
789-
);
790-
let result = file.as_syntax_node().to_string();
791-
assert_eq_text!(ra_fixture_after, &result);
841+
)
792842
}
793843

794844
fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {

crates/rust-analyzer/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ config_data! {
4444
assist_importPrefix: ImportPrefixDef = "\"plain\"",
4545
/// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
4646
assist_importGroup: bool = "true",
47+
/// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
48+
assist_allowMergingIntoGlobImports: bool = "true",
49+
4750
/// Show function name and docs in parameter hints.
4851
callInfo_full: bool = "true",
4952

@@ -672,6 +675,7 @@ impl Config {
672675
ImportPrefixDef::BySelf => PrefixKind::BySelf,
673676
},
674677
group: self.data.assist_importGroup,
678+
skip_glob_imports: !self.data.assist_allowMergingIntoGlobImports,
675679
}
676680
}
677681
pub fn completion(&self) -> CompletionConfig {

crates/rust-analyzer/src/integrated_benchmarks.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ fn integrated_completion_benchmark() {
143143
prefix_kind: hir::PrefixKind::ByCrate,
144144
enforce_granularity: true,
145145
group: true,
146+
skip_glob_imports: true,
146147
},
147148
};
148149
let position =
@@ -178,6 +179,7 @@ fn integrated_completion_benchmark() {
178179
prefix_kind: hir::PrefixKind::ByCrate,
179180
enforce_granularity: true,
180181
group: true,
182+
skip_glob_imports: true,
181183
},
182184
};
183185
let position =

0 commit comments

Comments
 (0)