Skip to content

Commit 11e41b0

Browse files
Moved types starting with 'Generic' into generics.rs.
1 parent 5375575 commit 11e41b0

File tree

2 files changed

+259
-248
lines changed

2 files changed

+259
-248
lines changed
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
2+
use crate::ty;
3+
use crate::ty::subst::{Subst, SubstsRef};
4+
use rustc_ast as ast;
5+
use rustc_data_structures::fx::FxHashMap;
6+
use rustc_hir as hir;
7+
use rustc_hir::def_id::DefId;
8+
use rustc_span::symbol::Symbol;
9+
use rustc_span::Span;
10+
11+
use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, TyCtxt};
12+
13+
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
14+
pub enum GenericParamDefKind {
15+
Lifetime,
16+
Type {
17+
has_default: bool,
18+
object_lifetime_default: ObjectLifetimeDefault,
19+
synthetic: Option<hir::SyntheticTyParamKind>,
20+
},
21+
Const,
22+
}
23+
24+
impl GenericParamDefKind {
25+
pub fn descr(&self) -> &'static str {
26+
match self {
27+
GenericParamDefKind::Lifetime => "lifetime",
28+
GenericParamDefKind::Type { .. } => "type",
29+
GenericParamDefKind::Const => "constant",
30+
}
31+
}
32+
pub fn to_ord(&self, tcx: TyCtxt<'_>) -> ast::ParamKindOrd {
33+
match self {
34+
GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime,
35+
GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type,
36+
GenericParamDefKind::Const => {
37+
ast::ParamKindOrd::Const { unordered: tcx.features().const_generics }
38+
}
39+
}
40+
}
41+
}
42+
43+
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
44+
pub struct GenericParamDef {
45+
pub name: Symbol,
46+
pub def_id: DefId,
47+
pub index: u32,
48+
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,
53+
54+
pub kind: GenericParamDefKind,
55+
}
56+
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 }
61+
} else {
62+
bug!("cannot convert a non-lifetime parameter def to an early bound region")
63+
}
64+
}
65+
}
66+
67+
#[derive(Default)]
68+
pub struct GenericParamCount {
69+
pub lifetimes: usize,
70+
pub types: usize,
71+
pub consts: usize,
72+
}
73+
74+
/// Information about the formal type/lifetime parameters associated
75+
/// with an item or method. Analogous to `hir::Generics`.
76+
///
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)]
80+
pub struct Generics {
81+
pub parent: Option<DefId>,
82+
pub parent_count: usize,
83+
pub params: Vec<GenericParamDef>,
84+
85+
/// Reverse map to the `index` field of each `GenericParamDef`.
86+
#[stable_hasher(ignore)]
87+
pub param_def_id_to_index: FxHashMap<DefId, u32>,
88+
89+
pub has_self: bool,
90+
pub has_late_bound_regions: Option<Span>,
91+
}
92+
93+
impl<'tcx> Generics {
94+
pub fn count(&self) -> usize {
95+
self.parent_count + self.params.len()
96+
}
97+
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();
103+
104+
for param in &self.params {
105+
match param.kind {
106+
GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
107+
GenericParamDefKind::Type { .. } => own_counts.types += 1,
108+
GenericParamDefKind::Const => own_counts.consts += 1,
109+
}
110+
}
111+
112+
own_counts
113+
}
114+
115+
pub fn own_defaults(&self) -> GenericParamCount {
116+
let mut own_defaults = GenericParamCount::default();
117+
118+
for param in &self.params {
119+
match param.kind {
120+
GenericParamDefKind::Lifetime => (),
121+
GenericParamDefKind::Type { has_default, .. } => {
122+
own_defaults.types += has_default as usize;
123+
}
124+
GenericParamDefKind::Const => {
125+
// FIXME(const_generics:defaults)
126+
}
127+
}
128+
}
129+
130+
own_defaults
131+
}
132+
133+
pub fn requires_monomorphization(&self, tcx: TyCtxt<'tcx>) -> bool {
134+
if self.own_requires_monomorphization() {
135+
return true;
136+
}
137+
138+
if let Some(parent_def_id) = self.parent {
139+
let parent = tcx.generics_of(parent_def_id);
140+
parent.requires_monomorphization(tcx)
141+
} else {
142+
false
143+
}
144+
}
145+
146+
pub fn own_requires_monomorphization(&self) -> bool {
147+
for param in &self.params {
148+
match param.kind {
149+
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
150+
GenericParamDefKind::Lifetime => {}
151+
}
152+
}
153+
false
154+
}
155+
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) {
159+
&self.params[index]
160+
} else {
161+
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
162+
.param_at(param_index, tcx)
163+
}
164+
}
165+
166+
/// Returns the `GenericParamDef` associated with this `EarlyBoundRegion`.
167+
pub fn region_param(
168+
&'tcx self,
169+
param: &EarlyBoundRegion,
170+
tcx: TyCtxt<'tcx>,
171+
) -> &'tcx GenericParamDef {
172+
let param = self.param_at(param.index as usize, tcx);
173+
match param.kind {
174+
GenericParamDefKind::Lifetime => param,
175+
_ => bug!("expected lifetime parameter, but found another generic parameter"),
176+
}
177+
}
178+
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);
182+
match param.kind {
183+
GenericParamDefKind::Type { .. } => param,
184+
_ => bug!("expected type parameter, but found another generic parameter"),
185+
}
186+
}
187+
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);
191+
match param.kind {
192+
GenericParamDefKind::Const => param,
193+
_ => bug!("expected const parameter, but found another generic parameter"),
194+
}
195+
}
196+
}
197+
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)],
203+
}
204+
205+
impl<'tcx> GenericPredicates<'tcx> {
206+
pub fn instantiate(
207+
&self,
208+
tcx: TyCtxt<'tcx>,
209+
substs: SubstsRef<'tcx>,
210+
) -> InstantiatedPredicates<'tcx> {
211+
let mut instantiated = InstantiatedPredicates::empty();
212+
self.instantiate_into(tcx, &mut instantiated, substs);
213+
instantiated
214+
}
215+
216+
pub fn instantiate_own(
217+
&self,
218+
tcx: TyCtxt<'tcx>,
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(),
224+
}
225+
}
226+
227+
fn instantiate_into(
228+
&self,
229+
tcx: TyCtxt<'tcx>,
230+
instantiated: &mut InstantiatedPredicates<'tcx>,
231+
substs: SubstsRef<'tcx>,
232+
) {
233+
if let Some(def_id) = self.parent {
234+
tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs);
235+
}
236+
instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)));
237+
instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp));
238+
}
239+
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);
243+
instantiated
244+
}
245+
246+
fn instantiate_identity_into(
247+
&self,
248+
tcx: TyCtxt<'tcx>,
249+
instantiated: &mut InstantiatedPredicates<'tcx>,
250+
) {
251+
if let Some(def_id) = self.parent {
252+
tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated);
253+
}
254+
instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p));
255+
instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
256+
}
257+
}

0 commit comments

Comments
 (0)