<commit_before><commit_msg>Add test to ensure edge-triggering<commit_after>/// Ensure all sockets operate on edge trigger mode.

extern crate amy;

use std::net::{TcpListener, TcpStream};
use std::thread;
use std::str;
use std::io::{Read, Write};

use amy::{
    Poller,
    Event,
};

const IP: &'static str = "127.0.0.1:10008";

/// This test ensures that only one write event is received, even if no data is written. On a level
/// triggered system, write events would come on every poll.
#[test]
fn edge_trigger() {

    // Spawn a listening thread and accept one connection
    thread::spawn(|| {
        let listener = TcpListener::bind(IP).unwrap();
        let (mut sock, _) = listener.accept().unwrap();
        // When the test completes, the client will send a "stop" message to shutdown the server.
        let mut buf = String::new();
        sock.read_to_string(&mut buf).unwrap();
    });

    // Setup a client socket in non-blocking mode
    // Loop until we connect because the listener needs to start first
    let mut sock;
    loop {
      if let Ok(s) = TcpStream::connect(IP) {
          sock = s;
          break;
      }
    }
    sock.set_nonblocking(true).unwrap();

    // Create the poller and registrar
    let mut poller = Poller::new().unwrap();
    let registrar = poller.get_registrar();

    // The socket should become writable once it's connected
    let id = registrar.register(&sock, Event::Write).unwrap();
    let notifications = poller.wait(250).unwrap();
    assert_eq!(1, notifications.len());
    assert_eq!(id, notifications[0].id);
    assert_eq!(Event::Write, notifications[0].event);

    // Poll as second time. There should be no notification, since the socket is edge triggered.
    let notifications = poller.wait(250).unwrap();
    assert_eq!(0, notifications.len());

    // Tell the listening thread to stop itself
    sock.write("stop".as_bytes()).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Ensure we have registered metrics.<commit_after><|endoftext|>


<commit_before><commit_msg>const param macro test<commit_after>// run-pass
// revisions: full min

#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]

macro_rules! bar {
    ($($t:tt)*) => { impl<const N: usize> $($t)* };
}

macro_rules! baz {
    ($t:tt) => { fn test<const M: usize>(&self) -> usize { $t } };
}

struct Foo<const N: usize>;

bar!(Foo<N> { baz!{ M } });

fn main() {
    assert_eq!(Foo::<7>.test::<3>(), 3);
}
<|endoftext|>


<commit_before><commit_msg>part 7 done..<commit_after><|endoftext|>


<commit_before><commit_msg>Test case for issue #718.<commit_after>//xfail-stage0
//xfail-stage1
//xfail-stage2

fn main() {

    obj a() {
        fn foo() -> int {
            ret 2;
        }
    }

    auto my_a = a();

    auto my_b = obj() {
        with my_a
    };

    assert (my_b.foo() == 2);

    auto my_c = obj() {
        with my_b
    };

    assert (my_c.foo() == 2);
}

<|endoftext|>


<commit_before><commit_msg>Fix: Make most fields optional<commit_after><|endoftext|>


<commit_before><commit_msg>audio.moveToAlbum method<commit_after><|endoftext|>


<commit_before><commit_msg>Fix a brown-paper-bag bug.<commit_after><|endoftext|>


<commit_before><commit_msg>rustup<commit_after><|endoftext|>


<commit_before><commit_msg>video.getAlbumsByVideo method<commit_after><|endoftext|>


<commit_before>// Copyright 2012 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::mem::size_of;

// The two enums that follow are designed so that bugs trigger layout optimization.
// Specifically, if either of the following reprs used here is not detected by the compiler,
// then the sizes will be wrong.

#[repr(C, u8)]
enum E1 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

#[repr(u8, C)]
enum E2 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

// From pr 37429

#[repr(C,packed)]
pub struct p0f_api_query {
    pub magic: u32,
    pub addr_type: u8,
    pub addr: [u8; 16],
}

pub fn main() {
    assert_eq!(size_of::<E1>(), 6);
    assert_eq!(size_of::<E2>(), 6);
    assert_eq!(size_of::<p0f_api_query>(), 21);
}
<commit_msg>Fix and improve test for enum repr sizes<commit_after>// Copyright 2012 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::mem::{size_of, align_of};
use std::os::raw::c_int;

// The two enums that follow are designed so that bugs trigger layout optimization.
// Specifically, if either of the following reprs used here is not detected by the compiler,
// then the sizes will be wrong.

#[repr(C, u8)]
enum E1 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

#[repr(u8, C)]
enum E2 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

// Check that repr(int) and repr(C) are in fact different from the above

#[repr(u8)]
enum E3 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

#[repr(u16)]
enum E4 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

#[repr(u32)]
enum E5 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

#[repr(u64)]
enum E6 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

#[repr(C)]
enum E7 {
    A(u8, u16, u8),
    B(u8, u16, u8)
}

// From pr 37429

#[repr(C,packed)]
pub struct p0f_api_query {
    pub magic: u32,
    pub addr_type: u8,
    pub addr: [u8; 16],
}

pub fn main() {
    assert_eq!(size_of::<E1>(), 8);
    assert_eq!(size_of::<E2>(), 8);
    assert_eq!(size_of::<E3>(), 6);
    assert_eq!(size_of::<E4>(), 8);
    assert_eq!(size_of::<E5>(), align_size(10, align_of::<u32>()));
    assert_eq!(size_of::<E6>(), align_size(14, align_of::<u64>()));
    assert_eq!(size_of::<E7>(), align_size(6 + size_of::<c_int>(), align_of::<c_int>()));
    assert_eq!(size_of::<p0f_api_query>(), 21);
}

fn align_size(size: usize, align: usize) -> usize {
    if size % align != 0 {
        size + (align - (size % align))
    } else {
        size
    }
}
<|endoftext|>


<commit_before>use collections::string::*;
use collections::vec::{IntoIter, Vec};

use core::ptr;

use syscall::call::*;

/// File seek
pub enum Seek {
    /// The start point
    Start(usize),
    /// The current point
    Current(isize),
    /// The end point
    End(isize),
}

/// A Unix-style file
pub struct File {
    /// The path to the file
    path: String,
    /// The id for the file
    fd: usize,
}

impl File {
    /// Open a new file using a path
    // TODO: Return Option<File>
    pub fn open(path: &str) -> Self {
        unsafe {
            let c_str = sys_alloc(path.len() + 1) as *mut u8;
            if path.len() > 0 {
                ptr::copy(path.as_ptr(), c_str, path.len());
            }
            ptr::write(c_str.offset(path.len() as isize), 0);

            let ret = File {
                path: path.to_string(),
                fd: sys_open(c_str, 0, 0),
            };

            sys_unalloc(c_str as usize);

            ret
        }
    }

    /// Return the url to the file
    pub fn url(&self) -> String {
        //TODO
        self.path.clone()
    }

    /// Write to the file
    // TODO: Move this to a write trait
    pub fn write(&mut self, buf: &[u8]) -> Option<usize> {
        unsafe {
            let count = sys_write(self.fd, buf.as_ptr(), buf.len());
            if count == 0xFFFFFFFF {
                Option::None
            } else {
                Option::Some(count)
            }
        }
    }

    /// Seek a given position
    pub fn seek(&mut self, pos: Seek) -> Option<usize> {
        let (whence, offset) = match pos {
            Seek::Start(offset) => (0, offset as isize),
            Seek::Current(offset) => (1, offset),
            Seek::End(offset) => (2, offset),
        };

        let position = unsafe { sys_lseek(self.fd, offset, whence) };
        if position == 0xFFFFFFFF {
            Option::None
        } else {
            Option::Some(position)
        }
    }

    /// Flush the io
    pub fn sync(&mut self) -> bool {
        unsafe { sys_fsync(self.fd) == 0 }
    }
}

pub trait Read {

    /// Read a file to a buffer
    fn read(&mut self, buf: &mut [u8]) -> Option<usize>;

    /// Read the file to the end
    fn read_to_end(&mut self, vec: &mut Vec<u8>) -> Option<usize> {
        let mut read = 0;
        loop {
            let mut bytes = [0; 1024];
            match self.read(&mut bytes) {
                Option::Some(0) => return Option::Some(read),
                Option::None => return Option::None,
                Option::Some(count) => {
                    for i in 0..count {
                        vec.push(bytes[i]);
                    }
                    read += count;
                }
            }
        }
    }
    /// Return an iterator of the bytes
    fn bytes(&mut self) -> IntoIter<u8> {
        // TODO: This is only a temporary implementation. Make this read one byte at a time.
        let mut buf = Vec::new();
        self.read_to_end(&mut buf);

        buf.into_iter()
    }
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        unsafe {
            let count = sys_read(self.fd, buf.as_mut_ptr(), buf.len());
            if count == 0xFFFFFFFF {
                Option::None
            } else {
                Option::Some(count)
            }
        }
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe {
            sys_close(self.fd);
        }
    }
}
<commit_msg>Add read trait<commit_after>use collections::string::*;
use collections::vec::{IntoIter, Vec};

use core::ptr;

use syscall::call::*;

/// File seek
pub enum Seek {
    /// The start point
    Start(usize),
    /// The current point
    Current(isize),
    /// The end point
    End(isize),
}

/// A Unix-style file
pub struct File {
    /// The path to the file
    path: String,
    /// The id for the file
    fd: usize,
}

impl File {
    /// Open a new file using a path
    // TODO: Return Option<File>
    pub fn open(path: &str) -> Self {
        unsafe {
            let c_str = sys_alloc(path.len() + 1) as *mut u8;
            if path.len() > 0 {
                ptr::copy(path.as_ptr(), c_str, path.len());
            }
            ptr::write(c_str.offset(path.len() as isize), 0);

            let ret = File {
                path: path.to_string(),
                fd: sys_open(c_str, 0, 0),
            };

            sys_unalloc(c_str as usize);

            ret
        }
    }

    /// Return the url to the file
    pub fn url(&self) -> String {
        //TODO
        self.path.clone()
    }

