<commit_before>use std::mem;
use std::io;
use std::slice;
use std::default::Default;

use color;
use color:: {
    Pixel,
    ColorType
};

/// An enumeration of Image Errors
#[deriving(Show, PartialEq, Eq)]
pub enum ImageError {
    ///The Image is not formatted properly
    FormatError(String),

    ///The Image's dimensions are either too small or too large
    DimensionError,

    ///The Decoder does not support this image format
    UnsupportedError(String),

    ///The Decoder does not support this color type
    UnsupportedColor(ColorType),

    ///Not enough data was provided to the Decoder
    ///to decode the image
    NotEnoughData,

    ///An I/O Error occurred while decoding the image
    IoError(io::IoError),

    ///The end of the image has been reached
    ImageEnd
}

pub type ImageResult<T> = Result<T, ImageError>;

/// An enumeration of supported image formats.
/// Not all formats support both encoding and decoding.
#[deriving(PartialEq, Eq, Show)]
pub enum ImageFormat {
    /// An Image in PNG Format
    PNG,

    /// An Image in JPEG Format
    JPEG,

    /// An Image in GIF Format
    GIF,

    /// An Image in WEBP Format
    WEBP,

    /// An Image in PPM Format
    PPM
}

/// The trait that all decoders implement
pub trait ImageDecoder {
    ///Return a tuple containing the width and height of the image
    fn dimensions(&mut self) -> ImageResult<(u32, u32)>;

    ///Return the color type of the image e.g RGB(8) (8bit RGB)
    fn colortype(&mut self) -> ImageResult<ColorType>;

    ///Returns the length in bytes of one decoded row of the image
    fn row_len(&mut self) -> ImageResult<uint>;

    ///Read one row from the image into buf
    ///Returns the row index
    fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;

    ///Decode the entire image and return it as a Vector
    fn read_image(&mut self) -> ImageResult<Vec<u8>>;

    ///Decode a specific region of the image, represented by the rectangle
    ///starting from ```x``` and ```y``` and having ```length``` and ```width```
    fn load_rect(&mut self, x: u32, y: u32, length: u32, width: u32) -> ImageResult<Vec<u8>> {
        let (w, h) = try!(self.dimensions());

        if length > h || width > w || x > w || y > h {
            return Err(DimensionError)
        }

        let c = try!(self.colortype());

        let bpp = color::bits_per_pixel(c) / 8;

        let rowlen  = try!(self.row_len());

        let mut buf = Vec::from_elem(length as uint * width as uint * bpp, 0u8);
        let mut tmp = Vec::from_elem(rowlen, 0u8);

        loop {
            let row = try!(self.read_scanline(tmp.as_mut_slice()));

            if row - 1 == y {
                break
            }
        }

        for i in range(0, length as uint) {
            {
                let from = tmp.slice_from(x as uint * bpp)
                              .slice_to(width as uint * bpp);

                let to   = buf.slice_from_mut(i * width as uint * bpp)
                              .slice_to_mut(width as uint * bpp);

                slice::bytes::copy_memory(to, from);
            }

            let _ = try!(self.read_scanline(tmp.as_mut_slice()));
        }

        Ok(buf)
    }
}

/// Immutable pixel iterator
pub struct Pixels<'a, I:'a> {
    image:  &'a I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> Iterator<(u32, u32, P)> for Pixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let pixel = self.image.get_pixel(self.x, self.y);
            let p = (self.x, self.y, pixel);

            self.x += 1;

            Some(p)
        }
    }
}

/// Mutable pixel iterator
pub struct MutPixels<'a, I:'a> {
    image:  &'a mut I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: MutableRefImage<P>> Iterator<(u32, u32, &'a mut P)> for MutPixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let tmp = self.image.get_mut_pixel(self.x, self.y);

            //error: lifetime of `self` is too short to guarantee its contents
            //       can be safely reborrowed...
            let ptr = unsafe {
                mem::transmute(tmp)
            };

            let p = (self.x, self.y, ptr);

            self.x += 1;

            Some(p)
        }
    }
}

///A trait for manipulating images.
pub trait GenericImage<P> {
    ///The width and height of this image.
    fn dimensions(&self) -> (u32, u32);

    ///The bounding rectangle of this image.
    fn bounds(&self) -> (u32, u32, u32, u32);

    ///Return the pixel located at (x, y)
    fn get_pixel(&self, x: u32, y: u32) -> P;

    ///Put a pixel at location (x, y)
    fn put_pixel(&mut self, x: u32, y: u32, pixel: P);

    ///Return an Iterator over the pixels of this image.
    ///The iterator yields the coordinates of each pixel
    ///along with their value
    fn pixels(&self) -> Pixels<Self> {
        let (width, height) = self.dimensions();

        Pixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }
}

///A trait for images that allow providing mutable references to pixels.
pub trait MutableRefImage<P>: GenericImage<P> {
    ///Return a mutable reference to the pixel located at (x, y)
    fn get_mut_pixel(&mut self, x: u32, y: u32) -> &mut P;

    ///Return an Iterator over mutable pixels of this image.
    ///The iterator yields the coordinates of each pixel
    ///along with a mutable reference to them.
    fn mut_pixels(&mut self) -> MutPixels<Self> {
        let (width, height) = self.dimensions();

        MutPixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }
}

///An Image whose pixels are contained within a vector
#[deriving(Clone)]
pub struct ImageBuf<P> {
    pixels:  Vec<P>,
    width:   u32,
    height:  u32,
}

impl<T: Primitive, P: Pixel<T>> ImageBuf<P> {
    ///Construct a new ImageBuf with the specified width and height.
    pub fn new(width: u32, height: u32) -> ImageBuf<P> {
        let pixel: P = Default::default();
        let pixels = Vec::from_elem((width * height) as uint, pixel.clone());

        ImageBuf {
            pixels:  pixels,
            width:   width,
            height:  height,
        }
    }

    ///Construct a new ImageBuf by repeated application of the supplied function.
    ///The arguments to the function are the pixel's x and y coordinates.
    pub fn from_fn(width: u32, height: u32, f: | u32, u32 | -> P) -> ImageBuf<P> {
        let mut pixels: Vec<P> = Vec::with_capacity((width * height) as uint);

        for y in range(0, height) {
            for x in range(0, width) {
                pixels.insert((y * width + x) as uint, f(x, y));
            }
        }

        ImageBuf::from_pixels(pixels, width, height)
    }

    ///Construct a new ImageBuf from a vector of pixels.
    pub fn from_pixels(pixels: Vec<P>, width: u32, height: u32) -> ImageBuf<P> {
        ImageBuf {
            pixels: pixels,
            width:  width,
            height: height,
        }
    }

    ///Construct a new ImageBuf from a pixel.
    pub fn from_pixel(width: u32, height: u32, pixel: P) -> ImageBuf<P> {
        let buf = Vec::from_elem(width as uint * height as uint, pixel.clone());

        ImageBuf::from_pixels(buf, width, height)
    }

    ///Return an immutable reference to this image's pixel buffer
    pub fn pixelbuf(&self) -> & [P] {
        self.pixels.as_slice()
    }

    ///Return a mutable reference to this image's pixel buffer
    pub fn mut_pixelbuf(&mut self) -> &mut [P] {
        self.pixels.as_mut_slice()
    }

    ///Destroy this ImageBuf, returning the internal vector
    pub fn into_vec(self) -> Vec<P> {
        self.pixels
    }

    ///Calls closure with immutable raw data of the image.
    ///Returns the result from the closure.
    pub fn with_bytes<U>(&self, f: | &[u8] | -> U) -> U {
        use std::mem::{ size_of, transmute };
        use std::raw::Slice;
        // Compute size of slice in bytes.
        let len = size_of::<P>() * self.pixels.len();
        let slice = Slice { data: self.pixels.as_ptr() as *const u8, len: len };
        f(unsafe { transmute(slice) })
    }

    ///Calls closure with mutable raw data of the image.
    ///Returns the result from the closure.
    pub fn with_mut_bytes<U>(&mut self, f: | &mut [u8] | -> U) -> U {
        use std::mem::{ size_of, transmute };
        use std::raw::Slice;
        // Compute size of slice in bytes.
        let len = size_of::<P>() * self.pixels.len();
        let slice = Slice { data: self.pixels.as_mut_ptr() as *const u8, len: len };
        f(unsafe { transmute(slice) })
    }
}

impl<T: Primitive, P: Pixel<T> + Clone + Copy> GenericImage<P> for ImageBuf<P> {
    fn dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }

    fn bounds(&self) -> (u32, u32, u32, u32) {
        (0, 0, self.width, self.height)
    }

    fn get_pixel(&self, x: u32, y: u32) -> P {
        let index  = y * self.width + x;

        self.pixels[index as uint]
    }

    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
        let index  = y * self.width + x;
        let buf    = self.pixels.as_mut_slice();

        buf[index as uint] = pixel;
    }
}

impl<T: Primitive, P: Pixel<T> + Clone + Copy> MutableRefImage<P> for ImageBuf<P> {
    fn get_mut_pixel(&mut self, x: u32, y: u32) -> &mut P {
        let index = y * self.width + x;

        self.pixels.get_mut(index as uint)
    }
}

