<commit_before>use super::package::*;
use super::executor::*;

use alloc::boxed::Box;

use core::{cmp, ptr, mem};

use common::event::{self, Event, EventOption, KeyEvent, MouseEvent};
use common::resource::{NoneResource, Resource, ResourceType, URL, VecResource};
use common::scheduler::*;
use common::string::{String, ToString};
use common::vec::Vec;

use graphics::bmp::*;
use graphics::color::Color;
use graphics::display::Display;
use graphics::point::Point;
use graphics::size::Size;
use graphics::window::Window;

use programs::common::SessionItem;

pub struct Session {
    pub display: Display,
    pub background: BMPFile,
    pub cursor: BMPFile,
    pub mouse_point: Point,
    last_mouse_event: MouseEvent,
    pub items: Vec<Box<SessionItem>>,
    pub packages: Vec<Box<Package>>,
    pub windows: Vec<*mut Window>,
    pub windows_ordered: Vec<*mut Window>,
    pub redraw: usize,
}

impl Session {
    pub fn new() -> Self {
        unsafe {
            Session {
                display: Display::root(),
                background: BMPFile::new(),
                cursor: BMPFile::new(),
                mouse_point: Point::new(0, 0),
                last_mouse_event: MouseEvent {
                    x: 0,
                    y: 0,
                    left_button: false,
                    middle_button: false,
                    right_button: false,
                },
                items: Vec::new(),
                packages: Vec::new(),
                windows: Vec::new(),
                windows_ordered: Vec::new(),
                redraw: event::REDRAW_ALL,
            }
        }
    }

    pub unsafe fn add_window(&mut self, add_window_ptr: *mut Window) {
        self.windows.push(add_window_ptr);
        self.windows_ordered.push(add_window_ptr);
        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
    }

    pub unsafe fn remove_window(&mut self, remove_window_ptr: *mut Window) {
        let mut i = 0;
        while i < self.windows.len() {
            let mut remove = false;

            match self.windows.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                } else {
                    i += 1;
                },
                Option::None => break,
            }

            if remove {
                self.windows.remove(i);
            }
        }

        i = 0;
        while i < self.windows_ordered.len() {
            let mut remove = false;

            match self.windows_ordered.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                } else {
                    i += 1;
                },
                Option::None => break,
            }

            if remove {
                self.windows_ordered.remove(i);
            }
        }

        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
    }

    pub unsafe fn on_irq(&mut self, irq: u8) {
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_irq(irq);
            end_no_ints(reenable);
        }
    }

    pub unsafe fn on_poll(&mut self) {
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_poll();
            end_no_ints(reenable);
        }
    }

    pub fn open(&self, url: &URL) -> Box<Resource> {
        if url.scheme().len() == 0 {
            let mut list = String::new();

            for item in self.items.iter() {
                let scheme = item.scheme();
                if scheme.len() > 0 {
                    if list.len() > 0 {
                        list = list + "\n" + scheme;
                    } else {
                        list = scheme;
                    }
                }
            }

            box VecResource::new(URL::new(), ResourceType::Dir, list.to_utf8())
        } else {
            for item in self.items.iter() {
                if item.scheme() == url.scheme() {
                    return item.open(url);
                }
            }
            box NoneResource
        }
    }

    fn on_key(&mut self, key_event: KeyEvent) {
        if self.windows.len() > 0 {
            match self.windows.get(self.windows.len() - 1) {
                Option::Some(window_ptr) => {
                    unsafe {
                        (**window_ptr).on_key(key_event);
                        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
                    }
                }
                Option::None => (),
            }
        }
    }

    fn on_mouse(&mut self, mouse_event: MouseEvent) {
        let mut catcher = -1;

        if mouse_event.y >= self.display.height as isize - 32 {
            if mouse_event.left_button && !self.last_mouse_event.left_button {
                let mut x = 0;
                for package in self.packages.iter() {
                    if package.icon.data.len() > 0 {
                        if mouse_event.x >= x &&
                           mouse_event.x < x + package.icon.size.width as isize {
                            execute(&package.binary, &package.url, &Vec::new());
                        }
                        x += package.icon.size.width as isize;
                    }
                }

                let mut chars = 32;
                while chars > 4 &&
                      (x as usize + (chars * 8 + 3 * 4) * self.windows.len()) >
                      self.display.width + 32 {
                    chars -= 1;
                }

                x += 4;
                for window_ptr in self.windows_ordered.iter() {
                    let w = (chars*8 + 2*4) as usize;
                    if mouse_event.x >= x && mouse_event.x < x + w as isize {
                        for j in 0..self.windows.len() {
                            match self.windows.get(j) {
                                Option::Some(catcher_window_ptr) =>
                                    if catcher_window_ptr == window_ptr {
                                    unsafe {
                                        if j == self.windows.len() - 1 {
                                            (**window_ptr).minimized = !(**window_ptr).minimized;
                                        } else {
                                            catcher = j as isize;
                                            (**window_ptr).minimized = false;
                                        }
                                    }
                                    break;
                                },
                                Option::None => break,
                            }
                        }
                        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
                        break;
                    }
                    x += w as isize;
                }
            }
        } else {
            for reverse_i in 0..self.windows.len() {
                let i = self.windows.len() - 1 - reverse_i;
                match self.windows.get(i) {
                    Option::Some(window_ptr) => unsafe {
                        if (**window_ptr).on_mouse(mouse_event, catcher < 0) {
                            catcher = i as isize;

                            self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
                        }
                    },
                    Option::None => (),
                }
            }
        }

        if catcher >= 0 && catcher < self.windows.len() as isize - 1 {
            match self.windows.remove(catcher as usize) {
                Option::Some(window_ptr) => self.windows.push(window_ptr),
                Option::None => (),
            }
        }

        self.last_mouse_event = mouse_event;
    }

    pub unsafe fn redraw(&mut self) {
        if self.redraw > event::REDRAW_NONE {
            //if self.redraw >= REDRAW_ALL {
            self.display.set(Color::new(64, 64, 64));
            if self.background.data.len() > 0 {
                self.background.draw(&self.display,
                                     Point::new((self.display.width as isize -
                                                 self.background.size.width as isize) /
                                                2,
                                                (self.display.height as isize -
                                                 self.background.size.height as isize) /
                                                2));
            }

            for i in 0..self.windows.len() {
                match self.windows.get(i) {
                    Option::Some(window_ptr) => {
                        (**window_ptr).focused = i == self.windows.len() - 1;
                        (**window_ptr).draw(&self.display);
                    }
                    Option::None => (),
                }
            }

            self.display.rect(Point::new(0, self.display.height as isize - 32),
                              Size::new(self.display.width, 32),
                              Color::alpha(0, 0, 0, 128));

            let mut x = 0;
            for package in self.packages.iter() {
                if package.icon.data.len() > 0 {
                    let y = self.display.height as isize - package.icon.size.height as isize;
                    if self.mouse_point.y >= y && self.mouse_point.x >= x &&
                       self.mouse_point.x < x + package.icon.size.width as isize {
                        self.display.rect(Point::new(x, y),
                                          package.icon.size,
                                          Color::alpha(128, 128, 128, 128));

                        let mut c_x = x;
                        for c in package.name.chars() {
                            self.display
                                .char(Point::new(c_x, y - 16), c, Color::new(255, 255, 255));
                            c_x += 8;
                        }
                    }
                    package.icon.draw(&self.display, Point::new(x, y));
                    x += package.icon.size.width as isize;
                }
            }

            let mut chars = 32;
            while chars > 4 &&
                  (x as usize + (chars * 8 + 3 * 4) * self.windows.len()) >
                  self.display.width + 32 {
                chars -= 1;
            }

            x += 4;
            for window_ptr in self.windows_ordered.iter() {
                let w = (chars*8 + 2*4) as usize;
                self.display.rect(Point::new(x, self.display.height as isize - 32),
                                  Size::new(w, 32),
                                  (**window_ptr).border_color);
                x += 4;

                for i in 0..chars {
                    let c = (**window_ptr).title[i];
                    if c != '\0' {
                        self.display.char(Point::new(x, self.display.height as isize - 24),
                                          c,
                                          (**window_ptr).title_color);
                    }
                    x += 8;
                }
                x += 8;
            }

            if self.cursor.data.len() > 0 {
                self.display.image_alpha(self.mouse_point,
                                         self.cursor.data.as_ptr(),
                                         self.cursor.size);
            } else {
                self.display.char(Point::new(self.mouse_point.x - 3, self.mouse_point.y - 9),
                                  'X',
                                  Color::new(255, 255, 255));
            }
            //}

            let reenable = start_no_ints();

            self.display.flip();

            /*
            if self.cursor.data.len() > 0 {
                self.display.image_alpha_onscreen(self.mouse_point, self.cursor.data.as_ptr(), self.cursor.size);
            } else {
                self.display.char_onscreen(Point::new(self.mouse_point.x - 3, self.mouse_point.y - 9), 'X', Color::new(255, 255, 255));
            }
            */

            self.redraw = event::REDRAW_NONE;

            end_no_ints(reenable);
        }
    }

    pub fn event(&mut self, event: Event) {
        match event.to_option() {
            EventOption::Mouse(mouse_event) => self.on_mouse(mouse_event),
            EventOption::Key(key_event) => self.on_key(key_event),
            EventOption::Redraw(redraw_event) =>
                self.redraw = cmp::max(self.redraw, redraw_event.redraw),
            EventOption::Open(open_event) => {
                let url_string = open_event.url_string;

                if url_string.ends_with(".bin".to_string()) {
                    execute(&URL::from_string(&url_string),
                            &URL::new(),
                            &Vec::new());
                } else {
                    for package in self.packages.iter() {
                        let mut accepted = false;
                        for accept in package.accepts.iter() {
                            if url_string.ends_with(accept.substr(1, accept.len() - 1)) {
                                accepted = true;
                                break;
                            }
                        }
                        if accepted {
                            let mut args: Vec<String> = Vec::new();
                            args.push(url_string.clone());
                            execute(&package.binary, &package.url, &args);
                            break;
                        }
                    }
                }
            }
            _ => (),
        }
    }
}
<commit_msg>Use default color to make loading time less noticeable<commit_after>use super::package::*;
use super::executor::*;

