Skip to content

Commit 10aabc4

Browse files
author
Lukas Markeffsky
committed
layout computation: eagerly error for unexpected unsized fields
1 parent e0d1766 commit 10aabc4

File tree

25 files changed

+1224
-1093
lines changed

25 files changed

+1224
-1093
lines changed

compiler/rustc_abi/src/layout.rs

Lines changed: 939 additions & 918 deletions
Large diffs are not rendered by default.

compiler/rustc_abi/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ mod layout;
2626
#[cfg(test)]
2727
mod tests;
2828

29-
pub use layout::LayoutCalculator;
29+
pub use layout::{LayoutCalculator, LayoutCalculatorError};
3030

3131
/// Requirements for a `StableHashingContext` to be used in this crate.
3232
/// This is a hack to allow using the `HashStable_Generic` derive macro
@@ -393,6 +393,14 @@ impl HasDataLayout for TargetDataLayout {
393393
}
394394
}
395395

396+
// used by rust-analyzer
397+
impl HasDataLayout for &TargetDataLayout {
398+
#[inline]
399+
fn data_layout(&self) -> &TargetDataLayout {
400+
(**self).data_layout()
401+
}
402+
}
403+
396404
/// Endianness of the target, which must match cfg(target-endian).
397405
#[derive(Copy, Clone, PartialEq, Eq)]
398406
pub enum Endian {

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ pub fn valtree_to_const_value<'tcx>(
319319
let branches = valtree.unwrap_branch();
320320
// Find the non-ZST field. (There can be aligned ZST!)
321321
for (i, &inner_valtree) in branches.iter().enumerate() {
322-
let field = layout.field(&LayoutCx { tcx, param_env }, i);
322+
let field = layout.field(&LayoutCx::new(tcx, param_env), i);
323323
if !field.is_zst() {
324324
return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree);
325325
}

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
946946
) -> Cow<'e, RangeSet> {
947947
assert!(layout.ty.is_union());
948948
assert!(layout.abi.is_sized(), "there are no unsized unions");
949-
let layout_cx = LayoutCx { tcx: *ecx.tcx, param_env: ecx.param_env };
949+
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.param_env);
950950
return M::cached_union_data_range(ecx, layout.ty, || {
951951
let mut out = RangeSet(Vec::new());
952952
union_data_range_uncached(&layout_cx, layout, Size::ZERO, &mut out);

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use rustc_middle::bug;
2-
use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement};
2+
use rustc_middle::ty::layout::{
3+
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
4+
};
35
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
46
use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
57

@@ -30,7 +32,7 @@ pub fn check_validity_requirement<'tcx>(
3032
return Ok(!layout.abi.is_uninhabited());
3133
}
3234

33-
let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env };
35+
let layout_cx = LayoutCx::new(tcx, param_env_and_ty.param_env);
3436
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
3537
check_validity_requirement_strict(layout, &layout_cx, kind)
3638
} else {
@@ -47,7 +49,7 @@ fn check_validity_requirement_strict<'tcx>(
4749
) -> Result<bool, &'tcx LayoutError<'tcx>> {
4850
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
4951

50-
let mut cx = InterpCx::new(cx.tcx, rustc_span::DUMMY_SP, cx.param_env, machine);
52+
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.param_env, machine);
5153

5254
let allocated = cx
5355
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::borrow::Cow;
21
use std::num::NonZero;
32
use std::ops::Bound;
43
use std::{cmp, fmt};
@@ -287,19 +286,13 @@ impl<'tcx> IntoDiagArg for LayoutError<'tcx> {
287286

288287
#[derive(Clone, Copy)]
289288
pub struct LayoutCx<'tcx> {
290-
pub tcx: TyCtxt<'tcx>,
289+
pub calc: LayoutCalculator<TyCtxt<'tcx>>,
291290
pub param_env: ty::ParamEnv<'tcx>,
292291
}
293292

294-
impl<'tcx> LayoutCalculator for LayoutCx<'tcx> {
295-
type TargetDataLayoutRef = &'tcx TargetDataLayout;
296-
297-
fn delayed_bug(&self, txt: impl Into<Cow<'static, str>>) {
298-
self.tcx.dcx().delayed_bug(txt);
299-
}
300-
301-
fn current_data_layout(&self) -> Self::TargetDataLayoutRef {
302-
&self.tcx.data_layout
293+
impl<'tcx> LayoutCx<'tcx> {
294+
pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
295+
Self { calc: LayoutCalculator::new(tcx), param_env }
303296
}
304297
}
305298

@@ -576,25 +569,25 @@ impl<'tcx> HasParamEnv<'tcx> for LayoutCx<'tcx> {
576569

577570
impl<'tcx> HasDataLayout for LayoutCx<'tcx> {
578571
fn data_layout(&self) -> &TargetDataLayout {
579-
self.tcx.data_layout()
572+
self.calc.cx.data_layout()
580573
}
581574
}
582575

583576
impl<'tcx> HasTargetSpec for LayoutCx<'tcx> {
584577
fn target_spec(&self) -> &Target {
585-
self.tcx.target_spec()
578+
self.calc.cx.target_spec()
586579
}
587580
}
588581

589582
impl<'tcx> HasWasmCAbiOpt for LayoutCx<'tcx> {
590583
fn wasm_c_abi_opt(&self) -> WasmCAbi {
591-
self.tcx.wasm_c_abi_opt()
584+
self.calc.cx.wasm_c_abi_opt()
592585
}
593586
}
594587

595588
impl<'tcx> HasTyCtxt<'tcx> for LayoutCx<'tcx> {
596589
fn tcx(&self) -> TyCtxt<'tcx> {
597-
self.tcx.tcx()
590+
self.calc.cx
598591
}
599592
}
600593

