@@ -58,7 +58,7 @@ use rustc_span::{
5858 symbol:: { sym, Symbol } ,
5959 BytePos , FileName , RealFileName ,
6060} ;
61- use serde:: ser:: { SerializeMap , SerializeSeq } ;
61+ use serde:: ser:: SerializeMap ;
6262use serde:: { Serialize , Serializer } ;
6363
6464use crate :: clean:: { self , ItemId , RenderedLink , SelfTy } ;
@@ -123,115 +123,163 @@ pub(crate) struct IndexItem {
123123}
124124
125125/// A type used for the search index.
126- #[ derive( Debug ) ]
126+ #[ derive( Debug , Eq , PartialEq ) ]
127127pub ( crate ) struct RenderType {
128128 id : Option < RenderTypeId > ,
129129 generics : Option < Vec < RenderType > > ,
130130 bindings : Option < Vec < ( RenderTypeId , Vec < RenderType > ) > > ,
131131}
132132
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 ) {
147135 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 ( '}' ) ;
151147 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 ( '}' ) ;
155160 }
156- seq . end ( )
161+ string . push ( '}' ) ;
157162 } 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+ }
159168 }
160169 }
161170}
162171
163- #[ derive( Clone , Copy , Debug ) ]
172+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
164173pub ( crate ) enum RenderTypeId {
165174 DefId ( DefId ) ,
166175 Primitive ( clean:: PrimitiveType ) ,
167176 AssociatedType ( Symbol ) ,
168177 Index ( isize ) ,
169178}
170179
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 {
177184 // 0 is a sentinel, everything else is one-indexed
178185 // concrete type
179- RenderTypeId :: Index ( idx) if * idx >= 0 => idx + 1 ,
186+ RenderTypeId :: Index ( idx) if * idx >= 0 => ( false , ( idx + 1isize ) . try_into ( ) . unwrap ( ) ) ,
180187 // generic type parameter
181- RenderTypeId :: Index ( idx) => * idx,
188+ RenderTypeId :: Index ( idx) => ( true , ( - * idx) . try_into ( ) . unwrap ( ) ) ,
182189 _ => panic ! ( "must convert render types to indexes before serializing" ) ,
183190 } ;
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+ }
185206 }
186207}
187208
188209/// Full type of functions/methods in the search index.
189- #[ derive( Debug ) ]
210+ #[ derive( Debug , Eq , PartialEq ) ]
190211pub ( crate ) struct IndexItemFunctionType {
191212 inputs : Vec < RenderType > ,
192213 output : Vec < RenderType > ,
193214 where_clause : Vec < Vec < RenderType > > ,
194215}
195216
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 ) ;
201224 // If we couldn't figure out a type, just write `0`.
202225 let has_missing = self
203226 . inputs
204227 . iter ( )
205228 . chain ( self . output . iter ( ) )
206229 . any ( |i| i. id . is_none ( ) && i. generics . is_none ( ) ) ;
207230 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+ ) ;
209237 } 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 ( '{' ) ;
211243 match & self . inputs [ ..] {
212244 [ 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 ( '}' ) ;
214253 }
215- _ => seq. serialize_element ( & self . inputs ) ?,
216254 }
217255 match & self . output [ ..] {
218256 [ ] if self . where_clause . is_empty ( ) => { }
219257 [ 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 ( '}' ) ;
221266 }
222- _ => seq. serialize_element ( & self . output ) ?,
223267 }
224268 for constraint in & self . where_clause {
225269 if let [ one] = & constraint[ ..]
226270 && one. generics . is_none ( )
227271 && one. bindings . is_none ( )
228272 {
229- seq . serialize_element ( one ) ? ;
273+ one . write_to_string ( string ) ;
230274 } else {
231- seq. serialize_element ( constraint) ?;
275+ string. push ( '{' ) ;
276+ for item in & constraint[ ..] {
277+ item. write_to_string ( string) ;
278+ }
279+ string. push ( '}' ) ;
232280 }
233281 }
234- seq . end ( )
282+ string . push ( '}' ) ;
235283 }
236284 }
237285}
0 commit comments