use alloc::boxed::Box;

use core::{cmp, ptr, mem};

use common::event::{self, Event, EventOption, KeyEvent, MouseEvent};
use common::resource::{NoneResource, Resource, ResourceType, URL, VecResource};
use common::scheduler::*;
use common::string::{String, ToString};
use common::vec::Vec;

use graphics::bmp::*;
use graphics::color::Color;
use graphics::display::Display;
use graphics::point::Point;
use graphics::size::Size;
use graphics::window::Window;

use programs::common::SessionItem;

pub struct Session {
    pub display: Display,
    pub background: BMPFile,
    pub cursor: BMPFile,
    pub mouse_point: Point,
    last_mouse_event: MouseEvent,
    pub items: Vec<Box<SessionItem>>,
    pub packages: Vec<Box<Package>>,
    pub windows: Vec<*mut Window>,
    pub windows_ordered: Vec<*mut Window>,
    pub redraw: usize,
}

impl Session {
    pub fn new() -> Self {
        unsafe {
            Session {
                display: Display::root(),
                background: BMPFile::new(),
                cursor: BMPFile::new(),
                mouse_point: Point::new(0, 0),
                last_mouse_event: MouseEvent {
                    x: 0,
                    y: 0,
                    left_button: false,
                    middle_button: false,
                    right_button: false,
                },
                items: Vec::new(),
                packages: Vec::new(),
                windows: Vec::new(),
                windows_ordered: Vec::new(),
                redraw: event::REDRAW_ALL,
            }
        }
    }

    pub unsafe fn add_window(&mut self, add_window_ptr: *mut Window) {
        self.windows.push(add_window_ptr);
        self.windows_ordered.push(add_window_ptr);
        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
    }

    pub unsafe fn remove_window(&mut self, remove_window_ptr: *mut Window) {
        let mut i = 0;
        while i < self.windows.len() {
            let mut remove = false;

            match self.windows.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                } else {
                    i += 1;
                },
                Option::None => break,
            }

