1use hir_def::{
4 ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, Lookup,
5 TypeOrConstParamId, TypeParamId,
6 db::DefDatabase,
7 expr_store::ExpressionStore,
8 hir::generics::{
9 GenericParamDataRef, GenericParams, LifetimeParamData, LocalLifetimeParamId,
10 LocalTypeOrConstParamId, TypeOrConstParamData, TypeParamData, TypeParamProvenance,
11 WherePredicate,
12 },
13};
14use hir_expand::name::Name;
15use intern::{Symbol, sym};
16use la_arena::Arena;
17use rustc_type_ir::inherent::Ty as _;
18use triomphe::Arc;
19
20use crate::{db::HirDatabase, generics::parent_generic_def, next_solver::Ty};
21
22use super::{Const, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId};
23
24use super::{DbInterner, GenericArg};
25
26pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
27 let mk_lt = |parent, index, local_id, lt: &LifetimeParamData| {
28 let name = lt.name.symbol().clone();
29 let id = GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id });
30 GenericParamDef { name, index, id }
31 };
32 let mk_ty = |parent, index, local_id, p: &TypeOrConstParamData| {
33 let name = p.name().map(|n| n.symbol().clone()).unwrap_or_else(|| sym::MISSING_NAME);
34 let id = TypeOrConstParamId { parent, local_id };
35 let id = match p {
36 TypeOrConstParamData::TypeParamData(_) => {
37 GenericParamId::TypeParamId(TypeParamId::from_unchecked(id))
38 }
39 TypeOrConstParamData::ConstParamData(_) => {
40 GenericParamId::ConstParamId(ConstParamId::from_unchecked(id))
41 }
42 };
43 GenericParamDef { name, index, id }
44 };
45 let own_params_for_generic_params = |parent, params: &GenericParams| {
46 let mut result = Vec::with_capacity(params.len());
47 let mut type_and_consts = params.iter_type_or_consts();
48 let mut index = 0;
49 if let Some(self_param) = params.trait_self_param() {
50 result.push(mk_ty(parent, 0, self_param, ¶ms[self_param]));
51 type_and_consts.next();
52 index += 1;
53 }
54 result.extend(params.iter_lt().map(|(local_id, data)| {
55 let lt = mk_lt(parent, index, local_id, data);
56 index += 1;
57 lt
58 }));
59 result.extend(type_and_consts.map(|(local_id, data)| {
60 let ty = mk_ty(parent, index, local_id, data);
61 index += 1;
62 ty
63 }));
64 result
65 };
66
67 let (parent, own_params) = match (def.try_into(), def) {
68 (Ok(def), _) => (
69 parent_generic_def(db, def),
70 own_params_for_generic_params(def, &db.generic_params(def)),
71 ),
72 (_, SolverDefId::InternedOpaqueTyId(id)) => {
73 match db.lookup_intern_impl_trait_id(id) {
74 crate::ImplTraitId::ReturnTypeImplTrait(function_id, _) => {
75 (Some(GenericDefId::FunctionId(function_id)), vec![])
77 }
78 crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
79 (Some(type_alias_id.into()), Vec::new())
80 }
81 crate::ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
82 let param = TypeOrConstParamData::TypeParamData(TypeParamData {
83 name: None,
84 default: None,
85 provenance: TypeParamProvenance::TypeParamList,
86 });
87 (
91 None,
92 vec![mk_ty(
93 GenericDefId::FunctionId(salsa::plumbing::FromId::from_id(unsafe {
94 salsa::Id::from_index(salsa::Id::MAX_U32 - 1)
95 })),
96 0,
97 LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)),
98 ¶m,
99 )],
100 )
101 }
102 }
103 }
104 _ => panic!("No generics for {def:?}"),
105 };
106 let parent_generics = parent.map(|def| Box::new(generics(db, def.into())));
107
108 Generics {
109 parent,
110 parent_count: parent_generics.map_or(0, |g| g.parent_count + g.own_params.len()),
111 own_params,
112 }
113}
114
115#[derive(Debug)]
116pub struct Generics {
117 pub parent: Option<GenericDefId>,
118 pub parent_count: usize,
119 pub own_params: Vec<GenericParamDef>,
120}
121
122#[derive(Debug)]
123pub struct GenericParamDef {
124 pub(crate) name: Symbol,
125 index: u32,
127 pub(crate) id: GenericParamId,
128}
129
130impl GenericParamDef {
131 pub fn index(&self) -> u32 {
134 self.index
135 }
136}
137
138impl<'db> rustc_type_ir::inherent::GenericsOf<DbInterner<'db>> for Generics {
139 fn count(&self) -> usize {
140 self.parent_count + self.own_params.len()
141 }
142}