6852: Ignore lifetime params in substitutions r=matklad a=Veykril

[`hir_ty::utils::Generics`](https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/hir_ty/src/utils.rs#L153) currently only assumes type parameters but not lifetime parameters and therefor creates incorrect index and length calculations, this PR just makes the use sites ignore LifetimeGenerics for now.

This fixes the panic at least locally for me for `analysis-stats`. Funnily enough this panic prevented me from using reference search for the `args` field to fix this problem.

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2020-12-13 11:34:43 +00:00 committed by GitHub
commit ca3a54f0a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 3 deletions

View file

@ -246,7 +246,10 @@ struct GenericParamsStorage {
impl GenericParamsStorage {
fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
if params.types.is_empty() && params.where_predicates.is_empty() {
if params.types.is_empty()
&& params.lifetimes.is_empty()
&& params.where_predicates.is_empty()
{
return GenericParamsId::EMPTY;
}

View file

@ -856,7 +856,12 @@ impl<'a> InferenceContext<'a> {
// handle provided type arguments
if let Some(generic_args) = generic_args {
// if args are provided, it should be all of them, but we can't rely on that
for arg in generic_args.args.iter().take(type_params) {
for arg in generic_args
.args
.iter()
.filter(|arg| matches!(arg, GenericArg::Type(_)))
.take(type_params)
{
match arg {
GenericArg::Type(type_ref) => {
let ty = self.make_ty(type_ref);

View file

@ -565,7 +565,13 @@ fn substs_from_path_segment(
if generic_args.has_self_type { self_params + type_params } else { type_params };
let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
// if args are provided, it should be all of them, but we can't rely on that
for arg in generic_args.args.iter().skip(skip).take(expected_num) {
for arg in generic_args
.args
.iter()
.filter(|arg| matches!(arg, GenericArg::Type(_)))
.skip(skip)
.take(expected_num)
{
match arg {
GenericArg::Type(type_ref) => {
had_explicit_type_args = true;