@@ -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 }
@@ -169,6 +171,15 @@ impl<'brand> Context<'brand> {
169171 lock. inner . slab [ bound. index ] . shallow_clone ( )
170172 }
171173
174+ /// Accesses a bound through a union-bound element.
175+ pub ( super ) fn get_root_ref (
176+ & self ,
177+ bound : & UbElement < ' brand , BoundRef < ' brand > > ,
178+ ) -> BoundRef < ' brand > {
179+ let mut lock = self . lock ( ) ;
180+ bound. root ( & mut lock. token )
181+ }
182+
172183 /// Reassigns a bound to a different bound.
173184 ///
174185 /// # Panics
@@ -195,10 +206,10 @@ impl<'brand> Context<'brand> {
195206 prod_r : & Type < ' brand > ,
196207 hint : & ' static str ,
197208 ) -> Result < ( ) , Error > {
198- let existing_root = existing. inner . bound . root ( ) ;
209+ let mut lock = self . lock ( ) ;
210+ let existing_root = existing. inner . bound . root ( & mut lock. token ) ;
199211 let new_bound = Bound :: Product ( prod_l. inner . shallow_clone ( ) , prod_r. inner . shallow_clone ( ) ) ;
200212
201- let mut lock = self . lock ( ) ;
202213 lock. bind ( existing_root, new_bound) . map_err ( |e| {
203214 let new_bound = lock. alloc_bound ( e. new ) ;
204215 drop ( lock) ;
@@ -278,7 +289,9 @@ impl<'brand> DagLike for (&'_ Context<'brand>, BoundRef<'brand>) {
278289 match self . 0 . get ( & self . 1 ) {
279290 Bound :: Free ( ..) | Bound :: Complete ( ..) => Dag :: Nullary ,
280291 Bound :: Sum ( ref ty1, ref ty2) | Bound :: Product ( ref ty1, ref ty2) => {
281- Dag :: Binary ( ( self . 0 , ty1. bound . root ( ) ) , ( self . 0 , ty2. bound . root ( ) ) )
292+ let root1 = self . 0 . get_root_ref ( & ty1. bound ) ;
293+ let root2 = self . 0 . get_root_ref ( & ty2. bound ) ;
294+ Dag :: Binary ( ( self . 0 , root1) , ( self . 0 , root2) )
282295 }
283296 }
284297 }
@@ -313,26 +326,29 @@ impl<'brand> ContextInner<'brand> {
313326 ) ;
314327 self . slab [ bound. index ] = new;
315328 }
329+ }
316330
331+ impl < ' brand > WithGhostToken < ' brand , ContextInner < ' brand > > {
317332 /// It is a common situation that we are pairing two types, and in the
318333 /// case that they are both complete, we want to pair the complete types.
319334 ///
320335 /// This method deals with all the annoying/complicated member variable
321336 /// paths to get the actual complete data out.
322337 fn complete_pair_data (
323- & self ,
338+ & mut self ,
324339 inn1 : & TypeInner < ' brand > ,
325340 inn2 : & TypeInner < ' brand > ,
326341 ) -> Option < ( Arc < Final > , Arc < Final > ) > {
327- let bound1 = & self . slab [ inn1. bound . root ( ) . index ] ;
328- let bound2 = & self . slab [ inn2. bound . root ( ) . index ] ;
342+ let idx1 = inn1. bound . root ( & mut self . token ) . index ;
343+ let idx2 = inn2. bound . root ( & mut self . token ) . index ;
344+ let bound1 = & self . slab [ idx1] ;
345+ let bound2 = & self . slab [ idx2] ;
329346 if let ( Bound :: Complete ( ref data1) , Bound :: Complete ( ref data2) ) = ( bound1, bound2) {
330347 Some ( ( Arc :: clone ( data1) , Arc :: clone ( data2) ) )
331348 } else {
332349 None
333350 }
334351 }
335-
336352 /// Unify the type with another one.
337353 ///
338354 /// Fails if the bounds on the two types are incompatible
@@ -341,9 +357,11 @@ impl<'brand> ContextInner<'brand> {
341357 existing : & TypeInner < ' brand > ,
342358 other : & TypeInner < ' brand > ,
343359 ) -> Result < ( ) , BindError < ' brand > > {
344- existing. bound . unify ( & other. bound , |x_bound, y_bound| {
345- self . bind ( x_bound, self . slab [ y_bound. index ] . shallow_clone ( ) )
346- } )
360+ existing
361+ . bound
362+ . unify ( self , & other. bound , |self_, x_bound, y_bound| {
363+ self_. bind ( x_bound, self_. slab [ y_bound. index ] . shallow_clone ( ) )
364+ } )
347365 }
348366
349367 fn bind (
@@ -386,8 +404,8 @@ impl<'brand> ContextInner<'brand> {
386404 Bound :: Product ( ref ty1, ref ty2) ,
387405 )
388406 | ( CompleteBound :: Sum ( ref comp1, ref comp2) , Bound :: Sum ( ref ty1, ref ty2) ) => {
389- let bound1 = ty1. bound . root ( ) ;
390- let bound2 = ty2. bound . root ( ) ;
407+ let bound1 = ty1. bound . root ( & mut self . token ) ;
408+ let bound2 = ty2. bound . root ( & mut self . token ) ;
391409 self . bind ( bound1, Bound :: Complete ( Arc :: clone ( comp1) ) ) ?;
392410 self . bind ( bound2, Bound :: Complete ( Arc :: clone ( comp2) ) )
393411 }
0 commit comments