Skip to content

Commit 56ce7e0

Browse files
committed
Auto merge of #17252 - davidbarsky:david/refactor-standalone-bools-into-struct, r=Veykril
internal: refactor `prefer_no_std`/`prefer_prelude` bools into a struct I noticed that there's a large number of functions/arguments during an unrelated change that take two booleans and realized they're _probably_ better off being in a single struct—less error-prone, etc. Feel free to suggest a better name than `ImportPathConfig`/close this entirely! I can also make these args enums; just hopefully making this a little more misuse-resistant.
2 parents ad810a5 + f50f8fb commit 56ce7e0

37 files changed

+313
-365
lines changed

src/tools/rust-analyzer/crates/hir-def/src/find_path.rs

+29-42
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//! An algorithm to find a path to refer to a certain item.
22
3-
use std::{
4-
cmp::Ordering,
5-
iter::{self, once},
6-
};
3+
use std::{cmp::Ordering, iter};
74

85
use hir_expand::{
96
name::{known, AsName, Name},
@@ -17,7 +14,7 @@ use crate::{
1714
nameres::DefMap,
1815
path::{ModPath, PathKind},
1916
visibility::{Visibility, VisibilityExplicitness},
20-
ModuleDefId, ModuleId,
17+
ImportPathConfig, ModuleDefId, ModuleId,
2118
};
2219

2320
/// Find a path that can be used to refer to a certain item. This can depend on
@@ -28,21 +25,10 @@ pub fn find_path(
2825
from: ModuleId,
2926
prefix_kind: PrefixKind,
3027
ignore_local_imports: bool,
31-
prefer_no_std: bool,
32-
prefer_prelude: bool,
28+
cfg: ImportPathConfig,
3329
) -> Option<ModPath> {
3430
let _p = tracing::span!(tracing::Level::INFO, "find_path").entered();
35-
find_path_inner(
36-
FindPathCtx {
37-
db,
38-
prefix: prefix_kind,
39-
prefer_no_std,
40-
prefer_prelude,
41-
ignore_local_imports,
42-
},
43-
item,
44-
from,
45-
)
31+
find_path_inner(FindPathCtx { db, prefix: prefix_kind, cfg, ignore_local_imports }, item, from)
4632
}
4733

4834
#[derive(Copy, Clone, Debug)]
@@ -88,16 +74,15 @@ impl PrefixKind {
8874
struct FindPathCtx<'db> {
8975
db: &'db dyn DefDatabase,
9076
prefix: PrefixKind,
91-
prefer_no_std: bool,
92-
prefer_prelude: bool,
77+
cfg: ImportPathConfig,
9378
ignore_local_imports: bool,
9479
}
9580

9681
/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId
9782
fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
9883
// - if the item is a builtin, it's in scope
9984
if let ItemInNs::Types(ModuleDefId::BuiltinType(builtin)) = item {
100-
return Some(ModPath::from_segments(PathKind::Plain, once(builtin.as_name())));
85+
return Some(ModPath::from_segments(PathKind::Plain, iter::once(builtin.as_name())));
10186
}
10287

10388
let def_map = from.def_map(ctx.db);
@@ -107,7 +92,11 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
10792
let mut visited_modules = FxHashSet::default();
10893
return find_path_for_module(
10994
FindPathCtx {
110-
prefer_no_std: ctx.prefer_no_std || ctx.db.crate_supports_no_std(crate_root.krate),
95+
cfg: ImportPathConfig {
96+
prefer_no_std: ctx.cfg.prefer_no_std
97+
|| ctx.db.crate_supports_no_std(crate_root.krate),
98+
..ctx.cfg
99+
},
111100
..ctx
112101
},
113102
&def_map,
@@ -132,7 +121,7 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
132121
// - if the item is already in scope, return the name under which it is
133122
let scope_name = find_in_scope(ctx.db, &def_map, from, item, ctx.ignore_local_imports);
134123
if let Some(scope_name) = scope_name {
135-
return Some(ModPath::from_segments(prefix.path_kind(), Some(scope_name)));
124+
return Some(ModPath::from_segments(prefix.path_kind(), iter::once(scope_name)));
136125
}
137126
}
138127

@@ -160,7 +149,11 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
160149

161150
calculate_best_path(
162151
FindPathCtx {
163-
prefer_no_std: ctx.prefer_no_std || ctx.db.crate_supports_no_std(crate_root.krate),
152+
cfg: ImportPathConfig {
153+
prefer_no_std: ctx.cfg.prefer_no_std
154+
|| ctx.db.crate_supports_no_std(crate_root.krate),
155+
..ctx.cfg
156+
},
164157
..ctx
165158
},
166159
&def_map,
@@ -213,7 +206,7 @@ fn find_path_for_module(
213206
} else {
214207
PathKind::Plain
215208
};
216-
return Some((ModPath::from_segments(kind, once(name.clone())), Stable));
209+
return Some((ModPath::from_segments(kind, iter::once(name.clone())), Stable));
217210
}
218211
}
219212
let prefix = if module_id.is_within_block() { PrefixKind::Plain } else { ctx.prefix };
@@ -231,7 +224,10 @@ fn find_path_for_module(
231224
);
232225
if let Some(scope_name) = scope_name {
233226
// - if the item is already in scope, return the name under which it is
234-
return Some((ModPath::from_segments(prefix.path_kind(), once(scope_name)), Stable));
227+
return Some((
228+
ModPath::from_segments(prefix.path_kind(), iter::once(scope_name)),
229+
Stable,
230+
));
235231
}
236232
}
237233

