GaloisInc / mir-json

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

Missing predicate for polymorphic trait implementation #10

Closed sweirich closed 5 years ago

sweirich commented 5 years ago

Consider this code

struct Data<T>(T);
trait G {
    fn g (&self) -> u32;
}
impl <T:G> G for Data<T> {
    fn g(&self) -> u32 {
        self.0.g()
    }
}

The function g produced by mir-json is lacking the predicate that the parameter must implement G.
(In fact, it has no predicates.)

fn ::{{impl}}[1]::g(_1 : &::Data<_0>) -> u32  {
   let mut _0 : u32;
   let mut _2 : &_0;
   bb0: {
      StorageLive(_2);
      _2 = &*_1.0;
      call(_0 = ::G::g<_0>(_2),bb1)
   }
   bb1: {
      StorageDead(_2);
      return;
   }
}
spernsteiner commented 5 years ago

As of 08059b316f496d20bcb7be6c8491b324f5588603, fns entries now inherit the generics.params and predicates from their enclosing elements. For example, on this code:

struct S<T>(T);

impl<A: Clone> S<A> {
  fn f<B: From<A>>(&self) -> B {
    self.0.clone().into()
  }
}

the crux-mir representation is:

// Type parameter _0 is A, and _1 is B.
fn ::{{impl}}::f(_1 : &::S<_0>) -> _1 where [::marker::Sized<_1>
                                            ,::convert::From<_1,_0>
                                            ,::marker::Sized<_0>
                                            ,::clone::Clone<_0>] {
  // ...
}

Also, the JSON output now includes the def path for each type parameter, in case crux-mir ever needs to distinguish impl/trait params from ones directly on the fn:

"generics": {
    "params": [
        {
            "def_id": "::{{impl}}[0]::A[0]",
            "param_def": "A"
        },
        {
            "def_id": "::{{impl}}[0]::f[0]::B[0]",
            "param_def": "B"
        }
    ]
},