            if remove {
                self.windows.remove(i);
            }
        }

        i = 0;
        while i < self.windows_ordered.len() {
            let mut remove = false;

            match self.windows_ordered.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                } else {
                    i += 1;
                },
                Option::None => break,
            }

            if remove {
                self.windows_ordered.remove(i);
            }
        }

        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
    }

    pub unsafe fn on_irq(&mut self, irq: u8) {
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_irq(irq);
            end_no_ints(reenable);
        }
    }

    pub unsafe fn on_poll(&mut self) {
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_poll();
            end_no_ints(reenable);
        }
    }

    pub fn open(&self, url: &URL) -> Box<Resource> {
        if url.scheme().len() == 0 {
            let mut list = String::new();

            for item in self.items.iter() {
                let scheme = item.scheme();
                if scheme.len() > 0 {
                    if list.len() > 0 {
                        list = list + "\n" + scheme;
                    } else {
                        list = scheme;
                    }
                }
            }

            box VecResource::new(URL::new(), ResourceType::Dir, list.to_utf8())
        } else {
            for item in self.items.iter() {
                if item.scheme() == url.scheme() {
                    return item.open(url);
                }
            }
            box NoneResource
        }
    }

    fn on_key(&mut self, key_event: KeyEvent) {
        if self.windows.len() > 0 {
            match self.windows.get(self.windows.len() - 1) {
                Option::Some(window_ptr) => {
                    unsafe {
                        (**window_ptr).on_key(key_event);
                        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
                    }
                }
                Option::None => (),
            }
        }
    }

    fn on_mouse(&mut self, mouse_event: MouseEvent) {
        let mut catcher = -1;

        if mouse_event.y >= self.display.height as isize - 32 {
            if mouse_event.left_button && !self.last_mouse_event.left_button {
                let mut x = 0;
                for package in self.packages.iter() {
                    if package.icon.data.len() > 0 {
                        if mouse_event.x >= x &&
                           mouse_event.x < x + package.icon.size.width as isize {
                            execute(&package.binary, &package.url, &Vec::new());
                        }
                        x += package.icon.size.width as isize;
                    }
                }

                let mut chars = 32;
                while chars > 4 &&
                      (x as usize + (chars * 8 + 3 * 4) * self.windows.len()) >
                      self.display.width + 32 {
                    chars -= 1;
                }

                x += 4;
                for window_ptr in self.windows_ordered.iter() {
                    let w = (chars*8 + 2*4) as usize;
                    if mouse_event.x >= x && mouse_event.x < x + w as isize {
                        for j in 0..self.windows.len() {
                            match self.windows.get(j) {
                                Option::Some(catcher_window_ptr) =>
                                    if catcher_window_ptr == window_ptr {
                                    unsafe {
                                        if j == self.windows.len() - 1 {
                                            (**window_ptr).minimized = !(**window_ptr).minimized;
                                        } else {
                                            catcher = j as isize;
                                            (**window_ptr).minimized = false;
                                        }
                                    }
                                    break;
                                },
                                Option::None => break,
                            }
                        }
                        self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
                        break;
                    }
                    x += w as isize;
                }
            }
        } else {
            for reverse_i in 0..self.windows.len() {
                let i = self.windows.len() - 1 - reverse_i;
                match self.windows.get(i) {
                    Option::Some(window_ptr) => unsafe {
                        if (**window_ptr).on_mouse(mouse_event, catcher < 0) {
                            catcher = i as isize;

                            self.redraw = cmp::max(self.redraw, event::REDRAW_ALL);
                        }
                    },
                    Option::None => (),
                }
            }
        }

        if catcher >= 0 && catcher < self.windows.len() as isize - 1 {
            match self.windows.remove(catcher as usize) {
                Option::Some(window_ptr) => self.windows.push(window_ptr),
                Option::None => (),
            }
        }

        self.last_mouse_event = mouse_event;
    }

    pub unsafe fn redraw(&mut self) {
        if self.redraw > event::REDRAW_NONE {
            //if self.redraw >= REDRAW_ALL {
            self.display.set(Color::new(75, 163, 253));
            if self.background.data.len() > 0 {
                self.background.draw(&self.display,
                                     Point::new((self.display.width as isize -
                                                 self.background.size.width as isize) /
                                                2,
                                                (self.display.height as isize -
                                                 self.background.size.height as isize) /
                                                2));
            }

            for i in 0..self.windows.len() {
                match self.windows.get(i) {
                    Option::Some(window_ptr) => {
                        (**window_ptr).focused = i == self.windows.len() - 1;
                        (**window_ptr).draw(&self.display);
                    }
                    Option::None => (),
                }
            }

            self.display.rect(Point::new(0, self.display.height as isize - 32),
                              Size::new(self.display.width, 32),
                              Color::alpha(0, 0, 0, 128));

            let mut x = 0;
            for package in self.packages.iter() {
                if package.icon.data.len() > 0 {
                    let y = self.display.height as isize - package.icon.size.height as isize;
                    if self.mouse_point.y >= y && self.mouse_point.x >= x &&
                       self.mouse_point.x < x + package.icon.size.width as isize {
                        self.display.rect(Point::new(x, y),
                                          package.icon.size,
                                          Color::alpha(128, 128, 128, 128));

                        let mut c_x = x;
                        for c in package.name.chars() {
                            self.display
                                .char(Point::new(c_x, y - 16), c, Color::new(255, 255, 255));
                            c_x += 8;
                        }
                    }
                    package.icon.draw(&self.display, Point::new(x, y));
                    x += package.icon.size.width as isize;
                }
            }

            let mut chars = 32;
            while chars > 4 &&
                  (x as usize + (chars * 8 + 3 * 4) * self.windows.len()) >
                  self.display.width + 32 {
                chars -= 1;
            }

            x += 4;
            for window_ptr in self.windows_ordered.iter() {
                let w = (chars*8 + 2*4) as usize;
                self.display.rect(Point::new(x, self.display.height as isize - 32),
                                  Size::new(w, 32),
                                  (**window_ptr).border_color);
                x += 4;

                for i in 0..chars {
                    let c = (**window_ptr).title[i];
                    if c != '\0' {
                        self.display.char(Point::new(x, self.display.height as isize - 24),
                                          c,
                                          (**window_ptr).title_color);
                    }
                    x += 8;
                }
                x += 8;
            }

            if self.cursor.data.len() > 0 {
                self.display.image_alpha(self.mouse_point,
                                         self.cursor.data.as_ptr(),
                                         self.cursor.size);
            } else {
                self.display.char(Point::new(self.mouse_point.x - 3, self.mouse_point.y - 9),
                                  'X',
                                  Color::new(255, 255, 255));
            }
            //}

            let reenable = start_no_ints();

            self.display.flip();

            /*
            if self.cursor.data.len() > 0 {
                self.display.image_alpha_onscreen(self.mouse_point, self.cursor.data.as_ptr(), self.cursor.size);
            } else {
                self.display.char_onscreen(Point::new(self.mouse_point.x - 3, self.mouse_point.y - 9), 'X', Color::new(255, 255, 255));
            }
            */

            self.redraw = event::REDRAW_NONE;

            end_no_ints(reenable);
        }
    }

    pub fn event(&mut self, event: Event) {
        match event.to_option() {
            EventOption::Mouse(mouse_event) => self.on_mouse(mouse_event),
            EventOption::Key(key_event) => self.on_key(key_event),
            EventOption::Redraw(redraw_event) =>
                self.redraw = cmp::max(self.redraw, redraw_event.redraw),
            EventOption::Open(open_event) => {
                let url_string = open_event.url_string;

                if url_string.ends_with(".bin".to_string()) {
                    execute(&URL::from_string(&url_string),
                            &URL::new(),
                            &Vec::new());
                } else {
                    for package in self.packages.iter() {
                        let mut accepted = false;
                        for accept in package.accepts.iter() {
                            if url_string.ends_with(accept.substr(1, accept.len() - 1)) {
                                accepted = true;
                                break;
                            }
                        }
                        if accepted {
                            let mut args: Vec<String> = Vec::new();
                            args.push(url_string.clone());
                            execute(&package.binary, &package.url, &args);
                            break;
                        }
                    }
                }
            }
            _ => (),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add cfail test for the new feature gate<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

// Test that the MSP430 interrupt ABI cannot be used when msp430_interrupt
// feature gate is not used.

extern "msp430-interrupt" fn foo() {}
//~^ ERROR msp430-interrupt ABI is experimental and subject to change

fn main() {
    foo();
}
<|endoftext|>


<commit_before><commit_msg>Add privately uninhabited dead code test<commit_after>// compile-pass

#![deny(unreachable_code)]

mod foo {
    enum Bar {}

    #[allow(dead_code)]
    pub struct Foo {
        value: Bar, // "privately" uninhabited
    }

    pub fn give_foo() -> Foo { panic!() }
}

fn main() {
    foo::give_foo();
    println!("Hello, world!"); // ok: we can't tell that this code is dead
}
<|endoftext|>


<commit_before><commit_msg>Add ui simple helpers<commit_after>pub fn time_ui_fmtstr() -> &'static str {
    "YYYY-MM-DD[THH[:mm[:ss]]]"
}

pub fn time_ui_fmtstr_expl() -> &'static str {
    #r"In the UI, the format for Time is always YEAR-MONTH-DAY.
    Optionally, Time can be specified by seperating it from the date with 'T'.
    Minutes and Seconds are optional.
    "#
}

<|endoftext|>


<commit_before><commit_msg>add Device Farm tests<commit_after>#![cfg(feature = "devicefarm")]

extern crate rusoto;

use rusoto::devicefarm::{DeviceFarmClient, ListDevicesRequest};
use rusoto::{DefaultCredentialsProvider, Region};

