Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0fef8f0

Browse files
committed
Move lifetimes in front of type and const params but after self
1 parent 99e432d commit 0fef8f0

File tree

3 files changed

+120
-124
lines changed

3 files changed

+120
-124
lines changed

src/tools/rust-analyzer/crates/hir-def/src/generics.rs

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,62 @@ impl GenericParams {
249249
self.lifetimes.iter()
250250
}
251251

252+
pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {
253+
self.type_or_consts.iter().find_map(|(id, p)| {
254+
if p.name().as_ref() == Some(&name) && p.type_param().is_some() {
255+
Some(TypeParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
256+
} else {
257+
None
258+
}
259+
})
260+
}
261+
262+
pub fn find_const_by_name(&self, name: &Name, parent: GenericDefId) -> Option<ConstParamId> {
263+
self.type_or_consts.iter().find_map(|(id, p)| {
264+
if p.name().as_ref() == Some(&name) && p.const_param().is_some() {
265+
Some(ConstParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
266+
} else {
267+
None
268+
}
269+
})
270+
}
271+
272+
#[inline]
273+
pub fn trait_self_param(&self) -> Option<LocalTypeOrConstParamId> {
274+
if self.type_or_consts.is_empty() {
275+
return None;
276+
}
277+
matches!(
278+
self.type_or_consts[SELF_PARAM_ID_IN_SELF],
279+
TypeOrConstParamData::TypeParamData(TypeParamData {
280+
provenance: TypeParamProvenance::TraitSelf,
281+
..
282+
})
283+
)
284+
.then(|| SELF_PARAM_ID_IN_SELF)
285+
}
286+
287+
pub fn find_lifetime_by_name(
288+
&self,
289+
name: &Name,
290+
parent: GenericDefId,
291+
) -> Option<LifetimeParamId> {
292+
self.lifetimes.iter().find_map(|(id, p)| {
293+
if &p.name == name {
294+
Some(LifetimeParamId { local_id: id, parent })
295+
} else {
296+
None
297+
}
298+
})
299+
}
300+
252301
pub(crate) fn generic_params_query(
253302
db: &dyn DefDatabase,
254303
def: GenericDefId,
255304
) -> Interned<GenericParams> {
256305
let _p = tracing::info_span!("generic_params_query").entered();
257306

258-
let krate = def.module(db).krate;
307+
let krate = def.krate(db);
259308
let cfg_options = db.crate_graph();
260309
let cfg_options = &cfg_options[krate].cfg_options;
261310

@@ -368,54 +417,6 @@ impl GenericParams {
368417
}),
369418
}
370419
}
371-
372-
pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {
373-
self.type_or_consts.iter().find_map(|(id, p)| {
374-
if p.name().as_ref() == Some(&name) && p.type_param().is_some() {
375-
Some(TypeParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
376-
} else {
377-
None
378-
}
379-
})
380-
}
381-
382-
pub fn find_const_by_name(&self, name: &Name, parent: GenericDefId) -> Option<ConstParamId> {
383-
self.type_or_consts.iter().find_map(|(id, p)| {
384-
if p.name().as_ref() == Some(&name) && p.const_param().is_some() {
385-
Some(ConstParamId::from_unchecked(TypeOrConstParamId { local_id: id, parent }))
386-
} else {
387-
None
388-
}
389-
})
390-
}
391-
392-
pub fn trait_self_param(&self) -> Option<LocalTypeOrConstParamId> {
393-
if self.type_or_consts.is_empty() {
394-
return None;
395-
}
396-
matches!(
397-
self.type_or_consts[SELF_PARAM_ID_IN_SELF],
398-
TypeOrConstParamData::TypeParamData(TypeParamData {
399-
provenance: TypeParamProvenance::TraitSelf,
400-
..
401-
})
402-
)
403-
.then(|| SELF_PARAM_ID_IN_SELF)
404-
}
405-
406-
pub fn find_lifetime_by_name(
407-
&self,
408-
name: &Name,
409-
parent: GenericDefId,
410-
) -> Option<LifetimeParamId> {
411-
self.lifetimes.iter().find_map(|(id, p)| {
412-
if &p.name == name {
413-
Some(LifetimeParamId { local_id: id, parent })
414-
} else {
415-
None
416-
}
417-
})
418-
}
419420
}
420421

421422
#[derive(Clone, Default)]

