From a306531e6aa7995145dc041166f68ea950aca1a8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 11:40:10 +0300 Subject: [PATCH 1/2] Decouple --- crates/ra_hir/src/ty/method_resolution.rs | 2 +- crates/ra_hir/src/ty/traits.rs | 6 ++-- crates/ra_hir/src/ty/traits/chalk.rs | 40 ++++++++++++++--------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 92645e2a52..7df2649c90 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -62,7 +62,7 @@ impl CrateImplBlocks { 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_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); match &impl_data.target_trait { Some(trait_ref) => { diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 39b489a4c9..99afeb35f2 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,13 +2,13 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::{expr::ExprId, DefWithBodyId, TraitId}; +use hir_def::{expr::ExprId, DefWithBodyId, TraitId, TypeAliasId}; use log::debug; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; use rustc_hash::FxHashSet; -use crate::{db::HirDatabase, ImplBlock, TypeAlias}; +use crate::{db::HirDatabase, ImplBlock}; use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; @@ -317,7 +317,7 @@ impl_intern_key!(GlobalImplId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum AssocTyValue { /// A normal assoc type value from an impl block. - TypeAlias(TypeAlias), + TypeAlias(TypeAliasId), /// The output type of the Fn trait implementation. ClosureFnTraitImplOutput(ClosureFnTraitImplData), } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 49fa955081..76ff6f67ff 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -11,7 +11,8 @@ use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum use ra_db::CrateId; 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; @@ -22,7 +23,7 @@ use crate::{ db::HirDatabase, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - ImplBlock, TypeAlias, + ImplBlock, }; /// This represents a trait whose name we could not resolve. @@ -670,7 +671,7 @@ fn impl_block_datum( // don't include associated types that don't exist in the trait 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(); debug!("impl_datum: {:?}", impl_datum_bound); let impl_datum = ImplDatum { @@ -773,24 +774,33 @@ pub(crate) fn associated_ty_value_query( fn type_alias_associated_ty_value( db: &impl HirDatabase, _krate: CrateId, - type_alias: TypeAlias, + type_alias: TypeAliasId, ) -> Arc> { - let impl_block = type_alias.impl_block(db).expect("assoc ty value should be in impl"); - let impl_id = Impl::ImplBlock(impl_block).to_chalk(db); - let trait_ = impl_block - .target_trait_ref(db) - .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 type_alias_data = db.type_alias_data(type_alias); + let impl_id = match type_alias.lookup(db).container { + ContainerId::ImplId(it) => it, + _ => panic!("assoc ty value should be in impl"), + }; + + 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 - .trait_data(trait_) - .associated_type_by_name(&type_alias.name(db)) + .trait_data(target_trait.trait_) + .associated_type_by_name(&type_alias_data.name) .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 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 = chalk_rust_ir::AssociatedTyValue { - impl_id, + impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), associated_ty_id: assoc_ty.to_chalk(db), value: make_binders(value_bound, bound_vars.len()), }; From 3a0929fca7a52605526c6f89be4e3e86c5d0359d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 27 Nov 2019 12:02:54 +0300 Subject: [PATCH 2/2] Decouple --- crates/ra_hir/src/db.rs | 6 +++--- crates/ra_hir/src/ty/infer/coerce.rs | 21 +++++++++++++++++---- crates/ra_hir/src/ty/traits.rs | 6 +++--- crates/ra_hir/src/ty/traits/chalk.rs | 2 +- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 17cb638686..a5bfef91f6 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -2,7 +2,7 @@ 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_db::{salsa, CrateId}; @@ -13,7 +13,7 @@ use crate::{ CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, ValueTyDefId, }, - DefWithBody, ImplBlock, + DefWithBody, }; pub use hir_def::db::{ @@ -63,7 +63,7 @@ pub trait HirDatabase: DefDatabase { fn impls_in_crate(&self, krate: CrateId) -> Arc; #[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 /// works from a specific crate, this query is keyed on the crate; and diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 5ed4470afa..cf45ede7ce 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -4,13 +4,17 @@ //! //! 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 test_utils::tested_by; use crate::{ db::HirDatabase, - ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, + ty::{autoderef, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, Mutability, }; @@ -57,9 +61,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { impls .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. - 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_to_ty = trait_ref.substs.0.get(1)?; diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 99afeb35f2..93cb328697 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs @@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex}; use chalk_ir::{cast::Cast, family::ChalkIr}; -use hir_def::{expr::ExprId, DefWithBodyId, TraitId, TypeAliasId}; +use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId}; use log::debug; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; @@ -79,7 +79,7 @@ pub(crate) fn impls_for_trait_query( db: &impl HirDatabase, krate: CrateId, trait_: TraitId, -) -> Arc<[ImplBlock]> { +) -> Arc<[ImplId]> { let mut impls = FxHashSet::default(); // 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 @@ -90,7 +90,7 @@ pub(crate) fn impls_for_trait_query( impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); } 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() } diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 76ff6f67ff..7b2e530a2c 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -453,7 +453,7 @@ where .impls_for_trait(self.krate, trait_.into()) .iter() .copied() - .map(Impl::ImplBlock) + .map(|it| Impl::ImplBlock(it.into())) .map(|impl_| impl_.to_chalk(self.db)) .collect();