    /// Seek a given position
    pub fn seek(&mut self, pos: Seek) -> Option<usize> {
        let (whence, offset) = match pos {
            Seek::Start(offset) => (0, offset as isize),
            Seek::Current(offset) => (1, offset),
            Seek::End(offset) => (2, offset),
        };

        let position = unsafe { sys_lseek(self.fd, offset, whence) };
        if position == 0xFFFFFFFF {
            Option::None
        } else {
            Option::Some(position)
        }
    }

    /// Flush the io
    pub fn sync(&mut self) -> bool {
        unsafe { sys_fsync(self.fd) == 0 }
    }
}

/// Types you can read
pub trait Read {

    /// Read a file to a buffer
    fn read(&mut self, buf: &mut [u8]) -> Option<usize>;

    /// Read the file to the end
    fn read_to_end(&mut self, vec: &mut Vec<u8>) -> Option<usize> {
        let mut read = 0;
        loop {
            let mut bytes = [0; 1024];
            match self.read(&mut bytes) {
                Option::Some(0) => return Option::Some(read),
                Option::None => return Option::None,
                Option::Some(count) => {
                    for i in 0..count {
                        vec.push(bytes[i]);
                    }
                    read += count;
                }
            }
        }
    }
    /// Return an iterator of the bytes
    fn bytes(&mut self) -> IntoIter<u8> {
        // TODO: This is only a temporary implementation. Make this read one byte at a time.
        let mut buf = Vec::new();
        self.read_to_end(&mut buf);

        buf.into_iter()
    }
}

/// Types you can write
pub trait Write {
    /// Write to the file
    fn write(&mut self, buf: &[u8]) -> Option<usize>;
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        unsafe {
            let count = sys_read(self.fd, buf.as_mut_ptr(), buf.len());
            if count == 0xFFFFFFFF {
                Option::None
            } else {
                Option::Some(count)
            }
        }
    }
}

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        unsafe {
            let count = sys_write(self.fd, buf.as_ptr(), buf.len());
            if count == 0xFFFFFFFF {
                Option::None
            } else {
                Option::Some(count)
            }
        }
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe {
            sys_close(self.fd);
        }
    }
}
<|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.

use target::Target;

pub fn target() -> Target {
    let mut base = super::windows_msvc_base::opts();
    base.cpu = "i686".to_string();

    Target {
        llvm_target: "i686-pc-windows-msvc".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        arch: "x86".to_string(),
        target_os: "windows".to_string(),
        target_env: "msvc".to_string(),
        options: base,
    }
}
<commit_msg>Rollup merge of #27647 - rust-lang:issue-27646, r=alexcrichton<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.

use target::Target;

pub fn target() -> Target {
    let mut base = super::windows_msvc_base::opts();
    base.cpu = "pentium4".to_string();

    Target {
        llvm_target: "i686-pc-windows-msvc".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        arch: "x86".to_string(),
        target_os: "windows".to_string(),
        target_env: "msvc".to_string(),
        options: base,
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashSet;
use std::{cmp, ffi, fmt, mem, str};
use gl;
use gfx_core::Capabilities;
use gfx_core::shade;

/// A version number for a specific component of an OpenGL implementation
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Version {
    pub major: u32,
    pub minor: u32,
    pub revision: Option<u32>,
    pub vendor_info: &'static str,
}

// FIXME https://github.com/rust-lang/rust/issues/18738
// derive

impl cmp::Ord for Version {
    #[inline]
    fn cmp(&self, other: &Version) -> cmp::Ordering {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}
impl cmp::PartialOrd for Version {
    #[inline]
    fn partial_cmp(&self, other: &Version) -> Option<cmp::Ordering> {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .partial_cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}

impl Version {
    /// Create a new OpenGL version number
    pub fn new(major: u32, minor: u32, revision: Option<u32>,
               vendor_info: &'static str) -> Version {
        Version {
            major: major,
            minor: minor,
            revision: revision,
            vendor_info: vendor_info,
        }
    }

    /// According to the OpenGL specification, the version information is
    /// expected to follow the following syntax:
    ///
    /// ~~~bnf
    /// <major>       ::= <number>
    /// <minor>       ::= <number>
    /// <revision>    ::= <number>
    /// <vendor-info> ::= <string>
    /// <release>     ::= <major> "." <minor> ["." <release>]
    /// <version>     ::= <release> [" " <vendor-info>]
    /// ~~~
    ///
    /// Note that this function is intentionally lenient in regards to parsing,
    /// and will try to recover at least the first two version numbers without
    /// resulting in an `Err`.
    pub fn parse(src: &'static str) -> Result<Version, &'static str> {
        let (version, vendor_info) = match src.find(' ') {
            Some(i) => (&src[..i], &src[(i + 1)..]),
            None => (src, ""),
        };

        // TODO: make this even more lenient so that we can also accept
        // `<major> "." <minor> [<???>]`
        let mut it = version.split('.');
        let major = it.next().and_then(|s| s.parse().ok());
        let minor = it.next().and_then(|s| s.parse().ok());
        let revision = it.next().and_then(|s| s.parse().ok());

        match (major, minor, revision) {
            (Some(major), Some(minor), revision) => Ok(Version {
                major: major,
                minor: minor,
                revision: revision,
                vendor_info: vendor_info,
            }),
            (_, _, _) => Err(src),
        }
    }
}

impl fmt::Debug for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match (self.major, self.minor, self.revision, self.vendor_info) {
            (major, minor, Some(revision), "") =>
                write!(f, "{}.{}.{}", major, minor, revision),
            (major, minor, None, "") =>
                write!(f, "{}.{}", major, minor),
            (major, minor, Some(revision), vendor_info) =>
                write!(f, "{}.{}.{}, {}", major, minor, revision, vendor_info),
            (major, minor, None, vendor_info) =>
                write!(f, "{}.{}, {}", major, minor, vendor_info),
        }
    }
}

const EMPTY_STRING: &'static str = "";

/// Get a statically allocated string from the implementation using
/// `glGetString`. Fails if it `GLenum` cannot be handled by the
/// implementation's `gl.GetString` function.
fn get_string(gl: &gl::Gl, name: gl::types::GLenum) -> &'static str {
    let ptr = unsafe { gl.GetString(name) } as *const i8;
    if !ptr.is_null() {
        // This should be safe to mark as statically allocated because
        // GlGetString only returns static strings.
        unsafe { c_str_as_static_str(ptr) }
    } else {
        error!("Invalid GLenum passed to `get_string`: {:x}", name);
        EMPTY_STRING
    }
}

fn get_usize(gl: &gl::Gl, name: gl::types::GLenum) -> usize {
    let mut value = 0 as gl::types::GLint;
    unsafe { gl.GetIntegerv(name, &mut value) };
    value as usize
}

unsafe fn c_str_as_static_str(c_str: *const i8) -> &'static str {
    mem::transmute(str::from_utf8(ffi::CStr::from_ptr(c_str).to_bytes()).unwrap())
}

/// A unique platform identifier that does not change between releases
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct PlatformName {
    /// The company responsible for the OpenGL implementation
    pub vendor: &'static str,
    /// The name of the renderer
    pub renderer: &'static str,
}

impl PlatformName {
    fn get(gl: &gl::Gl) -> PlatformName {
        PlatformName {
            vendor: get_string(gl, gl::VENDOR),
            renderer: get_string(gl, gl::RENDERER),
        }
    }
}

/// OpenGL implementation information
#[derive(Debug)]
pub struct Info {
    /// The platform identifier
    pub platform_name: PlatformName,
    /// The OpenGL API vesion number
    pub version: Version,
    /// The GLSL vesion number
    pub shading_language: Version,
    /// The extensions supported by the implementation
    pub extensions: HashSet<&'static str>,
}

impl Info {
    fn get(gl: &gl::Gl) -> Info {
        let platform_name = PlatformName::get(gl);
        let version = Version::parse(get_string(gl, gl::VERSION)).unwrap();
        let shading_language = Version::parse(get_string(gl, gl::SHADING_LANGUAGE_VERSION)).unwrap();
        let extensions = if version >= Version::new(3, 0, None, "") {
            let num_exts = get_usize(gl, gl::NUM_EXTENSIONS) as gl::types::GLuint;
            (0..num_exts)
                .map(|i| unsafe { c_str_as_static_str(gl.GetStringi(gl::EXTENSIONS, i) as *const i8) })
                .collect()
        } else {
            // Fallback
            get_string(gl, gl::EXTENSIONS).split(' ').collect()
        };
        Info {
            platform_name: platform_name,
            version: version,
            shading_language: shading_language,
            extensions: extensions,
        }
    }

    pub fn is_version_supported(&self, major: u32, minor: u32) -> bool {
        self.version >= Version::new(major, minor, None, "")
    }

    /// Returns `true` if the implementation supports the extension
    pub fn is_extension_supported(&self, s: &'static str) -> bool {
        self.extensions.contains(&s)
    }

    pub fn is_version_or_extension_supported(&self, major: u32, minor: u32, ext: &'static str) -> bool {
        self.is_version_supported(major, minor) || self.is_extension_supported(ext)
    }
}

fn to_shader_model(v: &Version) -> shade::ShaderModel {
    use gfx_core::shade::ShaderModel;
    match v {
        v if *v < Version::new(1, 20, None, "") => ShaderModel::Unsupported,
        v if *v < Version::new(1, 50, None, "") => ShaderModel::Version30,
        v if *v < Version::new(3,  0, None, "") => ShaderModel::Version40,
        v if *v < Version::new(4, 30, None, "") => ShaderModel::Version41,
        _                                       => ShaderModel::Version50,
    }
}

/// Load the information pertaining to the driver and the corresponding device
/// capabilities.
pub fn get(gl: &gl::Gl) -> (Info, Capabilities) {
    let info = Info::get(gl);
    let caps = Capabilities {
        shader_model:                   to_shader_model(&info.shading_language),

        max_vertex_count:               get_usize(gl, gl::MAX_ELEMENTS_VERTICES),
        max_index_count:                get_usize(gl, gl::MAX_ELEMENTS_INDICES),
        max_draw_buffers:               get_usize(gl, gl::MAX_DRAW_BUFFERS),
        max_texture_size:               get_usize(gl, gl::MAX_TEXTURE_SIZE),
        max_vertex_attributes:          get_usize(gl, gl::MAX_VERTEX_ATTRIBS),

        buffer_role_change_allowed:     true, //TODO

        array_buffer_supported:         info.is_version_or_extension_supported(3, 0, "GL_ARB_vertex_array_object"),
        fragment_output_supported:      info.is_version_or_extension_supported(3, 0, "GL_EXT_gpu_shader4"),
        immutable_storage_supported:    info.is_version_or_extension_supported(4, 2, "GL_ARB_texture_storage"),
        instance_base_supported:        info.is_version_or_extension_supported(4, 2, "GL_ARB_base_instance"),
        instance_call_supported:        info.is_version_or_extension_supported(3, 1, "GL_ARB_draw_instanced"),
        instance_rate_supported:        info.is_version_or_extension_supported(3, 3, "GL_ARB_instanced_arrays"),
        render_targets_supported:       info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object"),
        srgb_color_supported:           info.is_version_or_extension_supported(3, 2, "GL_ARB_framebuffer_sRGB"),
        sampler_objects_supported:      info.is_version_or_extension_supported(3, 3, "GL_ARB_sampler_objects"),
        uniform_block_supported:        info.is_version_or_extension_supported(3, 0, "GL_ARB_uniform_buffer_object"),
        vertex_base_supported:          info.is_version_or_extension_supported(3, 2, "GL_ARB_draw_elements_base_vertex"),
        separate_blending_slots_supported: info.is_version_or_extension_supported(4, 0, "GL_ARB_draw_buffers_blend"),
    };
    (info, caps)
}

#[cfg(test)]
mod tests {
    use super::Version;
    use super::to_shader_model;

    #[test]
    fn test_version_parse() {
        assert_eq!(Version::parse("1"), Err("1"));
        assert_eq!(Version::parse("1."), Err("1."));
        assert_eq!(Version::parse("1 h3l1o. W0rld"), Err("1 h3l1o. W0rld"));
        assert_eq!(Version::parse("1. h3l1o. W0rld"), Err("1. h3l1o. W0rld"));
        assert_eq!(Version::parse("1.2.3"), Ok(Version::new(1, 2, Some(3), "")));
        assert_eq!(Version::parse("1.2"), Ok(Version::new(1, 2, None, "")));
        assert_eq!(Version::parse("1.2 h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.h3l1o. W0rld"), Ok(Version::new(1, 2, None, "W0rld")));
        assert_eq!(Version::parse("1.2. h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.3.h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "W0rld")));
        assert_eq!(Version::parse("1.2.3 h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "h3l1o. W0rld")));
    }

    #[test]
    fn test_shader_model() {
        use gfx_core::shade::ShaderModel;
        assert_eq!(to_shader_model(&Version::parse("1.10").unwrap()), ShaderModel::Unsupported);
        assert_eq!(to_shader_model(&Version::parse("1.20").unwrap()), ShaderModel::Version30);
        assert_eq!(to_shader_model(&Version::parse("1.50").unwrap()), ShaderModel::Version40);
        assert_eq!(to_shader_model(&Version::parse("3.00").unwrap()), ShaderModel::Version41);
        assert_eq!(to_shader_model(&Version::parse("4.30").unwrap()), ShaderModel::Version50);
    }
}
<commit_msg>Update info.rs<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashSet;
use std::{cmp, ffi, fmt, mem, str};
use gl;
use gfx_core::Capabilities;
use gfx_core::shade;

/// A version number for a specific component of an OpenGL implementation
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Version {
    pub major: u32,
    pub minor: u32,
    pub revision: Option<u32>,
    pub vendor_info: &'static str,
}

// FIXME https://github.com/rust-lang/rust/issues/18738
// derive

impl cmp::Ord for Version {
    #[inline]
    fn cmp(&self, other: &Version) -> cmp::Ordering {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}
impl cmp::PartialOrd for Version {
    #[inline]
    fn partial_cmp(&self, other: &Version) -> Option<cmp::Ordering> {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .partial_cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}

impl Version {
    /// Create a new OpenGL version number
    pub fn new(major: u32, minor: u32, revision: Option<u32>,
               vendor_info: &'static str) -> Version {
        Version {
            major: major,
            minor: minor,
            revision: revision,
            vendor_info: vendor_info,
        }
    }

    /// According to the OpenGL specification, the version information is
    /// expected to follow the following syntax:
    ///
    /// ~~~bnf
    /// <major>       ::= <number>
    /// <minor>       ::= <number>
    /// <revision>    ::= <number>
    /// <vendor-info> ::= <string>
    /// <release>     ::= <major> "." <minor> ["." <release>]
    /// <version>     ::= <release> [" " <vendor-info>]
    /// ~~~
    ///
    /// Note that this function is intentionally lenient in regards to parsing,
    /// and will try to recover at least the first two version numbers without
    /// resulting in an `Err`.
    pub fn parse(src: &'static str) -> Result<Version, &'static str> {
        let (version, vendor_info) = match src.find(' ') {
            Some(i) => (&src[..i], &src[(i + 1)..]),
            None => (src, ""),
        };

        // TODO: make this even more lenient so that we can also accept
        // `<major> "." <minor> [<???>]`
        let mut it = version.split('.');
        let major = it.next().and_then(|s| s.parse().ok());
        let minor = it.next().and_then(|s| s.parse().ok());
        let revision = it.next().and_then(|s| s.parse().ok());

        match (major, minor, revision) {
            (Some(major), Some(minor), revision) => Ok(Version {
                major: major,
                minor: minor,
                revision: revision,
                vendor_info: vendor_info,
            }),
            (_, _, _) => Err(src),
        }
    }
}

impl fmt::Debug for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match (self.major, self.minor, self.revision, self.vendor_info) {
            (major, minor, Some(revision), "") =>
                write!(f, "{}.{}.{}", major, minor, revision),
            (major, minor, None, "") =>
                write!(f, "{}.{}", major, minor),
            (major, minor, Some(revision), vendor_info) =>
                write!(f, "{}.{}.{}, {}", major, minor, revision, vendor_info),
            (major, minor, None, vendor_info) =>
                write!(f, "{}.{}, {}", major, minor, vendor_info),
        }
    }
}

const EMPTY_STRING: &'static str = "";

/// Get a statically allocated string from the implementation using
/// `glGetString`. Fails if it `GLenum` cannot be handled by the
/// implementation's `gl.GetString` function.
fn get_string(gl: &gl::Gl, name: gl::types::GLenum) -> &'static str {
    let ptr = unsafe { gl.GetString(name) } as *const i8;
    if !ptr.is_null() {
        // This should be safe to mark as statically allocated because
        // GlGetString only returns static strings.
        unsafe { c_str_as_static_str(ptr) }
    } else {
        error!("Invalid GLenum passed to `get_string`: {:x}", name);
        EMPTY_STRING
    }
}

fn get_usize(gl: &gl::Gl, name: gl::types::GLenum) -> usize {
    let mut value = 0 as gl::types::GLint;
    unsafe { gl.GetIntegerv(name, &mut value) };
    value as usize
}

unsafe fn c_str_as_static_str(c_str: *const i8) -> &'static str {
    mem::transmute(str::from_utf8(ffi::CStr::from_ptr(c_str as *const _).to_bytes()).unwrap())
}

/// A unique platform identifier that does not change between releases
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct PlatformName {
    /// The company responsible for the OpenGL implementation
    pub vendor: &'static str,
    /// The name of the renderer
    pub renderer: &'static str,
}

impl PlatformName {
    fn get(gl: &gl::Gl) -> PlatformName {
        PlatformName {
            vendor: get_string(gl, gl::VENDOR),
            renderer: get_string(gl, gl::RENDERER),
        }
    }
}

/// OpenGL implementation information
#[derive(Debug)]
pub struct Info {
    /// The platform identifier
    pub platform_name: PlatformName,
    /// The OpenGL API vesion number
    pub version: Version,
    /// The GLSL vesion number
    pub shading_language: Version,
    /// The extensions supported by the implementation
    pub extensions: HashSet<&'static str>,
}

impl Info {
    fn get(gl: &gl::Gl) -> Info {
        let platform_name = PlatformName::get(gl);
        let version = Version::parse(get_string(gl, gl::VERSION)).unwrap();
        let shading_language = Version::parse(get_string(gl, gl::SHADING_LANGUAGE_VERSION)).unwrap();
        let extensions = if version >= Version::new(3, 0, None, "") {
            let num_exts = get_usize(gl, gl::NUM_EXTENSIONS) as gl::types::GLuint;
            (0..num_exts)
                .map(|i| unsafe { c_str_as_static_str(gl.GetStringi(gl::EXTENSIONS, i) as *const i8) })
                .collect()
        } else {
            // Fallback
            get_string(gl, gl::EXTENSIONS).split(' ').collect()
        };
        Info {
            platform_name: platform_name,
            version: version,
            shading_language: shading_language,
            extensions: extensions,
        }
    }

    pub fn is_version_supported(&self, major: u32, minor: u32) -> bool {
        self.version >= Version::new(major, minor, None, "")
    }

    /// Returns `true` if the implementation supports the extension
    pub fn is_extension_supported(&self, s: &'static str) -> bool {
        self.extensions.contains(&s)
    }

    pub fn is_version_or_extension_supported(&self, major: u32, minor: u32, ext: &'static str) -> bool {
        self.is_version_supported(major, minor) || self.is_extension_supported(ext)
    }
}

fn to_shader_model(v: &Version) -> shade::ShaderModel {
    use gfx_core::shade::ShaderModel;
    match v {
        v if *v < Version::new(1, 20, None, "") => ShaderModel::Unsupported,
        v if *v < Version::new(1, 50, None, "") => ShaderModel::Version30,
        v if *v < Version::new(3,  0, None, "") => ShaderModel::Version40,
        v if *v < Version::new(4, 30, None, "") => ShaderModel::Version41,
        _                                       => ShaderModel::Version50,
    }
}

/// Load the information pertaining to the driver and the corresponding device
/// capabilities.
pub fn get(gl: &gl::Gl) -> (Info, Capabilities) {
    let info = Info::get(gl);
    let caps = Capabilities {
        shader_model:                   to_shader_model(&info.shading_language),

        max_vertex_count:               get_usize(gl, gl::MAX_ELEMENTS_VERTICES),
        max_index_count:                get_usize(gl, gl::MAX_ELEMENTS_INDICES),
        max_draw_buffers:               get_usize(gl, gl::MAX_DRAW_BUFFERS),
        max_texture_size:               get_usize(gl, gl::MAX_TEXTURE_SIZE),
        max_vertex_attributes:          get_usize(gl, gl::MAX_VERTEX_ATTRIBS),

        buffer_role_change_allowed:     true, //TODO

        array_buffer_supported:         info.is_version_or_extension_supported(3, 0, "GL_ARB_vertex_array_object"),
        fragment_output_supported:      info.is_version_or_extension_supported(3, 0, "GL_EXT_gpu_shader4"),
        immutable_storage_supported:    info.is_version_or_extension_supported(4, 2, "GL_ARB_texture_storage"),
        instance_base_supported:        info.is_version_or_extension_supported(4, 2, "GL_ARB_base_instance"),
        instance_call_supported:        info.is_version_or_extension_supported(3, 1, "GL_ARB_draw_instanced"),
        instance_rate_supported:        info.is_version_or_extension_supported(3, 3, "GL_ARB_instanced_arrays"),
        render_targets_supported:       info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object"),
        srgb_color_supported:           info.is_version_or_extension_supported(3, 2, "GL_ARB_framebuffer_sRGB"),
        sampler_objects_supported:      info.is_version_or_extension_supported(3, 3, "GL_ARB_sampler_objects"),
        uniform_block_supported:        info.is_version_or_extension_supported(3, 0, "GL_ARB_uniform_buffer_object"),
        vertex_base_supported:          info.is_version_or_extension_supported(3, 2, "GL_ARB_draw_elements_base_vertex"),
        separate_blending_slots_supported: info.is_version_or_extension_supported(4, 0, "GL_ARB_draw_buffers_blend"),
    };
    (info, caps)
}

#[cfg(test)]
mod tests {
    use super::Version;
    use super::to_shader_model;

    #[test]
    fn test_version_parse() {
        assert_eq!(Version::parse("1"), Err("1"));
        assert_eq!(Version::parse("1."), Err("1."));
        assert_eq!(Version::parse("1 h3l1o. W0rld"), Err("1 h3l1o. W0rld"));
        assert_eq!(Version::parse("1. h3l1o. W0rld"), Err("1. h3l1o. W0rld"));
        assert_eq!(Version::parse("1.2.3"), Ok(Version::new(1, 2, Some(3), "")));
        assert_eq!(Version::parse("1.2"), Ok(Version::new(1, 2, None, "")));
        assert_eq!(Version::parse("1.2 h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.h3l1o. W0rld"), Ok(Version::new(1, 2, None, "W0rld")));
        assert_eq!(Version::parse("1.2. h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.3.h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "W0rld")));
        assert_eq!(Version::parse("1.2.3 h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "h3l1o. W0rld")));
    }

    #[test]
    fn test_shader_model() {
        use gfx_core::shade::ShaderModel;
        assert_eq!(to_shader_model(&Version::parse("1.10").unwrap()), ShaderModel::Unsupported);
        assert_eq!(to_shader_model(&Version::parse("1.20").unwrap()), ShaderModel::Version30);
        assert_eq!(to_shader_model(&Version::parse("1.50").unwrap()), ShaderModel::Version40);
        assert_eq!(to_shader_model(&Version::parse("3.00").unwrap()), ShaderModel::Version41);
        assert_eq!(to_shader_model(&Version::parse("4.30").unwrap()), ShaderModel::Version50);
    }
}
<|endoftext|>


<commit_before>fraptor ICON "misc/icons/Factor.ico"

<commit_msg>vm: change id of windows app icon resource to more standard "APPICON"<commit_after>APPICON ICON "misc/icons/Factor.ico"

<|endoftext|>


<commit_before><commit_msg>[Rust] catch_panic function.<commit_after>#![feature(catch_panic)]

use std::thread::catch_panic;

fn panic() {
    panic!("panic message {can} be formatted", can = "CaN");
}

fn main() {
    let result = catch_panic(panic);
    println!("Result: {:?}", result);
}
<|endoftext|>


<commit_before><commit_msg>chore: impl trait<commit_after><|endoftext|>


<commit_before><commit_msg>rust nth adapter<commit_after>let mut squares = (0..10).map(|i| i*i);

// What if we have ?Sized
// We need to strictly separate mutable and immutable iterators
assert_eq!(squares.nth(4), Some(16));
assert_eq!(squares.nth(0), Some(25));
assert_eq!(squares.nth(6), None);
<|endoftext|>


<commit_before><commit_msg>Initial commit for chapter 5 (empty)<commit_after><|endoftext|>


<commit_before>import front.ast;
import front.ast.ident;
import front.ast.def;
import front.ast.ann;
import driver.session;
import util.common.span;
import std.map.hashmap;
import std.list.list;
import std.list.nil;
import std.list.cons;
import std.option;
import std.option.some;
import std.option.none;
import std._str;
import std._vec;

tag scope {
    scope_crate(@ast.crate);
    scope_item(@ast.item);
    scope_block(ast.block);
    scope_arm(ast.arm);
}

type env = rec(list[scope] scopes,
               session.session sess);

fn lookup_name(&env e, ast.ident i) -> option.t[def] {

    // log "resolving name " + i;

    fn found_def_item(@ast.item i) -> option.t[def] {
        alt (i.node) {
            case (ast.item_const(_, _, _, ?id, _)) {
                ret some[def](ast.def_const(id));
            }
            case (ast.item_fn(_, _, _, ?id, _)) {
                ret some[def](ast.def_fn(id));
            }
            case (ast.item_mod(_, _, ?id)) {
                ret some[def](ast.def_mod(id));
            }
            case (ast.item_ty(_, _, _, ?id, _)) {
                ret some[def](ast.def_ty(id));
            }
            case (ast.item_tag(_, _, _, ?id)) {
                ret some[def](ast.def_ty(id));
            }
            case (ast.item_obj(_, _, _, ?id, _)) {
                ret some[def](ast.def_obj(id));
            }
        }
    }

    fn found_decl_stmt(@ast.stmt s) -> option.t[def] {
        alt (s.node) {
            case (ast.stmt_decl(?d)) {
                alt (d.node) {
                    case (ast.decl_local(?loc)) {
                        ret some[def](ast.def_local(loc.id));
                    }
                    case (ast.decl_item(?it)) {
                        ret found_def_item(it);
                    }
                }
            }
        }
        ret none[def];
    }

    fn check_mod(ast.ident i, ast._mod m) -> option.t[def] {
        alt (m.index.find(i)) {
            case (some[ast.mod_index_entry](?ent)) {
                alt (ent) {
                    case (ast.mie_item(?ix)) {
                        ret found_def_item(m.items.(ix));
                    }
                    case (ast.mie_tag_variant(?item_idx, ?variant_idx)) {
                        alt (m.items.(item_idx).node) {
                            case (ast.item_tag(_, ?variants, _, ?tid)) {
                                auto vid = variants.(variant_idx).id;
                                ret some[def](ast.def_variant(tid, vid));
                            }
                            case (_) {
                                log "tag item not actually a tag";
                                fail;
                            }
                        }
                    }
                }
            }
            case (none[ast.mod_index_entry]) { /* fall through */ }
        }
        ret none[def];
    }

    fn in_scope(ast.ident i, &scope s) -> option.t[def] {
        alt (s) {

            case (scope_crate(?c)) {
                ret check_mod(i, c.node.module);
            }

            case (scope_item(?it)) {
                alt (it.node) {
                    case (ast.item_fn(_, ?f, _, _, _)) {
                        for (ast.arg a in f.inputs) {
                            if (_str.eq(a.ident, i)) {
                                ret some[def](ast.def_arg(a.id));
                            }
                        }
                    }
                    case (ast.item_mod(_, ?m, _)) {
                        ret check_mod(i, m);
                    }
                    case (_) { /* fall through */ }
                }
            }

            case (scope_block(?b)) {
                alt (b.node.index.find(i)) {
                    case (some[uint](?ix)) {
                        ret found_decl_stmt(b.node.stmts.(ix));
                    }
                    case (_) { /* fall through */  }
                }
            }

            case (scope_arm(?a)) {
                alt (a.index.find(i)) {
                    case (some[ast.def_id](?did)) {
                        ret some[def](ast.def_binding(did));
                    }
                    case (_) { /* fall through */  }
                }
            }
        }
        ret none[def];
    }

    ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
}

fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
                option.t[ast.variant_def] old_def, ann a) -> @ast.pat {
    auto new_def;
    alt (lookup_name(e, i)) {
        case (some[def](?d)) {
            alt (d) {
                case (ast.def_variant(?did, ?vid)) {
                    new_def = some[ast.variant_def](tup(did, vid));
                }
                case (_) {
                    e.sess.err("not a tag variant: " + i);
                    new_def = none[ast.variant_def];
                }
            }
        }
        case (none[def]) {
            new_def = none[ast.variant_def];
            e.sess.err("unresolved name: " + i);
        }
    }

    ret @fold.respan[ast.pat_](sp, ast.pat_tag(i, args, new_def, a));
}

fn fold_expr_name(&env e, &span sp, &ast.name n,
                  &option.t[def] d, ann a) -> @ast.expr {

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resolving name expr with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
}

fn fold_ty_path(&env e, &span sp, ast.path p,
                &option.t[def] d) -> @ast.ty {

    let uint len = _vec.len[ast.name](p);
    check (len != 0u);
    if (len > 1u) {
        e.sess.unimpl("resolving path ty with >1 component");
    }

    let ast.name n = p.(0);

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resolving path ty with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.ty_](sp, ast.ty_path(p, d_));
}

fn update_env_for_crate(&env e, @ast.crate c) -> env {
    ret rec(scopes = cons[scope](scope_crate(c), @e.scopes) with e);
}

fn update_env_for_item(&env e, @ast.item i) -> env {
    ret rec(scopes = cons[scope](scope_item(i), @e.scopes) with e);
}

fn update_env_for_block(&env e, &ast.block b) -> env {
    ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
}

fn update_env_for_arm(&env e, &ast.arm p) -> env {
    ret rec(scopes = cons[scope](scope_arm(p), @e.scopes) with e);
}

fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {

    let fold.ast_fold[env] fld = fold.new_identity_fold[env]();

    fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,_,_,_,_),
                fold_expr_name = bind fold_expr_name(_,_,_,_,_),
                fold_ty_path = bind fold_ty_path(_,_,_,_),
                update_env_for_crate = bind update_env_for_crate(_,_),
                update_env_for_item = bind update_env_for_item(_,_),
                update_env_for_block = bind update_env_for_block(_,_),
                update_env_for_arm = bind update_env_for_arm(_,_)
                with *fld );

    auto e = rec(scopes = nil[scope],
                 sess = sess);

    ret fold.fold_crate[env](e, fld, crate);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>rustc: Resolve type params<commit_after>import front.ast;
import front.ast.ident;
import front.ast.def;
import front.ast.ann;
import driver.session;
import util.common.span;
import std.map.hashmap;
import std.list.list;
import std.list.nil;
import std.list.cons;
import std.option;
import std.option.some;
import std.option.none;
import std._str;
import std._vec;

tag scope {
    scope_crate(@ast.crate);
    scope_item(@ast.item);
    scope_block(ast.block);
    scope_arm(ast.arm);
}

type env = rec(list[scope] scopes,
               session.session sess);

fn lookup_name(&env e, ast.ident i) -> option.t[def] {

    // log "resolving name " + i;

    fn found_def_item(@ast.item i) -> option.t[def] {
        alt (i.node) {
            case (ast.item_const(_, _, _, ?id, _)) {
                ret some[def](ast.def_const(id));
            }
            case (ast.item_fn(_, _, _, ?id, _)) {
                ret some[def](ast.def_fn(id));
            }
            case (ast.item_mod(_, _, ?id)) {
                ret some[def](ast.def_mod(id));
            }
            case (ast.item_ty(_, _, _, ?id, _)) {
                ret some[def](ast.def_ty(id));
            }
            case (ast.item_tag(_, _, _, ?id)) {
                ret some[def](ast.def_ty(id));
            }
            case (ast.item_obj(_, _, _, ?id, _)) {
                ret some[def](ast.def_obj(id));
            }
        }
    }

    fn found_decl_stmt(@ast.stmt s) -> option.t[def] {
        alt (s.node) {
            case (ast.stmt_decl(?d)) {
                alt (d.node) {
                    case (ast.decl_local(?loc)) {
                        ret some[def](ast.def_local(loc.id));
                    }
                    case (ast.decl_item(?it)) {
                        ret found_def_item(it);
                    }
                }
            }
        }
        ret none[def];
    }

    fn check_mod(ast.ident i, ast._mod m) -> option.t[def] {
        alt (m.index.find(i)) {
            case (some[ast.mod_index_entry](?ent)) {
                alt (ent) {
                    case (ast.mie_item(?ix)) {
                        ret found_def_item(m.items.(ix));
                    }
                    case (ast.mie_tag_variant(?item_idx, ?variant_idx)) {
                        alt (m.items.(item_idx).node) {
                            case (ast.item_tag(_, ?variants, _, ?tid)) {
                                auto vid = variants.(variant_idx).id;
                                ret some[def](ast.def_variant(tid, vid));
                            }
                            case (_) {
                                log "tag item not actually a tag";
                                fail;
                            }
                        }
                    }
                }
            }
            case (none[ast.mod_index_entry]) { /* fall through */ }
        }
        ret none[def];
    }

    fn in_scope(ast.ident i, &scope s) -> option.t[def] {
        alt (s) {

            case (scope_crate(?c)) {
                ret check_mod(i, c.node.module);
            }

            case (scope_item(?it)) {
                alt (it.node) {
                    case (ast.item_fn(_, ?f, ?ty_params, _, _)) {
                        for (ast.arg a in f.inputs) {
                            if (_str.eq(a.ident, i)) {
                                ret some[def](ast.def_arg(a.id));
                            }
                        }
                        for (ast.ty_param tp in ty_params) {
                            if (_str.eq(tp.ident, i)) {
                                ret some[def](ast.def_ty_arg(tp.id));
                            }
                        }
                    }
                    case (ast.item_mod(_, ?m, _)) {
                        ret check_mod(i, m);
                    }
                    case (_) { /* fall through */ }
                }
            }

            case (scope_block(?b)) {
                alt (b.node.index.find(i)) {
                    case (some[uint](?ix)) {
                        ret found_decl_stmt(b.node.stmts.(ix));
                    }
                    case (_) { /* fall through */  }
                }
            }

            case (scope_arm(?a)) {
                alt (a.index.find(i)) {
                    case (some[ast.def_id](?did)) {
                        ret some[def](ast.def_binding(did));
                    }
                    case (_) { /* fall through */  }
                }
            }
        }
        ret none[def];
    }

    ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
}

fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
                option.t[ast.variant_def] old_def, ann a) -> @ast.pat {
    auto new_def;
    alt (lookup_name(e, i)) {
        case (some[def](?d)) {
            alt (d) {
                case (ast.def_variant(?did, ?vid)) {
                    new_def = some[ast.variant_def](tup(did, vid));
                }
                case (_) {
                    e.sess.err("not a tag variant: " + i);
                    new_def = none[ast.variant_def];
                }
            }
        }
        case (none[def]) {
            new_def = none[ast.variant_def];
            e.sess.err("unresolved name: " + i);
        }
    }

    ret @fold.respan[ast.pat_](sp, ast.pat_tag(i, args, new_def, a));
}

fn fold_expr_name(&env e, &span sp, &ast.name n,
                  &option.t[def] d, ann a) -> @ast.expr {

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resolving name expr with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
}

fn fold_ty_path(&env e, &span sp, ast.path p,
                &option.t[def] d) -> @ast.ty {

    let uint len = _vec.len[ast.name](p);
    check (len != 0u);
    if (len > 1u) {
        e.sess.unimpl("resolving path ty with >1 component");
    }

    let ast.name n = p.(0);

    if (_vec.len[@ast.ty](n.node.types) > 0u) {
        e.sess.unimpl("resolving path ty with ty params");
    }

    auto d_ = lookup_name(e, n.node.ident);

    alt (d_) {
        case (some[def](_)) {
            // log "resolved name " + n.node.ident;
        }
        case (none[def]) {
            e.sess.err("unresolved name: " + n.node.ident);
        }
    }

    ret @fold.respan[ast.ty_](sp, ast.ty_path(p, d_));
}

fn update_env_for_crate(&env e, @ast.crate c) -> env {
    ret rec(scopes = cons[scope](scope_crate(c), @e.scopes) with e);
}

fn update_env_for_item(&env e, @ast.item i) -> env {
    ret rec(scopes = cons[scope](scope_item(i), @e.scopes) with e);
}

fn update_env_for_block(&env e, &ast.block b) -> env {
    ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
}

fn update_env_for_arm(&env e, &ast.arm p) -> env {
    ret rec(scopes = cons[scope](scope_arm(p), @e.scopes) with e);
}

fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {

    let fold.ast_fold[env] fld = fold.new_identity_fold[env]();

    fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,_,_,_,_),
                fold_expr_name = bind fold_expr_name(_,_,_,_,_),
                fold_ty_path = bind fold_ty_path(_,_,_,_),
                update_env_for_crate = bind update_env_for_crate(_,_),
                update_env_for_item = bind update_env_for_item(_,_),
                update_env_for_block = bind update_env_for_block(_,_),
                update_env_for_arm = bind update_env_for_arm(_,_)
                with *fld );

    auto e = rec(scopes = nil[scope],
                 sess = sess);

    ret fold.fold_crate[env](e, fld, crate);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>Add the operators module with the actual op implementations<commit_after>#[derive(Debug,PartialEq)]
pub enum Infix {
    Add,
    Subtract,
    Multiply,
    Divide,
    Unrecognized,
}
#[derive(Debug,PartialEq)]
pub enum Prefix {
    Negative,
    Positive,
    Unrecognized,
}
#[derive(Debug,PartialEq)]
pub enum Postfix {
    Unrecognized,
}

#[derive(Debug,PartialEq,PartialOrd)]
pub enum Precedence {
    Other,
    MathNegativePositive,
    MathMultiplyDivide,
    MathAddSubtract,
}

use platonic_runtime::*;
use platonic_runtime::PlatonicValue::*;
use platonic_runtime::operators::Precedence::*;
use num::traits::*;

pub fn infix(string: &str) -> Infix {
    use platonic_runtime::operators::Infix::*;
    match string {
        "+" => Add,
        "-" => Subtract,
        "*" => Multiply,
        "/" => Divide,
        _   => Unrecognized,
    }
}

pub fn prefix(string: &str) -> Prefix {
    use platonic_runtime::operators::Prefix::*;
    match string {
        "+" => Positive,
        "-" => Negative,
        _   => Unrecognized,
    }
}

pub fn postfix(string: &str) -> Postfix {
    use platonic_runtime::operators::Postfix::*;
    match string {
        _   => Unrecognized,
    }
}

impl Infix {
    pub fn precedence(&self) -> Precedence {
        use platonic_runtime::operators::Infix::*;
        match *self {
            Add|Subtract => MathAddSubtract,
            Multiply|Divide => MathMultiplyDivide,
            Unrecognized => Other,
        }
    }

    pub fn evaluate(&self, evaluator: &PlatonicEvaluator, index: TokenIndex, last_precedence: Precedence, left: PlatonicValue, right: PlatonicValue) -> PlatonicValue {
        use platonic_runtime::operators::Infix::*;
        if *self == Unrecognized {
            println!("Unrecognized!!!");
            evaluator.report_at_token(UnrecognizedOperator, index)
        } else if self.precedence() < last_precedence && left != Error && right != Error {
            println!("Precedence error: ${:?}.precedence({:?}) > {:?}", self, self.precedence(), last_precedence);
            evaluator.report_at_token(OperatorsOutOfPrecedenceOrder, index)
        } else {
            match *self {
                Add      => self.evaluate_numeric(evaluator, index, left, right, |left,right| left+right),
                Subtract => self.evaluate_numeric(evaluator, index, left, right, |left,right| left-right),
                Multiply => self.evaluate_numeric(evaluator, index, left, right, |left,right| left*right),
                Divide   => {
                    if let Rational(ref denom) = right {
                        if denom.is_zero() {
                            evaluator.report_at_token(DivideByZero, index);
                            return Error;
                        }
                    }
                    self.evaluate_numeric(evaluator, index, left, right, |left,right| left/right)
                }
                Unrecognized => unreachable!(),
            }
        }
    }

    fn evaluate_numeric<F: FnOnce(BigRational,BigRational)->BigRational>(&self, evaluator: &PlatonicEvaluator, index: TokenIndex, left: PlatonicValue, right: PlatonicValue, f: F) -> PlatonicValue {
        match (left, right) {
            (Nothing, Nothing) => evaluator.report_at_token(MissingBothOperands, index),
            (_, Nothing) => evaluator.report_at_token(MissingLeftOperand, index),
            (Nothing, _) => evaluator.report_at_token(MissingRightOperand, index),
            (Error, _)|(_, Error) => Error,
            (Rational(left), Rational(right)) => Rational(f(left, right)),
        }
    }
}

impl Prefix {

    pub fn precedence(&self) -> Precedence {
        use platonic_runtime::operators::Prefix::*;
        match *self {
            Negative|Positive => MathNegativePositive,
            Unrecognized => Other,
        }
    }

    pub fn evaluate(&self, evaluator: &PlatonicEvaluator, index: TokenIndex, right: PlatonicValue) -> PlatonicValue {
        use platonic_runtime::operators::Prefix::*;
        if *self == Unrecognized {
            println!("Unrecognized!!!");
            evaluator.report_at_token(UnrecognizedOperator, index)
        } else {
            println!("Recognized! {:?}({:?}", self, right);
            let result = match *self {
                Positive => self.evaluate_numeric(evaluator, index, right, |right| right),
                Negative => self.evaluate_numeric(evaluator, index, right, |right| -right),
                Unrecognized => unreachable!(),
            };
            println!("----> Result: {:?}", result);
            result
        }
    }

    fn evaluate_numeric<F: FnOnce(BigRational)->BigRational>(&self, evaluator: &PlatonicEvaluator, index: TokenIndex, right: PlatonicValue, f: F) -> PlatonicValue {
        match right {
            Nothing => evaluator.report_at_token(MissingRightOperand, index),
            Error => Error,
            Rational(right) => Rational(f(right)),
        }
    }
}

impl Postfix {
    pub fn precedence(&self) -> Precedence {
        use platonic_runtime::operators::Postfix::*;
        match *self {
            Unrecognized => Other,
        }
    }

    pub fn evaluate(&self, evaluator: &PlatonicEvaluator, index: TokenIndex, last_precedence: Precedence, left: PlatonicValue) -> PlatonicValue {
        use platonic_runtime::operators::Postfix::*;
        if *self == Unrecognized {
            evaluator.report_at_token(UnrecognizedOperator, index)
        } else if self.precedence() < last_precedence && left != Error {
            evaluator.report_at_token(OperatorsOutOfPrecedenceOrder, index)
        } else {
            match *self {
                Unrecognized => unreachable!(),
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>FromIterator for Result<commit_after>fn main() {
    // We can take iterator with Result<String> and transform into Result<Vec<String>>
    // looks like really cool thing
    let lines = reader.lines().collect::<io::Result<Vec<String>>>()?;
}
// How does this work?
// The standard library contains an implementation of FromIterator for Result
// easy to overlook in the online documentation that makes this possible:

// impl<T, E, C> FromIterator<Result<T, E>> for Result<C, E>
//   where C: FromIterator<T>
// {
//     ...
// }
<|endoftext|>


<commit_before>// 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.

/// The expansion from a test function to the appropriate test struct for libtest
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.

use syntax::ext::base::*;
use syntax::ext::build::AstBuilder;
use syntax::ext::hygiene::{self, Mark, SyntaxContext};
use syntax::attr;
use syntax::ast;
use syntax::print::pprust;
use syntax::symbol::Symbol;
use syntax_pos::{DUMMY_SP, Span};
use syntax::source_map::{ExpnInfo, MacroAttribute};
use std::iter;

pub fn expand_test(
    cx: &mut ExtCtxt,
    attr_sp: Span,
    _meta_item: &ast::MetaItem,
    item: Annotatable,
) -> Vec<Annotatable> {
    expand_test_or_bench(cx, attr_sp, item, false)
}

pub fn expand_bench(
    cx: &mut ExtCtxt,
    attr_sp: Span,
    _meta_item: &ast::MetaItem,
    item: Annotatable,
) -> Vec<Annotatable> {
    expand_test_or_bench(cx, attr_sp, item, true)
}

pub fn expand_test_or_bench(
    cx: &mut ExtCtxt,
    attr_sp: Span,
    item: Annotatable,
    is_bench: bool
) -> Vec<Annotatable> {
    // If we're not in test configuration, remove the annotated item
    if !cx.ecfg.should_test { return vec![]; }

    let item =
        if let Annotatable::Item(i) = item { i }
        else {
            cx.parse_sess.span_diagnostic.span_fatal(item.span(),
                "#[test] attribute is only allowed on fn items").raise();
        };

    if let ast::ItemKind::Mac(_) = item.node {
        cx.parse_sess.span_diagnostic.span_warn(item.span,
            "#[test] attribute should not be used on macros. Use #[cfg(test)] instead.");
        return vec![Annotatable::Item(item)];
    }

    // has_*_signature will report any errors in the type so compilation
    // will fail. We shouldn't try to expand in this case because the errors
    // would be spurious.
    if (!is_bench && !has_test_signature(cx, &item)) ||
        (is_bench && !has_bench_signature(cx, &item)) {
        return vec![Annotatable::Item(item)];
    }

    let (sp, attr_sp) = {
        let mark = Mark::fresh(Mark::root());
        mark.set_expn_info(ExpnInfo {
            call_site: DUMMY_SP,
            def_site: None,
            format: MacroAttribute(Symbol::intern("test")),
            allow_internal_unstable: true,
            allow_internal_unsafe: false,
            local_inner_macros: false,
            edition: hygiene::default_edition(),
        });
        (item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)),
         attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)))
    };

    // Gensym "test" so we can extern crate without conflicting with any local names
    let test_id = cx.ident_of("test").gensym();

    // creates test::$name
    let test_path = |name| {
        cx.path(sp, vec![test_id, cx.ident_of(name)])
    };

    // creates test::$name
    let should_panic_path = |name| {
        cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic"), cx.ident_of(name)])
    };

    // creates $name: $expr
    let field = |name, expr| cx.field_imm(sp, cx.ident_of(name), expr);

    let test_fn = if is_bench {
        // A simple ident for a lambda
        let b = cx.ident_of("b");

        cx.expr_call(sp, cx.expr_path(test_path("StaticBenchFn")), vec![
            // |b| self::test::assert_test_result(
            cx.lambda1(sp,
                cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), vec![
                    // super::$test_fn(b)
                    cx.expr_call(sp,
                        cx.expr_path(cx.path(sp, vec![item.ident])),
                        vec![cx.expr_ident(sp, b)])
                ]),
                b
            )
            // )
        ])
    } else {
        cx.expr_call(sp, cx.expr_path(test_path("StaticTestFn")), vec![
            // || {
            cx.lambda0(sp,
                // test::assert_test_result(
                cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), vec![
                    // $test_fn()
                    cx.expr_call(sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![])
                // )
                ])
            // }
            )
        // )
        ])
    };

    let mut test_const = cx.item(sp, item.ident.gensym(),
        vec![
            // #[cfg(test)]
            cx.attribute(attr_sp, cx.meta_list(attr_sp, Symbol::intern("cfg"), vec![
                cx.meta_list_item_word(attr_sp, Symbol::intern("test"))
            ])),
            // #[rustc_test_marker]
            cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker")))
        ],
        // const $ident: test::TestDescAndFn =
        ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
            // test::TestDescAndFn {
            cx.expr_struct(sp, test_path("TestDescAndFn"), vec![
                // desc: test::TestDesc {
                field("desc", cx.expr_struct(sp, test_path("TestDesc"), vec![
                    // name: "path::to::test"
                    field("name", cx.expr_call(sp, cx.expr_path(test_path("StaticTestName")),
                        vec![
                            cx.expr_str(sp, Symbol::intern(&item_path(
                                // skip the name of the root module
                                &cx.current_expansion.module.mod_path[1..],
                                &item.ident
                            )))
                        ])),
                    // ignore: true | false
                    field("ignore", cx.expr_bool(sp, should_ignore(&item))),
                    // allow_fail: true | false
                    field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
                    // should_panic: ...
                    field("should_panic", match should_panic(cx, &item) {
                        // test::ShouldPanic::No
                        ShouldPanic::No => cx.expr_path(should_panic_path("No")),
                        // test::ShouldPanic::Yes
                        ShouldPanic::Yes(None) => cx.expr_path(should_panic_path("Yes")),
                        // test::ShouldPanic::YesWithMessage("...")
                        ShouldPanic::Yes(Some(sym)) => cx.expr_call(sp,
                            cx.expr_path(should_panic_path("YesWithMessage")),
                            vec![cx.expr_str(sp, sym)]),
                    }),
                // },
                ])),
                // testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
                field("testfn", test_fn)
            // }
            ])
        // }
        ));
    test_const = test_const.map(|mut tc| { tc.vis.node = ast::VisibilityKind::Public; tc});

    // extern crate test as test_gensym
    let test_extern = cx.item(sp,
        test_id,
        vec![],
        ast::ItemKind::ExternCrate(Some(Symbol::intern("test")))
    );

    debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const));

    vec![
        // Access to libtest under a gensymed name
        Annotatable::Item(test_extern),
        // The generated test case
        Annotatable::Item(test_const),
        // The original item
        Annotatable::Item(item)
    ]
}