#[test]
pub fn should_list_devices() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DeviceFarmClient::new(credentials, Region::UsWest2);

    let request = ListDevicesRequest::default();

    match client.list_devices(&request) {
        Ok(response) => {
            assert!(!response.devices.unwrap().is_empty())
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}
<|endoftext|>


<commit_before><commit_msg>Formatting mistake in the help function<commit_after><|endoftext|>


<commit_before><commit_msg>Test #[from]<commit_after>use std::io;
use thiserror::Error;

#[derive(Error, Debug)]
#[error("...")]
pub struct ErrorStruct {
    #[from]
    source: io::Error,
}

#[derive(Error, Debug)]
#[error("...")]
pub struct ErrorTuple(#[from] io::Error);

#[derive(Error, Debug)]
#[error("...")]
pub enum ErrorEnum {
    Test {
        #[from]
        source: io::Error,
    },
}

#[derive(Error, Debug)]
#[error("...")]
pub enum Many {
    Any(#[from] anyhow::Error),
    Io(#[from] io::Error),
}

fn assert_impl<T: From<io::Error>>() {}

#[test]
fn test_from() {
    assert_impl::<ErrorStruct>();
    assert_impl::<ErrorTuple>();
    assert_impl::<ErrorEnum>();
    assert_impl::<Many>();
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate png;
extern crate std;
extern crate test;

use std::io;
use std::io::{File, Reader, Process};
use std::io::process::ExitStatus;
use std::os;
use std::str;
use test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use test::run_tests_console;

fn main() {
    let args = os::args();
    let mut parts = args.tail().split(|e| "--" == e.as_slice());

    let files = parts.next().unwrap();  // .split() is never empty
    let servo_args = parts.next().unwrap_or(&[]);

    if files.len() == 0 {
        fail!("error: at least one reftest list must be given");
    }

    let tests = parse_lists(files, servo_args);
    let test_opts = TestOpts {
        filter: None,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        ratchet_noise_percent: None,
        ratchet_metrics: None,
        save_metrics: None,
        test_shard: None,
    };

    match run_tests_console(&test_opts, tests) {
        Ok(false) => os::set_exit_status(1), // tests failed
        Err(_) => os::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

#[deriving(Eq)]
enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: ~str,
    kind: ReftestKind,
    files: [~str, ..2],
    id: uint,
    servo_args: ~[~str],
}

fn parse_lists(filenames: &[~str], servo_args: &[~str]) -> Vec<TestDescAndFn> {
    let mut tests = Vec::new();
    let mut next_id = 0;
    for file in filenames.iter() {
        let file_path = Path::new(file.clone());
        let contents = match File::open_mode(&file_path, io::Open, io::Read)
            .and_then(|mut f| {
                f.read_to_str()
            }) {
                Ok(s) => s,
                _ => fail!("Could not read file"),
            };

        for line in contents.lines() {
            // ignore comments
            if line.starts_with("#") {
                continue;
            }

            let parts: ~[&str] = line.split(' ').filter(|p| !p.is_empty()).collect();

            if parts.len() != 3 {
                fail!("reftest line: '{:s}' doesn't match 'KIND LEFT RIGHT'", line);
            }

            let kind = match parts[0] {
                "==" => Same,
                "!=" => Different,
                _ => fail!("reftest line: '{:s}' has invalid kind '{:s}'",
                           line, parts[0])
            };
            let src_path = file_path.dir_path();
            let src_dir = src_path.display().to_str();
            let file_left =  src_dir + "/" + parts[1];
            let file_right = src_dir + "/" + parts[2];

            let reftest = Reftest {
                name: parts[1] + " / " + parts[2],
                kind: kind,
                files: [file_left, file_right],
                id: next_id,
                servo_args: servo_args.to_owned(),
            };

            next_id += 1;

            tests.push(make_test(reftest));
        }
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: false,
        },
        testfn: DynTestFn(proc() {
            check_reftest(reftest);
        }),
    }
}

fn capture(reftest: &Reftest, side: uint) -> png::Image {
    let filename = format!("/tmp/servo-reftest-{:06u}-{:u}.png", reftest.id, side);
    let mut args = reftest.servo_args.clone();
    args.push_all_move(~["-f".to_owned(), "-o".to_owned(), filename.clone(), reftest.files[side].clone()]);

    let retval = match Process::status("./servo", args) {
        Ok(status) => status,
        Err(e) => fail!("failed to execute process: {}", e),
    };
    assert!(retval == ExitStatus(0));

    png::load_png(&from_str::<Path>(filename).unwrap()).unwrap()
}

fn check_reftest(reftest: Reftest) {
    let left  = capture(&reftest, 0);
    let right = capture(&reftest, 1);

    let pixels: ~[u8] = left.pixels.iter().zip(right.pixels.iter()).map(|(&a, &b)| {
            if a as i8 - b as i8 == 0 {
                // White for correct
                0xFF
            } else {
                // "1100" in the RGBA channel with an error for an incorrect value
                // This results in some number of C0 and FFs, which is much more
                // readable (and distinguishable) than the previous difference-wise
                // scaling but does not require reconstructing the actual RGBA pixel.
                0xC0
            }
        }).collect();

    if pixels.iter().any(|&a| a < 255) {
        let output_str = format!("/tmp/servo-reftest-{:06u}-diff.png", reftest.id);
        let output = from_str::<Path>(output_str).unwrap();

        let img = png::Image {
            width: left.width,
            height: left.height,
            color_type: png::RGBA8,
            pixels: pixels,
        };
        let res = png::store_png(&img, &output);
        assert!(res.is_ok());

        assert!(reftest.kind == Different, "rendering difference: {}", output_str);
    } else {
        assert!(reftest.kind == Same);
    }
}
<commit_msg>auto merge of #2350 : zwarich/servo/unused-str-import, r=metajack<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate png;
extern crate std;
extern crate test;

use std::io;
use std::io::{File, Reader, Process};
use std::io::process::ExitStatus;
use std::os;
use test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use test::run_tests_console;

fn main() {
    let args = os::args();
    let mut parts = args.tail().split(|e| "--" == e.as_slice());

    let files = parts.next().unwrap();  // .split() is never empty
    let servo_args = parts.next().unwrap_or(&[]);

    if files.len() == 0 {
        fail!("error: at least one reftest list must be given");
    }

    let tests = parse_lists(files, servo_args);
    let test_opts = TestOpts {
        filter: None,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        ratchet_noise_percent: None,
        ratchet_metrics: None,
        save_metrics: None,
        test_shard: None,
    };

    match run_tests_console(&test_opts, tests) {
        Ok(false) => os::set_exit_status(1), // tests failed
        Err(_) => os::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

#[deriving(Eq)]
enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: ~str,
    kind: ReftestKind,
    files: [~str, ..2],
    id: uint,
    servo_args: ~[~str],
}

fn parse_lists(filenames: &[~str], servo_args: &[~str]) -> Vec<TestDescAndFn> {
    let mut tests = Vec::new();
    let mut next_id = 0;
    for file in filenames.iter() {
        let file_path = Path::new(file.clone());
        let contents = match File::open_mode(&file_path, io::Open, io::Read)
            .and_then(|mut f| {
                f.read_to_str()
            }) {
                Ok(s) => s,
                _ => fail!("Could not read file"),
            };

        for line in contents.lines() {
            // ignore comments
            if line.starts_with("#") {
                continue;
            }

            let parts: ~[&str] = line.split(' ').filter(|p| !p.is_empty()).collect();

            if parts.len() != 3 {
                fail!("reftest line: '{:s}' doesn't match 'KIND LEFT RIGHT'", line);
            }

            let kind = match parts[0] {
                "==" => Same,
                "!=" => Different,
                _ => fail!("reftest line: '{:s}' has invalid kind '{:s}'",
                           line, parts[0])
            };
            let src_path = file_path.dir_path();
            let src_dir = src_path.display().to_str();
            let file_left =  src_dir + "/" + parts[1];
            let file_right = src_dir + "/" + parts[2];

            let reftest = Reftest {
                name: parts[1] + " / " + parts[2],
                kind: kind,
                files: [file_left, file_right],
                id: next_id,
                servo_args: servo_args.to_owned(),
            };

            next_id += 1;

            tests.push(make_test(reftest));
        }
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: false,
        },
        testfn: DynTestFn(proc() {
            check_reftest(reftest);
        }),
    }
}

fn capture(reftest: &Reftest, side: uint) -> png::Image {
    let filename = format!("/tmp/servo-reftest-{:06u}-{:u}.png", reftest.id, side);
    let mut args = reftest.servo_args.clone();
    args.push_all_move(~["-f".to_owned(), "-o".to_owned(), filename.clone(), reftest.files[side].clone()]);

    let retval = match Process::status("./servo", args) {
        Ok(status) => status,
        Err(e) => fail!("failed to execute process: {}", e),
    };
    assert!(retval == ExitStatus(0));

    png::load_png(&from_str::<Path>(filename).unwrap()).unwrap()
}

fn check_reftest(reftest: Reftest) {
    let left  = capture(&reftest, 0);
    let right = capture(&reftest, 1);

    let pixels: ~[u8] = left.pixels.iter().zip(right.pixels.iter()).map(|(&a, &b)| {
            if a as i8 - b as i8 == 0 {
                // White for correct
                0xFF
            } else {
                // "1100" in the RGBA channel with an error for an incorrect value
                // This results in some number of C0 and FFs, which is much more
                // readable (and distinguishable) than the previous difference-wise
                // scaling but does not require reconstructing the actual RGBA pixel.
                0xC0
            }
        }).collect();

    if pixels.iter().any(|&a| a < 255) {
        let output_str = format!("/tmp/servo-reftest-{:06u}-diff.png", reftest.id);
        let output = from_str::<Path>(output_str).unwrap();

        let img = png::Image {
            width: left.width,
            height: left.height,
            color_type: png::RGBA8,
            pixels: pixels,
        };
        let res = png::store_png(&img, &output);
        assert!(res.is_ok());

        assert!(reftest.kind == Different, "rendering difference: {}", output_str);
    } else {
        assert!(reftest.kind == Same);
    }
}
<|endoftext|>


<commit_before><commit_msg>Test that binop subtyping in rustc_typeck fixes #27949<commit_after>// run-pass
//
// At one time, the `==` operator (and other binary operators) did not
// support subtyping during type checking, and would therefore require
// LHS and RHS to be exactly identical--i.e. to have the same lifetimes.
//
// This was fixed in 1a7fb7dc78439a704f024609ce3dc0beb1386552.

#[derive(Copy, Clone)]
struct Input<'a> {
    foo: &'a u32
}

impl <'a> std::cmp::PartialEq<Input<'a>> for Input<'a> {
    fn eq(&self, other: &Input<'a>) -> bool {
        self.foo == other.foo
    }

    fn ne(&self, other: &Input<'a>) -> bool {
        self.foo != other.foo
    }
}

fn check_equal<'a, 'b>(x: Input<'a>, y: Input<'b>) -> bool {
    // Type checking error due to 'a != 'b prior to 1a7fb7dc78
    x == y
}

fn main() {
    let i = 1u32;
    let j = 1u32;
    let k = 2u32;

    let input_i = Input { foo: &i };
    let input_j = Input { foo: &j };
    let input_k = Input { foo: &k };
    assert!(check_equal(input_i, input_i));
    assert!(check_equal(input_i, input_j));
    assert!(!check_equal(input_i, input_k));
}
<|endoftext|>


<commit_before><commit_msg>Match more status codes.<commit_after><|endoftext|>


<commit_before><commit_msg>Quick test for calling points.<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

//! Code related to match expresions. These are sufficiently complex
//! to warrant their own module and submodules. :) This main module
//! includes the high-level algorithm, the submodules contain the
//! details.

use build::{BlockAnd, Builder};
use repr::*;
use hair::*;

// helper functions, broken out by category:
mod simplify;
mod test;
mod util;

impl<H:Hair> Builder<H> {
    pub fn match_expr(&mut self,
                      destination: &Lvalue<H>,
                      span: H::Span,
                      mut block: BasicBlock,
                      discriminant: ExprRef<H>,
                      arms: Vec<Arm<H>>)
                      -> BlockAnd<()>
    {
        let discriminant_lvalue =
            unpack!(block = self.as_lvalue(block, discriminant));

        let arm_blocks: Vec<BasicBlock> =
            arms.iter()
                .map(|_| self.cfg.start_new_block())
                .collect();

        let arm_bodies: Vec<ExprRef<H>> =
            arms.iter()
                .map(|arm| arm.body.clone())
                .collect();

        // assemble a list of candidates: there is one candidate per
        // pattern, which means there may be more than one candidate
        // *per arm*. These candidates are kept sorted such that the
        // highest priority candidate comes last in the list. This the
        // reverse of the order in which candidates are written in the
        // source.
        let candidates: Vec<Candidate<H>> =
            arms.into_iter()
                .zip(arm_blocks.iter())
                .rev() // highest priority comes last
                .flat_map(|(arm, &arm_block)| {
                    let guard = arm.guard;
                    arm.patterns.into_iter()
                                .rev()
                                .map(move |pat| (arm_block, pat, guard.clone()))
                })
                .map(|(arm_block, pattern, guard)| {
                    Candidate {
                        match_pairs: vec![self.match_pair(discriminant_lvalue.clone(), pattern)],
                        bindings: vec![],
                        guard: guard,
                        arm_block: arm_block,
                    }
                })
                .collect();

        // this will generate code to test discriminant_lvalue and
        // branch to the appropriate arm block
        let var_extent = self.extent_of_innermost_scope().unwrap();
        self.match_candidates(span, var_extent, candidates, block);

        // all the arm blocks will rejoin here
        let end_block = self.cfg.start_new_block();

        for (arm_body, &arm_block) in arm_bodies.into_iter().zip(arm_blocks.iter()) {
            let mut arm_block = arm_block;
            unpack!(arm_block = self.into(destination, arm_block, arm_body));
            self.cfg.terminate(arm_block, Terminator::Goto { target: end_block });
        }

        end_block.unit()
    }

    pub fn expr_into_pattern(&mut self,
                             mut block: BasicBlock,
                             var_extent: H::CodeExtent,          // lifetime of vars
                             irrefutable_pat: PatternRef<H>,
                             initializer: ExprRef<H>)
                             -> BlockAnd<()>
    {
        // optimize the case of `let x = ...`
        let irrefutable_pat = self.hir.mirror(irrefutable_pat);
        match irrefutable_pat.kind {
            PatternKind::Binding { mutability,
                                   name,
                                   mode: BindingMode::ByValue,
                                   var,
                                   ty,
                                   subpattern: None } => {
                let index = self.declare_binding(var_extent, mutability, name,
                                                 var, ty, irrefutable_pat.span);
                let lvalue = Lvalue::Var(index);
                return self.into(&lvalue, block, initializer);
            }
            _ => { }
        }
        let lvalue = unpack!(block = self.as_lvalue(block, initializer));
        self.lvalue_into_pattern(block, var_extent,
                                 PatternRef::Mirror(Box::new(irrefutable_pat)), &lvalue)
    }

    pub fn lvalue_into_pattern(&mut self,
                               mut block: BasicBlock,
                               var_extent: H::CodeExtent,
                               irrefutable_pat: PatternRef<H>,
                               initializer: &Lvalue<H>)
                               -> BlockAnd<()>
    {
        // create a dummy candidate
        let mut candidate = Candidate::<H> {
            match_pairs: vec![self.match_pair(initializer.clone(), irrefutable_pat)],
            bindings: vec![],
            guard: None,
            arm_block: block
        };

        // Simplify the candidate. Since the pattern is irrefutable, this should
        // always convert all match-pairs into bindings.
        unpack!(block = self.simplify_candidate(block, &mut candidate));

        if !candidate.match_pairs.is_empty() {
            self.hir.span_bug(
                candidate.match_pairs[0].pattern.span,
                &format!("match pairs {:?} remaining after simplifying irrefutable pattern",
                         candidate.match_pairs));
        }

        // now apply the bindings, which will also declare the variables
        self.bind_matched_candidate(block, var_extent, candidate.bindings);

        block.unit()
    }

    pub fn declare_uninitialized_variables(&mut self,
                                           var_extent: H::CodeExtent,
                                           pattern: PatternRef<H>)
    {
        let pattern = self.hir.mirror(pattern);
        match pattern.kind {
            PatternKind::Binding { mutability, name, mode: _, var, ty, subpattern } => {
                self.declare_binding(var_extent, mutability, name, var, ty, pattern.span);
                if let Some(subpattern) = subpattern {
                    self.declare_uninitialized_variables(var_extent, subpattern);
                }
            }
            PatternKind::Array { prefix, slice, suffix } |
            PatternKind::Slice { prefix, slice, suffix } => {
                for subpattern in prefix.into_iter().chain(slice).chain(suffix) {
                    self.declare_uninitialized_variables(var_extent, subpattern);
                }
            }
            PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {
            }
            PatternKind::Deref { subpattern } => {
                self.declare_uninitialized_variables(var_extent, subpattern);
            }
            PatternKind::Leaf { subpatterns } |
            PatternKind::Variant { subpatterns, .. } => {
                for subpattern in subpatterns {
                    self.declare_uninitialized_variables(var_extent, subpattern.pattern);
                }
            }
        }
    }
}

#[derive(Clone, Debug)]
struct Candidate<H:Hair> {
    // all of these must be satisfied...
    match_pairs: Vec<MatchPair<H>>,

    // ...these bindings established...
    bindings: Vec<Binding<H>>,

    // ...and the guard must be evaluated...
    guard: Option<ExprRef<H>>,

    // ...and then we branch here.
    arm_block: BasicBlock,
}

#[derive(Clone, Debug)]
struct Binding<H:Hair> {
    span: H::Span,
    source: Lvalue<H>,
    name: H::Name,
    var_id: H::VarId,
    var_ty: H::Ty,
    mutability: Mutability,
    binding_mode: BindingMode<H>,
}

#[derive(Clone, Debug)]
struct MatchPair<H:Hair> {
    // this lvalue...
    lvalue: Lvalue<H>,

    // ... must match this pattern.
    pattern: Pattern<H>,
}

#[derive(Clone, Debug, PartialEq)]
enum TestKind<H:Hair> {
    // test the branches of enum
    Switch { adt_def: H::AdtDef },

    // test for equality
    Eq { value: Literal<H>, ty: H::Ty },

    // test whether the value falls within an inclusive range
    Range { lo: Literal<H>, hi: Literal<H>, ty: H::Ty },

    // test length of the slice is equal to len
    Len { len: usize, op: BinOp },
}

#[derive(Debug)]
struct Test<H:Hair> {
    span: H::Span,
    kind: TestKind<H>,
}

///////////////////////////////////////////////////////////////////////////
// Main matching algorithm

impl<H:Hair> Builder<H> {
    fn match_candidates(&mut self,
                        span: H::Span,
                        var_extent: H::CodeExtent,
                        mut candidates: Vec<Candidate<H>>,
                        mut block: BasicBlock)
    {
        debug!("matched_candidate(span={:?}, var_extent={:?}, block={:?}, candidates={:?})",
               span, var_extent, block, candidates);

        // Start by simplifying candidates. Once this process is
        // complete, all the match pairs which remain require some
        // form of test, whether it be a switch or pattern comparison.
        for candidate in &mut candidates {
            unpack!(block = self.simplify_candidate(block, candidate));
        }

        // The candidates are inversely sorted by priority. Check to
        // see whether the candidates in the front of the queue (and
        // hence back of the vec) have satisfied all their match
        // pairs.
        let fully_matched =
            candidates.iter().rev().take_while(|c| c.match_pairs.is_empty()).count();
        debug!("match_candidates: {:?} candidates fully matched", fully_matched);
        for _ in 0..fully_matched {
            // If so, apply any bindings, test the guard (if any), and
            // branch to the arm.
            let candidate = candidates.pop().unwrap();
            if let Some(b) = self.bind_and_guard_matched_candidate(block, var_extent, candidate) {
                block = b;
            } else {
                // if None is returned, then any remaining candidates
                // are unreachable (at least not through this path).
                return;
            }
        }

        // If there are no candidates that still need testing, we're done.
        // Since all matches are exhaustive, execution should never reach this point.
        if candidates.is_empty() {
            return self.panic(block);
        }

        // otherwise, extract the next match pair and construct tests
        let match_pair = &candidates.last().unwrap().match_pairs[0];
        let test = self.test(match_pair);
        debug!("match_candidates: test={:?} match_pair={:?}", test, match_pair);
        let target_blocks = self.perform_test(block, &match_pair.lvalue, &test);

        for (outcome, mut target_block) in target_blocks.into_iter().enumerate() {
            let applicable_candidates: Vec<Candidate<H>> =
                candidates.iter()
                          .filter_map(|candidate| {
                              unpack!(target_block =
                                      self.candidate_under_assumption(target_block,
                                                                      &match_pair.lvalue,
                                                                      &test.kind,
                                                                      outcome,
                                                                      candidate))
                          })
                          .collect();
            self.match_candidates(span, var_extent, applicable_candidates, target_block);
        }
    }

    /// Initializes each of the bindings from the candidate by
    /// moving/copying/ref'ing the source as appropriate. Tests the
    /// guard, if any, and then branches to the arm. Returns the block
    /// for the case where the guard fails.
    ///
    /// Note: we check earlier that if there is a guard, there cannot
    /// be move bindings.  This isn't really important for the
    /// self-consistency of this fn, but the reason for it should be
    /// clear: after we've done the assignments, if there were move
    /// bindings, further tests would be a use-after-move (which would
    /// in turn be detected by the borrowck code that runs on the
    /// MIR).
    fn bind_and_guard_matched_candidate(&mut self,
                                        mut block: BasicBlock,
                                        var_extent: H::CodeExtent,
                                        candidate: Candidate<H>)
                                        -> Option<BasicBlock> {
        debug!("bind_and_guard_matched_candidate(block={:?}, var_extent={:?}, candidate={:?})",
               block, var_extent, candidate);

        debug_assert!(candidate.match_pairs.is_empty());

        self.bind_matched_candidate(block, var_extent, candidate.bindings);

        if let Some(guard) = candidate.guard {
            // the block to branch to if the guard fails; if there is no
            // guard, this block is simply unreachable
            let cond = unpack!(block = self.as_operand(block, guard));
            let otherwise = self.cfg.start_new_block();
            self.cfg.terminate(block, Terminator::If { cond: cond,
                                                       targets: [candidate.arm_block, otherwise]});
            Some(otherwise)
        } else {
            self.cfg.terminate(block, Terminator::Goto { target: candidate.arm_block });
            None
        }
    }

    fn bind_matched_candidate(&mut self,
                              block: BasicBlock,
                              var_extent: H::CodeExtent,
                              bindings: Vec<Binding<H>>) {
        debug!("bind_matched_candidate(block={:?}, var_extent={:?}, bindings={:?})",
               block, var_extent, bindings);

        // Assign each of the bindings. This may trigger moves out of the candidate.
        for binding in bindings {
            // Create a variable for the `var_id` being bound. In the
            // case where there are multiple patterns for a single
            // arm, it may already exist.
            let var_index = if !self.var_indices.contains_key(&binding.var_id) {
                self.declare_binding(var_extent,
                                     binding.mutability,
                                     binding.name,
                                     binding.var_id,
                                     binding.var_ty,
                                     binding.span)
            } else {
                self.var_indices[&binding.var_id]
            };

            let rvalue = match binding.binding_mode {
                BindingMode::ByValue =>
                    Rvalue::Use(Operand::Consume(binding.source)),
                BindingMode::ByRef(region, borrow_kind) =>
                    Rvalue::Ref(region, borrow_kind, binding.source),
            };

            self.cfg.push_assign(block, binding.span, &Lvalue::Var(var_index), rvalue);
        }
    }

    fn declare_binding(&mut self,
                       var_extent: H::CodeExtent,
                       mutability: Mutability,
                       name: H::Name,
                       var_id: H::VarId,
                       var_ty: H::Ty,
                       span: H::Span)
                       -> u32
    {
        debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, var_extent={:?}, span={:?})",
               var_id, name, var_ty, var_extent, span);

        let index = self.var_decls.len();
        self.var_decls.push(VarDecl::<H> {
            mutability: mutability,
            name: name,
            ty: var_ty.clone(),
        });
        let index = index as u32;
        self.schedule_drop(span, var_extent, DropKind::Deep, &Lvalue::Var(index), var_ty);
        self.var_indices.insert(var_id, index);

        debug!("declare_binding: index={:?}", index);

        index
    }
}

<commit_msg>rather than just passing the block around, track the candidate's index, and track which arms are reached (though in fact we don't make use of this right now -- we might later if we absorb the checking of patterns into MIR, as I would like)<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

