@@ -117,9 +117,6 @@ impl<T: DriverOps> Drop for Registration<T> {
117117///
118118/// Implementers must ensure that:
119119/// - [`RawDeviceId::ZERO`] is actually a zeroed-out version of the raw device id.
120- /// - [`RawDeviceId::to_rawid`] stores `offset` in the context/data field of the raw device id so
121- /// that buses can recover the pointer to the data.
122- #[ const_trait]
123120pub unsafe trait RawDeviceId {
124121 /// The raw type that holds the device id.
125122 ///
@@ -131,13 +128,6 @@ pub unsafe trait RawDeviceId {
131128 /// Id tables created from [`Self`] use [`Self::ZERO`] as the sentinel to indicate the end of
132129 /// the table.
133130 const ZERO : Self :: RawType ;
134-
135- /// Converts an id into a raw id.
136- ///
137- /// `offset` is the offset from the memory location where the raw device id is stored to the
138- /// location where its associated context information is stored. Implementations must store
139- /// this in the appropriate context/data field of the raw type.
140- fn to_rawid ( & self , offset : isize ) -> Self :: RawType ;
141131}
142132
143133/// A zero-terminated device id array.
@@ -158,35 +148,7 @@ pub struct IdArray<T: RawDeviceId, U, const N: usize> {
158148}
159149
160150impl < T : RawDeviceId , U , const N : usize > IdArray < T , U , N > {
161- /// Creates a new instance of the array.
162- ///
163- /// The contents are derived from the given identifiers and context information.
164- pub const fn new ( ids : [ T ; N ] , infos : [ Option < U > ; N ] ) -> Self
165- where
166- T : ~const RawDeviceId + Copy ,
167- T :: RawType : Copy + Clone ,
168- {
169- let mut array = Self {
170- ids : IdArrayIds {
171- ids : [ T :: ZERO ; N ] ,
172- sentinel : T :: ZERO ,
173- } ,
174- id_infos : infos,
175- } ;
176- let mut i = 0usize ;
177- while i < N {
178- // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
179- // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
180- // so the pointers are necessarily 1-byte aligned.
181- let offset = unsafe {
182- ( & array. id_infos [ i] as * const _ as * const u8 )
183- . offset_from ( & array. ids . ids [ i] as * const _ as _ )
184- } ;
185- array. ids . ids [ i] = ids[ i] . to_rawid ( offset) ;
186- i += 1 ;
187- }
188- array
189- }
151+ const U_NONE : Option < U > = None ;
190152
191153 /// Returns an `IdTable` backed by `self`.
192154 ///
@@ -206,10 +168,82 @@ impl<T: RawDeviceId, U, const N: usize> IdArray<T, U, N> {
206168 /// Returns the inner IdArrayIds array, without the context data.
207169 pub const fn as_ids ( & self ) -> IdArrayIds < T , N >
208170 where
209- T : ~ const RawDeviceId + Copy ,
171+ T : RawDeviceId + Copy ,
210172 {
211173 self . ids
212174 }
175+
176+ /// Creates a new instance of the array.
177+ ///
178+ /// The contents are derived from the given identifiers and context information.
179+ #[ doc( hidden) ]
180+ pub const unsafe fn new ( raw_ids : [ T :: RawType ; N ] , infos : [ Option < U > ; N ] ) -> Self
181+ where
182+ T : RawDeviceId + Copy ,
183+ T :: RawType : Copy + Clone ,
184+ {
185+ Self {
186+ ids : IdArrayIds {
187+ ids : raw_ids,
188+ sentinel : T :: ZERO ,
189+ } ,
190+ id_infos : infos,
191+ }
192+ }
193+
194+ #[ doc( hidden) ]
195+ pub const fn get_offset ( idx : usize ) -> isize
196+ where
197+ T : RawDeviceId + Copy ,
198+ T :: RawType : Copy + Clone ,
199+ {
200+ // SAFETY: We are only using this dummy value to get offsets.
201+ let array = unsafe { Self :: new ( [ T :: ZERO ; N ] , [ Self :: U_NONE ; N ] ) } ;
202+ // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
203+ // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
204+ // so the pointers are necessarily 1-byte aligned.
205+ let ret = unsafe {
206+ ( & array. id_infos [ idx] as * const _ as * const u8 )
207+ . offset_from ( & array. ids . ids [ idx] as * const _ as _ )
208+ } ;
209+ core:: mem:: forget ( array) ;
210+ ret
211+ }
212+ }
213+
214+ // Creates a new ID array. This is a macro so it can take as a parameter the concrete ID type in order
215+ // to call to_rawid() on it, and still remain const. This is necessary until a new const_trait_impl
216+ // implementation lands, since the existing implementation was removed in Rust 1.73.
217+ #[ macro_export]
218+ #[ doc( hidden) ]
219+ macro_rules! _new_id_array {
220+ ( ( $( $args: tt) * ) , $id_type: ty) => { {
221+ /// Creates a new instance of the array.
222+ ///
223+ /// The contents are derived from the given identifiers and context information.
224+ const fn new< U , const N : usize >( ids: [ $id_type; N ] , infos: [ Option <U >; N ] )
225+ -> $crate:: driver:: IdArray <$id_type, U , N >
226+ where
227+ $id_type: $crate:: driver:: RawDeviceId + Copy ,
228+ <$id_type as $crate:: driver:: RawDeviceId >:: RawType : Copy + Clone ,
229+ {
230+ let mut raw_ids =
231+ [ <$id_type as $crate:: driver:: RawDeviceId >:: ZERO ; N ] ;
232+ let mut i = 0usize ;
233+ while i < N {
234+ let offset: isize = $crate:: driver:: IdArray :: <$id_type, U , N >:: get_offset( i) ;
235+ raw_ids[ i] = ids[ i] . to_rawid( offset) ;
236+ i += 1 ;
237+ }
238+
239+ // SAFETY: We are passing valid arguments computed with the correct offsets.
240+ unsafe {
241+ $crate:: driver:: IdArray :: <$id_type, U , N >:: new( raw_ids, infos)
242+ }
243+ }
244+
245+ new( $( $args) * )
246+ } }
213247}
214248
215249/// A device id table.
@@ -367,8 +401,8 @@ macro_rules! define_id_array {
367401 ( $table_name: ident, $id_type: ty, $data_type: ty, [ $( $t: tt) * ] ) => {
368402 const $table_name:
369403 $crate:: driver:: IdArray <$id_type, $data_type, { $crate:: count_paren_items!( $( $t) * ) } > =
370- $crate:: driver :: IdArray :: new (
371- $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) ;
404+ $crate:: _new_id_array! ( (
405+ $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) , $id_type ) ;
372406 } ;
373407}
374408
0 commit comments