Skip to content

Commit

Permalink
refactor: use #![feature(const_slice_index)]
Browse files Browse the repository at this point in the history
This feature, which covers the `const fn` version of `<[T]>::
get[_unchecked][_mut]`, was added by [rust-lang/rust#94657][1].

[1]: rust-lang/rust#94657
  • Loading branch information
yvt committed Mar 21, 2022
1 parent 630ba7e commit 79e4d28
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 85 deletions.
29 changes: 0 additions & 29 deletions doc/toolchain_limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,21 +376,6 @@ const fn f(_: usize) {}
```


### `[tag:const_slice_get]` `<[T]>::get` is not `const fn`

```rust
assert!(matches!(b"a".get(0), Some(b'a')));
assert!(matches!(b"a".get(1), None));
```

```rust,compile_fail,E0015
// `assert!` is used here due to [ref:const_assert_eq]
// `matches!` is used here due to [ref:option_const_partial_eq]
const _: () = assert!(matches!(b"a".get(0), Some(b'a')));
const _: () = assert!(matches!(b"a".get(1), None));
```


### `[tag:const_slice_sort_unstable]` `<[T]>::sort_unstable*` is not `const fn`

```rust
Expand Down Expand Up @@ -442,20 +427,6 @@ const _: () = { Ok::<(), ()>(()).map(identity); };
```


### `[tag:const_slice_get_unchecked]` `<[T]>::get_unchecked` is not `const fn`

```rust
assert!(unsafe { *b"a".get_unchecked(0) } == b'a');
```

```rust,compile_fail,E0015
// `assert!` is used here due to [ref:const_assert_eq]
// error[E0015]: cannot call non-const fn `core::slice::<impl [u8]>::
// get_unchecked::<usize>` in constants
const _: () = assert!(unsafe { *b"a".get_unchecked(0) } == b'a');
```


### `[tag:const_slice_iter]` `<[T]>::iter` is not `const fn`

```rust
Expand Down
14 changes: 6 additions & 8 deletions src/r3_core/src/bind/sorter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,17 +378,16 @@ pub(super) const fn sort_bindings<Callback, SorterUseInfoList, VertexList>(
SuccessorIterState::BindInitToBorrowingUser(bind_i, bind_user_i) => {
let cb = self.cb.borrow();
let bind_users = cb.bind_users(bind_i);
// `[T]::get` is not `const fn` yet [ref:const_slice_get]
if bind_user_i < bind_users.len() {
if let Some(bind_user) = bind_users.get(bind_user_i) {
self.st = SuccessorIterState::BindInitToBorrowingUser(
bind_i,
bind_user_i + 1,
);
if matches!(
bind_users[bind_user_i].1,
bind_user.1,
BindBorrowType::Borrow | BindBorrowType::BorrowMut
) {
return Some(match bind_users[bind_user_i].0 {
return Some(match bind_user.0 {
BindUsage::Executable => Vertex::Executable,
BindUsage::Bind(user_bind_i) => Vertex::BindInit(user_bind_i),
});
Expand Down Expand Up @@ -434,17 +433,16 @@ pub(super) const fn sort_bindings<Callback, SorterUseInfoList, VertexList>(
SuccessorIterState::BindDisownToTakingUser(bind_i, bind_user_i) => {
let cb = self.cb.borrow();
let bind_users = cb.bind_users(bind_i);
// `[T]::get` is not `const fn` yet [ref:const_slice_get]
if bind_user_i < bind_users.len() {
if let Some(bind_user) = bind_users.get(bind_user_i) {
self.st =
SuccessorIterState::BindDisownToTakingUser(bind_i, bind_user_i + 1);
if matches!(
bind_users[bind_user_i].1,
bind_user.1,
BindBorrowType::Take
| BindBorrowType::TakeRef
| BindBorrowType::TakeMut
) {
return Some(match bind_users[bind_user_i].0 {
return Some(match bind_user.0 {
BindUsage::Executable => Vertex::Executable,
BindUsage::Bind(user_bind_i) => Vertex::BindInit(user_bind_i),
});
Expand Down
10 changes: 4 additions & 6 deletions src/r3_core/src/kernel/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,10 @@ impl<'c, C: raw_cfg::CfgBase> Cfg<'c, C> {
let mut i = 0;
while i < self.interrupt_lines.len() {
let interrupt_line = &self.interrupt_lines[i];
// `<[T]>::get` is not `const fn` yet [ref:const_slice_get]
let start = if interrupt_line.num < C::System::CFG_INTERRUPT_HANDLERS.len() {
C::System::CFG_INTERRUPT_HANDLERS[interrupt_line.num]
} else {
None
};
let start = C::System::CFG_INTERRUPT_HANDLERS
.get(interrupt_line.num)
.copied()
.flatten();
self.raw.interrupt_line_define(
raw_cfg::InterruptLineDescriptor {
phantom: Init::INIT,
Expand Down
1 change: 1 addition & 0 deletions src/r3_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#![feature(maybe_uninit_slice)]
#![feature(const_nonnull_new)]
#![feature(const_result_drop)]
#![feature(const_slice_index)]
#![feature(const_option_ext)]
#![feature(const_ptr_offset)]
#![feature(const_trait_impl)]
Expand Down
42 changes: 6 additions & 36 deletions src/r3_core/src/utils/binary_heap/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<'a, T> Hole<'a, T> {
pub(super) const unsafe fn new(data: &'a mut [T], pos: usize) -> Self {
debug_assert!(pos < data.len());
// SAFE: pos should be inside the slice
let elt = unsafe { ptr::read(data.get_unchecked2(pos)) };
let elt = unsafe { ptr::read(data.get_unchecked(pos)) };
Hole {
data,
elt: ManuallyDrop::new(elt),
Expand Down Expand Up @@ -52,7 +52,7 @@ impl<'a, T> Hole<'a, T> {
pub(super) const unsafe fn get(&self, index: usize) -> &T {
debug_assert!(index != self.pos);
debug_assert!(index < self.data.len());
unsafe { self.data.get_unchecked2(index) }
unsafe { self.data.get_unchecked(index) }
}

/// Returns a mutable reference to the element at `index`.
Expand All @@ -62,7 +62,7 @@ impl<'a, T> Hole<'a, T> {
pub(super) const unsafe fn get_mut(&mut self, index: usize) -> &mut T {
debug_assert!(index != self.pos);
debug_assert!(index < self.data.len());
unsafe { self.data.get_unchecked_mut2(index) }
unsafe { self.data.get_unchecked_mut(index) }
}

/// Move hole to new location
Expand All @@ -73,8 +73,8 @@ impl<'a, T> Hole<'a, T> {
debug_assert!(index != self.pos);
debug_assert!(index < self.data.len());
unsafe {
let index_ptr: *const _ = self.data.get_unchecked2(index);
let hole_ptr = self.data.get_unchecked_mut2(self.pos);
let index_ptr: *const _ = self.data.get_unchecked(index);
let hole_ptr = self.data.get_unchecked_mut(self.pos);
ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1);
}
self.pos = index;
Expand All @@ -87,37 +87,7 @@ impl<T> const Drop for Hole<'_, T> {
// fill the hole again
unsafe {
let pos = self.pos;
ptr::copy_nonoverlapping(&*self.elt, self.data.get_unchecked_mut2(pos), 1);
ptr::copy_nonoverlapping(&*self.elt, self.data.get_unchecked_mut(pos), 1);
}
}
}

// `[T]::get_unchecked<usize>` is not `const fn` yet [ref:const_slice_get_unchecked]
trait GetUnchecked {
type Element;
unsafe fn get_unchecked2(&self, i: usize) -> &Self::Element;
}

impl<Element> const GetUnchecked for [Element] {
type Element = Element;

#[inline]
unsafe fn get_unchecked2(&self, i: usize) -> &Self::Element {
unsafe { &*self.as_ptr().add(i) }
}
}

// `[T]::get_unchecked_mut<usize>` is not `const fn` yet [ref:const_slice_get_unchecked]
trait GetUncheckedMut {
type Element;
unsafe fn get_unchecked_mut2(&mut self, i: usize) -> &mut Self::Element;
}

impl<Element> const GetUncheckedMut for [Element] {
type Element = Element;

#[inline]
unsafe fn get_unchecked_mut2(&mut self, i: usize) -> &mut Self::Element {
unsafe { &mut *self.as_mut_ptr().add(i) }
}
}
7 changes: 1 addition & 6 deletions src/r3_kernel/src/cfg/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,6 @@ impl InterruptHandlerTable {
/// specified interrupt number.
#[inline]
pub const fn get(&self, line: InterruptNum) -> Option<InterruptHandlerFn> {
// `<[T]>::get` is not `const fn` yet [ref:const_slice_get]
if line < self.storage.len() {
self.storage[line]
} else {
None
}
self.storage.get(line).copied().flatten()
}
}
1 change: 1 addition & 0 deletions src/r3_kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(generic_const_exprs)]
#![feature(const_refs_to_cell)]
#![feature(maybe_uninit_slice)]
#![feature(const_slice_index)]
#![feature(const_option_ext)]
#![feature(const_ptr_offset)]
#![feature(const_trait_impl)]
Expand Down

0 comments on commit 79e4d28

Please sign in to comment.