fn item_path(mod_path: &[ast::Ident], item_ident: &ast::Ident) -> String {
    mod_path.iter().chain(iter::once(item_ident))
        .map(|x| x.to_string()).collect::<Vec<String>>().join("::")
}

enum ShouldPanic {
    No,
    Yes(Option<Symbol>),
}

fn should_ignore(i: &ast::Item) -> bool {
    attr::contains_name(&i.attrs, "ignore")
}

fn should_fail(i: &ast::Item) -> bool {
    attr::contains_name(&i.attrs, "allow_fail")
}

fn should_panic(cx: &ExtCtxt, i: &ast::Item) -> ShouldPanic {
    match attr::find_by_name(&i.attrs, "should_panic") {
        Some(attr) => {
            let ref sd = cx.parse_sess.span_diagnostic;
            if attr.is_value_str() {
                sd.struct_span_warn(
                    attr.span(),
                    "attribute must be of the form: \
                     `#[should_panic]` or \
                     `#[should_panic(expected = \"error message\")]`"
                ).note("Errors in this attribute were erroneously allowed \
                        and will become a hard error in a future release.")
                .emit();
                return ShouldPanic::Yes(None);
            }
            match attr.meta_item_list() {
                // Handle #[should_panic]
                None => ShouldPanic::Yes(None),
                // Handle #[should_panic(expected = "foo")]
                Some(list) => {
                    let msg = list.iter()
                        .find(|mi| mi.check_name("expected"))
                        .and_then(|mi| mi.meta_item())
                        .and_then(|mi| mi.value_str());
                    if list.len() != 1 || msg.is_none() {
                        sd.struct_span_warn(
                            attr.span(),
                            "argument must be of the form: \
                             `expected = \"error message\"`"
                        ).note("Errors in this attribute were erroneously \
                                allowed and will become a hard error in a \
                                future release.").emit();
                        ShouldPanic::Yes(None)
                    } else {
                        ShouldPanic::Yes(msg)
                    }
                },
            }
        }
        None => ShouldPanic::No,
    }
}

