From 170cdf90769d7a2779ffd0a8cb552e5b2f63d11c Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 19 Jun 2020 18:32:42 +0200 Subject: Shift bound variables correctly when using assoc type shorthand Fixes #4885. Fixes #4800. --- crates/ra_hir_ty/src/lower.rs | 3 ++ crates/ra_hir_ty/src/tests/regression.rs | 91 ++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) (limited to 'crates/ra_hir_ty') 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 { } TypeParamLoweringMode::Variable => t.substs.clone(), }; + // We need to shift in the bound vars, since + // associated_type_shorthand_candidates does not do that + let substs = substs.shift_bound_vars(ctx.in_binders); // FIXME handle type parameters on the segment return Some(Ty::Projection(ProjectionTy { 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(i: T) { "### ); } + +#[test] +fn issue_4885() { + assert_snapshot!( + infer(r#" +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +trait Future { + type Output; +} +trait Foo { + type Bar; +} +fn foo(key: &K) -> impl Future +where + K: Foo, +{ + bar(key) +} +fn bar(key: &K) -> impl Future +where + K: Foo, +{ +} +"#), + @r###" + 137..140 'key': &K + 199..215 '{ ...key) }': impl Future>::Bar> + 205..208 'bar': fn bar(&K) -> impl Future>::Bar> + 205..213 'bar(key)': impl Future>::Bar> + 209..212 'key': &K + 229..232 'key': &K + 291..294 '{ }': () + "### + ); +} + +#[test] +fn issue_4800() { + assert_snapshot!( + infer(r#" +trait Debug {} + +struct Foo; + +type E1 = (T, T, T); +type E2 = E1>>; + +impl Debug for Foo> {} + +struct Request; + +pub trait Future { + type Output; +} + +pub struct PeerSet; + +impl Service for PeerSet +where + D: Discover, + D::Key: Debug, +{ + type Error = (); + type Future = dyn Future; + + fn call(&mut self) -> Self::Future { + loop {} + } +} + +pub trait Discover { + type Key; +} + +pub trait Service { + type Error; + type Future: Future; + fn call(&mut self) -> Self::Future; +} +"#), + @r###" + 380..384 'self': &mut PeerSet + 402..425 '{ ... }': dyn Future + 412..419 'loop {}': ! + 417..419 '{}': () + 576..580 'self': &mut Self + "### + ); +} -- cgit v1.2.3