<commit_before>#![allow(non_upper_case_globals)]

extern crate libc;
extern crate xlib;
extern crate xinerama;

use self::libc::{ c_char, c_int, c_uint, c_void };
use self::libc::funcs::c95::stdlib::malloc;
use self::xlib::{
    Display,
    Window,
    XCrossingEvent,
    XSetWindowBorder,
    XSetWindowBorderWidth,
    XDefaultRootWindow,
    XDefaultScreenOfDisplay,
    XDisplayWidth,
    XDisplayHeight,
    XEnterWindowEvent,
    XFetchName,
    XLeaveWindowEvent,
    XMapRequestEvent,
    XMapWindow,
    XMotionEvent,
    XMoveWindow,
    XNextEvent,
    XOpenDisplay,
    XPending,
    XQueryTree,
    XResizeWindow,
    XRootWindowOfScreen,
    XScreenCount,
    XSelectInput,
    XSync
};
use self::xinerama::{
    XineramaQueryScreens,
    XineramaScreenInfo
};

use std::ptr::null_mut;
use std::mem::transmute;
use std::mem::uninitialized;
use std::str::raw::c_str_to_static_slice;
use std::slice::raw::buf_as_slice;

use window_system::{ Rectangle, WindowSystem, WindowSystemEvent };
use window_system::{
    Enter,
    Leave,
    WindowCreated,
    WindowDestroyed,
    UnknownEvent
};

const KeyPress               : uint =  2;
const KeyRelease             : uint =  3;
const ButtonPress            : uint =  4;
const ButtonRelease          : uint =  5;
const MotionNotify           : uint =  6;
const EnterNotify            : uint =  7;
const LeaveNotify            : uint =  8;
const FocusIn                : uint =  9;
const FocusOut               : uint = 10;
const KeymapNotify           : uint = 11;
const Expose                 : uint = 12;
const GraphicsExpose         : uint = 13;
const NoExpose               : uint = 14;
const VisibilityNotify       : uint = 15;
const CreateNotify           : uint = 16;
const DestroyNotify          : uint = 17;
const UnmapNotify            : uint = 18;
const MapNotify              : uint = 19;
const MapRequest             : uint = 20;
const ReparentNotify         : uint = 21;
const ConfigureNotify        : uint = 22;
const ConfigureRequest       : uint = 23;
const GravityNotify          : uint = 24;
const ResizeRequest          : uint = 25;
const CirculateNotify        : uint = 26;
const CirculateRequest       : uint = 27;
const PropertyNotify         : uint = 28;
const SelectionClear         : uint = 29;
const SelectionRequest       : uint = 30;
const SelectionNotify        : uint = 31;
const ColormapNotify         : uint = 32;
const ClientMessage          : uint = 33;
const MappingNotify          : uint = 34;

pub struct XlibWindowSystem {
    display: *mut Display,
    root:    Window,
    event:   *mut c_void
}

impl XlibWindowSystem {
    pub fn new() -> XlibWindowSystem {
        unsafe {
            let display = XOpenDisplay(null_mut());
            let screen  = XDefaultScreenOfDisplay(display);
            let root    = XRootWindowOfScreen(screen);

            XSelectInput(display, root, 0x180030);
            XSync(display, 0);

            XlibWindowSystem {
                display: display,
                root:    root,
                event:   malloc(256)
            }
        }
    }

    fn get_event_as<T>(&self) -> &T {
        unsafe {
            let event_ptr : *const T = transmute(self.event);
            let ref event = *event_ptr;
            event
        }
    }
}

impl WindowSystem for XlibWindowSystem {
    fn get_screen_infos(&self) -> Vec<Rectangle> {
        unsafe {
            let mut num : c_int = 0;
            let screen_ptr = XineramaQueryScreens(self.display, &mut num);

            // If xinerama is not active, just return the default display
            // dimensions and "emulate" xinerama.
            if num == 0 {
                return vec!(Rectangle(0, 0,
                                      self.get_display_width(0) as uint,
                                      self.get_display_height(0) as uint));
            }

            buf_as_slice(screen_ptr, num as uint, |x| {
                let mut result : Vec<Rectangle> = Vec::new();
                for &screen_info in x.iter() {
                    result.push(Rectangle(
                            screen_info.x_org as uint,
                            screen_info.y_org as uint,
                            screen_info.width as uint,
                            screen_info.height as uint));
                }
                result
            })
        }
    }

    fn get_number_of_screens(&self) -> uint {
        unsafe {
            XScreenCount(self.display) as uint
        }
    }

    fn get_display_width(&self, screen: uint) -> u32 {
        unsafe {
            XDisplayWidth(self.display, screen as i32) as u32
        }
    }

    fn get_display_height(&self, screen: uint) -> u32 {
        unsafe {
            XDisplayHeight(self.display, screen as i32) as u32
        }
    }

    fn get_window_name(&self, window: Window) -> String {
        if window == self.root { return String::from_str("root"); }
        unsafe {
            let mut name : *mut c_char = uninitialized();
            let name_ptr : *mut *mut c_char = &mut name;
            XFetchName(self.display, window, name_ptr);
            String::from_str(c_str_to_static_slice(transmute(*name_ptr)))
        }
    }

    fn get_windows(&self) -> Vec<Window> {
        unsafe {
            let mut unused = 0u64;
            let mut children : *mut u64 = uninitialized();
            let children_ptr : *mut *mut u64 = &mut children;
            let mut num_children : c_uint = 0;
            XQueryTree(self.display, self.root, &mut unused, &mut unused, children_ptr, &mut num_children);
            let const_children : *const u64 = children as *const u64;
            buf_as_slice(const_children, num_children as uint, |x| {
                let mut result : Vec<Window> = Vec::new();
                for &child in x.iter() {
                    if child != self.root {
                        result.push(child);
                    }
                }
                result
            })
        }
    }

    fn set_window_border_width(&mut self, window: Window, border_width: uint) {
        if window == self.root { return; }
        unsafe {
            XSetWindowBorderWidth(self.display, window, border_width as u32);
        }
    }

    fn set_window_border_color(&mut self, window: Window, border_color: uint) {
        if window == self.root { return; }
        unsafe {
            XSetWindowBorder(self.display, window, border_color as Window);
        }
    }

    fn resize_window(&mut self, window: Window, width: uint, height: uint) {
        unsafe {
            XResizeWindow(self.display, window, width as u32, height as u32);
        }
    }

    fn move_window(&mut self, window: Window, x: uint, y: uint) {
        unsafe {
            XMoveWindow(self.display, window, x as i32, y as i32);
        }
    }

    fn show_window(&mut self, window: Window) {
        unsafe {
            XMapWindow(self.display, window);
        }
    }

    fn event_pending(&self) -> bool {
        unsafe {
            XPending(self.display) != 0
        }
    }

    fn get_event(&mut self) -> WindowSystemEvent {
        unsafe {
            XSync(self.display, 0);
            XNextEvent(self.display, self.event);
        }

        let event_type : c_int = *self.get_event_as();

        match event_type as uint {
            MapRequest => {
                let event : &XMapRequestEvent = self.get_event_as();
                unsafe { XSelectInput(self.display, event.window, 0x000030); }
                WindowCreated(event.window)
            },
            EnterNotify => {
                let event : &XEnterWindowEvent = self.get_event_as();
                Enter(event.window)
            },
            LeaveNotify => {
                let event : &XLeaveWindowEvent = self.get_event_as();
                Leave(event.window)
            },
            _  => {
                debug!("Unknown event {}", event_type);
                UnknownEvent
            }
        }
    }
}
<commit_msg>added check for missing display<commit_after>#![allow(non_upper_case_globals)]

extern crate libc;
extern crate xlib;
extern crate xinerama;

use self::libc::{ c_char, c_int, c_uint, c_void };
use self::libc::funcs::c95::stdlib::malloc;
use self::xlib::{
    Display,
    Window,
    XCrossingEvent,
    XSetWindowBorder,
    XSetWindowBorderWidth,
    XDefaultRootWindow,
    XDefaultScreenOfDisplay,
    XDisplayWidth,
    XDisplayHeight,
    XEnterWindowEvent,
    XFetchName,
    XLeaveWindowEvent,
    XMapRequestEvent,
    XMapWindow,
    XMotionEvent,
    XMoveWindow,
    XNextEvent,
    XOpenDisplay,
    XPending,
    XQueryTree,
    XResizeWindow,
    XRootWindowOfScreen,
    XScreenCount,
    XSelectInput,
    XSync
};
use self::xinerama::{
    XineramaQueryScreens,
    XineramaScreenInfo
};

use std::os::env;
use std::ptr::null;
use std::ptr::null_mut;
use std::mem::transmute;
use std::mem::uninitialized;
use std::str::raw::c_str_to_static_slice;
use std::slice::raw::buf_as_slice;

use window_system::{ Rectangle, WindowSystem, WindowSystemEvent };
use window_system::{
    Enter,
    Leave,
    WindowCreated,
    WindowDestroyed,
    UnknownEvent
};

const KeyPress               : uint =  2;
const KeyRelease             : uint =  3;
const ButtonPress            : uint =  4;
const ButtonRelease          : uint =  5;
const MotionNotify           : uint =  6;
const EnterNotify            : uint =  7;
const LeaveNotify            : uint =  8;
const FocusIn                : uint =  9;
const FocusOut               : uint = 10;
const KeymapNotify           : uint = 11;
const Expose                 : uint = 12;
const GraphicsExpose         : uint = 13;
const NoExpose               : uint = 14;
const VisibilityNotify       : uint = 15;
const CreateNotify           : uint = 16;
const DestroyNotify          : uint = 17;
const UnmapNotify            : uint = 18;
const MapNotify              : uint = 19;
const MapRequest             : uint = 20;
const ReparentNotify         : uint = 21;
const ConfigureNotify        : uint = 22;
const ConfigureRequest       : uint = 23;
const GravityNotify          : uint = 24;
const ResizeRequest          : uint = 25;
const CirculateNotify        : uint = 26;
const CirculateRequest       : uint = 27;
const PropertyNotify         : uint = 28;
const SelectionClear         : uint = 29;
const SelectionRequest       : uint = 30;
const SelectionNotify        : uint = 31;
const ColormapNotify         : uint = 32;
const ClientMessage          : uint = 33;
const MappingNotify          : uint = 34;

pub struct XlibWindowSystem {
    display: *mut Display,
    root:    Window,
    event:   *mut c_void
}

impl XlibWindowSystem {
    pub fn new() -> XlibWindowSystem {
        unsafe {
            let display = XOpenDisplay(null_mut());

            if display == null_mut() {
                error!("No display found at {}",
                       env().iter()
                       .find(|&&(ref d, _)| *d == String::from_str("DISPLAY"))
                       .map(|&(_, ref v)| v.clone())
                       .unwrap());
                panic!("Exiting");
            }

            let screen  = XDefaultScreenOfDisplay(display);
            let root    = XRootWindowOfScreen(screen);

            XSelectInput(display, root, 0x180030);
            XSync(display, 0);

            XlibWindowSystem {
                display: display,
                root:    root,
                event:   malloc(256)
            }
        }
    }