fn has_test_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
    let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
    let ref sd = cx.parse_sess.span_diagnostic;
    if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node {
        if header.unsafety == ast::Unsafety::Unsafe {
            sd.span_err(
                i.span,
                "unsafe functions cannot be used for tests"
            );
            return false
        }
        if header.asyncness.is_async() {
            sd.span_err(
                i.span,
                "async functions cannot be used for tests"
            );
            return false
        }

        // If the termination trait is active, the compiler will check that the output
        // type implements the `Termination` trait as `libtest` enforces that.
        let has_output = match decl.output {
            ast::FunctionRetTy::Default(..) => false,
            ast::FunctionRetTy::Ty(ref t) if t.node.is_unit() => false,
            _ => true
        };

        if !decl.inputs.is_empty() {
            sd.span_err(i.span, "functions used as tests can not have any arguments");
            return false;
        }

        match (has_output, has_should_panic_attr) {
            (true, true) => {
                sd.span_err(i.span, "functions using `#[should_panic]` must return `()`");
                false
            },
            (true, false) => if !generics.params.is_empty() {
                sd.span_err(i.span,
                                "functions used as tests must have signature fn() -> ()");
                false
            } else {
                true
            },
            (false, _) => true
        }
    } else {
        sd.span_err(i.span, "only functions may be used as tests");
        false
    }
}

