Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions SCHEMA_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ The following document describes the changes to the JSON schema that
as a changelog for the code in the `mir-json` tools themselves, which are
versioned separately.)

## 10

Add field offsets to the layout information for struct-like types. This is
omitted for primitives, unions, and arrays, for which the field offsets are
easy to compute if needed.

## 9

Add `trait_object`, which represents constant trait objects such as `const X:
Expand Down
3 changes: 2 additions & 1 deletion doc/mir-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ type FloatKind = { kind: "F32" | "F64" }

type Layout = {
align: number,
size: number
size: number,
field_offsets?: number[]
}


Expand Down
37 changes: 26 additions & 11 deletions src/analyz/ty_json.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_abi::FieldsShape;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hashes::Hash64;
use rustc_hir as hir;
Expand Down Expand Up @@ -638,26 +639,40 @@ impl<'tcx> ToJson<'tcx> for ty::Ty<'tcx> {
};

// Get layout information.
let layout_j =
match self.kind() {
let layout_j = match self.kind() {
// `CoroutineWitness` should not appear in actual code, so we
// can't compute their layout---and we don't need it---so we just
// skip it.
&ty::TyKind::CoroutineWitness(_,_) => None,
_ => {
let layout = tcx
.layout_of(
ty::TypingEnv::fully_monomorphized().as_query_input(*self)
)
.unwrap_or_else(|e| {
panic!("failed to get layout of {:?}: {}", self, e)
});
let layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*self))
.unwrap_or_else(|e| panic!("failed to get layout of {:?}: {}", self, e));
let field_offsets = match layout.fields {
// `FieldsShape::Primitive` has no fields.
FieldsShape::Primitive => None,
// `FieldsShape::Union` puts all fields at offset zero.
FieldsShape::Union(_) => None,
// `FieldsShape::Array` is used only for array-like types, for which offsets
// are easy to compute if needed.
FieldsShape::Array { .. } => {
assert!(matches!(self.kind(),
ty::TyKind::Array(..) | ty::TyKind::Slice(..) | ty::TyKind::Str),
"unexpected TyKind {:?} for FieldsShape::Array", self.kind());
None
},
FieldsShape::Arbitrary { ref offsets, .. } => {
Some(offsets.iter().map(|&off| off.bytes()).collect::<Vec<_>>())
},
};
if layout.is_sized() {
Some(json!({
"align": layout.align.abi.bytes(),
"size": layout.size.bytes()
}))
"size": layout.size.bytes(),
"field_offsets": field_offsets
}))
} else {
// TODO: provide field offsets even for unsized types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you open a mir-json issue to track this task?

None
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/schema_ver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
/// Each version of the schema is assumed to be backwards-incompatible with
/// previous versions of the schema. As such, any time this version number is
/// bumped, it should be treated as a major version bump.
pub const SCHEMA_VER: u64 = 9;
pub const SCHEMA_VER: u64 = 10;