@@ -305,7 +301,7 @@ fn find_in_prelude(
305301
});
306302

307303
if found_and_same_def.unwrap_or(true) {
308-
Some(ModPath::from_segments(PathKind::Plain, once(name.clone())))
304+
Some(ModPath::from_segments(PathKind::Plain, iter::once(name.clone())))
309305
} else {
310306
None
311307
}
@@ -381,9 +377,7 @@ fn calculate_best_path(
381377
path.0.push_segment(name);
382378

383379
let new_path = match best_path.take() {
384-
Some(best_path) => {
385-
select_best_path(best_path, path, ctx.prefer_no_std, ctx.prefer_prelude)
386-
}
380+
Some(best_path) => select_best_path(best_path, path, ctx.cfg),
387381
None => path,
388382
};
389383
best_path_len = new_path.0.len();
@@ -425,12 +419,7 @@ fn calculate_best_path(
425419
);
426420

427421
let new_path_with_stab = match best_path.take() {
428-
Some(best_path) => select_best_path(
429-
best_path,
430-
path_with_stab,
431-
ctx.prefer_no_std,
432-
ctx.prefer_prelude,
433-
),
422+
Some(best_path) => select_best_path(best_path, path_with_stab, ctx.cfg),
434423
None => path_with_stab,
435424
};
436425
update_best_path(&mut best_path, new_path_with_stab);
@@ -446,8 +435,7 @@ fn calculate_best_path(
446435
fn select_best_path(
447436
old_path @ (_, old_stability): (ModPath, Stability),
448437
new_path @ (_, new_stability): (ModPath, Stability),
449-
prefer_no_std: bool,
450-
prefer_prelude: bool,
438+
cfg: ImportPathConfig,
451439
) -> (ModPath, Stability) {
452440
match (old_stability, new_stability) {
453441
(Stable, Unstable) => return old_path,
@@ -461,7 +449,7 @@ fn select_best_path(
461449
let (old_path, _) = &old;
462450
let new_has_prelude = new_path.segments().iter().any(|seg| seg == &known::prelude);
463451
let old_has_prelude = old_path.segments().iter().any(|seg| seg == &known::prelude);
464-
match (new_has_prelude, old_has_prelude, prefer_prelude) {
452+
match (new_has_prelude, old_has_prelude, cfg.prefer_prelude) {
465453
(true, false, true) | (false, true, false) => new,
466454
(true, false, false) | (false, true, true) => old,
467455
// no prelude difference in the paths, so pick the shorter one
@@ -482,7 +470,7 @@ fn select_best_path(
482470

483471
match (old_path.0.segments().first(), new_path.0.segments().first()) {
484472
(Some(old), Some(new)) if STD_CRATES.contains(old) && STD_CRATES.contains(new) => {
485-
let rank = match prefer_no_std {
473+
let rank = match cfg.prefer_no_std {
486474
false => |name: &Name| match name {
487475
name if name == &known::core => 0,
488476
name if name == &known::alloc => 1,
@@ -647,10 +635,9 @@ mod tests {
647635
{
648636
let found_path = find_path_inner(
649637
FindPathCtx {
650-
prefer_no_std: false,
651638
db: &db,
652639
prefix,
653-
prefer_prelude,
640+
cfg: ImportPathConfig { prefer_no_std: false, prefer_prelude },
654641
ignore_local_imports,
655642
},
656643
resolved,

src/tools/rust-analyzer/crates/hir-def/src/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ use crate::{
108108

109109
type FxIndexMap<K, V> =
110110
indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
111+
/// A wrapper around two booleans, [`ImportPathConfig::prefer_no_std`] and [`ImportPathConfig::prefer_prelude`].
112+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
113+
pub struct ImportPathConfig {
114+
/// If true, prefer to unconditionally use imports of the `core` and `alloc` crate
115+
/// over the std.
116+
pub prefer_no_std: bool,
117+
/// If true, prefer import paths containing a prelude module.
118+
pub prefer_prelude: bool,
119+
}
111120

112121
#[derive(Debug)]
113122
pub struct ItemLoc<N: ItemTreeNode> {

src/tools/rust-analyzer/crates/hir-ty/src/display.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ use hir_def::{
2121
path::{Path, PathKind},
2222
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
2323
visibility::Visibility,
24-
HasModule, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId, TraitId,
24+
HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId,
25+
TraitId,
2526
};
2627
use hir_expand::name::Name;
2728
use intern::{Internable, Interned};
@@ -1001,8 +1002,7 @@ impl HirDisplay for Ty {
10011002
module_id,
10021003
PrefixKind::Plain,
10031004
false,
1004-
false,
1005-
true,
1005+
ImportPathConfig { prefer_no_std: false, prefer_prelude: true },
10061006
) {
10071007
write!(f, "{}", path.display(f.db.upcast()))?;
10081008
} else {

src/tools/rust-analyzer/crates/hir/src/lib.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ pub use {
122122
per_ns::Namespace,
123123
type_ref::{Mutability, TypeRef},
124124
visibility::Visibility,
125+
ImportPathConfig,
125126
// FIXME: This is here since some queries take it as input that are used
126127
// outside of hir.
127128
{AdtId, MacroId, ModuleDefId},
@@ -792,17 +793,15 @@ impl Module {
792793
self,
793794
db: &dyn DefDatabase,
794795
item: impl Into<ItemInNs>,
795-
prefer_no_std: bool,
796-
prefer_prelude: bool,
796+
cfg: ImportPathConfig,
797797
) -> Option<ModPath> {
798798
hir_def::find_path::find_path(
799799
db,
800800
item.into().into(),
801801
self.into(),
802802
PrefixKind::Plain,
803803
false,
804-
prefer_no_std,
805-
prefer_prelude,
804+
cfg,
806805
)
807806
}
808807

@@ -813,18 +812,9 @@ impl Module {
813812
db: &dyn DefDatabase,
814813
item: impl Into<ItemInNs>,
815814
prefix_kind: PrefixKind,
816-
prefer_no_std: bool,
817-
prefer_prelude: bool,
815+
cfg: ImportPathConfig,
818816
) -> Option<ModPath> {
819-
hir_def::find_path::find_path(
820-
db,
821-
item.into().into(),
822-
self.into(),
823-
prefix_kind,
824-
true,
825-
prefer_no_std,
826-
prefer_prelude,
827-
)
817+
hir_def::find_path::find_path(db, item.into().into(), self.into(), prefix_kind, true, cfg)
828818
}
829819
}
830820

0 commit comments

Comments
 (0)