@@ -131,6 +131,10 @@ pub(crate) struct RenderType {
131131}
132132
133133impl RenderType {
134+ // Types are rendered as lists of lists, because that's pretty compact.
135+ // The contents of the lists are always integers in self-terminating hex
136+ // form, handled by `RenderTypeId::write_to_string`, so no commas are
137+ // needed to separate the items.
134138 pub fn write_to_string ( & self , string : & mut String ) {
135139 fn write_optional_id ( id : Option < RenderTypeId > , string : & mut String ) {
136140 // 0 is a sentinel, everything else is one-indexed
@@ -139,6 +143,9 @@ impl RenderType {
139143 None => string. push ( '`' ) ,
140144 }
141145 }
146+ // Either just the type id, or `{type, generics, bindings?}`
147+ // where generics is a list of types,
148+ // and bindings is a list of `{id, typelist}` pairs.
142149 if self . generics . is_some ( ) || self . bindings . is_some ( ) {
143150 string. push ( '{' ) ;
144151 write_optional_id ( self . id , string) ;
@@ -186,10 +193,19 @@ impl RenderTypeId {
186193 RenderTypeId :: Index ( idx) => ( true , ( -* idx) . try_into ( ) . unwrap ( ) ) ,
187194 _ => panic ! ( "must convert render types to indexes before serializing" ) ,
188195 } ;
189- // zig-zag notation
196+ // zig-zag encoding
190197 let value: u32 = ( id << 1 ) | ( if sign { 1 } else { 0 } ) ;
191- // encode
192- // Documented in https://rust-lang.github.io/rustc-dev-guide/rustdoc-internals/search.html
198+ // Self-terminating hex use capital letters for everything but the
199+ // least significant digit, which is lowercase. For example, decimal 17
200+ // would be `` Aa `` if zig-zag encoding weren't used.
201+ //
202+ // Zig-zag encoding, however, stores the sign bit as the last bit.
203+ // This means, in the last hexit, 1 is actually `c`, -1 is `b`
204+ // (`a` is the imaginary -0), and, because all the bits are shifted
205+ // by one, `` A` `` is actually 8 and `` Aa `` is -8.
206+ //
207+ // https://rust-lang.github.io/rustc-dev-guide/rustdoc-internals/search.html
208+ // describes the encoding in more detail.
193209 let mut shift: u32 = 28 ;
194210 let mut mask: u32 = 0xF0_00_00_00 ;
195211 while shift < 32 {
@@ -219,8 +235,9 @@ impl IndexItemFunctionType {
219235 string : & mut String ,
220236 backref_queue : & mut VecDeque < & ' a IndexItemFunctionType > ,
221237 ) {
222- assert ! ( backref_queue. len( ) < 16 ) ;
223- // If we couldn't figure out a type, just write `0`.
238+ assert ! ( backref_queue. len( ) <= 16 ) ;
239+ // If we couldn't figure out a type, just write 0,
240+ // which is encoded as `` ` `` (see RenderTypeId::write_to_string).
224241 let has_missing = self
225242 . inputs
226243 . iter ( )
@@ -229,13 +246,15 @@ impl IndexItemFunctionType {
229246 if has_missing {
230247 string. push ( '`' ) ;
231248 } else if let Some ( idx) = backref_queue. iter ( ) . position ( |other| * other == self ) {
249+ // The backref queue has 16 items, so backrefs use
250+ // a single hexit, disjoint from the ones used for numbers.
232251 string. push (
233252 char:: try_from ( '0' as u32 + u32:: try_from ( idx) . unwrap ( ) )
234253 . expect ( "last possible value is '?'" ) ,
235254 ) ;
236255 } else {
237256 backref_queue. push_front ( self ) ;
238- if backref_queue. len ( ) >= 16 {
257+ if backref_queue. len ( ) > 16 {
239258 backref_queue. pop_back ( ) ;
240259 }
241260 string. push ( '{' ) ;
0 commit comments