    fn get_event_as<T>(&self) -> &T {
        unsafe {
            let event_ptr : *const T = transmute(self.event);
            let ref event = *event_ptr;
            event
        }
    }
}

impl WindowSystem for XlibWindowSystem {
    fn get_screen_infos(&self) -> Vec<Rectangle> {
        unsafe {
            let mut num : c_int = 0;
            let screen_ptr = XineramaQueryScreens(self.display, &mut num);

            // If xinerama is not active, just return the default display
            // dimensions and "emulate" xinerama.
            if num == 0 {
                return vec!(Rectangle(0, 0,
                                      self.get_display_width(0) as uint,
                                      self.get_display_height(0) as uint));
            }

            buf_as_slice(screen_ptr, num as uint, |x| {
                let mut result : Vec<Rectangle> = Vec::new();
                for &screen_info in x.iter() {
                    result.push(Rectangle(
                            screen_info.x_org as uint,
                            screen_info.y_org as uint,
                            screen_info.width as uint,
                            screen_info.height as uint));
                }
                result
            })
        }
    }

    fn get_number_of_screens(&self) -> uint {
        unsafe {
            XScreenCount(self.display) as uint
        }
    }

    fn get_display_width(&self, screen: uint) -> u32 {
        unsafe {
            XDisplayWidth(self.display, screen as i32) as u32
        }
    }

    fn get_display_height(&self, screen: uint) -> u32 {
        unsafe {
            XDisplayHeight(self.display, screen as i32) as u32
        }
    }

    fn get_window_name(&self, window: Window) -> String {
        if window == self.root { return String::from_str("root"); }
        unsafe {
            let mut name : *mut c_char = uninitialized();
            let name_ptr : *mut *mut c_char = &mut name;
            XFetchName(self.display, window, name_ptr);
            String::from_str(c_str_to_static_slice(transmute(*name_ptr)))
        }
    }

    fn get_windows(&self) -> Vec<Window> {
        unsafe {
            let mut unused = 0u64;
            let mut children : *mut u64 = uninitialized();
            let children_ptr : *mut *mut u64 = &mut children;
            let mut num_children : c_uint = 0;
            XQueryTree(self.display, self.root, &mut unused, &mut unused, children_ptr, &mut num_children);
            let const_children : *const u64 = children as *const u64;
            buf_as_slice(const_children, num_children as uint, |x| {
                let mut result : Vec<Window> = Vec::new();
                for &child in x.iter() {
                    if child != self.root {
                        result.push(child);
                    }
                }
                result
            })
        }
    }

    fn set_window_border_width(&mut self, window: Window, border_width: uint) {
        if window == self.root { return; }
        unsafe {
            XSetWindowBorderWidth(self.display, window, border_width as u32);
        }
    }

    fn set_window_border_color(&mut self, window: Window, border_color: uint) {
        if window == self.root { return; }
        unsafe {
            XSetWindowBorder(self.display, window, border_color as Window);
        }
    }

    fn resize_window(&mut self, window: Window, width: uint, height: uint) {
        unsafe {
            XResizeWindow(self.display, window, width as u32, height as u32);
        }
    }

    fn move_window(&mut self, window: Window, x: uint, y: uint) {
        unsafe {
            XMoveWindow(self.display, window, x as i32, y as i32);
        }
    }

    fn show_window(&mut self, window: Window) {
        unsafe {
            XMapWindow(self.display, window);
        }
    }

    fn event_pending(&self) -> bool {
        unsafe {
            XPending(self.display) != 0
        }
    }

    fn get_event(&mut self) -> WindowSystemEvent {
        unsafe {
            XSync(self.display, 0);
            XNextEvent(self.display, self.event);
        }

        let event_type : c_int = *self.get_event_as();

        match event_type as uint {
            MapRequest => {
                let event : &XMapRequestEvent = self.get_event_as();
                unsafe { XSelectInput(self.display, event.window, 0x000030); }
                WindowCreated(event.window)
            },
            EnterNotify => {
                let event : &XEnterWindowEvent = self.get_event_as();
                Enter(event.window)
            },
            LeaveNotify => {
                let event : &XLeaveWindowEvent = self.get_event_as();
                Leave(event.window)
            },
            _  => {
                debug!("Unknown event {}", event_type);
                UnknownEvent
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::backend::{Backend, SupportsOnConflictClause};
use crate::expression::SqlLiteral;
use crate::query_builder::*;
use crate::query_source::Column;
use crate::result::QueryResult;

#[cfg(feature = "postgres")]
pub use pg::on_constraint::*;

#[doc(hidden)]
pub trait OnConflictTarget<Table> {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct NoConflictTarget;

impl<DB> QueryFragment<DB> for NoConflictTarget
where
    DB: Backend + SupportsOnConflictClause,
{
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Table> OnConflictTarget<Table> for NoConflictTarget {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ConflictTarget<T>(pub T);

impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}

impl<DB, ST> QueryFragment<DB> for ConflictTarget<SqlLiteral<ST>>
where
    DB: Backend + SupportsOnConflictClause,
    SqlLiteral<ST>: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}

macro_rules! on_conflict_tuples {
    ($($col:ident),+) => {
        impl<DB, T, $($col),+> QueryFragment<DB> for ConflictTarget<(T, $($col),+)> where
            DB: Backend + SupportsOnConflictClause,
            T: Column,
            $($col: Column<Table=T::Table>,)+
        {
            fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
                out.push_sql(" (");
                out.push_identifier(T::NAME)?;
                $(
                    out.push_sql(", ");
                    out.push_identifier($col::NAME)?;
                )+
                out.push_sql(")");
                Ok(())
            }
        }

        impl<T, $($col),+> OnConflictTarget<T::Table> for ConflictTarget<(T, $($col),+)> where
            T: Column,
            $($col: Column<Table=T::Table>,)+
        {
        }
    }
}

on_conflict_tuples!(U);
on_conflict_tuples!(U, V);
on_conflict_tuples!(U, V, W);
on_conflict_tuples!(U, V, W, X);
on_conflict_tuples!(U, V, W, X, Y);
on_conflict_tuples!(U, V, W, X, Y, Z);
<commit_msg>Implement `ConflictTarget` for all supported tuple sizes<commit_after>use crate::backend::{Backend, SupportsOnConflictClause};
use crate::expression::SqlLiteral;
use crate::query_builder::*;
use crate::query_source::Column;
use crate::result::QueryResult;

#[cfg(feature = "postgres")]
pub use pg::on_constraint::*;

#[doc(hidden)]
pub trait OnConflictTarget<Table> {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct NoConflictTarget;

impl<DB> QueryFragment<DB> for NoConflictTarget
where
    DB: Backend + SupportsOnConflictClause,
{
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Table> OnConflictTarget<Table> for NoConflictTarget {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ConflictTarget<T>(pub T);

impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}

impl<DB, ST> QueryFragment<DB> for ConflictTarget<SqlLiteral<ST>>
where
    DB: Backend + SupportsOnConflictClause,
    SqlLiteral<ST>: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}

macro_rules! on_conflict_tuples {
    ($(
        $Tuple:tt {
            (0) -> A, SA, TA,
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
        }
    )+) => {
        $(
            impl<_DB, _T, $($T),*> QueryFragment<_DB> for ConflictTarget<(_T, $($T),*)> where
                _DB: Backend + SupportsOnConflictClause,
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
                fn walk_ast(&self, mut out: AstPass<_DB>) -> QueryResult<()> {
                    out.push_sql(" (");
                    out.push_identifier(_T::NAME)?;
                    $(
                        out.push_sql(", ");
                        out.push_identifier($T::NAME)?;
                    )*
                    out.push_sql(")");
                    Ok(())
                }
            }

            impl<_T, $($T),*> OnConflictTarget<_T::Table> for ConflictTarget<(_T, $($T),*)> where
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
            }
        )*
    }
}

__diesel_for_each_tuple!(on_conflict_tuples);
<|endoftext|>


<commit_before>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate bragi;
extern crate rustless;
extern crate iron;
extern crate iron_test;
use std::process::Command;

fn get_handler(url: String) -> rustless::Application {
    let api = bragi::api::ApiEndPoint{es_cnx_string: url}.root();
    rustless::Application::new(api)
}

pub fn bragi_tests(es_wrapper: ::ElasticSearchWrapper) {

    let bano2mimir = concat!(env!("OUT_DIR"), "/../../../bano2mimir");
    info!("Launching {}", bano2mimir);
    let status = Command::new(bano2mimir)
                     .args(&["--input=./tests/fixtures/sample-bano.csv".into(),
                             format!("--connection-string={}", es_wrapper.host())])
                     .status()
                     .unwrap();
    assert!(status.success(), "`bano2mimir` failed {}", &status);
    es_wrapper.refresh();

    let handler = get_handler(format!("{}/munin", es_wrapper.host()));

    // Call status
    let resp = iron_test::request::get("http://localhost:3000/status",
                                iron::Headers::new(),
                                &handler).unwrap();
    let result_body = iron_test::response::extract_body_to_string(resp);

    assert_eq!(result_body, r#"{"version":"1.0.0","es":"http://localhost:9242/munin","status":"good"}"#);

    // Call autocomplete
    let resp = iron_test::request::get("http://localhost:3000/autocomplete?q=15 Rue Hector Malot, (Paris)",
                                iron::Headers::new(),
                                &handler).unwrap();
    let result_body = iron_test::response::extract_body_to_string(resp);
    let result = concat!(r#"{"type":"FeatureCollection","#,
                         r#""geocoding":{"version":"0.1.0","query":""},"#,
                         r#""features":[{"type":"Feature","geometry":{"coordinates":"#,
                         r#"[2.3763789999999996,48.846495],"type":"Point"},"#,
                         r#""properties":{"geocoding":{"id":"addr:2.376379;48.846495","#,
                         r#""type":"house","label":"15 Rue Hector Malot (Paris)","#,
                         r#""name":"15 Rue Hector Malot","housenumber":"15","#,
                         r#""street":"Rue Hector Malot","postcode":null,"#,
                         r#""city":null,"administrative_regions":[]}}}]}"#);
    assert_eq!(result_body, result);
}
<commit_msg>update version in test<commit_after>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate bragi;
extern crate rustless;
extern crate iron;
extern crate iron_test;
use std::process::Command;

fn get_handler(url: String) -> rustless::Application {
    let api = bragi::api::ApiEndPoint { es_cnx_string: url }.root();
    rustless::Application::new(api)
}

pub fn bragi_tests(es_wrapper: ::ElasticSearchWrapper) {

    let bano2mimir = concat!(env!("OUT_DIR"), "/../../../bano2mimir");
    info!("Launching {}", bano2mimir);
    let status = Command::new(bano2mimir)
                     .args(&["--input=./tests/fixtures/sample-bano.csv".into(),
                             format!("--connection-string={}", es_wrapper.host())])
                     .status()
                     .unwrap();
    assert!(status.success(), "`bano2mimir` failed {}", &status);
    es_wrapper.refresh();

    let handler = get_handler(format!("{}/munin", es_wrapper.host()));

    // Call status
    let resp = iron_test::request::get("http://localhost:3000/status",
                                       iron::Headers::new(),
                                       &handler)
                   .unwrap();
    let result_body = iron_test::response::extract_body_to_string(resp);

    assert_eq!(result_body,
               r#"{"version":"1.1.0","es":"http://localhost:9242/munin","status":"good"}"#);

    // Call autocomplete
    let resp = iron_test::request::get("http://localhost:3000/autocomplete?q=15 Rue Hector \
                                        Malot, (Paris)",
                                       iron::Headers::new(),
                                       &handler)
                   .unwrap();
    let result_body = iron_test::response::extract_body_to_string(resp);
    let result = concat!(r#"{"type":"FeatureCollection","#,
                         r#""geocoding":{"version":"0.1.0","query":""},"#,
                         r#""features":[{"type":"Feature","geometry":{"coordinates":"#,
                         r#"[2.3763789999999996,48.846495],"type":"Point"},"#,
                         r#""properties":{"geocoding":{"id":"addr:2.376379;48.846495","#,
                         r#""type":"house","label":"15 Rue Hector Malot (Paris)","#,
                         r#""name":"15 Rue Hector Malot","housenumber":"15","#,
                         r#""street":"Rue Hector Malot","postcode":null,"#,
                         r#""city":null,"administrative_regions":[]}}}]}"#);
    assert_eq!(result_body, result);
}
<|endoftext|>


<commit_before>use byteorder::{LittleEndian, WriteBytesExt};
use std::collections::HashSet;
use std::io::prelude::*;
use std::io::{Cursor, Seek};
use std::iter::FromIterator;
use zip::write::FileOptions;
use zip::CompressionMethod;

// This test asserts that after creating a zip file, then reading its contents back out,
// the extracted data will *always* be exactly the same as the original data.
#[test]
fn end_to_end() {
    let file = &mut Cursor::new(Vec::new());

    write_to_zip(file).expect("file written");

    check_zip_contents(file, ENTRY_NAME);
}

// This test asserts that after copying a `ZipFile` to a new `ZipWriter`, then reading its
// contents back out, the extracted data will *always* be exactly the same as the original data.
#[test]
fn copy() {
    let src_file = &mut Cursor::new(Vec::new());
    write_to_zip(src_file).expect("file written");

    let mut tgt_file = &mut Cursor::new(Vec::new());

    {
        let mut src_archive = zip::ZipArchive::new(src_file).unwrap();
        let mut zip = zip::ZipWriter::new(&mut tgt_file);

        {
            let file = src_archive.by_name(ENTRY_NAME).expect("file found");
            zip.raw_copy_file(file).unwrap();
        }

        {
            let file = src_archive.by_name(ENTRY_NAME).expect("file found");
            zip.raw_copy_file_rename(file, COPY_ENTRY_NAME).unwrap();
        }
    }

    let mut tgt_archive = zip::ZipArchive::new(tgt_file).unwrap();

    check_zip_file_contents(&mut tgt_archive, ENTRY_NAME);
    check_zip_file_contents(&mut tgt_archive, COPY_ENTRY_NAME);
}

// This test asserts that after appending to a `ZipWriter`, then reading its contents back out,
// both the prior data and the appended data will be exactly the same as their originals.
#[test]
fn append() {
    let mut file = &mut Cursor::new(Vec::new());
    write_to_zip(file).expect("file written");

    {
        let mut zip = zip::ZipWriter::new_append(&mut file).unwrap();
        zip.start_file(COPY_ENTRY_NAME, Default::default()).unwrap();
        zip.write_all(LOREM_IPSUM).unwrap();
        zip.finish().unwrap();
    }

    let mut zip = zip::ZipArchive::new(&mut file).unwrap();
    check_zip_file_contents(&mut zip, ENTRY_NAME);
    check_zip_file_contents(&mut zip, COPY_ENTRY_NAME);
}

fn write_to_zip(file: &mut Cursor<Vec<u8>>) -> zip::result::ZipResult<()> {
    let mut zip = zip::ZipWriter::new(file);

    zip.add_directory("test/", Default::default())?;

    let options = FileOptions::default()
        .compression_method(CompressionMethod::Stored)
        .unix_permissions(0o755);
    zip.start_file("test/☃.txt", options)?;
    zip.write_all(b"Hello, World!\n")?;

    zip.start_file_with_extra_data("test_with_extra_data/🐢.txt", Default::default())?;
    zip.write_u16::<LittleEndian>(0xbeef)?;
    zip.write_u16::<LittleEndian>(EXTRA_DATA.len() as u16)?;
    zip.write_all(EXTRA_DATA)?;
    zip.end_extra_data()?;
    zip.write_all(b"Hello, World! Again.\n")?;

    zip.start_file(ENTRY_NAME, Default::default())?;
    zip.write_all(LOREM_IPSUM)?;

    zip.finish()?;
    Ok(())
}

fn read_zip<R: Read + Seek>(zip_file: R) -> zip::result::ZipResult<zip::ZipArchive<R>> {
    let mut archive = zip::ZipArchive::new(zip_file).unwrap();

    let expected_file_names = [
        "test/",
        "test/☃.txt",
        "test_with_extra_data/🐢.txt",
        ENTRY_NAME,
    ];
    let expected_file_names = HashSet::from_iter(expected_file_names.iter().map(|&v| v));
    let file_names = archive.file_names().collect::<HashSet<_>>();
    assert_eq!(file_names, expected_file_names);

    {
        let file_with_extra_data = archive.by_name("test_with_extra_data/🐢.txt")?;
        let mut extra_data = Vec::new();
        extra_data.write_u16::<LittleEndian>(0xbeef)?;
        extra_data.write_u16::<LittleEndian>(EXTRA_DATA.len() as u16)?;
        extra_data.write_all(EXTRA_DATA)?;
        assert_eq!(file_with_extra_data.extra_data(), extra_data.as_slice());
    }

    Ok(archive)
}

fn read_zip_file<R: Read + Seek>(
    archive: &mut zip::ZipArchive<R>,
    name: &str,
) -> zip::result::ZipResult<String> {
    let mut file = archive.by_name(name)?;

    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    Ok(contents)
}

fn check_zip_contents(zip_file: &mut Cursor<Vec<u8>>, name: &str) {
    let mut archive = read_zip(zip_file).unwrap();
    check_zip_file_contents(&mut archive, name);
}

fn check_zip_file_contents<R: Read + Seek>(archive: &mut zip::ZipArchive<R>, name: &str) {
    let file_contents: String = read_zip_file(archive, name).unwrap();
    assert!(file_contents.as_bytes() == LOREM_IPSUM);
}

const LOREM_IPSUM : &'static [u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tellus elit, tristique vitae mattis egestas, ultricies vitae risus. Quisque sit amet quam ut urna aliquet
molestie. Proin blandit ornare dui, a tempor nisl accumsan in. Praesent a consequat felis. Morbi metus diam, auctor in auctor vel, feugiat id odio. Curabitur ex ex,
dictum quis auctor quis, suscipit id lorem. Aliquam vestibulum dolor nec enim vehicula, porta tristique augue tincidunt. Vivamus ut gravida est. Sed pellentesque, dolor
vitae tristique consectetur, neque lectus pulvinar dui, sed feugiat purus diam id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Maecenas feugiat velit in ex ultrices scelerisque id id neque.
";

const EXTRA_DATA: &'static [u8] = b"Extra Data";

const ENTRY_NAME: &str = "test/lorem_ipsum.txt";

const COPY_ENTRY_NAME: &str = "test/lorem_ipsum_renamed.txt";
<commit_msg>Use all supported methods in end_to_end test<commit_after>use byteorder::{LittleEndian, WriteBytesExt};
use std::collections::HashSet;
use std::io::prelude::*;
use std::io::{Cursor, Seek};
use std::iter::FromIterator;
use zip::write::FileOptions;
use zip::CompressionMethod;

// This test asserts that after creating a zip file, then reading its contents back out,
// the extracted data will *always* be exactly the same as the original data.
#[test]
fn end_to_end() {
    for method in SUPPORTED_METHODS.iter() {
        let file = &mut Cursor::new(Vec::new());

        write_to_zip(file, *method).expect("Couldn't write to test file");

        check_zip_contents(file, ENTRY_NAME, Some(*method));
    }
}

// This test asserts that after copying a `ZipFile` to a new `ZipWriter`, then reading its
// contents back out, the extracted data will *always* be exactly the same as the original data.
#[test]
fn copy() {
    for method in SUPPORTED_METHODS.iter() {
        let src_file = &mut Cursor::new(Vec::new());
        write_to_zip(src_file, *method).expect("Couldn't write to test file");

        let mut tgt_file = &mut Cursor::new(Vec::new());

        {
            let mut src_archive = zip::ZipArchive::new(src_file).unwrap();
            let mut zip = zip::ZipWriter::new(&mut tgt_file);

            {
                let file = src_archive
                    .by_name(ENTRY_NAME)
                    .expect("Missing expected file");

                zip.raw_copy_file(file).expect("Couldn't copy file");
            }

            {
                let file = src_archive
                    .by_name(ENTRY_NAME)
                    .expect("Missing expected file");

                zip.raw_copy_file_rename(file, COPY_ENTRY_NAME)
                    .expect("Couldn't copy and rename file");
            }
        }

        let mut tgt_archive = zip::ZipArchive::new(tgt_file).unwrap();

        check_zip_file_contents(&mut tgt_archive, ENTRY_NAME);
        check_zip_file_contents(&mut tgt_archive, COPY_ENTRY_NAME);
    }
}

// This test asserts that after appending to a `ZipWriter`, then reading its contents back out,
// both the prior data and the appended data will be exactly the same as their originals.
#[test]
fn append() {
    for method in SUPPORTED_METHODS.iter() {
        let mut file = &mut Cursor::new(Vec::new());
        write_to_zip(file, *method).expect("Couldn't write to test file");

        {
            let mut zip = zip::ZipWriter::new_append(&mut file).unwrap();
            zip.start_file(
                COPY_ENTRY_NAME,
                FileOptions::default().compression_method(*method),
            )
            .unwrap();
            zip.write_all(LOREM_IPSUM).unwrap();
            zip.finish().unwrap();
        }

        let mut zip = zip::ZipArchive::new(&mut file).unwrap();
        check_zip_file_contents(&mut zip, ENTRY_NAME);
        check_zip_file_contents(&mut zip, COPY_ENTRY_NAME);
    }
}

fn write_to_zip(
    file: &mut Cursor<Vec<u8>>,
    method: CompressionMethod,
) -> zip::result::ZipResult<()> {
    let mut zip = zip::ZipWriter::new(file);

    zip.add_directory("test/", Default::default())?;

    let options = FileOptions::default()
        .compression_method(method)
        .unix_permissions(0o755);

    zip.start_file("test/☃.txt", options)?;
    zip.write_all(b"Hello, World!\n")?;

    zip.start_file_with_extra_data("test_with_extra_data/🐢.txt", options)?;
    zip.write_u16::<LittleEndian>(0xbeef)?;
    zip.write_u16::<LittleEndian>(EXTRA_DATA.len() as u16)?;
    zip.write_all(EXTRA_DATA)?;
    zip.end_extra_data()?;
    zip.write_all(b"Hello, World! Again.\n")?;

    zip.start_file(ENTRY_NAME, options)?;
    zip.write_all(LOREM_IPSUM)?;

    zip.finish()?;
    Ok(())
}

fn read_zip<R: Read + Seek>(zip_file: R) -> zip::result::ZipResult<zip::ZipArchive<R>> {
    let mut archive = zip::ZipArchive::new(zip_file).unwrap();

    let expected_file_names = [
        "test/",
        "test/☃.txt",
        "test_with_extra_data/🐢.txt",
        ENTRY_NAME,
    ];
    let expected_file_names = HashSet::from_iter(expected_file_names.iter().map(|&v| v));
    let file_names = archive.file_names().collect::<HashSet<_>>();
    assert_eq!(file_names, expected_file_names);

    {
        let file_with_extra_data = archive.by_name("test_with_extra_data/🐢.txt")?;
        let mut extra_data = Vec::new();
        extra_data.write_u16::<LittleEndian>(0xbeef)?;
        extra_data.write_u16::<LittleEndian>(EXTRA_DATA.len() as u16)?;
        extra_data.write_all(EXTRA_DATA)?;
        assert_eq!(file_with_extra_data.extra_data(), extra_data.as_slice());
    }

    Ok(archive)
}

fn read_zip_file<R: Read + Seek>(
    archive: &mut zip::ZipArchive<R>,
    name: &str,
) -> zip::result::ZipResult<String> {
    let mut file = archive.by_name(name)?;

    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    Ok(contents)
}

fn check_zip_contents(
    zip_file: &mut Cursor<Vec<u8>>,
    name: &str,
    expected_method: Option<CompressionMethod>,
) {
    let mut archive = read_zip(zip_file).unwrap();

    match expected_method {
        Some(method) => {
            let file = archive.by_name(name).unwrap();

            assert_eq!(
                method,
                file.compression(),
                "File does not have expected compression method"
            )
        }
        None => {}
    }

    check_zip_file_contents(&mut archive, name);
}

fn check_zip_file_contents<R: Read + Seek>(archive: &mut zip::ZipArchive<R>, name: &str) {
    let file_contents: String = read_zip_file(archive, name).unwrap();
    assert!(file_contents.as_bytes() == LOREM_IPSUM);
}

const LOREM_IPSUM : &'static [u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tellus elit, tristique vitae mattis egestas, ultricies vitae risus. Quisque sit amet quam ut urna aliquet
molestie. Proin blandit ornare dui, a tempor nisl accumsan in. Praesent a consequat felis. Morbi metus diam, auctor in auctor vel, feugiat id odio. Curabitur ex ex,
dictum quis auctor quis, suscipit id lorem. Aliquam vestibulum dolor nec enim vehicula, porta tristique augue tincidunt. Vivamus ut gravida est. Sed pellentesque, dolor
vitae tristique consectetur, neque lectus pulvinar dui, sed feugiat purus diam id lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Maecenas feugiat velit in ex ultrices scelerisque id id neque.
";

const EXTRA_DATA: &'static [u8] = b"Extra Data";

const ENTRY_NAME: &str = "test/lorem_ipsum.txt";

const COPY_ENTRY_NAME: &str = "test/lorem_ipsum_renamed.txt";

const SUPPORTED_METHODS: &'static [CompressionMethod] = &[
    CompressionMethod::Stored,
    //
    #[cfg(any(
        feature = "deflate",
        feature = "deflate-miniz",
        feature = "deflate-zlib"
    ))]
    CompressionMethod::Deflated,
    //
    #[cfg(feature = "bzip2")]
    CompressionMethod::Bzip2,
    //
    #[cfg(feature = "zstd")]
    CompressionMethod::Zstd,
];
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate log;
extern crate suppositions;

use suppositions::*;
use suppositions::generators::*;
use suppositions::data::*;
use std::fmt;

fn _assert_is_generator<G: Generator>(_: &G) {}

#[test]
fn i64s_should_generate_same_output_given_same_input() {
    let gen = i64s();
    property(info_pools(64).filter_map(|p| {
        let v0 = gen.generate_from(&p)?;
        let v1 = gen.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

#[test]
fn i64s_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = i64s();
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                gen.generate(&mut p0.replay())
                    .and_then(|v0| gen.generate(&mut p1.replay()).map(|v1| (v0, v1)))
            }),
    ).check(|(v0, v1)| v0.abs() <= v1.abs())
}

#[test]
fn f64s_should_generate_same_output_given_same_input() {
    let gen = f64s();
    property(
        info_pools(32)
            .filter_map(|p| {
                let v0 = gen.generate_from(&p)?;
                let v1 = gen.generate_from(&p)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0 == v1)
}

#[test]
fn f64s_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = f64s();
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0.abs() <= v1.abs())
}

#[test]
fn uniform_f64s_should_generate_same_output_given_same_input() {
    let gen = uniform_f64s();
    property(
        info_pools(32)
            .filter_map(|p| {
                let v0 = gen.generate_from(&p)?;
                let v1 = gen.generate_from(&p)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0 == v1)
}

#[test]
fn uniform_f64s_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = uniform_f64s();
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0.abs() <= v1.abs())
}

#[test]
fn weighted_coin_should_generate_same_output_given_same_input() {
    let gen = weighted_coin(1.0 / 7.0);
    property(info_pools(32).filter_map(|p| {
        let v0 = gen.generate_from(&p)?;
        let v1 = gen.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

#[test]
fn weighted_coin_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = weighted_coin(1.0 / 7.0);
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((v0, v1))
            }),
    ).check(|(v0, v1)| v0 <= v1)
}

#[test]
fn uniform_f64s_should_generate_values_between_0_and_1() {
    let gen = uniform_f64s();
    property(info_pools(32).filter_map(|p| gen.generate_from(&p))).check(|v| v >= 0.0 && v < 1.0)
}

#[test]
fn generator_map_should_trivially_preserve_invariants() {
    property(u8s().map(|v| (v as u16) * 2)).check(|v| v % 2 == 0)
}

#[test]
fn one_of_should_pick_a_single_sample() {
    let g = one_of(consts(1usize)).or(consts(2)).or(consts(3));
    property(g).check(|v| v >= 1 && v <= 3)
}

#[test]
fn one_of_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = one_of(consts(1usize)).or(consts(2)).or(consts(3));
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((p0, p1, v0, v1))
            }),
    ).check(|(_, _, v0, v1)| v0 <= v1)
}