//! Code related to match expresions. These are sufficiently complex
//! to warrant their own module and submodules. :) This main module
//! includes the high-level algorithm, the submodules contain the
//! details.

use build::{BlockAnd, Builder};
use repr::*;
use hair::*;

// helper functions, broken out by category:
mod simplify;
mod test;
mod util;

impl<H:Hair> Builder<H> {
    pub fn match_expr(&mut self,
                      destination: &Lvalue<H>,
                      span: H::Span,
                      mut block: BasicBlock,
                      discriminant: ExprRef<H>,
                      arms: Vec<Arm<H>>)
                      -> BlockAnd<()>
    {
        let discriminant_lvalue =
            unpack!(block = self.as_lvalue(block, discriminant));

        let mut arm_blocks = ArmBlocks {
            blocks: arms.iter()
                        .map(|_| self.cfg.start_new_block())
                        .collect(),
        };

        let arm_bodies: Vec<ExprRef<H>> =
            arms.iter()
                .map(|arm| arm.body.clone())
                .collect();

        // assemble a list of candidates: there is one candidate per
        // pattern, which means there may be more than one candidate
        // *per arm*. These candidates are kept sorted such that the
        // highest priority candidate comes last in the list. This the
        // reverse of the order in which candidates are written in the
        // source.
        let candidates: Vec<Candidate<H>> =
            arms.into_iter()
                .enumerate()
                .rev() // highest priority comes last
                .flat_map(|(arm_index, arm)| {
                    let guard = arm.guard;
                    arm.patterns.into_iter()
                                .rev()
                                .map(move |pat| (arm_index, pat, guard.clone()))
                })
                .map(|(arm_index, pattern, guard)| {
                    Candidate {
                        match_pairs: vec![self.match_pair(discriminant_lvalue.clone(), pattern)],
                        bindings: vec![],
                        guard: guard,
                        arm_index: arm_index,
                    }
                })
                .collect();

        // this will generate code to test discriminant_lvalue and
        // branch to the appropriate arm block
        let var_extent = self.extent_of_innermost_scope().unwrap();
        self.match_candidates(span, var_extent, &mut arm_blocks, candidates, block);

        // all the arm blocks will rejoin here
        let end_block = self.cfg.start_new_block();

        for (arm_index, arm_body) in arm_bodies.into_iter().enumerate() {
            let mut arm_block = arm_blocks.blocks[arm_index];
            unpack!(arm_block = self.into(destination, arm_block, arm_body));
            self.cfg.terminate(arm_block, Terminator::Goto { target: end_block });
        }

        end_block.unit()
    }

