diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 43900ba88993e..8e5e941fe8562 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3308,7 +3308,7 @@ mod size_asserts { rustc_data_structures::static_assert_size!(super::QPath<'static>, 24); rustc_data_structures::static_assert_size!(super::Ty<'static>, 80); - rustc_data_structures::static_assert_size!(super::Item<'static>, 184); + rustc_data_structures::static_assert_size!(super::Item<'static>, 176); rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 128); rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 152); rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 136); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 823a927fd8c74..115de0c0cda96 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -22,6 +22,7 @@ #![feature(nll)] #![feature(min_specialization)] #![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))] +#![feature(rustc_attrs)] #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 61e4074a7c80b..0aa5b3d27550f 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -72,16 +72,22 @@ use rustc_data_structures::fx::FxIndexSet; // #[cfg_attr(not(bootstrap), rustc_pass_by_value)] pub struct Span { base_or_index: u32, - len_or_tag: u16, + len_or_tag: LenOrTag, ctxt_or_zero: u16, } -const LEN_TAG: u16 = 0b1000_0000_0000_0000; +// LEN_TAG allows for some extra values at the top. Declare them to rustc to use as niches. +#[rustc_layout_scalar_valid_range_end(0b1000_0000_0000_0000)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +struct LenOrTag(u16); + +const LEN_TAG: LenOrTag = unsafe { LenOrTag(0b1000_0000_0000_0000) }; const MAX_LEN: u32 = 0b0111_1111_1111_1111; const MAX_CTXT: u32 = 0b1111_1111_1111_1111; /// Dummy span, both position and length are zero, syntax context is zero as well. -pub const DUMMY_SP: Span = Span { base_or_index: 0, len_or_tag: 0, ctxt_or_zero: 0 }; +pub const DUMMY_SP: Span = + Span { base_or_index: 0, len_or_tag: unsafe { LenOrTag(0) }, ctxt_or_zero: 0 }; impl Span { #[inline] @@ -99,7 +105,11 @@ impl Span { if len <= MAX_LEN && ctxt2 <= MAX_CTXT && parent.is_none() { // Inline format. - Span { base_or_index: base, len_or_tag: len as u16, ctxt_or_zero: ctxt2 as u16 } + Span { + base_or_index: base, + len_or_tag: unsafe { LenOrTag(len as u16) }, + ctxt_or_zero: ctxt2 as u16, + } } else { // Interned format. let index = @@ -123,10 +133,10 @@ impl Span { pub fn data_untracked(self) -> SpanData { if self.len_or_tag != LEN_TAG { // Inline format. - debug_assert!(self.len_or_tag as u32 <= MAX_LEN); + debug_assert!(self.len_or_tag.0 as u32 <= MAX_LEN); SpanData { lo: BytePos(self.base_or_index), - hi: BytePos(self.base_or_index + self.len_or_tag as u32), + hi: BytePos(self.base_or_index + self.len_or_tag.0 as u32), ctxt: SyntaxContext::from_u32(self.ctxt_or_zero as u32), parent: None, }