Skip to content

Commit 0f7961d

Browse files
Merge #4952
4952: Shift bound variables correctly when using assoc type shorthand r=matklad a=flodiebold Fixes #4885. Fixes #4800. Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
2 parents af0dcc5 + 170cdf9 commit 0f7961d

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

crates/ra_hir_ty/src/lower.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ impl Ty {
467467
}
468468
TypeParamLoweringMode::Variable => t.substs.clone(),
469469
};
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);
470473
// FIXME handle type parameters on the segment
471474
return Some(Ty::Projection(ProjectionTy {
472475
associated_ty,

crates/ra_hir_ty/src/tests/regression.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,3 +693,94 @@ fn check<T: PrimInt>(i: T) {
693693
"###
694694
);
695695
}
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+
}

0 commit comments

Comments
 (0)