1 use crate::middle
::resolve_lifetime
::ObjectLifetimeDefault
;
3 use crate::ty
::subst
::{Subst, SubstsRef}
;
5 use rustc_data_structures
::fx
::FxHashMap
;
7 use rustc_hir
::def_id
::DefId
;
8 use rustc_span
::symbol
::Symbol
;
11 use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, TyCtxt}
;
13 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
14 pub enum GenericParamDefKind
{
18 object_lifetime_default
: ObjectLifetimeDefault
,
19 synthetic
: Option
<hir
::SyntheticTyParamKind
>,
24 impl GenericParamDefKind
{
25 pub fn descr(&self) -> &'
static str {
27 GenericParamDefKind
::Lifetime
=> "lifetime",
28 GenericParamDefKind
::Type { .. }
=> "type",
29 GenericParamDefKind
::Const
=> "constant",
32 pub fn to_ord(&self, tcx
: TyCtxt
<'_
>) -> ast
::ParamKindOrd
{
34 GenericParamDefKind
::Lifetime
=> ast
::ParamKindOrd
::Lifetime
,
35 GenericParamDefKind
::Type { .. }
=> ast
::ParamKindOrd
::Type
,
36 GenericParamDefKind
::Const
=> {
37 ast
::ParamKindOrd
::Const { unordered: tcx.features().const_generics }
43 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
44 pub struct GenericParamDef
{
49 /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
50 /// on generic parameter `'a`/`T`, asserts data behind the parameter
51 /// `'a`/`T` won't be accessed during the parent type's `Drop` impl.
52 pub pure_wrt_drop
: bool
,
54 pub kind
: GenericParamDefKind
,
57 impl GenericParamDef
{
58 pub fn to_early_bound_region_data(&self) -> ty
::EarlyBoundRegion
{
59 if let GenericParamDefKind
::Lifetime
= self.kind
{
60 ty
::EarlyBoundRegion { def_id: self.def_id, index: self.index, name: self.name }
62 bug
!("cannot convert a non-lifetime parameter def to an early bound region")
68 pub struct GenericParamCount
{
74 /// Information about the formal type/lifetime parameters associated
75 /// with an item or method. Analogous to `hir::Generics`.
77 /// The ordering of parameters is the same as in `Subst` (excluding child generics):
78 /// `Self` (optionally), `Lifetime` params..., `Type` params...
79 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
81 pub parent
: Option
<DefId
>,
82 pub parent_count
: usize,
83 pub params
: Vec
<GenericParamDef
>,
85 /// Reverse map to the `index` field of each `GenericParamDef`.
86 #[stable_hasher(ignore)]
87 pub param_def_id_to_index
: FxHashMap
<DefId
, u32>,
90 pub has_late_bound_regions
: Option
<Span
>,
94 pub fn count(&self) -> usize {
95 self.parent_count
+ self.params
.len()
98 pub fn own_counts(&self) -> GenericParamCount
{
99 // We could cache this as a property of `GenericParamCount`, but
100 // the aim is to refactor this away entirely eventually and the
101 // presence of this method will be a constant reminder.
102 let mut own_counts
= GenericParamCount
::default();
104 for param
in &self.params
{
106 GenericParamDefKind
::Lifetime
=> own_counts
.lifetimes
+= 1,
107 GenericParamDefKind
::Type { .. }
=> own_counts
.types
+= 1,
108 GenericParamDefKind
::Const
=> own_counts
.consts
+= 1,
115 pub fn own_defaults(&self) -> GenericParamCount
{
116 let mut own_defaults
= GenericParamCount
::default();
118 for param
in &self.params
{
120 GenericParamDefKind
::Lifetime
=> (),
121 GenericParamDefKind
::Type { has_default, .. }
=> {
122 own_defaults
.types
+= has_default
as usize;
124 GenericParamDefKind
::Const
=> {
125 // FIXME(const_generics:defaults)
133 pub fn requires_monomorphization(&self, tcx
: TyCtxt
<'tcx
>) -> bool
{
134 if self.own_requires_monomorphization() {
138 if let Some(parent_def_id
) = self.parent
{
139 let parent
= tcx
.generics_of(parent_def_id
);
140 parent
.requires_monomorphization(tcx
)
146 pub fn own_requires_monomorphization(&self) -> bool
{
147 for param
in &self.params
{
149 GenericParamDefKind
::Type { .. }
| GenericParamDefKind
::Const
=> return true,
150 GenericParamDefKind
::Lifetime
=> {}
156 /// Returns the `GenericParamDef` with the given index.
157 pub fn param_at(&'tcx
self, param_index
: usize, tcx
: TyCtxt
<'tcx
>) -> &'tcx GenericParamDef
{
158 if let Some(index
) = param_index
.checked_sub(self.parent_count
) {
161 tcx
.generics_of(self.parent
.expect("parent_count > 0 but no parent?"))
162 .param_at(param_index
, tcx
)
166 /// Returns the `GenericParamDef` associated with this `EarlyBoundRegion`.
169 param
: &EarlyBoundRegion
,
171 ) -> &'tcx GenericParamDef
{
172 let param
= self.param_at(param
.index
as usize, tcx
);
174 GenericParamDefKind
::Lifetime
=> param
,
175 _
=> bug
!("expected lifetime parameter, but found another generic parameter"),
179 /// Returns the `GenericParamDef` associated with this `ParamTy`.
180 pub fn type_param(&'tcx
self, param
: &ParamTy
, tcx
: TyCtxt
<'tcx
>) -> &'tcx GenericParamDef
{
181 let param
= self.param_at(param
.index
as usize, tcx
);
183 GenericParamDefKind
::Type { .. }
=> param
,
184 _
=> bug
!("expected type parameter, but found another generic parameter"),
188 /// Returns the `GenericParamDef` associated with this `ParamConst`.
189 pub fn const_param(&'tcx
self, param
: &ParamConst
, tcx
: TyCtxt
<'tcx
>) -> &GenericParamDef
{
190 let param
= self.param_at(param
.index
as usize, tcx
);
192 GenericParamDefKind
::Const
=> param
,
193 _
=> bug
!("expected const parameter, but found another generic parameter"),
198 /// Bounds on generics.
199 #[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
200 pub struct GenericPredicates
<'tcx
> {
201 pub parent
: Option
<DefId
>,
202 pub predicates
: &'tcx
[(Predicate
<'tcx
>, Span
)],
205 impl<'tcx
> GenericPredicates
<'tcx
> {
209 substs
: SubstsRef
<'tcx
>,
210 ) -> InstantiatedPredicates
<'tcx
> {
211 let mut instantiated
= InstantiatedPredicates
::empty();
212 self.instantiate_into(tcx
, &mut instantiated
, substs
);
216 pub fn instantiate_own(
219 substs
: SubstsRef
<'tcx
>,
220 ) -> InstantiatedPredicates
<'tcx
> {
221 InstantiatedPredicates
{
222 predicates
: self.predicates
.iter().map(|(p
, _
)| p
.subst(tcx
, substs
)).collect(),
223 spans
: self.predicates
.iter().map(|(_
, sp
)| *sp
).collect(),
230 instantiated
: &mut InstantiatedPredicates
<'tcx
>,
231 substs
: SubstsRef
<'tcx
>,
233 if let Some(def_id
) = self.parent
{
234 tcx
.predicates_of(def_id
).instantiate_into(tcx
, instantiated
, substs
);
236 instantiated
.predicates
.extend(self.predicates
.iter().map(|(p
, _
)| p
.subst(tcx
, substs
)));
237 instantiated
.spans
.extend(self.predicates
.iter().map(|(_
, sp
)| *sp
));
240 pub fn instantiate_identity(&self, tcx
: TyCtxt
<'tcx
>) -> InstantiatedPredicates
<'tcx
> {
241 let mut instantiated
= InstantiatedPredicates
::empty();
242 self.instantiate_identity_into(tcx
, &mut instantiated
);
246 fn instantiate_identity_into(
249 instantiated
: &mut InstantiatedPredicates
<'tcx
>,
251 if let Some(def_id
) = self.parent
{
252 tcx
.predicates_of(def_id
).instantiate_identity_into(tcx
, instantiated
);
254 instantiated
.predicates
.extend(self.predicates
.iter().map(|(p
, _
)| p
));
255 instantiated
.spans
.extend(self.predicates
.iter().map(|(_
, s
)| s
));