diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-27 09:05:39 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-11-27 09:05:39 +0000 |
| commit | 57ad4542b6c7fdfeb3b6abc4cd1a4243495694df (patch) | |
| tree | 4917786a1df597ab44016a2f5c0a8eae67b852b5 | |
| parent | ac5ec2adcdfc727f2b33f85a6ca62355b6a130f1 (diff) | |
| parent | 3a0929fca7a52605526c6f89be4e3e86c5d0359d (diff) | |
Merge #2425
2425: Decouple r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
| -rw-r--r-- | crates/ra_hir/src/db.rs | 6 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/infer/coerce.rs | 21 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 2 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 10 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 42 |
5 files changed, 52 insertions, 29 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 17cb63868..a5bfef91f 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
| 4 | 4 | ||
| 5 | use hir_def::{GenericDefId, LocalStructFieldId, TraitId, VariantId}; | 5 | use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; |
| 6 | use ra_arena::map::ArenaMap; | 6 | use ra_arena::map::ArenaMap; |
| 7 | use ra_db::{salsa, CrateId}; | 7 | use ra_db::{salsa, CrateId}; |
| 8 | 8 | ||
| @@ -13,7 +13,7 @@ use crate::{ | |||
| 13 | CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, | 13 | CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, |
| 14 | ValueTyDefId, | 14 | ValueTyDefId, |
| 15 | }, | 15 | }, |
| 16 | DefWithBody, ImplBlock, | 16 | DefWithBody, |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | pub use hir_def::db::{ | 19 | pub use hir_def::db::{ |
| @@ -63,7 +63,7 @@ pub trait HirDatabase: DefDatabase { | |||
| 63 | fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>; | 63 | fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>; |
| 64 | 64 | ||
| 65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] | 65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] |
| 66 | fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplBlock]>; | 66 | fn impls_for_trait(&self, krate: CrateId, trait_: TraitId) -> Arc<[ImplId]>; |
| 67 | 67 | ||
| 68 | /// This provides the Chalk trait solver instance. Because Chalk always | 68 | /// This provides the Chalk trait solver instance. Because Chalk always |
| 69 | /// works from a specific crate, this query is keyed on the crate; and | 69 | /// 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 5ed4470af..cf45ede7c 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs | |||
| @@ -4,13 +4,17 @@ | |||
| 4 | //! | 4 | //! |
| 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
| 6 | 6 | ||
| 7 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId}; | 7 | use hir_def::{ |
| 8 | lang_item::LangItemTarget, | ||
| 9 | resolver::{HasResolver, Resolver}, | ||
| 10 | AdtId, | ||
| 11 | }; | ||
| 8 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
| 9 | use test_utils::tested_by; | 13 | use test_utils::tested_by; |
| 10 | 14 | ||
| 11 | use crate::{ | 15 | use crate::{ |
| 12 | db::HirDatabase, | 16 | db::HirDatabase, |
| 13 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, | 17 | ty::{autoderef, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, |
| 14 | Mutability, | 18 | Mutability, |
| 15 | }; | 19 | }; |
| 16 | 20 | ||
| @@ -57,9 +61,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
| 57 | 61 | ||
| 58 | impls | 62 | impls |
| 59 | .iter() | 63 | .iter() |
| 60 | .filter_map(|impl_block| { | 64 | .filter_map(|&impl_id| { |
| 65 | let impl_data = db.impl_data(impl_id); | ||
| 66 | let resolver = impl_id.resolver(db); | ||
| 67 | let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | ||
| 68 | |||
| 61 | // `CoerseUnsized` has one generic parameter for the target type. | 69 | // `CoerseUnsized` has one generic parameter for the target type. |
| 62 | let trait_ref = impl_block.target_trait_ref(db)?; | 70 | let trait_ref = TraitRef::from_hir( |
| 71 | db, | ||
| 72 | &resolver, | ||
| 73 | impl_data.target_trait.as_ref()?, | ||
| 74 | Some(target_ty), | ||
| 75 | )?; | ||
| 63 | let cur_from_ty = trait_ref.substs.0.get(0)?; | 76 | let cur_from_ty = trait_ref.substs.0.get(0)?; |
| 64 | let cur_to_ty = trait_ref.substs.0.get(1)?; | 77 | let cur_to_ty = trait_ref.substs.0.get(1)?; |
| 65 | 78 | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 92645e2a5..7df2649c9 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 { | |||
| 62 | let impl_data = db.impl_data(impl_id); | 62 | let impl_data = db.impl_data(impl_id); |
| 63 | let resolver = impl_id.resolver(db); | 63 | let resolver = impl_id.resolver(db); |
| 64 | 64 | ||
| 65 | let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; | 65 | let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); |
| 66 | 66 | ||
| 67 | match &impl_data.target_trait { | 67 | match &impl_data.target_trait { |
| 68 | Some(trait_ref) => { | 68 | Some(trait_ref) => { |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 39b489a4c..93cb32869 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
| @@ -2,13 +2,13 @@ | |||
| 2 | use std::sync::{Arc, Mutex}; | 2 | use std::sync::{Arc, Mutex}; |
| 3 | 3 | ||
| 4 | use chalk_ir::{cast::Cast, family::ChalkIr}; | 4 | use chalk_ir::{cast::Cast, family::ChalkIr}; |
| 5 | use hir_def::{expr::ExprId, DefWithBodyId, TraitId}; | 5 | use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId}; |
| 6 | use log::debug; | 6 | use log::debug; |
| 7 | use ra_db::{impl_intern_key, salsa, CrateId}; | 7 | use ra_db::{impl_intern_key, salsa, CrateId}; |
| 8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
| 9 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
| 10 | 10 | ||
| 11 | use crate::{db::HirDatabase, ImplBlock, TypeAlias}; | 11 | use crate::{db::HirDatabase, ImplBlock}; |
| 12 | 12 | ||
| 13 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; | 13 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; |
| 14 | 14 | ||
| @@ -79,7 +79,7 @@ pub(crate) fn impls_for_trait_query( | |||
| 79 | db: &impl HirDatabase, | 79 | db: &impl HirDatabase, |
| 80 | krate: CrateId, | 80 | krate: CrateId, |
| 81 | trait_: TraitId, | 81 | trait_: TraitId, |
| 82 | ) -> Arc<[ImplBlock]> { | 82 | ) -> Arc<[ImplId]> { |
| 83 | let mut impls = FxHashSet::default(); | 83 | let mut impls = FxHashSet::default(); |
| 84 | // We call the query recursively here. On the one hand, this means we can | 84 | // We call the query recursively here. On the one hand, this means we can |
| 85 | // reuse results from queries for different crates; on the other hand, this | 85 | // reuse results from queries for different crates; on the other hand, this |
| @@ -90,7 +90,7 @@ pub(crate) fn impls_for_trait_query( | |||
| 90 | impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); | 90 | impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); |
| 91 | } | 91 | } |
| 92 | let crate_impl_blocks = db.impls_in_crate(krate); | 92 | let crate_impl_blocks = db.impls_in_crate(krate); |
| 93 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); | 93 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); |
| 94 | impls.into_iter().collect() | 94 | impls.into_iter().collect() |
| 95 | } | 95 | } |
| 96 | 96 | ||
| @@ -317,7 +317,7 @@ impl_intern_key!(GlobalImplId); | |||
| 317 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 317 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
| 318 | pub enum AssocTyValue { | 318 | pub enum AssocTyValue { |
| 319 | /// A normal assoc type value from an impl block. | 319 | /// A normal assoc type value from an impl block. |
| 320 | TypeAlias(TypeAlias), | 320 | TypeAlias(TypeAliasId), |
| 321 | /// The output type of the Fn trait implementation. | 321 | /// The output type of the Fn trait implementation. |
| 322 | ClosureFnTraitImplOutput(ClosureFnTraitImplData), | 322 | ClosureFnTraitImplOutput(ClosureFnTraitImplData), |
| 323 | } | 323 | } |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 49fa95508..7b2e530a2 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 | |||
| 11 | use ra_db::CrateId; | 11 | use ra_db::CrateId; |
| 12 | 12 | ||
| 13 | use hir_def::{ | 13 | use hir_def::{ |
| 14 | lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, | 14 | lang_item::LangItemTarget, resolver::HasResolver, AstItemDef, ContainerId, GenericDefId, |
| 15 | Lookup, TraitId, TypeAliasId, | ||
| 15 | }; | 16 | }; |
| 16 | use hir_expand::name; | 17 | use hir_expand::name; |
| 17 | 18 | ||
| @@ -22,7 +23,7 @@ use crate::{ | |||
| 22 | db::HirDatabase, | 23 | db::HirDatabase, |
| 23 | ty::display::HirDisplay, | 24 | ty::display::HirDisplay, |
| 24 | ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, | 25 | ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, |
| 25 | ImplBlock, TypeAlias, | 26 | ImplBlock, |
| 26 | }; | 27 | }; |
| 27 | 28 | ||
| 28 | /// This represents a trait whose name we could not resolve. | 29 | /// This represents a trait whose name we could not resolve. |
| @@ -452,7 +453,7 @@ where | |||
| 452 | .impls_for_trait(self.krate, trait_.into()) | 453 | .impls_for_trait(self.krate, trait_.into()) |
| 453 | .iter() | 454 | .iter() |
| 454 | .copied() | 455 | .copied() |
| 455 | .map(Impl::ImplBlock) | 456 | .map(|it| Impl::ImplBlock(it.into())) |
| 456 | .map(|impl_| impl_.to_chalk(self.db)) | 457 | .map(|impl_| impl_.to_chalk(self.db)) |
| 457 | .collect(); | 458 | .collect(); |
| 458 | 459 | ||
| @@ -670,7 +671,7 @@ fn impl_block_datum( | |||
| 670 | // don't include associated types that don't exist in the trait | 671 | // don't include associated types that don't exist in the trait |
| 671 | trait_data.associated_type_by_name(&type_alias.name(db)).is_some() | 672 | trait_data.associated_type_by_name(&type_alias.name(db)).is_some() |
| 672 | }) | 673 | }) |
| 673 | .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) | 674 | .map(|type_alias| AssocTyValue::TypeAlias(type_alias.id).to_chalk(db)) |
| 674 | .collect(); | 675 | .collect(); |
| 675 | debug!("impl_datum: {:?}", impl_datum_bound); | 676 | debug!("impl_datum: {:?}", impl_datum_bound); |
| 676 | let impl_datum = ImplDatum { | 677 | let impl_datum = ImplDatum { |
| @@ -773,24 +774,33 @@ pub(crate) fn associated_ty_value_query( | |||
| 773 | fn type_alias_associated_ty_value( | 774 | fn type_alias_associated_ty_value( |
| 774 | db: &impl HirDatabase, | 775 | db: &impl HirDatabase, |
| 775 | _krate: CrateId, | 776 | _krate: CrateId, |
| 776 | type_alias: TypeAlias, | 777 | type_alias: TypeAliasId, |
| 777 | ) -> Arc<AssociatedTyValue<ChalkIr>> { | 778 | ) -> Arc<AssociatedTyValue<ChalkIr>> { |
| 778 | let impl_block = type_alias.impl_block(db).expect("assoc ty value should be in impl"); | 779 | let type_alias_data = db.type_alias_data(type_alias); |
| 779 | let impl_id = Impl::ImplBlock(impl_block).to_chalk(db); | 780 | let impl_id = match type_alias.lookup(db).container { |
| 780 | let trait_ = impl_block | 781 | ContainerId::ImplId(it) => it, |
| 781 | .target_trait_ref(db) | 782 | _ => panic!("assoc ty value should be in impl"), |
| 782 | .expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved | 783 | }; |
| 783 | .trait_; | 784 | |
| 785 | let impl_data = db.impl_data(impl_id); | ||
| 786 | let resolver = impl_id.resolver(db); | ||
| 787 | let target_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | ||
| 788 | let target_trait = impl_data | ||
| 789 | .target_trait | ||
| 790 | .as_ref() | ||
| 791 | .and_then(|trait_ref| TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))) | ||
| 792 | .expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved | ||
| 793 | |||
| 784 | let assoc_ty = db | 794 | let assoc_ty = db |
| 785 | .trait_data(trait_) | 795 | .trait_data(target_trait.trait_) |
| 786 | .associated_type_by_name(&type_alias.name(db)) | 796 | .associated_type_by_name(&type_alias_data.name) |
| 787 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 797 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
| 788 | let generic_params = db.generic_params(impl_block.id.into()); | 798 | let generic_params = db.generic_params(impl_id.into()); |
| 789 | let bound_vars = Substs::bound_vars(&generic_params); | 799 | let bound_vars = Substs::bound_vars(&generic_params); |
| 790 | let ty = db.ty(type_alias.id.into()).subst(&bound_vars); | 800 | let ty = db.ty(type_alias.into()).subst(&bound_vars); |
| 791 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; | 801 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; |
| 792 | let value = chalk_rust_ir::AssociatedTyValue { | 802 | let value = chalk_rust_ir::AssociatedTyValue { |
| 793 | impl_id, | 803 | impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), |
| 794 | associated_ty_id: assoc_ty.to_chalk(db), | 804 | associated_ty_id: assoc_ty.to_chalk(db), |
| 795 | value: make_binders(value_bound, bound_vars.len()), | 805 | value: make_binders(value_bound, bound_vars.len()), |
| 796 | }; | 806 | }; |
