Skip to content

Commit 67951d9

Browse files
committed
Auto merge of rust-lang#135319 - matthiaskrgr:rollup-un5lol6, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#133088 (`-Zrandomize-layout` harder. `Foo<T> != Foo<U>`) - rust-lang#134619 (Improve prose around `as_slice` example of IterMut) - rust-lang#134855 (Add `default_field_values` entry to unstable book) - rust-lang#134908 (Fix `ptr::from_ref` documentation example comment) - rust-lang#135275 (Add Pin::as_deref_mut to 1.84 relnotes) - rust-lang#135294 (Make `bare-fn-no-impl-fn-ptr-99875` test less dependent on path width) - rust-lang#135304 (Add tests cases from review of rust-lang#132289) - rust-lang#135308 (Make sure to walk into nested const blocks in `RegionResolutionVisitor`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 88ab2d8 + c51bfaf commit 67951d9

File tree

53 files changed

+738
-124
lines changed

Some content is hidden

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

53 files changed

+738
-124
lines changed

RELEASES.md

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Stabilized APIs
6060
- [`core::ptr::without_provenance_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.without_provenance_mut.html)
6161
- [`core::ptr::dangling`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling.html)
6262
- [`core::ptr::dangling_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling_mut.html)
63+
- [`Pin::as_deref_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.as_deref_mut)
6364

6465
These APIs are now stable in const contexts
6566

compiler/rustc_abi/src/layout.rs

+36-7
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
119119
.chain(Niche::from_scalar(dl, Size::ZERO, a))
120120
.max_by_key(|niche| niche.available(dl));
121121

122+
let combined_seed = a.size(&self.cx).bytes().wrapping_add(b.size(&self.cx).bytes());
123+
122124
LayoutData {
123125
variants: Variants::Single { index: VariantIdx::new(0) },
124126
fields: FieldsShape::Arbitrary {
@@ -131,6 +133,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
131133
size,
132134
max_repr_align: None,
133135
unadjusted_abi_align: align.abi,
136+
randomization_seed: combined_seed,
134137
}
135138
}
136139

@@ -223,6 +226,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
223226
size: Size::ZERO,
224227
max_repr_align: None,
225228
unadjusted_abi_align: dl.i8_align.abi,
229+
randomization_seed: 0,
226230
}
227231
}
228232

@@ -385,6 +389,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
385389
return Err(LayoutCalculatorError::EmptyUnion);
386390
};
387391

392+
let combined_seed = only_variant
393+
.iter()
394+
.map(|v| v.randomization_seed)
395+
.fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed));
396+
388397
Ok(LayoutData {
389398
variants: Variants::Single { index: only_variant_idx },
390399
fields: FieldsShape::Union(union_field_count),
@@ -394,6 +403,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
394403
size: size.align_to(align.abi),
395404
max_repr_align,
396405
unadjusted_abi_align,
406+
randomization_seed: combined_seed,
397407
})
398408
}
399409

@@ -650,6 +660,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
650660
BackendRepr::Memory { sized: true }
651661
};
652662

663+
let combined_seed = variant_layouts
664+
.iter()
665+
.map(|v| v.randomization_seed)
666+
.fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed));
667+
653668
let layout = LayoutData {
654669
variants: Variants::Multiple {
655670
tag: niche_scalar,
@@ -671,6 +686,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
671686
align,
672687
max_repr_align,
673688
unadjusted_abi_align,
689+
randomization_seed: combined_seed,
674690
};
675691

676692
Some(TmpLayout { layout, variants: variant_layouts })
@@ -961,6 +977,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
961977

962978
let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
963979

980+
let combined_seed = layout_variants
981+
.iter()
982+
.map(|v| v.randomization_seed)
983+
.fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed));
984+
964985
let tagged_layout = LayoutData {
965986
variants: Variants::Multiple {
966987
tag,
@@ -978,6 +999,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
978999
size,
9791000
max_repr_align,
9801001
unadjusted_abi_align,
1002+
randomization_seed: combined_seed,
9811003
};
9821004

9831005
let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants };
@@ -1030,12 +1052,15 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10301052
let mut max_repr_align = repr.align;
10311053
let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
10321054
let optimize_field_order = !repr.inhibit_struct_field_reordering();
1033-
if optimize_field_order && fields.len() > 1 {
1034-
let end =
1035-
if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
1036-
let optimizing = &mut inverse_memory_index.raw[..end];
1037-
let fields_excluding_tail = &fields.raw[..end];
1055+
let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
1056+
let optimizing = &mut inverse_memory_index.raw[..end];
1057+
let fields_excluding_tail = &fields.raw[..end];
1058+
// unsizable tail fields are excluded so that we use the same seed for the sized and unsized layouts.
1059+
let field_seed = fields_excluding_tail
1060+
.iter()
1061+
.fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed));
10381062

1063+
if optimize_field_order && fields.len() > 1 {
10391064
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
10401065
// the field ordering to try and catch some code making assumptions about layouts
10411066
// we don't guarantee.
@@ -1046,8 +1071,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10461071
use rand::seq::SliceRandom;
10471072
// `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
10481073
// ordering.
1049-
let mut rng =
1050-
rand_xoshiro::Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
1074+
let mut rng = rand_xoshiro::Xoshiro128StarStar::seed_from_u64(
1075+
field_seed.wrapping_add(repr.field_shuffle_seed),
1076+
);
10511077

10521078
// Shuffle the ordering of the fields.
10531079
optimizing.shuffle(&mut rng);
@@ -1344,6 +1370,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13441370
unadjusted_abi_align
13451371
};
13461372

