about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-02 12:20:54 +0000
committerbors <bors@rust-lang.org>2024-07-02 12:20:54 +0000
commit260a380e09b32d9209a78de47125afdc0077e0d0 (patch)
tree1497557b586b6abb3f8bc36591fd67dd8636ace2
parent96718417af0b413b959e6cd0dd214171fcb3dcd3 (diff)
parent0fef8f01a36c9e93f900b896ad1bc6722a6de67c (diff)
downloadrust-260a380e09b32d9209a78de47125afdc0077e0d0.tar.gz
rust-260a380e09b32d9209a78de47125afdc0077e0d0.zip
Auto merge of #17530 - Veykril:lifetime-order, r=Veykril
Move lifetimes in front of type and const params but after self
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/generics.rs417
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/src.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/generics.rs35
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs116
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs30
12 files changed, 333 insertions, 329 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs b/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs
index 106109eb184..0438278ca27 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs
@@ -214,8 +214,8 @@ impl ChildBySource for GenericDefId {
         }
 
         let generic_params = db.generic_params(*self);
-        let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
-        let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
+        let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx);
+        let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
 
         // For traits the first type index is `Self`, skip it.
         if let GenericDefId::TraitId(_) = *self {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
index ca02501567c..ebaaef66db6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
@@ -28,6 +28,7 @@ use crate::{
     LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
 };
 
+/// The index of the self param in the generic of the non-parent definition.
 const SELF_PARAM_ID_IN_SELF: la_arena::Idx<TypeOrConstParamData> =
     LocalTypeOrConstParamId::from_raw(RawIdx::from_u32(0));
 
@@ -158,9 +159,9 @@ pub enum GenericParamDataRef<'a> {
 /// Data about the generic parameters of a function, struct, impl, etc.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct GenericParams {
-    pub type_or_consts: Arena<TypeOrConstParamData>,
-    pub lifetimes: Arena<LifetimeParamData>,
-    pub where_predicates: Box<[WherePredicate]>,
+    type_or_consts: Arena<TypeOrConstParamData>,
+    lifetimes: Arena<LifetimeParamData>,
+    where_predicates: Box<[WherePredicate]>,
 }
 
 impl ops::Index<LocalTypeOrConstParamId> for GenericParams {
@@ -205,6 +206,219 @@ pub enum WherePredicateTypeTarget {
     TypeOrConstParam(LocalTypeOrConstParamId),
 }
 
+impl GenericParams {
+    /// Number of Generic parameters (type_or_consts + lifetimes)
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.type_or_consts.len() + self.lifetimes.len()
+    }
+
+    #[inline]
+    pub fn len_lifetimes(&self) -> usize {
+        self.lifetimes.len()
+    }
+
+    #[inline]
+    pub fn len_type_or_consts(&self) -> usize {
+        self.type_or_consts.len()
+    }
+
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
+    #[inline]
+    pub fn where_predicates(&self) -> std::slice::Iter<'_, WherePredicate> {
+        self.where_predicates.iter()
+    }
+
+    /// Iterator of type_or_consts field
+    #[inline]
+    pub fn iter_type_or_consts(
+        &self,
+    ) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
+        self.type_or_consts.iter()
+    }
+
+    /// Iterator of lifetimes field
+    #[inline]
+    pub fn iter_lt(
+        &self,
+    ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
+        self.lifetimes.iter()
+    }
+
+    pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {
+        self.type_or_consts.iter().find_map(|(id, p)| {
+            if p.name().as_ref() == Some(&name) && p.type_param().is_some() {
+                Some(TypeParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
+            } else {
+                None
+            }
+        })
+    }
+
+    pub fn find_const_by_name(&self, name: &Name, parent: GenericDefId) -> Option<ConstParamId> {
+        self.type_or_consts.iter().find_map(|(id, p)| {
+            if p.name().as_ref() == Some(&name) && p.const_param().is_some() {
+                Some(ConstParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
+            } else {
+                None
+            }
+        })
+    }
+
+    #[inline]
+    pub fn trait_self_param(&self) -> Option<LocalTypeOrConstParamId> {
+        if self.type_or_consts.is_empty() {
+            return None;
+        }
+        matches!(
+            self.type_or_consts[SELF_PARAM_ID_IN_SELF],
+            TypeOrConstParamData::TypeParamData(TypeParamData {
+                provenance: TypeParamProvenance::TraitSelf,
+                ..
+            })
+        )
+        .then(|| SELF_PARAM_ID_IN_SELF)
+    }
+
+    pub fn find_lifetime_by_name(
+        &self,
+        name: &Name,
+        parent: GenericDefId,
+    ) -> Option<LifetimeParamId> {
+        self.lifetimes.iter().find_map(|(id, p)| {
+            if &p.name == name {
+                Some(LifetimeParamId { local_id: id, parent })
+            } else {
+                None
+            }
+        })
+    }
+
+    pub(crate) fn generic_params_query(
+        db: &dyn DefDatabase,
+        def: GenericDefId,
+    ) -> Interned<GenericParams> {
+        let _p = tracing::info_span!("generic_params_query").entered();
+
+        let krate = def.krate(db);
+        let cfg_options = db.crate_graph();
+        let cfg_options = &cfg_options[krate].cfg_options;
+
+        // Returns the generic parameters that are enabled under the current `#[cfg]` options
+        let enabled_params =
+            |params: &Interned<GenericParams>, item_tree: &ItemTree, parent: GenericModItem| {
+                let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
+                let attr_owner_ct = |param| AttrOwner::TypeOrConstParamData(parent, param);
+                let attr_owner_lt = |param| AttrOwner::LifetimeParamData(parent, param);
+
+                // In the common case, no parameters will by disabled by `#[cfg]` attributes.
+                // Therefore, make a first pass to check if all parameters are enabled and, if so,
+                // clone the `Interned<GenericParams>` instead of recreating an identical copy.
+                let all_type_or_consts_enabled =
+                    params.type_or_consts.iter().all(|(idx, _)| enabled(attr_owner_ct(idx)));
+                let all_lifetimes_enabled =
+                    params.lifetimes.iter().all(|(idx, _)| enabled(attr_owner_lt(idx)));
+
+                if all_type_or_consts_enabled && all_lifetimes_enabled {
+                    params.clone()
+                } else {
+                    Interned::new(GenericParams {
+                        type_or_consts: all_type_or_consts_enabled
+                            .then(|| params.type_or_consts.clone())
+                            .unwrap_or_else(|| {
+                                params
+                                    .type_or_consts
+                                    .iter()
+                                    .filter(|&(idx, _)| enabled(attr_owner_ct(idx)))
+                                    .map(|(_, param)| param.clone())
+                                    .collect()
+                            }),
+                        lifetimes: all_lifetimes_enabled
+                            .then(|| params.lifetimes.clone())
+                            .unwrap_or_else(|| {
+                                params
+                                    .lifetimes
+                                    .iter()
+                                    .filter(|&(idx, _)| enabled(attr_owner_lt(idx)))
+                                    .map(|(_, param)| param.clone())
+                                    .collect()
+                            }),
+                        where_predicates: params.where_predicates.clone(),
+                    })
+                }
+            };
+        fn id_to_generics<Id: GenericsItemTreeNode>(
+            db: &dyn DefDatabase,
+            id: impl for<'db> Lookup<
+                Database<'db> = dyn DefDatabase + 'db,
+                Data = impl ItemTreeLoc<Id = Id>,
+            >,
+            enabled_params: impl Fn(
+                &Interned<GenericParams>,
+                &ItemTree,
+                GenericModItem,
+            ) -> Interned<GenericParams>,
+        ) -> Interned<GenericParams>
+        where
+            FileItemTreeId<Id>: Into<GenericModItem>,
+        {
+            let id = id.lookup(db).item_tree_id();
+            let tree = id.item_tree(db);
+            let item = &tree[id.value];
+            enabled_params(item.generic_params(), &tree, id.value.into())
+        }
+
+        match def {
+            GenericDefId::FunctionId(id) => {
+                let loc = id.lookup(db);
+                let tree = loc.id.item_tree(db);
+                let item = &tree[loc.id.value];
+
+                let enabled_params =
+                    enabled_params(&item.explicit_generic_params, &tree, loc.id.value.into());
+
+                let module = loc.container.module(db);
+                let func_data = db.function_data(id);
+                if func_data.params.is_empty() {
+                    enabled_params
+                } else {
+                    let mut generic_params = GenericParamsCollector {
+                        type_or_consts: enabled_params.type_or_consts.clone(),
+                        lifetimes: enabled_params.lifetimes.clone(),
+                        where_predicates: enabled_params.where_predicates.clone().into(),
+                    };
+
+                    // Don't create an `Expander` if not needed since this
+                    // could cause a reparse after the `ItemTree` has been created due to the spanmap.
+                    let mut expander = Lazy::new(|| {
+                        (module.def_map(db), Expander::new(db, loc.id.file_id(), module))
+                    });
+                    for param in func_data.params.iter() {
+                        generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
+                    }
+                    Interned::new(generic_params.finish())
+                }
+            }
+            GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics(db, id, enabled_params),
+            GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics(db, id, enabled_params),
+            GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics(db, id, enabled_params),
+            GenericDefId::TraitId(id) => id_to_generics(db, id, enabled_params),
+            GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params),
+            GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params),
+            GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params),
+            GenericDefId::ConstId(_) => Interned::new(GenericParams {
+                type_or_consts: Default::default(),
+                lifetimes: Default::default(),
+                where_predicates: Default::default(),
+            }),
+        }
+    }
+}
+
 #[derive(Clone, Default)]
 pub(crate) struct GenericParamsCollector {
     pub(crate) type_or_consts: Arena<TypeOrConstParamData>,
@@ -441,200 +655,3 @@ impl GenericParamsCollector {
         }
     }
 }