#[test]
fn boxed_generator_yields_same_as_inner_value() {
    env_logger::init().unwrap_or(());
    let orig = u64s();
    let boxed = u64s().boxed();
    _assert_is_generator(&boxed);
    property(info_pools(16).filter_map(|p| {
        let v0 = orig.generate_from(&p)?;
        let v1 = boxed.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

#[test]
fn generator_of_2_tuple() {
    let g = (u64s(), u32s());
    _assert_is_generator(&g);
}

#[test]
fn generator_of_3_tuple() {
    let g = (u64s(), u32s(), u8s());
    _assert_is_generator(&g);
}

#[test]
fn lazy_generator_yields_same_as_inner_value() {
    env_logger::init().unwrap_or(());
    let orig = u64s();
    let lazy = lazy(u64s);
    _assert_is_generator(&lazy);
    property(info_pools(16).filter_map(|p| {
        let v0 = orig.generate_from(&p)?;
        let v1 = lazy.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

fn uptos_never_generates_greater_than_limit<G: Generator + Clone>(g: G)
where
    G::Item: ScaleInt + Copy + fmt::Debug + PartialOrd,
{
    env_logger::init().unwrap_or(());
    property(g.clone().flat_map(|max| {
        let h = uptos(g.clone(), max);
        _assert_is_generator(&h);
        h.map(move |n| (n, max))
    })).check(|(n, max)| n <= max);
}

#[test]
fn uptos_u8_is_gen() {
    _assert_is_generator(&uptos(u8s(), ::std::u8::MAX))
}

#[test]
fn uptos_u8_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u8s())
}

#[test]
fn uptos_u16_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u16s())
}

#[test]
fn uptos_u32_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u32s())
}

#[test]
fn uptos_u64_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u64s())
}

struct RegionCounter<S> {
    src: S,
    cnt: usize,
}

impl<G: InfoSource> InfoSource for RegionCounter<G> {
    fn draw_u8(&mut self) -> u8 {
        self.src.draw_u8()
    }
    fn draw<S: InfoSink>(&mut self, sink: S) -> S::Out
    where
        Self: Sized,
    {
        self.cnt += 1;
        self.src.draw(sink)
    }
}

#[test]
fn optional_u64s_should_have_one_region_for_none() {
    let g = optional(u64s());

    property(
        info_pools(32)
            .filter_map(|p| {
                let mut ctr = RegionCounter {
                    src: &mut p.replay(),
                    cnt: 0,
                };
                g.generate(&mut ctr).map(|val| (ctr.cnt, val))
            })
            .filter(|&(_, ref val)| val.is_none()),
    ).check(|(cnt, _)| assert_eq!(1, cnt));
}

#[test]
fn optional_u64s_should_have_two_regions_for_some() {
    let g = optional(u64s());

    property(
        info_pools(32)
            .filter_map(|p| {
                let mut ctr = RegionCounter {
                    src: &mut p.replay(),
                    cnt: 0,
                };
                g.generate(&mut ctr).map(|val| (ctr.cnt, val))
            })
            .filter(|&(_, ref val)| val.is_some()),
    ).check(|(cnt, _)| assert_eq!(2, cnt));
}

#[test]
fn choice_should_always_draw_from_inputs() {
    let g = optional(u64s());

    property((vecs(u64s()), info_pools(32)).filter(|&(ref its, _)| its.len() > 0)).check(
        |(its, p)| {
            let choice = choice(its.clone())
                .generate_from(&p)
                .expect("generate_from");
            assert!(its.contains(&choice));
        },
    );
}

#[test]
fn choice_should_skip_on_empty_choices() {
    property(info_pools(32)).check(|p| {
        let result = choice(vec![0u8; 0]).generate_from(&p);
        assert_eq!(result, Err(DataError::SkipItem));
    });
}

#[test]
fn map_should_yield_generated_value_but_with_f_applied_for_usize() {
    fn add_one(i: usize) -> usize {
        i.wrapping_add(i)
    }
    let f = add_one;
    let g = usizes();
    map_should_yield_generated_value_but_with_f_applied(&g, &f);
}

fn map_should_yield_generated_value_but_with_f_applied<
    G: Generator,
    R: fmt::Debug + PartialEq,
    F: Fn(G::Item) -> R,
>(
    g: &G,
    f: &F,
) {
    // Check that g.map(f).generate(...) == f(g.generate(...))
    // (Modulo generator failure)
    property(info_pools(32)).check(move |p| {
        assert_eq!(
            g.generate_from(&p).map(f),
            g.clone().map(f).generate_from(&p)
        )
    });
}

// These are inspired by https://hackage.haskell.org/package/checkers-0.4.9.5/docs/src/Test-QuickCheck-Classes.html#monad

