Skip to content

Commit 2e8c03c

Browse files
committed
add field_offsets to layout info for struct-like types
1 parent 26035a4 commit 2e8c03c

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

SCHEMA_CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ The following document describes the changes to the JSON schema that
33
as a changelog for the code in the `mir-json` tools themselves, which are
44
versioned separately.)
55

6+
## 9
7+
8+
Add field offsets to the layout information for struct-like types. This is
9+
omitted for primitives, unions, and arrays, for which the field offsets are
10+
easy to compute if needed.
11+
612
## 8
713

814
Add details to the `InlineType` case for `TyKind::Coroutine` and to the

doc/mir-json-schema.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ type FloatKind = { kind: "F32" | "F64" }
169169

170170
type Layout = {
171171
align: number,
172-
size: number
172+
size: number,
173+
field_offsets?: number[]
173174
}
174175

175176

src/analyz/ty_json.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_abi::FieldsShape;
12
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
23
use rustc_hashes::Hash64;
34
use rustc_hir as hir;
@@ -639,12 +640,31 @@ impl<'tcx> ToJson<'tcx> for ty::Ty<'tcx> {
639640
let layout = tcx
640641
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*self))
641642
.unwrap_or_else(|e| panic!("failed to get layout of {:?}: {}", self, e));
643+
let field_offsets = match layout.fields {
644+
// `FieldsShape::Primitive` has no fields.
645+
FieldsShape::Primitive => None,
646+
// `FieldsShape::Union` puts all fields at offset zero.
647+
FieldsShape::Union(_) => None,
648+
// `FieldsShape::Array` is used only for array-like types, for which offsets
649+
// are easy to compute if needed.
650+
FieldsShape::Array { .. } => {
651+
assert!(matches!(self.kind(),
652+
ty::TyKind::Array(..) | ty::TyKind::Slice(..) | ty::TyKind::Str),
653+
"unexpected TyKind {:?} for FieldsShape::Array", self.kind());
654+
None
655+
},
656+
FieldsShape::Arbitrary { ref offsets, .. } => {
657+
Some(offsets.iter().map(|&off| off.bytes()).collect::<Vec<_>>())
658+
},
659+
};
642660
if layout.is_sized() {
643661
Some(json!({
644662
"align": layout.align.abi.bytes(),
645-
"size": layout.size.bytes()
663+
"size": layout.size.bytes(),
664+
"field_offsets": field_offsets
646665
}))
647666
} else {
667+
// TODO: provide field offsets even for unsized types
648668
None
649669
}
650670
}

src/schema_ver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
/// Each version of the schema is assumed to be backwards-incompatible with
77
/// previous versions of the schema. As such, any time this version number is
88
/// bumped, it should be treated as a major version bump.
9-
pub const SCHEMA_VER: u64 = 8;
9+
pub const SCHEMA_VER: u64 = 9;

0 commit comments

Comments
 (0)