Skip to content

Commit 3066253

Browse files
committed
Auto merge of rust-lang#120080 - cuviper:128-align-packed, r=nikic
Pack u128 in the compiler to mitigate new alignment This is based on rust-lang#116672, adding a new `#[repr(packed(8))]` wrapper on `u128` to avoid changing any of the compiler's size assertions. This is needed in two places: * `SwitchTargets`, otherwise its `SmallVec<[u128; 1]>` gets padded up to 32 bytes. * `LitKind::Int`, so that entire `enum` can stay 24 bytes. * This change definitely has far-reaching effects though, since it's public.
2 parents 366d112 + 33e0422 commit 3066253

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+173
-86
lines changed

compiler/rustc_ast/src/ast.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub use UnsafeSource::*;
2727
use crate::ptr::P;
2828
use crate::token::{self, CommentKind, Delimiter};
2929
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
30+
use rustc_data_structures::packed::Pu128;
3031
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3132
use rustc_data_structures::stack::ensure_sufficient_stack;
3233
use rustc_data_structures::sync::Lrc;
@@ -1833,7 +1834,7 @@ pub enum LitKind {
18331834
/// A character literal (`'a'`).
18341835
Char(char),
18351836
/// An integer literal (`1`).
1836-
Int(u128, LitIntType),
1837+
Int(Pu128, LitIntType),
18371838
/// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
18381839
/// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
18391840
/// and `Hash`.
@@ -3304,13 +3305,9 @@ mod size_asserts {
33043305
static_assert_size!(Impl, 136);
33053306
static_assert_size!(Item, 136);
33063307
static_assert_size!(ItemKind, 64);
3307-
// This can be removed after i128:128 is in the bootstrap compiler's target.
3308-
#[cfg(not(bootstrap))]
3309-
static_assert_size!(LitKind, 32);
3308+
static_assert_size!(LitKind, 24);
33103309
static_assert_size!(Local, 72);
3311-
// This can be removed after i128:128 is in the bootstrap compiler's target.
3312-
#[cfg(not(bootstrap))]
3313-
static_assert_size!(MetaItemLit, 48);
3310+
static_assert_size!(MetaItemLit, 40);
33143311
static_assert_size!(Param, 40);
33153312
static_assert_size!(Pat, 72);
33163313
static_assert_size!(Path, 24);

compiler/rustc_ast/src/util/literal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr
366366
};
367367

368368
let s = &s[if base != 10 { 2 } else { 0 }..];
369-
u128::from_str_radix(s, base).map(|i| LitKind::Int(i, ty)).map_err(|_| {
369+
u128::from_str_radix(s, base).map(|i| LitKind::Int(i.into(), ty)).map_err(|_| {
370370
// Small bases are lexed as if they were base 10, e.g, the string
371371
// might be `0b10201`. This will cause the conversion above to fail,
372372
// but these kinds of errors are already reported by the lexer.

compiler/rustc_ast_lowering/src/expr.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1899,15 +1899,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
18991899
pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> {
19001900
let lit = self.arena.alloc(hir::Lit {
19011901
span: sp,
1902-
node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
1902+
node: ast::LitKind::Int(
1903+
(value as u128).into(),
1904+
ast::LitIntType::Unsigned(ast::UintTy::Usize),
1905+
),
19031906
});
19041907
self.expr(sp, hir::ExprKind::Lit(lit))
19051908
}
19061909

19071910
pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> {
19081911
let lit = self.arena.alloc(hir::Lit {
19091912
span: sp,
1910-
node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)),
1913+
node: ast::LitKind::Int(
1914+
u128::from(value).into(),
1915+
ast::LitIntType::Unsigned(ast::UintTy::U32),
1916+
),
19111917
});
19121918
self.expr(sp, hir::ExprKind::Lit(lit))
19131919
}

compiler/rustc_attr/src/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1185,9 +1185,9 @@ fn allow_unstable<'a>(
11851185

11861186
pub fn parse_alignment(node: &ast::LitKind) -> Result<u32, &'static str> {
11871187
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
1188-
if literal.is_power_of_two() {
1188+
if literal.get().is_power_of_two() {
11891189
// rustc_middle::ty::layout::Align restricts align to <= 2^29
1190-
if *literal <= 1 << 29 { Ok(*literal as u32) } else { Err("larger than 2^29") }
1190+
if *literal <= 1 << 29 { Ok(literal.get() as u32) } else { Err("larger than 2^29") }
11911191
} else {
11921192
Err("not a power of two")
11931193
}

compiler/rustc_attr/src/session_diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<'a> IncorrectReprFormatGenericCause<'a> {
296296
pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
297297
match kind {
298298
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
299-
Some(Self::Int { span, name, int: *int })
299+
Some(Self::Int { span, name, int: int.get() })
300300
}
301301
ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
302302
_ => None,

compiler/rustc_builtin_macros/src/concat_bytes.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn invalid_type_err(
5454
val,
5555
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
5656
)) => {
57-
assert!(val > u8::MAX.into()); // must be an error
57+
assert!(val.get() > u8::MAX.into()); // must be an error
5858
dcx.emit_err(ConcatBytesOob { span });
5959
}
6060
Ok(ast::LitKind::Int(_, _)) => {
@@ -86,7 +86,7 @@ fn handle_array_element(
8686
Ok(ast::LitKind::Int(
8787
val,
8888
ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
89-
)) if val <= u8::MAX.into() => Some(val as u8),
89+
)) if val.get() <= u8::MAX.into() => Some(val.get() as u8),
9090

9191
Ok(ast::LitKind::Byte(val)) => Some(val),
9292
Ok(ast::LitKind::ByteStr(..)) => {
@@ -148,7 +148,7 @@ pub fn expand_concat_bytes(
148148
if let Some(elem) =
149149
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
150150
{
151-
for _ in 0..count_val {
151+
for _ in 0..count_val.get() {
152152
accumulator.push(elem);
153153
}
154154
}

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
658658
// if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
659659
// about LINK.EXE failing.)
660660
if *ordinal <= u16::MAX as u128 {
661-
Some(*ordinal as u16)
661+
Some(ordinal.get() as u16)
662662
} else {
663663
let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
664664
tcx.dcx()

compiler/rustc_data_structures/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub mod aligned;
9393
pub mod frozen;
9494
mod hashes;
9595
pub mod owned_slice;
96+
pub mod packed;
9697
pub mod sso;
9798
pub mod steal;
9899
pub mod tagged_ptr;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use crate::stable_hasher::{HashStable, StableHasher};
2+
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
3+
use std::cmp::Ordering;
4+
use std::fmt;
5+
6+
#[repr(packed(8))]
7+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
8+
pub struct Pu128(pub u128);
9+
10+
impl Pu128 {
11+
#[inline]
12+
pub fn get(self) -> u128 {
13+
self.0
14+
}
15+
}
16+
17+
impl From<u128> for Pu128 {
18+
#[inline]
19+
fn from(value: u128) -> Self {
20+
Self(value)
21+
}
22+
}
23+
24+
impl PartialEq<u128> for Pu128 {
25+
#[inline]
26+
fn eq(&self, other: &u128) -> bool {
27+
({ self.0 }) == *other
28+
}
29+
}
30+
31+
impl PartialOrd<u128> for Pu128 {
32+
#[inline]
33+
fn partial_cmp(&self, other: &u128) -> Option<Ordering> {
34+
{ self.0 }.partial_cmp(other)
35+
}
36+
}
37+
38+
impl fmt::Display for Pu128 {
39+
#[inline]
40+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41+
{ self.0 }.fmt(f)
42+
}
43+
}
44+
45+
impl fmt::UpperHex for Pu128 {
46+
#[inline]
47+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48+
{ self.0 }.fmt(f)
49+
}
50+
}
51+
52+
impl<CTX> HashStable<CTX> for Pu128 {
53+
#[inline]
54+
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
55+
{ self.0 }.hash_stable(ctx, hasher)
56+
}
57+
}
58+
59+
impl<S: Encoder> Encodable<S> for Pu128 {
60+
#[inline]
61+
fn encode(&self, s: &mut S) {
62+
{ self.0 }.encode(s);
63+
}
64+
}
65+
66+
impl<D: Decoder> Decodable<D> for Pu128 {
67+
#[inline]
68+
fn decode(d: &mut D) -> Self {
69+
Self(u128::decode(d))
70+
}
71+
}

compiler/rustc_expand/src/mbe/metavar_expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn parse_depth<'sess>(
124124
};
125125
if let Ok(lit_kind) = LitKind::from_token_lit(*lit)
126126
&& let LitKind::Int(n_u128, LitIntType::Unsuffixed) = lit_kind
127-
&& let Ok(n_usize) = usize::try_from(n_u128)
127+
&& let Ok(n_usize) = usize::try_from(n_u128.get())
128128
{
129129
Ok(n_usize)
130130
} else {

compiler/rustc_hir_typeck/src/expr.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -2981,10 +2981,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29812981
// fixed expression:
29822982
if let ExprKind::Lit(lit) = idx.kind
29832983
&& let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
2984-
&& i < types
2985-
.len()
2986-
.try_into()
2987-
.expect("expected tuple index to be < usize length")
2984+
&& i.get()
2985+
< types
2986+
.len()
2987+
.try_into()
2988+
.expect("expected tuple index to be < usize length")
29882989
{
29892990
err.span_suggestion(
29902991
brackets_span,

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::ty::TypeAndMut;
1111
use core::cmp::min;
1212
use core::iter;
1313
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
14+
use rustc_data_structures::packed::Pu128;
1415
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
1516
use rustc_hir as hir;
1617
use rustc_hir::def::Res;
@@ -1409,8 +1410,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091410
}
14101411
let (_, suffix) = snippet.split_at(snippet.len() - 3);
14111412
let value = match suffix {
1412-
"f32" => (lit - 0xf32) / (16 * 16 * 16),
1413-
"f64" => (lit - 0xf64) / (16 * 16 * 16),
1413+
"f32" => (lit.get() - 0xf32) / (16 * 16 * 16),
1414+
"f64" => (lit.get() - 0xf64) / (16 * 16 * 16),
14141415
_ => return false,
14151416
};
14161417
err.span_suggestions(
@@ -1440,7 +1441,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14401441
};
14411442

14421443
// Provided expression needs to be a literal `0`.
1443-
let ExprKind::Lit(Spanned { node: rustc_ast::LitKind::Int(0, _), span }) = expr.kind else {
1444+
let ExprKind::Lit(Spanned { node: rustc_ast::LitKind::Int(Pu128(0), _), span }) = expr.kind
1445+
else {
14441446
return false;
14451447
};
14461448

compiler/rustc_hir_typeck/src/op.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::method::MethodCallee;
44
use super::{has_expected_num_generic_args, FnCtxt};
55
use crate::Expectation;
66
use rustc_ast as ast;
7+
use rustc_data_structures::packed::Pu128;
78
use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder};
89
use rustc_hir as hir;
910
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -834,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
834835
hir::Expr {
835836
kind:
836837
hir::ExprKind::Lit(Spanned {
837-
node: ast::LitKind::Int(1, _),
838+
node: ast::LitKind::Int(Pu128(1), _),
838839
..
839840
}),
840841
..

compiler/rustc_lint/src/invalid_from_utf8.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
111111
.map(|e| match &e.kind {
112112
ExprKind::Lit(Spanned { node: lit, .. }) => match lit {
113113
LitKind::Byte(b) => Some(*b),
114-
LitKind::Int(b, _) => Some(*b as u8),
114+
LitKind::Int(b, _) => Some(b.get() as u8),
115115
_ => None,
116116
},
117117
_ => None,

compiler/rustc_lint/src/types.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ fn lint_uint_literal<'tcx>(
492492
let lit_val: u128 = match lit.node {
493493
// _v is u8, within range by definition
494494
ast::LitKind::Byte(_v) => return,
495-
ast::LitKind::Int(v, _) => v,
495+
ast::LitKind::Int(v, _) => v.get(),
496496
_ => bug!(),
497497
};
498498
if lit_val < min || lit_val > max {
@@ -555,7 +555,7 @@ fn lint_literal<'tcx>(
555555
ty::Int(t) => {
556556
match lit.node {
557557
ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
558-
lint_int_literal(cx, type_limits, e, lit, t, v)
558+
lint_int_literal(cx, type_limits, e, lit, t, v.get())
559559
}
560560
_ => bug!(),
561561
};
@@ -842,7 +842,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
842842
ast::LitKind::Int(
843843
v,
844844
ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed,
845-
) => v as i128,
845+
) => v.get() as i128,
846846
_ => return true,
847847
},
848848
_ => bug!(),
@@ -853,7 +853,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
853853
let (min, max): (u128, u128) = uint_ty_range(uint_ty);
854854
let lit_val: u128 = match lit.kind {
855855
hir::ExprKind::Lit(li) => match li.node {
856-
ast::LitKind::Int(v, _) => v,
856+
ast::LitKind::Int(v, _) => v.get(),
857857
_ => return true,
858858
},
859859
_ => bug!(),

compiler/rustc_middle/src/mir/mod.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -1672,19 +1672,13 @@ mod size_asserts {
16721672
use super::*;
16731673
use rustc_data_structures::static_assert_size;
16741674
// tidy-alphabetical-start
1675-
// This can be removed after i128:128 is in the bootstrap compiler's target.
1676-
#[cfg(not(bootstrap))]
1677-
static_assert_size!(BasicBlockData<'_>, 144);
1675+
static_assert_size!(BasicBlockData<'_>, 136);
16781676
static_assert_size!(LocalDecl<'_>, 40);
16791677
static_assert_size!(SourceScopeData<'_>, 72);
16801678
static_assert_size!(Statement<'_>, 32);
16811679
static_assert_size!(StatementKind<'_>, 16);
1682-
// This can be removed after i128:128 is in the bootstrap compiler's target.
1683-
#[cfg(not(bootstrap))]
1684-
static_assert_size!(Terminator<'_>, 112);
1685-
// This can be removed after i128:128 is in the bootstrap compiler's target.
1686-
#[cfg(not(bootstrap))]
1687-
static_assert_size!(TerminatorKind<'_>, 96);
1680+
static_assert_size!(Terminator<'_>, 104);
1681+
static_assert_size!(TerminatorKind<'_>, 88);
16881682
static_assert_size!(VarDebugInfo<'_>, 88);
16891683
// tidy-alphabetical-end
16901684
}

compiler/rustc_middle/src/mir/syntax.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::ty::{self, List, Ty};
1313
use crate::ty::{Region, UserTypeAnnotationIndex};
1414

1515
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
16+
use rustc_data_structures::packed::Pu128;
1617
use rustc_hir::def_id::DefId;
1718
use rustc_hir::{self, CoroutineKind};
1819
use rustc_index::IndexVec;
@@ -829,7 +830,7 @@ impl TerminatorKind<'_> {
829830
pub struct SwitchTargets {
830831
/// Possible values. The locations to branch to in each case
831832
/// are found in the corresponding indices from the `targets` vector.
832-
pub(super) values: SmallVec<[u128; 1]>,
833+
pub(super) values: SmallVec<[Pu128; 1]>,
833834

834835
/// Possible branch sites. The last element of this vector is used
835836
/// for the otherwise branch, so targets.len() == values.len() + 1

0 commit comments

Comments
 (0)