#[test]
fn flat_map_should_have_left_identity_over_usize() {
    let f = |i: usize| consts(i.wrapping_add(1));
    let gen = usizes();
    flat_map_should_have_left_identity(&gen, &f);
}

fn flat_map_should_have_left_identity<G: Generator, H: Generator, F: Fn(G::Item) -> H>(g: &G, f: &F)
where
    G::Item: fmt::Debug + Clone,
    H::Item: fmt::Debug + PartialEq,
{
    property(info_pools(32).filter_map(|p| {
        let a = g.generate_from(&p)?;
        Ok((p, a))
    })).check(|(p, a)| -> Result<(), DataError> {
        let lhs = consts(a.clone()).flat_map(f);
        let rhs = f(a);

        assert_eq!(lhs.generate_from(&p), rhs.generate_from(&p));

        Ok(())
    });
}

#[test]
fn flat_map_should_have_right_identity_over_usize() {
    flat_map_should_have_right_identity(&usizes());
}

fn flat_map_should_have_right_identity<G: Generator>(g: &G)
where
    G::Item: fmt::Debug + PartialEq + Clone,
{
    property(info_pools(32)).check(|p| -> Result<(), DataError> {
        let lhs = g.clone().flat_map(consts);
        let rhs = g;

        assert_eq!(lhs.generate_from(&p), rhs.generate_from(&p));

        Ok(())
    });
}
<commit_msg>Test for associativity of flat_map.<commit_after>extern crate env_logger;
extern crate log;
extern crate suppositions;

use suppositions::*;
use suppositions::generators::*;
use suppositions::data::*;
use std::fmt;

fn _assert_is_generator<G: Generator>(_: &G) {}

#[test]
fn i64s_should_generate_same_output_given_same_input() {
    let gen = i64s();
    property(info_pools(64).filter_map(|p| {
        let v0 = gen.generate_from(&p)?;
        let v1 = gen.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

#[test]
fn i64s_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = i64s();
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                gen.generate(&mut p0.replay())
                    .and_then(|v0| gen.generate(&mut p1.replay()).map(|v1| (v0, v1)))
            }),
    ).check(|(v0, v1)| v0.abs() <= v1.abs())
}

#[test]
fn f64s_should_generate_same_output_given_same_input() {
    let gen = f64s();
    property(
        info_pools(32)
            .filter_map(|p| {
                let v0 = gen.generate_from(&p)?;
                let v1 = gen.generate_from(&p)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0 == v1)
}

#[test]
fn f64s_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = f64s();
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0.abs() <= v1.abs())
}

#[test]
fn uniform_f64s_should_generate_same_output_given_same_input() {
    let gen = uniform_f64s();
    property(
        info_pools(32)
            .filter_map(|p| {
                let v0 = gen.generate_from(&p)?;
                let v1 = gen.generate_from(&p)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0 == v1)
}

#[test]
fn uniform_f64s_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = uniform_f64s();
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((v0, v1))
            })
            .filter(|&(v0, v1)| !(v0.is_nan() || v1.is_nan())),
    ).check(|(v0, v1)| v0.abs() <= v1.abs())
}

#[test]
fn weighted_coin_should_generate_same_output_given_same_input() {
    let gen = weighted_coin(1.0 / 7.0);
    property(info_pools(32).filter_map(|p| {
        let v0 = gen.generate_from(&p)?;
        let v1 = gen.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

#[test]
fn weighted_coin_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = weighted_coin(1.0 / 7.0);
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((v0, v1))
            }),
    ).check(|(v0, v1)| v0 <= v1)
}

#[test]
fn uniform_f64s_should_generate_values_between_0_and_1() {
    let gen = uniform_f64s();
    property(info_pools(32).filter_map(|p| gen.generate_from(&p))).check(|v| v >= 0.0 && v < 1.0)
}

#[test]
fn generator_map_should_trivially_preserve_invariants() {
    property(u8s().map(|v| (v as u16) * 2)).check(|v| v % 2 == 0)
}

#[test]
fn one_of_should_pick_a_single_sample() {
    let g = one_of(consts(1usize)).or(consts(2)).or(consts(3));
    property(g).check(|v| v >= 1 && v <= 3)
}

#[test]
fn one_of_should_partially_order_same_as_source() {
    env_logger::init().unwrap_or(());
    let gen = one_of(consts(1usize)).or(consts(2)).or(consts(3));
    property(
        (info_pools(16), info_pools(16))
            .filter(|&(ref p0, ref p1)| p0.buffer() < p1.buffer())
            .filter_map(|(p0, p1)| {
                let v0 = gen.generate_from(&p0)?;
                let v1 = gen.generate_from(&p1)?;
                Ok((p0, p1, v0, v1))
            }),
    ).check(|(_, _, v0, v1)| v0 <= v1)
}

#[test]
fn boxed_generator_yields_same_as_inner_value() {
    env_logger::init().unwrap_or(());
    let orig = u64s();
    let boxed = u64s().boxed();
    _assert_is_generator(&boxed);
    property(info_pools(16).filter_map(|p| {
        let v0 = orig.generate_from(&p)?;
        let v1 = boxed.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

#[test]
fn generator_of_2_tuple() {
    let g = (u64s(), u32s());
    _assert_is_generator(&g);
}

#[test]
fn generator_of_3_tuple() {
    let g = (u64s(), u32s(), u8s());
    _assert_is_generator(&g);
}

#[test]
fn lazy_generator_yields_same_as_inner_value() {
    env_logger::init().unwrap_or(());
    let orig = u64s();
    let lazy = lazy(u64s);
    _assert_is_generator(&lazy);
    property(info_pools(16).filter_map(|p| {
        let v0 = orig.generate_from(&p)?;
        let v1 = lazy.generate_from(&p)?;
        Ok((v0, v1))
    })).check(|(v0, v1)| v0 == v1)
}

fn uptos_never_generates_greater_than_limit<G: Generator + Clone>(g: G)
where
    G::Item: ScaleInt + Copy + fmt::Debug + PartialOrd,
{
    env_logger::init().unwrap_or(());
    property(g.clone().flat_map(|max| {
        let h = uptos(g.clone(), max);
        _assert_is_generator(&h);
        h.map(move |n| (n, max))
    })).check(|(n, max)| n <= max);
}

#[test]
fn uptos_u8_is_gen() {
    _assert_is_generator(&uptos(u8s(), ::std::u8::MAX))
}

#[test]
fn uptos_u8_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u8s())
}

#[test]
fn uptos_u16_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u16s())
}

#[test]
fn uptos_u32_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u32s())
}

#[test]
fn uptos_u64_never_generates_greater_than_limit() {
    uptos_never_generates_greater_than_limit(u64s())
}

struct RegionCounter<S> {
    src: S,
    cnt: usize,
}

impl<G: InfoSource> InfoSource for RegionCounter<G> {
    fn draw_u8(&mut self) -> u8 {
        self.src.draw_u8()
    }
    fn draw<S: InfoSink>(&mut self, sink: S) -> S::Out
    where
        Self: Sized,
    {
        self.cnt += 1;
        self.src.draw(sink)
    }
}

#[test]
fn optional_u64s_should_have_one_region_for_none() {
    let g = optional(u64s());

    property(
        info_pools(32)
            .filter_map(|p| {
                let mut ctr = RegionCounter {
                    src: &mut p.replay(),
                    cnt: 0,
                };
                g.generate(&mut ctr).map(|val| (ctr.cnt, val))
            })
            .filter(|&(_, ref val)| val.is_none()),
    ).check(|(cnt, _)| assert_eq!(1, cnt));
}

#[test]
fn optional_u64s_should_have_two_regions_for_some() {
    let g = optional(u64s());

    property(
        info_pools(32)
            .filter_map(|p| {
                let mut ctr = RegionCounter {
                    src: &mut p.replay(),
                    cnt: 0,
                };
                g.generate(&mut ctr).map(|val| (ctr.cnt, val))
            })
            .filter(|&(_, ref val)| val.is_some()),
    ).check(|(cnt, _)| assert_eq!(2, cnt));
}

#[test]
fn choice_should_always_draw_from_inputs() {
    let g = optional(u64s());

    property((vecs(u64s()), info_pools(32)).filter(|&(ref its, _)| its.len() > 0)).check(
        |(its, p)| {
            let choice = choice(its.clone())
                .generate_from(&p)
                .expect("generate_from");
            assert!(its.contains(&choice));
        },
    );
}

#[test]
fn choice_should_skip_on_empty_choices() {
    property(info_pools(32)).check(|p| {
        let result = choice(vec![0u8; 0]).generate_from(&p);
        assert_eq!(result, Err(DataError::SkipItem));
    });
}

#[test]
fn map_should_yield_generated_value_but_with_f_applied_for_usize() {
    fn add_one(i: usize) -> usize {
        i.wrapping_add(i)
    }
    let f = add_one;
    let g = usizes();
    map_should_yield_generated_value_but_with_f_applied(&g, &f);
}

fn map_should_yield_generated_value_but_with_f_applied<
    G: Generator,
    R: fmt::Debug + PartialEq,
    F: Fn(G::Item) -> R,
>(
    g: &G,
    f: &F,
) {
    // Check that g.map(f).generate(...) == f(g.generate(...))
    // (Modulo generator failure)
    property(info_pools(32)).check(move |p| {
        assert_eq!(
            g.generate_from(&p).map(f),
            g.clone().map(f).generate_from(&p)
        )
    });
}

// These are inspired by https://hackage.haskell.org/package/checkers-0.4.9.5/docs/src/Test-QuickCheck-Classes.html#monad

#[test]
fn flat_map_should_have_left_identity_over_usize() {
    let f = |i: usize| consts(i.wrapping_add(1));
    let gen = usizes();
    flat_map_should_have_left_identity(&gen, &f);
}

fn flat_map_should_have_left_identity<G: Generator, H: Generator, F: Fn(G::Item) -> H>(g: &G, f: &F)
where
    G::Item: fmt::Debug + Clone,
    H::Item: fmt::Debug + PartialEq,
{
    property(info_pools(32).filter_map(|p| {
        let a = g.generate_from(&p)?;
        Ok((p, a))
    })).check(|(p, a)| -> Result<(), DataError> {
        let lhs = consts(a.clone()).flat_map(f);
        let rhs = f(a);

        assert_eq!(lhs.generate_from(&p), rhs.generate_from(&p));

        Ok(())
    });
}

#[test]
fn flat_map_should_have_right_identity_over_usize() {
    flat_map_should_have_right_identity(&usizes());
}

fn flat_map_should_have_right_identity<G: Generator>(g: &G)
where
    G::Item: fmt::Debug + PartialEq + Clone,
{
    property(info_pools(32)).check(|p| -> Result<(), DataError> {
        let lhs = g.clone().flat_map(consts);
        let rhs = g;

        assert_eq!(lhs.generate_from(&p), rhs.generate_from(&p));

        Ok(())
    });
}

#[test]
fn flat_map_should_be_associative_over_canary_types() {
    // I can't think of a better example than this rather contrived thing.
    flat_map_should_be_associative(
        &usizes(),
        &|l| vecs(u8s()).mean_length(l),
        &|vs| choice(vs),
    );
}

