hyperlight_component_util/
tv.rs1use crate::etypes::{
5 BoundedTyvar, Ctx, Defined, FreeTyvar, Handleable, ImportExport, TypeBound, Tyvar,
6};
7use crate::substitute::{self, Substitution, Unvoidable};
8
9pub enum ResolvedTyvar<'a> {
11 Definite(Defined<'a>),
13 #[allow(unused)]
15 Bound(u32),
16 E(u32, u32, TypeBound<'a>),
18 U(u32, u32, TypeBound<'a>),
20}
21
22impl<'p, 'a> Ctx<'p, 'a> {
23 fn lookup_uvar<'c>(&'c self, o: u32, i: u32) -> &'c (BoundedTyvar<'a>, bool) {
25 &self.parents().nth(o as usize).unwrap().uvars[i as usize]
27 }
28 fn lookup_evar<'c>(&'c self, o: u32, i: u32) -> &'c (BoundedTyvar<'a>, Option<Defined<'a>>) {
30 &self.parents().nth(o as usize).unwrap().evars[i as usize]
32 }
33 pub fn var_bound<'c>(&'c self, tv: &Tyvar) -> &'c TypeBound<'a> {
37 match tv {
38 Tyvar::Bound(_) => panic!("Requested bound for Bound tyvar"),
39 Tyvar::Free(FreeTyvar::U(o, i)) => &self.lookup_uvar(*o, *i).0.bound,
40 Tyvar::Free(FreeTyvar::E(o, i)) => &self.lookup_evar(*o, *i).0.bound,
41 }
42 }
43 pub fn resolve_tyvar<'c>(&'c self, v: &Tyvar) -> ResolvedTyvar<'a> {
46 let check_deftype = |dt: &Defined<'a>| match dt {
47 Defined::Handleable(Handleable::Var(v_)) => self.resolve_tyvar(v_),
48 _ => ResolvedTyvar::Definite(dt.clone()),
49 };
50 match *v {
51 Tyvar::Bound(i) => ResolvedTyvar::Bound(i),
52 Tyvar::Free(FreeTyvar::E(o, i)) => {
53 let (tv, def) = self.lookup_evar(o, i);
54 match (&tv.bound, def) {
55 (TypeBound::Eq(dt), _) => check_deftype(dt),
56 (_, Some(dt)) => check_deftype(dt),
57 (tb, _) => ResolvedTyvar::E(o, i, tb.clone()),
58 }
59 }
60 Tyvar::Free(FreeTyvar::U(o, i)) => {
61 let (tv, _) = self.lookup_uvar(o, i);
62 match &tv.bound {
63 TypeBound::Eq(dt) => check_deftype(dt),
64 tb => ResolvedTyvar::U(o, i, tb.clone()),
65 }
66 }
67 }
68 }
69 pub fn bound_to_evars(
74 &mut self,
75 origin: Option<&'a str>,
76 vs: &[BoundedTyvar<'a>],
77 ) -> substitute::Opening {
78 let mut sub = substitute::Opening::new(false, self.evars.len() as u32);
79 for var in vs {
80 let var = var.push_origin(origin.map(ImportExport::Export));
81 let bound = sub.bounded_tyvar(&var).not_void();
82 self.evars.push((bound, None));
83 sub.next();
84 }
85 sub
86 }
87 pub fn bound_to_uvars(
92 &mut self,
93 origin: Option<&'a str>,
94 vs: &[BoundedTyvar<'a>],
95 imported: bool,
96 ) -> substitute::Opening {
97 let mut sub = substitute::Opening::new(true, self.uvars.len() as u32);
98 for var in vs {
99 let var = var.push_origin(origin.map(ImportExport::Import));
100 let bound = sub.bounded_tyvar(&var).not_void();
101 self.uvars.push((bound, imported));
102 sub.next();
103 }
104 sub
105 }
106}