Skip to content

Commit 40a1952

Browse files
committed
work with tree borrows
credit: ferrilab#266
1 parent 0ec9182 commit 40a1952

4 files changed

Lines changed: 67 additions & 85 deletions

File tree

src/ptr/span.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,17 @@ where
243243
/// [`::new`]: Self::new
244244
#[cfg(feature = "alloc")]
245245
pub(crate) unsafe fn set_address(&mut self, addr: Address<M, T>) {
246-
let mut addr_value = addr.to_const() as usize;
247-
addr_value &= Self::PTR_ADDR_MASK;
248-
addr_value |= self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK;
249-
self.ptr = NonNull::new_unchecked(addr_value as *mut ())
246+
self.ptr = NonNull::new_unchecked(
247+
addr.to_const()
248+
.map_addr(|mut addr_value| {
249+
addr_value &= Self::PTR_ADDR_MASK;
250+
addr_value |=
251+
self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK;
252+
addr_value
253+
})
254+
.cast::<()>()
255+
.cast_mut(),
256+
)
250257
}
251258

252259
/// Gets the starting bit index of the referent region.
@@ -283,11 +290,12 @@ where
283290
#[cfg(feature = "alloc")]
284291
pub(crate) unsafe fn set_head(&mut self, head: BitIdx<T::Mem>) {
285292
let head = head.into_inner() as usize;
286-
let mut ptr = self.ptr.as_ptr() as usize;
287-
288-
ptr &= Self::PTR_ADDR_MASK;
289-
ptr |= head >> Self::LEN_HEAD_BITS;
290-
self.ptr = NonNull::new_unchecked(ptr as *mut ());
293+
self.ptr =
294+
NonNull::new_unchecked(self.ptr.as_ptr().map_addr(|mut ptr| {
295+
ptr &= Self::PTR_ADDR_MASK;
296+
ptr |= head >> Self::LEN_HEAD_BITS;
297+
ptr
298+
}));
291299

292300
self.len &= !Self::LEN_HEAD_MASK;
293301
self.len |= head & Self::LEN_HEAD_MASK;

src/ptr/tests.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@ use core::cmp;
77
use crate::{
88
index::BitIdx,
99
prelude::*,
10-
ptr::{
11-
self as bv_ptr,
12-
AddressExt,
13-
BitSpan,
14-
BitSpanError,
15-
Mut,
16-
},
10+
ptr::{self as bv_ptr, AddressExt, BitSpan, BitSpanError, Mut},
1711
};
1812

1913
#[test]
@@ -23,13 +17,15 @@ fn free_functions() {
2317

2418
let one = BitPtr::<Mut, u8, Lsb0>::from_slice_mut(&mut a[..]);
2519
let two = one.wrapping_add(8);
26-
let three = BitPtr::<Mut, u16, Msb0>::from_mut(&mut b);
27-
let four = three.wrapping_add(8);
2820

2921
unsafe {
3022
bv_ptr::copy(two.to_const(), one, 8);
3123
}
3224
assert_eq!(a[0], !0);
25+
26+
let one = BitPtr::<Mut, u8, Lsb0>::from_slice_mut(&mut a);
27+
let three = BitPtr::<Mut, u16, Msb0>::from_mut(&mut b);
28+
3329
unsafe {
3430
bv_ptr::copy(three.to_const(), one, 8);
3531
}
@@ -43,6 +39,9 @@ fn free_functions() {
4339
assert_eq!(a[1], 0);
4440
assert_eq!(b, !0);
4541

42+
let three = BitPtr::<Mut, u16, Msb0>::from_mut(&mut b);
43+
let four = three.wrapping_add(8);
44+
4645
unsafe {
4746
bv_ptr::write_bits(four, false, 8);
4847
}

src/slice.rs

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,26 @@
22

33
#[cfg(feature = "alloc")]
44
use alloc::vec::Vec;
5-
use core::{
6-
marker::PhantomData,
7-
ops::RangeBounds,
8-
};
5+
use core::{marker::PhantomData, ops::RangeBounds};
6+
use std::cell::UnsafeCell;
97

108
use funty::Integral;
119
use tap::Pipe;
1210
#[cfg(feature = "alloc")]
1311
use tap::Tap;
1412
use wyz::{
1513
bidi::BidiIterator,
16-
comu::{
17-
Const,
18-
Mut,
19-
},
14+
comu::{Const, Mut},
2015
range::RangeExt,
2116
};
2217

2318
#[cfg(feature = "alloc")]
2419
use crate::vec::BitVec;
2520
use crate::{
26-
domain::{
27-
BitDomain,
28-
Domain,
29-
},
21+
domain::{BitDomain, Domain},
3022
mem,
31-
order::{
32-
BitOrder,
33-
Lsb0,
34-
Msb0,
35-
},
36-
ptr::{
37-
self as bv_ptr,
38-
BitPtr,
39-
BitPtrRange,
40-
BitSpan,
41-
BitSpanError,
42-
},
23+
order::{BitOrder, Lsb0, Msb0},
24+
ptr::{self as bv_ptr, BitPtr, BitPtrRange, BitSpan, BitSpanError},
4325
store::BitStore,
4426
};
4527

@@ -50,10 +32,7 @@ mod specialization;
5032
mod tests;
5133
mod traits;
5234

53-
pub use self::{
54-
api::*,
55-
iter::*,
56-
};
35+
pub use self::{api::*, iter::*};
5736

5837
#[repr(transparent)]
5938
#[doc = include_str!("../doc/slice/BitSlice.md")]
@@ -82,7 +61,7 @@ where
8261
///
8362
/// See `ptr::span` for more information on the encoding scheme used in
8463
/// references to `BitSlice`.
85-
_mem: [()],
64+
_mem: [UnsafeCell<()>],
8665
}
8766

8867
/// Constructors.
@@ -289,8 +268,7 @@ where
289268
elts.saturating_mul(mem::bits_of::<T::Mem>())
290269
.pipe(BitSpanError::TooLong)
291270
.pipe(Err)
292-
}
293-
else {
271+
} else {
294272
Ok(unsafe { Self::from_slice_unchecked(slice) })
295273
}
296274
}
@@ -378,8 +356,7 @@ where
378356
elts.saturating_mul(mem::bits_of::<T::Mem>())
379357
.pipe(BitSpanError::TooLong)
380358
.pipe(Err)
381-
}
382-
else {
359+
} else {
383360
Ok(unsafe { Self::from_slice_unchecked_mut(slice) })
384361
}
385362
}
@@ -805,7 +782,7 @@ where
805782
/// ```
806783
#[inline]
807784
pub fn replace(&mut self, index: usize, value: bool) -> bool {
808-
self.assert_in_bounds(index, 0 .. self.len());
785+
self.assert_in_bounds(index, 0..self.len());
809786
unsafe { self.replace_unchecked(index, value) }
810787
}
811788