impl<T: Primitive, P: Pixel<T>> Index<(u32, u32), P> for ImageBuf<P> {
    fn index(&self, coords: &(u32, u32)) -> &P {
        let &(x, y) = coords;
        let index  = y * self.width + x;

        &self.pixels[index as uint]
    }
}

/// A View into another image
pub struct SubImage <'a, I:'a> {
    image:   &'a mut I,
    xoffset: u32,
    yoffset: u32,
    xstride: u32,
    ystride: u32,
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> SubImage<'a, I> {
    ///Construct a new subimage
    pub fn new(image: &mut I, x: u32, y: u32, width: u32, height: u32) -> SubImage<I> {
        SubImage {
            image:   image,
            xoffset: x,
            yoffset: y,
            xstride: width,
            ystride: height,
        }
    }

    ///Return a mutable reference to the wrapped image.
    pub fn mut_inner(&mut self) -> &mut I {
        &mut (*self.image)
    }

    ///Change the coordinates of this subimage.
    pub fn change_bounds(&mut self, x: u32, y: u32, width: u32, height: u32) {
        self.xoffset = x;
        self.yoffset = y;
        self.xstride = width;
        self.ystride = height;
    }

    ///Convert this subimage to an ImageBuf
    pub fn to_image(&self) -> ImageBuf<P> {
        let p: P = Default::default();
        let mut out = ImageBuf::from_pixel(self.xstride, self.ystride, p.clone());

        for y in range(0, self.ystride) {
            for x in range(0, self.xstride) {
                let p = self.get_pixel(x, y);
                out.put_pixel(x, y, p);
            }
        }

        out
    }
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> GenericImage<P> for SubImage<'a, I> {
    fn dimensions(&self) -> (u32, u32) {
        (self.xstride, self.ystride)
    }

    fn bounds(&self) -> (u32, u32, u32, u32) {
        (self.xoffset, self.yoffset, self.xstride, self.ystride)
    }

    fn get_pixel(&self, x: u32, y: u32) -> P {
        self.image.get_pixel(x + self.xoffset, y + self.yoffset)
    }

    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
        self.image.put_pixel(x + self.xoffset, y + self.yoffset, pixel)
    }
}

impl<'a, T: Primitive, P: Pixel<T>, I: MutableRefImage<P>> MutableRefImage<P> for SubImage<'a, I> {
    fn get_mut_pixel(&mut self, x: u32, y: u32) -> &mut P {
        self.image.get_mut_pixel(x + self.xoffset, y + self.yoffset)
    }
}
<commit_msg>Use `rawbuf` and `mut_rawbuf` instead<commit_after>use std::mem;
use std::io;
use std::slice;
use std::default::Default;

use color;
use color:: {
    Pixel,
    ColorType
};

/// An enumeration of Image Errors
#[deriving(Show, PartialEq, Eq)]
pub enum ImageError {
    ///The Image is not formatted properly
    FormatError(String),

    ///The Image's dimensions are either too small or too large
    DimensionError,

    ///The Decoder does not support this image format
    UnsupportedError(String),

    ///The Decoder does not support this color type
    UnsupportedColor(ColorType),

    ///Not enough data was provided to the Decoder
    ///to decode the image
    NotEnoughData,

    ///An I/O Error occurred while decoding the image
    IoError(io::IoError),

    ///The end of the image has been reached
    ImageEnd
}

pub type ImageResult<T> = Result<T, ImageError>;

/// An enumeration of supported image formats.
/// Not all formats support both encoding and decoding.
#[deriving(PartialEq, Eq, Show)]
pub enum ImageFormat {
    /// An Image in PNG Format
    PNG,

    /// An Image in JPEG Format
    JPEG,

    /// An Image in GIF Format
    GIF,

    /// An Image in WEBP Format
    WEBP,

    /// An Image in PPM Format
    PPM
}

/// The trait that all decoders implement
pub trait ImageDecoder {
    ///Return a tuple containing the width and height of the image
    fn dimensions(&mut self) -> ImageResult<(u32, u32)>;

    ///Return the color type of the image e.g RGB(8) (8bit RGB)
    fn colortype(&mut self) -> ImageResult<ColorType>;

    ///Returns the length in bytes of one decoded row of the image
    fn row_len(&mut self) -> ImageResult<uint>;

    ///Read one row from the image into buf
    ///Returns the row index
    fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;

    ///Decode the entire image and return it as a Vector
    fn read_image(&mut self) -> ImageResult<Vec<u8>>;

    ///Decode a specific region of the image, represented by the rectangle
    ///starting from ```x``` and ```y``` and having ```length``` and ```width```
    fn load_rect(&mut self, x: u32, y: u32, length: u32, width: u32) -> ImageResult<Vec<u8>> {
        let (w, h) = try!(self.dimensions());

        if length > h || width > w || x > w || y > h {
            return Err(DimensionError)
        }

        let c = try!(self.colortype());

        let bpp = color::bits_per_pixel(c) / 8;

        let rowlen  = try!(self.row_len());

        let mut buf = Vec::from_elem(length as uint * width as uint * bpp, 0u8);
        let mut tmp = Vec::from_elem(rowlen, 0u8);

        loop {
            let row = try!(self.read_scanline(tmp.as_mut_slice()));

            if row - 1 == y {
                break
            }
        }

        for i in range(0, length as uint) {
            {
                let from = tmp.slice_from(x as uint * bpp)
                              .slice_to(width as uint * bpp);

                let to   = buf.slice_from_mut(i * width as uint * bpp)
                              .slice_to_mut(width as uint * bpp);

                slice::bytes::copy_memory(to, from);
            }

            let _ = try!(self.read_scanline(tmp.as_mut_slice()));
        }

        Ok(buf)
    }
}

/// Immutable pixel iterator
pub struct Pixels<'a, I:'a> {
    image:  &'a I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> Iterator<(u32, u32, P)> for Pixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let pixel = self.image.get_pixel(self.x, self.y);
            let p = (self.x, self.y, pixel);

            self.x += 1;

            Some(p)
        }
    }
}

/// Mutable pixel iterator
pub struct MutPixels<'a, I:'a> {
    image:  &'a mut I,
    x:      u32,
    y:      u32,
    width:  u32,
    height: u32
}

impl<'a, T: Primitive, P: Pixel<T>, I: MutableRefImage<P>> Iterator<(u32, u32, &'a mut P)> for MutPixels<'a, I> {
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
        if self.x >= self.width {
            self.x =  0;
            self.y += 1;
        }

        if self.y >= self.height {
            None
        } else {
            let tmp = self.image.get_mut_pixel(self.x, self.y);

            //error: lifetime of `self` is too short to guarantee its contents
            //       can be safely reborrowed...
            let ptr = unsafe {
                mem::transmute(tmp)
            };

            let p = (self.x, self.y, ptr);

            self.x += 1;

            Some(p)
        }
    }
}

///A trait for manipulating images.
pub trait GenericImage<P> {
    ///The width and height of this image.
    fn dimensions(&self) -> (u32, u32);

    ///The bounding rectangle of this image.
    fn bounds(&self) -> (u32, u32, u32, u32);

    ///Return the pixel located at (x, y)
    fn get_pixel(&self, x: u32, y: u32) -> P;

    ///Put a pixel at location (x, y)
    fn put_pixel(&mut self, x: u32, y: u32, pixel: P);

    ///Return an Iterator over the pixels of this image.
    ///The iterator yields the coordinates of each pixel
    ///along with their value
    fn pixels(&self) -> Pixels<Self> {
        let (width, height) = self.dimensions();

        Pixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }
}

///A trait for images that allow providing mutable references to pixels.
pub trait MutableRefImage<P>: GenericImage<P> {
    ///Return a mutable reference to the pixel located at (x, y)
    fn get_mut_pixel(&mut self, x: u32, y: u32) -> &mut P;

    ///Return an Iterator over mutable pixels of this image.
    ///The iterator yields the coordinates of each pixel
    ///along with a mutable reference to them.
    fn mut_pixels(&mut self) -> MutPixels<Self> {
        let (width, height) = self.dimensions();

        MutPixels {
            image:  self,
            x:      0,
            y:      0,
            width:  width,
            height: height,
        }
    }
}

///An Image whose pixels are contained within a vector
#[deriving(Clone)]
pub struct ImageBuf<P> {
    pixels:  Vec<P>,
    width:   u32,
    height:  u32,
}

impl<T: Primitive, P: Pixel<T>> ImageBuf<P> {
    ///Construct a new ImageBuf with the specified width and height.
    pub fn new(width: u32, height: u32) -> ImageBuf<P> {
        let pixel: P = Default::default();
        let pixels = Vec::from_elem((width * height) as uint, pixel.clone());

        ImageBuf {
            pixels:  pixels,
            width:   width,
            height:  height,
        }
    }

