diff options
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 91 |
2 files changed, 94 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 7a7fcb0ab..d5154f436 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -467,6 +467,9 @@ impl Ty { | |||
467 | } | 467 | } |
468 | TypeParamLoweringMode::Variable => t.substs.clone(), | 468 | TypeParamLoweringMode::Variable => t.substs.clone(), |
469 | }; | 469 | }; |
470 | // We need to shift in the bound vars, since | ||
471 | // associated_type_shorthand_candidates does not do that | ||
472 | let substs = substs.shift_bound_vars(ctx.in_binders); | ||
470 | // FIXME handle type parameters on the segment | 473 | // FIXME handle type parameters on the segment |
471 | return Some(Ty::Projection(ProjectionTy { | 474 | return Some(Ty::Projection(ProjectionTy { |
472 | associated_ty, | 475 | associated_ty, |
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 8dc5603b7..4da2e972b 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs | |||
@@ -693,3 +693,94 @@ fn check<T: PrimInt>(i: T) { | |||
693 | "### | 693 | "### |
694 | ); | 694 | ); |
695 | } | 695 | } |
696 | |||
697 | #[test] | ||
698 | fn issue_4885() { | ||
699 | assert_snapshot!( | ||
700 | infer(r#" | ||
701 | #[lang = "coerce_unsized"] | ||
702 | pub trait CoerceUnsized<T> {} | ||
703 | |||
704 | trait Future { | ||
705 | type Output; | ||
706 | } | ||
707 | trait Foo<R> { | ||
708 | type Bar; | ||
709 | } | ||
710 | fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> | ||
711 | where | ||
712 | K: Foo<R>, | ||
713 | { | ||
714 | bar(key) | ||
715 | } | ||
716 | fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> | ||
717 | where | ||
718 | K: Foo<R>, | ||
719 | { | ||
720 | } | ||
721 | "#), | ||
722 | @r###" | ||
723 | 137..140 'key': &K | ||
724 | 199..215 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> | ||
725 | 205..208 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> | ||
726 | 205..213 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> | ||
727 | 209..212 'key': &K | ||
728 | 229..232 'key': &K | ||
729 | 291..294 '{ }': () | ||
730 | "### | ||
731 | ); | ||
732 | } | ||
733 | |||
734 | #[test] | ||
735 | fn issue_4800() { | ||
736 | assert_snapshot!( | ||
737 | infer(r#" | ||
738 | trait Debug {} | ||
739 | |||
740 | struct Foo<T>; | ||
741 | |||
742 | type E1<T> = (T, T, T); | ||
743 | type E2<T> = E1<E1<E1<(T, T, T)>>>; | ||
744 | |||
745 | impl Debug for Foo<E2<()>> {} | ||
746 | |||
747 | struct Request; | ||
748 | |||
749 | pub trait Future { | ||
750 | type Output; | ||
751 | } | ||
752 | |||
753 | pub struct PeerSet<D>; | ||
754 | |||
755 | impl<D> Service<Request> for PeerSet<D> | ||
756 | where | ||
757 | D: Discover, | ||
758 | D::Key: Debug, | ||
759 | { | ||
760 | type Error = (); | ||
761 | type Future = dyn Future<Output = Self::Error>; | ||
762 | |||
763 | fn call(&mut self) -> Self::Future { | ||
764 | loop {} | ||
765 | } | ||
766 | } | ||
767 | |||
768 | pub trait Discover { | ||
769 | type Key; | ||
770 | } | ||
771 | |||
772 | pub trait Service<Request> { | ||
773 | type Error; | ||
774 | type Future: Future<Output = Self::Error>; | ||
775 | fn call(&mut self) -> Self::Future; | ||
776 | } | ||
777 | "#), | ||
778 | @r###" | ||
779 | 380..384 'self': &mut PeerSet<D> | ||
780 | 402..425 '{ ... }': dyn Future<Output = ()> | ||
781 | 412..419 'loop {}': ! | ||
782 | 417..419 '{}': () | ||
783 | 576..580 'self': &mut Self | ||
784 | "### | ||
785 | ); | ||
786 | } | ||