@@ -240,8 +240,9 @@ impl Buffer {
240
240
///
241
241
/// - If `bounds` is outside of the bounds of `self`.
242
242
/// - If `bounds` has a length less than 1.
243
+ #[ track_caller]
243
244
pub fn slice < S : RangeBounds < BufferAddress > > ( & self , bounds : S ) -> BufferSlice < ' _ > {
244
- let ( offset, size) = range_to_offset_size ( bounds) ;
245
+ let ( offset, size) = range_to_offset_size ( bounds, self . size ) ;
245
246
check_buffer_bounds ( self . size , offset, size) ;
246
247
BufferSlice {
247
248
buffer : self ,
@@ -438,7 +439,7 @@ impl Buffer {
438
439
pub struct BufferSlice < ' a > {
439
440
pub ( crate ) buffer : & ' a Buffer ,
440
441
pub ( crate ) offset : BufferAddress ,
441
- pub ( crate ) size : Option < BufferSize > ,
442
+ pub ( crate ) size : BufferSize ,
442
443
}
443
444
#[ cfg( send_sync) ]
444
445
static_assertions:: assert_impl_all!( BufferSlice <' _>: Send , Sync ) ;
@@ -456,20 +457,14 @@ impl<'a> BufferSlice<'a> {
456
457
///
457
458
/// - If `bounds` is outside of the bounds of `self`.
458
459
/// - If `bounds` has a length less than 1.
460
+ #[ track_caller]
459
461
pub fn slice < S : RangeBounds < BufferAddress > > ( & self , bounds : S ) -> BufferSlice < ' a > {
460
- let ( offset, size) = range_to_offset_size ( bounds) ;
461
- check_buffer_bounds (
462
- match self . size {
463
- Some ( size) => size. get ( ) ,
464
- None => self . buffer . size ( ) ,
465
- } ,
466
- offset,
467
- size,
468
- ) ;
462
+ let ( offset, size) = range_to_offset_size ( bounds, self . size . get ( ) ) ;
463
+ check_buffer_bounds ( self . size . get ( ) , offset, size) ;
469
464
BufferSlice {
470
465
buffer : self . buffer ,
471
466
offset : self . offset + offset, // check_buffer_bounds ensures this does not overflow
472
- size : size . or ( self . size ) , // check_buffer_bounds ensures this is essentially min()
467
+ size, // check_buffer_bounds ensures this is essentially min()
473
468
}
474
469
}
475
470
@@ -502,10 +497,7 @@ impl<'a> BufferSlice<'a> {
502
497
) {
503
498
let mut mc = self . buffer . map_context . lock ( ) ;
504
499
assert_eq ! ( mc. initial_range, 0 ..0 , "Buffer is already mapped" ) ;
505
- let end = match self . size {
506
- Some ( s) => self . offset + s. get ( ) ,
507
- None => mc. total_size ,
508
- } ;
500
+ let end = self . offset + self . size . get ( ) ;
509
501
mc. initial_range = self . offset ..end;
510
502
511
503
self . buffer
@@ -608,10 +600,7 @@ impl<'a> BufferSlice<'a> {
608
600
609
601
/// Returns the size of this slice.
610
602
pub fn size ( & self ) -> BufferSize {
611
- self . size . unwrap_or_else ( || {
612
- ( || BufferSize :: new ( self . buffer . size ( ) . checked_sub ( self . offset ) ?) ) ( )
613
- . expect ( "can't happen: slice has incorrect size for its buffer" )
614
- } )
603
+ self . size
615
604
}
616
605
}
617
606
@@ -622,7 +611,7 @@ impl<'a> From<BufferSlice<'a>> for crate::BufferBinding<'a> {
622
611
BufferBinding {
623
612
buffer : value. buffer ,
624
613
offset : value. offset ,
625
- size : value. size ,
614
+ size : Some ( value. size ) ,
626
615
}
627
616
}
628
617
}
@@ -637,16 +626,9 @@ impl<'a> From<BufferSlice<'a>> for crate::BindingResource<'a> {
637
626
638
627
/// The mapped portion of a buffer, if any, and its outstanding views.
639
628
///
640
- /// This ensures that views fall within the mapped range and don't overlap, and
641
- /// also takes care of turning `Option<BufferSize>` sizes into actual buffer
642
- /// offsets.
629
+ /// This ensures that views fall within the mapped range and don't overlap.
643
630
#[ derive( Debug ) ]
644
631
pub ( crate ) struct MapContext {
645
- /// The overall size of the buffer.
646
- ///
647
- /// This is just a convenient copy of [`Buffer::size`].
648
- pub ( crate ) total_size : BufferAddress ,
649
-
650
632
/// The range of the buffer that is mapped.
651
633
///
652
634
/// This is `0..0` if the buffer is not mapped. This becomes non-empty when
@@ -664,9 +646,8 @@ pub(crate) struct MapContext {
664
646
}
665
647
666
648
impl MapContext {
667
- pub ( crate ) fn new ( total_size : BufferAddress ) -> Self {
649
+ pub ( crate ) fn new ( ) -> Self {
668
650
Self {
669
- total_size,
670
651
initial_range : 0 ..0 ,
671
652
sub_ranges : Vec :: new ( ) ,
672
653
}
@@ -689,11 +670,8 @@ impl MapContext {
689
670
/// # Panics
690
671
///
691
672
/// This panics if the given range overlaps with any existing range.
692
- fn add ( & mut self , offset : BufferAddress , size : Option < BufferSize > ) -> BufferAddress {
693
- let end = match size {
694
- Some ( s) => offset + s. get ( ) ,
695
- None => self . initial_range . end ,
696
- } ;
673
+ fn add ( & mut self , offset : BufferAddress , size : BufferSize ) -> BufferAddress {
674
+ let end = offset + size. get ( ) ;
697
675
assert ! ( self . initial_range. start <= offset && end <= self . initial_range. end) ;
698
676
// This check is essential for avoiding undefined behavior: it is the
699
677
// only thing that ensures that `&mut` references to the buffer's
@@ -716,11 +694,8 @@ impl MapContext {
716
694
/// passed to [`add`].
717
695
///
718
696
/// [`add]`: MapContext::add
719
- fn remove ( & mut self , offset : BufferAddress , size : Option < BufferSize > ) {
720
- let end = match size {
721
- Some ( s) => offset + s. get ( ) ,
722
- None => self . initial_range . end ,
723
- } ;
697
+ fn remove ( & mut self , offset : BufferAddress , size : BufferSize ) {
698
+ let end = offset + size. get ( ) ;
724
699
725
700
let index = self
726
701
. sub_ranges
@@ -871,99 +846,100 @@ impl Drop for BufferViewMut<'_> {
871
846
}
872
847
}
873
848
849
+ #[ track_caller]
874
850
fn check_buffer_bounds (
875
851
buffer_size : BufferAddress ,
876
- offset : BufferAddress ,
877
- size : Option < BufferSize > ,
852
+ slice_offset : BufferAddress ,
853
+ slice_size : BufferSize ,
878
854
) {
879
855
// A slice of length 0 is invalid, so the offset must not be equal to or greater than the buffer size.
880
- if offset >= buffer_size {
856
+ if slice_offset >= buffer_size {
881
857
panic ! (
882
858
"slice offset {} is out of range for buffer of size {}" ,
883
- offset , buffer_size
859
+ slice_offset , buffer_size
884
860
) ;
885
861
}
886
862
887
- if let Some ( size) = size {
888
- // Detect integer overflow.
889
- let end = offset. checked_add ( size. get ( ) ) ;
890
- if end. is_none_or ( |end| end > buffer_size) {
891
- panic ! (
892
- "slice offset {} size {} is out of range for buffer of size {}" ,
893
- offset, size, buffer_size
894
- ) ;
895
- }
863
+ // Detect integer overflow.
864
+ let end = slice_offset. checked_add ( slice_size. get ( ) ) ;
865
+ if end. is_none_or ( |end| end > buffer_size) {
866
+ panic ! (
867
+ "slice offset {} size {} is out of range for buffer of size {}" ,
868
+ slice_offset, slice_size, buffer_size
869
+ ) ;
896
870
}
897
871
}
898
872
873
+ #[ track_caller]
899
874
fn range_to_offset_size < S : RangeBounds < BufferAddress > > (
900
875
bounds : S ,
901
- ) -> ( BufferAddress , Option < BufferSize > ) {
876
+ whole_size : BufferAddress ,
877
+ ) -> ( BufferAddress , BufferSize ) {
902
878
let offset = match bounds. start_bound ( ) {
903
879
Bound :: Included ( & bound) => bound,
904
880
Bound :: Excluded ( & bound) => bound + 1 ,
905
881
Bound :: Unbounded => 0 ,
906
882
} ;
907
- let size = match bounds. end_bound ( ) {
908
- Bound :: Included ( & bound) => Some ( bound + 1 - offset) ,
909
- Bound :: Excluded ( & bound) => Some ( bound - offset) ,
910
- Bound :: Unbounded => None ,
911
- }
912
- . map ( |size| BufferSize :: new ( size ) . expect ( "Buffer slices can not be empty" ) ) ;
883
+ let size = BufferSize :: new ( match bounds. end_bound ( ) {
884
+ Bound :: Included ( & bound) => bound + 1 - offset,
885
+ Bound :: Excluded ( & bound) => bound - offset,
886
+ Bound :: Unbounded => whole_size - offset ,
887
+ } )
888
+ . expect ( "buffer slices can not be empty" ) ;
913
889
914
890
( offset, size)
915
891
}
916
892
917
893
#[ cfg( test) ]
918
894
mod tests {
919
- use super :: { check_buffer_bounds, range_to_offset_size, BufferSize } ;
895
+ use super :: { check_buffer_bounds, range_to_offset_size, BufferAddress , BufferSize } ;
896
+
897
+ fn bs ( value : BufferAddress ) -> BufferSize {
898
+ BufferSize :: new ( value) . unwrap ( )
899
+ }
920
900
921
901
#[ test]
922
902
fn range_to_offset_size_works ( ) {
923
- assert_eq ! ( range_to_offset_size( 0 ..2 ) , ( 0 , BufferSize :: new( 2 ) ) ) ;
924
- assert_eq ! ( range_to_offset_size( 2 ..5 ) , ( 2 , BufferSize :: new( 3 ) ) ) ;
925
- assert_eq ! ( range_to_offset_size( ..) , ( 0 , None ) ) ;
926
- assert_eq ! ( range_to_offset_size( 21 ..) , ( 21 , None ) ) ;
927
- assert_eq ! ( range_to_offset_size( 0 ..) , ( 0 , None ) ) ;
928
- assert_eq ! ( range_to_offset_size( ..21 ) , ( 0 , BufferSize :: new( 21 ) ) ) ;
903
+ let whole = 100 ;
904
+
905
+ assert_eq ! ( range_to_offset_size( 0 ..2 , whole) , ( 0 , bs( 2 ) ) ) ;
906
+ assert_eq ! ( range_to_offset_size( 2 ..5 , whole) , ( 2 , bs( 3 ) ) ) ;
907
+ assert_eq ! ( range_to_offset_size( .., whole) , ( 0 , bs( whole) ) ) ;
908
+ assert_eq ! ( range_to_offset_size( 21 .., whole) , ( 21 , bs( whole - 21 ) ) ) ;
909
+ assert_eq ! ( range_to_offset_size( 0 .., whole) , ( 0 , bs( whole) ) ) ;
910
+ assert_eq ! ( range_to_offset_size( ..21 , whole) , ( 0 , bs( 21 ) ) ) ;
929
911
}
930
912
931
913
#[ test]
932
- #[ should_panic]
914
+ #[ should_panic = "buffer slices can not be empty" ]
933
915
fn range_to_offset_size_panics_for_empty_range ( ) {
934
- range_to_offset_size ( 123 ..123 ) ;
916
+ range_to_offset_size ( 123 ..123 , 200 ) ;
935
917
}
936
918
937
919
#[ test]
938
- #[ should_panic]
920
+ #[ should_panic = "buffer slices can not be empty" ]
939
921
fn range_to_offset_size_panics_for_unbounded_empty_range ( ) {
940
- range_to_offset_size ( ..0 ) ;
941
- }
942
-
943
- #[ test]
944
- #[ should_panic]
945
- fn check_buffer_bounds_panics_for_offset_at_size ( ) {
946
- check_buffer_bounds ( 100 , 100 , None ) ;
922
+ range_to_offset_size ( ..0 , 100 ) ;
947
923
}
948
924
949
925
#[ test]
950
926
fn check_buffer_bounds_works_for_end_in_range ( ) {
951
- check_buffer_bounds ( 200 , 100 , BufferSize :: new ( 50 ) ) ;
952
- check_buffer_bounds ( 200 , 100 , BufferSize :: new ( 100 ) ) ;
953
- check_buffer_bounds ( u64:: MAX , u64:: MAX - 100 , BufferSize :: new ( 100 ) ) ;
954
- check_buffer_bounds ( u64:: MAX , 0 , BufferSize :: new ( u64:: MAX ) ) ;
955
- check_buffer_bounds ( u64:: MAX , 1 , BufferSize :: new ( u64:: MAX - 1 ) ) ;
927
+ check_buffer_bounds ( 200 , 100 , bs ( 50 ) ) ;
928
+ check_buffer_bounds ( 200 , 100 , bs ( 100 ) ) ;
929
+ check_buffer_bounds ( u64:: MAX , u64:: MAX - 100 , bs ( 100 ) ) ;
930
+ check_buffer_bounds ( u64:: MAX , 0 , bs ( u64:: MAX ) ) ;
931
+ check_buffer_bounds ( u64:: MAX , 1 , bs ( u64:: MAX - 1 ) ) ;
956
932
}
957
933
958
934
#[ test]
959
935
#[ should_panic]
960
936
fn check_buffer_bounds_panics_for_end_over_size ( ) {
961
- check_buffer_bounds ( 200 , 100 , BufferSize :: new ( 101 ) ) ;
937
+ check_buffer_bounds ( 200 , 100 , bs ( 101 ) ) ;
962
938
}
963
939
964
940
#[ test]
965
941
#[ should_panic]
966
942
fn check_buffer_bounds_panics_for_end_wraparound ( ) {
967
- check_buffer_bounds ( u64:: MAX , 1 , BufferSize :: new ( u64:: MAX ) ) ;
943
+ check_buffer_bounds ( u64:: MAX , 1 , bs ( u64:: MAX ) ) ;
968
944
}
969
945
}
0 commit comments