Skip to content

Commit dd3f5e0

Browse files
committed
Auto merge of rust-lang#12168 - Veykril:completion-rev, r=Veykril
internal: Remove unqualified_path completions module
2 parents cc9ae2b + 0c4e23b commit dd3f5e0

File tree

15 files changed

+769
-732
lines changed

15 files changed

+769
-732
lines changed

crates/hir/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub use crate::{
8888
UnresolvedModule, UnresolvedProcMacro,
8989
},
9090
has_source::HasSource,
91-
semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo},
91+
semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo, VisibleTraits},
9292
};
9393

9494
// Be careful with these re-exports.

crates/hir/src/semantics.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1370,10 +1370,10 @@ impl<'a> SemanticsScope<'a> {
13701370
&self.resolver
13711371
}
13721372

1373-
/// Note: `FxHashSet<TraitId>` should be treated as an opaque type, passed into `Type
1374-
pub fn visible_traits(&self) -> FxHashSet<TraitId> {
1373+
/// Note: `VisibleTraits` should be treated as an opaque type, passed into `Type
1374+
pub fn visible_traits(&self) -> VisibleTraits {
13751375
let resolver = &self.resolver;
1376-
resolver.traits_in_scope(self.db.upcast())
1376+
VisibleTraits(resolver.traits_in_scope(self.db.upcast()))
13771377
}
13781378

13791379
pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
@@ -1424,3 +1424,5 @@ impl<'a> SemanticsScope<'a> {
14241424
)
14251425
}
14261426
}
1427+
1428+
pub struct VisibleTraits(pub FxHashSet<TraitId>);

crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,13 @@ fn is_ref_and_impls_iter_method(
148148
let ty = sema.type_of_expr(&expr_behind_ref)?.adjusted();
149149
let scope = sema.scope(iterable.syntax())?;
150150
let krate = scope.krate();
151-
let traits_in_scope = scope.visible_traits();
152151
let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?;
153152

154153
let has_wanted_method = ty
155154
.iterate_method_candidates(
156155
sema.db,
157156
&scope,
158-
&traits_in_scope,
157+
&scope.visible_traits().0,
159158
None,
160159
Some(&wanted_method),
161160
|func| {

crates/ide-assists/src/handlers/generate_is_empty_from_len.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,14 @@ fn get_impl_method(
9595

9696
let scope = ctx.sema.scope(impl_.syntax())?;
9797
let ty = impl_def.self_ty(db);
98-
let traits_in_scope = scope.visible_traits();
99-
ty.iterate_method_candidates(db, &scope, &traits_in_scope, None, Some(fn_name), |func| {
100-
Some(func)
101-
})
98+
ty.iterate_method_candidates(
99+
db,
100+
&scope,
101+
&scope.visible_traits().0,
102+
None,
103+
Some(fn_name),
104+
|func| Some(func),
105+
)
102106
}
103107

104108
#[cfg(test)]

crates/ide-completion/src/completions.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub(crate) mod lifetime;
1313
pub(crate) mod mod_;
1414
pub(crate) mod pattern;
1515
pub(crate) mod postfix;
16-
pub(crate) mod qualified_path;
1716
pub(crate) mod record;
1817
pub(crate) mod snippet;
1918
pub(crate) mod trait_impl;

crates/ide-completion/src/completions/dot.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,10 @@ fn complete_methods(
7878
mut f: impl FnMut(hir::Function),
7979
) {
8080
let mut seen_methods = FxHashSet::default();
81-
let mut traits_in_scope = ctx.scope.visible_traits();
82-
83-
// Remove drop from the environment as calling `Drop::drop` is not allowed
84-
if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
85-
cov_mark::hit!(dot_remove_drop_trait);
86-
traits_in_scope.remove(&drop_trait.into());
87-
}
88-
8981
receiver.iterate_method_candidates(
9082
ctx.db,
9183
&ctx.scope,
92-
&traits_in_scope,
84+
&ctx.traits_in_scope().0,
9385
Some(ctx.module),
9486
None,
9587
|func| {
@@ -758,7 +750,6 @@ fn main() {
758750

759751
#[test]
760752
fn postfix_drop_completion() {
761-
cov_mark::check!(dot_remove_drop_trait);
762753
cov_mark::check!(postfix_drop_completion);
763754
check_edit(
764755
"drop",

crates/ide-completion/src/completions/expr.rs

+136-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Completion of names from the current scope in expression position.
22
33
use hir::ScopeDef;
4+
use ide_db::FxHashSet;
45

56
use crate::{
67
context::{PathCompletionCtx, PathKind, PathQualifierCtx},
@@ -20,8 +21,129 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
2021
_ => return,
2122
};
2223

24+
let scope_def_applicable = |def| {
25+
use hir::{GenericParam::*, ModuleDef::*};
26+
match def {
27+
ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
28+
// Don't suggest attribute macros and derives.
29+
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
30+
_ => true,
31+
}
32+
};
33+
2334
match qualifier {
24-
Some(PathQualifierCtx { .. }) => return,
35+
Some(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
36+
if *is_infer_qualifier {
37+
ctx.traits_in_scope()
38+
.0
39+
.into_iter()
40+
.flat_map(|it| hir::Trait::from(it).items(ctx.sema.db))
41+
.for_each(|item| add_assoc_item(acc, ctx, item));
42+
return;
43+
}
44+
let resolution = match resolution {
45+
Some(it) => it,
46+
None => return,
47+
};
48+
// Add associated types on type parameters and `Self`.
49+
ctx.scope.assoc_type_shorthand_candidates(resolution, |_, alias| {
50+
acc.add_type_alias(ctx, alias);
51+
None::<()>
52+
});
53+
match resolution {
54+
hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
55+
let module_scope = module.scope(ctx.db, Some(ctx.module));
56+
for (name, def) in module_scope {
57+
if scope_def_applicable(def) {
58+
acc.add_resolution(ctx, name, def);
59+
}
60+
}
61+
}
62+
63+
hir::PathResolution::Def(
64+
def @ (hir::ModuleDef::Adt(_)
65+
| hir::ModuleDef::TypeAlias(_)
66+
| hir::ModuleDef::BuiltinType(_)),
67+
) => {
68+
if let &hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
69+
add_enum_variants(acc, ctx, e);
70+
}
71+
let ty = match def {
72+
hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
73+
hir::ModuleDef::TypeAlias(a) => {
74+
let ty = a.ty(ctx.db);
75+
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
76+
cov_mark::hit!(completes_variant_through_alias);
77+
add_enum_variants(acc, ctx, e);
78+
}
79+
ty
80+
}
81+
hir::ModuleDef::BuiltinType(builtin) => {
82+
cov_mark::hit!(completes_primitive_assoc_const);
83+
builtin.ty(ctx.db)
84+
}
85+
_ => unreachable!(),
86+
};
87+
88+
// XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
89+
// (where AssocType is defined on a trait, not an inherent impl)
90+
91+
ty.iterate_path_candidates(
92+
ctx.db,
93+
&ctx.scope,
94+
&ctx.traits_in_scope().0,
95+
Some(ctx.module),
96+
None,
97+
|item| {
98+
add_assoc_item(acc, ctx, item);
99+
None::<()>
100+
},
101+
);
102+
103+
// Iterate assoc types separately
104+
ty.iterate_assoc_items(ctx.db, ctx.krate, |item| {
105+
if let hir::AssocItem::TypeAlias(ty) = item {
106+
acc.add_type_alias(ctx, ty)
107+
}
108+
None::<()>
109+
});
110+
}
111+
hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
112+
// Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
113+
for item in t.items(ctx.db) {
114+
add_assoc_item(acc, ctx, item);
115+
}
116+
}
117+
hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
118+
let ty = match resolution {
119+
hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
120+
hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
121+
_ => return,
122+
};
123+
124+
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
125+
add_enum_variants(acc, ctx, e);
126+
}
127+
let mut seen = FxHashSet::default();
128+
ty.iterate_path_candidates(
129+
ctx.db,
130+
&ctx.scope,
131+
&ctx.traits_in_scope().0,
132+
Some(ctx.module),
133+
None,
134+
|item| {
135+
// We might iterate candidates of a trait multiple times here, so deduplicate
136+
// them.
137+
if seen.insert(item) {
138+
add_assoc_item(acc, ctx, item);
139+
}
140+
None::<()>
141+
},
142+
);
143+
}
144+
_ => (),
145+
}
146+
}
25147
None if is_absolute_path => acc.add_crate_roots(ctx),
26148
None => {
27149
acc.add_nameref_keywords_with_colon(ctx);
@@ -33,17 +155,22 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
33155
});
34156
}
35157
ctx.process_all_names(&mut |name, def| {
36-
use hir::{GenericParam::*, ModuleDef::*};
37-
let add_resolution = match def {
38-
ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
39-
// Don't suggest attribute macros and derives.
40-
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
41-
_ => true,
42-
};
43-
if add_resolution {
158+
if scope_def_applicable(def) {
44159
acc.add_resolution(ctx, name, def);
45160
}
46161
});
47162
}
48163
}
49164
}
165+
166+
fn add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem) {
167+
match item {
168+
hir::AssocItem::Function(func) => acc.add_function(ctx, func, None),
169+
hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
170+
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
171+
}
172+
}
173+
174+
fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum) {
175+
e.variants(ctx.db).into_iter().for_each(|variant| acc.add_enum_variant(ctx, variant, None));
176+
}

crates/ide-completion/src/completions/pattern.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,11 @@ fn pattern_path_completion(
163163
_ => return,
164164
};
165165

166-
let traits_in_scope = ctx.scope.visible_traits();
167166
let mut seen = FxHashSet::default();
168167
ty.iterate_path_candidates(
169168
ctx.db,
170169
&ctx.scope,
171-
&traits_in_scope,
170+
&ctx.scope.visible_traits().0,
172171
Some(ctx.module),
173172
None,
174173
|item| {

0 commit comments

Comments
 (0)