@@ -58,7 +58,7 @@ use rustc_span::{
58
58
symbol:: { sym, Symbol } ,
59
59
BytePos , FileName , RealFileName ,
60
60
} ;
61
- use serde:: ser:: { SerializeMap , SerializeSeq } ;
61
+ use serde:: ser:: SerializeMap ;
62
62
use serde:: { Serialize , Serializer } ;
63
63
64
64
use crate :: clean:: { self , ItemId , RenderedLink , SelfTy } ;
@@ -123,115 +123,163 @@ pub(crate) struct IndexItem {
123
123
}
124
124
125
125
/// A type used for the search index.
126
- #[ derive( Debug ) ]
126
+ #[ derive( Debug , Eq , PartialEq ) ]
127
127
pub ( crate ) struct RenderType {
128
128
id : Option < RenderTypeId > ,
129
129
generics : Option < Vec < RenderType > > ,
130
130
bindings : Option < Vec < ( RenderTypeId , Vec < RenderType > ) > > ,
131
131
}
132
132
133
- impl Serialize for RenderType {
134
- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
135
- where
136
- S : Serializer ,
137
- {
138
- let id = match & self . id {
139
- // 0 is a sentinel, everything else is one-indexed
140
- None => 0 ,
141
- // concrete type
142
- Some ( RenderTypeId :: Index ( idx) ) if * idx >= 0 => idx + 1 ,
143
- // generic type parameter
144
- Some ( RenderTypeId :: Index ( idx) ) => * idx,
145
- _ => panic ! ( "must convert render types to indexes before serializing" ) ,
146
- } ;
133
+ impl RenderType {
134
+ pub fn write_to_string ( & self , string : & mut String ) {
147
135
if self . generics . is_some ( ) || self . bindings . is_some ( ) {
148
- let mut seq = serializer. serialize_seq ( None ) ?;
149
- seq. serialize_element ( & id) ?;
150
- seq. serialize_element ( self . generics . as_ref ( ) . map ( Vec :: as_slice) . unwrap_or_default ( ) ) ?;
136
+ string. push ( '{' ) ;
137
+ // 0 is a sentinel, everything else is one-indexed
138
+ match self . id {
139
+ Some ( id) => id. write_to_string ( string) ,
140
+ None => string. push ( '`' ) ,
141
+ }
142
+ string. push ( '{' ) ;
143
+ for generic in & self . generics . as_ref ( ) . map ( Vec :: as_slice) . unwrap_or_default ( ) [ ..] {
144
+ generic. write_to_string ( string) ;
145
+ }
146
+ string. push ( '}' ) ;
151
147
if self . bindings . is_some ( ) {
152
- seq. serialize_element (
153
- self . bindings . as_ref ( ) . map ( Vec :: as_slice) . unwrap_or_default ( ) ,
154
- ) ?;
148
+ string. push ( '{' ) ;
149
+ for binding in & self . bindings . as_ref ( ) . map ( Vec :: as_slice) . unwrap_or_default ( ) [ ..] {
150
+ string. push ( '{' ) ;
151
+ binding. 0 . write_to_string ( string) ;
152
+ string. push ( '{' ) ;
153
+ for constraint in & binding. 1 [ ..] {
154
+ constraint. write_to_string ( string) ;
155
+ }
156
+ string. push ( '}' ) ;
157
+ string. push ( '}' ) ;
158
+ }
159
+ string. push ( '}' ) ;
155
160
}
156
- seq . end ( )
161
+ string . push ( '}' ) ;
157
162
} else {
158
- id. serialize ( serializer)
163
+ // 0 is a sentinel, everything else is one-indexed
164
+ match self . id {
165
+ Some ( id) => id. write_to_string ( string) ,
166
+ None => string. push ( '`' ) ,
167
+ }
159
168
}
160
169
}
161
170
}
162
171
163
- #[ derive( Clone , Copy , Debug ) ]
172
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
164
173
pub ( crate ) enum RenderTypeId {
165
174
DefId ( DefId ) ,
166
175
Primitive ( clean:: PrimitiveType ) ,
167
176
AssociatedType ( Symbol ) ,
168
177
Index ( isize ) ,
169
178
}
170
179
171
- impl Serialize for RenderTypeId {
172
- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
173
- where
174
- S : Serializer ,
175
- {
176
- let id = match & self {
180
+ impl RenderTypeId {
181
+ pub fn write_to_string ( & self , string : & mut String ) {
182
+ // (sign, value)
183
+ let ( sign, id) : ( bool , u32 ) = match & self {
177
184
// 0 is a sentinel, everything else is one-indexed
178
185
// concrete type
179
- RenderTypeId :: Index ( idx) if * idx >= 0 => idx + 1 ,
186
+ RenderTypeId :: Index ( idx) if * idx >= 0 => ( false , ( idx + 1isize ) . try_into ( ) . unwrap ( ) ) ,
180
187
// generic type parameter
181
- RenderTypeId :: Index ( idx) => * idx,
188
+ RenderTypeId :: Index ( idx) => ( true , ( - * idx) . try_into ( ) . unwrap ( ) ) ,
182
189
_ => panic ! ( "must convert render types to indexes before serializing" ) ,
183
190
} ;
184
- id. serialize ( serializer)
191
+ // zig-zag notation
192
+ let value: u32 = ( id << 1 ) | ( if sign { 1 } else { 0 } ) ;
193
+ // encode
194
+ let mut shift: u32 = 28 ;
195
+ let mut mask: u32 = 0xF0_00_00_00 ;
196
+ while shift < 32 {
197
+ let hexit = ( value & mask) >> shift;
198
+ if hexit != 0 || shift == 0 {
199
+ let hex =
200
+ char:: try_from ( if shift == 0 { '`' } else { '@' } as u32 + hexit) . unwrap ( ) ;
201
+ string. push ( hex) ;
202
+ }
203
+ shift = shift. wrapping_sub ( 4 ) ;
204
+ mask = mask >> 4 ;
205
+ }
185
206
}
186
207
}
187
208
188
209
/// Full type of functions/methods in the search index.
189
- #[ derive( Debug ) ]
210
+ #[ derive( Debug , Eq , PartialEq ) ]
190
211
pub ( crate ) struct IndexItemFunctionType {
191
212
inputs : Vec < RenderType > ,
192
213
output : Vec < RenderType > ,
193
214
where_clause : Vec < Vec < RenderType > > ,
194
215
}
195
216
196
- impl Serialize for IndexItemFunctionType {
197
- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
198
- where
199
- S : Serializer ,
200
- {
217
+ impl IndexItemFunctionType {
218
+ pub fn write_to_string < ' a > (
219
+ & ' a self ,
220
+ string : & mut String ,
221
+ backref_queue : & mut VecDeque < & ' a IndexItemFunctionType > ,
222
+ ) {
223
+ assert ! ( backref_queue. len( ) < 16 ) ;
201
224
// If we couldn't figure out a type, just write `0`.
202
225
let has_missing = self
203
226
. inputs
204
227
. iter ( )
205
228
. chain ( self . output . iter ( ) )
206
229
. any ( |i| i. id . is_none ( ) && i. generics . is_none ( ) ) ;
207
230
if has_missing {
208
- 0 . serialize ( serializer)
231
+ string. push ( '`' ) ;
232
+ } else if let Some ( idx) = backref_queue. iter ( ) . position ( |other| * other == self ) {
233
+ string. push (
234
+ char:: try_from ( '0' as u32 + u32:: try_from ( idx) . unwrap ( ) )
235
+ . expect ( "last possible value is '?'" ) ,
236
+ ) ;
209
237
} else {
210
- let mut seq = serializer. serialize_seq ( None ) ?;
238
+ backref_queue. push_front ( self ) ;
239
+ if backref_queue. len ( ) >= 16 {
240
+ backref_queue. pop_back ( ) ;
241
+ }
242
+ string. push ( '{' ) ;
211
243
match & self . inputs [ ..] {
212
244
[ one] if one. generics . is_none ( ) && one. bindings . is_none ( ) => {
213
- seq. serialize_element ( one) ?
245
+ one. write_to_string ( string) ;
246
+ }
247
+ _ => {
248
+ string. push ( '{' ) ;
249
+ for item in & self . inputs [ ..] {
250
+ item. write_to_string ( string) ;
251
+ }
252
+ string. push ( '}' ) ;
214
253
}
215
- _ => seq. serialize_element ( & self . inputs ) ?,
216
254
}
217
255
match & self . output [ ..] {
218
256
[ ] if self . where_clause . is_empty ( ) => { }
219
257
[ one] if one. generics . is_none ( ) && one. bindings . is_none ( ) => {
220
- seq. serialize_element ( one) ?
258
+ one. write_to_string ( string) ;
259
+ }
260
+ _ => {
261
+ string. push ( '{' ) ;
262
+ for item in & self . output [ ..] {
263
+ item. write_to_string ( string) ;
264
+ }
265
+ string. push ( '}' ) ;
221
266
}
222
- _ => seq. serialize_element ( & self . output ) ?,
223
267
}
224
268
for constraint in & self . where_clause {
225
269
if let [ one] = & constraint[ ..]
226
270
&& one. generics . is_none ( )
227
271
&& one. bindings . is_none ( )
228
272
{
229
- seq . serialize_element ( one ) ? ;
273
+ one . write_to_string ( string ) ;
230
274
} else {
231
- seq. serialize_element ( constraint) ?;
275
+ string. push ( '{' ) ;
276
+ for item in & constraint[ ..] {
277
+ item. write_to_string ( string) ;
278
+ }
279
+ string. push ( '}' ) ;
232
280
}
233
281
}
234
- seq . end ( )
282
+ string . push ( '}' ) ;
235
283
}
236
284
}
237
285
}
0 commit comments