-
-impl GenericParams {
-    /// Number of Generic parameters (type_or_consts + lifetimes)
-    #[inline]
-    pub fn len(&self) -> usize {
-        self.type_or_consts.len() + self.lifetimes.len()
-    }
-
-    #[inline]
-    pub fn is_empty(&self) -> bool {
-        self.len() == 0
-    }
-
-    /// Iterator of type_or_consts field
-    #[inline]
-    pub fn iter_type_or_consts(
-        &self,
-    ) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
-        self.type_or_consts.iter()
-    }
-
-    /// Iterator of lifetimes field
-    #[inline]
-    pub fn iter_lt(
-        &self,
-    ) -> impl DoubleEndedIterator<Item = (LocalLifetimeParamId, &LifetimeParamData)> {
-        self.lifetimes.iter()
-    }
-
-    pub(crate) fn generic_params_query(
-        db: &dyn DefDatabase,
-        def: GenericDefId,
-    ) -> Interned<GenericParams> {
-        let _p = tracing::info_span!("generic_params_query").entered();
-
-        let krate = def.module(db).krate;
-        let cfg_options = db.crate_graph();
-        let cfg_options = &cfg_options[krate].cfg_options;
-
-        // Returns the generic parameters that are enabled under the current `#[cfg]` options
-        let enabled_params =
-            |params: &Interned<GenericParams>, item_tree: &ItemTree, parent: GenericModItem| {
-                let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
-                let attr_owner_ct = |param| AttrOwner::TypeOrConstParamData(parent, param);
-                let attr_owner_lt = |param| AttrOwner::LifetimeParamData(parent, param);
-
-                // In the common case, no parameters will by disabled by `#[cfg]` attributes.
-                // Therefore, make a first pass to check if all parameters are enabled and, if so,
-                // clone the `Interned<GenericParams>` instead of recreating an identical copy.
-                let all_type_or_consts_enabled =
-                    params.type_or_consts.iter().all(|(idx, _)| enabled(attr_owner_ct(idx)));
-                let all_lifetimes_enabled =
-                    params.lifetimes.iter().all(|(idx, _)| enabled(attr_owner_lt(idx)));
-
-                if all_type_or_consts_enabled && all_lifetimes_enabled {
-                    params.clone()
-                } else {
-                    Interned::new(GenericParams {
-                        type_or_consts: all_type_or_consts_enabled
-                            .then(|| params.type_or_consts.clone())
-                            .unwrap_or_else(|| {
-                                params
-                                    .type_or_consts
-                                    .iter()
-                                    .filter(|&(idx, _)| enabled(attr_owner_ct(idx)))
-                                    .map(|(_, param)| param.clone())
-                                    .collect()
-                            }),
-                        lifetimes: all_lifetimes_enabled
-                            .then(|| params.lifetimes.clone())
-                            .unwrap_or_else(|| {
-                                params
-                                    .lifetimes
-                                    .iter()
-                                    .filter(|&(idx, _)| enabled(attr_owner_lt(idx)))
-                                    .map(|(_, param)| param.clone())
-                                    .collect()
-                            }),
-                        where_predicates: params.where_predicates.clone(),
-                    })
-                }
-            };
-        fn id_to_generics<Id: GenericsItemTreeNode>(
-            db: &dyn DefDatabase,
-            id: impl for<'db> Lookup<
-                Database<'db> = dyn DefDatabase + 'db,
-                Data = impl ItemTreeLoc<Id = Id>,
-            >,
-            enabled_params: impl Fn(
-                &Interned<GenericParams>,
-                &ItemTree,
-                GenericModItem,
-            ) -> Interned<GenericParams>,
-        ) -> Interned<GenericParams>
-        where
-            FileItemTreeId<Id>: Into<GenericModItem>,
-        {
-            let id = id.lookup(db).item_tree_id();
-            let tree = id.item_tree(db);
-            let item = &tree[id.value];
-            enabled_params(item.generic_params(), &tree, id.value.into())
-        }
-
-        match def {
-            GenericDefId::FunctionId(id) => {
-                let loc = id.lookup(db);
-                let tree = loc.id.item_tree(db);
-                let item = &tree[loc.id.value];
-
-                let enabled_params =
-                    enabled_params(&item.explicit_generic_params, &tree, loc.id.value.into());
-
-                let module = loc.container.module(db);
-                let func_data = db.function_data(id);
-                if func_data.params.is_empty() {
-                    enabled_params
-                } else {
-                    let mut generic_params = GenericParamsCollector {
-                        type_or_consts: enabled_params.type_or_consts.clone(),
-                        lifetimes: enabled_params.lifetimes.clone(),
-                        where_predicates: enabled_params.where_predicates.clone().into(),
-                    };
-
-                    // Don't create an `Expander` if not needed since this
-                    // could cause a reparse after the `ItemTree` has been created due to the spanmap.
-                    let mut expander = Lazy::new(|| {
-                        (module.def_map(db), Expander::new(db, loc.id.file_id(), module))
-                    });
-                    for param in func_data.params.iter() {
-                        generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
-                    }
-                    Interned::new(generic_params.finish())
-                }
-            }
-            GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics(db, id, enabled_params),
-            GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics(db, id, enabled_params),
-            GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics(db, id, enabled_params),
-            GenericDefId::TraitId(id) => id_to_generics(db, id, enabled_params),
-            GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params),
-            GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params),
-            GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params),
-            GenericDefId::ConstId(_) => Interned::new(GenericParams {
-                type_or_consts: Default::default(),
-                lifetimes: Default::default(),
-                where_predicates: Default::default(),
-            }),
-        }
-    }
-
-    pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {
-        self.type_or_consts.iter().find_map(|(id, p)| {
-            if p.name().as_ref() == Some(&name) && p.type_param().is_some() {
-                Some(TypeParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
-            } else {
-                None
-            }
-        })
-    }
-
-    pub fn find_const_by_name(&self, name: &Name, parent: GenericDefId) -> Option<ConstParamId> {
-        self.type_or_consts.iter().find_map(|(id, p)| {
-            if p.name().as_ref() == Some(&name) && p.const_param().is_some() {
-                Some(ConstParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
-            } else {
-                None
-            }
-        })
-    }
-
-    pub fn trait_self_param(&self) -> Option<LocalTypeOrConstParamId> {
-        if self.type_or_consts.is_empty() {
-            return None;
-        }
-        matches!(
-            self.type_or_consts[SELF_PARAM_ID_IN_SELF],
-            TypeOrConstParamData::TypeParamData(TypeParamData {
-                provenance: TypeParamProvenance::TraitSelf,
-                ..
-            })
-        )
-        .then(|| SELF_PARAM_ID_IN_SELF)
-    }
-
-    pub fn find_lifetime_by_name(
-        &self,
-        name: &Name,
-        parent: GenericDefId,
-    ) -> Option<LifetimeParamId> {
-        self.lifetimes.iter().find_map(|(id, p)| {
-            if &p.name == name {
-                Some(LifetimeParamId { local_id: id, parent })
-            } else {
-                None
-            }
-        })
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index 2803678a330..6283ae23b52 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -532,7 +532,7 @@ impl Printer<'_> {
 
         w!(self, "<");
         let mut first = true;
-        for (idx, lt) in params.lifetimes.iter() {
+        for (idx, lt) in params.iter_lt() {
             if !first {
                 w!(self, ", ");
             }
@@ -540,7 +540,7 @@ impl Printer<'_> {
             self.print_attrs_of(AttrOwner::LifetimeParamData(parent, idx), " ");
             w!(self, "{}", lt.name.display(self.db.upcast()));
         }
-        for (idx, x) in params.type_or_consts.iter() {
+        for (idx, x) in params.iter_type_or_consts() {
             if !first {
                 w!(self, ", ");
             }
@@ -570,13 +570,13 @@ impl Printer<'_> {
     }
 
     fn print_where_clause(&mut self, params: &GenericParams) -> bool {
-        if params.where_predicates.is_empty() {
+        if params.where_predicates().next().is_none() {
             return false;
         }
 
         w!(self, "\nwhere");
         self.indented(|this| {
-            for (i, pred) in params.where_predicates.iter().enumerate() {
+            for (i, pred) in params.where_predicates().enumerate() {
                 if i != 0 {
                     wln!(this, ",");
                 }
@@ -607,12 +607,10 @@ impl Printer<'_> {
 
                 match target {
                     WherePredicateTypeTarget::TypeRef(ty) => this.print_type_ref(ty),
-                    WherePredicateTypeTarget::TypeOrConstParam(id) => {
-                        match &params.type_or_consts[*id].name() {
-                            Some(name) => w!(this, "{}", name.display(self.db.upcast())),
-                            None => w!(this, "_anon_{}", id.into_raw()),
-                        }
-                    }
+                    WherePredicateTypeTarget::TypeOrConstParam(id) => match params[*id].name() {
+                        Some(name) => w!(this, "{}", name.display(self.db.upcast())),
+                        None => w!(this, "_anon_{}", id.into_raw()),
+                    },
                 }
                 w!(this, ": ");
                 this.print_type_bounds(std::slice::from_ref(bound));
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index a83157415c7..e5c1f93bbde 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -596,7 +596,7 @@ impl Resolver {
                 Scope::GenericParams { params, def } => Some((params, def)),
                 _ => None,
             })
-            .flat_map(|(params, def)| params.where_predicates.iter().zip(iter::repeat(def)))
+            .flat_map(|(params, def)| params.where_predicates().zip(iter::repeat(def)))
     }
 
     pub fn generic_def(&self) -> Option<GenericDefId> {
@@ -758,10 +758,10 @@ impl Scope {
             }
             Scope::GenericParams { params, def: parent } => {
                 let parent = *parent;
-                for (local_id, param) in params.type_or_consts.iter() {
+                for (local_id, param) in params.iter_type_or_consts() {
                     if let Some(name) = &param.name() {
                         let id = TypeOrConstParamId { parent, local_id };
-                        let data = &db.generic_params(parent).type_or_consts[local_id];
+                        let data = &db.generic_params(parent)[local_id];
                         acc.add(
                             name,
                             ScopeDef::GenericParam(match data {
@@ -775,7 +775,7 @@ impl Scope {
                         );
                     }
                 }
-                for (local_id, param) in params.lifetimes.iter() {
+                for (local_id, param) in params.iter_lt() {
                     let id = LifetimeParamId { parent, local_id };
                     acc.add(&param.name, ScopeDef::GenericParam(id.into()))
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
index 2b1da8c34e1..a0d2079e0d4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
@@ -64,7 +64,7 @@ impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
         db: &dyn DefDatabase,
     ) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
         let generic_params = db.generic_params(*self);
-        let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
+        let mut idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx);
 
         let (file_id, generic_params_list) = self.file_id_and_params_of(db);
 
@@ -103,7 +103,7 @@ impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
         db: &dyn DefDatabase,
     ) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
         let generic_params = db.generic_params(*self);
-        let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
+        let idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
 
         let (file_id, generic_params_list) = self.file_id_and_params_of(db);
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
index 320e5bd8a2e..d0d217d2706 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
@@ -309,7 +309,7 @@ impl TyExt for Ty {
             TyKind::Placeholder(idx) => {
                 let id = from_placeholder_idx(db, *idx);
                 let generic_params = db.generic_params(id.parent);
-                let param_data = &generic_params.type_or_consts[id.local_id];
+                let param_data = &generic_params[id.local_id];
                 match param_data {
                     TypeOrConstParamData::TypeParamData(p) => match p.provenance {
                         hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
index 2685dc0ef85..a96c101a388 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
@@ -2,8 +2,8 @@
 //!
 //! The layout for generics as expected by chalk are as follows:
 //! - Optional Self parameter
-//! - Type or Const parameters
 //! - Lifetime parameters
+//! - Type or Const parameters
 //! - Parent parameters
 //!
 //! where parent follows the same scheme.
@@ -20,19 +20,23 @@ use hir_def::{
     LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
 };
 use intern::Interned;
+use itertools::chain;
 use stdx::TupleExt;
 
 use crate::{db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx, Interner, Substitution};
 
 pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
     let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
-    Generics { def, params: db.generic_params(def), parent_generics }
+    let params = db.generic_params(def);
+    let has_trait_self_param = params.trait_self_param().is_some();
+    Generics { def, params, parent_generics, has_trait_self_param }
 }
 #[derive(Clone, Debug)]
 pub(crate) struct Generics {
     def: GenericDefId,
     params: Interned<GenericParams>,
     parent_generics: Option<Box<Generics>>,
+    has_trait_self_param: bool,
 }
 
 impl<T> ops::Index<T> for Generics
@@ -74,10 +78,6 @@ impl Generics {
         self.params.iter_type_or_consts().map(from_toc_id(self)).map(TupleExt::head)
     }
 
-    pub(crate) fn iter_self_lt_id(&self) -> impl DoubleEndedIterator<Item = GenericParamId> + '_ {
-        self.params.iter_lt().map(from_lt_id(self)).map(TupleExt::head)
-    }
-
     /// Iterate over the params followed by the parent params.
     pub(crate) fn iter(
         &self,
@@ -89,10 +89,9 @@ impl Generics {
     pub(crate) fn iter_self(
         &self,
     ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
-        self.params
-            .iter_type_or_consts()
-            .map(from_toc_id(self))
-            .chain(self.params.iter_lt().map(from_lt_id(self)))
+        let mut toc = self.params.iter_type_or_consts().map(from_toc_id(self));
+        let trait_self_param = self.has_trait_self_param.then(|| toc.next()).flatten();
+        chain!(trait_self_param, self.params.iter_lt().map(from_lt_id(self)), toc)
     }
 
     /// Iterator over types and const params of parent.
@@ -100,8 +99,9 @@ impl Generics {
         &self,
     ) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
         self.parent_generics().into_iter().flat_map(|it| {
-            let lt_iter = it.params.iter_lt().map(from_lt_id(it));
-            it.params.iter_type_or_consts().map(from_toc_id(it)).chain(lt_iter)
+            let mut toc = it.params.iter_type_or_consts().map(from_toc_id(it));
+            let trait_self_param = it.has_trait_self_param.then(|| toc.next()).flatten();
+            chain!(trait_self_param, it.params.iter_lt().map(from_lt_id(it)), toc)
         })
     }
 
@@ -145,8 +145,11 @@ impl Generics {
     fn find_type_or_const_param(&self, param: TypeOrConstParamId) -> Option<usize> {
         if param.parent == self.def {
             let idx = param.local_id.into_raw().into_u32() as usize;
-            debug_assert!(idx <= self.params.type_or_consts.len());
-            Some(idx)
+            debug_assert!(idx <= self.params.len_type_or_consts());
+            if self.params.trait_self_param() == Some(param.local_id) {
+                return Some(idx);
+            }
+            Some(self.params.len_lifetimes() + idx)
         } else {
             debug_assert_eq!(self.parent_generics().map(|it| it.def), Some(param.parent));
             self.parent_generics()
@@ -163,8 +166,8 @@ impl Generics {
     fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<usize> {
         if lifetime.parent == self.def {
             let idx = lifetime.local_id.into_raw().into_u32() as usize;
-            debug_assert!(idx <= self.params.lifetimes.len());
-            Some(self.params.type_or_consts.len() + idx)
+            debug_assert!(idx <= self.params.len_lifetimes());
+            Some(self.params.trait_self_param().is_some() as usize + idx)
         } else {
             debug_assert_eq!(self.parent_generics().map(|it| it.def), Some(lifetime.parent));
             self.parent_generics()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 54f4ee782fa..d421e72d364 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -384,14 +384,18 @@ impl<'a> TyLoweringContext<'a> {
                             type_params,
                             const_params,
                             _impl_trait_params,
-                            _lifetime_params,
+                            lifetime_params,
                         ) = self
                             .generics()
                             .expect("variable impl trait lowering must be in a generic def")
                             .provenance_split();
                         TyKind::BoundVar(BoundVar::new(
                             self.in_binders,
-                            idx as usize + self_param as usize + type_params + const_params,
+                            idx as usize
+                                + self_param as usize
+                                + type_params
+                                + const_params
+                                + lifetime_params,
                         ))
                         .intern(Interner)
                     }
@@ -816,8 +820,8 @@ impl<'a> TyLoweringContext<'a> {
 
         // Order is
         // - Optional Self parameter
-        // - Type or Const parameters
         // - Lifetime parameters
+        // - Type or Const parameters
         // - Parent parameters
         let def_generics = generics(self.db.upcast(), def);
         let (
@@ -839,7 +843,6 @@ impl<'a> TyLoweringContext<'a> {
 
         let ty_error = || TyKind::Error.intern(Interner).cast(Interner);
         let mut def_toc_iter = def_generics.iter_self_type_or_consts_id();
-        let mut def_lt_iter = def_generics.iter_self_lt_id();
         let fill_self_param = || {
             if self_param {
                 let self_ty = explicit_self_ty.map(|x| x.cast(Interner)).unwrap_or_else(ty_error);
@@ -852,56 +855,56 @@ impl<'a> TyLoweringContext<'a> {
         };
         let mut had_explicit_args = false;
 
-        let mut lifetimes = SmallVec::<[_; 1]>::new();
         if let Some(&GenericArgs { ref args, has_self_type, .. }) = args_and_bindings {
-            if !has_self_type {
-                fill_self_param();
-            }
-            let expected_num = if has_self_type {
-                self_param as usize + type_params + const_params
+            // Fill in the self param first
+            if has_self_type && self_param {
+                had_explicit_args = true;
+                if let Some(id) = def_toc_iter.next() {
+                    assert!(matches!(id, GenericParamId::TypeParamId(_)));
+                    had_explicit_args = true;
+                    if let GenericArg::Type(ty) = &args[0] {
+                        substs.push(self.lower_ty(ty).cast(Interner));
+                    }
+                }
             } else {
-                type_params + const_params
+                fill_self_param()
             };
-            let skip = if has_self_type && !self_param { 1 } else { 0 };
-            // if non-lifetime args are provided, it should be all of them, but we can't rely on that
+
+            // Then fill in the supplied lifetime args, or error lifetimes if there are too few
+            // (default lifetimes aren't a thing)
             for arg in args
                 .iter()
-                .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
-                .skip(skip)
-                .take(expected_num)
+                .filter_map(|arg| match arg {
+                    GenericArg::Lifetime(arg) => Some(self.lower_lifetime(arg)),
+                    _ => None,
+                })
+                .chain(iter::repeat(error_lifetime()))
+                .take(lifetime_params)
             {
-                if let Some(id) = def_toc_iter.next() {
-                    had_explicit_args = true;
-                    let arg = generic_arg_to_chalk(
-                        self.db,
-                        id,
-                        arg,
-                        &mut (),
-                        |_, type_ref| self.lower_ty(type_ref),
-                        |_, const_ref, ty| self.lower_const(const_ref, ty),
-                        |_, lifetime_ref| self.lower_lifetime(lifetime_ref),
-                    );
-                    substs.push(arg);
-                }
+                substs.push(arg.cast(Interner));
             }
 
-            for arg in args
+            let skip = if has_self_type { 1 } else { 0 };
+            // Fill in supplied type and const args
+            // Note if non-lifetime args are provided, it should be all of them, but we can't rely on that
+            for (arg, id) in args
                 .iter()
-                .filter(|arg| matches!(arg, GenericArg::Lifetime(_)))
-                .take(lifetime_params)
+                .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
+                .skip(skip)
+                .take(type_params + const_params)
+                .zip(def_toc_iter)
             {
-                if let Some(id) = def_lt_iter.next() {
-                    let arg = generic_arg_to_chalk(
-                        self.db,
-                        id,
-                        arg,
-                        &mut (),
-                        |_, type_ref| self.lower_ty(type_ref),
-                        |_, const_ref, ty| self.lower_const(const_ref, ty),
-                        |_, lifetime_ref| self.lower_lifetime(lifetime_ref),
-                    );
-                    lifetimes.push(arg);
-                }
+                had_explicit_args = true;
+                let arg = generic_arg_to_chalk(
+                    self.db,
+                    id,
+                    arg,
+                    &mut (),
+                    |_, type_ref| self.lower_ty(type_ref),
+                    |_, const_ref, ty| self.lower_const(const_ref, ty),
+                    |_, lifetime_ref| self.lower_lifetime(lifetime_ref),
+                );
+                substs.push(arg);
             }
         } else {
             fill_self_param();
@@ -923,16 +926,16 @@ impl<'a> TyLoweringContext<'a> {
             }
             _ => false,
         };
-        if (!infer_args || had_explicit_args) && !is_assoc_ty() {
+        let fill_defaults = (!infer_args || had_explicit_args) && !is_assoc_ty();
+        if fill_defaults {
             let defaults = &*self.db.generic_defaults(def);
             let (item, _parent) = defaults.split_at(item_len);
-            let (toc, lt) = item.split_at(item_len - lifetime_params);
             let parent_from = item_len - substs.len();
 
             let mut rem =
                 def_generics.iter_id().skip(substs.len()).map(param_to_err).collect::<Vec<_>>();
             // Fill in defaults for type/const params
-            for (idx, default_ty) in toc[substs.len()..].iter().enumerate() {
+            for (idx, default_ty) in item[substs.len()..].iter().enumerate() {
                 // each default can depend on the previous parameters
                 let substs_so_far = Substitution::from_iter(
                     Interner,
@@ -940,20 +943,9 @@ impl<'a> TyLoweringContext<'a> {
                 );
                 substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
             }
-            let n_lifetimes = lifetimes.len();
-            // Fill in deferred lifetimes
-            substs.extend(lifetimes);
-            // Fill in defaults for lifetime params
-            for default_ty in &lt[n_lifetimes..] {
-                // these are always errors so skipping is fine
-                substs.push(default_ty.skip_binders().clone());
-            }
-            // Fill in remaining def params and parent params
+            // Fill in remaining parent params
             substs.extend(rem.drain(parent_from..));
         } else {
-            substs.extend(def_toc_iter.map(param_to_err));
-            // Fill in deferred lifetimes
-            substs.extend(lifetimes);
             // Fill in remaining def params and parent params
             substs.extend(def_generics.iter_id().skip(substs.len()).map(param_to_err));
         }
@@ -1725,8 +1717,8 @@ pub(crate) fn generic_predicates_query(
         })
         .collect::<Vec<_>>();
 
-    let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
-    if !subst.is_empty(Interner) {
+    if generics.len() > 0 {
+        let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
         let explicitly_unsized_tys = ctx.unsized_types.into_inner();
         if let Some(implicitly_sized_predicates) =
             implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
@@ -2071,7 +2063,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
 // returns None if def is a type arg
 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
     let parent_data = db.generic_params(def.parent());
-    let data = &parent_data.type_or_consts[def.local_id()];
+    let data = &parent_data[def.local_id()];
     let resolver = def.parent().resolver(db.upcast());
     let ctx = TyLoweringContext::new(db, &resolver, def.parent().into());
     match data {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 0569d06695c..f7119c303ac 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -183,7 +183,7 @@ impl MirLowerError {
             },
             MirLowerError::GenericArgNotProvided(id, subst) => {
                 let parent = id.parent;
-                let param = &db.generic_params(parent).type_or_consts[id.local_id];
+                let param = &db.generic_params(parent)[id.local_id];
                 writeln!(
                     f,
                     "Generic arg not provided for {}",
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index 969999cdb84..738e8421463 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -157,8 +157,7 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(Tra
     let generic_params = db.generic_params(trait_.into());
     let trait_self = generic_params.trait_self_param();
     generic_params
-        .where_predicates
-        .iter()
+        .where_predicates()
         .filter_map(|pred| match pred {
             WherePredicate::ForLifetime { target, bound, .. }
             | WherePredicate::TypeBound { target, bound } => {
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 79069ed66bf..72e79af75df 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -452,7 +452,7 @@ impl HirDisplay for TypeOrConstParam {
 impl HirDisplay for TypeParam {
     fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
         let params = f.db.generic_params(self.id.parent());
-        let param_data = &params.type_or_consts[self.id.local_id()];
+        let param_data = &params[self.id.local_id()];
         let substs = TyBuilder::placeholder_subst(f.db, self.id.parent());
         let krate = self.id.parent().krate(f.db).id;
         let ty =
@@ -539,11 +539,10 @@ fn write_generic_params(
     f: &mut HirFormatter<'_>,
 ) -> Result<(), HirDisplayError> {
     let params = f.db.generic_params(def);
-    if params.lifetimes.is_empty()
-        && params.type_or_consts.iter().all(|it| it.1.const_param().is_none())
+    if params.iter_lt().next().is_none()
+        && params.iter_type_or_consts().all(|it| it.1.const_param().is_none())
         && params
-            .type_or_consts
-            .iter()
+            .iter_type_or_consts()
             .filter_map(|it| it.1.type_param())
             .all(|param| !matches!(param.provenance, TypeParamProvenance::TypeParamList))
     {
@@ -560,11 +559,11 @@ fn write_generic_params(
             f.write_str(", ")
         }
     };
-    for (_, lifetime) in params.lifetimes.iter() {
+    for (_, lifetime) in params.iter_lt() {
         delim(f)?;
         write!(f, "{}", lifetime.name.display(f.db.upcast()))?;
     }
-    for (_, ty) in params.type_or_consts.iter() {
+    for (_, ty) in params.iter_type_or_consts() {
         if let Some(name) = &ty.name() {
             match ty {
                 TypeOrConstParamData::TypeParamData(ty) => {
@@ -612,11 +611,11 @@ fn write_where_clause(
 }
 
 fn has_disaplayable_predicates(params: &Interned<GenericParams>) -> bool {
-    params.where_predicates.iter().any(|pred| {
+    params.where_predicates().any(|pred| {
         !matches!(
             pred,
             WherePredicate::TypeBound { target: WherePredicateTypeTarget::TypeOrConstParam(id), .. }
-            if params.type_or_consts[*id].name().is_none()
+            if params[*id].name().is_none()
         )
     })
 }
@@ -631,13 +630,13 @@ fn write_where_predicates(
     let is_unnamed_type_target =
         |params: &Interned<GenericParams>, target: &WherePredicateTypeTarget| {
             matches!(target,
-                WherePredicateTypeTarget::TypeOrConstParam(id) if params.type_or_consts[*id].name().is_none()
+                WherePredicateTypeTarget::TypeOrConstParam(id) if params[*id].name().is_none()
             )
         };
 
     let write_target = |target: &WherePredicateTypeTarget, f: &mut HirFormatter<'_>| match target {
         WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f),
-        WherePredicateTypeTarget::TypeOrConstParam(id) => match params.type_or_consts[*id].name() {
+        WherePredicateTypeTarget::TypeOrConstParam(id) => match params[*id].name() {
             Some(name) => write!(f, "{}", name.display(f.db.upcast())),
             None => f.write_str("{unnamed}"),
         },
@@ -653,7 +652,7 @@ fn write_where_predicates(
         _ => false,
     };
 
-    let mut iter = params.where_predicates.iter().peekable();
+    let mut iter = params.where_predicates().peekable();
     while let Some(pred) = iter.next() {
         if matches!(pred, TypeBound { target, .. } if is_unnamed_type_target(params, target)) {
             continue;
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index cd916330c20..18a5325db6b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -665,7 +665,7 @@ impl Module {
                 }
                 let parent = impl_def.id.into();
                 let generic_params = db.generic_params(parent);
-                let lifetime_params = generic_params.lifetimes.iter().map(|(local_id, _)| {
+                let lifetime_params = generic_params.iter_lt().map(|(local_id, _)| {
                     GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id })
                 });
                 let type_params = generic_params
@@ -1540,8 +1540,7 @@ impl Adt {
         resolver
             .generic_params()
             .and_then(|gp| {
-                gp.lifetimes
-                    .iter()
+                gp.iter_lt()
                     // there should only be a single lifetime
                     // but `Arena` requires to use an iterator
                     .nth(0)
@@ -2503,8 +2502,7 @@ impl Trait {
         count_required_only: bool,
     ) -> usize {
         db.generic_params(self.id.into())
-            .type_or_consts
-            .iter()
+            .iter_type_or_consts()
             .filter(|(_, ty)| !matches!(ty, TypeOrConstParamData::TypeParamData(ty) if ty.provenance != TypeParamProvenance::TypeParamList))
             .filter(|(_, ty)| !count_required_only || !ty.has_default())
             .count()
@@ -3125,7 +3123,7 @@ impl_from!(
 impl GenericDef {
     pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
         let generics = db.generic_params(self.into());
-        let ty_params = generics.type_or_consts.iter().map(|(local_id, _)| {
+        let ty_params = generics.iter_type_or_consts().map(|(local_id, _)| {
             let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } };
             match toc.split(db) {
                 Either::Left(it) => GenericParam::ConstParam(it),
@@ -3142,8 +3140,7 @@ impl GenericDef {
     pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec<LifetimeParam> {
         let generics = db.generic_params(self.into());
         generics
-            .lifetimes
-            .iter()
+            .iter_lt()
             .map(|(local_id, _)| LifetimeParam {
                 id: LifetimeParamId { parent: self.into(), local_id },
             })
@@ -3153,8 +3150,7 @@ impl GenericDef {
     pub fn type_or_const_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
         let generics = db.generic_params(self.into());
         generics
-            .type_or_consts
-            .iter()
+            .iter_type_or_consts()
             .map(|(local_id, _)| TypeOrConstParam {
                 id: TypeOrConstParamId { parent: self.into(), local_id },
             })
@@ -3496,7 +3492,7 @@ impl TypeParam {
     /// argument)?
     pub fn is_implicit(self, db: &dyn HirDatabase) -> bool {
         let params = db.generic_params(self.id.parent());
-        let data = &params.type_or_consts[self.id.local_id()];
+        let data = &params[self.id.local_id()];
         match data.type_param().unwrap().provenance {
             hir_def::generics::TypeParamProvenance::TypeParamList => false,
             hir_def::generics::TypeParamProvenance::TraitSelf
@@ -3550,7 +3546,7 @@ pub struct LifetimeParam {
 impl LifetimeParam {
     pub fn name(self, db: &dyn HirDatabase) -> Name {
         let params = db.generic_params(self.id.parent);
-        params.lifetimes[self.id.local_id].name.clone()
+        params[self.id.local_id].name.clone()
     }
 
     pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -3574,7 +3570,7 @@ impl ConstParam {
 
     pub fn name(self, db: &dyn HirDatabase) -> Name {
         let params = db.generic_params(self.id.parent());
-        match params.type_or_consts[self.id.local_id()].name() {
+        match params[self.id.local_id()].name() {
             Some(it) => it.clone(),
             None => {
                 never!();
@@ -3617,7 +3613,7 @@ pub struct TypeOrConstParam {
 impl TypeOrConstParam {
     pub fn name(self, db: &dyn HirDatabase) -> Name {
         let params = db.generic_params(self.id.parent);
-        match params.type_or_consts[self.id.local_id].name() {
+        match params[self.id.local_id].name() {
             Some(n) => n.clone(),
             _ => Name::missing(),
         }
@@ -3633,7 +3629,7 @@ impl TypeOrConstParam {
 
     pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
         let params = db.generic_params(self.id.parent);
-        match &params.type_or_consts[self.id.local_id] {
+        match &params[self.id.local_id] {
             hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
                 Either::Right(TypeParam { id: TypeParamId::from_unchecked(self.id) })
             }
@@ -3652,7 +3648,7 @@ impl TypeOrConstParam {
 
     pub fn as_type_param(self, db: &dyn HirDatabase) -> Option<TypeParam> {
         let params = db.generic_params(self.id.parent);
-        match &params.type_or_consts[self.id.local_id] {
+        match &params[self.id.local_id] {
             hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
                 Some(TypeParam { id: TypeParamId::from_unchecked(self.id) })
             }
@@ -3662,7 +3658,7 @@ impl TypeOrConstParam {
 
     pub fn as_const_param(self, db: &dyn HirDatabase) -> Option<ConstParam> {
         let params = db.generic_params(self.id.parent);
-        match &params.type_or_consts[self.id.local_id] {
+        match &params[self.id.local_id] {
             hir_def::generics::TypeOrConstParamData::TypeParamData(_) => None,
             hir_def::generics::TypeOrConstParamData::ConstParamData(_) => {
                 Some(ConstParam { id: ConstParamId::from_unchecked(self.id) })