mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
Merge #2421
2421: Cleanup r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
7d088a16df
9 changed files with 118 additions and 113 deletions
|
@ -28,7 +28,8 @@ use crate::{
|
||||||
expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
|
expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
|
||||||
ty::display::HirFormatter,
|
ty::display::HirFormatter,
|
||||||
ty::{
|
ty::{
|
||||||
self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
|
self, InEnvironment, InferenceResult, TraitEnvironment, TraitRef, Ty, TyDefId, TypeCtor,
|
||||||
|
TypeWalk,
|
||||||
},
|
},
|
||||||
CallableDef, Either, HirDisplay, Name, Source,
|
CallableDef, Either, HirDisplay, Name, Source,
|
||||||
};
|
};
|
||||||
|
@ -498,12 +499,9 @@ impl Adt {
|
||||||
let subst = db.generic_defaults(self.into());
|
let subst = db.generic_defaults(self.into());
|
||||||
subst.iter().any(|ty| ty == &Ty::Unknown)
|
subst.iter().any(|ty| ty == &Ty::Unknown)
|
||||||
}
|
}
|
||||||
pub fn ty(self, db: &impl HirDatabase) -> Ty {
|
pub fn ty(self, db: &impl HirDatabase) -> Type {
|
||||||
match self {
|
let id = AdtId::from(self);
|
||||||
Adt::Struct(it) => it.ty(db),
|
Type::from_def(db, id.module(db).krate, id)
|
||||||
Adt::Union(it) => it.ty(db),
|
|
||||||
Adt::Enum(it) => it.ty(db),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module(self, db: &impl DefDatabase) -> Module {
|
pub fn module(self, db: &impl DefDatabase) -> Module {
|
||||||
|
@ -795,8 +793,8 @@ impl TypeAlias {
|
||||||
db.type_alias_data(self.id).type_ref.clone()
|
db.type_alias_data(self.id).type_ref.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty(self, db: &impl HirDatabase) -> Ty {
|
pub fn ty(self, db: &impl HirDatabase) -> Type {
|
||||||
db.ty(self.id.into())
|
Type::from_def(db, self.id.lookup(db).module(db).krate, self.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self, db: &impl DefDatabase) -> Name {
|
pub fn name(self, db: &impl DefDatabase) -> Name {
|
||||||
|
@ -945,7 +943,7 @@ impl ImplBlock {
|
||||||
}
|
}
|
||||||
pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
|
pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
|
||||||
let impls = db.impls_in_crate(krate.crate_id);
|
let impls = db.impls_in_crate(krate.crate_id);
|
||||||
impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect()
|
impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
|
pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
|
||||||
|
@ -989,6 +987,17 @@ pub struct Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
|
fn from_def(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
krate: CrateId,
|
||||||
|
def: impl HasResolver + Into<TyDefId>,
|
||||||
|
) -> Type {
|
||||||
|
let resolver = def.resolver(db);
|
||||||
|
let environment = TraitEnvironment::lower(db, &resolver);
|
||||||
|
let ty = db.ty(def.into());
|
||||||
|
Type { krate, ty: InEnvironment { value: ty, environment } }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_bool(&self) -> bool {
|
pub fn is_bool(&self) -> bool {
|
||||||
match &self.ty.value {
|
match &self.ty.value {
|
||||||
Ty::Apply(a_ty) => match a_ty.ctor {
|
Ty::Apply(a_ty) => match a_ty.ctor {
|
||||||
|
@ -1097,6 +1106,28 @@ impl Type {
|
||||||
.map(move |ty| self.derived(ty))
|
.map(move |ty| self.derived(ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This would be nicer if it just returned an iterator, but that runs into
|
||||||
|
// lifetime problems, because we need to borrow temp `CrateImplBlocks`.
|
||||||
|
pub fn iterate_impl_items<T>(
|
||||||
|
self,
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
krate: Crate,
|
||||||
|
mut callback: impl FnMut(AssocItem) -> Option<T>,
|
||||||
|
) -> Option<T> {
|
||||||
|
for krate in self.ty.value.def_crates(db, krate.crate_id)? {
|
||||||
|
let impls = db.impls_in_crate(krate);
|
||||||
|
|
||||||
|
for impl_block in impls.lookup_impl_blocks(&self.ty.value) {
|
||||||
|
for &item in db.impl_data(impl_block).items.iter() {
|
||||||
|
if let Some(result) = callback(item.into()) {
|
||||||
|
return Some(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: remove
|
// FIXME: remove
|
||||||
pub fn into_ty(self) -> Ty {
|
pub fn into_ty(self) -> Ty {
|
||||||
self.ty.value
|
self.ty.value
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use hir_def::{GenericDefId, LocalStructFieldId, TraitId, VariantId};
|
||||||
use ra_arena::map::ArenaMap;
|
use ra_arena::map::ArenaMap;
|
||||||
use ra_db::{salsa, CrateId};
|
use ra_db::{salsa, CrateId};
|
||||||
|
|
||||||
|
@ -12,19 +13,15 @@ use crate::{
|
||||||
CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor,
|
CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor,
|
||||||
ValueTyDefId,
|
ValueTyDefId,
|
||||||
},
|
},
|
||||||
Crate, DefWithBody, ImplBlock, Trait,
|
Crate, DefWithBody, ImplBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use hir_def::{
|
pub use hir_def::db::{
|
||||||
db::{
|
BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
|
||||||
BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
|
DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
|
||||||
DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
|
FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
|
||||||
FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase,
|
LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery,
|
||||||
InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery,
|
StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery,
|
||||||
RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery,
|
|
||||||
TypeAliasDataQuery,
|
|
||||||
},
|
|
||||||
GenericDefId, LocalStructFieldId, VariantId,
|
|
||||||
};
|
};
|
||||||
pub use hir_expand::db::{
|
pub use hir_expand::db::{
|
||||||
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
||||||
|
@ -66,7 +63,7 @@ pub trait HirDatabase: DefDatabase {
|
||||||
fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>;
|
fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::ty::traits::impls_for_trait_query)]
|
#[salsa::invoke(crate::ty::traits::impls_for_trait_query)]
|
||||||
fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>;
|
fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplBlock]>;
|
||||||
|
|
||||||
/// This provides the Chalk trait solver instance. Because Chalk always
|
/// This provides the Chalk trait solver instance. Because Chalk always
|
||||||
/// works from a specific crate, this query is keyed on the crate; and
|
/// works from a specific crate, this query is keyed on the crate; and
|
||||||
|
|
|
@ -389,14 +389,14 @@ impl SourceAnalyzer {
|
||||||
pub fn iterate_path_candidates<T>(
|
pub fn iterate_path_candidates<T>(
|
||||||
&self,
|
&self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
ty: Ty,
|
ty: &Type,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
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
|
// FIXME replace Unknown by bound vars here
|
||||||
let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
|
let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 };
|
||||||
method_resolution::iterate_method_candidates(
|
method_resolution::iterate_method_candidates(
|
||||||
&canonical,
|
&canonical,
|
||||||
db,
|
db,
|
||||||
|
|
|
@ -189,7 +189,7 @@ impl Ty {
|
||||||
Ty::Param { idx, name }
|
Ty::Param { idx, name }
|
||||||
}
|
}
|
||||||
TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db),
|
TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db),
|
||||||
TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db),
|
TypeNs::AdtSelfType(adt) => db.ty(adt.into()),
|
||||||
|
|
||||||
TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()),
|
TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()),
|
||||||
TypeNs::BuiltinType(it) => {
|
TypeNs::BuiltinType(it) => {
|
||||||
|
|
|
@ -6,9 +6,10 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef,
|
lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability,
|
||||||
HasModule, ImplId, TraitId,
|
AssocItemId, AstItemDef, HasModule, ImplId, TraitId,
|
||||||
};
|
};
|
||||||
|
use hir_expand::name::Name;
|
||||||
use ra_db::CrateId;
|
use ra_db::CrateId;
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
@ -17,7 +18,7 @@ use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
ty::primitive::{FloatBitness, Uncertain},
|
ty::primitive::{FloatBitness, Uncertain},
|
||||||
ty::{utils::all_super_traits, Ty, TypeCtor},
|
ty::{utils::all_super_traits, Ty, TypeCtor},
|
||||||
AssocItem, Crate, Function, Mutability, Name, Trait,
|
AssocItem, Function,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
|
use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
|
||||||
|
@ -87,8 +88,8 @@ impl CrateImplBlocks {
|
||||||
fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
|
fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplId> + '_ {
|
pub fn lookup_impl_blocks_for_trait(&self, tr: TraitId) -> impl Iterator<Item = ImplId> + '_ {
|
||||||
self.impls_by_trait.get(&tr.id).into_iter().flatten().copied()
|
self.impls_by_trait.get(&tr).into_iter().flatten().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a {
|
pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a {
|
||||||
|
@ -96,51 +97,56 @@ impl CrateImplBlocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> {
|
impl Ty {
|
||||||
// Types like slice can have inherent impls in several crates, (core and alloc).
|
pub(crate) fn def_crates(
|
||||||
// The corresponding impls are marked with lang items, so we can use them to find the required crates.
|
&self,
|
||||||
macro_rules! lang_item_crate {
|
db: &impl HirDatabase,
|
||||||
|
cur_crate: CrateId,
|
||||||
|
) -> Option<ArrayVec<[CrateId; 2]>> {
|
||||||
|
// Types like slice can have inherent impls in several crates, (core and alloc).
|
||||||
|
// The corresponding impls are marked with lang items, so we can use them to find the required crates.
|
||||||
|
macro_rules! lang_item_crate {
|
||||||
($($name:expr),+ $(,)?) => {{
|
($($name:expr),+ $(,)?) => {{
|
||||||
let mut v = ArrayVec::<[LangItemTarget; 2]>::new();
|
let mut v = ArrayVec::<[LangItemTarget; 2]>::new();
|
||||||
$(
|
$(
|
||||||
v.extend(db.lang_item(cur_crate.crate_id, $name.into()));
|
v.extend(db.lang_item(cur_crate, $name.into()));
|
||||||
)+
|
)+
|
||||||
v
|
v
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
let lang_item_targets = match ty {
|
let lang_item_targets = match self {
|
||||||
Ty::Apply(a_ty) => match a_ty.ctor {
|
Ty::Apply(a_ty) => match a_ty.ctor {
|
||||||
TypeCtor::Adt(def_id) => {
|
TypeCtor::Adt(def_id) => {
|
||||||
return Some(std::iter::once(def_id.module(db).krate.into()).collect())
|
return Some(std::iter::once(def_id.module(db).krate).collect())
|
||||||
}
|
}
|
||||||
TypeCtor::Bool => lang_item_crate!("bool"),
|
TypeCtor::Bool => lang_item_crate!("bool"),
|
||||||
TypeCtor::Char => lang_item_crate!("char"),
|
TypeCtor::Char => lang_item_crate!("char"),
|
||||||
TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {
|
TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {
|
||||||
// There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
|
// There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
|
||||||
FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
|
FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
|
||||||
FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
|
FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
|
||||||
|
},
|
||||||
|
TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
|
||||||
|
TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
|
||||||
|
TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
|
||||||
|
TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
|
||||||
|
TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
|
||||||
|
_ => return None,
|
||||||
},
|
},
|
||||||
TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
|
|
||||||
TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
|
|
||||||
TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
|
|
||||||
TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
|
|
||||||
TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
};
|
||||||
_ => return None,
|
let res = lang_item_targets
|
||||||
};
|
.into_iter()
|
||||||
let res = lang_item_targets
|
.filter_map(|it| match it {
|
||||||
.into_iter()
|
LangItemTarget::ImplBlockId(it) => Some(it),
|
||||||
.filter_map(|it| match it {
|
_ => None,
|
||||||
LangItemTarget::ImplBlockId(it) => Some(it),
|
})
|
||||||
_ => None,
|
.map(|it| it.module(db).krate)
|
||||||
})
|
.collect();
|
||||||
.map(|it| it.module(db).krate.into())
|
Some(res)
|
||||||
.collect();
|
}
|
||||||
Some(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the method with the given name, returning the actual autoderefed
|
/// Look up the method with the given name, returning the actual autoderefed
|
||||||
/// receiver type (but without autoref applied yet).
|
/// receiver type (but without autoref applied yet).
|
||||||
pub(crate) fn lookup_method(
|
pub(crate) fn lookup_method(
|
||||||
|
@ -193,14 +199,9 @@ pub(crate) fn iterate_method_candidates<T>(
|
||||||
let environment = TraitEnvironment::lower(db, resolver);
|
let environment = TraitEnvironment::lower(db, resolver);
|
||||||
let ty = InEnvironment { value: ty.clone(), environment };
|
let ty = InEnvironment { value: ty.clone(), environment };
|
||||||
for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) {
|
for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) {
|
||||||
if let Some(result) = iterate_inherent_methods(
|
if let Some(result) =
|
||||||
&derefed_ty,
|
iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback)
|
||||||
db,
|
{
|
||||||
name,
|
|
||||||
mode,
|
|
||||||
krate.into(),
|
|
||||||
&mut callback,
|
|
||||||
) {
|
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
if let Some(result) = iterate_trait_method_candidates(
|
if let Some(result) = iterate_trait_method_candidates(
|
||||||
|
@ -283,11 +284,11 @@ fn iterate_inherent_methods<T>(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mode: LookupMode,
|
mode: LookupMode,
|
||||||
krate: Crate,
|
krate: CrateId,
|
||||||
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
for krate in def_crates(db, krate, &ty.value)? {
|
for krate in ty.value.def_crates(db, krate)? {
|
||||||
let impls = db.impls_in_crate(krate.crate_id);
|
let impls = db.impls_in_crate(krate);
|
||||||
|
|
||||||
for impl_block in impls.lookup_impl_blocks(&ty.value) {
|
for impl_block in impls.lookup_impl_blocks(&ty.value) {
|
||||||
for &item in db.impl_data(impl_block).items.iter() {
|
for &item in db.impl_data(impl_block).items.iter() {
|
||||||
|
@ -327,7 +328,7 @@ pub(crate) fn implements_trait(
|
||||||
ty: &Canonical<Ty>,
|
ty: &Canonical<Ty>,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
krate: Crate,
|
krate: CrateId,
|
||||||
trait_: TraitId,
|
trait_: TraitId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if ty.value.inherent_trait() == Some(trait_) {
|
if ty.value.inherent_trait() == Some(trait_) {
|
||||||
|
@ -337,35 +338,11 @@ pub(crate) fn implements_trait(
|
||||||
}
|
}
|
||||||
let env = TraitEnvironment::lower(db, resolver);
|
let env = TraitEnvironment::lower(db, resolver);
|
||||||
let goal = generic_implements_goal(db, env, trait_, ty.clone());
|
let goal = generic_implements_goal(db, env, trait_, ty.clone());
|
||||||
let solution = db.trait_solve(krate, goal);
|
let solution = db.trait_solve(krate.into(), goal);
|
||||||
|
|
||||||
solution.is_some()
|
solution.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ty {
|
|
||||||
// This would be nicer if it just returned an iterator, but that runs into
|
|
||||||
// lifetime problems, because we need to borrow temp `CrateImplBlocks`.
|
|
||||||
pub fn iterate_impl_items<T>(
|
|
||||||
self,
|
|
||||||
db: &impl HirDatabase,
|
|
||||||
krate: Crate,
|
|
||||||
mut callback: impl FnMut(AssocItem) -> Option<T>,
|
|
||||||
) -> Option<T> {
|
|
||||||
for krate in def_crates(db, krate, &self)? {
|
|
||||||
let impls = db.impls_in_crate(krate.crate_id);
|
|
||||||
|
|
||||||
for impl_block in impls.lookup_impl_blocks(&self) {
|
|
||||||
for &item in db.impl_data(impl_block).items.iter() {
|
|
||||||
if let Some(result) = callback(item.into()) {
|
|
||||||
return Some(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This creates Substs for a trait with the given Self type and type variables
|
/// This creates Substs for a trait with the given Self type and type variables
|
||||||
/// for all other parameters, to query Chalk with it.
|
/// for all other parameters, to query Chalk with it.
|
||||||
fn generic_implements_goal(
|
fn generic_implements_goal(
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use chalk_ir::{cast::Cast, family::ChalkIr};
|
use chalk_ir::{cast::Cast, family::ChalkIr};
|
||||||
use hir_def::{expr::ExprId, DefWithBodyId};
|
use hir_def::{expr::ExprId, DefWithBodyId, TraitId};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use ra_db::{impl_intern_key, salsa};
|
use ra_db::{impl_intern_key, salsa, CrateId};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
use crate::{db::HirDatabase, Crate, ImplBlock, Trait, TypeAlias};
|
use crate::{db::HirDatabase, Crate, ImplBlock, TypeAlias};
|
||||||
|
|
||||||
use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
|
use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
|
||||||
|
|
||||||
|
@ -77,8 +77,8 @@ pub(crate) fn trait_solver_query(
|
||||||
/// Collects impls for the given trait in the whole dependency tree of `krate`.
|
/// Collects impls for the given trait in the whole dependency tree of `krate`.
|
||||||
pub(crate) fn impls_for_trait_query(
|
pub(crate) fn impls_for_trait_query(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
krate: Crate,
|
krate: CrateId,
|
||||||
trait_: Trait,
|
trait_: TraitId,
|
||||||
) -> Arc<[ImplBlock]> {
|
) -> Arc<[ImplBlock]> {
|
||||||
let mut impls = FxHashSet::default();
|
let mut impls = FxHashSet::default();
|
||||||
// We call the query recursively here. On the one hand, this means we can
|
// We call the query recursively here. On the one hand, this means we can
|
||||||
|
@ -86,10 +86,10 @@ pub(crate) fn impls_for_trait_query(
|
||||||
// will only ever get called for a few crates near the root of the tree (the
|
// will only ever get called for a few crates near the root of the tree (the
|
||||||
// ones the user is editing), so this may actually be a waste of memory. I'm
|
// ones the user is editing), so this may actually be a waste of memory. I'm
|
||||||
// doing it like this mainly for simplicity for now.
|
// doing it like this mainly for simplicity for now.
|
||||||
for dep in krate.dependencies(db) {
|
for dep in db.crate_graph().dependencies(krate) {
|
||||||
impls.extend(db.impls_for_trait(dep.krate, trait_).iter());
|
impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter());
|
||||||
}
|
}
|
||||||
let crate_impl_blocks = db.impls_in_crate(krate.crate_id);
|
let crate_impl_blocks = db.impls_in_crate(krate);
|
||||||
impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from));
|
impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from));
|
||||||
impls.into_iter().collect()
|
impls.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,7 +448,7 @@ where
|
||||||
let trait_: TraitId = from_chalk(self.db, trait_id);
|
let trait_: TraitId = from_chalk(self.db, trait_id);
|
||||||
let mut result: Vec<_> = self
|
let mut result: Vec<_> = self
|
||||||
.db
|
.db
|
||||||
.impls_for_trait(self.krate, trait_.into())
|
.impls_for_trait(self.krate.crate_id, trait_.into())
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.map(Impl::ImplBlock)
|
.map(Impl::ImplBlock)
|
||||||
|
|
|
@ -484,7 +484,7 @@ impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasResolver {
|
pub trait HasResolver: Copy {
|
||||||
/// Builds a resolver for type references inside this def.
|
/// Builds a resolver for type references inside this def.
|
||||||
fn resolver(self, db: &impl DefDatabase) -> Resolver;
|
fn resolver(self, db: &impl DefDatabase) -> Resolver;
|
||||||
}
|
}
|
||||||
|
@ -502,7 +502,7 @@ impl HasResolver for TraitId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<AdtId>> HasResolver for T {
|
impl<T: Into<AdtId> + Copy> HasResolver for T {
|
||||||
fn resolver(self, db: &impl DefDatabase) -> Resolver {
|
fn resolver(self, db: &impl DefDatabase) -> Resolver {
|
||||||
let def = self.into();
|
let def = self.into();
|
||||||
def.module(db)
|
def.module(db)
|
||||||
|
|
|
@ -50,7 +50,7 @@ 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!(),
|
||||||
};
|
};
|
||||||
ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| {
|
ctx.analyzer.iterate_path_candidates(ctx.db, &ty, None, |_ty, item| {
|
||||||
match item {
|
match item {
|
||||||
hir::AssocItem::Function(func) => {
|
hir::AssocItem::Function(func) => {
|
||||||
if !func.has_self_param(ctx.db) {
|
if !func.has_self_param(ctx.db) {
|
||||||
|
|
Loading…
Reference in a new issue