mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-17 02:08:30 +00:00
Shift bound variables correctly when using assoc type shorthand
Fixes #4885. Fixes #4800.
This commit is contained in:
parent
1d4388f6bd
commit
170cdf9076
2 changed files with 94 additions and 0 deletions
|
@ -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,
|
||||
|
|
|
@ -693,3 +693,94 @@ fn check<T: PrimInt>(i: T) {
|
|||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_4885() {
|
||||
assert_snapshot!(
|
||||
infer(r#"
|
||||
#[lang = "coerce_unsized"]
|
||||
pub trait CoerceUnsized<T> {}
|
||||
|
||||
trait Future {
|
||||
type Output;
|
||||
}
|
||||
trait Foo<R> {
|
||||
type Bar;
|
||||
}
|
||||
fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar>
|
||||
where
|
||||
K: Foo<R>,
|
||||
{
|
||||
bar(key)
|
||||
}
|
||||
fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
|
||||
where
|
||||
K: Foo<R>,
|
||||
{
|
||||
}
|
||||
"#),
|
||||
@r###"
|
||||
137..140 'key': &K
|
||||
199..215 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
|
||||
205..208 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
|
||||
205..213 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
|
||||
209..212 'key': &K
|
||||
229..232 'key': &K
|
||||
291..294 '{ }': ()
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_4800() {
|
||||
assert_snapshot!(
|
||||
infer(r#"
|
||||
trait Debug {}
|
||||
|
||||
struct Foo<T>;
|
||||
|
||||
type E1<T> = (T, T, T);
|
||||
type E2<T> = E1<E1<E1<(T, T, T)>>>;
|
||||
|
||||
impl Debug for Foo<E2<()>> {}
|
||||
|
||||
struct Request;
|
||||
|
||||
pub trait Future {
|
||||
type Output;
|
||||
}
|
||||
|
||||
pub struct PeerSet<D>;
|
||||
|
||||
impl<D> Service<Request> for PeerSet<D>
|
||||
where
|
||||
D: Discover,
|
||||
D::Key: Debug,
|
||||
{
|
||||
type Error = ();
|
||||
type Future = dyn Future<Output = Self::Error>;
|
||||
|
||||
fn call(&mut self) -> Self::Future {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Discover {
|
||||
type Key;
|
||||
}
|
||||
|
||||
pub trait Service<Request> {
|
||||
type Error;
|
||||
type Future: Future<Output = Self::Error>;
|
||||
fn call(&mut self) -> Self::Future;
|
||||
}
|
||||
"#),
|
||||
@r###"
|
||||
380..384 'self': &mut PeerSet<D>
|
||||
402..425 '{ ... }': dyn Future<Output = ()>
|
||||
412..419 'loop {}': !
|
||||
417..419 '{}': ()
|
||||
576..580 'self': &mut Self
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue