Skip to content

Commit b096f68

Browse files
committed
chore: update the target compiler version to nightly-2020-06-24
This commit includes work-arounds for the following changes in the compiler: - Raw pointers as const generic parameters are now forbidden. <rust-lang/rust#73398> This means the work-around for ICE caused by `&'static [_]` const generic parameters doesn't work anymore. An alternative work-around is yet to be implemented. - Mutable references are now forbidden in all constant contexts except for `const fn`s. <rust-lang/rust#72934> Working around this change was as easy as mechanically replacing `const` with `const fn` for most cases. The only tricky case was the definition of `id_map` inside `build!`, which is a macro meant to be called inside a `const` item. The type of `id_map` isn't explicitly specified but is rather implied by a given configuration function, so this couldn't be mechanically replaced with a `const` item. To resolve this problem, I added an explicit type to `build!`'s signature.
1 parent ff6165c commit b096f68

File tree

12 files changed

+94
-80
lines changed

12 files changed

+94
-80
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct Objects {
4040
task: Task<System>,
4141
}
4242

43-
const COTTAGE: Objects = constance::build!(System, configure_app);
43+
const COTTAGE: Objects = constance::build!(System, configure_app => Objects);
4444

4545
constance::configure! {
4646
const fn configure_app(_: &mut CfgBuilder<System>) -> Objects {

examples/basic/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct Objects {
1515
mutex1: Mutex<System, u32>,
1616
}
1717

18-
const COTTAGE: Objects = constance::build!(System, configure_app);
18+
const COTTAGE: Objects = constance::build!(System, configure_app => Objects);
1919

2020
constance::configure! {
2121
const fn configure_app(_: &mut CfgBuilder<System>) -> Objects {

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2020-06-06
1+
nightly-2020-06-24

src/constance/src/kernel/cfg.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ macro_rules! configure {
293293
/// [`KernelCfg2`]: crate::kernel::KernelCfg2
294294
#[macro_export]
295295
macro_rules! build {
296-
($sys:ty, $configure:expr) => {{
296+
($sys:ty, $configure:expr => $id_map_ty:ty) => {{
297297
use $crate::{
298298
kernel::{
299299
cfg::{
@@ -312,17 +312,28 @@ macro_rules! build {
312312
// `$configure` produces two values: a `CfgBuilder` and an ID map
313313
// (custom type). We need the first one to be `const` so that we can
314314
// calculate the values of generic parameters based on its contents.
315-
const CFG: CfgBuilderInner<$sys> = {
315+
const CFG: CfgBuilderInner<$sys> = get_cfg();
316+
317+
const fn get_cfg() -> CfgBuilderInner<$sys> {
318+
// FIXME: Unable to do this inside a `const` item because of
319+
// <https://github.com/rust-lang/rust/pull/72934>
320+
316321
// Safety: We are `build!`, so it's okay to use `CfgBuilder::new`
317322
let mut cfg = unsafe { CfgBuilder::new() };
318323
$configure(&mut cfg);
319324
cfg.finalize();
320325
cfg.into_inner()
321-
};
326+
}
322327

323328
// The second value can be just `let`
324329
// Safety: We are `build!`, so it's okay to use `CfgBuilder::new`
325-
let id_map = $configure(&mut unsafe { CfgBuilder::new() });
330+
const fn id_map() -> $id_map_ty {
331+
// FIXME: Unable to do this inside a `const` item because of
332+
// <https://github.com/rust-lang/rust/pull/72934>
333+
// This is also why `$id_map_ty` has to be given.
334+
335+
$configure(&mut unsafe { CfgBuilder::new() })
336+
}
326337

327338
// Set up task priority levels
328339
type TaskPriority = UIntegerWithBound<{ CFG.num_task_priority_levels as u128 - 1 }>;
@@ -382,7 +393,7 @@ macro_rules! build {
382393
$sys,
383394
U<NUM_INTERRUPT_LINES>,
384395
U<NUM_INTERRUPT_HANDLERS>,
385-
{ INTERRUPT_HANDLERS.as_ptr() },
396+
{ &INTERRUPT_HANDLERS },
386397
NUM_INTERRUPT_HANDLERS,
387398
NUM_INTERRUPT_LINES,
388399
>()
@@ -426,7 +437,7 @@ macro_rules! build {
426437
}
427438
}
428439

429-
id_map
440+
id_map()
430441
}};
431442
}
432443

src/constance/src/kernel/cfg/interrupt.rs

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -408,14 +408,14 @@ type ProtoCombinedHandlerFn = fn(interrupt::InterruptNum, bool);
408408
struct MakeProtoCombinedHandlers<
409409
System,
410410
NumHandlers,
411-
const HANDLERS: *const CfgBuilderInterruptHandler,
411+
const HANDLERS: &'static [CfgBuilderInterruptHandler],
412412
const NUM_HANDLERS: usize,
413413
>(PhantomData<(System, NumHandlers)>);
414414

415415
trait MakeProtoCombinedHandlersTrait {
416416
type System: Port;
417417
type NumHandlers: Nat;
418-
const HANDLERS: *const CfgBuilderInterruptHandler;
418+
const HANDLERS: &'static [CfgBuilderInterruptHandler];
419419
const NUM_HANDLERS: usize;
420420
const PROTO_COMBINED_HANDLERS: &'static [ProtoCombinedHandlerFn];
421421
const FIRST_PROTO_COMBINED_HANDLER: Option<ProtoCombinedHandlerFn>;
@@ -424,14 +424,14 @@ trait MakeProtoCombinedHandlersTrait {
424424
impl<
425425
System: Port,
426426
NumHandlers: Nat,
427-
const HANDLERS: *const CfgBuilderInterruptHandler,
427+
const HANDLERS: &'static [CfgBuilderInterruptHandler],
428428
const NUM_HANDLERS: usize,
429429
> MakeProtoCombinedHandlersTrait
430430
for MakeProtoCombinedHandlers<System, NumHandlers, HANDLERS, NUM_HANDLERS>
431431
{
432432
type System = System;
433433
type NumHandlers = NumHandlers;
434-
const HANDLERS: *const CfgBuilderInterruptHandler = HANDLERS;
434+
const HANDLERS: &'static [CfgBuilderInterruptHandler] = HANDLERS;
435435
const NUM_HANDLERS: usize = NUM_HANDLERS;
436436
const PROTO_COMBINED_HANDLERS: &'static [ProtoCombinedHandlerFn] =
437437
&Self::PROTO_COMBINED_HANDLERS_ARRAY;
@@ -445,68 +445,71 @@ impl<
445445
impl<
446446
System: Port,
447447
NumHandlers: Nat,
448-
const HANDLERS: *const CfgBuilderInterruptHandler,
448+
const HANDLERS: &'static [CfgBuilderInterruptHandler],
449449
const NUM_HANDLERS: usize,
450450
> MakeProtoCombinedHandlers<System, NumHandlers, HANDLERS, NUM_HANDLERS>
451451
{
452-
const PROTO_COMBINED_HANDLERS_ARRAY: [ProtoCombinedHandlerFn; NUM_HANDLERS] = const_array_from_fn! {
453-
fn iter<[T: MakeProtoCombinedHandlersTrait], I: Nat>(ref mut cell: T) -> ProtoCombinedHandlerFn {
454-
#[inline(always)]
455-
fn proto_combined_handler<T: MakeProtoCombinedHandlersTrait, I: Nat>(cur_line: interrupt::InterruptNum, mut should_unlock_cpu: bool) {
456-
// Safety: `I::N < NUM_HANDLERS`
457-
let handler = unsafe { &*T::HANDLERS.wrapping_add(I::N) };
458-
459-
if cur_line == handler.line {
460-
if should_unlock_cpu {
461-
// Relinquish CPU Lock before calling the next handler
462-
if T::System::is_cpu_lock_active() {
463-
// Safety: CPU Lock active, we have the ownership
464-
// of the current CPU Lock (because a previously
465-
// called handler left it active)
466-
unsafe { T::System::leave_cpu_lock() };
452+
const PROTO_COMBINED_HANDLERS_ARRAY: [ProtoCombinedHandlerFn; NUM_HANDLERS] =
453+
Self::proto_combined_handlers_array();
454+
455+
const fn proto_combined_handlers_array() -> [ProtoCombinedHandlerFn; NUM_HANDLERS] {
456+
// FIXME: Unable to do this inside a `const` item because of
457+
// <https://github.com/rust-lang/rust/pull/72934>
458+
const_array_from_fn! {
459+
fn iter<[T: MakeProtoCombinedHandlersTrait], I: Nat>(ref mut cell: T) -> ProtoCombinedHandlerFn {
460+
#[inline(always)]
461+
fn proto_combined_handler<T: MakeProtoCombinedHandlersTrait, I: Nat>(cur_line: interrupt::InterruptNum, mut should_unlock_cpu: bool) {
462+
let handler = T::HANDLERS[I::N];
463+
464+
if cur_line == handler.line {
465+
if should_unlock_cpu {
466+
// Relinquish CPU Lock before calling the next handler
467+
if T::System::is_cpu_lock_active() {
468+
// Safety: CPU Lock active, we have the ownership
469+
// of the current CPU Lock (because a previously
470+
// called handler left it active)
471+
unsafe { T::System::leave_cpu_lock() };
472+
}
467473
}
468-
}
469474

470-
(handler.start)(handler.param);
475+
(handler.start)(handler.param);
471476

472-
should_unlock_cpu = true;
473-
}
477+
should_unlock_cpu = true;
478+
}
474479

475-
// Call the next proto combined handler
476-
let i = I::N + 1;
477-
if i < T::NUM_HANDLERS {
478-
T::PROTO_COMBINED_HANDLERS[i](cur_line, should_unlock_cpu);
480+
// Call the next proto combined handler
481+
let i = I::N + 1;
482+
if i < T::NUM_HANDLERS {
483+
T::PROTO_COMBINED_HANDLERS[i](cur_line, should_unlock_cpu);
484+
}
479485
}
486+
proto_combined_handler::<T, I>
480487
}
481-
proto_combined_handler::<T, I>
482-
}
483488

484-
// `Self: MakeProtoCombinedHandlersTrait` is used as the context type
485-
// for the iteration
486-
(0..NUM_HANDLERS).map(|i| iter::<[Self], i>(Self(PhantomData))).collect::<[_; NumHandlers]>()
487-
};
489+
// `Self: MakeProtoCombinedHandlersTrait` is used as the context type
490+
// for the iteration
491+
(0..NUM_HANDLERS).map(|i| iter::<[Self], i>(Self(PhantomData))).collect::<[_; NumHandlers]>()
492+
}
493+
}
488494
}
489495

490-
// FIXME: ICE results if this has type `&'static [_]`.
491-
// Pointer generic parameters entail raw pointer comparison
492-
// (<https://github.com/rust-lang/rust/issues/53020>), which has
493-
// unclear aspects and thus is unstable at this point.
496+
// TODO: ICE results because this has type `&'static [_]`.
497+
// Pointer generic parameters entail raw pointer comparison
498+
// (<https://github.com/rust-lang/rust/issues/53020>), which has
499+
// unclear aspects, thus they are forbidden in const generic parameters,
500+
// meaning the work-around with `*const CfgBuilderInterruptHandler`
501+
// doesn't work anymore.
494502
// FIXME: ↑ This was meant to be inserted before `const HANDLERS: ...`, but when
495503
// I did that, rustfmt tried to destroy the code
496504
// <https://github.com/rust-lang/rustfmt/issues/4263>
497505

498506
/// Construct `InterruptHandlerTable`. Only meant to be used by `build!`
499-
///
500-
/// # Safety
501-
///
502-
/// `std::slice::from_raw_parts(HANDLERS, NUM_HANDLERS)` must be a valid
503-
/// reference.
504507
#[doc(hidden)]
505508
pub const unsafe fn new_interrupt_handler_table<
506509
System: Port,
507510
NumLines: Nat,
508511
NumHandlers: Nat,
509-
const HANDLERS: *const CfgBuilderInterruptHandler,
512+
const HANDLERS: &'static [CfgBuilderInterruptHandler],
510513
const NUM_HANDLERS: usize,
511514
const NUM_LINES: usize,
512515
>() -> InterruptHandlerTable<[Option<InterruptHandlerFn>; NUM_LINES]> {
@@ -526,9 +529,7 @@ pub const unsafe fn new_interrupt_handler_table<
526529
// FIXME: Work-around for `for` being unsupported in `const fn`
527530
let mut i = 0;
528531
while i < NUM_HANDLERS {
529-
// Safety: `i < NUM_HANDLERS`. MIRI (the compile-time interpreter)
530-
// actually can catch unsafe pointer references.
531-
let handler = unsafe { &*HANDLERS.wrapping_add(i) };
532+
let handler = HANDLERS[i];
532533
if handler.line >= NUM_LINES {
533534
panic!("`handler.line >= NUM_LINES`");
534535
}

src/constance/src/lib.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ crate your_app {
102102
task1: constance::Task<System>,
103103
}
104104
105-
static COTTAGE: Objects = constance::build!(System, configure_app);
105+
static COTTAGE: Objects = constance::build!(System, configure_app => Objects);
106106
107107
// The configuration function. See "Static Configuration" for details.
108108
fn configure_app(b: &mut constance::CfgBuilder<System>) -> Objects {

src/constance/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#![feature(const_mut_refs)]
99
#![feature(const_slice_from_raw_parts)]
1010
#![feature(const_raw_ptr_deref)]
11-
#![feature(const_compare_raw_pointers)]
1211
#![feature(ptr_wrapping_offset_from)]
1312
#![feature(unsafe_block_in_unsafe_fn)] // `unsafe fn` doesn't imply `unsafe {}`
1413
#![feature(never_type)] // `!`

src/constance/src/utils/for_times.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ mod tests {
257257
fn test() {
258258
struct Cell<T>(T, u128);
259259

260-
const GOT: u128 = {
260+
const fn got() -> u128 {
261261
let mut cell = Cell("unused", 0);
262262
const_for_times! {
263263
fn iter<[T], I: Nat>(cell: &mut Cell<T>) {
@@ -267,7 +267,7 @@ mod tests {
267267
(0..U<20>).for_each(|i| iter::<[_], i>(&mut cell))
268268
}
269269
cell.1
270-
};
270+
}
271271

272272
let expected = {
273273
let mut cell = 0;
@@ -277,13 +277,13 @@ mod tests {
277277
cell
278278
};
279279

280-
assert_eq!(expected, GOT);
280+
assert_eq!(expected, got());
281281
}
282282

283283
#[test]
284284
fn const_array_from_fn() {
285285
struct Cell<T>(T, u128);
286-
const GOT: [u128; 20] = {
286+
const fn got() -> [u128; 20] {
287287
let mut cell = Cell("unused", 0);
288288
const_array_from_fn! {
289289
fn iter<[T], I: Nat>(ref mut cell: &mut Cell<T>) -> u128 {
@@ -293,7 +293,7 @@ mod tests {
293293

294294
(0..20).map(|i| iter::<[&'static str], i>(&mut cell)).collect::<[_; U<20>]>()
295295
}
296-
};
296+
}
297297

298298
let expected = {
299299
let mut cell = Cell("unused", 0);
@@ -308,6 +308,6 @@ mod tests {
308308
.collect::<Vec<_>>()
309309
};
310310

311-
assert_eq!(GOT[..], *expected);
311+
assert_eq!(got()[..], *expected);
312312
}
313313
}

src/constance/src/utils/sort.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ mod tests {
4949

5050
#[test]
5151
fn const_sort() {
52-
const RESULT: [u32; 14] = {
52+
const fn result() -> [u32; 14] {
5353
let mut array = [2, 6, 1, 9, 13, 3, 8, 12, 5, 11, 14, 7, 4, 10];
5454
sort_by!(14, |i| &mut array[i], |x, y| x < y);
5555
array
56-
};
56+
}
5757

58-
assert_eq!(RESULT, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
58+
assert_eq!(result(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
5959
}
6060

6161
#[quickcheck]

src/constance/src/utils/vec.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,14 @@ mod tests {
103103

104104
#[test]
105105
fn push() {
106-
const VEC: ComptimeVec<u32> = {
106+
const fn vec() -> ComptimeVec<u32> {
107+
// FIXME: Unable to do this inside a `const` item because of
108+
// <https://github.com/rust-lang/rust/pull/72934>
107109
let mut v = ComptimeVec::new();
108110
v.push(42);
109111
v
110-
};
112+
}
113+
const VEC: ComptimeVec<u32> = vec();
111114

112115
const VEC_LEN: usize = VEC.len();
113116
assert_eq!(VEC_LEN, 1);
@@ -118,32 +121,32 @@ mod tests {
118121

119122
#[test]
120123
fn to_array() {
121-
const ARRAY: [u32; 3] = {
124+
const fn array() -> [u32; 3] {
122125
let mut v = ComptimeVec::new();
123126
v.push(1);
124127
v.push(2);
125128
v.push(3);
126129
v.to_array()
127-
};
128-
assert_eq!(ARRAY, [1, 2, 3]);
130+
}
131+
assert_eq!(array(), [1, 2, 3]);
129132
}
130133

131134
#[test]
132135
fn get_mut() {
133-
const VAL: u32 = {
136+
const fn val() -> u32 {
134137
let mut v = ComptimeVec::new();
135138
v.push(1);
136139
v.push(2);
137140
v.push(3);
138141
*v.get_mut(1) += 2;
139142
*v.get(1)
140-
};
141-
assert_eq!(VAL, 4);
143+
}
144+
assert_eq!(val(), 4);
142145
}
143146

144147
#[test]
145148
fn const_vec_position() {
146-
const POS: [Option<usize>; 2] = {
149+
const fn pos() -> [Option<usize>; 2] {
147150
let mut v = ComptimeVec::new();
148151
v.push(42);
149152
v.push(43);
@@ -152,8 +155,8 @@ mod tests {
152155
vec_position!(v, |i| *i == 43),
153156
vec_position!(v, |i| *i == 50),
154157
]
155-
};
156-
assert_eq!(POS, [Some(1), None]);
158+
}
159+
assert_eq!(pos(), [Some(1), None]);
157160
}
158161

159162
#[quickcheck]

src/constance_port_std/src/lib.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use constance::kernel::Task;
1717
// Use the simulator port
1818
constance_port_std::use_port!(unsafe struct System);
1919

20-
const COTTAGE: () = constance::build!(System, configure_app);
20+
const COTTAGE: () = constance::build!(System, configure_app => ());
2121

2222
constance::configure! {
2323
const fn configure_app(_: &mut CfgBuilder<System>) -> () {

0 commit comments

Comments
 (0)