@@ -22,7 +22,9 @@ use ghost_cell::GhostToken;
2222
2323use crate :: dag:: { Dag , DagLike } ;
2424
25- use super :: { Bound , CompleteBound , Error , Final , Incomplete , Type , TypeInner , WithGhostToken } ;
25+ use super :: {
26+ Bound , CompleteBound , Error , Final , Incomplete , Type , TypeInner , UbElement , WithGhostToken ,
27+ } ;
2628
2729// Copied from ghost_cell source. See
2830// https://arhan.sh/blog/the-generativity-pattern-in-rust/
@@ -78,7 +80,7 @@ impl<'brand> Context<'brand> {
7880 pub fn new ( token : GhostToken < ' brand > ) -> Self {
7981 Context {
8082 inner : Arc :: new ( Mutex :: new ( WithGhostToken {
81- _token : token,
83+ token,
8284 inner : ContextInner { slab : vec ! [ ] } ,
8385 } ) ) ,
8486 }
@@ -151,6 +153,15 @@ impl<'brand> Context<'brand> {
151153 lock. inner . slab [ bound. index ] . shallow_clone ( )
152154 }
153155
156+ /// Accesses a bound through a union-bound element.
157+ pub ( super ) fn get_root_ref (
158+ & self ,
159+ bound : & UbElement < ' brand , BoundRef < ' brand > > ,
160+ ) -> BoundRef < ' brand > {
161+ let mut lock = self . lock ( ) ;
162+ bound. root ( & mut lock. token )
163+ }
164+
154165 /// Reassigns a bound to a different bound.
155166 ///
156167 /// # Panics
@@ -177,10 +188,10 @@ impl<'brand> Context<'brand> {
177188 prod_r : & Type < ' brand > ,
178189 hint : & ' static str ,
179190 ) -> Result < ( ) , Error > {
180- let existing_root = existing. inner . bound . root ( ) ;
191+ let mut lock = self . lock ( ) ;
192+ let existing_root = existing. inner . bound . root ( & mut lock. token ) ;
181193 let new_bound = Bound :: Product ( prod_l. inner . shallow_clone ( ) , prod_r. inner . shallow_clone ( ) ) ;
182194
183- let mut lock = self . lock ( ) ;
184195 lock. bind ( existing_root, new_bound) . map_err ( |e| {
185196 let new_bound = lock. alloc_bound ( e. new ) ;
186197 drop ( lock) ;
@@ -260,7 +271,9 @@ impl<'brand> DagLike for (&'_ Context<'brand>, BoundRef<'brand>) {
260271 match self . 0 . get ( & self . 1 ) {
261272 Bound :: Free ( ..) | Bound :: Complete ( ..) => Dag :: Nullary ,
262273 Bound :: Sum ( ref ty1, ref ty2) | Bound :: Product ( ref ty1, ref ty2) => {
263- Dag :: Binary ( ( self . 0 , ty1. bound . root ( ) ) , ( self . 0 , ty2. bound . root ( ) ) )
274+ let root1 = self . 0 . get_root_ref ( & ty1. bound ) ;
275+ let root2 = self . 0 . get_root_ref ( & ty2. bound ) ;
276+ Dag :: Binary ( ( self . 0 , root1) , ( self . 0 , root2) )
264277 }
265278 }
266279 }
@@ -295,26 +308,29 @@ impl<'brand> ContextInner<'brand> {
295308 ) ;
296309 self . slab [ bound. index ] = new;
297310 }
311+ }
298312
313+ impl < ' brand > WithGhostToken < ' brand , ContextInner < ' brand > > {
299314 /// It is a common situation that we are pairing two types, and in the
300315 /// case that they are both complete, we want to pair the complete types.
301316 ///
302317 /// This method deals with all the annoying/complicated member variable
303318 /// paths to get the actual complete data out.
304319 fn complete_pair_data (
305- & self ,
320+ & mut self ,
306321 inn1 : & TypeInner < ' brand > ,
307322 inn2 : & TypeInner < ' brand > ,
308323 ) -> Option < ( Arc < Final > , Arc < Final > ) > {
309- let bound1 = & self . slab [ inn1. bound . root ( ) . index ] ;
310- let bound2 = & self . slab [ inn2. bound . root ( ) . index ] ;
324+ let idx1 = inn1. bound . root ( & mut self . token ) . index ;
325+ let idx2 = inn2. bound . root ( & mut self . token ) . index ;
326+ let bound1 = & self . slab [ idx1] ;
327+ let bound2 = & self . slab [ idx2] ;
311328 if let ( Bound :: Complete ( ref data1) , Bound :: Complete ( ref data2) ) = ( bound1, bound2) {
312329 Some ( ( Arc :: clone ( data1) , Arc :: clone ( data2) ) )
313330 } else {
314331 None
315332 }
316333 }
317-
318334 /// Unify the type with another one.
319335 ///
320336 /// Fails if the bounds on the two types are incompatible
@@ -323,9 +339,11 @@ impl<'brand> ContextInner<'brand> {
323339 existing : & TypeInner < ' brand > ,
324340 other : & TypeInner < ' brand > ,
325341 ) -> Result < ( ) , BindError < ' brand > > {
326- existing. bound . unify ( & other. bound , |x_bound, y_bound| {
327- self . bind ( x_bound, self . slab [ y_bound. index ] . shallow_clone ( ) )
328- } )
342+ existing
343+ . bound
344+ . unify ( self , & other. bound , |self_, x_bound, y_bound| {
345+ self_. bind ( x_bound, self_. slab [ y_bound. index ] . shallow_clone ( ) )
346+ } )
329347 }
330348
331349 fn bind (
@@ -368,8 +386,8 @@ impl<'brand> ContextInner<'brand> {
368386 Bound :: Product ( ref ty1, ref ty2) ,
369387 )
370388 | ( CompleteBound :: Sum ( ref comp1, ref comp2) , Bound :: Sum ( ref ty1, ref ty2) ) => {
371- let bound1 = ty1. bound . root ( ) ;
372- let bound2 = ty2. bound . root ( ) ;
389+ let bound1 = ty1. bound . root ( & mut self . token ) ;
390+ let bound2 = ty2. bound . root ( & mut self . token ) ;
373391 self . bind ( bound1, Bound :: Complete ( Arc :: clone ( comp1) ) ) ?;
374392 self . bind ( bound2, Bound :: Complete ( Arc :: clone ( comp2) ) )
375393 }
0 commit comments