GaloisInc / mir-json

Plugin for rustc to dump MIR in JSON format
Apache License 2.0
8 stars 2 forks source link

Distinguish ADT instantiations that use const generics #64

Open RyanGlScott opened 8 months ago

RyanGlScott commented 8 months ago

Consider this code:

pub struct S<const N: usize> {
    pub x: [u32; N]
}

pub fn f(y: [u32; 1]) -> S<1> {
    S { x: y }
}

pub fn g(y: [u32; 2]) -> S<2> {
    S { x: y }
}

The f and g functions return two different instantiations of the S struct. While S<1> and S<2> look distinct at the source level, they are not so distinct at the MIR level:

```json "tys": [ { "name": "ty::Adt::ccb7a3d199d9879b", "ty": { "kind": "Adt", "name": "test/00d7a51d::S::_adt72feacd62a9e3865[0]", "orig_def_id": "test/00d7a51d::S", "substs": [ "nonty::Const" ] } }, { "name": "ty::Adt::5b888c1bd33ee4cb", "ty": { "kind": "Adt", "name": "test/00d7a51d::S::_adta30875ee2d695833[0]", "orig_def_id": "test/00d7a51d::S", "substs": [ "nonty::Const" ] } } ] ``` ```json "adts": [ { "kind": { "kind": "Struct" }, "name": "test/00d7a51d::S::_adt72feacd62a9e3865[0]", "orig_def_id": "test/00d7a51d::S", "orig_substs": [ "nonty::Const" ], "repr_transparent": false, "size": 4, "variants": [ { "ctor_kind": null, "discr": { "index": 0, "kind": "Relative" }, "discr_value": null, "fields": [ { "name": "test/00d7a51d::S::x", "ty": "ty::Array::6d2918a465036a67" } ], "inhabited": true, "name": "test/00d7a51d::S" } ] }, { "kind": { "kind": "Struct" }, "name": "test/00d7a51d::S::_adta30875ee2d695833[0]", "orig_def_id": "test/00d7a51d::S", "orig_substs": [ "nonty::Const" ], "repr_transparent": false, "size": 8, "variants": [ { "ctor_kind": null, "discr": { "index": 0, "kind": "Relative" }, "discr_value": null, "fields": [ { "name": "test/00d7a51d::S::x", "ty": "ty::Array::cef0e4ed0a308aa2" } ], "inhabited": true, "name": "test/00d7a51d::S" } ] } ] ```

Both occurrences of S are represented as ADTs with their const parameter instantiated with nonty::Const. This is a challenge for tools like SAW, which look up ADTs in a type-directed way. One might imagine writing something like this to look up S<1> or S<2>:

mir_find_adt m "test::S" [mir_const];

Where mir_const represents nonty::Const. The problem is that this is ambiguous, as it could refer to both S<1> and S<2>. Moreover, the JSON doesn't provide a straightforward way to tell which ADT was instantiated with <1> and which was instantiated with <2>.

I propose that we change the representation of nonty::Const to also include the particular constant that was used for the instantiation. That way, SAW users could write something like:

mir_find_adt m "test::S" [mir_const {{ 1 }}];
mir_find_adt m "test::S" [mir_const {{ 2 }}];

MIR's GenericArgKind::Const should provide all the information necessary to encode this constant information.