aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-06-19 17:32:42 +0100
committerFlorian Diebold <[email protected]>2020-06-19 21:07:58 +0100
commit170cdf90769d7a2779ffd0a8cb552e5b2f63d11c (patch)
treed0930615d22a99de16b502ea99409cca5313c922 /crates/ra_hir_ty
parent1d4388f6bd02e6dda816028f0bdac7b39225ca0b (diff)
Shift bound variables correctly when using assoc type shorthand
Fixes #4885. Fixes #4800.
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/lower.rs3
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs91
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]
698fn issue_4885() {
699 assert_snapshot!(
700 infer(r#"
701#[lang = "coerce_unsized"]
702pub trait CoerceUnsized<T> {}
703
704trait Future {
705 type Output;
706}
707trait Foo<R> {
708 type Bar;
709}
710fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar>
711where
712 K: Foo<R>,
713{
714 bar(key)
715}
716fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
717where
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]
735fn issue_4800() {
736 assert_snapshot!(
737 infer(r#"
738trait Debug {}
739
740struct Foo<T>;
741
742type E1<T> = (T, T, T);
743type E2<T> = E1<E1<E1<(T, T, T)>>>;
744
745impl Debug for Foo<E2<()>> {}
746
747struct Request;
748
749pub trait Future {
750 type Output;
751}
752
753pub struct PeerSet<D>;
754
755impl<D> Service<Request> for PeerSet<D>
756where
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
768pub trait Discover {
769 type Key;
770}
771
772pub 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}