    pub fn expr_into_pattern(&mut self,
                             mut block: BasicBlock,
                             var_extent: H::CodeExtent,          // lifetime of vars
                             irrefutable_pat: PatternRef<H>,
                             initializer: ExprRef<H>)
                             -> BlockAnd<()>
    {
        // optimize the case of `let x = ...`
        let irrefutable_pat = self.hir.mirror(irrefutable_pat);
        match irrefutable_pat.kind {
            PatternKind::Binding { mutability,
                                   name,
                                   mode: BindingMode::ByValue,
                                   var,
                                   ty,
                                   subpattern: None } => {
                let index = self.declare_binding(var_extent, mutability, name,
                                                 var, ty, irrefutable_pat.span);
                let lvalue = Lvalue::Var(index);
                return self.into(&lvalue, block, initializer);
            }
            _ => { }
        }
        let lvalue = unpack!(block = self.as_lvalue(block, initializer));
        self.lvalue_into_pattern(block, var_extent,
                                 PatternRef::Mirror(Box::new(irrefutable_pat)), &lvalue)
    }

    pub fn lvalue_into_pattern(&mut self,
                               mut block: BasicBlock,
                               var_extent: H::CodeExtent,
                               irrefutable_pat: PatternRef<H>,
                               initializer: &Lvalue<H>)
                               -> BlockAnd<()>
    {
        // create a dummy candidate
        let mut candidate = Candidate::<H> {
            match_pairs: vec![self.match_pair(initializer.clone(), irrefutable_pat)],
            bindings: vec![],
            guard: None,
            arm_index: 0, // since we don't call `match_candidates`, this field is unused
        };

        // Simplify the candidate. Since the pattern is irrefutable, this should
        // always convert all match-pairs into bindings.
        unpack!(block = self.simplify_candidate(block, &mut candidate));

        if !candidate.match_pairs.is_empty() {
            self.hir.span_bug(
                candidate.match_pairs[0].pattern.span,
                &format!("match pairs {:?} remaining after simplifying irrefutable pattern",
                         candidate.match_pairs));
        }

        // now apply the bindings, which will also declare the variables
        self.bind_matched_candidate(block, var_extent, candidate.bindings);

        block.unit()
    }