fn has_bench_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
    let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.node {
        // NB: inadequate check, but we're running
        // well before resolve, can't get too deep.
        decl.inputs.len() == 1
    } else {
        false
    };

    if !has_sig {
        cx.parse_sess.span_diagnostic.span_err(i.span, "functions used as benches must have \
            signature `fn(&mut Bencher) -> impl Termination`");
    }

    has_sig
}
<commit_msg>reword #[test] attribute error on fn items<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.

/// The expansion from a test function to the appropriate test struct for libtest
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.

use syntax::ext::base::*;
use syntax::ext::build::AstBuilder;
use syntax::ext::hygiene::{self, Mark, SyntaxContext};
use syntax::attr;
use syntax::ast;
use syntax::print::pprust;
use syntax::symbol::Symbol;
use syntax_pos::{DUMMY_SP, Span};
use syntax::source_map::{ExpnInfo, MacroAttribute};
use std::iter;

pub fn expand_test(
    cx: &mut ExtCtxt,
    attr_sp: Span,
    _meta_item: &ast::MetaItem,
    item: Annotatable,
) -> Vec<Annotatable> {
    expand_test_or_bench(cx, attr_sp, item, false)
}

pub fn expand_bench(
    cx: &mut ExtCtxt,
    attr_sp: Span,
    _meta_item: &ast::MetaItem,
    item: Annotatable,
) -> Vec<Annotatable> {
    expand_test_or_bench(cx, attr_sp, item, true)
}

