mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
Auto merge of #17916 - ShoyuVanilla:issue-17711, r=Veykril
fix: Wrong BoundVar index when lowering impl trait parameter of parent generics Fixes #17711 From the following test code; ```rust //- minicore: deref use core::ops::Deref; struct Struct<'a, T>(&'a T); trait Trait {} impl<'a, T: Deref<Target = impl Trait>> Struct<'a, T> { fn foo(&self) -> &Self { self } fn bar(&self) { let _ = self.foo(); } } ``` when we call `register_obligations_for_call` for `let _ = self.foo();`,07659783fd/crates/hir-ty/src/infer/expr.rs (L1939-L1952)
we are querying `generic_predicates` and it has `T: Deref<Target = impl Trait>` predicate from the parent `impl Struct`;07659783fd/crates/hir-ty/src/lower.rs (L375-L399)
but as we can see above, lowering `TypeRef = impl Trait` doesn't take into account the parent generic parameters, so the `BoundVar` index here is `0`, as `fn foo` has no generic args other than parent's, But this `BoundVar` is pointing at `'a` in `<'a, T: Deref<Target = impl Trait>>`. So, in the first code reference `register_obligations_for_call`'s L:1948 - `.substitute(Interner, parameters)`, we are substituting `'a` with `Ty`, not `Lifetime` and this makes panic inside the chalk. This PR fixes this wrong `BoundVar` index in such cases
This commit is contained in:
commit
469b06214a
2 changed files with 50 additions and 18 deletions
|
@ -377,26 +377,25 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
// Count the number of `impl Trait` things that appear within our bounds.
|
// Count the number of `impl Trait` things that appear within our bounds.
|
||||||
// Since t hose have been emitted as implicit type args already.
|
// Since t hose have been emitted as implicit type args already.
|
||||||
counter.set(idx + count_impl_traits(type_ref) as u16);
|
counter.set(idx + count_impl_traits(type_ref) as u16);
|
||||||
let (
|
let kind = self
|
||||||
_parent_params,
|
|
||||||
self_param,
|
|
||||||
type_params,
|
|
||||||
const_params,
|
|
||||||
_impl_trait_params,
|
|
||||||
lifetime_params,
|
|
||||||
) = self
|
|
||||||
.generics()
|
.generics()
|
||||||
.expect("variable impl trait lowering must be in a generic def")
|
.expect("variable impl trait lowering must be in a generic def")
|
||||||
.provenance_split();
|
.iter()
|
||||||
TyKind::BoundVar(BoundVar::new(
|
.enumerate()
|
||||||
self.in_binders,
|
.filter_map(|(i, (id, data))| match (id, data) {
|
||||||
idx as usize
|
(
|
||||||
+ self_param as usize
|
GenericParamId::TypeParamId(_),
|
||||||
+ type_params
|
GenericParamDataRef::TypeParamData(data),
|
||||||
+ const_params
|
) if data.provenance == TypeParamProvenance::ArgumentImplTrait => {
|
||||||
+ lifetime_params,
|
Some(i)
|
||||||
))
|
}
|
||||||
.intern(Interner)
|
_ => None,
|
||||||
|
})
|
||||||
|
.nth(idx as usize)
|
||||||
|
.map_or(TyKind::Error, |id| {
|
||||||
|
TyKind::BoundVar(BoundVar { debruijn: self.in_binders, index: id })
|
||||||
|
});
|
||||||
|
kind.intern(Interner)
|
||||||
}
|
}
|
||||||
ImplTraitLoweringState::Disallowed => {
|
ImplTraitLoweringState::Disallowed => {
|
||||||
// FIXME: report error
|
// FIXME: report error
|
||||||
|
|
|
@ -2162,3 +2162,36 @@ fn main() {
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn issue_17711() {
|
||||||
|
check_infer(
|
||||||
|
r#"
|
||||||
|
//- minicore: deref
|
||||||
|
use core::ops::Deref;
|
||||||
|
|
||||||
|
struct Struct<'a, T>(&'a T);
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
impl<'a, T: Deref<Target = impl Trait>> Struct<'a, T> {
|
||||||
|
fn foo(&self) -> &Self { self }
|
||||||
|
|
||||||
|
fn bar(&self) {
|
||||||
|
let _ = self.foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
137..141 'self': &'? Struct<'a, T>
|
||||||
|
152..160 '{ self }': &'? Struct<'a, T>
|
||||||
|
154..158 'self': &'? Struct<'a, T>
|
||||||
|
174..178 'self': &'? Struct<'a, T>
|
||||||
|
180..215 '{ ... }': ()
|
||||||
|
194..195 '_': &'? Struct<'?, T>
|
||||||
|
198..202 'self': &'? Struct<'a, T>
|
||||||
|
198..208 'self.foo()': &'? Struct<'?, T>
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue