@@ -119,7 +119,6 @@ impl<T: DriverOps> Drop for Registration<T> {
119
119
/// - [`RawDeviceId::ZERO`] is actually a zeroed-out version of the raw device id.
120
120
/// - [`RawDeviceId::to_rawid`] stores `offset` in the context/data field of the raw device id so
121
121
/// that buses can recover the pointer to the data.
122
- #[ const_trait]
123
122
pub unsafe trait RawDeviceId {
124
123
/// The raw type that holds the device id.
125
124
///
@@ -131,13 +130,6 @@ pub unsafe trait RawDeviceId {
131
130
/// Id tables created from [`Self`] use [`Self::ZERO`] as the sentinel to indicate the end of
132
131
/// the table.
133
132
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 ;
141
133
}
142
134
143
135
/// A zero-terminated device id array.
@@ -158,35 +150,7 @@ pub struct IdArray<T: RawDeviceId, U, const N: usize> {
158
150
}
159
151
160
152
impl < 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
- }
153
+ const U_NONE : Option < U > = None ;
190
154
191
155
/// Returns an `IdTable` backed by `self`.
192
156
///
@@ -206,10 +170,82 @@ impl<T: RawDeviceId, U, const N: usize> IdArray<T, U, N> {
206
170
/// Returns the inner IdArrayIds array, without the context data.
207
171
pub const fn as_ids ( & self ) -> IdArrayIds < T , N >
208
172
where
209
- T : ~ const RawDeviceId + Copy ,
173
+ T : RawDeviceId + Copy ,
210
174
{
211
175
self . ids
212
176
}
177
+
178
+ /// Creates a new instance of the array.
179
+ ///
180
+ /// The contents are derived from the given identifiers and context information.
181
+ #[ doc( hidden) ]
182
+ pub const unsafe fn new ( raw_ids : [ T :: RawType ; N ] , infos : [ Option < U > ; N ] ) -> Self
183
+ where
184
+ T : RawDeviceId + Copy ,
185
+ T :: RawType : Copy + Clone ,
186
+ {
187
+ Self {
188
+ ids : IdArrayIds {
189
+ ids : raw_ids,
190
+ sentinel : T :: ZERO ,
191
+ } ,
192
+ id_infos : infos,
193
+ }
194
+ }
195
+
196
+ #[ doc( hidden) ]
197
+ pub const fn get_offset ( idx : usize ) -> isize
198
+ where
199
+ T : RawDeviceId + Copy ,
200
+ T :: RawType : Copy + Clone ,
201
+ {
202
+ // SAFETY: We are only using this dummy value to get offsets.
203
+ let array = unsafe { Self :: new ( [ T :: ZERO ; N ] , [ Self :: U_NONE ; N ] ) } ;
204
+ // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
205
+ // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
206
+ // so the pointers are necessarily 1-byte aligned.
207
+ let ret = unsafe {
208
+ ( & array. id_infos [ idx] as * const _ as * const u8 )
209
+ . offset_from ( & array. ids . ids [ idx] as * const _ as _ )
210
+ } ;
211
+ core:: mem:: forget ( array) ;
212
+ ret
213
+ }
214
+ }
215
+
216
+ // Creates a new ID array. This is a macro so it can take as a parameter the concrete ID type in order
217
+ // to call to_rawid() on it, and still remain const. This is necessary until a new const_trait_impl
218
+ // implementation lands, since the existing implementation was removed in Rust 1.73.
219
+ #[ macro_export]
220
+ #[ doc( hidden) ]
221
+ macro_rules! _new_id_array {
222
+ ( ( $( $args: tt) * ) , $id_type: ty) => { {
223
+ /// Creates a new instance of the array.
224
+ ///
225
+ /// The contents are derived from the given identifiers and context information.
226
+ const fn new< U , const N : usize >( ids: [ $id_type; N ] , infos: [ Option <U >; N ] )
227
+ -> $crate:: driver:: IdArray <$id_type, U , N >
228
+ where
229
+ $id_type: $crate:: driver:: RawDeviceId + Copy ,
230
+ <$id_type as $crate:: driver:: RawDeviceId >:: RawType : Copy + Clone ,
231
+ {
232
+ let mut raw_ids =
233
+ [ <$id_type as $crate:: driver:: RawDeviceId >:: ZERO ; N ] ;
234
+ let mut i = 0usize ;
235
+ while i < N {
236
+ let offset: isize = $crate:: driver:: IdArray :: <$id_type, U , N >:: get_offset( i) ;
237
+ raw_ids[ i] = ids[ i] . to_rawid( offset) ;
238
+ i += 1 ;
239
+ }
240
+
241
+ // SAFETY: We are passing valid arguments computed with the correct offsets.
242
+ unsafe {
243
+ $crate:: driver:: IdArray :: <$id_type, U , N >:: new( raw_ids, infos)
244
+ }
245
+ }
246
+
247
+ new( $( $args) * )
248
+ } }
213
249
}
214
250
215
251
/// A device id table.
@@ -367,8 +403,8 @@ macro_rules! define_id_array {
367
403
( $table_name: ident, $id_type: ty, $data_type: ty, [ $( $t: tt) * ] ) => {
368
404
const $table_name:
369
405
$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) * ) ) ;
406
+ $crate:: _new_id_array! ( (
407
+ $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) , $id_type ) ;
372
408
} ;
373
409
}
374
410
0 commit comments