    pub fn declare_uninitialized_variables(&mut self,
                                           var_extent: H::CodeExtent,
                                           pattern: PatternRef<H>)
    {
        let pattern = self.hir.mirror(pattern);
        match pattern.kind {
            PatternKind::Binding { mutability, name, mode: _, var, ty, subpattern } => {
                self.declare_binding(var_extent, mutability, name, var, ty, pattern.span);
                if let Some(subpattern) = subpattern {
                    self.declare_uninitialized_variables(var_extent, subpattern);
                }
            }
            PatternKind::Array { prefix, slice, suffix } |
            PatternKind::Slice { prefix, slice, suffix } => {
                for subpattern in prefix.into_iter().chain(slice).chain(suffix) {
                    self.declare_uninitialized_variables(var_extent, subpattern);
                }
            }
            PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {
            }
            PatternKind::Deref { subpattern } => {
                self.declare_uninitialized_variables(var_extent, subpattern);
            }
            PatternKind::Leaf { subpatterns } |
            PatternKind::Variant { subpatterns, .. } => {
                for subpattern in subpatterns {
                    self.declare_uninitialized_variables(var_extent, subpattern.pattern);
                }
            }
        }
    }
}

/// List of blocks for each arm (and potentially other metadata in the
/// future).
struct ArmBlocks {
    blocks: Vec<BasicBlock>,
}

#[derive(Clone, Debug)]
struct Candidate<H:Hair> {
    // all of these must be satisfied...
    match_pairs: Vec<MatchPair<H>>,

    // ...these bindings established...
    bindings: Vec<Binding<H>>,

    // ...and the guard must be evaluated...
    guard: Option<ExprRef<H>>,

    // ...and then we branch to arm with this index.
    arm_index: usize,
}

#[derive(Clone, Debug)]
struct Binding<H:Hair> {
    span: H::Span,
    source: Lvalue<H>,
    name: H::Name,
    var_id: H::VarId,
    var_ty: H::Ty,
    mutability: Mutability,
    binding_mode: BindingMode<H>,
}

#[derive(Clone, Debug)]
struct MatchPair<H:Hair> {
    // this lvalue...
    lvalue: Lvalue<H>,

    // ... must match this pattern.
    pattern: Pattern<H>,
}

#[derive(Clone, Debug, PartialEq)]
enum TestKind<H:Hair> {
    // test the branches of enum
    Switch { adt_def: H::AdtDef },

    // test for equality
    Eq { value: Literal<H>, ty: H::Ty },

    // test whether the value falls within an inclusive range
    Range { lo: Literal<H>, hi: Literal<H>, ty: H::Ty },

    // test length of the slice is equal to len
    Len { len: usize, op: BinOp },
}

#[derive(Debug)]
struct Test<H:Hair> {
    span: H::Span,
    kind: TestKind<H>,
}

///////////////////////////////////////////////////////////////////////////
// Main matching algorithm

impl<H:Hair> Builder<H> {
    fn match_candidates(&mut self,
                        span: H::Span,
                        var_extent: H::CodeExtent,
                        arm_blocks: &mut ArmBlocks,
                        mut candidates: Vec<Candidate<H>>,
                        mut block: BasicBlock)
    {
        debug!("matched_candidate(span={:?}, var_extent={:?}, block={:?}, candidates={:?})",
               span, var_extent, block, candidates);

        // Start by simplifying candidates. Once this process is
        // complete, all the match pairs which remain require some
        // form of test, whether it be a switch or pattern comparison.
        for candidate in &mut candidates {
            unpack!(block = self.simplify_candidate(block, candidate));
        }

        // The candidates are inversely sorted by priority. Check to
        // see whether the candidates in the front of the queue (and
        // hence back of the vec) have satisfied all their match
        // pairs.
        let fully_matched =
            candidates.iter().rev().take_while(|c| c.match_pairs.is_empty()).count();
        debug!("match_candidates: {:?} candidates fully matched", fully_matched);
        for _ in 0..fully_matched {
            // If so, apply any bindings, test the guard (if any), and
            // branch to the arm.
            let candidate = candidates.pop().unwrap();
            if let Some(b) = self.bind_and_guard_matched_candidate(block, var_extent,
                                                                   arm_blocks, candidate) {
                block = b;
            } else {
                // if None is returned, then any remaining candidates
                // are unreachable (at least not through this path).
                return;
            }
        }

        // If there are no candidates that still need testing, we're done.
        // Since all matches are exhaustive, execution should never reach this point.
        if candidates.is_empty() {
            return self.panic(block);
        }

        // otherwise, extract the next match pair and construct tests
        let match_pair = &candidates.last().unwrap().match_pairs[0];
        let test = self.test(match_pair);
        debug!("match_candidates: test={:?} match_pair={:?}", test, match_pair);
        let target_blocks = self.perform_test(block, &match_pair.lvalue, &test);

        for (outcome, mut target_block) in target_blocks.into_iter().enumerate() {
            let applicable_candidates: Vec<Candidate<H>> =
                candidates.iter()
                          .filter_map(|candidate| {
                              unpack!(target_block =
                                      self.candidate_under_assumption(target_block,
                                                                      &match_pair.lvalue,
                                                                      &test.kind,
                                                                      outcome,
                                                                      candidate))
                          })
                          .collect();
            self.match_candidates(span, var_extent, arm_blocks, applicable_candidates, target_block);
        }
    }

    /// Initializes each of the bindings from the candidate by
    /// moving/copying/ref'ing the source as appropriate. Tests the
    /// guard, if any, and then branches to the arm. Returns the block
    /// for the case where the guard fails.
    ///
    /// Note: we check earlier that if there is a guard, there cannot
    /// be move bindings.  This isn't really important for the
    /// self-consistency of this fn, but the reason for it should be
    /// clear: after we've done the assignments, if there were move
    /// bindings, further tests would be a use-after-move (which would
    /// in turn be detected by the borrowck code that runs on the
    /// MIR).
    fn bind_and_guard_matched_candidate(&mut self,
                                        mut block: BasicBlock,
                                        var_extent: H::CodeExtent,
                                        arm_blocks: &mut ArmBlocks,
                                        candidate: Candidate<H>)
                                        -> Option<BasicBlock> {
        debug!("bind_and_guard_matched_candidate(block={:?}, var_extent={:?}, candidate={:?})",
               block, var_extent, candidate);

        debug_assert!(candidate.match_pairs.is_empty());

        self.bind_matched_candidate(block, var_extent, candidate.bindings);

        let arm_block = arm_blocks.blocks[candidate.arm_index];

        if let Some(guard) = candidate.guard {
            // the block to branch to if the guard fails; if there is no
            // guard, this block is simply unreachable
            let cond = unpack!(block = self.as_operand(block, guard));
            let otherwise = self.cfg.start_new_block();
            self.cfg.terminate(block, Terminator::If { cond: cond,
                                                       targets: [arm_block, otherwise]});
            Some(otherwise)
        } else {
            self.cfg.terminate(block, Terminator::Goto { target: arm_block });
            None
        }
    }

