@@ -408,14 +408,14 @@ type ProtoCombinedHandlerFn = fn(interrupt::InterruptNum, bool);
408
408
struct MakeProtoCombinedHandlers <
409
409
System ,
410
410
NumHandlers ,
411
- const HANDLERS : * const CfgBuilderInterruptHandler ,
411
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
412
412
const NUM_HANDLERS : usize ,
413
413
> ( PhantomData < ( System , NumHandlers ) > ) ;
414
414
415
415
trait MakeProtoCombinedHandlersTrait {
416
416
type System : Port ;
417
417
type NumHandlers : Nat ;
418
- const HANDLERS : * const CfgBuilderInterruptHandler ;
418
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ;
419
419
const NUM_HANDLERS : usize ;
420
420
const PROTO_COMBINED_HANDLERS : & ' static [ ProtoCombinedHandlerFn ] ;
421
421
const FIRST_PROTO_COMBINED_HANDLER : Option < ProtoCombinedHandlerFn > ;
@@ -424,14 +424,14 @@ trait MakeProtoCombinedHandlersTrait {
424
424
impl <
425
425
System : Port ,
426
426
NumHandlers : Nat ,
427
- const HANDLERS : * const CfgBuilderInterruptHandler ,
427
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
428
428
const NUM_HANDLERS : usize ,
429
429
> MakeProtoCombinedHandlersTrait
430
430
for MakeProtoCombinedHandlers < System , NumHandlers , HANDLERS , NUM_HANDLERS >
431
431
{
432
432
type System = System ;
433
433
type NumHandlers = NumHandlers ;
434
- const HANDLERS : * const CfgBuilderInterruptHandler = HANDLERS ;
434
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] = HANDLERS ;
435
435
const NUM_HANDLERS : usize = NUM_HANDLERS ;
436
436
const PROTO_COMBINED_HANDLERS : & ' static [ ProtoCombinedHandlerFn ] =
437
437
& Self :: PROTO_COMBINED_HANDLERS_ARRAY ;
@@ -445,68 +445,71 @@ impl<
445
445
impl <
446
446
System : Port ,
447
447
NumHandlers : Nat ,
448
- const HANDLERS : * const CfgBuilderInterruptHandler ,
448
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
449
449
const NUM_HANDLERS : usize ,
450
450
> MakeProtoCombinedHandlers < System , NumHandlers , HANDLERS , NUM_HANDLERS >
451
451
{
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
+ }
467
473
}
468
- }
469
474
470
- ( handler. start) ( handler. param) ;
475
+ ( handler. start) ( handler. param) ;
471
476
472
- should_unlock_cpu = true ;
473
- }
477
+ should_unlock_cpu = true ;
478
+ }
474
479
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
+ }
479
485
}
486
+ proto_combined_handler:: <T , I >
480
487
}
481
- proto_combined_handler:: <T , I >
482
- }
483
488
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
+ }
488
494
}
489
495
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.
494
502
// FIXME: ↑ This was meant to be inserted before `const HANDLERS: ...`, but when
495
503
// I did that, rustfmt tried to destroy the code
496
504
// <https://github.com/rust-lang/rustfmt/issues/4263>
497
505
498
506
/// 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.
504
507
#[ doc( hidden) ]
505
508
pub const unsafe fn new_interrupt_handler_table <
506
509
System : Port ,
507
510
NumLines : Nat ,
508
511
NumHandlers : Nat ,
509
- const HANDLERS : * const CfgBuilderInterruptHandler ,
512
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
510
513
const NUM_HANDLERS : usize ,
511
514
const NUM_LINES : usize ,
512
515
> ( ) -> InterruptHandlerTable < [ Option < InterruptHandlerFn > ; NUM_LINES ] > {
@@ -526,9 +529,7 @@ pub const unsafe fn new_interrupt_handler_table<
526
529
// FIXME: Work-around for `for` being unsupported in `const fn`
527
530
let mut i = 0 ;
528
531
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] ;
532
533
if handler. line >= NUM_LINES {
533
534
panic ! ( "`handler.line >= NUM_LINES`" ) ;
534
535
}
0 commit comments