Skip to content

Commit

Permalink
feat(core): use ~const in supertraits
Browse files Browse the repository at this point in the history
`[ref:const_supertraits]` has been resolved by [rust-lang/rust#93429][1].

[1]: rust-lang/rust#93429
  • Loading branch information
yvt committed Aug 13, 2022
1 parent c4cfc44 commit afc66ce
Show file tree
Hide file tree
Showing 88 changed files with 108 additions and 231 deletions.
16 changes: 0 additions & 16 deletions doc/toolchain_limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,6 @@ const fn clone_projection<T: ~const Trait>(p: &T::Proj) -> T::Proj {
```


### `[tag:const_supertraits]` Supertraits can't have `~const`

*Upstream PR:* [rust-lang/rust#93429](https://github.com/rust-lang/rust/pull/93429) might resolve this

```rust
#![feature(const_trait_impl)]
trait Trait: Clone {}
```

```rust,compile_fail
#![feature(const_trait_impl)]
// error: `~const` is not allowed here
trait Trait: ~const Clone {}
```


### `[tag:impl_block_const_bounds]` The trait bounds of an `impl` block can't include `~const`

```rust,compile_fail
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_wio_terminal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ mod queue {
impl<System: SupportedSystem, T: Init + Copy + Send + 'static> Queue<System, T> {
pub const fn new<C>(cfg: &mut Cfg<C>) -> Self
where
C: ~const traits::CfgBase<System = System> + ~const traits::CfgMutex,
C: ~const traits::CfgMutex<System = System>,
{
Self {
st: StaticMutex::define()
Expand Down
14 changes: 5 additions & 9 deletions src/r3/src/bind/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
/// # type Objects = ();
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgBase<System = System> +
/// ~const traits::CfgTask +
/// C: ~const traits::CfgTask<System = System> +
/// ~const traits::CfgTimer,
/// {
/// // Create a binding and give the timer an exclusive access
Expand Down Expand Up @@ -97,8 +96,7 @@
/// # type Objects = ();
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgBase<System = System> +
/// ~const traits::CfgTask +
/// C: ~const traits::CfgTask<System = System> +
/// ~const traits::CfgTimer,
/// {
/// let count = bind((), || 0).finish(cfg);
Expand All @@ -119,7 +117,7 @@
/// ```
)]
#![doc = include_str!("../common.md")]
use r3_core::kernel::{cfg, raw_cfg};
use r3_core::kernel::cfg;

pub use r3_core::bind::{
fn_bind_map, Bind, BindBorrow, BindBorrowMut, BindDefiner, BindRef, BindTable, BindTake,
Expand Down Expand Up @@ -196,8 +194,7 @@ pub const fn bind_uninit<'pool, T, C>(
) -> Bind<'pool, C::System, core::mem::MaybeUninit<T>>
where
T: 'static,
// `~const CfgBase` not implied due to [ref:const_supertraits]
C: ~const raw_cfg::CfgBase + ~const cfg::CfgStatic,
C: ~const cfg::CfgStatic,
{
// Safety: `MaybeUninit` is safe to leave uninitialized
unsafe { Bind::define().uninit_unchecked().finish(cfg) }
Expand Down Expand Up @@ -234,8 +231,7 @@ where
pub const fn bind_default<'pool, T, C>(cfg: &mut cfg::Cfg<'pool, C>) -> Bind<'pool, C::System, T>
where
T: Default + 'static,
// `~const CfgBase` not implied due to [ref:const_supertraits]
C: ~const raw_cfg::CfgBase + ~const cfg::CfgStatic,
C: ~const cfg::CfgStatic,
{
Bind::define().init(Default::default).finish(cfg)
}
7 changes: 2 additions & 5 deletions src/r3/src/sync/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ pub struct GenericMutex<Cell, Mutex> {
///
/// const fn configure_app<C>(cfg: &mut Cfg<C>) -> Objects
/// where
/// C: ~const traits::CfgBase<System = System> +
/// ~const traits::CfgTask +
/// C: ~const traits::CfgTask<System = System> +
/// ~const traits::CfgMutex,
/// {
/// StaticTask::define()
Expand Down Expand Up @@ -272,9 +271,7 @@ where
System: traits::KernelMutex + traits::KernelStatic,
{
/// Complete the definition of a mutex, returning a reference to the mutex.
// `CfgMutex` can't have `~const CfgBase` as a supertrait because of
// [ref:const_supertraits], hence we need to specify `~const CfgBase` here
pub const fn finish<C: ~const traits::CfgMutex<System = System> + ~const traits::CfgBase>(
pub const fn finish<C: ~const traits::CfgMutex<System = System>>(
self,
cfg: &mut Cfg<C>,
) -> StaticMutex<System, Source::Target>
Expand Down
7 changes: 2 additions & 5 deletions src/r3/src/sync/recursive_mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ pub struct GenericRecursiveMutex<Cell, Mutex> {
///
/// const fn configure_app<C>(cfg: &mut Cfg<C>) -> Objects
/// where
/// C: ~const traits::CfgBase<System = System> +
/// ~const traits::CfgTask +
/// C: ~const traits::CfgTask<System = System> +
/// ~const traits::CfgMutex,
/// {
/// StaticTask::define()
Expand Down Expand Up @@ -310,9 +309,7 @@ where
System: traits::KernelMutex + traits::KernelStatic,
{
/// Complete the definition of a mutex, returning a reference to the mutex.
// `CfgMutex` can't have `~const CfgBase` as a supertrait because of
// [ref:const_supertraits], hence we need to specify `~const CfgBase` here
pub const fn finish<C: ~const traits::CfgMutex<System = System> + ~const traits::CfgBase, T>(
pub const fn finish<C: ~const traits::CfgMutex<System = System>, T>(
self,
cfg: &mut Cfg<C>,
) -> StaticRecursiveMutex<System, T>
Expand Down
1 change: 1 addition & 0 deletions src/r3_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added

- The new blanket-implemented `CfgStatic` trait can be used to simplify some trait bounds of configuration functions.
- The `Cfg*` traits now include `~const` in their supertraits ([rust-lang/rust#93429](https://github.com/rust-lang/rust/pull/93429)), making `~const CfgBase` trait bound unnecessary if it's implied by others.

### Fixed

Expand Down
6 changes: 2 additions & 4 deletions src/r3_core/src/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,8 +686,7 @@ impl<'pool, System, T> DivideBind<'pool, System, T> {
///
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
// `~const CfgBase` not implied due to [ref:const_supertraits]
/// C: ~const traits::CfgBase + ~const traits::CfgStatic,
/// C: ~const traits::CfgStatic,
/// {
/// let values = Bind::define().init(|| (12, 34)).finish(cfg);
/// let (value0, value1) = values.unzip();
Expand Down Expand Up @@ -818,8 +817,7 @@ impl<'pool, const LEN: usize, System, T> const UnzipBind for Bind<'pool, System,
///
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgBase +
/// ~const traits::CfgTask,
/// C: ~const traits::CfgTask,
/// C::System: traits::KernelStatic,
/// {
/// let foo = Bind::define().init(|| {
Expand Down
10 changes: 4 additions & 6 deletions src/r3_core/src/bind/sorter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
// restricted to "comptime" anymore
use core::{
marker::Destruct,
ops::{Deref, DerefMut, Index, IndexMut},
ops::{Index, IndexMut},
};

use super::{BindBorrowType, BindUsage};
Expand Down Expand Up @@ -149,8 +149,8 @@ pub(super) const fn sort_bindings<Callback, SorterUseInfoList, VertexList>(
temp_vertices: &mut VertexList,
) where
Callback: ~const SorterCallback,
SorterUseInfoList: ~const VecLike<Element = SorterUseInfo> + ~const Deref + ~const DerefMut,
VertexList: ~const VecLike<Element = Vertex> + ~const Deref + ~const DerefMut,
SorterUseInfoList: ~const VecLike<Element = SorterUseInfo>,
VertexList: ~const VecLike<Element = Vertex>,
{
// Preconditions
let num_binds = cb.num_binds();
Expand Down Expand Up @@ -605,9 +605,7 @@ where
Graph::SuccessorIter<'a>: ~const MyIterator + ~const Destruct,
VertexRef: Copy,
VertexRefLessThan: ~const FnMut(&VertexRef, &VertexRef) -> bool,
// `~const Deref[Mut]` isn't implied because of
// [ref:veclike_const_supertrait]
ReadyVertexQueue: ~const VecLike<Element = VertexRef> + ~const Deref + ~const DerefMut,
ReadyVertexQueue: ~const VecLike<Element = VertexRef>,
for<'index> VertexInfoMap: ~const Index<&'index VertexRef, Output = TopologicalSortVertexInfo>
+ ~const IndexMut<&'index VertexRef>,
OutputSink: ~const TopologicalSortOutputSink<VertexRef>,
Expand Down
6 changes: 2 additions & 4 deletions src/r3_core/src/kernel/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,7 @@ macro array_item_from_fn($(
/// #
/// const fn configure<C>(cfg: &mut C)
/// where
// `~const CfgBase` not implied due to [ref:const_supertraits]
/// C: ~const traits::CfgBase + ~const traits::CfgStatic,
/// C: ~const traits::CfgStatic,
/// {
/// todo!()
/// }
Expand All @@ -764,8 +763,7 @@ macro array_item_from_fn($(
/// todo!()
/// }
/// ```
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub trait CfgStatic: raw_cfg::CfgBase<System: KernelStatic> {}
pub trait CfgStatic: ~const raw_cfg::CfgBase<System: KernelStatic> {}

impl<C> const CfgStatic for C
where
Expand Down
18 changes: 6 additions & 12 deletions src/r3_core/src/kernel/raw_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ pub unsafe trait CfgBase {
/// [2]: crate::kernel::cfg::KernelStatic
/// [3]: self#stability
/// [4]: self#safety
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub unsafe trait CfgTask: CfgBase {
pub unsafe trait CfgTask: ~const CfgBase {
fn task_define<Properties: ~const Bag>(
&mut self,
descriptor: TaskDescriptor<Self::System>,
Expand Down Expand Up @@ -115,8 +114,7 @@ pub struct TaskDescriptor<System> {
/// [2]: crate::kernel::cfg::KernelStatic
/// [3]: self#stability
/// [4]: self#safety
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub unsafe trait CfgEventGroup: CfgBase<System: raw::KernelEventGroup> {
pub unsafe trait CfgEventGroup: ~const CfgBase<System: raw::KernelEventGroup> {
fn event_group_define<Properties: ~const Bag>(
&mut self,
descriptor: EventGroupDescriptor<Self::System>,
Expand Down Expand Up @@ -147,8 +145,7 @@ pub struct EventGroupDescriptor<System> {
/// [2]: crate::kernel::cfg::KernelStatic
/// [3]: self#stability
/// [4]: self#safety
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub unsafe trait CfgMutex: CfgBase<System: raw::KernelMutex> {
pub unsafe trait CfgMutex: ~const CfgBase<System: raw::KernelMutex> {
fn mutex_define<Properties: ~const Bag>(
&mut self,
descriptor: MutexDescriptor<Self::System>,
Expand Down Expand Up @@ -178,8 +175,7 @@ pub struct MutexDescriptor<System> {
/// [2]: crate::kernel::cfg::KernelStatic
/// [3]: self#stability
/// [4]: self#safety
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub unsafe trait CfgSemaphore: CfgBase<System: raw::KernelSemaphore> {
pub unsafe trait CfgSemaphore: ~const CfgBase<System: raw::KernelSemaphore> {
fn semaphore_define<Properties: ~const Bag>(
&mut self,
descriptor: SemaphoreDescriptor<Self::System>,
Expand Down Expand Up @@ -211,8 +207,7 @@ pub struct SemaphoreDescriptor<System> {
/// [2]: crate::kernel::cfg::KernelStatic
/// [3]: self#stability
/// [4]: self#safety
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub unsafe trait CfgTimer: CfgBase<System: raw::KernelTimer> {
pub unsafe trait CfgTimer: ~const CfgBase<System: raw::KernelTimer> {
fn timer_define<Properties: ~const Bag>(
&mut self,
descriptor: TimerDescriptor<Self::System>,
Expand Down Expand Up @@ -245,8 +240,7 @@ pub struct TimerDescriptor<System> {
/// [2]: crate::kernel::cfg::KernelStatic
/// [3]: self#stability
/// [4]: self#safety
// The supertrait can't be `~const` due to [ref:const_supertraits]
pub unsafe trait CfgInterruptLine: CfgBase<System: raw::KernelInterruptLine> {
pub unsafe trait CfgInterruptLine: ~const CfgBase<System: raw::KernelInterruptLine> {
fn interrupt_line_define<Properties: ~const Bag>(
&mut self,
descriptor: InterruptLineDescriptor<Self::System>,
Expand Down
8 changes: 4 additions & 4 deletions src/r3_core/src/lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ const COTTAGE: Objects = r3_kernel::build!(SystemTraits, configure_app => Object
// This is the top-level configuration function
const fn configure_app<C>(b: &mut Cfg<C>) -> Objects
where
C: ~const traits::CfgBase<System = System>
+ ~const traits::CfgTask,
// `C: ~const CfgBase` is implied by `CfgTask`'s supertrait
C: ~const traits::CfgTask<System = System>,
{
b.num_task_priority_levels(4);
let task = StaticTask::define()
Expand Down Expand Up @@ -110,7 +110,7 @@ Configuration functions are highly composable as they can make nested calls to o
// Top-level configuration function
const fn configure_app<C>(b: &mut Cfg<C>) -> Objects<C::System>
where
C: ~const traits::CfgBase + ~const traits::CfgTask,
C: ~const traits::CfgTask,
{
b.num_task_priority_levels(4);
let my_module = m::configure(b);
Expand All @@ -122,7 +122,7 @@ mod m {
# pub struct MyModule<System: traits::KernelBase> { task: StaticTask<System> }
pub const fn configure<C>(b: &mut Cfg<C>) -> MyModule<C::System>
where
C: ~const traits::CfgBase + ~const traits::CfgTask,
C: ~const traits::CfgTask,
{
let task = StaticTask::define()
.start(task_body).priority(3).active(true).finish(b);
Expand Down
4 changes: 1 addition & 3 deletions src/r3_core/src/utils/binary_heap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ pub trait BinaryHeap: VecLike {

impl<T> const BinaryHeap for T
where
// `~const Deref` isn't implied because of
// [ref:veclike_const_supertrait]
T: ~const VecLike + ~const core::ops::Deref + ~const core::ops::DerefMut,
T: ~const VecLike,
T::Element: ~const Destruct,
{
fn heap_pop<Ctx>(&mut self, ctx: Ctx) -> Option<Self::Element>
Expand Down
6 changes: 3 additions & 3 deletions src/r3_core/src/utils/binary_heap/veclike.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use arrayvec::ArrayVec;
use core::ops;

// [tag:veclike_const_supertrait] Can't specify `~const Deref` due to
// [ref:const_supertraits]
pub trait VecLike: ops::Deref<Target = [<Self as VecLike>::Element]> + ops::DerefMut {
pub trait VecLike:
~const ops::Deref<Target = [<Self as VecLike>::Element]> + ~const ops::DerefMut
{
type Element;
fn is_empty(&self) -> bool;
fn len(&self) -> usize;
Expand Down
3 changes: 1 addition & 2 deletions src/r3_port_arm_m/src/systick_tickful/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ macro_rules! use_systick_tickful {
impl $Traits {
pub const fn configure_systick<C>(b: &mut Cfg<C>)
where
C: ~const traits::CfgBase<System = System<Self>>
+ ~const traits::CfgInterruptLine,
C: ~const traits::CfgInterruptLine<System = System<Self>>,
{
imp::configure(b);
}
Expand Down
2 changes: 1 addition & 1 deletion src/r3_port_arm_m/src/systick_tickful/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub unsafe trait SysTickTickfulInstance: KernelTraits + SysTickOptions {
/// The configuration function.
pub const fn configure<C, Traits: SysTickTickfulInstance>(b: &mut Cfg<C>)
where
C: ~const traits::CfgBase<System = System<Traits>> + ~const traits::CfgInterruptLine,
C: ~const traits::CfgInterruptLine<System = System<Traits>>,
{
InterruptLine::define()
.line(INTERRUPT_SYSTICK)
Expand Down
2 changes: 1 addition & 1 deletion src/r3_port_arm_m_test_driver/src/board_rp2040.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl log::Log for Logger {

pub const fn configure<C>(b: &mut Cfg<C>)
where
C: ~const traits::CfgBase + ~const traits::CfgInterruptLine,
C: ~const traits::CfgInterruptLine,
C::System: traits::KernelInterruptLine + traits::KernelStatic,
{
let (rp2040_resets, rp2040_usbctrl_regs) = bind((), || {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct App<System> {
impl<System: traits::KernelBase> App<System> {
pub const fn new<C, D: Driver<Self>>(b: &mut Cfg<C>) -> Self
where
C: ~const traits::CfgBase<System = System> + ~const traits::CfgTask,
C: ~const traits::CfgTask<System = System>,
{
StartupHook::define()
.start(startup_hook_body::<System, D>)
Expand Down
4 changes: 1 addition & 3 deletions src/r3_port_std/tests/kernel_tests/external_interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ pub struct App<System: traits::KernelBase + traits::KernelInterruptLine + traits
impl<Traits: SupportedSystemTraits> App<System<Traits>> {
pub const fn new<C, D: Driver<Self>>(b: &mut Cfg<C>) -> Self
where
C: ~const traits::CfgBase<System = System<Traits>>
+ ~const traits::CfgInterruptLine
+ ~const traits::CfgTask,
C: ~const traits::CfgTask<System = System<Traits>> + ~const traits::CfgInterruptLine,
{
StaticTask::define()
.start(task_body1::<Traits, D>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct App<System> {
impl<Traits: SupportedSystemTraits> App<System<Traits>> {
pub const fn new<C, D: Driver<Self>>(b: &mut Cfg<C>) -> Self
where
C: ~const traits::CfgBase<System = System<Traits>> + ~const traits::CfgInterruptLine,
C: ~const traits::CfgInterruptLine<System = System<Traits>>,
{
StartupHook::define()
.start(hook_body::<Traits, D>)
Expand Down
2 changes: 1 addition & 1 deletion src/r3_port_std/tests/kernel_tests/stack_align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct App<System> {
impl<Traits: SupportedSystemTraits> App<System<Traits>> {
pub const fn new<C, D: Driver<Self>>(b: &mut Cfg<C>) -> Self
where
C: ~const traits::CfgBase<System = System<Traits>> + ~const traits::CfgTask,
C: ~const traits::CfgTask<System = System<Traits>>,
{
StaticTask::define()
.start(task_body::<Traits, D>)
Expand Down
3 changes: 1 addition & 2 deletions src/r3_support_rp2040/src/usbstdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ pub const fn configure<'pool, C, TOptions: Options>(
rp2040_resets: Bind<'pool, C::System, rp2040_pac::RESETS>,
rp2040_usbctrl_regs: Bind<'pool, C::System, rp2040_pac::USBCTRL_REGS>,
) where
// `~const CfgBase` not implied due to [ref:const_supertraits]
C: ~const traits::CfgBase + ~const traits::CfgStatic + ~const traits::CfgInterruptLine,
C: ~const traits::CfgStatic + ~const traits::CfgInterruptLine,
{
bind(
(rp2040_resets.borrow_mut(), rp2040_usbctrl_regs.take()),
Expand Down
Loading

0 comments on commit afc66ce

Please sign in to comment.