@@ -402,15 +402,23 @@ impl InterruptHandlerTable {
402
402
/// ```
403
403
type ProtoCombinedHandlerFn = fn ( interrupt:: InterruptNum , bool ) ;
404
404
405
+ // FIXME: Passing `&'static [_]` as a const generic parameter causes ICE:
406
+ // <https://github.com/rust-lang/rust/issues/73727>
407
+ // `CfgBuilderInterruptHandlerList` is a work-around for this issue.
408
+ /// A static list of [`CfgBuilderInterruptHandler`]s.
409
+ #[ doc( hidden) ]
410
+ pub trait CfgBuilderInterruptHandlerList {
411
+ /// `U<Self::NUM_HANDLERS>`
412
+ type NumHandlers : Nat ;
413
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ;
414
+ }
415
+
405
416
/// The ultimate purpose of this type is to make `PROTO_COMBINED_HANDLERS`
406
417
/// (a list of `ProtoCombinedHandlerFn`s) and `FIRST_PROTO_COMBINED_HANDLER`
407
418
/// available to `new_interrupt_handler_table`.
408
- struct MakeProtoCombinedHandlers <
409
- System ,
410
- NumHandlers ,
411
- const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
412
- const NUM_HANDLERS : usize ,
413
- > ( PhantomData < ( System , NumHandlers ) > ) ;
419
+ struct MakeProtoCombinedHandlers < System , Handlers , const NUM_HANDLERS : usize > (
420
+ PhantomData < ( System , Handlers ) > ,
421
+ ) ;
414
422
415
423
trait MakeProtoCombinedHandlersTrait {
416
424
type System : Port ;
@@ -421,17 +429,12 @@ trait MakeProtoCombinedHandlersTrait {
421
429
const FIRST_PROTO_COMBINED_HANDLER : Option < ProtoCombinedHandlerFn > ;
422
430
}
423
431
424
- impl <
425
- System : Port ,
426
- NumHandlers : Nat ,
427
- const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
428
- const NUM_HANDLERS : usize ,
429
- > MakeProtoCombinedHandlersTrait
430
- for MakeProtoCombinedHandlers < System , NumHandlers , HANDLERS , NUM_HANDLERS >
432
+ impl < System : Port , Handlers : CfgBuilderInterruptHandlerList , const NUM_HANDLERS : usize >
433
+ MakeProtoCombinedHandlersTrait for MakeProtoCombinedHandlers < System , Handlers , NUM_HANDLERS >
431
434
{
432
435
type System = System ;
433
- type NumHandlers = NumHandlers ;
434
- const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] = HANDLERS ;
436
+ type NumHandlers = Handlers :: NumHandlers ;
437
+ const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] = Handlers :: HANDLERS ;
435
438
const NUM_HANDLERS : usize = NUM_HANDLERS ;
436
439
const PROTO_COMBINED_HANDLERS : & ' static [ ProtoCombinedHandlerFn ] =
437
440
& Self :: PROTO_COMBINED_HANDLERS_ARRAY ;
@@ -442,12 +445,8 @@ impl<
442
445
} ;
443
446
}
444
447
445
- impl <
446
- System : Port ,
447
- NumHandlers : Nat ,
448
- const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
449
- const NUM_HANDLERS : usize ,
450
- > MakeProtoCombinedHandlers < System , NumHandlers , HANDLERS , NUM_HANDLERS >
448
+ impl < System : Port , Handlers : CfgBuilderInterruptHandlerList , const NUM_HANDLERS : usize >
449
+ MakeProtoCombinedHandlers < System , Handlers , NUM_HANDLERS >
451
450
{
452
451
const PROTO_COMBINED_HANDLERS_ARRAY : [ ProtoCombinedHandlerFn ; NUM_HANDLERS ] =
453
452
Self :: proto_combined_handlers_array ( ) ;
@@ -488,30 +487,19 @@ impl<
488
487
489
488
// `Self: MakeProtoCombinedHandlersTrait` is used as the context type
490
489
// for the iteration
491
- ( 0 ..NUM_HANDLERS ) . map( |i| iter:: <[ Self ] , i>( Self ( PhantomData ) ) ) . collect:: <[ _; NumHandlers ] >( )
490
+ ( 0 ..NUM_HANDLERS ) . map( |i| iter:: <[ Self ] , i>( Self ( PhantomData ) ) ) . collect:: <[ _; Handlers :: NumHandlers ] >( )
492
491
}
493
492
}
494
493
}
495
494
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.
502
- // FIXME: ↑ This was meant to be inserted before `const HANDLERS: ...`, but when
503
- // I did that, rustfmt tried to destroy the code
504
- // <https://github.com/rust-lang/rustfmt/issues/4263>
505
-
506
495
/// Construct `InterruptHandlerTable`. Only meant to be used by `build!`
507
496
#[ doc( hidden) ]
508
497
pub const unsafe fn new_interrupt_handler_table <
509
498
System : Port ,
510
499
NumLines : Nat ,
511
- NumHandlers : Nat ,
512
- const HANDLERS : & ' static [ CfgBuilderInterruptHandler ] ,
513
- const NUM_HANDLERS : usize ,
500
+ Handlers : CfgBuilderInterruptHandlerList ,
514
501
const NUM_LINES : usize ,
502
+ const NUM_HANDLERS : usize ,
515
503
> ( ) -> InterruptHandlerTable < [ Option < InterruptHandlerFn > ; NUM_LINES ] > {
516
504
// Check generic parameters
517
505
@@ -522,14 +510,14 @@ pub const unsafe fn new_interrupt_handler_table<
522
510
if NumLines :: N != NUM_LINES {
523
511
panic ! ( "`NumLines::N != NUM_LINES`" ) ;
524
512
}
525
- if NumHandlers :: N != NUM_HANDLERS {
513
+ if Handlers :: NumHandlers :: N != NUM_HANDLERS {
526
514
panic ! ( "`NumHandlers::N != NUM_HANDLERS`" ) ;
527
515
}
528
516
529
517
// FIXME: Work-around for `for` being unsupported in `const fn`
530
518
let mut i = 0 ;
531
519
while i < NUM_HANDLERS {
532
- let handler = HANDLERS [ i] ;
520
+ let handler = Handlers :: HANDLERS [ i] ;
533
521
if handler. line >= NUM_LINES {
534
522
panic ! ( "`handler.line >= NUM_LINES`" ) ;
535
523
}
@@ -553,9 +541,8 @@ pub const unsafe fn new_interrupt_handler_table<
553
541
554
542
( 0 ..NUM_LINES ) . map( |i| iter:: <[ MakeProtoCombinedHandlers <
555
543
System ,
556
- NumHandlers ,
557
- HANDLERS ,
558
- NUM_HANDLERS
544
+ Handlers ,
545
+ NUM_HANDLERS ,
559
546
>] , i>( MakeProtoCombinedHandlers ( PhantomData ) ) ) . collect:: <[ _; NumLines ] >( )
560
547
} ;
561
548
0 commit comments