@@ -948,7 +925,9 @@ where
948925
/// ```
949926
#[inline]
950927
pub unsafe fn copy_within_unchecked<R>(&mut self, src: R, dest: usize)
951-
where R: RangeExt<usize> {
928+
where
929+
R: RangeExt<usize>,
930+
{
952931
if let Some(this) = self.coerce_mut::<T, Lsb0>() {
953932
return this.sp_copy_within_unchecked(src, dest);
954933
}
@@ -958,7 +937,7 @@ where
958937
let source = src.normalize(0, self.len());
959938
let source_len = source.len();
960939
let rev = source.contains(&dest);
961-
let dest = dest .. dest + source_len;
940+
let dest = dest..dest + source_len;
962941
for (from, to) in self
963942
.get_unchecked(source)
964943
.as_bitptr_range()
@@ -1490,8 +1469,8 @@ where
14901469
);
14911470

14921471
unsafe {
1493-
self.copy_within_unchecked(by .., 0);
1494-
self.get_unchecked_mut(len - by ..).fill(false);
1472+
self.copy_within_unchecked(by.., 0);
1473+
self.get_unchecked_mut(len - by..).fill(false);
14951474
}
14961475
}
14971476

@@ -1556,8 +1535,8 @@ where
15561535
);
15571536

15581537
unsafe {
1559-
self.copy_within_unchecked(.. len - by, by);
1560-
self.get_unchecked_mut(.. by).fill(false);
1538+
self.copy_within_unchecked(..len - by, by);
1539+
self.get_unchecked_mut(..by).fill(false);
15611540
}
15621541
}
15631542