1373+
let seed = field_seed.wrapping_add(repr.field_shuffle_seed);
1374+
13471375
Ok(LayoutData {
13481376
variants: Variants::Single { index: VariantIdx::new(0) },
13491377
fields: FieldsShape::Arbitrary { offsets, memory_index },
@@ -1353,6 +1381,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13531381
size,
13541382
max_repr_align,
13551383
unadjusted_abi_align,
1384+
randomization_seed: seed,
13561385
})
13571386
}
13581387

compiler/rustc_abi/src/lib.rs

+39
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,18 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
17191719
/// Only used on aarch64-linux, where the argument passing ABI ignores the requested alignment
17201720
/// in some cases.
17211721
pub unadjusted_abi_align: Align,
1722+
1723+
/// The randomization seed based on this type's own repr and its fields.
1724+
///
1725+
/// Since randomization is toggled on a per-crate basis even crates that do not have randomization
1726+
/// enabled should still calculate a seed so that downstream uses can use it to distinguish different
1727+
/// types.
1728+
///
1729+
/// For every T and U for which we do not guarantee that a repr(Rust) `Foo<T>` can be coerced or
1730+
/// transmuted to `Foo<U>` we aim to create probalistically distinct seeds so that Foo can choose
1731+
/// to reorder its fields based on that information. The current implementation is a conservative
1732+
/// approximation of this goal.
1733+
pub randomization_seed: u64,
17221734
}
17231735

17241736
impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
@@ -1739,6 +1751,30 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
17391751
let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
17401752
let size = scalar.size(cx);
17411753
let align = scalar.align(cx);
1754+
1755+
let range = scalar.valid_range(cx);
1756+
1757+
// All primitive types for which we don't have subtype coercions should get a distinct seed,
1758+
// so that types wrapping them can use randomization to arrive at distinct layouts.
1759+
//
1760+
// Some type information is already lost at this point, so as an approximation we derive
1761+
// the seed from what remains. For example on 64-bit targets usize and u64 can no longer
1762+
// be distinguished.
1763+
let randomization_seed = size
1764+
.bytes()
1765+
.wrapping_add(
1766+
match scalar.primitive() {
1767+
Primitive::Int(_, true) => 1,
1768+
Primitive::Int(_, false) => 2,
1769+
Primitive::Float(_) => 3,
1770+
Primitive::Pointer(_) => 4,
1771+
} << 32,
1772+
)
1773+
// distinguishes references from pointers
1774+
.wrapping_add((range.start as u64).rotate_right(16))
1775+
// distinguishes char from u32 and bool from u8
1776+
.wrapping_add((range.end as u64).rotate_right(16));
1777+
17421778
LayoutData {
17431779
variants: Variants::Single { index: VariantIdx::new(0) },
17441780
fields: FieldsShape::Primitive,
@@ -1748,6 +1784,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
17481784
align,
17491785
max_repr_align: None,
17501786
unadjusted_abi_align: align.abi,
1787+
randomization_seed,
17511788
}
17521789
}
17531790
}
@@ -1770,6 +1807,7 @@ where
17701807
variants,
17711808
max_repr_align,
17721809
unadjusted_abi_align,
1810+
ref randomization_seed,
17731811
} = self;
17741812
f.debug_struct("Layout")
17751813
.field("size", size)
@@ -1780,6 +1818,7 @@ where
17801818
.field("variants", variants)
17811819
.field("max_repr_align", max_repr_align)
17821820
.field("unadjusted_abi_align", unadjusted_abi_align)
1821+
.field("randomization_seed", randomization_seed)
17831822
.finish()
17841823
}
17851824
}

compiler/rustc_hir_analysis/src/check/region.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct Context {
3131
parent: Option<(Scope, ScopeDepth)>,
3232
}
3333

34-
struct RegionResolutionVisitor<'tcx> {
34+
struct ScopeResolutionVisitor<'tcx> {
3535
tcx: TyCtxt<'tcx>,
3636

3737
// The number of expressions and patterns visited in the current body.
@@ -71,7 +71,7 @@ struct RegionResolutionVisitor<'tcx> {
7171
}
7272