fn flat_map_should_be_associative<
    G: Generator,
    H: Generator,
    I: Generator,
    E: Fn(G::Item) -> H,
    F: Fn(H::Item) -> I,
>(
    gen: &G,
    e: &E,
    f: &F,
) where
    I::Item: fmt::Debug + PartialEq,
{
    // Check that g.map(f).generate(...) == f(g.generate(...))
    // (return a >>= f)  =-= f a
    // (Modulo generator failure)
    property(info_pools(32)).check(|p| -> Result<(), DataError> {
        let lhs = gen.flat_map(e).flat_map(f);
        let rhs = gen.flat_map(|x| e(x).flat_map(f));

        assert_eq!(lhs.generate_from(&p), rhs.generate_from(&p));

        Ok(())
    });
}
<|endoftext|>


<commit_before>fn main() {
    fn diverges() -> ! {
       panic!("This function never returns!");
    }
    let x: i32 = diverges();
    let x: String = diverges();

}

<commit_msg>forgot to note source for that code!<commit_after>fn main() {
    //src: https://doc.rust-lang.org/nightly/book/functions.html#diverging-functions
    fn diverges() -> ! {
       panic!("This function never returns!");
    }
    let x: i32 = diverges();
    let x: String = diverges();

}

<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Depth and stencil operations description.
//!
//! After the fragment shader has finished running, each fragment goes through the depth
//! and stencil tests.
//!
//! The depth test passes of fails depending on how the depth value of each fragment compares
//! to the existing depth value in the depth buffer at that fragment's location. Depth values
//! are always between 0.0 and 1.0.
//!
//! The stencil test passes or fails depending on how a reference value compares to the existing
//! value in the stencil buffer at each fragment's location. Depending on the outcome of the
//! depth and stencil tests, the value of the stencil buffer at that location can be updated.

use std::ops::Range;
use std::u32;
use vk;

/// Configuration of the depth and stencil tests.
#[derive(Debug, Clone)]
pub struct DepthStencil {
    /// Comparison to use between the depth value of each fragment and the depth value currently
    /// in the depth buffer.
    pub depth_compare: Compare,

    /// If `true`, then the value in the depth buffer will be updated when the depth test succeeds.
    pub depth_write: bool,

    /// Allows you to ask the GPU to exclude fragments that are outside of a certain range. This is
    /// done in addition to the regular depth test.
    pub depth_bounds_test: DepthBounds,

    /// Stencil operations to use for points, lines and triangles whose front is facing the user.
    pub stencil_front: Stencil,

    /// Stencil operations to use for triangles whose back is facing the user.
    pub stencil_back: Stencil,
}

impl DepthStencil {
    /// Creates a `DepthStencil` with a `Less` depth test, `depth_write` set to true, and stencil
    /// testing disabled.
    #[inline]
    pub fn simple_depth_test() -> DepthStencil {
        DepthStencil {
            depth_write: true,
            depth_compare: Compare::Less,
            depth_bounds_test: DepthBounds::Disabled,
            stencil_front: Default::default(),
            stencil_back: Default::default(),
        }
    }
}

impl Default for DepthStencil {
    #[inline]
    fn default() -> DepthStencil {
        DepthStencil {
            depth_write: false,
            depth_compare: Compare::Always,
            depth_bounds_test: DepthBounds::Disabled,
            stencil_front: Default::default(),
            stencil_back: Default::default(),
        }
    }
}

/// Configuration of a stencil test.
#[derive(Debug, Copy, Clone)]
pub struct Stencil {
    /// The comparison to perform between the existing stencil value in the stencil buffer, and
    /// the reference value (given by `reference`).
    pub compare: Compare,

    /// The operation to perform when both the depth test and the stencil test passed.
    pub pass_op: StencilOp,

    /// The operation to perform when the stencil test failed.
    pub fail_op: StencilOp,

    /// The operation to perform when the stencil test passed but the depth test failed.
    pub depth_fail_op: StencilOp,

    /// Selects the bits of the unsigned integer stencil values participating in the stencil test.
    ///
    /// Ignored if `compare` is `Never` or `Always`.
    ///
    /// If `None`, then this value is dynamic and will need to be set when drawing. Doesn't apply
    /// if `compare` is `Never` or `Always`.
    ///
    /// Note that if this value is `Some` in `stencil_front`, it must also be `Some` in
    /// `stencil_back` (but the content can be different). If this value is `None` in
    /// `stencil_front`, then it must also be `None` in `stencil_back`. This rule doesn't apply
    /// if `compare` is `Never` or `Always`.
    pub compare_mask: Option<u32>,

    /// Selects the bits of the unsigned integer stencil values updated by the stencil test in the
    /// stencil framebuffer attachment.
    ///
    /// If `None`, then this value is dynamic and will need to be set when drawing.
    ///
    /// Note that if this value is `Some` in `stencil_front`, it must also be `Some` in
    /// `stencil_back` (but the content can be different). If this value is `None` in
    /// `stencil_front`, then it must also be `None` in `stencil_back`.
    pub write_mask: Option<u32>,

    /// Reference value that is used in the unsigned stencil comparison.
    ///
    /// If `None`, then this value is dynamic and will need to be set when drawing.
    ///
    /// Note that if this value is `Some` in `stencil_front`, it must also be `Some` in
    /// `stencil_back` (but the content can be different). If this value is `None` in
    /// `stencil_front`, then it must also be `None` in `stencil_back`.
    pub reference: Option<u32>,
}

impl Stencil {
    /// Returns true if the stencil operation will always result in `Keep`.
    #[inline]
    pub fn always_keep(&self) -> bool {
        match self.compare {
            Compare::Always => self.pass_op == StencilOp::Keep &&
                               self.depth_fail_op == StencilOp::Keep,
            Compare::Never => self.fail_op == StencilOp::Keep,
            _ => self.pass_op == StencilOp::Keep && self.fail_op == StencilOp::Keep &&
                 self.depth_fail_op == StencilOp::Keep,
        }
    }
}

impl Default for Stencil {
    #[inline]
    fn default() -> Stencil {
        Stencil {
            compare: Compare::Never,
            pass_op: StencilOp::Keep,
            fail_op: StencilOp::Keep,
            depth_fail_op: StencilOp::Keep,
            compare_mask: Some(u32::MAX),
            write_mask: Some(u32::MAX),
            reference: Some(u32::MAX),
        }
    }
}

/// Operation to perform after the depth and stencil tests.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum StencilOp {
    Keep = vk::STENCIL_OP_KEEP,
    Zero = vk::STENCIL_OP_ZERO,
    Replace = vk::STENCIL_OP_REPLACE,
    IncrementAndClamp = vk::STENCIL_OP_INCREMENT_AND_CLAMP,
    DecrementAndClamp = vk::STENCIL_OP_DECREMENT_AND_CLAMP,
    Invert = vk::STENCIL_OP_INVERT,
    IncrementAndWrap = vk::STENCIL_OP_INCREMENT_AND_WRAP,
    DecrementAndWrap = vk::STENCIL_OP_DECREMENT_AND_WRAP,
}

/// Allows you to ask the GPU to exclude fragments that are outside of a certain range.
#[derive(Debug, Clone, PartialEq)]
pub enum DepthBounds {
    /// The test is disabled. All fragments pass the depth bounds test.
    Disabled,

    /// Fragments that are within the given range do pass the test. Values are depth values
    /// between 0.0 and 1.0.
    Fixed(Range<f32>),

    /// The depth bounds test is enabled, but the range will need to specified when you submit
    /// a draw command.
    Dynamic,
}

impl DepthBounds {
    /// Returns true if equal to `DepthBounds::Dynamic`.
    #[inline]
    pub fn is_dynamic(&self) -> bool {
        match self {
            &DepthBounds::Dynamic => true,
            _ => false,
        }
    }
}

/// Specifies how two values should be compared to decide whether a test passes or fails.
///
/// Used for both depth testing and stencil testing.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum Compare {
    /// The test never passes.
    Never = vk::COMPARE_OP_NEVER,
    /// The test passes if `value < reference_value`.
    Less = vk::COMPARE_OP_LESS,
    /// The test passes if `value == reference_value`.
    Equal = vk::COMPARE_OP_EQUAL,
    /// The test passes if `value <= reference_value`.
    LessOrEqual = vk::COMPARE_OP_LESS_OR_EQUAL,
    /// The test passes if `value > reference_value`.
    Greater = vk::COMPARE_OP_GREATER,
    /// The test passes if `value != reference_value`.
    NotEqual = vk::COMPARE_OP_NOT_EQUAL,
    /// The test passes if `value >= reference_value`.
    GreaterOrEqual = vk::COMPARE_OP_GREATER_OR_EQUAL,
    /// The test always passes.
    Always = vk::COMPARE_OP_ALWAYS,
}
<commit_msg>Add DepthStencil::disabled<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Depth and stencil operations description.
//!
//! After the fragment shader has finished running, each fragment goes through the depth
//! and stencil tests.
//!
//! The depth test passes of fails depending on how the depth value of each fragment compares
//! to the existing depth value in the depth buffer at that fragment's location. Depth values
//! are always between 0.0 and 1.0.
//!
//! The stencil test passes or fails depending on how a reference value compares to the existing
//! value in the stencil buffer at each fragment's location. Depending on the outcome of the
//! depth and stencil tests, the value of the stencil buffer at that location can be updated.

use std::ops::Range;
use std::u32;
use vk;

/// Configuration of the depth and stencil tests.
#[derive(Debug, Clone)]
pub struct DepthStencil {
    /// Comparison to use between the depth value of each fragment and the depth value currently
    /// in the depth buffer.
    pub depth_compare: Compare,

    /// If `true`, then the value in the depth buffer will be updated when the depth test succeeds.
    pub depth_write: bool,

    /// Allows you to ask the GPU to exclude fragments that are outside of a certain range. This is
    /// done in addition to the regular depth test.
    pub depth_bounds_test: DepthBounds,

    /// Stencil operations to use for points, lines and triangles whose front is facing the user.
    pub stencil_front: Stencil,

    /// Stencil operations to use for triangles whose back is facing the user.
    pub stencil_back: Stencil,
}

impl DepthStencil {
    /// Creates a `DepthStencil` where both the depth and stencil tests are disabled and have
    /// no effect.
    #[inline]
    pub fn disabled() -> DepthStencil {
        DepthStencil {
            depth_write: false,
            depth_compare: Compare::Always,
            depth_bounds_test: DepthBounds::Disabled,
            stencil_front: Default::default(),
            stencil_back: Default::default(),
        }
    }

    /// Creates a `DepthStencil` with a `Less` depth test, `depth_write` set to true, and stencil
    /// testing disabled.
    #[inline]
    pub fn simple_depth_test() -> DepthStencil {
        DepthStencil {
            depth_write: true,
            depth_compare: Compare::Less,
            depth_bounds_test: DepthBounds::Disabled,
            stencil_front: Default::default(),
            stencil_back: Default::default(),
        }
    }
}

impl Default for DepthStencil {
    #[inline]
    fn default() -> DepthStencil {
        DepthStencil::disabled()
    }
}

