diff options
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 6c7bbc448..21e7baf8b 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -8,6 +8,8 @@ | |||
8 | use std::iter; | 8 | use std::iter; |
9 | use std::sync::Arc; | 9 | use std::sync::Arc; |
10 | 10 | ||
11 | use smallvec::SmallVec; | ||
12 | |||
11 | use hir_def::{ | 13 | use hir_def::{ |
12 | adt::StructKind, | 14 | adt::StructKind, |
13 | builtin_type::BuiltinType, | 15 | builtin_type::BuiltinType, |
@@ -596,21 +598,35 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
596 | .into_iter() | 598 | .into_iter() |
597 | .flat_map(|segment| segment.args_and_bindings.into_iter()) | 599 | .flat_map(|segment| segment.args_and_bindings.into_iter()) |
598 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) | 600 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) |
599 | .map(move |(name, type_ref)| { | 601 | .flat_map(move |binding| { |
600 | let associated_ty = associated_type_by_name_including_super_traits( | 602 | let associated_ty = associated_type_by_name_including_super_traits( |
601 | ctx.db.upcast(), | 603 | ctx.db.upcast(), |
602 | trait_ref.trait_, | 604 | trait_ref.trait_, |
603 | &name, | 605 | &binding.name, |
604 | ); | 606 | ); |
605 | let associated_ty = match associated_ty { | 607 | let associated_ty = match associated_ty { |
606 | None => return GenericPredicate::Error, | 608 | None => return SmallVec::<[GenericPredicate; 1]>::new(), |
607 | Some(t) => t, | 609 | Some(t) => t, |
608 | }; | 610 | }; |
609 | let projection_ty = | 611 | let projection_ty = |
610 | ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; | 612 | ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; |
611 | let ty = Ty::from_hir(ctx, type_ref); | 613 | let mut preds = SmallVec::with_capacity( |
612 | let projection_predicate = ProjectionPredicate { projection_ty, ty }; | 614 | binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), |
613 | GenericPredicate::Projection(projection_predicate) | 615 | ); |
616 | if let Some(type_ref) = &binding.type_ref { | ||
617 | let ty = Ty::from_hir(ctx, type_ref); | ||
618 | let projection_predicate = | ||
619 | ProjectionPredicate { projection_ty: projection_ty.clone(), ty }; | ||
620 | preds.push(GenericPredicate::Projection(projection_predicate)); | ||
621 | } | ||
622 | for bound in &binding.bounds { | ||
623 | preds.extend(GenericPredicate::from_type_bound( | ||
624 | ctx, | ||
625 | bound, | ||
626 | Ty::Projection(projection_ty.clone()), | ||
627 | )); | ||
628 | } | ||
629 | preds | ||
614 | }) | 630 | }) |
615 | } | 631 | } |
616 | 632 | ||