    fn bind_matched_candidate(&mut self,
                              block: BasicBlock,
                              var_extent: H::CodeExtent,
                              bindings: Vec<Binding<H>>) {
        debug!("bind_matched_candidate(block={:?}, var_extent={:?}, bindings={:?})",
               block, var_extent, bindings);

        // Assign each of the bindings. This may trigger moves out of the candidate.
        for binding in bindings {
            // Create a variable for the `var_id` being bound. In the
            // case where there are multiple patterns for a single
            // arm, it may already exist.
            let var_index = if !self.var_indices.contains_key(&binding.var_id) {
                self.declare_binding(var_extent,
                                     binding.mutability,
                                     binding.name,
                                     binding.var_id,
                                     binding.var_ty,
                                     binding.span)
            } else {
                self.var_indices[&binding.var_id]
            };

            let rvalue = match binding.binding_mode {
                BindingMode::ByValue =>
                    Rvalue::Use(Operand::Consume(binding.source)),
                BindingMode::ByRef(region, borrow_kind) =>
                    Rvalue::Ref(region, borrow_kind, binding.source),
            };

            self.cfg.push_assign(block, binding.span, &Lvalue::Var(var_index), rvalue);
        }
    }

    fn declare_binding(&mut self,
                       var_extent: H::CodeExtent,
                       mutability: Mutability,
                       name: H::Name,
                       var_id: H::VarId,
                       var_ty: H::Ty,
                       span: H::Span)
                       -> u32
    {
        debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, var_extent={:?}, span={:?})",
               var_id, name, var_ty, var_extent, span);

        let index = self.var_decls.len();
        self.var_decls.push(VarDecl::<H> {
            mutability: mutability,
            name: name,
            ty: var_ty.clone(),
        });
        let index = index as u32;
        self.schedule_drop(span, var_extent, DropKind::Deep, &Lvalue::Var(index), var_ty);
        self.var_indices.insert(var_id, index);

        debug!("declare_binding: index={:?}", index);

        index
    }
}

<|endoftext|>


<commit_before>use {Future, Poll, Async};

/// A future which "fuse"s a future once it's been resolved.
///
/// Normally futures can behave unpredictable once they're used after a future
/// has been resolved, but `Fuse` is always defined to return `Async::NotReady`
/// from `poll` after it has succeeded, and after it has succeeded all future
/// calls to `schedule` will be ignored.
#[must_use = "futures do nothing unless polled"]
pub struct Fuse<A: Future> {
    future: Option<A>,
}

pub fn new<A: Future>(f: A) -> Fuse<A> {
    Fuse {
        future: Some(f),
    }
}

impl<A: Future> Future for Fuse<A> {
    type Item = A::Item;
    type Error = A::Error;

    fn poll(&mut self) -> Poll<A::Item, A::Error> {
        let res = self.future.as_mut().map(|f| f.poll());
        match res.unwrap_or(Ok(Async::NotReady)) {
            res @ Ok(Async::Ready(_)) |
            res @ Err(_) => {
                self.future = None;
                res
            }
            Ok(Async::NotReady) => Ok(Async::NotReady)
        }
    }
}
<commit_msg>Tweak `Fuse` docs: remove reference to `schedule`<commit_after>use {Future, Poll, Async};

/// A future which "fuses" a future once it's been resolved.
///
/// Normally futures can behave unpredictable once they're used after a future
/// has been resolved, but `Fuse` is always defined to return `Async::NotReady`
/// from `poll` after it has resolved successfully or returned an error.
///
/// This is created by the `Future::fuse` method.
#[must_use = "futures do nothing unless polled"]
pub struct Fuse<A: Future> {
    future: Option<A>,
}

pub fn new<A: Future>(f: A) -> Fuse<A> {
    Fuse {
        future: Some(f),
    }
}

impl<A: Future> Future for Fuse<A> {
    type Item = A::Item;
    type Error = A::Error;

    fn poll(&mut self) -> Poll<A::Item, A::Error> {
        let res = self.future.as_mut().map(|f| f.poll());
        match res.unwrap_or(Ok(Async::NotReady)) {
            res @ Ok(Async::Ready(_)) |
            res @ Err(_) => {
                self.future = None;
                res
            }
            Ok(Async::NotReady) => Ok(Async::NotReady)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>draft alpha-conversion<commit_after><|endoftext|>


<commit_before><commit_msg>blank message<commit_after><|endoftext|>


<commit_before><commit_msg>More VIP mapping<commit_after><|endoftext|>


<commit_before><commit_msg>Add regression test for #20797. Fixes #20797.<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

// Regression test for #20797.

use std::default::Default;
use std::io::IoResult;
use std::io::fs;
use std::io::fs::PathExtensions;

/// A strategy for acquiring more subpaths to walk.
pub trait Strategy {
  type P: PathExtensions;
  /// Get additional subpaths from a given path.
  fn get_more(&self, item: &Self::P) -> IoResult<Vec<Self::P>>;
  /// Determine whether a path should be walked further.
  /// This is run against each item from `get_more()`.
  fn prune(&self, p: &Self::P) -> bool;
}

/// The basic fully-recursive strategy. Nothing is pruned.
#[derive(Copy, Default)]
pub struct Recursive;

impl Strategy for Recursive {
  type P = Path;
  fn get_more(&self, p: &Path) -> IoResult<Vec<Path>> { fs::readdir(p) }

  fn prune(&self, _: &Path) -> bool { false }
}

/// A directory walker of `P` using strategy `S`.
pub struct Subpaths<S: Strategy> {
    stack: Vec<S::P>,
    strategy: S,
}

impl<S: Strategy> Subpaths<S> {
  /// Create a directory walker with a root path and strategy.
  pub fn new(p: &S::P, strategy: S) -> IoResult<Subpaths<S>> {
    let stack = try!(strategy.get_more(p));
    Ok(Subpaths { stack: stack, strategy: strategy })
  }
}

impl<S: Default + Strategy> Subpaths<S> {
  /// Create a directory walker with a root path and a default strategy.
  pub fn walk(p: &S::P) -> IoResult<Subpaths<S>> {
      Subpaths::new(p, Default::default())
  }
}

impl<S: Default + Strategy> Default for Subpaths<S> {
  fn default() -> Subpaths<S> {
    Subpaths { stack: Vec::new(), strategy: Default::default() }
  }
}

impl<S: Strategy> Iterator for Subpaths<S> {
  type Item = S::P;
  fn next (&mut self) -> Option<S::P> {
    let mut opt_path = self.stack.pop();
    while opt_path.is_some() && self.strategy.prune(opt_path.as_ref().unwrap()) {
      opt_path = self.stack.pop();
    }
    match opt_path {
      Some(path) => {
        if PathExtensions::is_dir(&path) {
          let result = self.strategy.get_more(&path);
          match result {
            Ok(dirs) => { self.stack.extend(dirs.into_iter()); },
            Err(..) => { }
          }
        }
        Some(path)
      }
      None => None,
    }
  }
}

fn main() {
  let mut walker: Subpaths<Recursive> = Subpaths::walk(&Path::new("/home")).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Add run-pass test<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ffi::OsString;

fn main() {
    let os_str = OsString::from("Hello Rust!");

    assert_eq!(os_str, "Hello Rust!");
    assert_eq!("Hello Rust!", os_str);
}
<|endoftext|>


<commit_before><commit_msg>auto merge of #8956 : thestinger/rust/test, r=huonw<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-fast: check-fast screws up repr paths

use std::unstable::intrinsics::get_tydesc;

struct Foo<T> {
    x: T
}

fn main() {
    unsafe {
        assert_eq!((*get_tydesc::<int>()).name, "int");
        assert_eq!((*get_tydesc::<~[int]>()).name, "~[int]");
        assert_eq!((*get_tydesc::<Foo<uint>>()).name, "Foo<uint>");
    }
}
<|endoftext|>