1use std::cmp::Ordering;
2use std::hash::Hash;
3
4use rustc_data_structures::fx::FxIndexSet;
5use rustc_data_structures::stable_hash::RawSpan;
6use rustc_serialize::int_overflow::DebugStrictAdd;
9
10use crate::def_id::{DefIndex, LocalDefId};
11use crate::hygiene::SyntaxContext;
12use crate::{BytePos, SPAN_TRACK, SpanData};
13
14#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Span { }
#[automatically_derived]
impl ::core::clone::Clone for Span {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u64>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Span { }Copy, #[automatically_derived]
impl ::core::cmp::Eq for Span {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u64>;
}
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Span { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Span {
#[inline]
fn eq(&self, other: &Self) -> bool { ({ self.0 }) == ({ other.0 }) }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Span {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&{ self.0 }, state)
}
}Hash)]
87#[rustc_pass_by_value]
88#[repr(packed(4))]
89pub struct Span(u64);
90
91impl !PartialOrd for Span {}
95impl !Ord for Span {}
96
97#[derive(#[automatically_derived]
impl ::core::marker::Copy for SpanField { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SpanField { }
#[automatically_derived]
impl ::core::clone::Clone for SpanField {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone)]
100struct SpanField {
101 shift: u32,
103 width: u32,
105}
106
107impl SpanField {
108 #[inline]
110 const fn top(width: u32) -> Self {
111 SpanField { shift: 64 - width, width }
112 }
113
114 #[inline]
116 const fn below(self, width: u32) -> Self {
117 SpanField { shift: self.shift - width, width }
118 }
119
120 #[inline]
122 const fn mask(self) -> u64 {
123 (1 << self.width) - 1
124 }
125
126 #[inline]
128 const fn get(self, u: u64) -> u32 {
129 ((u >> self.shift) & self.mask()) as u32
130 }
131
132 #[inline]
134 const fn set(self, v: u32) -> u64 {
135 if true {
if !(v <= self.mask() as u32) {
::core::panicking::panic("assertion failed: v <= self.mask() as u32")
};
};debug_assert!(v <= self.mask() as u32);
136 (v as u64) << self.shift
137 }
138
139 #[inline]
141 const fn too_big(self, v: u32) -> u32 {
142 v & !(self.mask() as u32)
143 }
144
145 #[inline]
147 const fn assert_is_bottom(self) {
148 if !(self.shift == 0) {
::core::panicking::panic("assertion failed: self.shift == 0")
};assert!(self.shift == 0);
149 }
150}
151
152#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InlineCtxt { }
#[automatically_derived]
impl ::core::clone::Clone for InlineCtxt {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InlineCtxt { }Copy)]
154struct InlineCtxt {
155 lo: u32,
156 len: u32,
157 ctxt: u32,
158}
159
160#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InlineParent { }
#[automatically_derived]
impl ::core::clone::Clone for InlineParent {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InlineParent { }Copy)]
161struct InlineParent {
162 lo: u32,
163 len: u32,
164 parent: u32,
165}
166
167#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InlinePair { }
#[automatically_derived]
impl ::core::clone::Clone for InlinePair {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InlinePair { }Copy)]
168struct InlinePair {
169 lo: u32,
170 len: u32,
171 ctxt: u32,
172 parent: u32,
173}
174
175#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Interned { }
#[automatically_derived]
impl ::core::clone::Clone for Interned {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Interned { }Copy)]
176struct Interned {
177 ctxt: u32,
178 index: u32,
179}
180
181impl InlineCtxt {
182 const PREFIX_VALUE: u32 = 0b0;
183 const PREFIX: SpanField = SpanField::top(1);
184 const LEN: SpanField = Self::PREFIX.below(15);
185 const CTXT: SpanField = Self::LEN.below(16);
186 const LO: SpanField = Self::CTXT.below(32);
187
188 #[inline]
189 const fn try_new_span(lo: u32, len: u32, ctxt: u32) -> Option<Span> {
190 if Self::LEN.too_big(len) | Self::CTXT.too_big(ctxt) == 0 {
191 Some(Span(
192 Self::PREFIX.set(Self::PREFIX_VALUE)
193 | Self::LEN.set(len)
194 | Self::CTXT.set(ctxt)
195 | Self::LO.set(lo),
196 ))
197 } else {
198 None
199 }
200 }
201
202 #[inline]
203 fn data(self) -> SpanData {
204 SpanData {
205 lo: BytePos(self.lo),
206 hi: BytePos(self.lo.debug_strict_add(self.len)),
207 ctxt: SyntaxContext::from_u32(self.ctxt),
208 parent: None,
209 }
210 }
211
212 #[inline]
213 fn from_span(span: Span) -> InlineCtxt {
214 let u = span.0;
215 Self { lo: Self::LO.get(u), len: Self::LEN.get(u), ctxt: Self::CTXT.get(u) }
216 }
217}
218const _: () = InlineCtxt::LO.assert_is_bottom();
219
220impl InlineParent {
221 const PREFIX_VALUE: u32 = 0b110;
222 const PREFIX: SpanField = SpanField::top(3);
223 const LEN: SpanField = Self::PREFIX.below(14);
224 const PARENT: SpanField = Self::LEN.below(15);
225 const LO: SpanField = Self::PARENT.below(32);
226
227 #[inline]
228 fn try_new_span(lo: u32, len: u32, ctxt: u32, parent: u32) -> Option<Span> {
229 if Self::LEN.too_big(len) | ctxt | Self::PARENT.too_big(parent) == 0 {
230 Some(Span(
231 Self::PREFIX.set(Self::PREFIX_VALUE)
232 | Self::LEN.set(len)
233 | Self::PARENT.set(parent)
234 | Self::LO.set(lo),
235 ))
236 } else {
237 None
238 }
239 }
240
241 #[inline]
242 fn data(self) -> SpanData {
243 SpanData {
244 lo: BytePos(self.lo),
245 hi: BytePos(self.lo.debug_strict_add(self.len)),
246 ctxt: SyntaxContext::root(),
247 parent: Some(LocalDefId { local_def_index: DefIndex::from_u32(self.parent) }),
248 }
249 }
250
251 #[inline]
252 fn from_span(span: Span) -> InlineParent {
253 let u = span.0;
254 Self { lo: Self::LO.get(u), len: Self::LEN.get(u), parent: Self::PARENT.get(u) }
255 }
256}
257const _: () = InlineParent::LO.assert_is_bottom();
258
259impl InlinePair {
260 const PREFIX_VALUE: u32 = 0b10;
261 const PREFIX: SpanField = SpanField::top(2);
262 const LEN: SpanField = Self::PREFIX.below(7);
263 const CTXT: SpanField = Self::LEN.below(15);
264 const PARENT: SpanField = Self::CTXT.below(16);
265 const LO: SpanField = Self::PARENT.below(24);
266
267 #[inline]
268 fn try_new_span(lo: u32, len: u32, ctxt: u32, parent: u32) -> Option<Span> {
269 if Self::LO.too_big(lo)
270 | Self::LEN.too_big(len)
271 | Self::CTXT.too_big(ctxt)
272 | Self::PARENT.too_big(parent)
273 == 0
274 {
275 Some(Span(
276 Self::PREFIX.set(Self::PREFIX_VALUE)
277 | Self::LEN.set(len)
278 | Self::CTXT.set(ctxt)
279 | Self::PARENT.set(parent)
280 | Self::LO.set(lo),
281 ))
282 } else {
283 None
284 }
285 }
286
287 #[inline]
288 fn data(self) -> SpanData {
289 SpanData {
290 lo: BytePos(self.lo),
291 hi: BytePos(self.lo.debug_strict_add(self.len)),
292 ctxt: SyntaxContext::from_u32(self.ctxt),
293 parent: Some(LocalDefId { local_def_index: DefIndex::from_u32(self.parent) }),
294 }
295 }
296
297 #[inline]
298 fn from_span(span: Span) -> InlinePair {
299 let u = span.0;
300 Self {
301 lo: Self::LO.get(u),
302 len: Self::LEN.get(u),
303 ctxt: Self::CTXT.get(u),
304 parent: Self::PARENT.get(u),
305 }
306 }
307}
308const _: () = InlinePair::LO.assert_is_bottom();
309
310impl Interned {
311 const PREFIX_VALUE: u32 = 0b111;
312 const PREFIX: SpanField = SpanField::top(3);
313 const CTXT: SpanField = Self::PREFIX.below(29);
314 const INDEX: SpanField = Self::CTXT.below(32);
315
316 #[inline]
317 fn new_span(ctxt: u32, index: u32) -> Span {
318 Span(Self::PREFIX.set(Self::PREFIX_VALUE) | Self::CTXT.set(ctxt) | Self::INDEX.set(index))
319 }
320
321 #[inline]
322 fn data(self) -> SpanData {
323 let SpanDataNoCtxt { lo, hi, parent } =
324 with_span_interner(|interner| interner.spans[self.index as usize]);
325 SpanData { lo, hi, ctxt: SyntaxContext::from_u32(self.ctxt), parent }
326 }
327
328 #[inline]
329 fn from_span(span: Span) -> Interned {
330 let u = span.0;
331 Self { ctxt: Self::CTXT.get(u), index: Self::INDEX.get(u) }
332 }
333}
334const _: () = Interned::INDEX.assert_is_bottom();
335
336macro_rules! match_span_kind {
340 (
341 $span:expr,
342 InlineCtxt($span1:ident) => $arm1:expr,
343 InlineParent($span2:ident) => $arm2:expr,
344 InlinePair($span3:ident) => $arm3:expr,
345 Interned($span4:ident) => $arm4:expr,
346 ) => {{
347 let span64 = $span.0;
348 if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
349 let $span1 = InlineCtxt::from_span($span);
350 $arm1
351 } else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
352 let $span2 = InlineParent::from_span($span);
353 $arm2
354 } else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
355 let $span3 = InlinePair::from_span($span);
356 $arm3
357 } else {
358 let $span4 = Interned::from_span($span);
359 $arm4
360 }
361 }};
362}
363
364pub const DUMMY_SP: Span = InlineCtxt::try_new_span(0, 0, 0).unwrap();
366
367impl Span {
368 #[inline]
369 pub fn new(
370 mut lo: BytePos,
371 mut hi: BytePos,
372 ctxt: SyntaxContext,
373 parent: Option<LocalDefId>,
374 ) -> Self {
375 #[cold]
376 #[inline(never)]
377 fn interned(lo: BytePos, hi: BytePos, ctxt: u32, parent: Option<LocalDefId>) -> Span {
378 {
match (&Interned::CTXT.too_big(ctxt), &0) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(Interned::CTXT.too_big(ctxt), 0); let index =
381 with_span_interner(|interner| interner.intern(&SpanDataNoCtxt { lo, hi, parent }));
382 Interned::new_span(ctxt, index)
383 }
384
385 if lo > hi {
386 std::mem::swap(&mut lo, &mut hi);
387 }
388
389 let lo32 = lo.0;
390 let (len, ctxt32) = (hi.0 - lo32, ctxt.as_u32());
391 if let Some(parent) = parent {
392 if let Some(span) = Span::try_new_span_with_parent(lo32, len, ctxt32, parent) {
393 return span;
395 }
396 } else if let Some(span) = InlineCtxt::try_new_span(lo32, len, ctxt32) {
397 return span;
399 }
400
401 interned(lo, hi, ctxt32, parent)
402 }
403
404 #[inline]
407 fn try_new_span_with_parent(lo: u32, len: u32, ctxt: u32, parent: LocalDefId) -> Option<Self> {
408 let parent = parent.local_def_index.as_u32();
409 InlineParent::try_new_span(lo, len, ctxt, parent)
410 .or_else(|| InlinePair::try_new_span(lo, len, ctxt, parent))
411 }
412
413 #[inline]
414 pub fn data(self) -> SpanData {
415 let data = self.data_untracked();
416 if let Some(parent) = data.parent {
417 (*SPAN_TRACK)(parent);
418 }
419 data
420 }
421
422 #[inline]
425 pub fn data_untracked(self) -> SpanData {
426 {
let span64 = self.0;
if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
let span = InlineCtxt::from_span(self);
span.data()
} else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
let span = InlineParent::from_span(self);
span.data()
} else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
let span = InlinePair::from_span(self);
span.data()
} else { let span = Interned::from_span(self); span.data() }
}match_span_kind! {
427 self,
428 InlineCtxt(span) => span.data(),
429 InlineParent(span) => span.data(),
430 InlinePair(span) => span.data(),
431 Interned(span) => span.data(),
432 }
433 }
434
435 #[inline]
437 pub fn from_expansion(self) -> bool {
438 !self.ctxt().is_root()
439 }
440
441 #[inline]
444 pub fn is_dummy(self) -> bool {
445 {
let span64 = self.0;
if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
let span = InlineCtxt::from_span(self);
span.lo == 0 && span.len == 0
} else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
let span = InlineParent::from_span(self);
span.lo == 0 && span.len == 0
} else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
let span = InlinePair::from_span(self);
span.lo == 0 && span.len == 0
} else {
let span = Interned::from_span(self);
{
let data =
with_span_interner(|interner|
interner.spans[span.index as usize]);
data.lo == BytePos(0) && data.hi == BytePos(0)
}
}
}match_span_kind! {
446 self,
447 InlineCtxt(span) => span.lo == 0 && span.len == 0,
448 InlineParent(span) => span.lo == 0 && span.len == 0,
449 InlinePair(span) => span.lo == 0 && span.len == 0,
450 Interned(span) => {
451 let data = with_span_interner(|interner| interner.spans[span.index as usize]);
452 data.lo == BytePos(0) && data.hi == BytePos(0)
453 },
454 }
455 }
456
457 #[inline]
458 pub fn map_ctxt(self, map: impl FnOnce(SyntaxContext) -> SyntaxContext) -> Span {
459 let data = {
let span64 = self.0;
if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
let span = InlineCtxt::from_span(self);
{
let new_ctxt = map(SyntaxContext::from_u32(span.ctxt));
let new_ctxt32 = new_ctxt.as_u32();
return if let Some(span) =
InlineCtxt::try_new_span(span.lo, span.len, new_ctxt32) {
span
} else { span.data().with_ctxt(new_ctxt) };
}
} else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
let span = InlineParent::from_span(self);
span.data()
} else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
let span = InlinePair::from_span(self);
span.data()
} else { let span = Interned::from_span(self); span.data() }
}match_span_kind! {
460 self,
461 InlineCtxt(span) => {
462 let new_ctxt = map(SyntaxContext::from_u32(span.ctxt));
465 let new_ctxt32 = new_ctxt.as_u32();
466 return if let Some(span) = InlineCtxt::try_new_span(span.lo, span.len, new_ctxt32) {
467 span
468 } else {
469 span.data().with_ctxt(new_ctxt)
470 };
471 },
472 InlineParent(span) => span.data(),
473 InlinePair(span) => span.data(),
474 Interned(span) => span.data(),
475 };
476
477 data.with_ctxt(map(data.ctxt))
478 }
479
480 #[inline]
483 pub fn ctxt(self) -> SyntaxContext {
484 let ctxt32 = {
let span64 = self.0;
if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
let span = InlineCtxt::from_span(self);
span.ctxt
} else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
let _span = InlineParent::from_span(self);
return SyntaxContext::root()
} else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
let span = InlinePair::from_span(self);
span.ctxt
} else { let span = Interned::from_span(self); span.ctxt }
}match_span_kind! {
485 self,
486 InlineCtxt(span) => span.ctxt,
487 InlineParent(_span) => return SyntaxContext::root(),
488 InlinePair(span) => span.ctxt,
489 Interned(span) => span.ctxt,
490 };
491 SyntaxContext::from_u32(ctxt32)
492 }
493
494 #[inline]
497 pub fn eq_ctxt(self, other: Span) -> bool {
498 self.ctxt() == other.ctxt()
499 }
500
501 #[inline]
502 pub fn with_parent(self, parent: Option<LocalDefId>) -> Span {
503 let data = {
let span64 = self.0;
if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
let span = InlineCtxt::from_span(self);
{
match parent {
None => return self,
Some(parent) if
let Some(span) =
Span::try_new_span_with_parent(span.lo, span.len, span.ctxt,
parent) => {
return span;
}
_ => span.data(),
}
}
} else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
let span = InlineParent::from_span(self);
span.data()
} else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
let span = InlinePair::from_span(self);
span.data()
} else { let span = Interned::from_span(self); span.data() }
}match_span_kind! {
504 self,
505 InlineCtxt(span) => {
506 match parent {
509 None => return self,
510 Some(parent)
511 if let Some(span) =
512 Span::try_new_span_with_parent(span.lo, span.len, span.ctxt, parent) =>
513 {
514 return span;
515 }
516 _ => span.data(),
517 }
518 },
519 InlineParent(span) => span.data(),
520 InlinePair(span) => span.data(),
521 Interned(span) => span.data(),
522 };
523
524 if let Some(old_parent) = data.parent {
525 (*SPAN_TRACK)(old_parent);
526 }
527 data.with_parent(parent)
528 }
529
530 #[inline]
531 pub fn parent(self) -> Option<LocalDefId> {
532 let to_parent = |parent| Some(LocalDefId { local_def_index: DefIndex::from_u32(parent) });
533 {
let span64 = self.0;
if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
let _span = InlineCtxt::from_span(self);
None
} else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
let span = InlineParent::from_span(self);
to_parent(span.parent)
} else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
let span = InlinePair::from_span(self);
to_parent(span.parent)
} else {
let span = Interned::from_span(self);
{
with_span_interner(|interner|
interner.spans[span.index as usize].parent)
}
}
}match_span_kind! {
534 self,
535 InlineCtxt(_span) => None,
536 InlineParent(span) => to_parent(span.parent),
537 InlinePair(span) => to_parent(span.parent),
538 Interned(span) => {
539 with_span_interner(|interner| interner.spans[span.index as usize].parent)
540 },
541 }
542 }
543
544 #[inline]
545 pub(crate) fn to_raw_span(self) -> RawSpan {
546 RawSpan(self.0)
547 }
548
549 #[inline]
550 pub fn from_raw_span(RawSpan(a): RawSpan) -> Span {
551 Span(a)
552 }
553}
554
555#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OrdSpan { }
#[automatically_derived]
impl ::core::clone::Clone for OrdSpan {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OrdSpan { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for OrdSpan {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "OrdSpan",
&&self.0)
}
}Debug)]
559pub struct OrdSpan(pub Span);
560
561impl PartialEq for OrdSpan {
562 fn eq(&self, rhs: &Self) -> bool {
563 self.0.lo_hi() == rhs.0.lo_hi()
565 }
566}
567
568impl Eq for OrdSpan {}
569
570impl PartialOrd for OrdSpan {
571 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
572 Some(self.cmp(rhs))
573 }
574}
575
576impl Ord for OrdSpan {
577 fn cmp(&self, rhs: &Self) -> Ordering {
578 self.0.lo_hi().cmp(&rhs.0.lo_hi())
580 }
581}
582
583impl !Hash for OrdSpan {}
586
587#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SpanDataNoCtxt { }
#[automatically_derived]
impl ::core::clone::Clone for SpanDataNoCtxt {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<BytePos>;
let _: ::core::clone::AssertParamIsClone<Option<LocalDefId>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SpanDataNoCtxt { }Copy, #[automatically_derived]
impl ::core::hash::Hash for SpanDataNoCtxt {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.lo, state);
::core::hash::Hash::hash(&self.hi, state);
::core::hash::Hash::hash(&self.parent, state)
}
}Hash, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for SpanDataNoCtxt { }
#[automatically_derived]
impl ::core::cmp::PartialEq for SpanDataNoCtxt {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.lo == other.lo && self.hi == other.hi &&
self.parent == other.parent
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SpanDataNoCtxt {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<BytePos>;
let _: ::core::cmp::AssertParamIsEq<Option<LocalDefId>>;
}
}Eq)]
590struct SpanDataNoCtxt {
591 lo: BytePos,
592 hi: BytePos,
593 parent: Option<LocalDefId>,
594}
595
596#[derive(#[automatically_derived]
impl ::core::default::Default for SpanInterner {
#[inline]
fn default() -> Self {
SpanInterner { spans: ::core::default::Default::default() }
}
}Default)]
597pub(crate) struct SpanInterner {
598 spans: FxIndexSet<SpanDataNoCtxt>,
599}
600
601impl SpanInterner {
602 fn intern(&mut self, span_data_no_ctxt: &SpanDataNoCtxt) -> u32 {
603 let (index, _) = self.spans.insert_full(*span_data_no_ctxt);
604 index as u32
605 }
606}
607
608#[inline]
610fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
611 crate::with_session_globals(|session_globals| f(&mut session_globals.span_interner.lock()))
612}