Open sweirich opened 5 years ago
mir-json
now outputs information on statics, including promoted statics.
The short version is:
Place::Static
now contains a reference to a static. Place::Promoted
contains a reference to a static, indirected through a table of promoted statics on the parent fn
.
Each static already produced an entry in fns
, containing a function that produces the static's initial value. Now promoted statics produce fns
as well.
There's a new top-level table, statics
, that contains metadata on each static (including promoted statics) in the crate.
Note that each static has only a single DefId, which is used in all three locations (the Place
, the entry in fns
, and the entry in statics
).
Now for the long version:
Places:
Place::Static
is now represented like this:
{
"kind": "Static",
"def_id": "::S[0]",
"ty": {
"kind": "Ref",
"mutability": {
"kind": "MutImmutable"
},
"ty": {
"kind": "Uint",
"uintkind": {
"kind": "usize"
}
}
}
}
Place::Promoted
is now represented like this:
{
"kind": "Promoted",
"index": 1,
"ty": {
"kind": "Uint",
"uintkind": {
"kind": "usize"
}
}
}
index
is an index into the promoted
table of the containing function.
MIR:
MIR function bodies in fns
now contain a table called promoted
, which lists the DefId of each promoted static from that MIR:
{
"name": "::f[0]",
// other fields...
"promoted": [
"::f[0]::{{promoted}}[0]",
"::f[0]::{{promoted}}[1]"
]
}
So the previous { "kind": "Promoted", "index": 1, ... }
Place
would be a reference to the promoted static ::f[0]::{{promoted}}[1]
, and an entry with "name": "::f[0]::{{promoted}}[1]"
should be present in both fns
and statics
.
Statics:
There is a new top-level table, statics
, which contains an entry for each static item and each promoted static in the crate. This is in addition to the entries that statics already had in fns
, so each static now has two entries in the JSON: an entry in fns
representing a zero-argument function that returns the static's initial value, and an entry in statics
with the same name
that contains (I believe) the necessary metadata to allocate storage for the static.
The statics
entry for a static item looks like this:
{
"name": "::S[0]",
"mutable": false, // Will be `true` for a `static mut` item
"ty": {
"kind": "Ref",
"mutability": {
"kind": "MutImmutable"
},
"ty": {
"kind": "Uint",
"uintkind": {
"kind": "usize"
}
}
}
}
The entry for a promoted static additionally has a back-reference to the function that produced it. Not sure if this is useful, but just in case you need it:
{
"name": "::f[0]::{{promoted}}[1]",
"ty": ..., // as above
"mutable": ..., // as above
"promoted_from": "::f[0]",
"promoted_index": 1,
},
Note, in case you haven't seen it before, Rust's handling of function pointers is a bit unusual. If you write this:
fn f() { ... }
let fp = f;
then the type of fp
is not fn()
(the type of pointers to nullary functions returning unit), but rather fn() {f}
, which encodes the fact that it's a pointer specifically to the function f
into the type (internally, this is written TyKind::FnDef(<f's DefId>)
), and which takes up zero bytes at run time. So, in the MIR initializer function for the promoted static in by your example above, the reference to f
will likely appear only in the type of the zero-sized constant, and not in any Const
s or Rvalue
s.
Thanks! I've incorporated this update into mir-verifier. I'd hate for this comment to get lost though---it's good documentation for mir-json.
Thanks also for the info about Rust function pointers. We do have one (currently-failing) test case that uses a promoted function pointer. However, the type translation needs to be able to look up the type of 'f' to translate TyFnDef
correctly. I'll need to do some refactoring to make this info available in the right place, so I can fix that test case.
The following example
Generates a use of a
Promoted
lvalue in the definition of thef
function (in the definition of_4
).This promoted value is a constant function pointer to the
k
function, but that isn't clear from its definition. Should there be another definition in the MIR output that linkspromoted[0]
tok
?