@@ -107,10 +107,12 @@ impl<K, V> LeafNode<K, V> {
107
107
}
108
108
}
109
109
110
- // We need to implement Sync here in order to make a static instance
110
+ // We need to implement Sync here in order to make a static instance.
111
111
unsafe impl Sync for LeafNode < ( ) , ( ) > { }
112
112
113
- // An empty node used as a placeholder for the root node, to avoid allocations
113
+ // An empty node used as a placeholder for the root node, to avoid allocations.
114
+ // We use () in order to save space, since no operation on an empty tree will
115
+ // ever take a pointer past the first key.
114
116
static EMPTY_ROOT_NODE : LeafNode < ( ) , ( ) > = LeafNode {
115
117
parent : ptr:: null ( ) ,
116
118
parent_idx : 0 ,
@@ -539,26 +541,39 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
539
541
}
540
542
}
541
543
542
- pub fn keys_mut ( & mut self ) -> & mut [ K ] {
544
+ fn keys_mut ( & mut self ) -> & mut [ K ] {
543
545
unsafe { self . reborrow_mut ( ) . into_key_slice_mut ( ) }
544
546
}
545
547
546
- pub fn vals_mut ( & mut self ) -> & mut [ V ] {
548
+ fn vals_mut ( & mut self ) -> & mut [ V ] {
547
549
unsafe { self . reborrow_mut ( ) . into_val_slice_mut ( ) }
548
550
}
549
551
}
550
552
551
553
impl < ' a , K : ' a , V : ' a , Type > NodeRef < marker:: Immut < ' a > , K , V , Type > {
552
554
fn into_key_slice ( self ) -> & ' a [ K ] {
553
- unsafe {
554
- slice:: from_raw_parts (
555
- self . as_leaf ( ) . keys . as_ptr ( ) ,
556
- self . len ( )
557
- )
555
+ // When taking a pointer to the keys, if our key has a stricter
556
+ // alignment requirement than the shared root does, then the pointer
557
+ // would be out of bounds, which LLVM assumes will not happen. If the
558
+ // alignment is more strict, we need to make an empty slice that doesn't
559
+ // use an out of bounds pointer.
560
+ if mem:: align_of :: < K > ( ) > mem:: align_of :: < LeafNode < ( ) , ( ) > > ( ) && self . is_shared_root ( ) {
561
+ & [ ]
562
+ } else {
563
+ // Here either it's not the root, or the alignment is less strict,
564
+ // in which case the keys pointer will point "one-past-the-end" of
565
+ // the node, which is allowed by LLVM.
566
+ unsafe {
567
+ slice:: from_raw_parts (
568
+ self . as_leaf ( ) . keys . as_ptr ( ) ,
569
+ self . len ( )
570
+ )
571
+ }
558
572
}
559
573
}
560
574
561
575
fn into_val_slice ( self ) -> & ' a [ V ] {
576
+ debug_assert ! ( !self . is_shared_root( ) ) ;
562
577
unsafe {
563
578
slice:: from_raw_parts (
564
579
self . as_leaf ( ) . vals . as_ptr ( ) ,
@@ -583,15 +598,20 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
583
598
}
584
599
585
600
fn into_key_slice_mut ( mut self ) -> & ' a mut [ K ] {
586
- unsafe {
587
- slice:: from_raw_parts_mut (
588
- & mut self . as_leaf_mut ( ) . keys as * mut [ K ] as * mut K ,
589
- self . len ( )
590
- )
601
+ if mem:: align_of :: < K > ( ) > mem:: align_of :: < LeafNode < ( ) , ( ) > > ( ) && self . is_shared_root ( ) {
602
+ & mut [ ]
603
+ } else {
604
+ unsafe {
605
+ slice:: from_raw_parts_mut (
606
+ & mut self . as_leaf_mut ( ) . keys as * mut [ K ] as * mut K ,
607
+ self . len ( )
608
+ )
609
+ }
591
610
}
592
611
}
593
612
594
613
fn into_val_slice_mut ( mut self ) -> & ' a mut [ V ] {
614
+ debug_assert ! ( !self . is_shared_root( ) ) ;
595
615
unsafe {
596
616
slice:: from_raw_parts_mut (
597
617
& mut self . as_leaf_mut ( ) . vals as * mut [ V ] as * mut V ,
0 commit comments