aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-09-07 13:31:43 +0100
committerFlorian Diebold <[email protected]>2019-09-07 13:31:43 +0100
commit60bdb66ef23f78d8c73afa1897a4542e7e722ed2 (patch)
treecc5dc599d3c369a4769c792a2c440749ed4b7771 /crates/ra_hir/src/ty
parent4ae4d9c311084e3092eb4c2d35e98f6c2c70315b (diff)
Lower bounds on trait definition, and resolve assoc types from super traits
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs4
-rw-r--r--crates/ra_hir/src/ty/infer.rs6
-rw-r--r--crates/ra_hir/src/ty/lower.rs27
-rw-r--r--crates/ra_hir/src/ty/tests.rs10
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs2
5 files changed, 26 insertions, 23 deletions
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 08f52a53b..caa17f64e 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -8,7 +8,7 @@ use std::iter::successors;
8use log::{info, warn}; 8use log::{info, warn};
9 9
10use super::{traits::Solution, Canonical, Ty, TypeWalk}; 10use super::{traits::Solution, Canonical, Ty, TypeWalk};
11use crate::{HasGenericParams, HirDatabase, Name, Resolver}; 11use crate::{name, HasGenericParams, HirDatabase, Resolver};
12 12
13const AUTODEREF_RECURSION_LIMIT: usize = 10; 13const AUTODEREF_RECURSION_LIMIT: usize = 10;
14 14
@@ -42,7 +42,7 @@ fn deref_by_trait(
42 crate::lang_item::LangItemTarget::Trait(t) => t, 42 crate::lang_item::LangItemTarget::Trait(t) => t,
43 _ => return None, 43 _ => return None,
44 }; 44 };
45 let target = deref_trait.associated_type_by_name(db, Name::target())?; 45 let target = deref_trait.associated_type_by_name(db, &name::TARGET)?;
46 46
47 if target.generic_params(db).count_params_including_parent() != 1 { 47 if target.generic_params(db).count_params_including_parent() != 1 {
48 // the Target type + Deref trait should only have one generic parameter, 48 // the Target type + Deref trait should only have one generic parameter,
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index ec3b7ffef..0e6ebd365 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -1453,7 +1453,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1453 1453
1454 match self.resolver.resolve_path_segments(self.db, &into_iter_path).into_fully_resolved() { 1454 match self.resolver.resolve_path_segments(self.db, &into_iter_path).into_fully_resolved() {
1455 PerNs { types: Some(Def(Trait(trait_))), .. } => { 1455 PerNs { types: Some(Def(Trait(trait_))), .. } => {
1456 Some(trait_.associated_type_by_name(self.db, name::ITEM)?) 1456 Some(trait_.associated_type_by_name(self.db, &name::ITEM)?)
1457 } 1457 }
1458 _ => None, 1458 _ => None,
1459 } 1459 }
@@ -1471,7 +1471,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1471 1471
1472 match self.resolver.resolve_path_segments(self.db, &ops_try_path).into_fully_resolved() { 1472 match self.resolver.resolve_path_segments(self.db, &ops_try_path).into_fully_resolved() {
1473 PerNs { types: Some(Def(Trait(trait_))), .. } => { 1473 PerNs { types: Some(Def(Trait(trait_))), .. } => {
1474 Some(trait_.associated_type_by_name(self.db, name::OK)?) 1474 Some(trait_.associated_type_by_name(self.db, &name::OK)?)
1475 } 1475 }
1476 _ => None, 1476 _ => None,
1477 } 1477 }
@@ -1493,7 +1493,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1493 .into_fully_resolved() 1493 .into_fully_resolved()
1494 { 1494 {
1495 PerNs { types: Some(Def(Trait(trait_))), .. } => { 1495 PerNs { types: Some(Def(Trait(trait_))), .. } => {
1496 Some(trait_.associated_type_by_name(self.db, name::OUTPUT)?) 1496 Some(trait_.associated_type_by_name(self.db, &name::OUTPUT)?)
1497 } 1497 }
1498 _ => None, 1498 _ => None,
1499 } 1499 }
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index f6f0137cf..480bae740 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -132,14 +132,16 @@ impl Ty {
132 if let Some(remaining_index) = remaining_index { 132 if let Some(remaining_index) = remaining_index {
133 if remaining_index == path.segments.len() - 1 { 133 if remaining_index == path.segments.len() - 1 {
134 let segment = &path.segments[remaining_index]; 134 let segment = &path.segments[remaining_index];
135 let associated_ty = 135 let associated_ty = match trait_ref
136 match trait_ref.trait_.associated_type_by_name(db, segment.name.clone()) { 136 .trait_
137 Some(t) => t, 137 .associated_type_by_name_including_super_traits(db, &segment.name)
138 None => { 138 {
139 // associated type not found 139 Some(t) => t,
140 return Ty::Unknown; 140 None => {
141 } 141 // associated type not found
142 }; 142 return Ty::Unknown;
143 }
144 };
143 // FIXME handle type parameters on the segment 145 // FIXME handle type parameters on the segment
144 Ty::Projection(ProjectionTy { associated_ty, parameters: trait_ref.substs }) 146 Ty::Projection(ProjectionTy { associated_ty, parameters: trait_ref.substs })
145 } else { 147 } else {
@@ -387,10 +389,11 @@ fn assoc_type_bindings_from_type_bound<'a>(
387 .flat_map(|segment| segment.args_and_bindings.iter()) 389 .flat_map(|segment| segment.args_and_bindings.iter())
388 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 390 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
389 .map(move |(name, type_ref)| { 391 .map(move |(name, type_ref)| {
390 let associated_ty = match trait_ref.trait_.associated_type_by_name(db, name.clone()) { 392 let associated_ty =
391 None => return GenericPredicate::Error, 393 match trait_ref.trait_.associated_type_by_name_including_super_traits(db, &name) {
392 Some(t) => t, 394 None => return GenericPredicate::Error,
393 }; 395 Some(t) => t,
396 };
394 let projection_ty = 397 let projection_ty =
395 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; 398 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
396 let ty = Ty::from_hir(db, resolver, type_ref); 399 let ty = Ty::from_hir(db, resolver, type_ref);
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index cb5540cb6..17c4e3556 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3720,11 +3720,11 @@ fn test() {
3720 [157; 160) '{t}': T 3720 [157; 160) '{t}': T
3721 [158; 159) 't': T 3721 [158; 159) 't': T
3722 [259; 280) '{ ...S)); }': () 3722 [259; 280) '{ ...S)); }': ()
3723 [265; 269) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U 3723 [265; 269) 'get2': fn get2<u64, S<u64>>(T) -> U
3724 [265; 277) 'get2(set(S))': {unknown} 3724 [265; 277) 'get2(set(S))': u64
3725 [270; 273) 'set': fn set<S<{unknown}>>(T) -> T 3725 [270; 273) 'set': fn set<S<u64>>(T) -> T
3726 [270; 276) 'set(S)': S<{unknown}> 3726 [270; 276) 'set(S)': S<u64>
3727 [274; 275) 'S': S<{unknown}> 3727 [274; 275) 'S': S<u64>
3728 "### 3728 "###
3729 ); 3729 );
3730} 3730}
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index c201c5e50..cfe0cab16 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -636,7 +636,7 @@ pub(crate) fn impl_datum_query(
636 _ => None, 636 _ => None,
637 }) 637 })
638 .filter_map(|t| { 638 .filter_map(|t| {
639 let assoc_ty = trait_.associated_type_by_name(db, t.name(db))?; 639 let assoc_ty = trait_.associated_type_by_name(db, &t.name(db))?;
640 let ty = db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars); 640 let ty = db.type_for_def(t.into(), crate::Namespace::Types).subst(&bound_vars);
641 Some(chalk_rust_ir::AssociatedTyValue { 641 Some(chalk_rust_ir::AssociatedTyValue {
642 impl_id, 642 impl_id,