llogiq / mutagen

Breaking your Rust code for fun and profit
Apache License 2.0
625 stars 35 forks source link

Mutation: Remove statements #14

Open llogiq opened 6 years ago

llogiq commented 6 years ago

One of the more interesting mutations is removing code. Since Rust's semantics won't let us remove expressions, we can only remove statements, but even that comes with two caveats:

First, the statement may be a let statement, or an initializer for a deferred let, as in

let a = 5;
let b;
..
b = 8;

The latter may even be included in sub-statements e.g. within block expressions. Also we need to make sure the return statement (if any) is left intact. The only things we can safely remove without further analysis are assign-ops, e.g. a += 1.

However, if we choose to do the analysis, we can do it on block-level, we only need to apply a visitor to check for initializing assignments, but even there we only need the result for the whole statement. This will give us a crude data flow representation so we can for each statement find the shortest continuous range of statements we can remove without disrupting either subsequent statements or the return value.

hmvp commented 6 years ago

let statements can be replaced with default calls if the type implements default.

And while the last return statement should stay we could replace it with a default call if the type implements it.

Any other explicit returns expect for the last should also be removable. Although I suspect this will lead to a lot of non-halting functions..

Blocks like

let value = {
   computation...;
   result
}

should be replaceable with a default call