Do not pessimise top level functions under NAD
[hiphop-php.git] / hphp / hack / src / hackrs / ty / decl / from_oxidized.rs
blob42b9f64985b9ae0e9887fad2c6736bb6613f506a
1 // Copyright (c) Meta Platforms, Inc. and affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
6 use oxidized_by_ref as obr;
7 use pos::Pos;
9 use crate::decl;
10 use crate::decl::folded;
11 use crate::decl::shallow;
12 use crate::decl::ty;
13 use crate::decl::Ty;
14 use crate::decl::Ty_;
15 use crate::reason::Reason;
17 #[inline]
18 fn slice<T: Copy + Into<U>, U>(items: &[T]) -> Box<[U]> {
19     items.iter().copied().map(Into::into).collect()
22 #[inline]
23 fn map<'a, K1, V1, K2, V2, M>(items: impl Iterator<Item = (&'a K1, &'a V1)>) -> M
24 where
25     K1: Copy + Into<K2> + 'a,
26     V1: Copy + Into<V2> + 'a,
27     M: FromIterator<(K2, V2)>,
29     items.map(|(&k, &v)| (k.into(), v.into())).collect()
32 impl From<obr::ast_defs::XhpEnumValue<'_>> for ty::XhpEnumValue {
33     fn from(x: obr::ast_defs::XhpEnumValue<'_>) -> Self {
34         use obr::ast_defs::XhpEnumValue as Obr;
35         match x {
36             Obr::XEVInt(i) => Self::XEVInt(i),
37             Obr::XEVString(s) => Self::XEVString(s.into()),
38         }
39     }
42 impl From<obr::typing_defs::CeVisibility<'_>> for ty::CeVisibility {
43     fn from(x: obr::typing_defs::CeVisibility<'_>) -> Self {
44         use obr::typing_defs::CeVisibility as Obr;
45         match x {
46             Obr::Vpublic => Self::Public,
47             Obr::Vprivate(s) => Self::Private(s.into()),
48             Obr::Vprotected(s) => Self::Protected(s.into()),
49             Obr::Vinternal(s) => Self::Internal(s.into()),
50         }
51     }
54 impl From<obr::typing_defs::IfcFunDecl<'_>> for ty::IfcFunDecl {
55     fn from(x: obr::typing_defs::IfcFunDecl<'_>) -> Self {
56         use obr::typing_defs_core::IfcFunDecl as Obr;
57         match x {
58             Obr::FDPolicied(s) => Self::FDPolicied(s.map(Into::into)),
59             Obr::FDInferFlows => Self::FDInferFlows,
60         }
61     }
64 fn tshape_field_name_from_decl<P: Pos>(
65     x: obr::typing_defs::TshapeFieldName<'_>,
66 ) -> (ty::ShapeFieldNamePos<P>, ty::TshapeFieldName) {
67     use obr::typing_defs_core::TshapeFieldName as Obr;
68     use ty::ShapeFieldNamePos as SfnPos;
69     use ty::TshapeFieldName;
70     match x {
71         Obr::TSFlitInt(&pos_id) => (
72             SfnPos::Simple(pos_id.0.into()),
73             TshapeFieldName::TSFlitInt(pos_id.1.into()),
74         ),
75         Obr::TSFlitStr(&pos_bytes) => (
76             SfnPos::Simple(pos_bytes.0.into()),
77             TshapeFieldName::TSFlitStr(pos_bytes.1.into()),
78         ),
79         Obr::TSFclassConst(&(pos_id1, pos_id2)) => (
80             SfnPos::ClassConst(pos_id1.0.into(), pos_id2.0.into()),
81             TshapeFieldName::TSFclassConst(pos_id1.1.into(), pos_id2.1.into()),
82         ),
83     }
86 impl<P: Pos> From<&obr::typing_defs::UserAttribute<'_>> for ty::UserAttribute<P> {
87     fn from(attr: &obr::typing_defs::UserAttribute<'_>) -> Self {
88         Self {
89             name: attr.name.into(),
90             classname_params: (attr.classname_params.iter())
91                 .copied()
92                 .map(Into::into)
93                 .collect(),
94         }
95     }
98 impl<R: Reason> From<&obr::typing_defs::Tparam<'_>> for ty::Tparam<R, Ty<R>> {
99     fn from(tparam: &obr::typing_defs::Tparam<'_>) -> Self {
100         Self {
101             variance: tparam.variance,
102             name: tparam.name.into(),
103             tparams: slice(tparam.tparams),
104             constraints: (tparam.constraints.iter())
105                 .map(|(kind, ty)| (*kind, (*ty).into()))
106                 .collect(),
107             reified: tparam.reified,
108             user_attributes: slice(tparam.user_attributes),
109         }
110     }
113 impl<R: Reason> From<&obr::typing_defs::WhereConstraint<'_>> for ty::WhereConstraint<Ty<R>> {
114     fn from(x: &obr::typing_defs::WhereConstraint<'_>) -> Self {
115         Self(x.0.into(), x.1, x.2.into())
116     }
119 fn decl_shape_field_type<R: Reason>(
120     field_name_pos: ty::ShapeFieldNamePos<R::Pos>,
121     sft: &obr::typing_defs::ShapeFieldType<'_>,
122 ) -> ty::ShapeFieldType<R> {
123     ty::ShapeFieldType {
124         field_name_pos,
125         optional: sft.optional,
126         ty: sft.ty.into(),
127     }
130 impl<R: Reason> From<&obr::typing_defs::Ty<'_>> for Ty<R> {
131     fn from(ty: &obr::typing_defs::Ty<'_>) -> Self {
132         use obr::typing_defs_core;
133         use Ty_::*;
134         let reason = R::from(*ty.0);
135         let ty_ = match ty.1 {
136             typing_defs_core::Ty_::Tthis => Tthis,
137             typing_defs_core::Ty_::Tapply(&(pos_id, tys)) => {
138                 Tapply(Box::new((pos_id.into(), slice(tys))))
139             }
140             typing_defs_core::Ty_::Tmixed => Tmixed,
141             typing_defs_core::Ty_::Tlike(ty) => Tlike(ty.into()),
142             typing_defs_core::Ty_::Tany(_) => Tany,
143             typing_defs_core::Ty_::Tnonnull => Tnonnull,
144             typing_defs_core::Ty_::Tdynamic => Tdynamic,
145             typing_defs_core::Ty_::Toption(ty) => Toption(ty.into()),
146             typing_defs_core::Ty_::Tprim(prim) => Tprim(*prim),
147             typing_defs_core::Ty_::Tfun(ft) => Tfun(Box::new(ft.into())),
148             typing_defs_core::Ty_::Ttuple(tys) => Ttuple(slice(tys)),
149             typing_defs_core::Ty_::Tshape(&(kind, fields)) => Tshape(Box::new((
150                 kind,
151                 fields
152                     .iter()
153                     .map(|(name, ty)| {
154                         let (field_name_pos, name) = tshape_field_name_from_decl(name.0);
155                         (name, decl_shape_field_type(field_name_pos, ty))
156                     })
157                     .collect(),
158             ))),
159             typing_defs_core::Ty_::Trefinement(&(ty, cr)) => {
160                 Trefinement(Box::new(decl::TrefinementType {
161                     ty: ty.into(),
162                     refinement: ty::ClassRefinement {
163                         consts: (cr.cr_consts.iter())
164                             .map(|(k, v)| ((*k).into(), (*v).into()))
165                             .collect(),
166                     },
167                 }))
168             }
169             typing_defs_core::Ty_::Tvar(ident) => Tvar(ident.into()),
170             typing_defs_core::Ty_::Tgeneric(&(pos_id, tys)) => {
171                 Tgeneric(Box::new((pos_id.into(), slice(tys))))
172             }
173             typing_defs_core::Ty_::Tunion(tys) => Tunion(slice(tys)),
174             typing_defs_core::Ty_::Tintersection(tys) => Tintersection(slice(tys)),
175             typing_defs_core::Ty_::TvecOrDict(&(ty1, ty2)) => {
176                 TvecOrDict(Box::new((ty1.into(), ty2.into())))
177             }
178             typing_defs_core::Ty_::Taccess(taccess_type) => Taccess(Box::new(taccess_type.into())),
179             typing_defs_core::Ty_::TunappliedAlias(_)
180             | typing_defs_core::Ty_::Tnewtype(_)
181             | typing_defs_core::Ty_::Tdependent(_)
182             | typing_defs_core::Ty_::Tclass(_)
183             | typing_defs_core::Ty_::Tneg(_) => {
184                 unreachable!("Not used in decl tys")
185             }
186         };
187         Ty::new(reason, ty_)
188     }
191 impl<R: Reason> From<obr::typing_defs::RefinedConst<'_>> for ty::RefinedConst<Ty<R>> {
192     fn from(rc: obr::typing_defs::RefinedConst<'_>) -> Self {
193         Self {
194             bound: rc.bound.into(),
195             is_ctx: rc.is_ctx.into(),
196         }
197     }
200 impl<R: Reason> From<obr::typing_defs::RefinedConstBound<'_>> for ty::RefinedConstBound<Ty<R>> {
201     fn from(ctr: obr::typing_defs::RefinedConstBound<'_>) -> Self {
202         use obr::typing_defs::RefinedConstBound::*;
203         match ctr {
204             TRexact(ty) => Self::Exact(ty.into()),
205             TRloose(bounds) => Self::Loose(bounds.into()),
206         }
207     }
210 impl<R: Reason> From<&obr::typing_defs::RefinedConstBounds<'_>> for ty::RefinedConstBounds<Ty<R>> {
211     fn from(bounds: &obr::typing_defs::RefinedConstBounds<'_>) -> Self {
212         Self {
213             lower: slice(bounds.lower),
214             upper: slice(bounds.upper),
215         }
216     }
219 impl<R: Reason> From<&obr::typing_defs::TaccessType<'_>> for ty::TaccessType<R, Ty<R>> {
220     fn from(taccess_type: &obr::typing_defs::TaccessType<'_>) -> Self {
221         Self {
222             ty: taccess_type.0.into(),
223             type_const: taccess_type.1.into(),
224         }
225     }
228 impl<R: Reason> From<obr::typing_defs::Capability<'_>> for ty::Capability<R, Ty<R>> {
229     fn from(cap: obr::typing_defs::Capability<'_>) -> Self {
230         use obr::typing_defs_core::Capability as Obr;
231         match cap {
232             Obr::CapDefaults(pos) => Self::CapDefaults(pos.into()),
233             Obr::CapTy(ty) => Self::CapTy(ty.into()),
234         }
235     }
238 impl<R: Reason> From<&obr::typing_defs::FunImplicitParams<'_>> for ty::FunImplicitParams<R, Ty<R>> {
239     fn from(x: &obr::typing_defs::FunImplicitParams<'_>) -> Self {
240         Self {
241             capability: x.capability.into(),
242         }
243     }
246 impl<R: Reason> From<&obr::typing_defs::FunType<'_>> for ty::FunType<R, Ty<R>> {
247     fn from(ft: &obr::typing_defs::FunType<'_>) -> Self {
248         Self {
249             tparams: slice(ft.tparams),
250             where_constraints: slice(ft.where_constraints),
251             params: slice(ft.params),
252             implicit_params: ft.implicit_params.into(),
253             ret: ft.ret.into(),
254             flags: ft.flags,
255             ifc_decl: ft.ifc_decl.into(),
256         }
257     }
260 impl<R: Reason> From<&obr::typing_defs_core::PossiblyEnforcedTy<'_>>
261     for decl::ty::PossiblyEnforcedTy<Ty<R>>
263     fn from(ty: &obr::typing_defs_core::PossiblyEnforcedTy<'_>) -> Self {
264         Self {
265             ty: ty.type_.into(),
266             enforced: ty.enforced,
267         }
268     }
271 impl<R: Reason> From<&obr::typing_defs_core::FunParam<'_>> for ty::FunParam<R, Ty<R>> {
272     fn from(fp: &obr::typing_defs_core::FunParam<'_>) -> Self {
273         Self {
274             pos: fp.pos.into(),
275             name: fp.name.map(Into::into),
276             ty: fp.type_.into(),
277             flags: fp.flags,
278         }
279     }
282 impl From<obr::typing_defs::ClassConstFrom<'_>> for ty::ClassConstFrom {
283     fn from(x: obr::typing_defs::ClassConstFrom<'_>) -> Self {
284         use obr::typing_defs::ClassConstFrom as Obr;
285         match x {
286             Obr::Self_ => Self::Self_,
287             Obr::From(s) => Self::From(s.into()),
288         }
289     }
292 impl From<obr::typing_defs::ClassConstRef<'_>> for ty::ClassConstRef {
293     fn from(x: obr::typing_defs::ClassConstRef<'_>) -> Self {
294         Self(x.0.into(), x.1.into())
295     }
298 impl<R: Reason> From<&obr::typing_defs::AbstractTypeconst<'_>> for ty::AbstractTypeconst<R> {
299     fn from(x: &obr::typing_defs::AbstractTypeconst<'_>) -> Self {
300         Self {
301             as_constraint: x.as_constraint.map(Into::into),
302             super_constraint: x.super_constraint.map(Into::into),
303             default: x.default.map(Into::into),
304         }
305     }
308 impl<R: Reason> From<&obr::typing_defs::ConcreteTypeconst<'_>> for ty::ConcreteTypeconst<R> {
309     fn from(x: &obr::typing_defs::ConcreteTypeconst<'_>) -> Self {
310         Self {
311             ty: x.tc_type.into(),
312         }
313     }
316 impl<R: Reason> From<obr::typing_defs::Typeconst<'_>> for ty::Typeconst<R> {
317     fn from(x: obr::typing_defs::Typeconst<'_>) -> Self {
318         use obr::typing_defs::Typeconst as Obr;
319         match x {
320             Obr::TCAbstract(atc) => Self::TCAbstract(atc.into()),
321             Obr::TCConcrete(ctc) => Self::TCConcrete(ctc.into()),
322         }
323     }
326 impl<R: Reason> From<&obr::typing_defs::EnumType<'_>> for ty::EnumType<R> {
327     fn from(x: &obr::typing_defs::EnumType<'_>) -> Self {
328         Self {
329             base: x.base.into(),
330             constraint: x.constraint.map(Into::into),
331             includes: slice(x.includes),
332         }
333     }
336 impl<P: Pos> From<(&obr::pos::Pos<'_>, bool)> for ty::Enforceable<P> {
337     fn from((pos, is_enforceable): (&obr::pos::Pos<'_>, bool)) -> Self {
338         if is_enforceable {
339             Self(Some(pos.into()))
340         } else {
341             Self(None)
342         }
343     }
346 impl<R: Reason> From<&obr::shallow_decl_defs::ShallowClassConst<'_>>
347     for shallow::ShallowClassConst<R>
349     fn from(scc: &obr::shallow_decl_defs::ShallowClassConst<'_>) -> Self {
350         Self {
351             kind: scc.abstract_,
352             name: scc.name.into(),
353             ty: scc.type_.into(),
354             refs: slice(scc.refs),
355         }
356     }
359 impl<R: Reason> From<&obr::shallow_decl_defs::ShallowTypeconst<'_>>
360     for shallow::ShallowTypeconst<R>
362     fn from(stc: &obr::shallow_decl_defs::ShallowTypeconst<'_>) -> Self {
363         Self {
364             name: stc.name.into(),
365             kind: stc.kind.into(),
366             enforceable: <ty::Enforceable<R::Pos>>::from(stc.enforceable),
367             reifiable: stc.reifiable.map(Into::into),
368             is_ctx: stc.is_ctx,
369         }
370     }
373 impl<R: Reason> From<&obr::shallow_decl_defs::ShallowMethod<'_>> for shallow::ShallowMethod<R> {
374     fn from(sm: &obr::shallow_decl_defs::ShallowMethod<'_>) -> Self {
375         Self {
376             name: sm.name.into(),
377             ty: sm.type_.into(),
378             visibility: sm.visibility,
379             deprecated: sm.deprecated.map(Into::into),
380             attributes: slice(sm.attributes),
381             flags: sm.flags,
382         }
383     }
386 impl<R: Reason> From<&obr::shallow_decl_defs::ShallowProp<'_>> for shallow::ShallowProp<R> {
387     fn from(sp: &obr::shallow_decl_defs::ShallowProp<'_>) -> Self {
388         Self {
389             name: sp.name.into(),
390             xhp_attr: sp.xhp_attr,
391             ty: sp.type_.into(),
392             visibility: sp.visibility,
393             flags: sp.flags,
394         }
395     }
398 impl<R: Reason> From<&obr::shallow_decl_defs::ClassDecl<'_>> for shallow::ShallowClass<R> {
399     fn from(sc: &obr::shallow_decl_defs::ClassDecl<'_>) -> Self {
400         // Destructure to help ensure we convert every field.
401         let obr::shallow_decl_defs::ClassDecl {
402             mode,
403             final_,
404             abstract_,
405             is_xhp,
406             internal,
407             has_xhp_keyword,
408             kind,
409             module,
410             name,
411             tparams,
412             where_constraints,
413             extends,
414             uses,
415             xhp_attr_uses,
416             xhp_enum_values,
417             req_extends,
418             req_implements,
419             req_class,
420             implements,
421             support_dynamic_type,
422             consts,
423             typeconsts,
424             props,
425             sprops,
426             constructor,
427             static_methods,
428             methods,
429             user_attributes,
430             enum_type,
431             docs_url,
432         } = sc;
433         Self {
434             mode: *mode,
435             is_final: *final_,
436             is_abstract: *abstract_,
437             is_internal: *internal,
438             is_xhp: *is_xhp,
439             has_xhp_keyword: *has_xhp_keyword,
440             kind: *kind,
441             module: module.map(Into::into),
442             name: (*name).into(),
443             tparams: slice(tparams),
444             where_constraints: slice(where_constraints),
445             extends: slice(extends),
446             uses: slice(uses),
447             xhp_attr_uses: slice(xhp_attr_uses),
448             xhp_enum_values: (xhp_enum_values.iter())
449                 .map(|(&k, v)| (k.into(), slice(v)))
450                 .collect(),
451             req_extends: slice(req_extends),
452             req_implements: slice(req_implements),
453             req_class: slice(req_class),
454             implements: slice(implements),
455             support_dynamic_type: *support_dynamic_type,
456             consts: slice(consts),
457             typeconsts: slice(typeconsts),
458             props: slice(props),
459             static_props: slice(sprops),
460             constructor: constructor.map(Into::into),
461             static_methods: slice(static_methods),
462             methods: slice(methods),
463             user_attributes: slice(user_attributes),
464             enum_type: enum_type.map(Into::into),
465             docs_url: docs_url.map(Into::into),
466         }
467     }
470 impl<R: Reason> From<&obr::shallow_decl_defs::FunDecl<'_>> for shallow::FunDecl<R> {
471     fn from(sf: &obr::shallow_decl_defs::FunDecl<'_>) -> Self {
472         Self {
473             pos: sf.pos.into(),
474             ty: sf.type_.into(),
475             deprecated: sf.deprecated.map(Into::into),
476             module: sf.module.map(Into::into),
477             internal: sf.internal,
478             php_std_lib: sf.php_std_lib,
479             support_dynamic_type: sf.support_dynamic_type,
480             no_auto_dynamic: sf.no_auto_dynamic,
481         }
482     }
485 impl<R: Reason> From<&obr::shallow_decl_defs::TypedefDecl<'_>> for shallow::TypedefDecl<R> {
486     fn from(x: &obr::shallow_decl_defs::TypedefDecl<'_>) -> Self {
487         Self {
488             module: x.module.map(Into::into),
489             pos: x.pos.into(),
490             vis: x.vis,
491             tparams: slice(x.tparams),
492             as_constraint: x.as_constraint.map(Into::into),
493             super_constraint: x.super_constraint.map(Into::into),
494             ty: x.type_.into(),
495             is_ctx: x.is_ctx,
496             attributes: slice(x.attributes),
497             internal: x.internal,
498             docs_url: x.docs_url.map(Into::into),
499         }
500     }
503 impl<R: Reason> From<&obr::shallow_decl_defs::ConstDecl<'_>> for shallow::ConstDecl<R> {
504     fn from(x: &obr::shallow_decl_defs::ConstDecl<'_>) -> Self {
505         Self {
506             pos: x.pos.into(),
507             ty: x.type_.into(),
508         }
509     }
512 impl From<obr::typing_defs::ModuleReference<'_>> for ty::ModuleReference {
513     fn from(x: obr::typing_defs::ModuleReference<'_>) -> Self {
514         use obr::typing_defs::ModuleReference as Obr;
515         match x {
516             Obr::MRGlobal => Self::MRGlobal,
517             Obr::MRPrefix(m) => Self::MRPrefix(m.into()),
518             Obr::MRExact(m) => Self::MRExact(m.into()),
519         }
520     }
523 impl<R: Reason> From<&obr::shallow_decl_defs::ModuleDefType<'_>> for shallow::ModuleDecl<R> {
524     fn from(x: &obr::shallow_decl_defs::ModuleDefType<'_>) -> Self {
525         Self {
526             pos: x.pos.into(),
527             exports: x.exports.map(slice),
528             imports: x.imports.map(slice),
529         }
530     }
533 impl<R: Reason> From<&obr::shallow_decl_defs::Decl<'_>> for shallow::Decl<R> {
534     fn from(decl: &obr::shallow_decl_defs::Decl<'_>) -> Self {
535         use obr::shallow_decl_defs::Decl as Obr;
536         match *decl {
537             Obr::Class(x) => Self::Class(x.into()),
538             Obr::Fun(x) => Self::Fun(x.into()),
539             Obr::Typedef(x) => Self::Typedef(x.into()),
540             Obr::Const(x) => Self::Const(x.into()),
541             Obr::Module(x) => Self::Module(x.into()),
542         }
543     }
546 impl<R: Reason> From<&(&str, obr::shallow_decl_defs::Decl<'_>)> for shallow::NamedDecl<R> {
547     fn from(decl: &(&str, obr::shallow_decl_defs::Decl<'_>)) -> Self {
548         use obr::shallow_decl_defs::Decl as Obr;
549         match *decl {
550             (name, Obr::Class(x)) => Self::Class(name.into(), x.into()),
551             (name, Obr::Fun(x)) => Self::Fun(name.into(), x.into()),
552             (name, Obr::Typedef(x)) => Self::Typedef(name.into(), x.into()),
553             (name, Obr::Const(x)) => Self::Const(name.into(), x.into()),
554             (name, Obr::Module(x)) => Self::Module(name.into(), x.into()),
555         }
556     }
559 impl From<&obr::decl_defs::Element<'_>> for folded::FoldedElement {
560     fn from(x: &obr::decl_defs::Element<'_>) -> Self {
561         Self {
562             flags: x.flags,
563             origin: x.origin.into(),
564             visibility: x.visibility.into(),
565             deprecated: x.deprecated.map(Into::into),
566         }
567     }
570 impl<R: Reason> From<&obr::decl_defs::SubstContext<'_>> for folded::SubstContext<R> {
571     fn from(x: &obr::decl_defs::SubstContext<'_>) -> Self {
572         Self {
573             subst: folded::Subst(map(x.subst.iter())),
574             class_context: x.class_context.into(),
575             from_req_extends: x.from_req_extends,
576         }
577     }
580 impl<R: Reason> From<&obr::typing_defs::TypeconstType<'_>> for folded::TypeConst<R> {
581     fn from(x: &obr::typing_defs::TypeconstType<'_>) -> Self {
582         Self {
583             is_synthesized: x.synthesized,
584             name: x.name.into(),
585             kind: x.kind.into(),
586             origin: x.origin.into(),
587             enforceable: x.enforceable.into(),
588             reifiable: x.reifiable.map(Into::into),
589             is_concretized: x.concretized,
590             is_ctx: x.is_ctx,
591         }
592     }
595 impl<R: Reason> From<&obr::typing_defs::ClassConst<'_>> for folded::ClassConst<R> {
596     fn from(x: &obr::typing_defs::ClassConst<'_>) -> Self {
597         Self {
598             is_synthesized: x.synthesized,
599             kind: x.abstract_,
600             pos: x.pos.into(),
601             ty: x.type_.into(),
602             origin: x.origin.into(),
603             refs: slice(x.refs),
604         }
605     }
608 impl<R: Reason> From<&obr::decl_defs::Requirement<'_>> for folded::Requirement<R> {
609     fn from(req: &obr::decl_defs::Requirement<'_>) -> Self {
610         Self {
611             pos: req.0.into(),
612             ty: req.1.into(),
613         }
614     }
617 impl From<(Option<&obr::decl_defs::Element<'_>>, ty::ConsistentKind)> for folded::Constructor {
618     fn from(construct: (Option<&obr::decl_defs::Element<'_>>, ty::ConsistentKind)) -> Self {
619         Self::new(construct.0.map(Into::into), construct.1)
620     }
623 impl<P> From<obr::decl_defs::DeclError<'_>> for crate::decl_error::DeclError<P>
624 where
625     P: for<'a> From<&'a obr::pos::Pos<'a>>,
627     fn from(decl_error: obr::decl_defs::DeclError<'_>) -> Self {
628         use obr::decl_defs::DeclError as Obr;
629         match decl_error {
630             Obr::WrongExtendKind {
631                 pos,
632                 kind,
633                 name,
634                 parent_pos,
635                 parent_kind,
636                 parent_name,
637             } => Self::WrongExtendKind {
638                 pos: pos.into(),
639                 kind,
640                 name: name.into(),
641                 parent_pos: parent_pos.into(),
642                 parent_kind,
643                 parent_name: parent_name.into(),
644             },
645             Obr::CyclicClassDef { pos, stack } => {
646                 Self::CyclicClassDef(pos.into(), stack.iter().copied().map(Into::into).collect())
647             }
648         }
649     }
652 impl<R: Reason> From<&obr::decl_defs::DeclClassType<'_>> for folded::FoldedClass<R> {
653     fn from(cls: &obr::decl_defs::DeclClassType<'_>) -> Self {
654         // Destructure to help ensure we convert every field. A couple fields
655         // are ignored because they're redundant with other fields (and
656         // `folded::FoldedClass` just omits the redundant fields).
657         let obr::decl_defs::DeclClassType {
658             name,
659             pos,
660             kind,
661             abstract_: _, // `Self::is_abstract()` just reads the `kind` field
662             final_,
663             const_,
664             internal,
665             is_xhp,
666             has_xhp_keyword,
667             support_dynamic_type,
668             module,
669             tparams,
670             where_constraints,
671             substs,
672             ancestors,
673             props,
674             sprops,
675             methods,
676             smethods,
677             consts,
678             typeconsts,
679             xhp_enum_values,
680             construct,
681             need_init: _, // `Self::has_concrete_constructor()` reads the `constructor` field
682             deferred_init_members,
683             req_ancestors,
684             req_ancestors_extends,
685             req_class_ancestors,
686             extends,
687             sealed_whitelist,
688             xhp_attr_deps,
689             enum_type,
690             decl_errors,
691             docs_url,
692         } = cls;
693         Self {
694             name: (*name).into(),
695             pos: (*pos).into(),
696             kind: *kind,
697             is_final: *final_,
698             is_const: *const_,
699             is_internal: *internal,
700             is_xhp: *is_xhp,
701             has_xhp_keyword: *has_xhp_keyword,
702             support_dynamic_type: *support_dynamic_type,
703             enum_type: enum_type.map(Into::into),
704             module: module.map(Into::into),
705             tparams: slice(tparams),
706             where_constraints: slice(where_constraints),
707             substs: map(substs.iter()),
708             ancestors: map(ancestors.iter()),
709             props: map(props.iter()),
710             static_props: map(sprops.iter()),
711             methods: map(methods.iter()),
712             static_methods: map(smethods.iter()),
713             constructor: (*construct).into(),
714             consts: map(consts.iter()),
715             type_consts: map(typeconsts.iter()),
716             xhp_enum_values: (xhp_enum_values.iter())
717                 .map(|(&s, &evs)| (s.into(), slice(evs)))
718                 .collect(),
719             extends: extends.iter().copied().map(Into::into).collect(),
720             xhp_attr_deps: xhp_attr_deps.iter().copied().map(Into::into).collect(),
721             req_ancestors: req_ancestors.iter().copied().map(Into::into).collect(),
722             req_ancestors_extends: (req_ancestors_extends.iter())
723                 .copied()
724                 .map(Into::into)
725                 .collect(),
726             req_class_ancestors: (req_class_ancestors.iter())
727                 .copied()
728                 .map(Into::into)
729                 .collect(),
730             sealed_whitelist: (sealed_whitelist)
731                 .map(|l| l.iter().copied().map(Into::into).collect()),
732             deferred_init_members: (deferred_init_members.iter())
733                 .copied()
734                 .map(Into::into)
735                 .collect(),
736             decl_errors: slice(*decl_errors),
737             docs_url: docs_url.map(Into::into),
738         }
739     }