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)]
91#[rustc_pass_by_value]
92#[repr(packed(4))]
93pub struct Span(u64);
94
95impl !PartialOrd for Span {}
99impl !Ord for Span {}
100
101#[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)]
104struct SpanField {
105 shift: u32,
107 width: u32,
109}
110
111impl SpanField {
112 #[inline]
114 const fn top(width: u32) -> Self {
115 SpanField { shift: 64 - width, width }
116 }
117
118 #[inline]
120 const fn below(self, width: u32) -> Self {
121 SpanField { shift: self.shift - width, width }
122 }
123
124 #[inline]
126 const fn mask(self) -> u64 {
127 (1 << self.width) - 1
128 }
129
130 #[inline]
132 const fn get(self, u: u64) -> u32 {
133 ((u >> self.shift) & self.mask()) as u32
134 }
135
136 #[inline]
138 const fn set(self, v: u32) -> u64 {
139 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);
140 (v as u64) << self.shift
141 }
142
143 #[inline]
145 const fn too_big(self, v: u32) -> u32 {
146 v & !(self.mask() as u32)
147 }
148
149 #[inline]
151 const fn assert_is_bottom(self) {
152 if !(self.shift == 0) {
::core::panicking::panic("assertion failed: self.shift == 0")
};assert!(self.shift == 0);
153 }
154}
155
156#[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)]
159pub(crate) struct InlineCtxt {
160 pub(crate) lo: u32,
161 pub(crate) len: u32,
162 pub(crate) ctxt: u32,
163}
164
165#[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)]
166struct InlineParent {
167 lo: u32,
168 len: u32,
169 parent: u32,
170}
171
172#[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)]
173struct InlinePair {
174 lo: u32,
175 len: u32,
176 ctxt: u32,
177 parent: u32,
178}
179
180#[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)]
181struct Interned {
182 ctxt: u32,
183 index: u32,
184}
185
186impl InlineCtxt {
187 const PREFIX_VALUE: u32 = 0b0;
188 const PREFIX: SpanField = SpanField::top(1);
189 const LEN: SpanField = Self::PREFIX.below(15);
190 const CTXT: SpanField = Self::LEN.below(16);
191 const LO: SpanField = Self::CTXT.below(32);
192
193 #[inline]
194 pub(crate) const fn try_new_span(lo: u32, len: u32, ctxt: u32) -> Option<Span> {
195 if Self::LEN.too_big(len) | Self::CTXT.too_big(ctxt) == 0 {
196 Some(Span(
197 Self::PREFIX.set(Self::PREFIX_VALUE)
198 | Self::LEN.set(len)
199 | Self::CTXT.set(ctxt)
200 | Self::LO.set(lo),
201 ))
202 } else {
203 None
204 }
205 }
206
207 #[inline]
208 fn data(self) -> SpanData {
209 SpanData {
210 lo: BytePos(self.lo),
211 hi: BytePos(self.lo.debug_strict_add(self.len)),
212 ctxt: SyntaxContext::from_u32(self.ctxt),
213 parent: None,
214 }
215 }
216
217 #[inline]
218 fn from_span(span: Span) -> InlineCtxt {
219 let u = span.0;
220 Self { lo: Self::LO.get(u), len: Self::LEN.get(u), ctxt: Self::CTXT.get(u) }
221 }
222
223 #[inline]
224 pub(crate) fn try_from_span(span: Span) -> Option<InlineCtxt> {
225 if Self::PREFIX.get(span.0) == Self::PREFIX_VALUE {
226 Some(Self::from_span(span))
227 } else {
228 None
229 }
230 }
231}
232const _: () = InlineCtxt::LO.assert_is_bottom();
233
234impl InlineParent {
235 const PREFIX_VALUE: u32 = 0b110;
236 const PREFIX: SpanField = SpanField::top(3);
237 const LEN: SpanField = Self::PREFIX.below(14);
238 const PARENT: SpanField = Self::LEN.below(15);
239 const LO: SpanField = Self::PARENT.below(32);
240
241 #[inline]
242 fn try_new_span(lo: u32, len: u32, ctxt: u32, parent: u32) -> Option<Span> {
243 if Self::LEN.too_big(len) | ctxt | Self::PARENT.too_big(parent) == 0 {
244 Some(Span(
245 Self::PREFIX.set(Self::PREFIX_VALUE)
246 | Self::LEN.set(len)
247 | Self::PARENT.set(parent)
248 | Self::LO.set(lo),
249 ))
250 } else {
251 None
252 }
253 }
254
255 #[inline]
256 fn data(self) -> SpanData {
257 SpanData {
258 lo: BytePos(self.lo),
259 hi: BytePos(self.lo.debug_strict_add(self.len)),
260 ctxt: SyntaxContext::root(),
261 parent: Some(LocalDefId { local_def_index: DefIndex::from_u32(self.parent) }),
262 }
263 }
264
265 #[inline]
266 fn from_span(span: Span) -> InlineParent {
267 let u = span.0;
268 Self { lo: Self::LO.get(u), len: Self::LEN.get(u), parent: Self::PARENT.get(u) }
269 }
270}
271const _: () = InlineParent::LO.assert_is_bottom();
272
273impl InlinePair {
274 const PREFIX_VALUE: u32 = 0b10;
275 const PREFIX: SpanField = SpanField::top(2);
276 const LEN: SpanField = Self::PREFIX.below(7);
277 const CTXT: SpanField = Self::LEN.below(15);
278 const PARENT: SpanField = Self::CTXT.below(16);
279 const LO: SpanField = Self::PARENT.below(24);
280
281 #[inline]
282 fn try_new_span(lo: u32, len: u32, ctxt: u32, parent: u32) -> Option<Span> {
283 if Self::LO.too_big(lo)
284 | Self::LEN.too_big(len)
285 | Self::CTXT.too_big(ctxt)
286 | Self::PARENT.too_big(parent)
287 == 0
288 {
289 Some(Span(
290 Self::PREFIX.set(Self::PREFIX_VALUE)
291 | Self::LEN.set(len)
292 | Self::CTXT.set(ctxt)
293 | Self::PARENT.set(parent)
294 | Self::LO.set(lo),
295 ))
296 } else {
297 None
298 }
299 }
300
301 #[inline]
302 fn data(self) -> SpanData {
303 SpanData {
304 lo: BytePos(self.lo),
305 hi: BytePos(self.lo.debug_strict_add(self.len)),
306 ctxt: SyntaxContext::from_u32(self.ctxt),
307 parent: Some(LocalDefId { local_def_index: DefIndex::from_u32(self.parent) }),
308 }
309 }
310
311 #[inline]
312 fn from_span(span: Span) -> InlinePair {
313 let u = span.0;
314 Self {
315 lo: Self::LO.get(u),
316 len: Self::LEN.get(u),
317 ctxt: Self::CTXT.get(u),
318 parent: Self::PARENT.get(u),
319 }
320 }
321}
322const _: () = InlinePair::LO.assert_is_bottom();
323
324impl Interned {
325 const PREFIX_VALUE: u32 = 0b111;
326 const PREFIX: SpanField = SpanField::top(3);
327 const CTXT: SpanField = Self::PREFIX.below(29);
328 const INDEX: SpanField = Self::CTXT.below(32);
329
330 #[inline]
331 fn new_span(ctxt: u32, index: u32) -> Span {
332 Span(Self::PREFIX.set(Self::PREFIX_VALUE) | Self::CTXT.set(ctxt) | Self::INDEX.set(index))
333 }
334
335 #[inline]
336 fn data(self) -> SpanData {
337 #[cold]
338 #[inline(never)]
339 fn interned(index: u32) -> SpanDataNoCtxt {
340 with_span_interner(|interner| interner.spans[index as usize])
341 }
342
343 let SpanDataNoCtxt { lo, hi, parent } = interned(self.index);
344 SpanData { lo, hi, ctxt: SyntaxContext::from_u32(self.ctxt), parent }
345 }
346
347 #[inline]
348 fn from_span(span: Span) -> Interned {
349 let u = span.0;
350 Self { ctxt: Self::CTXT.get(u), index: Self::INDEX.get(u) }
351 }
352}
353const _: () = Interned::INDEX.assert_is_bottom();
354
355macro_rules! match_span_kind {
359 (
360 $span:expr,
361 InlineCtxt($span1:ident) => $arm1:expr,
362 InlineParent($span2:ident) => $arm2:expr,
363 InlinePair($span3:ident) => $arm3:expr,
364 Interned($span4:ident) => $arm4:expr,
365 ) => {{
366 let span64 = $span.0;
367 if InlineCtxt::PREFIX.get(span64) == InlineCtxt::PREFIX_VALUE {
368 let $span1 = InlineCtxt::from_span($span);
369 $arm1
370 } else if InlineParent::PREFIX.get(span64) == InlineParent::PREFIX_VALUE {
371 let $span2 = InlineParent::from_span($span);
372 $arm2
373 } else if InlinePair::PREFIX.get(span64) == InlinePair::PREFIX_VALUE {
374 let $span3 = InlinePair::from_span($span);
375 $arm3
376 } else {
377 let $span4 = Interned::from_span($span);
378 $arm4
379 }
380 }};
381}
382
383pub const DUMMY_SP: Span = InlineCtxt::try_new_span(0, 0, 0).unwrap();
385
386impl Span {
387 #[inline]
391 pub fn new(
392 mut lo: BytePos,
393 mut hi: BytePos,
394 ctxt: SyntaxContext,
395 parent: Option<LocalDefId>,
396 ) -> Self {
397 if lo > hi {
398 std::mem::swap(&mut lo, &mut hi);
399 }
400 Span::new_ordered(lo, hi, ctxt, parent)
401 }
402
403 #[inline]
407 pub fn new_ordered(
408 lo: BytePos,
409 hi: BytePos,
410 ctxt: SyntaxContext,
411 parent: Option<LocalDefId>,
412 ) -> Self {
413 #[cold]
414 #[inline(never)]
415 fn interned(lo: BytePos, hi: BytePos, ctxt: u32, parent: Option<LocalDefId>) -> Span {
416 {
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 =
419 with_span_interner(|interner| interner.intern(&SpanDataNoCtxt { lo, hi, parent }));
420 Interned::new_span(ctxt, index)
421 }
422
423 if true {
if !(lo <= hi) { ::core::panicking::panic("assertion failed: lo <= hi") };
};debug_assert!(lo <= hi);
424
425 let lo32 = lo.0;
426 let (len, ctxt32) = (hi.0 - lo32, ctxt.as_u32());
427 if let Some(parent) = parent {
428 if let Some(span) = Span::try_new_span_with_parent(lo32, len, ctxt32, parent) {
429 return span;
431 }
432 } else if let Some(span) = InlineCtxt::try_new_span(lo32, len, ctxt32) {
433 return span;
435 }
436
437 interned(lo, hi, ctxt32, parent)
438 }
439
440 #[inline]
443 fn try_new_span_with_parent(lo: u32, len: u32, ctxt: u32, parent: LocalDefId) -> Option<Self> {
444 let parent = parent.local_def_index.as_u32();
445 InlineParent::try_new_span(lo, len, ctxt, parent)
446 .or_else(|| InlinePair::try_new_span(lo, len, ctxt, parent))
447 }
448
449 #[inline]
450 pub fn data(self) -> SpanData {
451 let data = self.data_untracked();
452 if let Some(parent) = data.parent {
453 (*SPAN_TRACK)(parent);
454 }
455 data
456 }
457
458 #[inline]
461 pub fn data_untracked(self) -> SpanData {
462 {
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! {
463 self,
464 InlineCtxt(span) => span.data(),
465 InlineParent(span) => span.data(),
466 InlinePair(span) => span.data(),
467 Interned(span) => span.data(),
468 }
469 }
470
471 #[inline]
473 pub fn from_expansion(self) -> bool {
474 !self.ctxt().is_root()
475 }
476
477 #[inline]
480 pub fn is_dummy(self) -> bool {
481 {
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); span.data().is_dummy() }
}match_span_kind! {
482 self,
483 InlineCtxt(span) => span.lo == 0 && span.len == 0,
484 InlineParent(span) => span.lo == 0 && span.len == 0,
485 InlinePair(span) => span.lo == 0 && span.len == 0,
486 Interned(span) => span.data().is_dummy(),
487 }
488 }
489
490 #[inline]
491 pub fn map_ctxt(self, map: impl FnOnce(SyntaxContext) -> SyntaxContext) -> Span {
492 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! {
493 self,
494 InlineCtxt(span) => {
495 let new_ctxt = map(SyntaxContext::from_u32(span.ctxt));
498 let new_ctxt32 = new_ctxt.as_u32();
499 return if let Some(span) = InlineCtxt::try_new_span(span.lo, span.len, new_ctxt32) {
500 span
501 } else {
502 span.data().with_ctxt(new_ctxt)
503 };
504 },
505 InlineParent(span) => span.data(),
506 InlinePair(span) => span.data(),
507 Interned(span) => span.data(),
508 };
509
510 data.with_ctxt(map(data.ctxt))
511 }
512
513 #[inline]
516 pub fn ctxt(self) -> SyntaxContext {
517 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! {
518 self,
519 InlineCtxt(span) => span.ctxt,
520 InlineParent(_span) => return SyntaxContext::root(),
521 InlinePair(span) => span.ctxt,
522 Interned(span) => span.ctxt,
523 };
524 SyntaxContext::from_u32(ctxt32)
525 }
526
527 #[inline]
528 pub fn with_parent(self, parent: Option<LocalDefId>) -> Span {
529 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! {
530 self,
531 InlineCtxt(span) => {
532 match parent {
535 None => return self,
536 Some(parent)
537 if let Some(span) =
538 Span::try_new_span_with_parent(span.lo, span.len, span.ctxt, parent) =>
539 {
540 return span;
541 }
542 _ => span.data(),
543 }
544 },
545 InlineParent(span) => span.data(),
546 InlinePair(span) => span.data(),
547 Interned(span) => span.data(),
548 };
549
550 if let Some(old_parent) = data.parent {
551 (*SPAN_TRACK)(old_parent);
552 }
553 data.with_parent(parent)
554 }
555
556 #[inline]
557 pub fn parent(self) -> Option<LocalDefId> {
558 let to_parent = |parent| Some(LocalDefId { local_def_index: DefIndex::from_u32(parent) });
559 {
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); span.data().parent }
}match_span_kind! {
560 self,
561 InlineCtxt(_span) => None,
562 InlineParent(span) => to_parent(span.parent),
563 InlinePair(span) => to_parent(span.parent),
564 Interned(span) => span.data().parent,
565 }
566 }
567
568 #[inline]
569 pub(crate) fn to_raw_span(self) -> RawSpan {
570 RawSpan(self.0)
571 }
572
573 #[inline]
574 pub fn from_raw_span(RawSpan(a): RawSpan) -> Span {
575 Span(a)
576 }
577}
578
579#[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_struct_field1_finish(f, "OrdSpan",
&&self.0)
}
}Debug)]
583pub struct OrdSpan(pub Span);
584
585impl PartialEq for OrdSpan {
586 fn eq(&self, rhs: &Self) -> bool {
587 self.0.lo_hi() == rhs.0.lo_hi()
589 }
590}
591
592impl Eq for OrdSpan {}
593
594impl PartialOrd for OrdSpan {
595 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
596 Some(self.cmp(rhs))
597 }
598}
599
600impl Ord for OrdSpan {
601 fn cmp(&self, rhs: &Self) -> Ordering {
602 self.0.lo_hi().cmp(&rhs.0.lo_hi())
604 }
605}
606
607impl !Hash for OrdSpan {}
610
611#[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)]
614struct SpanDataNoCtxt {
615 lo: BytePos,
616 hi: BytePos,
617 parent: Option<LocalDefId>,
618}
619
620#[derive(#[automatically_derived]impl ::core::default::Default for SpanInterner {
#[inline]
fn default() -> Self {
SpanInterner { spans: ::core::default::Default::default() }
}
}Default)]
621pub(crate) struct SpanInterner {
622 spans: FxIndexSet<SpanDataNoCtxt>,
623}
624
625impl SpanInterner {
626 fn intern(&mut self, span_data_no_ctxt: &SpanDataNoCtxt) -> u32 {
627 let (index, _) = self.spans.insert_full(*span_data_no_ctxt);
628 index as u32
629 }
630}
631
632#[inline]
634fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
635 crate::with_session_globals(|session_globals| f(&mut session_globals.span_interner.lock()))
636}