rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
95.41k stars 12.29k forks source link

fn where clause "constrains trait impls" or something #99211

Open leddoo opened 2 years ago

leddoo commented 2 years ago

the code below should be pretty self-explanatory. anyway, here's the run down:

I tried this code:

#![feature(portable_simd)]

use core::simd::*;

trait SimdExt<const N: usize> where LaneCount<N>: SupportedLaneCount {
    fn id(self) -> Self;
}

impl<const N: usize> SimdExt<N> for Simd<f32, N> where LaneCount<N>: SupportedLaneCount {
    fn id(self) -> Self { self }
}

// these are all the same.
// just adding the where clause breaks it.

fn fine() {
    let foo: f32x2 = f32x2::splat(0.0).id();
}

fn also_fine<const N: usize>() {
    let foo: f32x2 = f32x2::splat(0.0).id();
}

// this one doesn't compile
fn oops<const N: usize>() where LaneCount<N>: SupportedLaneCount {
    // the trait `SimdExt<N>` is not implemented for `std::simd::Simd<f32, 2_usize>`
    let foo: f32x2 = f32x2::splat(0.0).id();
}

// this function demonstrates the "constrains" part (it compiles just fine).
fn fine_again<const N: usize>() where LaneCount<N>: SupportedLaneCount {
    let foo: Simd<f32, N> = <Simd<f32, N>>::splat(0.0).id();
}

I expected to see this happen: it compiles.

Instead, this happened: it doesn't compile.

Meta

rustc --version --verbose:

rustc 1.64.0-nightly (1c7b36d4d 2022-07-12)
binary: rustc
commit-hash: 1c7b36d4db582cb47513a6c7176baaec1c3346ab
commit-date: 2022-07-12
host: x86_64-pc-windows-msvc
release: 1.64.0-nightly
LLVM version: 14.0.6

(i encountered this initially on 1.63.0 nightly, then upgraded hoping that it has been fixed in the latest version, which it wasn't)

leddoo commented 2 years ago

note that where LaneCount<N>: SupportedLaneCount, LaneCount<2_usize>: SupportedLaneCount doesn't work either. it somehow "unifies everything trying to use that trait with N".