    ///Construct a new ImageBuf by repeated application of the supplied function.
    ///The arguments to the function are the pixel's x and y coordinates.
    pub fn from_fn(width: u32, height: u32, f: | u32, u32 | -> P) -> ImageBuf<P> {
        let mut pixels: Vec<P> = Vec::with_capacity((width * height) as uint);

        for y in range(0, height) {
            for x in range(0, width) {
                pixels.insert((y * width + x) as uint, f(x, y));
            }
        }

        ImageBuf::from_pixels(pixels, width, height)
    }

    ///Construct a new ImageBuf from a vector of pixels.
    pub fn from_pixels(pixels: Vec<P>, width: u32, height: u32) -> ImageBuf<P> {
        ImageBuf {
            pixels: pixels,
            width:  width,
            height: height,
        }
    }

    ///Construct a new ImageBuf from a pixel.
    pub fn from_pixel(width: u32, height: u32, pixel: P) -> ImageBuf<P> {
        let buf = Vec::from_elem(width as uint * height as uint, pixel.clone());

        ImageBuf::from_pixels(buf, width, height)
    }

    ///Return an immutable reference to this image's pixel buffer
    pub fn pixelbuf(&self) -> & [P] {
        self.pixels.as_slice()
    }

    ///Return a mutable reference to this image's pixel buffer
    pub fn mut_pixelbuf(&mut self) -> &mut [P] {
        self.pixels.as_mut_slice()
    }

    ///Destroy this ImageBuf, returning the internal vector
    pub fn into_vec(self) -> Vec<P> {
        self.pixels
    }

    ///Return an immutable reference to this image's raw data buffer
    pub fn rawbuf(&self) -> &[u8] {
        use std::mem::{ size_of, transmute };
        use std::raw::Slice;
        // Compute size of slice in bytes.
        let len = size_of::<P>() * self.pixels.len();
        let slice = Slice { data: self.pixels.as_ptr() as *const u8, len: len };
        unsafe { transmute(slice) }
    }

    ///Return a mutable reference to this image's raw data buffer
    pub fn mut_rawbuf(&mut self) -> &mut [u8] {
        use std::mem::{ size_of, transmute };
        use std::raw::Slice;
        // Compute size of slice in bytes.
        let len = size_of::<P>() * self.pixels.len();
        let slice = Slice { data: self.pixels.as_mut_ptr() as *const u8, len: len };
        unsafe { transmute(slice) }
    }
}

impl<T: Primitive, P: Pixel<T> + Clone + Copy> GenericImage<P> for ImageBuf<P> {
    fn dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }

    fn bounds(&self) -> (u32, u32, u32, u32) {
        (0, 0, self.width, self.height)
    }

    fn get_pixel(&self, x: u32, y: u32) -> P {
        let index  = y * self.width + x;

        self.pixels[index as uint]
    }

    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
        let index  = y * self.width + x;
        let buf    = self.pixels.as_mut_slice();

        buf[index as uint] = pixel;
    }
}

impl<T: Primitive, P: Pixel<T> + Clone + Copy> MutableRefImage<P> for ImageBuf<P> {
    fn get_mut_pixel(&mut self, x: u32, y: u32) -> &mut P {
        let index = y * self.width + x;

        self.pixels.get_mut(index as uint)
    }
}

impl<T: Primitive, P: Pixel<T>> Index<(u32, u32), P> for ImageBuf<P> {
    fn index(&self, coords: &(u32, u32)) -> &P {
        let &(x, y) = coords;
        let index  = y * self.width + x;

        &self.pixels[index as uint]
    }
}

/// A View into another image
pub struct SubImage <'a, I:'a> {
    image:   &'a mut I,
    xoffset: u32,
    yoffset: u32,
    xstride: u32,
    ystride: u32,
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> SubImage<'a, I> {
    ///Construct a new subimage
    pub fn new(image: &mut I, x: u32, y: u32, width: u32, height: u32) -> SubImage<I> {
        SubImage {
            image:   image,
            xoffset: x,
            yoffset: y,
            xstride: width,
            ystride: height,
        }
    }

    ///Return a mutable reference to the wrapped image.
    pub fn mut_inner(&mut self) -> &mut I {
        &mut (*self.image)
    }

    ///Change the coordinates of this subimage.
    pub fn change_bounds(&mut self, x: u32, y: u32, width: u32, height: u32) {
        self.xoffset = x;
        self.yoffset = y;
        self.xstride = width;
        self.ystride = height;
    }

    ///Convert this subimage to an ImageBuf
    pub fn to_image(&self) -> ImageBuf<P> {
        let p: P = Default::default();
        let mut out = ImageBuf::from_pixel(self.xstride, self.ystride, p.clone());

        for y in range(0, self.ystride) {
            for x in range(0, self.xstride) {
                let p = self.get_pixel(x, y);
                out.put_pixel(x, y, p);
            }
        }

        out
    }
}

impl<'a, T: Primitive, P: Pixel<T>, I: GenericImage<P>> GenericImage<P> for SubImage<'a, I> {
    fn dimensions(&self) -> (u32, u32) {
        (self.xstride, self.ystride)
    }

    fn bounds(&self) -> (u32, u32, u32, u32) {
        (self.xoffset, self.yoffset, self.xstride, self.ystride)
    }

    fn get_pixel(&self, x: u32, y: u32) -> P {
        self.image.get_pixel(x + self.xoffset, y + self.yoffset)
    }

    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
        self.image.put_pixel(x + self.xoffset, y + self.yoffset, pixel)
    }
}

impl<'a, T: Primitive, P: Pixel<T>, I: MutableRefImage<P>> MutableRefImage<P> for SubImage<'a, I> {
    fn get_mut_pixel(&mut self, x: u32, y: u32) -> &mut P {
        self.image.get_mut_pixel(x + self.xoffset, y + self.yoffset)
    }
}
<|endoftext|>


<commit_before><commit_msg>Added example for test generics<commit_after>struct InfoValue<V> {
    value: V,
    info: &'static str,
}

pub trait Info {
    fn get_info(&self) -> &'static str;
}

impl Info for InfoValue<u32>  {
    fn get_info(&self) -> &'static str {
        self.info
    }
}

struct ImprovedPoint<T: Info> {
    x: T,
    y: T,
}

struct ContainerEx {
    improved_integer: ImprovedPoint<InfoValue<u32>>
}

fn main() {
    let impr_x = InfoValue{value: 5, info: "is a 5"};
    let impr_y = InfoValue{value: 10, info: "is a 10"};
    let improved_integer = ImprovedPoint{x: impr_x, y: impr_y};
    let container = ContainerEx{improved_integer: improved_integer};

}
<|endoftext|>


<commit_before><commit_msg>rename params<commit_after><|endoftext|>


<commit_before><commit_msg>conversion test<commit_after><|endoftext|>


<commit_before><commit_msg>add state handling methods<commit_after>use Window;
use std::any::TypeId;
use std::mem::forget;
use std::collections::hash_map;
use std::hash::{Hasher, Writer};
use std::collections::hash_state::HashState;
use std::mem::transmute;
use std::raw::TraitObject;
use std::any::Any;

/// An extension of `AnyRefExt` allowing unchecked downcasting of trait objects to `&T`.
pub trait UncheckedAnyRefExt<'a> {
    /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
    /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
    unsafe fn downcast_ref_unchecked<T: 'static>(self) -> &'a T;
}

impl<'a> UncheckedAnyRefExt<'a> for &'a Any {
    #[inline]
    unsafe fn downcast_ref_unchecked<T: 'static>(self) -> &'a T {
        // Get the raw representation of the trait object
        let to: TraitObject = transmute(self);

        // Extract the data pointer
        transmute(to.data)
    }
}

/// An extension of `AnyMutRefExt` allowing unchecked downcasting of trait objects to `&mut T`.
pub trait UncheckedAnyMutRefExt<'a> {
    /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
    /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
    unsafe fn downcast_mut_unchecked<T: 'static>(self) -> &'a mut T;
}

impl<'a> UncheckedAnyMutRefExt<'a> for &'a mut Any {
    #[inline]
    unsafe fn downcast_mut_unchecked<T: 'static>(self) -> &'a mut T {
        // Get the raw representation of the trait object
        let to: TraitObject = transmute(self);

        // Extract the data pointer
        transmute(to.data)
    }
}

/// An extension of `BoxAny` allowing unchecked downcasting of trait objects to `Box<T>`.
pub trait UncheckedBoxAny {
    /// Returns the boxed value, assuming that it is of type `T`. This should only be called if you
    /// are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
    unsafe fn downcast_unchecked<T: 'static>(self) -> Box<T>;
}

impl UncheckedBoxAny for Box<Any + 'static> {
    #[inline]
    unsafe fn downcast_unchecked<T: 'static>(self) -> Box<T> {
        // Get the raw representation of the trait object
        let to: TraitObject = *transmute::<&Box<Any>, &TraitObject>(&self);

        // Prevent destructor on self being run
        forget(self);

        // Extract the data pointer
        transmute(to.data)
    }
}