@@ -695,7 +688,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx> {
695688
_: Span,
696689
_: Ty<'tcx>,
697690
) -> &'tcx LayoutError<'tcx> {
698-
self.tcx.arena.alloc(err)
691+
self.tcx().arena.alloc(err)
699692
}
700693
}
701694

@@ -1323,7 +1316,7 @@ impl<'tcx> TyCtxt<'tcx> {
13231316
where
13241317
I: Iterator<Item = (VariantIdx, FieldIdx)>,
13251318
{
1326-
let cx = LayoutCx { tcx: self, param_env };
1319+
let cx = LayoutCx::new(self, param_env);
13271320
let mut offset = Size::ZERO;
13281321

13291322
for (variant, field) in indices {

compiler/rustc_passes/src/layout_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
128128
}
129129

130130
Err(layout_error) => {
131-
tcx.dcx().emit_fatal(Spanned { node: layout_error.into_diagnostic(), span });
131+
tcx.dcx().emit_err(Spanned { node: layout_error.into_diagnostic(), span });
132132
}
133133
}
134134
}

compiler/rustc_transmute/src/layout/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub mod rustc {
6363
use std::fmt::{self, Write};
6464

6565
use rustc_middle::mir::Mutability;
66-
use rustc_middle::ty::layout::{LayoutCx, LayoutError};
66+
use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, LayoutError};
6767
use rustc_middle::ty::{self, Ty};
6868
use rustc_target::abi::Layout;
6969

@@ -128,7 +128,7 @@ pub mod rustc {
128128
ty: Ty<'tcx>,
129129
) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
130130
use rustc_middle::ty::layout::LayoutOf;
131-
let ty = cx.tcx.erase_regions(ty);
131+
let ty = cx.tcx().erase_regions(ty);
132132
cx.layout_of(ty).map(|tl| tl.layout)
133133
}
134134
}

compiler/rustc_transmute/src/layout/tree.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ pub(crate) mod rustc {
212212
return Err(Err::TypeError(e));
213213
}
214214

215-
let target = cx.tcx.data_layout();
215+
let target = cx.data_layout();
216216
let pointer_size = target.pointer_size;
217217

218218
match ty.kind() {
@@ -320,7 +320,7 @@ pub(crate) mod rustc {
320320

321321
// Computes the variant of a given index.
322322
let layout_of_variant = |index, encoding: Option<TagEncoding<VariantIdx>>| {
323-
let tag = cx.tcx.tag_for_variant((cx.tcx.erase_regions(ty), index));
323+
let tag = cx.tcx().tag_for_variant((cx.tcx().erase_regions(ty), index));
324324
let variant_def = Def::Variant(def.variant(index));
325325
let variant_layout = ty_variant(cx, (ty, layout), index);
326326
Self::from_variant(
@@ -417,7 +417,7 @@ pub(crate) mod rustc {
417417
}
418418
}
419419
}
420-
struct_tree = struct_tree.then(Self::from_tag(*tag, cx.tcx));
420+
struct_tree = struct_tree.then(Self::from_tag(*tag, cx.tcx()));
421421
}
422422

423423
// Append the fields, in memory order, to the layout.
@@ -509,12 +509,12 @@ pub(crate) mod rustc {
509509
match layout.variants {
510510
Variants::Single { index } => {
511511
let field = &def.variant(index).fields[i];
512-
field.ty(cx.tcx, args)
512+
field.ty(cx.tcx(), args)
513513
}
514514
// Discriminant field for enums (where applicable).
515515
Variants::Multiple { tag, .. } => {
516516
assert_eq!(i.as_usize(), 0);
517-
ty::layout::PrimitiveExt::to_ty(&tag.primitive(), cx.tcx)
517+
ty::layout::PrimitiveExt::to_ty(&tag.primitive(), cx.tcx())
518518
}
519519
}
520520
}
@@ -531,7 +531,7 @@ pub(crate) mod rustc {
531531
(ty, layout): (Ty<'tcx>, Layout<'tcx>),
532532
i: VariantIdx,
533533
) -> Layout<'tcx> {
534-
let ty = cx.tcx.erase_regions(ty);
534+
let ty = cx.tcx().erase_regions(ty);
535535
TyAndLayout { ty, layout }.for_variant(&cx, i).layout
536536
}
537537
}

compiler/rustc_transmute/src/maybe_transmutable/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mod rustc {
4343
pub fn answer(self) -> Answer<<TyCtxt<'tcx> as QueryContext>::Ref> {
4444
let Self { src, dst, assume, context } = self;
4545

46-
let layout_cx = LayoutCx { tcx: context, param_env: ParamEnv::reveal_all() };
46+
let layout_cx = LayoutCx::new(context, ParamEnv::reveal_all());
4747

4848
// Convert `src` and `dst` from their rustc representations, to `Tree`-based
4949
// representations.

0 commit comments

Comments
 (0)