我相信你在这里看到的是,primitive types并不是真正意义上的std::ops
.这std::ops
条可能只是为了无缝的trait 扩展,等等.我认为Rust Tidbits: What Is a Lang Item?篇博文部分解释了这一点.
我导出了你的例子that works with primitive types的和平号.我得到:
bb5: {
StorageDead(_9); // bb5[0]: scope 1 at src/main.rs:6:8: 6:9
_10 = CheckedAdd((*_8), move _5); // bb5[1]: scope 1 at src/main.rs:6:5: 6:17
assert(!move (_10.1: bool), "attempt to add with overflow") -> [success: bb6, unwind: bb4]; // bb5[2]: scope 1 at src/main.rs:6:5: 6:17
}
对于出错的代码,我很难导出MIR.在没有借阅判断的情况下输出MIR对我来说是一件 fresh 事,我不知道该怎么做.
Thisplayground 有一个非常相似的东西,但汇编:)
它给我打了一个add_assign
的电话:
bb3: {
_8 = _9; // bb3[0]: scope 1 at src/main.rs:14:5: 14:9
StorageDead(_10); // bb3[1]: scope 1 at src/main.rs:14:8: 14:9
StorageLive(_11); // bb3[2]: scope 1 at src/main.rs:14:14: 14:22
(_11.0: i32) = const 1i32; // bb3[3]: scope 1 at src/main.rs:14:14: 14:22
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000001))
// mir::Constant
// + span: src/main.rs:14:20: 14:21
// + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
_7 = const <MyNum as std::ops::AddAssign>::add_assign(move _8, move _11) -> [return: bb5, unwind: bb4]; // bb3[4]: scope 1 at src/main.rs:14:5: 14:22
// ty::Const
// + ty: for<'r> fn(&'r mut MyNum, MyNum) {<MyNum as std::ops::AddAssign>::add_assign}
// + val: Value(Scalar(<ZST>))
// mir::Constant
// + span: src/main.rs:14:5: 14:22
// + literal: Const { ty: for<'r> fn(&'r mut MyNum, MyNum) {<MyNum as std::ops::AddAssign>::add_assign}, val: Value(Scalar(<ZST>)) }
}
原始 case 如何通过借阅判断器?因为不调用add_assign
,所以可以在需要可变引用之前删除不可变引用.MIR只是在前面取消对所需位置的引用,并按值传递它.
bb3: {
_5 = (*_6); // bb3[0]: scope 1 at src/main.rs:6:13: 6:17
StorageDead(_7); // bb3[1]: scope 1 at src/main.rs:6:16: 6:17
...
}