aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/db.rs6
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs21
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs2
-rw-r--r--crates/ra_hir/src/ty/traits.rs10
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs42
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
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{GenericDefId, LocalStructFieldId, TraitId, VariantId}; 5use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId};
6use ra_arena::map::ArenaMap; 6use ra_arena::map::ArenaMap;
7use ra_db::{salsa, CrateId}; 7use 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
19pub use hir_def::db::{ 19pub 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
7use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId}; 7use hir_def::{
8 lang_item::LangItemTarget,
9 resolver::{HasResolver, Resolver},
10 AdtId,
11};
8use rustc_hash::FxHashMap; 12use rustc_hash::FxHashMap;
9use test_utils::tested_by; 13use test_utils::tested_by;
10 14
11use crate::{ 15use 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 @@
2use std::sync::{Arc, Mutex}; 2use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::{cast::Cast, family::ChalkIr};
5use hir_def::{expr::ExprId, DefWithBodyId, TraitId}; 5use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
6use log::debug; 6use log::debug;
7use ra_db::{impl_intern_key, salsa, CrateId}; 7use ra_db::{impl_intern_key, salsa, CrateId};
8use ra_prof::profile; 8use ra_prof::profile;
9use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
10 10
11use crate::{db::HirDatabase, ImplBlock, TypeAlias}; 11use crate::{db::HirDatabase, ImplBlock};
12 12
13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use 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)]
318pub enum AssocTyValue { 318pub 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
11use ra_db::CrateId; 11use ra_db::CrateId;
12 12
13use hir_def::{ 13use 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};
16use hir_expand::name; 17use 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(
773fn type_alias_associated_ty_value( 774fn 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 };