为什么std :: ops :: Shl :: shl不等于<<?

llo*_*giq 8 types rust

mutagen中,我使用特化来尽可能地改变二进制操作.基本上,我a + b::mutagen::AddSub::add(a, b, mutation_count)Alas 替换,它在转换操作的情况下失败,因为类型推断失败.

我已经将问题简化为一个非常简单的测试用例:

use std::ops::Shl;

fn main() {
    println!("{}", 1u32.shl(2) * 3);
}
Run Code Online (Sandbox Code Playgroud)

这失败了error[E0277]: cannot multiply i32 to u32.这似乎是因为std::ops::Shl为各种整数实现的,而且那些impl总是返回自我类型(但不是Self,正如我从源头看到的那样),类型检查可能看不到它们,并且空出来,默认为i32.如果你替换了1u32.shl(2)(1u32 << 2),它的工作原理.

因此,转发std::ops::Shl/ Shr将无法使用自定义特征(如在pub trait AddSub)或使用包装类型作为操作的左侧.在这两种情况下,尽管知道,类型推断仍然无法看到整数移位的等式 SelfSelf::Output整数移位Self.

这是一个错误吗?有解决方法吗?是什么导致的?

llo*_*giq 5

这不是一个错误.其原因是对typeck中的非(或半)推断类型进行了一些特殊的二元操作处理.

解决方法是使用if-expression 修复表达式的返回类型,其中一个分支是原始二进制操作,另一个是变异操作,例如

(if ::mutagen::now(42) {
     ::mutagen::ShlShr::shl(left, right)
 } else {
     left << right
 })
Run Code Online (Sandbox Code Playgroud)