pub fn expand_test_or_bench(
    cx: &mut ExtCtxt,
    attr_sp: Span,
    item: Annotatable,
    is_bench: bool
) -> Vec<Annotatable> {
    // If we're not in test configuration, remove the annotated item
    if !cx.ecfg.should_test { return vec![]; }

    let item =
        if let Annotatable::Item(i) = item { i }
        else {
            cx.parse_sess.span_diagnostic.span_fatal(item.span(),
                "#[test] attribute is only allowed on non associated functions").raise();
        };

    if let ast::ItemKind::Mac(_) = item.node {
        cx.parse_sess.span_diagnostic.span_warn(item.span,
            "#[test] attribute should not be used on macros. Use #[cfg(test)] instead.");
        return vec![Annotatable::Item(item)];
    }

    // has_*_signature will report any errors in the type so compilation
    // will fail. We shouldn't try to expand in this case because the errors
    // would be spurious.
    if (!is_bench && !has_test_signature(cx, &item)) ||
        (is_bench && !has_bench_signature(cx, &item)) {
        return vec![Annotatable::Item(item)];
    }

    let (sp, attr_sp) = {
        let mark = Mark::fresh(Mark::root());
        mark.set_expn_info(ExpnInfo {
            call_site: DUMMY_SP,
            def_site: None,
            format: MacroAttribute(Symbol::intern("test")),
            allow_internal_unstable: true,
            allow_internal_unsafe: false,
            local_inner_macros: false,
            edition: hygiene::default_edition(),
        });
        (item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)),
         attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)))
    };

    // Gensym "test" so we can extern crate without conflicting with any local names
    let test_id = cx.ident_of("test").gensym();

    // creates test::$name
    let test_path = |name| {
        cx.path(sp, vec![test_id, cx.ident_of(name)])
    };

    // creates test::$name
    let should_panic_path = |name| {
        cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic"), cx.ident_of(name)])
    };

    // creates $name: $expr
    let field = |name, expr| cx.field_imm(sp, cx.ident_of(name), expr);

    let test_fn = if is_bench {
        // A simple ident for a lambda
        let b = cx.ident_of("b");

        cx.expr_call(sp, cx.expr_path(test_path("StaticBenchFn")), vec![
            // |b| self::test::assert_test_result(
            cx.lambda1(sp,
                cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), vec![
                    // super::$test_fn(b)
                    cx.expr_call(sp,
                        cx.expr_path(cx.path(sp, vec![item.ident])),
                        vec![cx.expr_ident(sp, b)])
                ]),
                b
            )
            // )
        ])
    } else {
        cx.expr_call(sp, cx.expr_path(test_path("StaticTestFn")), vec![
            // || {
            cx.lambda0(sp,
                // test::assert_test_result(
                cx.expr_call(sp, cx.expr_path(test_path("assert_test_result")), vec![
                    // $test_fn()
                    cx.expr_call(sp, cx.expr_path(cx.path(sp, vec![item.ident])), vec![])
                // )
                ])
            // }
            )
        // )
        ])
    };

    let mut test_const = cx.item(sp, item.ident.gensym(),
        vec![
            // #[cfg(test)]
            cx.attribute(attr_sp, cx.meta_list(attr_sp, Symbol::intern("cfg"), vec![
                cx.meta_list_item_word(attr_sp, Symbol::intern("test"))
            ])),
            // #[rustc_test_marker]
            cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker")))
        ],
        // const $ident: test::TestDescAndFn =
        ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
            // test::TestDescAndFn {
            cx.expr_struct(sp, test_path("TestDescAndFn"), vec![
                // desc: test::TestDesc {
                field("desc", cx.expr_struct(sp, test_path("TestDesc"), vec![
                    // name: "path::to::test"
                    field("name", cx.expr_call(sp, cx.expr_path(test_path("StaticTestName")),
                        vec![
                            cx.expr_str(sp, Symbol::intern(&item_path(
                                // skip the name of the root module
                                &cx.current_expansion.module.mod_path[1..],
                                &item.ident
                            )))
                        ])),
                    // ignore: true | false
                    field("ignore", cx.expr_bool(sp, should_ignore(&item))),
                    // allow_fail: true | false
                    field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
                    // should_panic: ...
                    field("should_panic", match should_panic(cx, &item) {
                        // test::ShouldPanic::No
                        ShouldPanic::No => cx.expr_path(should_panic_path("No")),
                        // test::ShouldPanic::Yes
                        ShouldPanic::Yes(None) => cx.expr_path(should_panic_path("Yes")),
                        // test::ShouldPanic::YesWithMessage("...")
                        ShouldPanic::Yes(Some(sym)) => cx.expr_call(sp,
                            cx.expr_path(should_panic_path("YesWithMessage")),
                            vec![cx.expr_str(sp, sym)]),
                    }),
                // },
                ])),
                // testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
                field("testfn", test_fn)
            // }
            ])
        // }
        ));
    test_const = test_const.map(|mut tc| { tc.vis.node = ast::VisibilityKind::Public; tc});

    // extern crate test as test_gensym
    let test_extern = cx.item(sp,
        test_id,
        vec![],
        ast::ItemKind::ExternCrate(Some(Symbol::intern("test")))
    );

    debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const));

    vec![
        // Access to libtest under a gensymed name
        Annotatable::Item(test_extern),
        // The generated test case
        Annotatable::Item(test_const),
        // The original item
        Annotatable::Item(item)
    ]
}

fn item_path(mod_path: &[ast::Ident], item_ident: &ast::Ident) -> String {
    mod_path.iter().chain(iter::once(item_ident))
        .map(|x| x.to_string()).collect::<Vec<String>>().join("::")
}

enum ShouldPanic {
    No,
    Yes(Option<Symbol>),
}