@@ -1598,7 +1577,9 @@ where
15981577
///
15991578
/// This panics if `bounds` is outside `index`.
16001579
pub(crate) fn assert_in_bounds<R>(&self, index: usize, bounds: R)
1601-
where R: RangeExt<usize> {
1580+
where
1581+
R: RangeExt<usize>,
1582+
{
16021583
let bounds = bounds.normalize(0, self.len());
16031584
assert!(
16041585
bounds.contains(&index),
@@ -1690,7 +1671,7 @@ where
16901671
/// [`.set()`]: Self::set
16911672
#[inline]
16921673
pub fn set_aliased(&self, index: usize, value: bool) {
1693-
self.assert_in_bounds(index, 0 .. self.len());
1674+
self.assert_in_bounds(index, 0..self.len());
16941675
unsafe {
16951676
self.set_aliased_unchecked(index, value);
16961677
}

src/slice/traits.rs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,13 @@ use core::{
66
cmp,
77
convert::TryFrom,
88
fmt::{
9-
self,
10-
Binary,
11-
Debug,
12-
Display,
13-
Formatter,
14-
LowerHex,
15-
Octal,
16-
Pointer,
9+
self, Binary, Debug, Display, Formatter, LowerHex, Octal, Pointer,
1710
UpperHex,
1811
},
19-
hash::{
20-
Hash,
21-
Hasher,
22-
},
12+
hash::{Hash, Hasher},
2313
str,
2414
};
15+
use std::panic::RefUnwindSafe;
2516

2617
use wyz::fmt::FmtForward;
2718

@@ -31,11 +22,7 @@ use crate::vec::BitVec;
3122
use crate::{
3223
domain::Domain,
3324
mem,
34-
order::{
35-
BitOrder,
36-
Lsb0,
37-
Msb0,
38-
},
25+
order::{BitOrder, Lsb0, Msb0},
3926
store::BitStore,
4027
view::BitView,
4128
};
@@ -107,13 +94,11 @@ where
10794
(self.coerce::<T1, Lsb0>(), rhs.coerce::<T1, Lsb0>())
10895
{
10996
this.sp_eq(that)
110-
}
111-
else if let (Some(this), Some(that)) =
97+
} else if let (Some(this), Some(that)) =
11298
(self.coerce::<T1, Msb0>(), rhs.coerce::<T1, Msb0>())
11399
{
114100
this.sp_eq(that)
115-
}
116-
else {
101+
} else {
117102
self.len() == rhs.len()
118103
&& self
119104
.iter()
@@ -410,8 +395,8 @@ where
410395
val |= bit as u8;
411396
}
412397
match val {
413-
v @ 0 ..= 9 => b'0' + v,
414-
v @ 10 ..= 35 => alpha - 10 + v,
398+
v @ 0..=9 => b'0' + v,
399+
v @ 10..=35 => alpha - 10 + v,
415400
_ => unreachable!(
416401
"bit-slices wider than five bits cannot be rendered to ASCII b36"
417402
),
@@ -450,7 +435,7 @@ where
450435
*slot = bits_to_ascii(chunk, alpha);
451436
skip += 1;
452437
}
453-
unsafe { str::from_utf8_unchecked(&into[.. skip]) }
438+
unsafe { str::from_utf8_unchecked(&into[..skip]) }
454439
}
455440

456441
/// Constructs the numeric formatting implementations.
@@ -536,11 +521,20 @@ where
536521
{
537522
#[inline]
538523
fn hash<H>(&self, hasher: &mut H)
539-
where H: Hasher {
524+
where
525+
H: Hasher,
526+
{
540527
self.iter().by_vals().for_each(|bit| bit.hash(hasher));
541528
}
542529
}
543530

531+
impl<T, O> RefUnwindSafe for BitSlice<T, O>
532+
where
533+
T: BitStore + RefUnwindSafe,
534+
O: BitOrder,
535+
{
536+
}
537+
544538
#[doc = include_str!("../../doc/slice/threadsafe.md")]
545539
unsafe impl<T, O> Send for BitSlice<T, O>
546540
where

0 commit comments

Comments
 (0)