src/tools/rust-analyzer/crates/hir-ty/src/generics.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
//!
33
//! The layout for generics as expected by chalk are as follows:
44
//! - Optional Self parameter
5-
//! - Type or Const parameters
65
//! - Lifetime parameters
6+
//! - Type or Const parameters
77
//! - Parent parameters
88
//!
99
//! where parent follows the same scheme.
@@ -20,19 +20,23 @@ use hir_def::{
2020
LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
2121
};
2222
use intern::Interned;
23+
use itertools::chain;
2324
use stdx::TupleExt;
2425

2526
use crate::{db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx, Interner, Substitution};
2627

2728
pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
2829
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
29-
Generics { def, params: db.generic_params(def), parent_generics }
30+
let params = db.generic_params(def);
31+
let has_trait_self_param = params.trait_self_param().is_some();
32+
Generics { def, params, parent_generics, has_trait_self_param }
3033
}
3134
#[derive(Clone, Debug)]
3235
pub(crate) struct Generics {
3336
def: GenericDefId,
3437
params: Interned<GenericParams>,
3538
parent_generics: Option<Box<Generics>>,
39+
has_trait_self_param: bool,
3640
}
3741

3842
impl<T> ops::Index<T> for Generics
@@ -74,10 +78,6 @@ impl Generics {
7478
self.params.iter_type_or_consts().map(from_toc_id(self)).map(TupleExt::head)
7579
}
7680

77-
pub(crate) fn iter_self_lt_id(&self) -> impl DoubleEndedIterator<Item = GenericParamId> + '_ {
78-
self.params.iter_lt().map(from_lt_id(self)).map(TupleExt::head)
79-
}
80-
8181
/// Iterate over the params followed by the parent params.
8282
pub(crate) fn iter(
8383
&self,
@@ -89,19 +89,19 @@ impl Generics {
8989
pub(crate) fn iter_self(
9090
&self,
9191
) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
92-
self.params
93-
.iter_type_or_consts()
94-
.map(from_toc_id(self))
95-
.chain(self.params.iter_lt().map(from_lt_id(self)))
92+
let mut toc = self.params.iter_type_or_consts().map(from_toc_id(self));
93+
let trait_self_param = self.has_trait_self_param.then(|| toc.next()).flatten();
94+
chain!(trait_self_param, self.params.iter_lt().map(from_lt_id(self)), toc)
9695
}
9796

9897
/// Iterator over types and const params of parent.
9998
fn iter_parent(
10099
&self,
101100
) -> impl DoubleEndedIterator<Item = (GenericParamId, GenericParamDataRef<'_>)> + '_ {
102101
self.parent_generics().into_iter().flat_map(|it| {
103-
let lt_iter = it.params.iter_lt().map(from_lt_id(it));
104-
it.params.iter_type_or_consts().map(from_toc_id(it)).chain(lt_iter)
102+
let mut toc = it.params.iter_type_or_consts().map(from_toc_id(it));
103+
let trait_self_param = it.has_trait_self_param.then(|| toc.next()).flatten();
104+
chain!(trait_self_param, it.params.iter_lt().map(from_lt_id(it)), toc)
105105
})
106106
}
107107

@@ -146,7 +146,10 @@ impl Generics {
146146
if param.parent == self.def {
147147
let idx = param.local_id.into_raw().into_u32() as usize;
148148
debug_assert!(idx <= self.params.len_type_or_consts());
149-
Some(idx)
149+
if self.params.trait_self_param() == Some(param.local_id) {
150+
return Some(idx);
151+
}
152+
Some(self.params.len_lifetimes() + idx)
150153
} else {
151154
debug_assert_eq!(self.parent_generics().map(|it| it.def), Some(param.parent));
152155
self.parent_generics()
@@ -164,7 +167,7 @@ impl Generics {
164167
if lifetime.parent == self.def {
165168
let idx = lifetime.local_id.into_raw().into_u32() as usize;
166169
debug_assert!(idx <= self.params.len_lifetimes());
167-
Some(self.params.len_type_or_consts() + idx)
170+
Some(self.params.trait_self_param().is_some() as usize + idx)
168171
} else {
169172
debug_assert_eq!(self.parent_generics().map(|it| it.def), Some(lifetime.parent));
170173
self.parent_generics()

0 commit comments

Comments
 (0)