hyperlight_component_util/
tv.rs1use crate::etypes::{
18 BoundedTyvar, Ctx, Defined, FreeTyvar, Handleable, ImportExport, TypeBound, Tyvar,
19};
20use crate::substitute::{self, Substitution, Unvoidable};
21
22pub enum ResolvedTyvar<'a> {
24 Definite(Defined<'a>),
26 #[allow(unused)]
28 Bound(u32),
29 E(u32, u32, TypeBound<'a>),
31 U(u32, u32, TypeBound<'a>),
33}
34
35impl<'p, 'a> Ctx<'p, 'a> {
36 fn lookup_uvar<'c>(&'c self, o: u32, i: u32) -> &'c (BoundedTyvar<'a>, bool) {
38 &self.parents().nth(o as usize).unwrap().uvars[i as usize]
40 }
41 fn lookup_evar<'c>(&'c self, o: u32, i: u32) -> &'c (BoundedTyvar<'a>, Option<Defined<'a>>) {
43 &self.parents().nth(o as usize).unwrap().evars[i as usize]
45 }
46 pub fn var_bound<'c>(&'c self, tv: &Tyvar) -> &'c TypeBound<'a> {
50 match tv {
51 Tyvar::Bound(_) => panic!("Requested bound for Bound tyvar"),
52 Tyvar::Free(FreeTyvar::U(o, i)) => &self.lookup_uvar(*o, *i).0.bound,
53 Tyvar::Free(FreeTyvar::E(o, i)) => &self.lookup_evar(*o, *i).0.bound,
54 }
55 }
56 pub fn resolve_tyvar<'c>(&'c self, v: &Tyvar) -> ResolvedTyvar<'a> {
59 let check_deftype = |dt: &Defined<'a>| match dt {
60 Defined::Handleable(Handleable::Var(v_)) => self.resolve_tyvar(v_),
61 _ => ResolvedTyvar::Definite(dt.clone()),
62 };
63 match *v {
64 Tyvar::Bound(i) => ResolvedTyvar::Bound(i),
65 Tyvar::Free(FreeTyvar::E(o, i)) => {
66 let (tv, def) = self.lookup_evar(o, i);
67 match (&tv.bound, def) {
68 (TypeBound::Eq(dt), _) => check_deftype(dt),
69 (_, Some(dt)) => check_deftype(dt),
70 (tb, _) => ResolvedTyvar::E(o, i, tb.clone()),
71 }
72 }
73 Tyvar::Free(FreeTyvar::U(o, i)) => {
74 let (tv, _) = self.lookup_uvar(o, i);
75 match &tv.bound {
76 TypeBound::Eq(dt) => check_deftype(dt),
77 tb => ResolvedTyvar::U(o, i, tb.clone()),
78 }
79 }
80 }
81 }
82 pub fn bound_to_evars(
87 &mut self,
88 origin: Option<&'a str>,
89 vs: &[BoundedTyvar<'a>],
90 ) -> substitute::Opening {
91 let mut sub = substitute::Opening::new(false, self.evars.len() as u32);
92 for var in vs {
93 let var = var.push_origin(origin.map(ImportExport::Export));
94 let bound = sub.bounded_tyvar(&var).not_void();
95 self.evars.push((bound, None));
96 sub.next();
97 }
98 sub
99 }
100 pub fn bound_to_uvars(
105 &mut self,
106 origin: Option<&'a str>,
107 vs: &[BoundedTyvar<'a>],
108 imported: bool,
109 ) -> substitute::Opening {
110 let mut sub = substitute::Opening::new(true, self.uvars.len() as u32);
111 for var in vs {
112 let var = var.push_origin(origin.map(ImportExport::Import));
113 let bound = sub.bounded_tyvar(&var).not_void();
114 self.uvars.push((bound, imported));
115 sub.next();
116 }
117 sub
118 }
119}