fn should_ignore(i: &ast::Item) -> bool {
    attr::contains_name(&i.attrs, "ignore")
}

fn should_fail(i: &ast::Item) -> bool {
    attr::contains_name(&i.attrs, "allow_fail")
}

fn should_panic(cx: &ExtCtxt, i: &ast::Item) -> ShouldPanic {
    match attr::find_by_name(&i.attrs, "should_panic") {
        Some(attr) => {
            let ref sd = cx.parse_sess.span_diagnostic;
            if attr.is_value_str() {
                sd.struct_span_warn(
                    attr.span(),
                    "attribute must be of the form: \
                     `#[should_panic]` or \
                     `#[should_panic(expected = \"error message\")]`"
                ).note("Errors in this attribute were erroneously allowed \
                        and will become a hard error in a future release.")
                .emit();
                return ShouldPanic::Yes(None);
            }
            match attr.meta_item_list() {
                // Handle #[should_panic]
                None => ShouldPanic::Yes(None),
                // Handle #[should_panic(expected = "foo")]
                Some(list) => {
                    let msg = list.iter()
                        .find(|mi| mi.check_name("expected"))
                        .and_then(|mi| mi.meta_item())
                        .and_then(|mi| mi.value_str());
                    if list.len() != 1 || msg.is_none() {
                        sd.struct_span_warn(
                            attr.span(),
                            "argument must be of the form: \
                             `expected = \"error message\"`"
                        ).note("Errors in this attribute were erroneously \
                                allowed and will become a hard error in a \
                                future release.").emit();
                        ShouldPanic::Yes(None)
                    } else {
                        ShouldPanic::Yes(msg)
                    }
                },
            }
        }
        None => ShouldPanic::No,
    }
}

fn has_test_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
    let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
    let ref sd = cx.parse_sess.span_diagnostic;
    if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node {
        if header.unsafety == ast::Unsafety::Unsafe {
            sd.span_err(
                i.span,
                "unsafe functions cannot be used for tests"
            );
            return false
        }
        if header.asyncness.is_async() {
            sd.span_err(
                i.span,
                "async functions cannot be used for tests"
            );
            return false
        }

        // If the termination trait is active, the compiler will check that the output
        // type implements the `Termination` trait as `libtest` enforces that.
        let has_output = match decl.output {
            ast::FunctionRetTy::Default(..) => false,
            ast::FunctionRetTy::Ty(ref t) if t.node.is_unit() => false,
            _ => true
        };

        if !decl.inputs.is_empty() {
            sd.span_err(i.span, "functions used as tests can not have any arguments");
            return false;
        }

        match (has_output, has_should_panic_attr) {
            (true, true) => {
                sd.span_err(i.span, "functions using `#[should_panic]` must return `()`");
                false
            },
            (true, false) => if !generics.params.is_empty() {
                sd.span_err(i.span,
                                "functions used as tests must have signature fn() -> ()");
                false
            } else {
                true
            },
            (false, _) => true
        }
    } else {
        sd.span_err(i.span, "only functions may be used as tests");
        false
    }
}

fn has_bench_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
    let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.node {
        // NB: inadequate check, but we're running
        // well before resolve, can't get too deep.
        decl.inputs.len() == 1
    } else {
        false
    };

    if !has_sig {
        cx.parse_sess.span_diagnostic.span_err(i.span, "functions used as benches must have \
            signature `fn(&mut Bencher) -> impl Termination`");
    }

    has_sig
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #52825 - RalfJung:codegen, r=alexcrichton<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.

// no-system-llvm
// compile-flags: -O -C panic=abort
#![crate_type = "lib"]

fn search<T: Ord + Eq>(arr: &mut [T], a: &T) -> Result<usize, ()> {
    match arr.iter().position(|x| x == a) {
        Some(p) => {
            Ok(p)
        },
        None => Err(()),
    }
}

// CHECK-LABEL: @position_no_bounds_check
#[no_mangle]
pub fn position_no_bounds_check(y: &mut [u32], x: &u32, z: &u32) -> bool {
    // This contains "call assume" so we cannot just rule out all calls
    // CHECK-NOT: panic_bounds_check
    if let Ok(p) = search(y, x) {
      y[p] == *z
    } else {
      false
    }
}

// just to make sure that panicking really emits "panic_bounds_check" somewhere in the IR
// CHECK-LABEL: @test_check
#[no_mangle]
pub fn test_check(y: &[i32]) -> i32 {
    // CHECK: panic_bounds_check
    y[12]
}
<|endoftext|>


<commit_before><commit_msg>Added fast exponentiation in Rust<commit_after>//Performs the fast exponentiation algorithm by repeated squaring operations
fn fast_exponentiation(base: u64, exponent: u64) -> u64 {
	if exponent == 0 {
		return 1;
	}

	if exponent == 1 {
		return base;
	}

	if exponent % 2 == 0 {
		return fast_exponentiation(base*base, exponent/2);
	} else {
		return base * fast_exponentiation(base*base, (exponent-1)/2);
	}
}

fn main() {
    println!("fast_exp({}, {}) = {} equals pow({},{}) = {}", 10, 1, fast_exponentiation(10, 1), 10, 1, 10_u64.pow(1));
    println!("fast_exp({}, {}) = {} equals pow({},{}) = {}", 10, 0, fast_exponentiation(10, 0), 10, 0, 10_u64.pow(0));
    println!("fast_exp({}, {}) = {} equals pow({},{}) = {}", 20, 3, fast_exponentiation(20, 3), 20, 3, 20_u64.pow(3));
    println!("fast_exp({}, {}) = {} equals pow({},{}) = {}", 4, 20, fast_exponentiation(4, 20), 4, 20, 4_u64.pow(20));
}<|endoftext|>


<commit_before><commit_msg>Add problem #92<commit_after>use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 92,
    answer: "8581146",
    solver: solve
};

fn square_digit_sum(mut n: uint) -> uint {
    let mut sum = 0;
    while n > 0 {
        let (d, m) = n.div_mod(&10);
        sum += m * m;
        n = d;
    }
    return sum;
}

fn is_reach_89(n: uint, map: &mut [Option<bool>]) -> bool {
    if n >= map.len() {
        return is_reach_89(square_digit_sum(n), map);
    }

    match map[n] {
        Some(b) => { return b; }
        None => { }
    }

    let result = is_reach_89(square_digit_sum(n), map);
    map[n] = Some(result);
    return result;
}

fn solve() -> ~str {
    let limit = 10000000;
    let mut cnt = 0u;

    let vec_size = 81 * 7 + 1;
    let mut map = vec::from_elem(vec_size, None);
    map[0] = Some(false);
    map[1] = Some(false);
    map[89] = Some(true);
    for uint::range(1, limit + 1) |n| {
        if is_reach_89(n, map) { cnt += 1; }
    }
    return cnt.to_str();
}
<|endoftext|>


<commit_before><commit_msg>Add case to handle invalid magic bytes<commit_after><|endoftext|>


<commit_before>// Copyright 2014 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.

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(slice_patterns)]

fn a() {
    let mut vec = [box 1, box 2, box 3];
    match vec {
        [box ref _a, _, _] => {
        //~^ borrow of `vec[..]` occurs here
            vec[0] = box 4; //~ ERROR cannot assign
            //~^ assignment to borrowed `vec[..]` occurs here
        }
    }
}

fn b() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [ref _b..] => {
        //~^ borrow of `vec[..]` occurs here
            vec[0] = box 4; //~ ERROR cannot assign
            //~^ assignment to borrowed `vec[..]` occurs here
        }
    }
}

fn c() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [_a, //~ ERROR cannot move out
            //~| cannot move out
            //~| to prevent move
            ..
        ] => {
            // Note: `_a` is *moved* here, but `b` is borrowing,
            // hence illegal.
            //
            // See comment in middle/borrowck/gather_loans/mod.rs
            // in the case covering these sorts of vectors.
        }
        _ => {}
    }
    let a = vec[0]; //~ ERROR cannot move out
    //~| cannot move out of here
}

fn d() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [ //~ ERROR cannot move out
        //~^ cannot move out
         _b] => {}
        _ => {}
    }
    let a = vec[0]; //~ ERROR cannot move out
    //~| cannot move out of here
}

fn e() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
        //~| cannot move out
        _ => {}
    }
    let a = vec[0]; //~ ERROR cannot move out
    //~| cannot move out of here
}

fn main() {}
<commit_msg>Drive-by: Make assignment conflict tests in borrowck-vec-pattern-nesting.rs robust for NLL.<commit_after>// Copyright 2014 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.

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(slice_patterns)]

fn a() {
    let mut vec = [box 1, box 2, box 3];
    match vec {
        [box ref _a, _, _] => {
        //~^ borrow of `vec[..]` occurs here
            vec[0] = box 4; //~ ERROR cannot assign
            //~^ assignment to borrowed `vec[..]` occurs here
            _a.use_ref();
        }
    }
}

fn b() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [ref _b..] => {
        //~^ borrow of `vec[..]` occurs here
            vec[0] = box 4; //~ ERROR cannot assign
            //~^ assignment to borrowed `vec[..]` occurs here
            _b.use_ref();
        }
    }
}

fn c() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [_a, //~ ERROR cannot move out
            //~| cannot move out
            //~| to prevent move
            ..
        ] => {
            // Note: `_a` is *moved* here, but `b` is borrowing,
            // hence illegal.
            //
            // See comment in middle/borrowck/gather_loans/mod.rs
            // in the case covering these sorts of vectors.
        }
        _ => {}
    }
    let a = vec[0]; //~ ERROR cannot move out
    //~| cannot move out of here
}

fn d() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [ //~ ERROR cannot move out
        //~^ cannot move out
         _b] => {}
        _ => {}
    }
    let a = vec[0]; //~ ERROR cannot move out
    //~| cannot move out of here
}

fn e() {
    let mut vec = vec![box 1, box 2, box 3];
    let vec: &mut [Box<isize>] = &mut vec;
    match vec {
        &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
        //~| cannot move out
        _ => {}
    }
    let a = vec[0]; //~ ERROR cannot move out
    //~| cannot move out of here
}

fn main() {}

trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { }  }
impl<T> Fake for T { }
<|endoftext|>