7373
/// Records the lifetime of a local variable as `cx.var_parent`
74-
fn record_var_lifetime(visitor: &mut RegionResolutionVisitor<'_>, var_id: hir::ItemLocalId) {
74+
fn record_var_lifetime(visitor: &mut ScopeResolutionVisitor<'_>, var_id: hir::ItemLocalId) {
7575
match visitor.cx.var_parent {
7676
None => {
7777
// this can happen in extern fn declarations like
@@ -82,7 +82,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor<'_>, var_id: hir::I
8282
}
8383
}
8484

85-
fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx hir::Block<'tcx>) {
85+
fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hir::Block<'tcx>) {
8686
debug!("resolve_block(blk.hir_id={:?})", blk.hir_id);
8787

8888
let prev_cx = visitor.cx;
@@ -193,7 +193,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
193193
visitor.cx = prev_cx;
194194
}
195195

196-
fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) {
196+
fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) {
197197
fn has_let_expr(expr: &Expr<'_>) -> bool {
198198
match &expr.kind {
199199
hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
@@ -220,7 +220,7 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir
220220
visitor.cx = prev_cx;
221221
}
222222

223-
fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
223+
fn resolve_pat<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
224224
visitor.record_child_scope(Scope { local_id: pat.hir_id.local_id, data: ScopeData::Node });
225225

226226
// If this is a binding then record the lifetime of that binding.
@@ -237,7 +237,7 @@ fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir
237237
debug!("resolve_pat - post-increment {} pat = {:?}", visitor.expr_and_pat_count, pat);
238238
}
239239

240-
fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) {
240+
fn resolve_stmt<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) {
241241
let stmt_id = stmt.hir_id.local_id;
242242
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
243243

@@ -256,7 +256,7 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
256256
visitor.cx.parent = prev_parent;
257257
}
258258

259-
fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
259+
fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
260260
debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
261261

262262
let prev_cx = visitor.cx;
@@ -420,10 +420,10 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
420420
// properly, we can't miss any types.
421421

422422
match expr.kind {
423-
// Manually recurse over closures and inline consts, because they are the only
424-
// case of nested bodies that share the parent environment.
425-
hir::ExprKind::Closure(&hir::Closure { body, .. })
426-
| hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
423+
// Manually recurse over closures, because they are nested bodies
424+
// that share the parent environment. We handle const blocks in
425+
// `visit_inline_const`.
426+
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
427427
let body = visitor.tcx.hir().body(body);
428428
visitor.visit_body(body);
429429
}
@@ -554,7 +554,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
554554
}
555555

556556
fn resolve_local<'tcx>(
557-
visitor: &mut RegionResolutionVisitor<'tcx>,
557+
visitor: &mut ScopeResolutionVisitor<'tcx>,
558558
pat: Option<&'tcx hir::Pat<'tcx>>,
559559
init: Option<&'tcx hir::Expr<'tcx>>,
560560
) {
@@ -725,7 +725,7 @@ fn resolve_local<'tcx>(
725725
/// | ( E& )
726726
/// ```
727727
fn record_rvalue_scope_if_borrow_expr<'tcx>(
728-
visitor: &mut RegionResolutionVisitor<'tcx>,
728+
visitor: &mut ScopeResolutionVisitor<'tcx>,
729729
expr: &hir::Expr<'_>,
730730
blk_id: Option<Scope>,
731731
) {
@@ -782,7 +782,7 @@ fn resolve_local<'tcx>(
782782
}
783783
}
784784

785-
impl<'tcx> RegionResolutionVisitor<'tcx> {
785+
impl<'tcx> ScopeResolutionVisitor<'tcx> {
786786
/// Records the current parent (if any) as the parent of `child_scope`.
787787
/// Returns the depth of `child_scope`.
788788
fn record_child_scope(&mut self, child_scope: Scope) -> ScopeDepth {
@@ -838,7 +838,7 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
838838
}
839839
}
840840

841-
impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
841+
impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
842842
fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
843843
resolve_block(self, b);
844844
}
@@ -906,6 +906,10 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
906906
fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) {
907907
resolve_local(self, Some(l.pat), l.init)
908908
}
909+
fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
910+
let body = self.tcx.hir().body(c.body);
911+
self.visit_body(body);
912+
}
909913
}
910914

911915
/// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body;
@@ -922,7 +926,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
922926
}
923927

924928
let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) {
925-
let mut visitor = RegionResolutionVisitor {
929+
let mut visitor = ScopeResolutionVisitor {
926930
tcx,
927931
scope_tree: ScopeTree::default(),
928932
expr_and_pat_count: 0,

compiler/rustc_middle/src/ty/layout.rs

+1
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ where
770770
size: Size::ZERO,
771771
max_repr_align: None,
772772
unadjusted_abi_align: tcx.data_layout.i8_align.abi,
773+
randomization_seed: 0,
773774
})
774775
}
775776

0 commit comments

Comments
 (0)