2425: Decouple r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-11-27 09:05:39 +00:00 committed by GitHub
commit 57ad4542b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 29 deletions

View file

@ -2,7 +2,7 @@
use std::sync::Arc; use std::sync::Arc;
use hir_def::{GenericDefId, LocalStructFieldId, TraitId, VariantId}; use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId};
use ra_arena::map::ArenaMap; use ra_arena::map::ArenaMap;
use ra_db::{salsa, CrateId}; use ra_db::{salsa, CrateId};
@ -13,7 +13,7 @@ use crate::{
CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor,
ValueTyDefId, ValueTyDefId,
}, },
DefWithBody, ImplBlock, DefWithBody,
}; };
pub use hir_def::db::{ pub use hir_def::db::{
@ -63,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: CrateId, trait_: TraitId) -> Arc<[ImplBlock]>; fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplId]>;
/// 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

View file

@ -4,13 +4,17 @@
//! //!
//! See: https://doc.rust-lang.org/nomicon/coercions.html //! See: https://doc.rust-lang.org/nomicon/coercions.html
use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId}; use hir_def::{
lang_item::LangItemTarget,
resolver::{HasResolver, Resolver},
AdtId,
};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use test_utils::tested_by; use test_utils::tested_by;
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, ty::{autoderef, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
Mutability, Mutability,
}; };
@ -57,9 +61,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
impls impls
.iter() .iter()
.filter_map(|impl_block| { .filter_map(|&impl_id| {
let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db);
let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
// `CoerseUnsized` has one generic parameter for the target type. // `CoerseUnsized` has one generic parameter for the target type.
let trait_ref = impl_block.target_trait_ref(db)?; let trait_ref = TraitRef::from_hir(
db,
&resolver,
impl_data.target_trait.as_ref()?,
Some(target_ty),
)?;
let cur_from_ty = trait_ref.substs.0.get(0)?; let cur_from_ty = trait_ref.substs.0.get(0)?;
let cur_to_ty = trait_ref.substs.0.get(1)?; let cur_to_ty = trait_ref.substs.0.get(1)?;

View file

@ -62,7 +62,7 @@ impl CrateImplBlocks {
let impl_data = db.impl_data(impl_id); let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db); let resolver = impl_id.resolver(db);
let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
match &impl_data.target_trait { match &impl_data.target_trait {
Some(trait_ref) => { Some(trait_ref) => {

View file

@ -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, TraitId}; use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
use log::debug; use log::debug;
use ra_db::{impl_intern_key, salsa, CrateId}; 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, ImplBlock, TypeAlias}; use crate::{db::HirDatabase, ImplBlock};
use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
@ -79,7 +79,7 @@ pub(crate) fn impls_for_trait_query(
db: &impl HirDatabase, db: &impl HirDatabase,
krate: CrateId, krate: CrateId,
trait_: TraitId, trait_: TraitId,
) -> Arc<[ImplBlock]> { ) -> Arc<[ImplId]> {
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
// reuse results from queries for different crates; on the other hand, this // reuse results from queries for different crates; on the other hand, this
@ -90,7 +90,7 @@ pub(crate) fn impls_for_trait_query(
impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter());
} }
let crate_impl_blocks = db.impls_in_crate(krate); 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_));
impls.into_iter().collect() impls.into_iter().collect()
} }
@ -317,7 +317,7 @@ impl_intern_key!(GlobalImplId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum AssocTyValue { pub enum AssocTyValue {
/// A normal assoc type value from an impl block. /// A normal assoc type value from an impl block.
TypeAlias(TypeAlias), TypeAlias(TypeAliasId),
/// The output type of the Fn trait implementation. /// The output type of the Fn trait implementation.
ClosureFnTraitImplOutput(ClosureFnTraitImplData), ClosureFnTraitImplOutput(ClosureFnTraitImplData),
} }

View file

@ -11,7 +11,8 @@ use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum
use ra_db::CrateId; use ra_db::CrateId;
use hir_def::{ use hir_def::{
lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, lang_item::LangItemTarget, resolver::HasResolver, AstItemDef, ContainerId, GenericDefId,
Lookup, TraitId, TypeAliasId,
}; };
use hir_expand::name; use hir_expand::name;
@ -22,7 +23,7 @@ use crate::{
db::HirDatabase, db::HirDatabase,
ty::display::HirDisplay, ty::display::HirDisplay,
ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
ImplBlock, TypeAlias, ImplBlock,
}; };
/// This represents a trait whose name we could not resolve. /// This represents a trait whose name we could not resolve.
@ -452,7 +453,7 @@ where
.impls_for_trait(self.krate, trait_.into()) .impls_for_trait(self.krate, trait_.into())
.iter() .iter()
.copied() .copied()
.map(Impl::ImplBlock) .map(|it| Impl::ImplBlock(it.into()))
.map(|impl_| impl_.to_chalk(self.db)) .map(|impl_| impl_.to_chalk(self.db))
.collect(); .collect();
@ -670,7 +671,7 @@ fn impl_block_datum(
// don't include associated types that don't exist in the trait // don't include associated types that don't exist in the trait
trait_data.associated_type_by_name(&type_alias.name(db)).is_some() trait_data.associated_type_by_name(&type_alias.name(db)).is_some()
}) })
.map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) .map(|type_alias| AssocTyValue::TypeAlias(type_alias.id).to_chalk(db))
.collect(); .collect();
debug!("impl_datum: {:?}", impl_datum_bound); debug!("impl_datum: {:?}", impl_datum_bound);
let impl_datum = ImplDatum { let impl_datum = ImplDatum {
@ -773,24 +774,33 @@ pub(crate) fn associated_ty_value_query(
fn type_alias_associated_ty_value( fn type_alias_associated_ty_value(
db: &impl HirDatabase, db: &impl HirDatabase,
_krate: CrateId, _krate: CrateId,
type_alias: TypeAlias, type_alias: TypeAliasId,
) -> Arc<AssociatedTyValue<ChalkIr>> { ) -> Arc<AssociatedTyValue<ChalkIr>> {
let impl_block = type_alias.impl_block(db).expect("assoc ty value should be in impl"); let type_alias_data = db.type_alias_data(type_alias);
let impl_id = Impl::ImplBlock(impl_block).to_chalk(db); let impl_id = match type_alias.lookup(db).container {
let trait_ = impl_block ContainerId::ImplId(it) => it,
.target_trait_ref(db) _ => panic!("assoc ty value should be in impl"),
.expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved };
.trait_;
let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db);
let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
let target_trait = impl_data
.target_trait
.as_ref()
.and_then(|trait_ref| TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)))
.expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved
let assoc_ty = db let assoc_ty = db
.trait_data(trait_) .trait_data(target_trait.trait_)
.associated_type_by_name(&type_alias.name(db)) .associated_type_by_name(&type_alias_data.name)
.expect("assoc ty value should not exist"); // validated when building the impl data as well .expect("assoc ty value should not exist"); // validated when building the impl data as well
let generic_params = db.generic_params(impl_block.id.into()); let generic_params = db.generic_params(impl_id.into());
let bound_vars = Substs::bound_vars(&generic_params); let bound_vars = Substs::bound_vars(&generic_params);
let ty = db.ty(type_alias.id.into()).subst(&bound_vars); let ty = db.ty(type_alias.into()).subst(&bound_vars);
let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
let value = chalk_rust_ir::AssociatedTyValue { let value = chalk_rust_ir::AssociatedTyValue {
impl_id, impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db),
associated_ty_id: assoc_ty.to_chalk(db), associated_ty_id: assoc_ty.to_chalk(db),
value: make_binders(value_bound, bound_vars.len()), value: make_binders(value_bound, bound_vars.len()),
}; };