kornelski / rust-rgb

struct RGB for sharing pixels between crates
https://lib.rs/rgb
MIT License
97 stars 19 forks source link

0.8.42 breaks build #116

Closed tronical closed 1 month ago

tronical commented 1 month ago

We see build errors in Slint with the 0.8.42 release:

error[E0599]: the method `as_bytes` exists for reference `&SharedPixelBuffer<Rgb<u8>>`, but its trait bounds were not satisfied
  --> internal/core/graphics/image/cache.rs:18:59
   |
18 |                 SharedImageBuffer::RGB8(pixels) => pixels.as_bytes().len(),
   |                                                           ^^^^^^^^ method cannot be called on `&SharedPixelBuffer<Rgb<u8>>` due to unsatisfied trait bounds
   |
note: trait bound `[RGB<u8>]: ComponentBytes<u8>` was not satisfied
  --> internal/core/graphics/image.rs:94:14
   |
92 | impl<Pixel: Clone + rgb::Pod> SharedPixelBuffer<Pixel>
   |                               ------------------------
93 | where
94 |     [Pixel]: rgb::ComponentBytes<u8>,
   |              ^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following traits define an item `as_bytes`, perhaps you need to implement one of them:
           candidate #1: `ComponentBytes`
           candidate #2: `EncodableLayout`
           candidate #3: `OsStrExt`
           candidate #4: `rgb::legacy::internal::pixel::ComponentBytes`

Bisection suggests that this regressed with commit 788e50fa60247a5c6954944c9319abfe7088ef2d

Since 0.8.42 is a patch release, this unfortunately breaks the build of our existing releases.

ogoffart commented 1 month ago

Reduced testcase:

pub type Rgb8Pixel = rgb::RGB8;

#[derive(Debug, Clone)]
#[repr(C)]
pub struct SharedPixelBuffer<Pixel> {
    data: Vec<Pixel>,
}

impl<Pixel: Clone + rgb::Pod> SharedPixelBuffer<Pixel>
where
    [Pixel]: rgb::ComponentBytes<u8>,
{
    pub fn as_bytes(&self) -> &[u8] {
        todo!()
        //use rgb::ComponentBytes;
        //self.data.as_slice().as_bytes()
    }
}

pub fn foo(pixels: &SharedPixelBuffer<Rgb8Pixel>) {
    let _ = pixels.as_bytes();
}

compiles with rgb 0.8.40 but not 0.8.42

ripytide commented 1 month ago

The underlying issue is the lack of Pod implementation on the pixel types like Rgb<u8> since that is now gated behind the bytemuck feature, I think making the bytemuck feature a default feature should fix this., wait,nevermind it's already default so that can't be the issue.

ripytide commented 1 month ago

Ah ok so the underlying issue is when we switched to a default generic implementation we use the pixel-level generic type parameter instead of the the component-level one as with the previous implementations. So this will compile:

pub type Rgb8Pixel = rgb::RGB8;

#[derive(Debug, Clone)]
#[repr(C)]
pub struct SharedPixelBuffer<Pixel> {
    data: Vec<Pixel>,
}

impl<Pixel: Clone + rgb::Pod> SharedPixelBuffer<Pixel>
where
    [Pixel]: rgb::ComponentBytes<Pixel>,
{
    pub fn as_bytes(&self) -> &[u8] {
        todo!()
        //use rgb::ComponentBytes;
        //self.data.as_slice().as_bytes()
    }
}

pub fn foo(pixels: &SharedPixelBuffer<Rgb8Pixel>) {
    let _ = pixels.as_bytes();
}

fn main() {}
kornelski commented 1 month ago

I've reverted the change, yanked 0.8.42, and released 0.8.43.

tronical commented 1 month ago

Thank you :)