fixes #79
This is a feature I'll definitely use in serde-xml, and probably implement it for json, too. Basically anything that processes tree-structures benefits enormously from it.
example run with miri:
Interpreting: factorial_recursive
TRACE:miri::interpreter: // bb0
TRACE:miri::interpreter: return = factorial_recursive::fact(const 10i64) -> bb1
TRACE:miri::interpreter: // bb0
TRACE:miri::interpreter: var0 = arg0
TRACE:miri::interpreter: tmp1 = var0
TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
TRACE:miri::interpreter: // bb3
TRACE:miri::interpreter: tmp2 = var0
TRACE:miri::interpreter: tmp5 = var0
TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
TRACE:miri::interpreter: // bb0
TRACE:miri::interpreter: var0 = arg0
TRACE:miri::interpreter: tmp1 = var0
TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
TRACE:miri::interpreter: // bb3
TRACE:miri::interpreter: tmp2 = var0
TRACE:miri::interpreter: tmp5 = var0
TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
TRACE:miri::interpreter: // bb0
TRACE:miri::interpreter: var0 = arg0
TRACE:miri::interpreter: tmp1 = var0
TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
TRACE:miri::interpreter: // bb3
TRACE:miri::interpreter: tmp2 = var0
TRACE:miri::interpreter: tmp5 = var0
TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
|TRACE:miri::interpreter: // bb0
|TRACE:miri::interpreter: var0 = arg0
|TRACE:miri::interpreter: tmp1 = var0
|TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
|TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
|TRACE:miri::interpreter: // bb3
|TRACE:miri::interpreter: tmp2 = var0
|TRACE:miri::interpreter: tmp5 = var0
|TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
|TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| TRACE:miri::interpreter: // bb0
| TRACE:miri::interpreter: var0 = arg0
| TRACE:miri::interpreter: tmp1 = var0
| TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| TRACE:miri::interpreter: // bb3
| TRACE:miri::interpreter: tmp2 = var0
| TRACE:miri::interpreter: tmp5 = var0
| TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
| TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| TRACE:miri::interpreter: // bb0
| TRACE:miri::interpreter: var0 = arg0
| TRACE:miri::interpreter: tmp1 = var0
| TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| TRACE:miri::interpreter: // bb3
| TRACE:miri::interpreter: tmp2 = var0
| TRACE:miri::interpreter: tmp5 = var0
| TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
| TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| TRACE:miri::interpreter: // bb0
| TRACE:miri::interpreter: var0 = arg0
| TRACE:miri::interpreter: tmp1 = var0
| TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| TRACE:miri::interpreter: // bb3
| TRACE:miri::interpreter: tmp2 = var0
| TRACE:miri::interpreter: tmp5 = var0
| TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
| TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| TRACE:miri::interpreter: // bb0
| TRACE:miri::interpreter: var0 = arg0
| TRACE:miri::interpreter: tmp1 = var0
| TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| TRACE:miri::interpreter: // bb3
| TRACE:miri::interpreter: tmp2 = var0
| TRACE:miri::interpreter: tmp5 = var0
| TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
| TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| |TRACE:miri::interpreter: // bb0
| |TRACE:miri::interpreter: var0 = arg0
| |TRACE:miri::interpreter: tmp1 = var0
| |TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| |TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| |TRACE:miri::interpreter: // bb3
| |TRACE:miri::interpreter: tmp2 = var0
| |TRACE:miri::interpreter: tmp5 = var0
| |TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
| |TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| | TRACE:miri::interpreter: // bb0
| | TRACE:miri::interpreter: var0 = arg0
| | TRACE:miri::interpreter: tmp1 = var0
| | TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| | TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| | TRACE:miri::interpreter: // bb3
| | TRACE:miri::interpreter: tmp2 = var0
| | TRACE:miri::interpreter: tmp5 = var0
| | TRACE:miri::interpreter: tmp4 = Sub(tmp5, const 1i64)
| | TRACE:miri::interpreter: tmp3 = factorial_recursive::fact(tmp4) -> bb4
| | TRACE:miri::interpreter: // bb0
| | TRACE:miri::interpreter: var0 = arg0
| | TRACE:miri::interpreter: tmp1 = var0
| | TRACE:miri::interpreter: tmp0 = Eq(tmp1, const 0i64)
| | TRACE:miri::interpreter: if(tmp0) -> [true: bb2, false: bb3]
| | TRACE:miri::interpreter: // bb2
| | TRACE:miri::interpreter: return = const 1i64
| | TRACE:miri::interpreter: goto -> bb1
| | TRACE:miri::interpreter: // bb1
| | TRACE:miri::interpreter: return
| | TRACE:miri::interpreter: // bb4
| | TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
| | TRACE:miri::interpreter: goto -> bb1
| | TRACE:miri::interpreter: // bb1
| | TRACE:miri::interpreter: return
| |TRACE:miri::interpreter: // bb4
| |TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
| |TRACE:miri::interpreter: goto -> bb1
| |TRACE:miri::interpreter: // bb1
| |TRACE:miri::interpreter: return
| TRACE:miri::interpreter: // bb4
| TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
| TRACE:miri::interpreter: goto -> bb1
| TRACE:miri::interpreter: // bb1
| TRACE:miri::interpreter: return
| TRACE:miri::interpreter: // bb4
| TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
| TRACE:miri::interpreter: goto -> bb1
| TRACE:miri::interpreter: // bb1
| TRACE:miri::interpreter: return
| TRACE:miri::interpreter: // bb4
| TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
| TRACE:miri::interpreter: goto -> bb1
| TRACE:miri::interpreter: // bb1
| TRACE:miri::interpreter: return
| TRACE:miri::interpreter: // bb4
| TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
| TRACE:miri::interpreter: goto -> bb1
| TRACE:miri::interpreter: // bb1
| TRACE:miri::interpreter: return
|TRACE:miri::interpreter: // bb4
|TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
|TRACE:miri::interpreter: goto -> bb1
|TRACE:miri::interpreter: // bb1
|TRACE:miri::interpreter: return
TRACE:miri::interpreter: // bb4
TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
TRACE:miri::interpreter: goto -> bb1
TRACE:miri::interpreter: // bb1
TRACE:miri::interpreter: return
TRACE:miri::interpreter: // bb4
TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
TRACE:miri::interpreter: goto -> bb1
TRACE:miri::interpreter: // bb1
TRACE:miri::interpreter: return
TRACE:miri::interpreter: // bb4
TRACE:miri::interpreter: return = Mul(tmp2, tmp3)
TRACE:miri::interpreter: goto -> bb1
TRACE:miri::interpreter: // bb1
TRACE:miri::interpreter: return
TRACE:miri::interpreter: // bb1
TRACE:miri::interpreter: return