@@ -274,7 +274,7 @@ impl<S: Record> FieldPtr<S> for Ptr<S> {
274274 PtrKind :: Field ( _, _, FieldShape :: Single ) => {
275275 self . field_ptr ( get, get_mut, offset) . decay ( )
276276 }
277- _ => self . elems_of ( get, get_mut, offset ( & S :: OFFSETS ) ) ,
277+ _ => self . elems_of ( get, get_mut, offset ( & S :: OFFSETS ) , true ) ,
278278 }
279279 }
280280}
@@ -290,7 +290,8 @@ impl<S: Record> Ptr<S> {
290290 // A pointer to the first element of the array or vector that `get` gives
291291 // in the struct that self points to, which is at byte `offset` of the
292292 // struct. The pointer reaches the array or vector through the Value that
293- // holds the struct, or else through self.
293+ // holds the struct, or else through self. `inline` tells if the elements
294+ // are in the memory of the struct, as those of an array are.
294295 // The projection of an array of structs takes the array as a Box, the
295296 // contents of its Value.
296297 #[ allow( clippy:: borrowed_box) ]
@@ -300,6 +301,7 @@ impl<S: Record> Ptr<S> {
300301 get : impl Fn ( & S ) -> & C + ' static ,
301302 get_mut : impl Fn ( & mut S ) -> & mut C + ' static ,
302303 offset : usize ,
304+ inline : bool ,
303305 ) -> Ptr < T >
304306 where
305307 C : AsRef < [ T ] > + AsMut < [ T ] > + ' static ,
@@ -318,18 +320,21 @@ impl<S: Record> Ptr<S> {
318320 move |s : & S | get ( s) . as_ref ( ) ,
319321 move |s : & mut S | get_mut ( s) . as_mut ( ) ,
320322 address ( w. as_ptr ( ) as * const ( ) ) ,
323+ inline,
321324 ) ) ,
322325 PtrKind :: StackArray ( w) | PtrKind :: HeapArray ( w) => Rc :: new ( InValue :: new (
323326 w,
324327 move |a : & Box < [ S ] > | get ( & a[ idx] ) . as_ref ( ) ,
325328 move |a : & mut Box < [ S ] > | get_mut ( & mut a[ idx] ) . as_mut ( ) ,
326329 address ( w. as_ptr ( ) as * const ( ) ) ,
330+ inline,
327331 ) ) ,
328332 PtrKind :: StackVec ( w) | PtrKind :: HeapVec ( w) => Rc :: new ( InValue :: new (
329333 w,
330334 move |v : & Vec < S > | get ( & v[ idx] ) . as_ref ( ) ,
331335 move |v : & mut Vec < S > | get_mut ( & mut v[ idx] ) . as_mut ( ) ,
332336 address ( w. as_ptr ( ) as * const ( ) ) ,
337+ inline,
333338 ) ) ,
334339 _ => Rc :: new ( FieldOf :: new (
335340 self . clone ( ) ,
@@ -355,11 +360,13 @@ struct InValue<R, G, M> {
355360 get_mut : M ,
356361 // The address of the field, for comparisons.
357362 address : usize ,
363+ // Whether the elements are in the memory of the struct.
364+ inline : bool ,
358365}
359366
360367impl < R , G , M > InValue < R , G , M > {
361368 #[ inline]
362- fn new < T > ( root : & Weak < RefCell < R > > , get : G , get_mut : M , address : usize ) -> Self
369+ fn new < T > ( root : & Weak < RefCell < R > > , get : G , get_mut : M , address : usize , inline : bool ) -> Self
363370 where
364371 G : Fn ( & R ) -> & [ T ] ,
365372 M : Fn ( & mut R ) -> & mut [ T ] ,
@@ -369,6 +376,7 @@ impl<R, G, M> InValue<R, G, M> {
369376 get,
370377 get_mut,
371378 address,
379+ inline,
372380 }
373381 }
374382}
@@ -404,6 +412,11 @@ where
404412 fn address ( & self ) -> usize {
405413 self . address
406414 }
415+
416+ fn struct_root ( & self ) -> Option < usize > {
417+ self . inline
418+ . then_some ( self . root . as_ptr ( ) as * const ( ) as usize )
419+ }
407420}
408421
409422// A field of a struct, as returned by field_ref!, which is made a pointer to
@@ -445,7 +458,7 @@ where
445458 . decay ( ) ,
446459 _ => self
447460 . base
448- . elems_of ( self . get , self . get_mut , ( self . offset ) ( & S :: OFFSETS ) ) ,
461+ . elems_of ( self . get , self . get_mut , ( self . offset ) ( & S :: OFFSETS ) , false ) ,
449462 }
450463 }
451464}
@@ -1586,6 +1599,70 @@ mod tests {
15861599 assert_eq ! ( v. offset( 1 ) . read( ) , 6 ) ;
15871600 }
15881601
1602+ #[ derive( Clone , Default , Record , ByteRepr ) ]
1603+ #[ byte_size( 44 ) ]
1604+ struct Adjacent {
1605+ #[ offset( 0 ) ]
1606+ #[ byte_size( 8 ) ]
1607+ a : Box < [ i32 ] > ,
1608+ #[ offset( 8 ) ]
1609+ #[ byte_size( 8 ) ]
1610+ b : Box < [ i32 ] > ,
1611+ #[ offset( 16 ) ]
1612+ #[ byte_size( 24 ) ]
1613+ v : Vec < i32 > ,
1614+ #[ offset( 40 ) ]
1615+ c : i32 ,
1616+ }
1617+
1618+ #[ derive( Default , Record , ByteRepr ) ]
1619+ #[ byte_size( 48 ) ]
1620+ struct HoldsAdjacent {
1621+ #[ offset( 0 ) ]
1622+ n : i32 ,
1623+ #[ offset( 4 ) ]
1624+ #[ byte_size( 44 ) ]
1625+ adj : Adjacent ,
1626+ }
1627+
1628+ fn adjacent ( ) -> Adjacent {
1629+ Adjacent {
1630+ a : vec ! [ 1 , 2 ] . into_boxed_slice ( ) ,
1631+ b : vec ! [ 3 , 4 ] . into_boxed_slice ( ) ,
1632+ v : vec ! [ 5 , 6 , 7 , 8 , 9 , 10 ] ,
1633+ c : 11 ,
1634+ }
1635+ }
1636+
1637+ fn check_adjacent ( s : Ptr < Adjacent > ) {
1638+ // One past the end of an array field is the next field.
1639+ let a: Ptr < i32 > = array_field_ptr ! ( s, a) ;
1640+ let b: Ptr < i32 > = array_field_ptr ! ( s, b) ;
1641+ assert_eq ! ( a. offset( 2 ) , b) ;
1642+ assert ! ( a. offset( 2 ) <= b && a. offset( 2 ) >= b) ;
1643+ assert ! ( a. offset( 1 ) < b && b < a. offset( 3 ) ) ;
1644+ assert_ne ! ( a. offset( 1 ) , b) ;
1645+ assert_eq ! ( b. offset( -2 ) , a) ;
1646+ // The elements of a vector are not in the struct.
1647+ let v: Ptr < i32 > = field_ref ! ( s, v) . as_pointer ( ) ;
1648+ assert_ne ! ( v. offset( 6 ) , field_ptr!( s, c) ) ;
1649+ }
1650+
1651+ #[ test]
1652+ fn adjacent_array_fields ( ) {
1653+ let s: Value < Adjacent > = Rc :: new ( RefCell :: new ( adjacent ( ) ) ) ;
1654+ check_adjacent ( s. as_pointer ( ) ) ;
1655+ let held: Value < HoldsAdjacent > = Rc :: new ( RefCell :: new ( HoldsAdjacent {
1656+ n : 0 ,
1657+ adj : adjacent ( ) ,
1658+ } ) ) ;
1659+ check_adjacent ( field_ptr ! ( held, adj) ) ;
1660+ // Fields of different structs are not equal.
1661+ let other: Value < Adjacent > = Rc :: new ( RefCell :: new ( adjacent ( ) ) ) ;
1662+ let a: Ptr < i32 > = array_field_ptr ! ( s, a) ;
1663+ assert_ne ! ( a. offset( 2 ) , array_field_ptr!( other, b) ) ;
1664+ }
1665+
15891666 #[ test]
15901667 fn pointer_size ( ) {
15911668 // Pointers to elements of fields are no larger than other pointers.
0 commit comments