resolve::ScopeDef,
source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
ty::{
- display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
+ display::HirDisplay, method_resolution::LookupMode, ApplicationTy, CallableDef, Substs,
+ TraitRef, Ty, TypeCtor, TypeWalk,
},
};
},
ids::LocationCtx,
resolve::{ScopeDef, TypeNs, ValueNs},
- ty::method_resolution::implements_trait,
+ ty::method_resolution::{self, implements_trait},
AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId,
MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty,
};
db: &impl HirDatabase,
ty: Ty,
name: Option<&Name>,
+ mode: method_resolution::LookupMode,
callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
) -> Option<T> {
// There should be no inference vars in types passed here
// FIXME check that?
+ // FIXME replace Unknown by bound vars here
let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
- crate::ty::method_resolution::iterate_method_candidates(
+ method_resolution::iterate_method_candidates(
&canonical,
db,
&self.resolver,
name,
- crate::ty::method_resolution::LookupMode::MethodCall,
+ mode,
callback,
)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub(crate) enum LookupMode {
+pub enum LookupMode {
MethodCall,
Path,
}
fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
let mut seen_methods = FxHashSet::default();
- ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_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);
+ ctx.analyzer.iterate_method_candidates(
+ ctx.db,
+ receiver,
+ None,
+ 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)]
hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
_ => unreachable!(),
};
- let krate = ctx.module.map(|m| m.krate());
- if let Some(krate) = krate {
- ty.iterate_impl_items(ctx.db, krate, |item| {
+ ctx.analyzer.iterate_method_candidates(
+ ctx.db,
+ ty.clone(),
+ None,
+ hir::LookupMode::Path,
+ |_ty, item| {
match item {
hir::AssocItem::Function(func) => {
let data = func.data(ctx.db);
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
}
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::<()>
});
}
}
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",
+ ),
+ },
+ ]
+ "###
);
}