/// Configuration of a stencil test.
#[derive(Debug, Copy, Clone)]
pub struct Stencil {
    /// The comparison to perform between the existing stencil value in the stencil buffer, and
    /// the reference value (given by `reference`).
    pub compare: Compare,

    /// The operation to perform when both the depth test and the stencil test passed.
    pub pass_op: StencilOp,

    /// The operation to perform when the stencil test failed.
    pub fail_op: StencilOp,

    /// The operation to perform when the stencil test passed but the depth test failed.
    pub depth_fail_op: StencilOp,

    /// Selects the bits of the unsigned integer stencil values participating in the stencil test.
    ///
    /// Ignored if `compare` is `Never` or `Always`.
    ///
    /// If `None`, then this value is dynamic and will need to be set when drawing. Doesn't apply
    /// if `compare` is `Never` or `Always`.
    ///
    /// Note that if this value is `Some` in `stencil_front`, it must also be `Some` in
    /// `stencil_back` (but the content can be different). If this value is `None` in
    /// `stencil_front`, then it must also be `None` in `stencil_back`. This rule doesn't apply
    /// if `compare` is `Never` or `Always`.
    pub compare_mask: Option<u32>,

    /// Selects the bits of the unsigned integer stencil values updated by the stencil test in the
    /// stencil framebuffer attachment.
    ///
    /// If `None`, then this value is dynamic and will need to be set when drawing.
    ///
    /// Note that if this value is `Some` in `stencil_front`, it must also be `Some` in
    /// `stencil_back` (but the content can be different). If this value is `None` in
    /// `stencil_front`, then it must also be `None` in `stencil_back`.
    pub write_mask: Option<u32>,

    /// Reference value that is used in the unsigned stencil comparison.
    ///
    /// If `None`, then this value is dynamic and will need to be set when drawing.
    ///
    /// Note that if this value is `Some` in `stencil_front`, it must also be `Some` in
    /// `stencil_back` (but the content can be different). If this value is `None` in
    /// `stencil_front`, then it must also be `None` in `stencil_back`.
    pub reference: Option<u32>,
}

impl Stencil {
    /// Returns true if the stencil operation will always result in `Keep`.
    #[inline]
    pub fn always_keep(&self) -> bool {
        match self.compare {
            Compare::Always => self.pass_op == StencilOp::Keep &&
                               self.depth_fail_op == StencilOp::Keep,
            Compare::Never => self.fail_op == StencilOp::Keep,
            _ => self.pass_op == StencilOp::Keep && self.fail_op == StencilOp::Keep &&
                 self.depth_fail_op == StencilOp::Keep,
        }
    }
}

impl Default for Stencil {
    #[inline]
    fn default() -> Stencil {
        Stencil {
            compare: Compare::Never,
            pass_op: StencilOp::Keep,
            fail_op: StencilOp::Keep,
            depth_fail_op: StencilOp::Keep,
            compare_mask: Some(u32::MAX),
            write_mask: Some(u32::MAX),
            reference: Some(u32::MAX),
        }
    }
}

/// Operation to perform after the depth and stencil tests.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum StencilOp {
    Keep = vk::STENCIL_OP_KEEP,
    Zero = vk::STENCIL_OP_ZERO,
    Replace = vk::STENCIL_OP_REPLACE,
    IncrementAndClamp = vk::STENCIL_OP_INCREMENT_AND_CLAMP,
    DecrementAndClamp = vk::STENCIL_OP_DECREMENT_AND_CLAMP,
    Invert = vk::STENCIL_OP_INVERT,
    IncrementAndWrap = vk::STENCIL_OP_INCREMENT_AND_WRAP,
    DecrementAndWrap = vk::STENCIL_OP_DECREMENT_AND_WRAP,
}

/// Allows you to ask the GPU to exclude fragments that are outside of a certain range.
#[derive(Debug, Clone, PartialEq)]
pub enum DepthBounds {
    /// The test is disabled. All fragments pass the depth bounds test.
    Disabled,

    /// Fragments that are within the given range do pass the test. Values are depth values
    /// between 0.0 and 1.0.
    Fixed(Range<f32>),

    /// The depth bounds test is enabled, but the range will need to specified when you submit
    /// a draw command.
    Dynamic,
}

impl DepthBounds {
    /// Returns true if equal to `DepthBounds::Dynamic`.
    #[inline]
    pub fn is_dynamic(&self) -> bool {
        match self {
            &DepthBounds::Dynamic => true,
            _ => false,
        }
    }
}

/// Specifies how two values should be compared to decide whether a test passes or fails.
///
/// Used for both depth testing and stencil testing.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum Compare {
    /// The test never passes.
    Never = vk::COMPARE_OP_NEVER,
    /// The test passes if `value < reference_value`.
    Less = vk::COMPARE_OP_LESS,
    /// The test passes if `value == reference_value`.
    Equal = vk::COMPARE_OP_EQUAL,
    /// The test passes if `value <= reference_value`.
    LessOrEqual = vk::COMPARE_OP_LESS_OR_EQUAL,
    /// The test passes if `value > reference_value`.
    Greater = vk::COMPARE_OP_GREATER,
    /// The test passes if `value != reference_value`.
    NotEqual = vk::COMPARE_OP_NOT_EQUAL,
    /// The test passes if `value >= reference_value`.
    GreaterOrEqual = vk::COMPARE_OP_GREATER_OR_EQUAL,
    /// The test always passes.
    Always = vk::COMPARE_OP_ALWAYS,
}
<|endoftext|>


<commit_before>#![feature(
    i128_type,
    rustc_private,
)]

// From rustc.
#[macro_use]
extern crate log;
#[macro_use]
extern crate rustc;
extern crate syntax;

use rustc::ty::{self, TyCtxt};
use rustc::ty::layout::Layout;
use rustc::hir::def_id::DefId;
use rustc::mir;

use syntax::codemap::Span;

use std::collections::{HashMap, BTreeMap};

#[macro_use]
extern crate rustc_miri;
pub use rustc_miri::interpret::*;

mod fn_call;
mod operator;
mod intrinsic;
mod helpers;
mod memory;
mod tls;

use fn_call::EvalContextExt as MissingFnsEvalContextExt;
use operator::EvalContextExt as OperatorEvalContextExt;
use intrinsic::EvalContextExt as IntrinsicEvalContextExt;
use tls::EvalContextExt as TlsEvalContextExt;

pub fn eval_main<'a, 'tcx: 'a>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    main_id: DefId,
    start_wrapper: Option<DefId>,
    limits: ResourceLimits,
) {
    fn run_main<'a, 'tcx: 'a>(
        ecx: &mut rustc_miri::interpret::EvalContext<'a, 'tcx, Evaluator>,
        main_id: DefId,
        start_wrapper: Option<DefId>,
    ) -> EvalResult<'tcx> {
        let main_instance = ty::Instance::mono(ecx.tcx, main_id);
        let main_mir = ecx.load_mir(main_instance.def)?;
        let mut cleanup_ptr = None; // Pointer to be deallocated when we are done

        if !main_mir.return_ty.is_nil() || main_mir.arg_count != 0 {
            return err!(Unimplemented(
                "miri does not support main functions without `fn()` type signatures"
                    .to_owned(),
            ));
        }

        if let Some(start_id) = start_wrapper {
            let start_instance = ty::Instance::mono(ecx.tcx, start_id);
            let start_mir = ecx.load_mir(start_instance.def)?;

            if start_mir.arg_count != 3 {
                return err!(AbiViolation(format!(
                    "'start' lang item should have three arguments, but has {}",
                    start_mir.arg_count
                )));
            }

            // Return value
            let size = ecx.tcx.data_layout.pointer_size.bytes();
            let align = ecx.tcx.data_layout.pointer_align.abi();
            let ret_ptr = ecx.memory_mut().allocate(size, align, MemoryKind::Stack)?;
            cleanup_ptr = Some(ret_ptr);

            // Push our stack frame
            ecx.push_stack_frame(
                start_instance,
                start_mir.span,
                start_mir,
                Lvalue::from_ptr(ret_ptr),
                StackPopCleanup::None,
            )?;

            let mut args = ecx.frame().mir.args_iter();

            // First argument: pointer to main()
            let main_ptr = ecx.memory_mut().create_fn_alloc(main_instance);
            let dest = ecx.eval_lvalue(&mir::Lvalue::Local(args.next().unwrap()))?;
            let main_ty = main_instance.def.def_ty(ecx.tcx);
            let main_ptr_ty = ecx.tcx.mk_fn_ptr(main_ty.fn_sig(ecx.tcx));
            ecx.write_value(
                ValTy {
                    value: Value::ByVal(PrimVal::Ptr(main_ptr)),
                    ty: main_ptr_ty,
                },
                dest,
            )?;

            // Second argument (argc): 0
            let dest = ecx.eval_lvalue(&mir::Lvalue::Local(args.next().unwrap()))?;
            let ty = ecx.tcx.types.isize;
            ecx.write_null(dest, ty)?;

            // Third argument (argv): 0
            let dest = ecx.eval_lvalue(&mir::Lvalue::Local(args.next().unwrap()))?;
            let ty = ecx.tcx.mk_imm_ptr(ecx.tcx.mk_imm_ptr(ecx.tcx.types.u8));
            ecx.write_null(dest, ty)?;
        } else {
            ecx.push_stack_frame(
                main_instance,
                main_mir.span,
                main_mir,
                Lvalue::undef(),
                StackPopCleanup::None,
            )?;
        }

        while ecx.step()? {}
        ecx.run_tls_dtors()?;
        if let Some(cleanup_ptr) = cleanup_ptr {
            ecx.memory_mut().deallocate(
                cleanup_ptr,
                None,
                MemoryKind::Stack,
            )?;
        }
        Ok(())
    }

    let mut ecx = EvalContext::new(tcx, limits, Default::default(), Default::default());
    match run_main(&mut ecx, main_id, start_wrapper) {
        Ok(()) => {
            let leaks = ecx.memory().leak_report();
            if leaks != 0 {
                tcx.sess.err("the evaluated program leaked memory");
            }
        }
        Err(mut e) => {
            ecx.report(&mut e);
        }
    }
}

pub struct Evaluator;
#[derive(Default)]
pub struct EvaluatorData {
    /// Environment variables set by `setenv`
    /// Miri does not expose env vars from the host to the emulated program
    pub(crate) env_vars: HashMap<Vec<u8>, MemoryPointer>,
}

pub type TlsKey = usize;

#[derive(Copy, Clone, Debug)]
pub struct TlsEntry<'tcx> {
    data: Pointer, // Will eventually become a map from thread IDs to `Pointer`s, if we ever support more than one thread.
    dtor: Option<ty::Instance<'tcx>>,
}

#[derive(Default)]
pub struct MemoryData<'tcx> {
    /// The Key to use for the next thread-local allocation.
    next_thread_local: TlsKey,

    /// pthreads-style thread-local storage.
    thread_local: BTreeMap<TlsKey, TlsEntry<'tcx>>,
}

impl<'tcx> Machine<'tcx> for Evaluator {
    type Data = EvaluatorData;
    type MemoryData = MemoryData<'tcx>;
    type MemoryKinds = memory::MemoryKind;

    /// Returns Ok() when the function was handled, fail otherwise
    fn eval_fn_call<'a>(
        ecx: &mut EvalContext<'a, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        destination: Option<(Lvalue, mir::BasicBlock)>,
        args: &[ValTy<'tcx>],
        span: Span,
        sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx, bool> {
        ecx.eval_fn_call(instance, destination, args, span, sig)
    }

    fn call_intrinsic<'a>(
        ecx: &mut rustc_miri::interpret::EvalContext<'a, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[ValTy<'tcx>],
        dest: Lvalue,
        dest_ty: ty::Ty<'tcx>,
        dest_layout: &'tcx Layout,
        target: mir::BasicBlock,
    ) -> EvalResult<'tcx> {
        ecx.call_intrinsic(instance, args, dest, dest_ty, dest_layout, target)
    }

    fn try_ptr_op<'a>(
        ecx: &rustc_miri::interpret::EvalContext<'a, 'tcx, Self>,
        bin_op: mir::BinOp,
        left: PrimVal,
        left_ty: ty::Ty<'tcx>,
        right: PrimVal,
        right_ty: ty::Ty<'tcx>,
    ) -> EvalResult<'tcx, Option<(PrimVal, bool)>> {
        ecx.ptr_op(bin_op, left, left_ty, right, right_ty)
    }

    fn mark_static_initialized(m: memory::MemoryKind) -> EvalResult<'tcx> {
        use memory::MemoryKind::*;
        match m {
            // FIXME: This could be allowed, but not for env vars set during miri execution
            Env => err!(Unimplemented("statics can't refer to env vars".to_owned())),
            _ => Ok(()),
        }
    }

    fn box_alloc<'a>(
        ecx: &mut EvalContext<'a, 'tcx, Self>,
        ty: ty::Ty<'tcx>,
    ) -> EvalResult<'tcx, PrimVal> {
        // FIXME: call the `exchange_malloc` lang item if available
        let size = ecx.type_size(ty)?.expect("box only works with sized types");
        let align = ecx.type_align(ty)?;
        if size == 0 {
            Ok(PrimVal::Bytes(align.into()))
        } else {
            ecx.memory
                .allocate(size, align, MemoryKind::Machine(memory::MemoryKind::Rust))
                .map(PrimVal::Ptr)
        }
    }
}
<commit_msg>Add at least the program name argument in order to get rustc tests a little further<commit_after>#![feature(
    i128_type,
    rustc_private,
)]

// From rustc.
#[macro_use]
extern crate log;
#[macro_use]
extern crate rustc;
extern crate syntax;

use rustc::ty::{self, TyCtxt};
use rustc::ty::layout::Layout;
use rustc::hir::def_id::DefId;
use rustc::mir;

use syntax::ast::Mutability;
use syntax::codemap::Span;

use std::collections::{HashMap, BTreeMap};

#[macro_use]
extern crate rustc_miri;
pub use rustc_miri::interpret::*;

mod fn_call;
mod operator;
mod intrinsic;
mod helpers;
mod memory;
mod tls;

use fn_call::EvalContextExt as MissingFnsEvalContextExt;
use operator::EvalContextExt as OperatorEvalContextExt;
use intrinsic::EvalContextExt as IntrinsicEvalContextExt;
use tls::EvalContextExt as TlsEvalContextExt;

pub fn eval_main<'a, 'tcx: 'a>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    main_id: DefId,
    start_wrapper: Option<DefId>,
    limits: ResourceLimits,
) {
    fn run_main<'a, 'tcx: 'a>(
        ecx: &mut rustc_miri::interpret::EvalContext<'a, 'tcx, Evaluator>,
        main_id: DefId,
        start_wrapper: Option<DefId>,
    ) -> EvalResult<'tcx> {
        let main_instance = ty::Instance::mono(ecx.tcx, main_id);
        let main_mir = ecx.load_mir(main_instance.def)?;
        let mut cleanup_ptr = None; // Pointer to be deallocated when we are done

        if !main_mir.return_ty.is_nil() || main_mir.arg_count != 0 {
            return err!(Unimplemented(
                "miri does not support main functions without `fn()` type signatures"
                    .to_owned(),
            ));
        }

        if let Some(start_id) = start_wrapper {
            let start_instance = ty::Instance::mono(ecx.tcx, start_id);
            let start_mir = ecx.load_mir(start_instance.def)?;

            if start_mir.arg_count != 3 {
                return err!(AbiViolation(format!(
                    "'start' lang item should have three arguments, but has {}",
                    start_mir.arg_count
                )));
            }

            // Return value
            let size = ecx.tcx.data_layout.pointer_size.bytes();
            let align = ecx.tcx.data_layout.pointer_align.abi();
            let ret_ptr = ecx.memory_mut().allocate(size, align, MemoryKind::Stack)?;
            cleanup_ptr = Some(ret_ptr);

            // Push our stack frame
            ecx.push_stack_frame(
                start_instance,
                start_mir.span,
                start_mir,
                Lvalue::from_ptr(ret_ptr),
                StackPopCleanup::None,
            )?;

            let mut args = ecx.frame().mir.args_iter();

            // First argument: pointer to main()
            let main_ptr = ecx.memory_mut().create_fn_alloc(main_instance);
            let dest = ecx.eval_lvalue(&mir::Lvalue::Local(args.next().unwrap()))?;
            let main_ty = main_instance.def.def_ty(ecx.tcx);
            let main_ptr_ty = ecx.tcx.mk_fn_ptr(main_ty.fn_sig(ecx.tcx));
            ecx.write_value(
                ValTy {
                    value: Value::ByVal(PrimVal::Ptr(main_ptr)),
                    ty: main_ptr_ty,
                },
                dest,
            )?;

            // Second argument (argc): 1
            let dest = ecx.eval_lvalue(&mir::Lvalue::Local(args.next().unwrap()))?;
            let ty = ecx.tcx.types.isize;
            ecx.write_primval(dest, PrimVal::Bytes(1), ty)?;

            // FIXME: extract main source file path
            // Third argument (argv): &[b"foo"]
            let dest = ecx.eval_lvalue(&mir::Lvalue::Local(args.next().unwrap()))?;
            let ty = ecx.tcx.mk_imm_ptr(ecx.tcx.mk_imm_ptr(ecx.tcx.types.u8));
            let foo = ecx.memory.allocate_cached(b"foo\0")?;
            let ptr_size = ecx.memory.pointer_size();
            let foo_ptr = ecx.memory.allocate(ptr_size * 1, ptr_size, MemoryKind::UninitializedStatic)?;
            ecx.memory.write_primval(foo_ptr.into(), PrimVal::Ptr(foo.into()), ptr_size, false)?;
            ecx.memory.mark_static_initalized(foo_ptr.alloc_id, Mutability::Immutable)?;
            ecx.write_ptr(dest, foo_ptr.into(), ty)?;
        } else {
            ecx.push_stack_frame(
                main_instance,
                main_mir.span,
                main_mir,
                Lvalue::undef(),
                StackPopCleanup::None,
            )?;
        }

        while ecx.step()? {}
        ecx.run_tls_dtors()?;
        if let Some(cleanup_ptr) = cleanup_ptr {
            ecx.memory_mut().deallocate(
                cleanup_ptr,
                None,
                MemoryKind::Stack,
            )?;
        }
        Ok(())
    }

    let mut ecx = EvalContext::new(tcx, limits, Default::default(), Default::default());
    match run_main(&mut ecx, main_id, start_wrapper) {
        Ok(()) => {
            let leaks = ecx.memory().leak_report();
            if leaks != 0 {
                tcx.sess.err("the evaluated program leaked memory");
            }
        }
        Err(mut e) => {
            ecx.report(&mut e);
        }
    }
}

pub struct Evaluator;
#[derive(Default)]
pub struct EvaluatorData {
    /// Environment variables set by `setenv`
    /// Miri does not expose env vars from the host to the emulated program
    pub(crate) env_vars: HashMap<Vec<u8>, MemoryPointer>,
}

pub type TlsKey = usize;

#[derive(Copy, Clone, Debug)]
pub struct TlsEntry<'tcx> {
    data: Pointer, // Will eventually become a map from thread IDs to `Pointer`s, if we ever support more than one thread.
    dtor: Option<ty::Instance<'tcx>>,
}

#[derive(Default)]
pub struct MemoryData<'tcx> {
    /// The Key to use for the next thread-local allocation.
    next_thread_local: TlsKey,

    /// pthreads-style thread-local storage.
    thread_local: BTreeMap<TlsKey, TlsEntry<'tcx>>,
}

impl<'tcx> Machine<'tcx> for Evaluator {
    type Data = EvaluatorData;
    type MemoryData = MemoryData<'tcx>;
    type MemoryKinds = memory::MemoryKind;

    /// Returns Ok() when the function was handled, fail otherwise
    fn eval_fn_call<'a>(
        ecx: &mut EvalContext<'a, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        destination: Option<(Lvalue, mir::BasicBlock)>,
        args: &[ValTy<'tcx>],
        span: Span,
        sig: ty::FnSig<'tcx>,
    ) -> EvalResult<'tcx, bool> {
        ecx.eval_fn_call(instance, destination, args, span, sig)
    }

    fn call_intrinsic<'a>(
        ecx: &mut rustc_miri::interpret::EvalContext<'a, 'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[ValTy<'tcx>],
        dest: Lvalue,
        dest_ty: ty::Ty<'tcx>,
        dest_layout: &'tcx Layout,
        target: mir::BasicBlock,
    ) -> EvalResult<'tcx> {
        ecx.call_intrinsic(instance, args, dest, dest_ty, dest_layout, target)
    }

    fn try_ptr_op<'a>(
        ecx: &rustc_miri::interpret::EvalContext<'a, 'tcx, Self>,
        bin_op: mir::BinOp,
        left: PrimVal,
        left_ty: ty::Ty<'tcx>,
        right: PrimVal,
        right_ty: ty::Ty<'tcx>,
    ) -> EvalResult<'tcx, Option<(PrimVal, bool)>> {
        ecx.ptr_op(bin_op, left, left_ty, right, right_ty)
    }

    fn mark_static_initialized(m: memory::MemoryKind) -> EvalResult<'tcx> {
        use memory::MemoryKind::*;
        match m {
            // FIXME: This could be allowed, but not for env vars set during miri execution
            Env => err!(Unimplemented("statics can't refer to env vars".to_owned())),
            _ => Ok(()),
        }
    }

    fn box_alloc<'a>(
        ecx: &mut EvalContext<'a, 'tcx, Self>,
        ty: ty::Ty<'tcx>,
    ) -> EvalResult<'tcx, PrimVal> {
        // FIXME: call the `exchange_malloc` lang item if available
        let size = ecx.type_size(ty)?.expect("box only works with sized types");
        let align = ecx.type_align(ty)?;
        if size == 0 {
            Ok(PrimVal::Bytes(align.into()))
        } else {
            ecx.memory
                .allocate(size, align, MemoryKind::Machine(memory::MemoryKind::Rust))
                .map(PrimVal::Ptr)
        }
    }
}
<|endoftext|>