diff options
author | Florian Diebold <[email protected]> | 2019-09-07 13:31:43 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-09-07 13:31:43 +0100 |
commit | 60bdb66ef23f78d8c73afa1897a4542e7e722ed2 (patch) | |
tree | cc5dc599d3c369a4769c792a2c440749ed4b7771 /crates/ra_hir/src/ty | |
parent | 4ae4d9c311084e3092eb4c2d35e98f6c2c70315b (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.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 27 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 2 |
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; | |||
8 | use log::{info, warn}; | 8 | use log::{info, warn}; |
9 | 9 | ||
10 | use super::{traits::Solution, Canonical, Ty, TypeWalk}; | 10 | use super::{traits::Solution, Canonical, Ty, TypeWalk}; |
11 | use crate::{HasGenericParams, HirDatabase, Name, Resolver}; | 11 | use crate::{name, HasGenericParams, HirDatabase, Resolver}; |
12 | 12 | ||
13 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 13 | const 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, |