@@ -28,12 +28,17 @@ use rustc_data_structures::fx::FxIndexSet;
28
28
/// Inline (compressed) format:
29
29
/// - `span.base_or_index == span_data.lo`
30
30
/// - `span.len_or_tag == len == span_data.hi - span_data.lo` (must be `<= MAX_LEN`)
31
- /// - `span.ctxt == span_data.ctxt` (must be `< MAX_CTXT`)
31
+ /// - `span.ctxt_or_tag == span_data.ctxt` (must be `<= MAX_CTXT`)
32
+ ///
33
+ /// Interned format with inline `SyntaxContext`:
34
+ /// - `span.base_or_index == index` (indexes into the interner table)
35
+ /// - `span.len_or_tag == LEN_TAG` (high bit set, all other bits are zero)
36
+ /// - `span.ctxt_or_tag == span_data.ctxt` (must be `<= MAX_CTXT`)
32
37
///
33
38
/// Interned format:
34
39
/// - `span.base_or_index == index` (indexes into the interner table)
35
40
/// - `span.len_or_tag == LEN_TAG` (high bit set, all other bits are zero)
36
- /// - `span.ctxt == span_data.ctxt` (must be < `MAX_CTXT`) or `MAX_CTXT` otherwise
41
+ /// - `span.ctxt_or_tag == CTXT_TAG`
37
42
///
38
43
/// The inline form uses 0 for the tag value (rather than 1) so that we don't
39
44
/// need to mask out the tag bit when getting the length, and so that the
@@ -50,10 +55,10 @@ use rustc_data_structures::fx::FxIndexSet;
50
55
/// at 3 or 4, and then it drops off quickly from 8 onwards. 15 bits is enough
51
56
/// for 99.99%+ of cases, but larger values (sometimes 20+ bits) might occur
52
57
/// dozens of times in a typical crate.
53
- /// - `ctxt ` is 16 bits in `Span` and 32 bits in `SpanData`, which means that
58
+ /// - `ctxt_or_tag ` is 16 bits in `Span` and 32 bits in `SpanData`, which means that
54
59
/// large `ctxt` values will cause interning. The number of bits needed for
55
60
/// `ctxt` values depend partly on the crate size and partly on the form of
56
- /// the code. No crates in `rustc-perf` need more than 15 bits for `ctxt `,
61
+ /// the code. No crates in `rustc-perf` need more than 15 bits for `ctxt_or_tag `,
57
62
/// but larger crates might need more than 16 bits.
58
63
///
59
64
/// In order to reliably use parented spans in incremental compilation,
@@ -65,15 +70,16 @@ use rustc_data_structures::fx::FxIndexSet;
65
70
pub struct Span {
66
71
base_or_index : u32 ,
67
72
len_or_tag : u16 ,
68
- ctxt_or_max : u16 ,
73
+ ctxt_or_tag : u16 ,
69
74
}
70
75
71
76
const LEN_TAG : u16 = 0b1000_0000_0000_0000 ;
72
77
const MAX_LEN : u32 = 0b0111_1111_1111_1111 ;
73
- const MAX_CTXT : u32 = 0b1111_1111_1111_1111 ;
78
+ const CTXT_TAG : u32 = 0b1111_1111_1111_1111 ;
79
+ const MAX_CTXT : u32 = CTXT_TAG - 1 ;
74
80
75
81
/// Dummy span, both position and length are zero, syntax context is zero as well.
76
- pub const DUMMY_SP : Span = Span { base_or_index : 0 , len_or_tag : 0 , ctxt_or_max : 0 } ;
82
+ pub const DUMMY_SP : Span = Span { base_or_index : 0 , len_or_tag : 0 , ctxt_or_tag : 0 } ;
77
83
78
84
impl Span {
79
85
#[ inline]
@@ -89,15 +95,15 @@ impl Span {
89
95
90
96
let ( base, len, ctxt2) = ( lo. 0 , hi. 0 - lo. 0 , ctxt. as_u32 ( ) ) ;
91
97
92
- if len <= MAX_LEN && ctxt2 < MAX_CTXT && parent. is_none ( ) {
98
+ if len <= MAX_LEN && ctxt2 <= MAX_CTXT && parent. is_none ( ) {
93
99
// Inline format.
94
- Span { base_or_index : base, len_or_tag : len as u16 , ctxt_or_max : ctxt2 as u16 }
100
+ Span { base_or_index : base, len_or_tag : len as u16 , ctxt_or_tag : ctxt2 as u16 }
95
101
} else {
96
102
// Interned format.
97
103
let index =
98
104
with_span_interner ( |interner| interner. intern ( & SpanData { lo, hi, ctxt, parent } ) ) ;
99
- let ctxt_or_max = if ctxt2 < MAX_CTXT { ctxt2 } else { MAX_CTXT } as u16 ;
100
- Span { base_or_index : index, len_or_tag : LEN_TAG , ctxt_or_max }
105
+ let ctxt_or_tag = if ctxt2 <= MAX_CTXT { ctxt2 } else { CTXT_TAG } as u16 ;
106
+ Span { base_or_index : index, len_or_tag : LEN_TAG , ctxt_or_tag }
101
107
}
102
108
}
103
109
@@ -120,7 +126,7 @@ impl Span {
120
126
SpanData {
121
127
lo : BytePos ( self . base_or_index ) ,
122
128
hi : BytePos ( self . base_or_index + self . len_or_tag as u32 ) ,
123
- ctxt : SyntaxContext :: from_u32 ( self . ctxt_or_max as u32 ) ,
129
+ ctxt : SyntaxContext :: from_u32 ( self . ctxt_or_tag as u32 ) ,
124
130
parent : None ,
125
131
}
126
132
} else {
@@ -133,10 +139,10 @@ impl Span {
133
139
/// This function is used as a fast path when decoding the full `SpanData` is not necessary.
134
140
#[ inline]
135
141
pub fn ctxt ( self ) -> SyntaxContext {
136
- let ctxt_or_max = self . ctxt_or_max as u32 ;
137
- if ctxt_or_max < MAX_CTXT {
142
+ let ctxt_or_tag = self . ctxt_or_tag as u32 ;
143
+ if ctxt_or_tag <= MAX_CTXT {
138
144
// Inline format or interned format with inline ctxt.
139
- SyntaxContext :: from_u32 ( ctxt_or_max )
145
+ SyntaxContext :: from_u32 ( ctxt_or_tag )
140
146
} else {
141
147
// Interned format.
142
148
let index = self . base_or_index ;
0 commit comments