Skip to content

Commit 273fb2a

Browse files
nnethercotecjgillot
andcommitted
Tell rustc about unused bits in Span.
This shrinks the size of `Option<Span>` and similar types, which shrinks several AST and HIR nodes. The most important of these are `hir::Expr` and `ast::Ty`. This change was first attempted in rust-lang#93747 where it had little effect. But the improved niche-filling implemented by rust-lang#94075 means this change now has a much bigger effect. Co-authored-by: Camille Gillot <[email protected]>
1 parent bf286a8 commit 273fb2a

File tree

5 files changed

+118
-108
lines changed

5 files changed

+118
-108
lines changed

compiler/rustc_ast/src/ast.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -3040,19 +3040,19 @@ mod size_asserts {
30403040
use super::*;
30413041
use rustc_data_structures::static_assert_size;
30423042
// tidy-alphabetical-start
3043-
static_assert_size!(AssocItem, 104);
3044-
static_assert_size!(AssocItemKind, 32);
3043+
static_assert_size!(AssocItem, 96);
3044+
static_assert_size!(AssocItemKind, 24);
30453045
static_assert_size!(Attribute, 32);
30463046
static_assert_size!(Block, 48);
30473047
static_assert_size!(Expr, 104);
30483048
static_assert_size!(ExprKind, 72);
3049-
static_assert_size!(Fn, 184);
3049+
static_assert_size!(Fn, 168);
30503050
static_assert_size!(ForeignItem, 96);
30513051
static_assert_size!(ForeignItemKind, 24);
30523052
static_assert_size!(GenericArg, 24);
30533053
static_assert_size!(GenericBound, 88);
30543054
static_assert_size!(Generics, 72);
3055-
static_assert_size!(Impl, 200);
3055+
static_assert_size!(Impl, 184);
30563056
static_assert_size!(Item, 184);
30573057
static_assert_size!(ItemKind, 112);
30583058
static_assert_size!(Lit, 48);
@@ -3065,7 +3065,7 @@ mod size_asserts {
30653065
static_assert_size!(PatKind, 96);
30663066
static_assert_size!(Stmt, 32);
30673067
static_assert_size!(StmtKind, 16);
3068-
static_assert_size!(Ty, 96);
3069-
static_assert_size!(TyKind, 72);
3068+
static_assert_size!(Ty, 88);
3069+
static_assert_size!(TyKind, 64);
30703070
// tidy-alphabetical-end
30713071
}

compiler/rustc_hir/src/hir.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -3517,20 +3517,20 @@ mod size_asserts {
35173517
// tidy-alphabetical-start
35183518
static_assert_size!(Block<'_>, 48);
35193519
static_assert_size!(Body<'_>, 32);
3520-
static_assert_size!(Expr<'_>, 64);
3521-
static_assert_size!(ExprKind<'_>, 48);
3520+
static_assert_size!(Expr<'_>, 56);
3521+
static_assert_size!(ExprKind<'_>, 40);
35223522
static_assert_size!(FnDecl<'_>, 40);
35233523
static_assert_size!(ForeignItem<'_>, 72);
35243524
static_assert_size!(ForeignItemKind<'_>, 40);
35253525
static_assert_size!(GenericArg<'_>, 24);
35263526
static_assert_size!(GenericBound<'_>, 48);
35273527
static_assert_size!(Generics<'_>, 56);
3528-
static_assert_size!(Impl<'_>, 80);
3528+
static_assert_size!(Impl<'_>, 72);
35293529
static_assert_size!(ImplItem<'_>, 80);
35303530
static_assert_size!(ImplItemKind<'_>, 32);
35313531
static_assert_size!(Item<'_>, 80);
35323532
static_assert_size!(ItemKind<'_>, 48);
3533-
static_assert_size!(Local<'_>, 64);
3533+
static_assert_size!(Local<'_>, 56);
35343534
static_assert_size!(Param<'_>, 32);
35353535
static_assert_size!(Pat<'_>, 72);
35363536
static_assert_size!(Path<'_>, 40);
@@ -3540,8 +3540,8 @@ mod size_asserts {
35403540
static_assert_size!(Res, 12);
35413541
static_assert_size!(Stmt<'_>, 32);
35423542
static_assert_size!(StmtKind<'_>, 16);
3543-
static_assert_size!(TraitItem<'_>, 88);
3544-
static_assert_size!(TraitItemKind<'_>, 48);
3543+
static_assert_size!(TraitItem<'_>, 80);
3544+
static_assert_size!(TraitItemKind<'_>, 40);
35453545
static_assert_size!(Ty<'_>, 48);
35463546
static_assert_size!(TyKind<'_>, 32);
35473547
// tidy-alphabetical-end

compiler/rustc_parse/src/parser/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub struct Parser<'a> {
156156
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
157157
// it doesn't unintentionally get bigger.
158158
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
159-
rustc_data_structures::static_assert_size!(Parser<'_>, 328);
159+
rustc_data_structures::static_assert_size!(Parser<'_>, 320);
160160

161161
/// Stores span information about a closure.
162162
#[derive(Clone)]

compiler/rustc_span/src/span_encoding.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,23 @@ use rustc_data_structures::fx::FxIndexSet;
6969
#[rustc_pass_by_value]
7070
pub struct Span {
7171
base_or_index: u32,
72-
len_or_tag: u16,
72+
len_or_tag: LenOrTag,
7373
ctxt_or_tag: u16,
7474
}
7575

76-
const LEN_TAG: u16 = 0b1000_0000_0000_0000;
76+
// LEN_TAG allows for some extra values at the top. Declare them to rustc to use as niches.
77+
#[rustc_layout_scalar_valid_range_end(0b1000_0000_0000_0000)]
78+
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
79+
struct LenOrTag(u16);
80+
81+
const LEN_TAG: LenOrTag = unsafe { LenOrTag(0b1000_0000_0000_0000) };
7782
const MAX_LEN: u32 = 0b0111_1111_1111_1111;
7883
const CTXT_TAG: u32 = 0b1111_1111_1111_1111;
7984
const MAX_CTXT: u32 = CTXT_TAG - 1;
8085

8186
/// Dummy span, both position and length are zero, syntax context is zero as well.
82-
pub const DUMMY_SP: Span = Span { base_or_index: 0, len_or_tag: 0, ctxt_or_tag: 0 };
87+
pub const DUMMY_SP: Span =
88+
Span { base_or_index: 0, len_or_tag: unsafe { LenOrTag(0) }, ctxt_or_tag: 0 };
8389

8490
impl Span {
8591
#[inline]
@@ -97,7 +103,11 @@ impl Span {
97103

98104
if len <= MAX_LEN && ctxt2 <= MAX_CTXT && parent.is_none() {
99105
// Inline format.
100-
Span { base_or_index: base, len_or_tag: len as u16, ctxt_or_tag: ctxt2 as u16 }
106+
Span {
107+
base_or_index: base,
108+
len_or_tag: unsafe { LenOrTag(len as u16) },
109+
ctxt_or_tag: ctxt2 as u16,
110+
}
101111
} else {
102112
// Interned format.
103113
let index =
@@ -122,10 +132,10 @@ impl Span {
122132
pub fn data_untracked(self) -> SpanData {
123133
if self.len_or_tag != LEN_TAG {
124134
// Inline format.
125-
debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
135+
debug_assert!(self.len_or_tag.0 as u32 <= MAX_LEN);
126136
SpanData {
127137
lo: BytePos(self.base_or_index),
128-
hi: BytePos(self.base_or_index + self.len_or_tag as u32),
138+
hi: BytePos(self.base_or_index + self.len_or_tag.0 as u32),
129139
ctxt: SyntaxContext::from_u32(self.ctxt_or_tag as u32),
130140
parent: None,
131141
}

0 commit comments

Comments
 (0)