#[test]
fn test_state(){
    let mut w = Window::new("",10,10);
    w.set_state([1,0,0,0,0,0,0,0,0,0,0,0], Box::new(34u8));
    assert!(w.find_state([1,0,0,0,0,0,0,0,0,0,0,0]) == Some(&34u8));

    w.set_state([1,1,2,1,1,1,1,1,4,0,0,0], Box::new(34u64));
    assert!(w.find_state([1,1,2,1,1,1,1,1,4,0,0,0]) == Some(&34u64));
}
<|endoftext|>


<commit_before><commit_msg>Create rr.rs<commit_after>use std::os;
use std::io;

fn main() {
    let args = os::args();
    let _prog = args[0].clone();
    let src_file = args[1].clone();
    let exec_args = args.slice_from(2);

    match io::Command::new("rustc").arg("-o").arg("/tmp/rust-exe").arg(src_file).spawn() {
        Ok(mut p) => {
            let output = p.stdout.get_mut_ref().read_to_string().unwrap() + p.stderr.get_mut_ref().read_to_string().unwrap();

            if output.len() != 0 {
                println!("COMPILE:\n================================================================================");
                print!("{}", output);

                if output.as_slice().contains("error:") {
                    return;
                }
                println!("\nEXECUTE:\n================================================================================");
            }
        },
        Err(e) => fail!("failed to execute process: {}", e),
    };

    match io::Command::new("/tmp/rust-exe").args(exec_args.as_slice()).spawn() {
        Ok(mut p) => {
            let output = p.stdout.get_mut_ref().read_to_string().unwrap() + p.stderr.get_mut_ref().read_to_string().unwrap();
            if output.len() != 0 {
                print!("{}", output);
            }
        },
        Err(e) => fail!("failed to execute process: {}", e),
    };
}
<|endoftext|>


<commit_before>use std::mem;

use proc_macro2::{Ident, Span, TokenStream};
use quote::{quote, ToTokens};
use syn::{
    parse_quote, punctuated::Pair, spanned::Spanned, Attribute, Data, DeriveInput, Fields,
    GenericArgument, Path, PathArguments, Type, TypePath,
};

mod wrap_incoming;

use wrap_incoming::Meta;

enum StructKind {
    Struct,
    Tuple,
}

pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
    if !input.generics.params.is_empty() {
        return Err(syn::Error::new_spanned(
            input.generics,
            "derive(Outgoing) doesn't currently support types with generics!",
        ));
    }

    let derive_deserialize = if no_deserialize_in_attrs(&input.attrs) {
        TokenStream::new()
    } else {
        quote!(#[derive(ruma_api::exports::serde::Deserialize)])
    };

    let (mut fields, struct_kind): (Vec<_>, _) = match input.data {
        Data::Enum(_) | Data::Union(_) => {
            panic!("#[derive(Outgoing)] is only supported for structs")
        }
        Data::Struct(s) => match s.fields {
            Fields::Named(fs) => {
                (fs.named.into_pairs().map(Pair::into_value).collect(), StructKind::Struct)
            }
            Fields::Unnamed(fs) => {
                (fs.unnamed.into_pairs().map(Pair::into_value).collect(), StructKind::Tuple)
            }
            Fields::Unit => return Ok(impl_outgoing_with_incoming_self(input.ident)),
        },
    };

    let mut any_attribute = false;

    for field in &mut fields {
        let mut field_meta = None;

        let mut remaining_attrs = Vec::new();
        for attr in mem::replace(&mut field.attrs, Vec::new()) {
            if let Some(meta) = Meta::from_attribute(&attr)? {
                if field_meta.is_some() {
                    return Err(syn::Error::new_spanned(
                        attr,
                        "duplicate #[wrap_incoming] attribute",
                    ));
                }
                field_meta = Some(meta);
                any_attribute = true;
            } else {
                remaining_attrs.push(attr);
            }
        }
        field.attrs = remaining_attrs;

        if let Some(attr) = field_meta {
            if let Some(type_to_wrap) = attr.type_to_wrap {
                wrap_generic_arg(&type_to_wrap, &mut field.ty, attr.wrapper_type.as_ref())?;
            } else {
                wrap_ty(&mut field.ty, attr.wrapper_type)?;
            }
        }
    }

    if !any_attribute {
        return Ok(impl_outgoing_with_incoming_self(input.ident));
    }

    let vis = input.vis;
    let doc = format!("'Incoming' variant of [{ty}](struct.{ty}.html).", ty = input.ident);
    let original_ident = input.ident;
    let incoming_ident = Ident::new(&format!("Incoming{}", original_ident), Span::call_site());

    let struct_def = match struct_kind {
        StructKind::Struct => quote! { { #(#fields,)* } },
        StructKind::Tuple => quote! { ( #(#fields,)* ); },
    };

    Ok(quote! {
        #[doc = #doc]
        #derive_deserialize
        #vis struct #incoming_ident #struct_def

        impl ruma_api::Outgoing for #original_ident {
            type Incoming = #incoming_ident;
        }
    })
}

fn no_deserialize_in_attrs(attrs: &[Attribute]) -> bool {
    for attr in attrs {
        match &attr.path {
            Path { leading_colon: None, segments }
                if segments.len() == 1 && segments[0].ident == "incoming_no_deserialize" =>
            {
                return true
            }
            _ => {}
        }
    }

    false
}

fn impl_outgoing_with_incoming_self(ident: Ident) -> TokenStream {
    quote! {
        impl ruma_api::Outgoing for #ident {
            type Incoming = Self;
        }
    }
}

fn wrap_ty(ty: &mut Type, path: Option<Path>) -> syn::Result<()> {
    if let Some(wrap_ty) = path {
        *ty = parse_quote!(#wrap_ty<#ty>);
    } else {
        match ty {
            Type::Path(TypePath { path, .. }) => {
                let ty_ident = &mut path.segments.last_mut().unwrap().ident;
                let ident = Ident::new(&format!("Incoming{}", ty_ident), Span::call_site());
                *ty_ident = parse_quote!(#ident);
            }
            _ => return Err(syn::Error::new_spanned(ty, "Can't wrap this type")),
        }
    }

    Ok(())
}

fn wrap_generic_arg(type_to_wrap: &Type, of: &mut Type, with: Option<&Path>) -> syn::Result<()> {
    let mut span = None;
    wrap_generic_arg_impl(type_to_wrap, of, with, &mut span)?;

    if span.is_some() {
        Ok(())
    } else {
        Err(syn::Error::new_spanned(
            of,
            format!(
                "Couldn't find generic argument `{}` in this type",
                type_to_wrap.to_token_stream()
            ),
        ))
    }
}

fn wrap_generic_arg_impl(
    type_to_wrap: &Type,
    of: &mut Type,
    with: Option<&Path>,
    span: &mut Option<Span>,
) -> syn::Result<()> {
    // TODO: Support things like array types?
    let ty_path = match of {
        Type::Path(TypePath { path, .. }) => path,
        _ => return Ok(()),
    };

    let args = match &mut ty_path.segments.last_mut().unwrap().arguments {
        PathArguments::AngleBracketed(ab) => &mut ab.args,
        _ => return Ok(()),
    };

    for arg in args.iter_mut() {
        let ty = match arg {
            GenericArgument::Type(ty) => ty,
            _ => continue,
        };

        if ty == type_to_wrap {
            if let Some(s) = span {
                let mut error = syn::Error::new(
                    *s,
                    format!(
                        "`{}` found multiple times, this is not currently supported",
                        type_to_wrap.to_token_stream()
                    ),
                );
                error.combine(syn::Error::new_spanned(ty, "second occurrence"));
                return Err(error);
            }

            *span = Some(ty.span());

            if let Some(wrapper_type) = with {
                *ty = parse_quote!(#wrapper_type<#ty>);
            } else if let Type::Path(TypePath { path, .. }) = ty {
                let ty_ident = &mut path.segments.last_mut().unwrap().ident;
                let ident = Ident::new(&format!("Incoming{}", ty_ident), Span::call_site());
                *ty_ident = parse_quote!(#ident);
            } else {
                return Err(syn::Error::new_spanned(ty, "Can't wrap this type"));
            }
        } else {
            wrap_generic_arg_impl(type_to_wrap, ty, with, span)?;
        }
    }

    Ok(())
}
<commit_msg>Use quote::format_ident!<commit_after>use std::mem;

use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::{
    parse_quote, punctuated::Pair, spanned::Spanned, Attribute, Data, DeriveInput, Fields,
    GenericArgument, Path, PathArguments, Type, TypePath,
};

mod wrap_incoming;

use wrap_incoming::Meta;

enum StructKind {
    Struct,
    Tuple,
}

pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
    if !input.generics.params.is_empty() {
        return Err(syn::Error::new_spanned(
            input.generics,
            "derive(Outgoing) doesn't currently support types with generics!",
        ));
    }

    let derive_deserialize = if no_deserialize_in_attrs(&input.attrs) {
        TokenStream::new()
    } else {
        quote!(#[derive(ruma_api::exports::serde::Deserialize)])
    };

    let (mut fields, struct_kind): (Vec<_>, _) = match input.data {
        Data::Enum(_) | Data::Union(_) => {
            panic!("#[derive(Outgoing)] is only supported for structs")
        }
        Data::Struct(s) => match s.fields {
            Fields::Named(fs) => {
                (fs.named.into_pairs().map(Pair::into_value).collect(), StructKind::Struct)
            }
            Fields::Unnamed(fs) => {
                (fs.unnamed.into_pairs().map(Pair::into_value).collect(), StructKind::Tuple)
            }
            Fields::Unit => return Ok(impl_outgoing_with_incoming_self(input.ident)),
        },
    };

    let mut any_attribute = false;

    for field in &mut fields {
        let mut field_meta = None;

        let mut remaining_attrs = Vec::new();
        for attr in mem::replace(&mut field.attrs, Vec::new()) {
            if let Some(meta) = Meta::from_attribute(&attr)? {
                if field_meta.is_some() {
                    return Err(syn::Error::new_spanned(
                        attr,
                        "duplicate #[wrap_incoming] attribute",
                    ));
                }
                field_meta = Some(meta);
                any_attribute = true;
            } else {
                remaining_attrs.push(attr);
            }
        }
        field.attrs = remaining_attrs;

        if let Some(attr) = field_meta {
            if let Some(type_to_wrap) = attr.type_to_wrap {
                wrap_generic_arg(&type_to_wrap, &mut field.ty, attr.wrapper_type.as_ref())?;
            } else {
                wrap_ty(&mut field.ty, attr.wrapper_type)?;
            }
        }
    }

    if !any_attribute {
        return Ok(impl_outgoing_with_incoming_self(input.ident));
    }

    let vis = input.vis;
    let doc = format!("'Incoming' variant of [{ty}](struct.{ty}.html).", ty = input.ident);
    let original_ident = input.ident;
    let incoming_ident = format_ident!("Incoming{}", original_ident, span = Span::call_site());

    let struct_def = match struct_kind {
        StructKind::Struct => quote! { { #(#fields,)* } },
        StructKind::Tuple => quote! { ( #(#fields,)* ); },
    };

    Ok(quote! {
        #[doc = #doc]
        #derive_deserialize
        #vis struct #incoming_ident #struct_def

        impl ruma_api::Outgoing for #original_ident {
            type Incoming = #incoming_ident;
        }
    })
}

fn no_deserialize_in_attrs(attrs: &[Attribute]) -> bool {
    for attr in attrs {
        match &attr.path {
            Path { leading_colon: None, segments }
                if segments.len() == 1 && segments[0].ident == "incoming_no_deserialize" =>
            {
                return true
            }
            _ => {}
        }
    }

    false
}

fn impl_outgoing_with_incoming_self(ident: Ident) -> TokenStream {
    quote! {
        impl ruma_api::Outgoing for #ident {
            type Incoming = Self;
        }
    }
}

fn wrap_ty(ty: &mut Type, path: Option<Path>) -> syn::Result<()> {
    if let Some(wrap_ty) = path {
        *ty = parse_quote!(#wrap_ty<#ty>);
    } else {
        match ty {
            Type::Path(TypePath { path, .. }) => {
                let ty_ident = &mut path.segments.last_mut().unwrap().ident;
                let ident = format_ident!("Incoming{}", ty_ident, span = Span::call_site());
                *ty_ident = parse_quote!(#ident);
            }
            _ => return Err(syn::Error::new_spanned(ty, "Can't wrap this type")),
        }
    }

    Ok(())
}

fn wrap_generic_arg(type_to_wrap: &Type, of: &mut Type, with: Option<&Path>) -> syn::Result<()> {
    let mut span = None;
    wrap_generic_arg_impl(type_to_wrap, of, with, &mut span)?;

    if span.is_some() {
        Ok(())
    } else {
        Err(syn::Error::new_spanned(
            of,
            format!(
                "Couldn't find generic argument `{}` in this type",
                type_to_wrap.to_token_stream()
            ),
        ))
    }
}

fn wrap_generic_arg_impl(
    type_to_wrap: &Type,
    of: &mut Type,
    with: Option<&Path>,
    span: &mut Option<Span>,
) -> syn::Result<()> {
    // TODO: Support things like array types?
    let ty_path = match of {
        Type::Path(TypePath { path, .. }) => path,
        _ => return Ok(()),
    };

    let args = match &mut ty_path.segments.last_mut().unwrap().arguments {
        PathArguments::AngleBracketed(ab) => &mut ab.args,
        _ => return Ok(()),
    };

    for arg in args.iter_mut() {
        let ty = match arg {
            GenericArgument::Type(ty) => ty,
            _ => continue,
        };

        if ty == type_to_wrap {
            if let Some(s) = span {
                let mut error = syn::Error::new(
                    *s,
                    format!(
                        "`{}` found multiple times, this is not currently supported",
                        type_to_wrap.to_token_stream()
                    ),
                );
                error.combine(syn::Error::new_spanned(ty, "second occurrence"));
                return Err(error);
            }

            *span = Some(ty.span());

            if let Some(wrapper_type) = with {
                *ty = parse_quote!(#wrapper_type<#ty>);
            } else if let Type::Path(TypePath { path, .. }) = ty {
                let ty_ident = &mut path.segments.last_mut().unwrap().ident;
                let ident = format_ident!("Incoming{}", ty_ident, span = Span::call_site());
                *ty_ident = parse_quote!(#ident);
            } else {
                return Err(syn::Error::new_spanned(ty, "Can't wrap this type"));
            }
        } else {
            wrap_generic_arg_impl(type_to_wrap, ty, with, span)?;
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>add mod file for torchvision<commit_after>pub mod transforms;
pub mod datasets;<|endoftext|>


<commit_before>use rustc::mir;
use rustc::ty::{self, Ty};
use rustc::ty::layout::LayoutOf;
use syntax::codemap::Span;
use rustc_target::spec::abi::Abi;

use rustc::mir::interpret::{EvalResult, Scalar, Value};
use super::{EvalContext, Place, Machine, ValTy};

use rustc_data_structures::indexed_vec::Idx;
use interpret::memory::HasMemory;

mod drop;

impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
    pub fn goto_block(&mut self, target: mir::BasicBlock) {
        self.frame_mut().block = target;
        self.frame_mut().stmt = 0;
    }

    pub(super) fn eval_terminator(
        &mut self,
        terminator: &mir::Terminator<'tcx>,
    ) -> EvalResult<'tcx> {
        use rustc::mir::TerminatorKind::*;
        match terminator.kind {
            Return => {
                self.dump_local(self.frame().return_place);
                self.pop_stack_frame()?
            }

            Goto { target } => self.goto_block(target),

            SwitchInt {
                ref discr,
                ref values,
                ref targets,
                ..
            } => {
                let discr_val = self.eval_operand(discr)?;
                let discr_prim = self.value_to_scalar(discr_val)?;

                // Branch to the `otherwise` case by default, if no match is found.
                let mut target_block = targets[targets.len() - 1];

                for (index, &const_int) in values.iter().enumerate() {
                    if discr_prim.to_bits(self.layout_of(discr_val.ty).unwrap().size)? == const_int {
                        target_block = targets[index];
                        break;
                    }
                }

                self.goto_block(target_block);
            }

            Call {
                ref func,
                ref args,
                ref destination,
                ..
            } => {
                let destination = match *destination {
                    Some((ref lv, target)) => Some((self.eval_place(lv)?, target)),
                    None => None,
                };

                let func = self.eval_operand(func)?;
                let (fn_def, sig) = match func.ty.sty {
                    ty::TyFnPtr(sig) => {
                        let fn_ptr = self.value_to_scalar(func)?.to_ptr()?;
                        let instance = self.memory.get_fn(fn_ptr)?;
                        let instance_ty = instance.ty(*self.tcx);
                        match instance_ty.sty {
                            ty::TyFnDef(..) => {
                                let real_sig = instance_ty.fn_sig(*self.tcx);
                                let sig = self.tcx.normalize_erasing_late_bound_regions(
                                    ty::ParamEnv::reveal_all(),
                                    &sig,
                                );
                                let real_sig = self.tcx.normalize_erasing_late_bound_regions(
                                    ty::ParamEnv::reveal_all(),
                                    &real_sig,
                                );
                                if !self.check_sig_compat(sig, real_sig)? {
                                    return err!(FunctionPointerTyMismatch(real_sig, sig));
                                }
                            }
                            ref other => bug!("instance def ty: {:?}", other),
                        }
                        (instance, sig)
                    }
                    ty::TyFnDef(def_id, substs) => (
                        self.resolve(def_id, substs)?,
                        func.ty.fn_sig(*self.tcx),
                    ),
                    _ => {
                        let msg = format!("can't handle callee of type {:?}", func.ty);
                        return err!(Unimplemented(msg));
                    }
                };
                let args = self.operands_to_args(args)?;
                let sig = self.tcx.normalize_erasing_late_bound_regions(
                    ty::ParamEnv::reveal_all(),
                    &sig,
                );
                self.eval_fn_call(
                    fn_def,
                    destination,
                    &args,
                    terminator.source_info.span,
                    sig,
                )?;
            }

            Drop {
                ref location,
                target,
                ..
            } => {
                // FIXME(CTFE): forbid drop in const eval
                let place = self.eval_place(location)?;
                let ty = self.place_ty(location);
                let ty = self.tcx.subst_and_normalize_erasing_regions(
                    self.substs(),
                    ty::ParamEnv::reveal_all(),
                    &ty,
                );
                trace!("TerminatorKind::drop: {:?}, type {}", location, ty);

                let instance = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
                self.drop_place(
                    place,
                    instance,
                    ty,
                    terminator.source_info.span,
                    target,
                )?;
            }

            Assert {
                ref cond,
                expected,
                ref msg,
                target,
                ..
            } => {
                let cond_val = self.eval_operand_to_scalar(cond)?.to_bool()?;
                if expected == cond_val {
                    self.goto_block(target);
                } else {
                    use rustc::mir::interpret::EvalErrorKind::*;
                    return match *msg {
                        BoundsCheck { ref len, ref index } => {
                            let len = self.eval_operand_to_scalar(len)
                                .expect("can't eval len")
                                .to_bits(self.memory().pointer_size())? as u64;
                            let index = self.eval_operand_to_scalar(index)
                                .expect("can't eval index")
                                .to_bits(self.memory().pointer_size())? as u64;
                            err!(BoundsCheck { len, index })
                        }
                        Overflow(op) => Err(Overflow(op).into()),
                        OverflowNeg => Err(OverflowNeg.into()),
                        DivisionByZero => Err(DivisionByZero.into()),
                        RemainderByZero => Err(RemainderByZero.into()),
                        GeneratorResumedAfterReturn |
                        GeneratorResumedAfterPanic => unimplemented!(),
                        _ => bug!(),
                    };
                }
            }

            Yield { .. } => unimplemented!("{:#?}", terminator.kind),
            GeneratorDrop => unimplemented!(),
            DropAndReplace { .. } => unimplemented!(),
            Resume => unimplemented!(),
            Abort => unimplemented!(),
            FalseEdges { .. } => bug!("should have been eliminated by `simplify_branches` mir pass"),
            FalseUnwind { .. } => bug!("should have been eliminated by `simplify_branches` mir pass"),
            Unreachable => return err!(Unreachable),
        }

        Ok(())
    }

    /// Decides whether it is okay to call the method with signature `real_sig` using signature `sig`.
    /// FIXME: This should take into account the platform-dependent ABI description.
    fn check_sig_compat(
        &mut self,
        sig: ty::FnSig<'tcx>,
        real_sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx, bool> {
        fn check_ty_compat<'tcx>(ty: Ty<'tcx>, real_ty: Ty<'tcx>) -> bool {
            if ty == real_ty {
                return true;
            } // This is actually a fast pointer comparison
            return match (&ty.sty, &real_ty.sty) {
                // Permit changing the pointer type of raw pointers and references as well as
                // mutability of raw pointers.
                // TODO: Should not be allowed when fat pointers are involved.
                (&ty::TyRawPtr(_), &ty::TyRawPtr(_)) => true,
                (&ty::TyRef(_, _, _), &ty::TyRef(_, _, _)) => {
                    ty.is_mutable_pointer() == real_ty.is_mutable_pointer()
                }
                // rule out everything else
                _ => false,
            };
        }

        if sig.abi == real_sig.abi && sig.variadic == real_sig.variadic &&
            sig.inputs_and_output.len() == real_sig.inputs_and_output.len() &&
            sig.inputs_and_output
                .iter()
                .zip(real_sig.inputs_and_output)
                .all(|(ty, real_ty)| check_ty_compat(ty, real_ty))
        {
            // Definitely good.
            return Ok(true);
        }

        if sig.variadic || real_sig.variadic {
            // We're not touching this
            return Ok(false);
        }

        // We need to allow what comes up when a non-capturing closure is cast to a fn().
        match (sig.abi, real_sig.abi) {
            (Abi::Rust, Abi::RustCall) // check the ABIs.  This makes the test here non-symmetric.
                if check_ty_compat(sig.output(), real_sig.output()) && real_sig.inputs_and_output.len() == 3 => {
                // First argument of real_sig must be a ZST
                let fst_ty = real_sig.inputs_and_output[0];
                if self.layout_of(fst_ty)?.is_zst() {
                    // Second argument must be a tuple matching the argument list of sig
                    let snd_ty = real_sig.inputs_and_output[1];
                    match snd_ty.sty {
                        ty::TyTuple(tys) if sig.inputs().len() == tys.len() =>
                            if sig.inputs().iter().zip(tys).all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) {
                                return Ok(true)
                            },
                        _ => {}
                    }
                }
            }
            _ => {}
        };

        // Nope, this doesn't work.
        return Ok(false);
    }

    fn eval_fn_call(
        &mut self,
        instance: ty::Instance<'tcx>,
        destination: Option<(Place, mir::BasicBlock)>,
        args: &[ValTy<'tcx>],
        span: Span,
        sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx> {
        trace!("eval_fn_call: {:#?}", instance);
        match instance.def {
            ty::InstanceDef::Intrinsic(..) => {
                let (ret, target) = match destination {
                    Some(dest) => dest,
                    _ => return err!(Unreachable),
                };
                let ty = sig.output();
                let layout = self.layout_of(ty)?;
                M::call_intrinsic(self, instance, args, ret, layout, target)?;
                self.dump_local(ret);
                Ok(())
            }
            // FIXME: figure out why we can't just go through the shim
            ty::InstanceDef::ClosureOnceShim { .. } => {
                if M::eval_fn_call(self, instance, destination, args, span, sig)? {
                    return Ok(());
                }
                let mut arg_locals = self.frame().mir.args_iter();
                match sig.abi {
                    // closure as closure once
                    Abi::RustCall => {
                        for (arg_local, &valty) in arg_locals.zip(args) {
                            let dest = self.eval_place(&mir::Place::Local(arg_local))?;
                            self.write_value(valty, dest)?;
                        }
                    }
                    // non capture closure as fn ptr
                    // need to inject zst ptr for closure object (aka do nothing)
                    // and need to pack arguments
                    Abi::Rust => {
                        trace!(
                            "arg_locals: {:?}",
                            self.frame().mir.args_iter().collect::<Vec<_>>()
                        );
                        trace!("args: {:?}", args);
                        let local = arg_locals.nth(1).unwrap();
                        for (i, &valty) in args.into_iter().enumerate() {
                            let dest = self.eval_place(&mir::Place::Local(local).field(
                                mir::Field::new(i),
                                valty.ty,
                            ))?;
                            self.write_value(valty, dest)?;
                        }
                    }
                    _ => bug!("bad ABI for ClosureOnceShim: {:?}", sig.abi),
                }
                Ok(())
            }
            ty::InstanceDef::FnPtrShim(..) |
            ty::InstanceDef::DropGlue(..) |
            ty::InstanceDef::CloneShim(..) |
            ty::InstanceDef::Item(_) => {
                // Push the stack frame, and potentially be entirely done if the call got hooked
                if M::eval_fn_call(self, instance, destination, args, span, sig)? {
                    return Ok(());
                }

                // Pass the arguments
                let mut arg_locals = self.frame().mir.args_iter();
                trace!("ABI: {:?}", sig.abi);
                trace!(
                    "arg_locals: {:?}",
                    self.frame().mir.args_iter().collect::<Vec<_>>()
                );
                trace!("args: {:?}", args);
                match sig.abi {
                    Abi::RustCall => {
                        assert_eq!(args.len(), 2);

                        {
                            // write first argument
                            let first_local = arg_locals.next().unwrap();
                            let dest = self.eval_place(&mir::Place::Local(first_local))?;
                            self.write_value(args[0], dest)?;
                        }

                        // unpack and write all other args
                        let layout = self.layout_of(args[1].ty)?;
                        if let ty::TyTuple(..) = args[1].ty.sty {
                            if self.frame().mir.args_iter().count() == layout.fields.count() + 1 {
                                match args[1].value {
                                    Value::ByRef(ptr, align) => {
                                        for (i, arg_local) in arg_locals.enumerate() {
                                            let field = layout.field(&self, i)?;
                                            let offset = layout.fields.offset(i);
                                            let arg = Value::ByRef(ptr.ptr_offset(offset, &self)?,
                                                                   align.min(field.align));
                                            let dest =
                                                self.eval_place(&mir::Place::Local(arg_local))?;
                                            trace!(
                                                "writing arg {:?} to {:?} (type: {})",
                                                arg,
                                                dest,
                                                field.ty
                                            );
                                            let valty = ValTy {
                                                value: arg,
                                                ty: field.ty,
                                            };
                                            self.write_value(valty, dest)?;
                                        }
                                    }
                                    Value::Scalar(Scalar::Bits { defined: 0, .. }) => {}
                                    other => {
                                        trace!("{:#?}, {:#?}", other, layout);
                                        let mut layout = layout;
                                        'outer: loop {
                                            for i in 0..layout.fields.count() {
                                                let field = layout.field(&self, i)?;
                                                if layout.fields.offset(i).bytes() == 0 && layout.size == field.size {
                                                    layout = field;
                                                    continue 'outer;
                                                }
                                            }
                                            break;
                                        }
                                        let dest = self.eval_place(&mir::Place::Local(
                                            arg_locals.next().unwrap(),
                                        ))?;
                                        let valty = ValTy {
                                            value: other,
                                            ty: layout.ty,
                                        };
                                        self.write_value(valty, dest)?;
                                    }
                                }
                            } else {
                                trace!("manual impl of rust-call ABI");
                                // called a manual impl of a rust-call function
                                let dest = self.eval_place(
                                    &mir::Place::Local(arg_locals.next().unwrap()),
                                )?;
                                self.write_value(args[1], dest)?;
                            }
                        } else {
                            bug!(
                                "rust-call ABI tuple argument was {:#?}, {:#?}",
                                args[1].ty,
                                layout
                            );
                        }
                    }
                    _ => {
                        for (arg_local, &valty) in arg_locals.zip(args) {
                            let dest = self.eval_place(&mir::Place::Local(arg_local))?;
                            self.write_value(valty, dest)?;
                        }
                    }
                }
                Ok(())
            }
            // cannot use the shim here, because that will only result in infinite recursion
            ty::InstanceDef::Virtual(_, idx) => {
                let ptr_size = self.memory.pointer_size();
                let ptr_align = self.tcx.data_layout.pointer_align;
                let (ptr, vtable) = self.into_ptr_vtable_pair(args[0].value)?;
                let fn_ptr = self.memory.read_ptr_sized(
                    vtable.offset(ptr_size * (idx as u64 + 3), &self)?,
                    ptr_align
                )?.to_ptr()?;
                let instance = self.memory.get_fn(fn_ptr)?;
                let mut args = args.to_vec();
                let ty = self.layout_of(args[0].ty)?.field(&self, 0)?.ty;
                args[0].ty = ty;
                args[0].value = ptr.to_value();
                // recurse with concrete function
                self.eval_fn_call(instance, destination, &args, span, sig)
            }
        }
    }
}
<commit_msg>Pull a layout computation out of a loop<commit_after>use rustc::mir;
use rustc::ty::{self, Ty};
use rustc::ty::layout::LayoutOf;
use syntax::codemap::Span;
use rustc_target::spec::abi::Abi;

use rustc::mir::interpret::{EvalResult, Scalar, Value};
use super::{EvalContext, Place, Machine, ValTy};

use rustc_data_structures::indexed_vec::Idx;
use interpret::memory::HasMemory;

mod drop;

impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
    pub fn goto_block(&mut self, target: mir::BasicBlock) {
        self.frame_mut().block = target;
        self.frame_mut().stmt = 0;
    }

    pub(super) fn eval_terminator(
        &mut self,
        terminator: &mir::Terminator<'tcx>,
    ) -> EvalResult<'tcx> {
        use rustc::mir::TerminatorKind::*;
        match terminator.kind {
            Return => {
                self.dump_local(self.frame().return_place);
                self.pop_stack_frame()?
            }

            Goto { target } => self.goto_block(target),

            SwitchInt {
                ref discr,
                ref values,
                ref targets,
                ..
            } => {
                let discr_val = self.eval_operand(discr)?;
                let discr_prim = self.value_to_scalar(discr_val)?;
                let discr_layout = self.layout_of(discr_val.ty).unwrap();
                trace!("SwitchInt({:?}, {:#?})", discr_prim, discr_layout);
                let discr_prim = discr_prim.to_bits(discr_layout.size)?;

                // Branch to the `otherwise` case by default, if no match is found.
                let mut target_block = targets[targets.len() - 1];

                for (index, &const_int) in values.iter().enumerate() {
                    if discr_prim == const_int {
                        target_block = targets[index];
                        break;
                    }
                }

                self.goto_block(target_block);
            }

            Call {
                ref func,
                ref args,
                ref destination,
                ..
            } => {
                let destination = match *destination {
                    Some((ref lv, target)) => Some((self.eval_place(lv)?, target)),
                    None => None,
                };

                let func = self.eval_operand(func)?;
                let (fn_def, sig) = match func.ty.sty {
                    ty::TyFnPtr(sig) => {
                        let fn_ptr = self.value_to_scalar(func)?.to_ptr()?;
                        let instance = self.memory.get_fn(fn_ptr)?;
                        let instance_ty = instance.ty(*self.tcx);
                        match instance_ty.sty {
                            ty::TyFnDef(..) => {
                                let real_sig = instance_ty.fn_sig(*self.tcx);
                                let sig = self.tcx.normalize_erasing_late_bound_regions(
                                    ty::ParamEnv::reveal_all(),
                                    &sig,
                                );
                                let real_sig = self.tcx.normalize_erasing_late_bound_regions(
                                    ty::ParamEnv::reveal_all(),
                                    &real_sig,
                                );
                                if !self.check_sig_compat(sig, real_sig)? {
                                    return err!(FunctionPointerTyMismatch(real_sig, sig));
                                }
                            }
                            ref other => bug!("instance def ty: {:?}", other),
                        }
                        (instance, sig)
                    }
                    ty::TyFnDef(def_id, substs) => (
                        self.resolve(def_id, substs)?,
                        func.ty.fn_sig(*self.tcx),
                    ),
                    _ => {
                        let msg = format!("can't handle callee of type {:?}", func.ty);
                        return err!(Unimplemented(msg));
                    }
                };
                let args = self.operands_to_args(args)?;
                let sig = self.tcx.normalize_erasing_late_bound_regions(
                    ty::ParamEnv::reveal_all(),
                    &sig,
                );
                self.eval_fn_call(
                    fn_def,
                    destination,
                    &args,
                    terminator.source_info.span,
                    sig,
                )?;
            }

            Drop {
                ref location,
                target,
                ..
            } => {
                // FIXME(CTFE): forbid drop in const eval
                let place = self.eval_place(location)?;
                let ty = self.place_ty(location);
                let ty = self.tcx.subst_and_normalize_erasing_regions(
                    self.substs(),
                    ty::ParamEnv::reveal_all(),
                    &ty,
                );
                trace!("TerminatorKind::drop: {:?}, type {}", location, ty);

                let instance = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
                self.drop_place(
                    place,
                    instance,
                    ty,
                    terminator.source_info.span,
                    target,
                )?;
            }

            Assert {
                ref cond,
                expected,
                ref msg,
                target,
                ..
            } => {
                let cond_val = self.eval_operand_to_scalar(cond)?.to_bool()?;
                if expected == cond_val {
                    self.goto_block(target);
                } else {
                    use rustc::mir::interpret::EvalErrorKind::*;
                    return match *msg {
                        BoundsCheck { ref len, ref index } => {
                            let len = self.eval_operand_to_scalar(len)
                                .expect("can't eval len")
                                .to_bits(self.memory().pointer_size())? as u64;
                            let index = self.eval_operand_to_scalar(index)
                                .expect("can't eval index")
                                .to_bits(self.memory().pointer_size())? as u64;
                            err!(BoundsCheck { len, index })
                        }
                        Overflow(op) => Err(Overflow(op).into()),
                        OverflowNeg => Err(OverflowNeg.into()),
                        DivisionByZero => Err(DivisionByZero.into()),
                        RemainderByZero => Err(RemainderByZero.into()),
                        GeneratorResumedAfterReturn |
                        GeneratorResumedAfterPanic => unimplemented!(),
                        _ => bug!(),
                    };
                }
            }

            Yield { .. } => unimplemented!("{:#?}", terminator.kind),
            GeneratorDrop => unimplemented!(),
            DropAndReplace { .. } => unimplemented!(),
            Resume => unimplemented!(),
            Abort => unimplemented!(),
            FalseEdges { .. } => bug!("should have been eliminated by `simplify_branches` mir pass"),
            FalseUnwind { .. } => bug!("should have been eliminated by `simplify_branches` mir pass"),
            Unreachable => return err!(Unreachable),
        }

        Ok(())
    }

    /// Decides whether it is okay to call the method with signature `real_sig` using signature `sig`.
    /// FIXME: This should take into account the platform-dependent ABI description.
    fn check_sig_compat(
        &mut self,
        sig: ty::FnSig<'tcx>,
        real_sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx, bool> {
        fn check_ty_compat<'tcx>(ty: Ty<'tcx>, real_ty: Ty<'tcx>) -> bool {
            if ty == real_ty {
                return true;
            } // This is actually a fast pointer comparison
            return match (&ty.sty, &real_ty.sty) {
                // Permit changing the pointer type of raw pointers and references as well as
                // mutability of raw pointers.
                // TODO: Should not be allowed when fat pointers are involved.
                (&ty::TyRawPtr(_), &ty::TyRawPtr(_)) => true,
                (&ty::TyRef(_, _, _), &ty::TyRef(_, _, _)) => {
                    ty.is_mutable_pointer() == real_ty.is_mutable_pointer()
                }
                // rule out everything else
                _ => false,
            };
        }

        if sig.abi == real_sig.abi && sig.variadic == real_sig.variadic &&
            sig.inputs_and_output.len() == real_sig.inputs_and_output.len() &&
            sig.inputs_and_output
                .iter()
                .zip(real_sig.inputs_and_output)
                .all(|(ty, real_ty)| check_ty_compat(ty, real_ty))
        {
            // Definitely good.
            return Ok(true);
        }

        if sig.variadic || real_sig.variadic {
            // We're not touching this
            return Ok(false);
        }

        // We need to allow what comes up when a non-capturing closure is cast to a fn().
        match (sig.abi, real_sig.abi) {
            (Abi::Rust, Abi::RustCall) // check the ABIs.  This makes the test here non-symmetric.
                if check_ty_compat(sig.output(), real_sig.output()) && real_sig.inputs_and_output.len() == 3 => {
                // First argument of real_sig must be a ZST
                let fst_ty = real_sig.inputs_and_output[0];
                if self.layout_of(fst_ty)?.is_zst() {
                    // Second argument must be a tuple matching the argument list of sig
                    let snd_ty = real_sig.inputs_and_output[1];
                    match snd_ty.sty {
                        ty::TyTuple(tys) if sig.inputs().len() == tys.len() =>
                            if sig.inputs().iter().zip(tys).all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) {
                                return Ok(true)
                            },
                        _ => {}
                    }
                }
            }
            _ => {}
        };

        // Nope, this doesn't work.
        return Ok(false);
    }

    fn eval_fn_call(
        &mut self,
        instance: ty::Instance<'tcx>,
        destination: Option<(Place, mir::BasicBlock)>,
        args: &[ValTy<'tcx>],
        span: Span,
        sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx> {
        trace!("eval_fn_call: {:#?}", instance);
        match instance.def {
            ty::InstanceDef::Intrinsic(..) => {
                let (ret, target) = match destination {
                    Some(dest) => dest,
                    _ => return err!(Unreachable),
                };
                let ty = sig.output();
                let layout = self.layout_of(ty)?;
                M::call_intrinsic(self, instance, args, ret, layout, target)?;
                self.dump_local(ret);
                Ok(())
            }
            // FIXME: figure out why we can't just go through the shim
            ty::InstanceDef::ClosureOnceShim { .. } => {
                if M::eval_fn_call(self, instance, destination, args, span, sig)? {
                    return Ok(());
                }
                let mut arg_locals = self.frame().mir.args_iter();
                match sig.abi {
                    // closure as closure once
                    Abi::RustCall => {
                        for (arg_local, &valty) in arg_locals.zip(args) {
                            let dest = self.eval_place(&mir::Place::Local(arg_local))?;
                            self.write_value(valty, dest)?;
                        }
                    }
                    // non capture closure as fn ptr
                    // need to inject zst ptr for closure object (aka do nothing)
                    // and need to pack arguments
                    Abi::Rust => {
                        trace!(
                            "arg_locals: {:?}",
                            self.frame().mir.args_iter().collect::<Vec<_>>()
                        );
                        trace!("args: {:?}", args);
                        let local = arg_locals.nth(1).unwrap();
                        for (i, &valty) in args.into_iter().enumerate() {
                            let dest = self.eval_place(&mir::Place::Local(local).field(
                                mir::Field::new(i),
                                valty.ty,
                            ))?;
                            self.write_value(valty, dest)?;
                        }
                    }
                    _ => bug!("bad ABI for ClosureOnceShim: {:?}", sig.abi),
                }
                Ok(())
            }
            ty::InstanceDef::FnPtrShim(..) |
            ty::InstanceDef::DropGlue(..) |
            ty::InstanceDef::CloneShim(..) |
            ty::InstanceDef::Item(_) => {
                // Push the stack frame, and potentially be entirely done if the call got hooked
                if M::eval_fn_call(self, instance, destination, args, span, sig)? {
                    return Ok(());
                }

                // Pass the arguments
                let mut arg_locals = self.frame().mir.args_iter();
                trace!("ABI: {:?}", sig.abi);
                trace!(
                    "arg_locals: {:?}",
                    self.frame().mir.args_iter().collect::<Vec<_>>()
                );
                trace!("args: {:?}", args);
                match sig.abi {
                    Abi::RustCall => {
                        assert_eq!(args.len(), 2);

                        {
                            // write first argument
                            let first_local = arg_locals.next().unwrap();
                            let dest = self.eval_place(&mir::Place::Local(first_local))?;
                            self.write_value(args[0], dest)?;
                        }

                        // unpack and write all other args
                        let layout = self.layout_of(args[1].ty)?;
                        if let ty::TyTuple(..) = args[1].ty.sty {
                            if self.frame().mir.args_iter().count() == layout.fields.count() + 1 {
                                match args[1].value {
                                    Value::ByRef(ptr, align) => {
                                        for (i, arg_local) in arg_locals.enumerate() {
                                            let field = layout.field(&self, i)?;
                                            let offset = layout.fields.offset(i);
                                            let arg = Value::ByRef(ptr.ptr_offset(offset, &self)?,
                                                                   align.min(field.align));
                                            let dest =
                                                self.eval_place(&mir::Place::Local(arg_local))?;
                                            trace!(
                                                "writing arg {:?} to {:?} (type: {})",
                                                arg,
                                                dest,
                                                field.ty
                                            );
                                            let valty = ValTy {
                                                value: arg,
                                                ty: field.ty,
                                            };
                                            self.write_value(valty, dest)?;
                                        }
                                    }
                                    Value::Scalar(Scalar::Bits { defined: 0, .. }) => {}
                                    other => {
                                        trace!("{:#?}, {:#?}", other, layout);
                                        let mut layout = layout;
                                        'outer: loop {
                                            for i in 0..layout.fields.count() {
                                                let field = layout.field(&self, i)?;
                                                if layout.fields.offset(i).bytes() == 0 && layout.size == field.size {
                                                    layout = field;
                                                    continue 'outer;
                                                }
                                            }
                                            break;
                                        }
                                        let dest = self.eval_place(&mir::Place::Local(
                                            arg_locals.next().unwrap(),
                                        ))?;
                                        let valty = ValTy {
                                            value: other,
                                            ty: layout.ty,
                                        };
                                        self.write_value(valty, dest)?;
                                    }
                                }
                            } else {
                                trace!("manual impl of rust-call ABI");
                                // called a manual impl of a rust-call function
                                let dest = self.eval_place(
                                    &mir::Place::Local(arg_locals.next().unwrap()),
                                )?;
                                self.write_value(args[1], dest)?;
                            }
                        } else {
                            bug!(
                                "rust-call ABI tuple argument was {:#?}, {:#?}",
                                args[1].ty,
                                layout
                            );
                        }
                    }
                    _ => {
                        for (arg_local, &valty) in arg_locals.zip(args) {
                            let dest = self.eval_place(&mir::Place::Local(arg_local))?;
                            self.write_value(valty, dest)?;
                        }
                    }
                }
                Ok(())
            }
            // cannot use the shim here, because that will only result in infinite recursion
            ty::InstanceDef::Virtual(_, idx) => {
                let ptr_size = self.memory.pointer_size();
                let ptr_align = self.tcx.data_layout.pointer_align;
                let (ptr, vtable) = self.into_ptr_vtable_pair(args[0].value)?;
                let fn_ptr = self.memory.read_ptr_sized(
                    vtable.offset(ptr_size * (idx as u64 + 3), &self)?,
                    ptr_align
                )?.to_ptr()?;
                let instance = self.memory.get_fn(fn_ptr)?;
                let mut args = args.to_vec();
                let ty = self.layout_of(args[0].ty)?.field(&self, 0)?.ty;
                args[0].ty = ty;
                args[0].value = ptr.to_value();
                // recurse with concrete function
                self.eval_fn_call(instance, destination, &args, span, sig)
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>One more clippy warning (in FromForm derive).<commit_after><|endoftext|>


<commit_before>#![allow(unstable)]

extern crate shader_version;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate input;

use std::cell::RefCell;
use opengl_graphics::{
    Gl,
    Texture,
};
use sdl2_window::Sdl2Window;

fn main() {
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        event::WindowSettings {
            title: "Image".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let image = Path::new("./bin/assets/rust-logo.png");
    let image = Texture::from_path(&image).unwrap();
    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);
    for e in event::events(&window) {
        use event::RenderEvent;

        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([1.0; 4], gl);
                graphics::image(&image, &c, gl);
            });
        };
    }
}

<commit_msg>removed crate that is no longer in cargo package. Not needed to compile & run<commit_after>#![allow(unstable)]

extern crate shader_version;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use std::cell::RefCell;
use opengl_graphics::{
    Gl,
    Texture,
};
use sdl2_window::Sdl2Window;

fn main() {
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        event::WindowSettings {
            title: "Image".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let image = Path::new("./bin/assets/rust-logo.png");
    let image = Texture::from_path(&image).unwrap();
    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);
    for e in event::events(&window) {
        use event::RenderEvent;

        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([1.0; 4], gl);
                graphics::image(&image, &c, gl);
            });
        };
    }
}

<|endoftext|>