@@ -126,7 +126,6 @@ impl<T: DriverOps> Drop for Registration<T> {
126126/// - [`RawDeviceId::ZERO`] is actually a zeroed-out version of the raw device id.
127127/// - [`RawDeviceId::to_rawid`] stores `offset` in the context/data field of the raw device id so
128128/// that buses can recover the pointer to the data.
129- #[ const_trait]
130129pub unsafe trait RawDeviceId {
131130 /// The raw type that holds the device id.
132131 ///
@@ -138,13 +137,6 @@ pub unsafe trait RawDeviceId {
138137 /// Id tables created from [`Self`] use [`Self::ZERO`] as the sentinel to indicate the end of
139138 /// the table.
140139 const ZERO : Self :: RawType ;
141-
142- /// Converts an id into a raw id.
143- ///
144- /// `offset` is the offset from the memory location where the raw device id is stored to the
145- /// location where its associated context information is stored. Implementations must store
146- /// this in the appropriate context/data field of the raw type.
147- fn to_rawid ( & self , offset : isize ) -> Self :: RawType ;
148140}
149141
150142/// A zero-terminated device id array.
@@ -166,35 +158,7 @@ pub struct IdArray<T: RawDeviceId, U, const N: usize> {
166158}
167159
168160impl < T : RawDeviceId , U , const N : usize > IdArray < T , U , N > {
169- /// Creates a new instance of the array.
170- ///
171- /// The contents are derived from the given identifiers and context information.
172- pub const fn new ( ids : [ T ; N ] , infos : [ Option < U > ; N ] ) -> Self
173- where
174- T : ~const RawDeviceId + Copy ,
175- T :: RawType : Copy + Clone ,
176- {
177- let mut array = Self {
178- ids : IdArrayIds {
179- ids : [ T :: ZERO ; N ] ,
180- sentinel : T :: ZERO ,
181- } ,
182- id_infos : infos,
183- } ;
184- let mut i = 0usize ;
185- while i < N {
186- // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
187- // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
188- // so the pointers are necessarily 1-byte aligned.
189- let offset = unsafe {
190- ( & array. id_infos [ i] as * const _ as * const u8 )
191- . offset_from ( & array. ids . ids [ i] as * const _ as _ )
192- } ;
193- array. ids . ids [ i] = ids[ i] . to_rawid ( offset) ;
194- i += 1 ;
195- }
196- array
197- }
161+ const U_NONE : Option < U > = None ;
198162
199163 /// Returns an `IdTable` backed by `self`.
200164 ///
@@ -214,10 +178,82 @@ impl<T: RawDeviceId, U, const N: usize> IdArray<T, U, N> {
214178 /// Returns the inner IdArrayIds array, without the context data.
215179 pub const fn as_ids ( & self ) -> IdArrayIds < T , N >
216180 where
217- T : ~ const RawDeviceId + Copy ,
181+ T : RawDeviceId + Copy ,
218182 {
219183 self . ids
220184 }
185+
186+ /// Creates a new instance of the array.
187+ ///
188+ /// The contents are derived from the given identifiers and context information.
189+ #[ doc( hidden) ]
190+ pub const unsafe fn new ( raw_ids : [ T :: RawType ; N ] , infos : [ Option < U > ; N ] ) -> Self
191+ where
192+ T : RawDeviceId + Copy ,
193+ T :: RawType : Copy + Clone ,
194+ {
195+ Self {
196+ ids : IdArrayIds {
197+ ids : raw_ids,
198+ sentinel : T :: ZERO ,
199+ } ,
200+ id_infos : infos,
201+ }
202+ }
203+
204+ #[ doc( hidden) ]
205+ pub const fn get_offset ( idx : usize ) -> isize
206+ where
207+ T : RawDeviceId + Copy ,
208+ T :: RawType : Copy + Clone ,
209+ {
210+ // SAFETY: We are only using this dummy value to get offsets.
211+ let array = unsafe { Self :: new ( [ T :: ZERO ; N ] , [ Self :: U_NONE ; N ] ) } ;
212+ // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
213+ // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
214+ // so the pointers are necessarily 1-byte aligned.
215+ let ret = unsafe {
216+ ( & array. id_infos [ idx] as * const _ as * const u8 )
217+ . offset_from ( & array. ids . ids [ idx] as * const _ as _ )
218+ } ;
219+ core:: mem:: forget ( array) ;
220+ ret
221+ }
222+ }
223+
224+ // Creates a new ID array. This is a macro so it can take as a parameter the concrete ID type in order
225+ // to call to_rawid() on it, and still remain const. This is necessary until a new const_trait_impl
226+ // implementation lands, since the existing implementation was removed in Rust 1.73.
227+ #[ macro_export]
228+ #[ doc( hidden) ]
229+ macro_rules! _new_id_array {
230+ ( ( $( $args: tt) * ) , $id_type: ty) => { {
231+ /// Creates a new instance of the array.
232+ ///
233+ /// The contents are derived from the given identifiers and context information.
234+ const fn new< U , const N : usize >( ids: [ $id_type; N ] , infos: [ Option <U >; N ] )
235+ -> $crate:: driver:: IdArray <$id_type, U , N >
236+ where
237+ $id_type: $crate:: driver:: RawDeviceId + Copy ,
238+ <$id_type as $crate:: driver:: RawDeviceId >:: RawType : Copy + Clone ,
239+ {
240+ let mut raw_ids =
241+ [ <$id_type as $crate:: driver:: RawDeviceId >:: ZERO ; N ] ;
242+ let mut i = 0usize ;
243+ while i < N {
244+ let offset: isize = $crate:: driver:: IdArray :: <$id_type, U , N >:: get_offset( i) ;
245+ raw_ids[ i] = ids[ i] . to_rawid( offset) ;
246+ i += 1 ;
247+ }
248+
249+ // SAFETY: We are passing valid arguments computed with the correct offsets.
250+ unsafe {
251+ $crate:: driver:: IdArray :: <$id_type, U , N >:: new( raw_ids, infos)
252+ }
253+ }
254+
255+ new( $( $args) * )
256+ } }
221257}
222258
223259/// A device id table.
@@ -375,8 +411,8 @@ macro_rules! define_id_array {
375411 ( $table_name: ident, $id_type: ty, $data_type: ty, [ $( $t: tt) * ] ) => {
376412 const $table_name:
377413 $crate:: driver:: IdArray <$id_type, $data_type, { $crate:: count_paren_items!( $( $t) * ) } > =
378- $crate:: driver :: IdArray :: new (
379- $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) ;
414+ $crate:: _new_id_array! ( (
415+ $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) , $id_type ) ;
380416 } ;
381417}
382418
0 commit comments