mutagen icon indicating copy to clipboard operation
mutagen copied to clipboard

Possible other ways to mutate

Open vitiral opened this issue 7 years ago • 6 comments

From the reddit thread:

Some other possible ways to mutate rust:

  • Remove match arms, using _ => ... if necessary
  • When matching by value, match on different ones
  • Flip matches when values are not captured, i.e. match foo {A => ..., B => ...} becomes match foo {B => ..., A => ...}
    • this could be extended to values of any like-type, i.e. match foo { A(u32) => ..., B(u32) => ...} becomes match foo { B(u32) => ..., A(u32) => ...}

vitiral avatar Feb 16 '18 20:02 vitiral

Some other ideas:

  • Use into() way too liberally. For instance maybe you match on a Meter(meter) or Inch(inch) but inch implements Into<Meter> so you can do Meter(inch.into())
  • Clone things in places they shouldn't be, like &foo.clone() or even &mut foo.clone(). Helps answer the question "does foo really need to be mutable?"
  • use as in horrible places. (Inch as f64).into() -> Meter

vitiral avatar Feb 16 '18 20:02 vitiral

Thanks for writing this up. I should probably explain why we won't be able to implement all suggestions within mutagen: The plan is to mutate & compile once. The mutated code takes a global mutation number and changes behavior on that. So changing match expressions is basically only feasible by matching on an additional bool, which is generated by the mutagen helper. We still need the match to be complete, so we cannot simply deactivate match arms (unless a wildcard arm is present), but e.g. switching order might work (or may not change anything at all, if the match arms have no overlap). Flipping the match actions could work, too, if we can figure out the types (e.g. in simple cases).

llogiq avatar Feb 16 '18 21:02 llogiq

You could replace the match statement with a construct that does the same thing but allows more mutations..

hmvp avatar Feb 18 '18 10:02 hmvp

Unfortunately this is very hard to do without running afoul of the borrow checker.

llogiq avatar Feb 18 '18 11:02 llogiq

(About that earlier comment: We cannot even in general assume that things will implement Clone, unless we know the type. Even if we know the type we may not know if it can be cloned, for we can unfortunately only see the part of the code annotated with #[mutate].

llogiq avatar Feb 18 '18 11:02 llogiq

And about match statements, we could do something like changing:

match blub {
   Foo(x) => frobnicate(x),
   Bar(a, b) => a.adjunct(b),
   Baz => blubb(),
   _ => bleargh()
}

to (pseudocode):

match (mutagen::get(), blub) {
    (42, Foo(x)) => frobnicate(x),
    ..
} 

We should probably open a separate issue about that.

llogiq avatar Feb 18 '18 14:02 llogiq