rust - Unable to create default trait implementation
问题描述
I am trying to implement a vector math library that can generate SIMD optimized versions of a function based on the feature set supported by the processor. Currently I have a structure for each feature set and a trait that defines a fallback structure. I implement each operation on the feature set structure. I have not been able to implement the fallback mechanism. What I have now generates the flowing error.
error[E0119]: conflicting implementations of trait `Add<Vec4, Vec4>` for type `Scalar`:
--> src/main.rs:41:1
|
14 | default impl<F: FeatureSet, Lhs, Rhs> Add<Lhs, Rhs> for F where <F as FeatureSet>::Fallback: Add<Lhs, Rhs> {
| ---------------------------------------------------------------------------------------------------------- first implementation here
...
41 | impl Add<Vec4, Vec4> for Scalar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Scalar`
Does anyone have any suggestions on how to fix this?
Example code:
#![feature(specialization)]
use std::arch::x86_64 as arch;
trait FeatureSet {
type Fallback;
}
trait Add<Lhs, Rhs> {
type Output;
unsafe fn add(lhs: Lhs, rhs: Rhs) -> Self::Output;
}
// Attempt at implementing fallback to implementation in Fallback type
default impl<F: FeatureSet, Lhs, Rhs> Add<Lhs, Rhs> for F where <F as FeatureSet>::Fallback: Add<Lhs, Rhs> {
type Output = <<F as FeatureSet>::Fallback as Add<Lhs, Rhs>>::Output;
unsafe fn add(lhs: Lhs, rhs: Rhs) -> Self::Output {
<F as FeatureSet>::Fallback::add(lhs, rhs)
}
}
#[repr(C)]
union Vec4 {
scalar: std::mem::ManuallyDrop<[f32; 4]>,
#[allow(unused)]
simd: std::mem::ManuallyDrop<arch::__m128>,
}
impl std::convert::From<[f32; 4]> for Vec4 {
fn from(values: [f32; 4]) -> Self {
Self {
scalar: std::mem::ManuallyDrop::new(values)
}
}
}
struct Scalar;
impl FeatureSet for Scalar {
type Fallback = ();
}
impl Add<Vec4, Vec4> for Scalar {
type Output = Vec4;
unsafe fn add(lhs: Vec4, rhs: Vec4) -> Self::Output {
let mut r: [f32; 4] = std::mem::MaybeUninit::uninit().assume_init();
for i in 0 .. 4 {
r[i] = lhs.scalar[i] + rhs.scalar[i];
}
r.into()
}
}
struct Sse;
impl FeatureSet for Sse {
type Fallback = Scalar;
}
// Should fall back to implementation in FeatureSet::Fallback type when not implemented
impl Add<Vec4, Vec4> for Sse {
type Output = Vec4;
#[inline]
#[target_feature(enable = "sse")]
unsafe fn add(lhs: Vec4, rhs: Vec4) -> Self::Output {
let r = arch::_mm_add_ps(*lhs.simd, *rhs.simd);
Vec4 {
simd: std::mem::ManuallyDrop::new(r)
}
}
}
#[inline(never)]
// This function should be able to be specialized for each feature set for later
// runtime selection
unsafe fn perform_add<F: FeatureSet>(a: Vec4, b: Vec4) -> Vec4 {
F::add(a, b)
}
fn main() {
let a = [0.0, 1.0, 2.0, 3.0].into();
let b = [4.0, 4.0, 5.0, 6.0].into();
unsafe {
let c = perform_add::<Sse>(a, b);
println!("{} {} {} {}", c.scalar[0], c.scalar[1], c.scalar[2], c.scalar[3]);
}
}
解决方案
推荐阅读
- css - 如何减少引导列之间的间隙
- reactjs - 为什么我会收到此错误“TypeError:无法读取未定义的属性‘值’”
- c# - Unity Shader Graph中的平铺和偏移
- java - 通过restAssured 发送带有请求的cookie 的两种方式不同?
- django - 如何在模板标签中修改 {% block %}?
- java - 如何将我的 awt java 表单与 mysql 数据库连接?
- c++ - 将相同的值分配给 const 变量是否会导致 C++ 中的 UB?
- ssl - Grails SOAP WS 仅在 DEBUG 模式下因握手失败而失败 (intellij)
- libvirt - 如何将驱动程序信息作为 KVM 传递以将 PCI 设备添加到 VM 实例
- ruby-on-rails - 使用资源的自定义 URL