@@ -408,14 +408,14 @@ type ProtoCombinedHandlerFn = fn(interrupt::InterruptNum, bool);
408408struct 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
415415trait 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 {
424424impl <
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<
445445impl <
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) ]
505508pub 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 }
0 commit comments