mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Complete trait assoc items
This commit is contained in:
parent
5da941897d
commit
79cb0a0dab
5 changed files with 56 additions and 17 deletions
|
@ -76,7 +76,8 @@ pub use crate::{
|
||||||
resolve::ScopeDef,
|
resolve::ScopeDef,
|
||||||
source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
|
source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
|
||||||
ty::{
|
ty::{
|
||||||
display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
|
display::HirDisplay, method_resolution::LookupMode, ApplicationTy, CallableDef, Substs,
|
||||||
|
TraitRef, Ty, TypeCtor, TypeWalk,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
ids::LocationCtx,
|
ids::LocationCtx,
|
||||||
resolve::{ScopeDef, TypeNs, ValueNs},
|
resolve::{ScopeDef, TypeNs, ValueNs},
|
||||||
ty::method_resolution::implements_trait,
|
ty::method_resolution::{self, implements_trait},
|
||||||
AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId,
|
AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId,
|
||||||
MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty,
|
MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty,
|
||||||
};
|
};
|
||||||
|
@ -327,17 +327,19 @@ impl SourceAnalyzer {
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
ty: Ty,
|
ty: Ty,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
|
mode: method_resolution::LookupMode,
|
||||||
callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
|
callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
// There should be no inference vars in types passed here
|
// There should be no inference vars in types passed here
|
||||||
// FIXME check that?
|
// FIXME check that?
|
||||||
|
// FIXME replace Unknown by bound vars here
|
||||||
let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
|
let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
|
||||||
crate::ty::method_resolution::iterate_method_candidates(
|
method_resolution::iterate_method_candidates(
|
||||||
&canonical,
|
&canonical,
|
||||||
db,
|
db,
|
||||||
&self.resolver,
|
&self.resolver,
|
||||||
name,
|
name,
|
||||||
crate::ty::method_resolution::LookupMode::MethodCall,
|
mode,
|
||||||
callback,
|
callback,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ pub(crate) fn lookup_method(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum LookupMode {
|
pub enum LookupMode {
|
||||||
MethodCall,
|
MethodCall,
|
||||||
Path,
|
Path,
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,15 +58,21 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
|
||||||
|
|
||||||
fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
|
fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
|
||||||
let mut seen_methods = FxHashSet::default();
|
let mut seen_methods = FxHashSet::default();
|
||||||
ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, item| {
|
ctx.analyzer.iterate_method_candidates(
|
||||||
if let hir::AssocItem::Function(func) = item {
|
ctx.db,
|
||||||
let data = func.data(ctx.db);
|
receiver,
|
||||||
if data.has_self_param() && seen_methods.insert(data.name().clone()) {
|
None,
|
||||||
acc.add_function(ctx, func);
|
hir::LookupMode::MethodCall,
|
||||||
|
|_ty, item| {
|
||||||
|
if let hir::AssocItem::Function(func) = item {
|
||||||
|
let data = func.data(ctx.db);
|
||||||
|
if data.has_self_param() && seen_methods.insert(data.name().clone()) {
|
||||||
|
acc.add_function(ctx, func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
None::<()>
|
||||||
None::<()>
|
},
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -50,9 +50,12 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
|
hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let krate = ctx.module.map(|m| m.krate());
|
ctx.analyzer.iterate_method_candidates(
|
||||||
if let Some(krate) = krate {
|
ctx.db,
|
||||||
ty.iterate_impl_items(ctx.db, krate, |item| {
|
ty.clone(),
|
||||||
|
None,
|
||||||
|
hir::LookupMode::Path,
|
||||||
|
|_ty, item| {
|
||||||
match item {
|
match item {
|
||||||
hir::AssocItem::Function(func) => {
|
hir::AssocItem::Function(func) => {
|
||||||
let data = func.data(ctx.db);
|
let data = func.data(ctx.db);
|
||||||
|
@ -64,6 +67,18 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
|
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
|
||||||
}
|
}
|
||||||
None::<()>
|
None::<()>
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// Iterate assoc types separately
|
||||||
|
// FIXME: complete T::AssocType
|
||||||
|
let krate = ctx.module.map(|m| m.krate());
|
||||||
|
if let Some(krate) = krate {
|
||||||
|
ty.iterate_impl_items(ctx.db, krate, |item| {
|
||||||
|
match item {
|
||||||
|
hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {}
|
||||||
|
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
|
||||||
|
}
|
||||||
|
None::<()>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -593,7 +608,22 @@ mod tests {
|
||||||
fn foo() { let _ = S::<|> }
|
fn foo() { let _ = S::<|> }
|
||||||
"
|
"
|
||||||
),
|
),
|
||||||
@"[]"
|
@r###"
|
||||||
|
[
|
||||||
|
CompletionItem {
|
||||||
|
label: "m()",
|
||||||
|
source_range: [99; 99),
|
||||||
|
delete: [99; 99),
|
||||||
|
insert: "m()$0",
|
||||||
|
kind: Function,
|
||||||
|
lookup: "m",
|
||||||
|
detail: "fn m()",
|
||||||
|
documentation: Documentation(
|
||||||
|
"A trait method",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue