@@ -61,13 +61,15 @@ use rustc_middle::ty::print::PrintTraitRefExt;
61
61
use rustc_middle:: ty:: { self , TyCtxt } ;
62
62
use rustc_span:: symbol:: { Symbol , sym} ;
63
63
use rustc_span:: { BytePos , DUMMY_SP , FileName , RealFileName } ;
64
+ use serde:: ser:: SerializeSeq as _;
65
+ use serde:: { Deserialize , Serialize } ;
64
66
use tracing:: { debug, info} ;
65
67
66
68
pub ( crate ) use self :: context:: * ;
67
69
pub ( crate ) use self :: span_map:: { LinkFromSrc , collect_spans_and_sources} ;
68
70
pub ( crate ) use self :: write_shared:: * ;
69
71
use crate :: clean:: { self , ItemId , RenderedLink } ;
70
- use crate :: display:: { Joined as _, MaybeDisplay as _} ;
72
+ use crate :: display:: { Joined as _, MaybeDisplay as _, Wrapped } ;
71
73
use crate :: error:: Error ;
72
74
use crate :: formats:: Impl ;
73
75
use crate :: formats:: cache:: Cache ;
@@ -144,7 +146,7 @@ pub(crate) struct IndexItem {
144
146
}
145
147
146
148
/// A type used for the search index.
147
- #[ derive( Debug , Eq , PartialEq ) ]
149
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
148
150
struct RenderType {
149
151
id : Option < RenderTypeId > ,
150
152
generics : Option < Vec < RenderType > > ,
@@ -153,59 +155,35 @@ struct RenderType {
153
155
154
156
impl RenderType {
155
157
fn size ( & self ) -> usize {
156
- let mut size = 1 ;
157
- if let Some ( generics) = & self . generics {
158
- size += generics. iter ( ) . map ( RenderType :: size) . sum :: < usize > ( ) ;
159
- }
160
- if let Some ( bindings) = & self . bindings {
161
- for ( _, constraints) in bindings. iter ( ) {
162
- size += 1 ;
163
- size += constraints. iter ( ) . map ( RenderType :: size) . sum :: < usize > ( ) ;
164
- }
165
- }
166
- size
158
+ self . bindings
159
+ . iter ( )
160
+ . flatten ( )
161
+ . map ( |( _, constraints) | constraints)
162
+ . chain ( self . generics . iter ( ) )
163
+ . map ( |constraints| constraints. iter ( ) . map ( RenderType :: size) . sum :: < usize > ( ) + 1 )
164
+ . sum ( )
167
165
}
168
- // Types are rendered as lists of lists, because that's pretty compact.
169
- // The contents of the lists are always integers in self-terminating hex
170
- // form, handled by `RenderTypeId::write_to_string`, so no commas are
171
- // needed to separate the items.
172
- fn write_to_string ( & self , string : & mut String ) {
173
- fn write_optional_id ( id : Option < RenderTypeId > , string : & mut String ) {
174
- // 0 is a sentinel, everything else is one-indexed
175
- match id {
176
- Some ( id) => id. write_to_string ( string) ,
177
- None => string. push ( '`' ) ,
178
- }
179
- }
180
- // Either just the type id, or `{type, generics, bindings?}`
181
- // where generics is a list of types,
182
- // and bindings is a list of `{id, typelist}` pairs.
183
- if self . generics . is_some ( ) || self . bindings . is_some ( ) {
184
- string. push ( '{' ) ;
185
- write_optional_id ( self . id , string) ;
186
- string. push ( '{' ) ;
187
- for generic in self . generics . as_deref ( ) . unwrap_or_default ( ) {
188
- generic. write_to_string ( string) ;
189
- }
190
- string. push ( '}' ) ;
191
- if self . bindings . is_some ( ) {
192
- string. push ( '{' ) ;
193
- for binding in self . bindings . as_deref ( ) . unwrap_or_default ( ) {
194
- string. push ( '{' ) ;
195
- binding. 0 . write_to_string ( string) ;
196
- string. push ( '{' ) ;
197
- for constraint in & binding. 1 [ ..] {
198
- constraint. write_to_string ( string) ;
199
- }
200
- string. push_str ( "}}" ) ;
201
- }
202
- string. push ( '}' ) ;
166
+
167
+ fn write_bindings ( & self ) -> Option < impl fmt:: Display > {
168
+ let Some ( bindings) = & self . bindings else {
169
+ return None ;
170
+ } ;
171
+
172
+ Some ( Wrapped :: with_curly_brackets ( ) . wrap_fn ( move |f| {
173
+ for ( binding, constraints) in bindings {
174
+ Wrapped :: with_curly_brackets ( )
175
+ . wrap_fn ( |f| {
176
+ binding. write_to_string ( ) . fmt ( f) ?;
177
+ Wrapped :: with_curly_brackets ( )
178
+ . wrap_fn ( |f| constraints. iter ( ) . joined ( "" , f) )
179
+ . fmt ( f)
180
+ } )
181
+ . fmt ( f) ?;
203
182
}
204
- string. push ( '}' ) ;
205
- } else {
206
- write_optional_id ( self . id , string) ;
207
- }
183
+ Ok ( ( ) )
184
+ } ) )
208
185
}
186
+
209
187
fn read_from_bytes ( string : & [ u8 ] ) -> ( RenderType , usize ) {
210
188
let mut i = 0 ;
211
189
if string[ i] == b'{' {
@@ -264,6 +242,40 @@ impl RenderType {
264
242
}
265
243
}
266
244
245
+ impl fmt:: Display for RenderType {
246
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
247
+ // Types are rendered as lists of lists, because that's pretty compact.
248
+ // The contents of the lists are always integers in self-terminating hex
249
+ // form, handled by `RenderTypeId::write_to_string`, so no commas are
250
+ // needed to separate the items.
251
+
252
+ fn write_optional_id ( id : Option < RenderTypeId > ) -> impl fmt:: Display {
253
+ // 0 is a sentinel, everything else is one-indexed
254
+ match id {
255
+ Some ( id) => Either :: Left ( id. write_to_string ( ) ) ,
256
+ None => Either :: Right ( '`' ) ,
257
+ }
258
+ }
259
+
260
+ // Either just the type id, or `{type, generics, bindings?}`
261
+ // where generics is a list of types,
262
+ // and bindings is a list of `{id, typelist}` pairs.
263
+ if self . generics . is_some ( ) || self . bindings . is_some ( ) {
264
+ Wrapped :: with_curly_brackets ( )
265
+ . wrap_fn ( |f| {
266
+ let id = write_optional_id ( self . id ) ;
267
+ let generics = Wrapped :: with_curly_brackets ( )
268
+ . wrap_fn ( |f| self . generics . iter ( ) . flatten ( ) . joined ( "" , f) ) ;
269
+ let bindings = self . write_bindings ( ) . maybe_display ( ) ;
270
+ write ! ( f, "{id}{generics}{bindings}" )
271
+ } )
272
+ . fmt ( f)
273
+ } else {
274
+ write_optional_id ( self . id ) . fmt ( f)
275
+ }
276
+ }
277
+ }
278
+
267
279
#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
268
280
enum RenderTypeId {
269
281
DefId ( DefId ) ,
@@ -274,7 +286,7 @@ enum RenderTypeId {
274
286
}
275
287
276
288
impl RenderTypeId {
277
- fn write_to_string ( & self , string : & mut String ) {
289
+ fn write_to_string ( & self ) -> impl fmt :: Display + use < > {
278
290
let id: i32 = match & self {
279
291
// 0 is a sentinel, everything else is one-indexed
280
292
// concrete type
@@ -283,7 +295,7 @@ impl RenderTypeId {
283
295
RenderTypeId :: Index ( idx) => ( * idx) . try_into ( ) . unwrap ( ) ,
284
296
_ => panic ! ( "must convert render types to indexes before serializing" ) ,
285
297
} ;
286
- search_index:: encode:: write_signed_vlqhex_to_string ( id, string ) ;
298
+ search_index:: encode:: write_signed_vlqhex_to_string ( id)
287
299
}
288
300
fn read_from_bytes ( string : & [ u8 ] ) -> ( Option < RenderTypeId > , usize ) {
289
301
let Some ( ( value, offset) ) = search_index:: encode:: read_signed_vlqhex_from_string ( string)
@@ -301,7 +313,7 @@ impl RenderTypeId {
301
313
}
302
314
303
315
/// Full type of functions/methods in the search index.
304
- #[ derive( Debug , Eq , PartialEq ) ]
316
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
305
317
pub ( crate ) struct IndexItemFunctionType {
306
318
inputs : Vec < RenderType > ,
307
319
output : Vec < RenderType > ,
@@ -311,13 +323,13 @@ pub(crate) struct IndexItemFunctionType {
311
323
312
324
impl IndexItemFunctionType {
313
325
fn size ( & self ) -> usize {
314
- self . inputs . iter ( ) . map ( RenderType :: size ) . sum :: < usize > ( )
315
- + self . output . iter ( ) . map ( RenderType :: size ) . sum :: < usize > ( )
316
- + self
317
- . where_clause
318
- . iter ( )
319
- . map ( |constraints| constraints . iter ( ) . map ( RenderType :: size) . sum :: < usize > ( ) )
320
- . sum :: < usize > ( )
326
+ self . where_clause
327
+ . iter ( )
328
+ . flatten ( )
329
+ . chain ( & self . inputs )
330
+ . chain ( & self . output )
331
+ . map ( RenderType :: size)
332
+ . sum ( )
321
333
}
322
334
fn read_from_string_without_param_names ( string : & [ u8 ] ) -> ( IndexItemFunctionType , usize ) {
323
335
let mut i = 0 ;
@@ -367,7 +379,7 @@ impl IndexItemFunctionType {
367
379
i += 1 ;
368
380
( IndexItemFunctionType { inputs, output, where_clause, param_names : Vec :: new ( ) } , i)
369
381
}
370
- fn write_to_string_without_param_names < ' a > ( & ' a self , string : & mut String ) {
382
+ fn write_to_string_without_param_names < ' a > ( & ' a self ) -> impl fmt :: Display {
371
383
// If we couldn't figure out a type, just write 0,
372
384
// which is encoded as `` ` `` (see RenderTypeId::write_to_string).
373
385
let has_missing = self
@@ -376,50 +388,94 @@ impl IndexItemFunctionType {
376
388
. chain ( self . output . iter ( ) )
377
389
. any ( |i| i. id . is_none ( ) && i. generics . is_none ( ) ) ;
378
390
if has_missing {
379
- string . push ( '`' ) ;
391
+ Either :: Left ( '`' )
380
392
} else {
381
- string. push ( '{' ) ;
382
- match & self . inputs [ ..] {
383
- [ one] if one. generics . is_none ( ) && one. bindings . is_none ( ) => {
384
- one. write_to_string ( string) ;
393
+ Either :: Right ( Wrapped :: with_curly_brackets ( ) . wrap_fn ( |f| {
394
+ fn write_render_types ( types : & [ RenderType ] ) -> impl fmt:: Display {
395
+ Wrapped :: with_curly_brackets ( )
396
+ . when ( !matches ! ( types, [ one] if one. generics. is_none( ) && one. bindings. is_none( ) ) )
397
+ . wrap_fn ( |f| types. iter ( ) . joined ( "" , f) )
385
398
}
386
- _ => {
387
- string. push ( '{' ) ;
388
- for item in & self . inputs [ ..] {
389
- item. write_to_string ( string) ;
390
- }
391
- string. push ( '}' ) ;
399
+
400
+ write_render_types ( & self . inputs ) . fmt ( f) ?;
401
+ if !( self . output . is_empty ( ) && self . where_clause . is_empty ( ) ) {
402
+ write_render_types ( & self . output ) . fmt ( f) ?;
392
403
}
404
+ self . where_clause
405
+ . iter ( )
406
+ . map ( |constraints| write_render_types ( constraints) )
407
+ . joined ( "" , f) ?;
408
+
409
+ Ok ( ( ) )
410
+ } ) )
411
+ }
412
+ }
413
+ }
414
+
415
+ impl Serialize for IndexItemFunctionType {
416
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
417
+ where
418
+ S : serde:: Serializer ,
419
+ {
420
+ let mut seq = serializer. serialize_seq ( Some ( 2 ) ) ?;
421
+ seq. serialize_element ( & self . write_to_string_without_param_names ( ) . to_string ( ) ) ?;
422
+
423
+ struct ParamNames < ' a > ( & ' a [ Option < Symbol > ] ) ;
424
+
425
+ impl < ' a > Serialize for ParamNames < ' a > {
426
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
427
+ where
428
+ S : serde:: Serializer ,
429
+ {
430
+ serializer. collect_seq (
431
+ self . 0
432
+ . iter ( )
433
+ . map ( |symbol| symbol. as_ref ( ) . map ( ToString :: to_string) . unwrap_or_default ( ) ) ,
434
+ )
393
435
}
394
- match & self . output [ ..] {
395
- [ ] if self . where_clause . is_empty ( ) => { }
396
- [ one] if one. generics . is_none ( ) && one. bindings . is_none ( ) => {
397
- one. write_to_string ( string) ;
398
- }
399
- _ => {
400
- string. push ( '{' ) ;
401
- for item in & self . output [ ..] {
402
- item. write_to_string ( string) ;
403
- }
404
- string. push ( '}' ) ;
405
- }
436
+ }
437
+
438
+ seq. serialize_element ( & ParamNames ( & self . param_names ) ) ?;
439
+ seq. end ( )
440
+ }
441
+ }
442
+
443
+ impl < ' de > Deserialize < ' de > for IndexItemFunctionType {
444
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
445
+ where
446
+ D : serde:: Deserializer < ' de > ,
447
+ {
448
+ use serde:: de:: { self , Error as _} ;
449
+
450
+ struct FunctionDataVisitor ;
451
+ impl < ' de > de:: Visitor < ' de > for FunctionDataVisitor {
452
+ type Value = IndexItemFunctionType ;
453
+ fn expecting ( & self , formatter : & mut std:: fmt:: Formatter < ' _ > ) -> fmt:: Result {
454
+ write ! ( formatter, "fn data" )
406
455
}
407
- for constraint in & self . where_clause {
408
- if let [ one] = & constraint[ ..]
409
- && one. generics . is_none ( )
410
- && one. bindings . is_none ( )
411
- {
412
- one. write_to_string ( string) ;
413
- } else {
414
- string. push ( '{' ) ;
415
- for item in & constraint[ ..] {
416
- item. write_to_string ( string) ;
417
- }
418
- string. push ( '}' ) ;
419
- }
456
+ fn visit_seq < A : de:: SeqAccess < ' de > > ( self , mut v : A ) -> Result < Self :: Value , A :: Error > {
457
+ let ( mut function_signature, _) = v
458
+ . next_element ( ) ?
459
+ . map ( |fn_ : String | {
460
+ IndexItemFunctionType :: read_from_string_without_param_names ( fn_. as_bytes ( ) )
461
+ } )
462
+ . ok_or_else ( || A :: Error :: missing_field ( "function_signature" ) ) ?;
463
+ let param_names: Vec < Option < Symbol > > = v
464
+ . next_element ( ) ?
465
+ . map ( |param_names : Vec < String > | {
466
+ param_names
467
+ . into_iter ( )
468
+ . map ( |symbol| {
469
+ if symbol. is_empty ( ) { None } else { Some ( Symbol :: intern ( & symbol) ) }
470
+ } )
471
+ . collect ( )
472
+ } )
473
+ . ok_or_else ( || A :: Error :: missing_field ( "param_names" ) ) ?;
474
+ function_signature. param_names = param_names;
475
+ Ok ( function_signature)
420
476
}
421
- string. push ( '}' ) ;
422
477
}
478
+ deserializer. deserialize_any ( FunctionDataVisitor )
423
479
}
424
480
}
425
481
0 commit comments