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

use container::MutableSet;
use hashmap::HashSet;
use option::{Some, None, Option};
use vec::ImmutableVector;
use rt::rtio::EventLoop;

// Need to tell the linker on OS X to not barf on undefined symbols
// and instead look them up at runtime, which we need to resolve
// the crate_map properly.
#[cfg(target_os = "macos")]
#[link_args = "-Wl,-U,__rust_crate_map_toplevel"]
extern {}

pub struct ModEntry<'self> {
    name: &'self str,
    log_level: *mut u32
}

pub struct CrateMap<'self> {
    version: i32,
    entries: &'self [ModEntry<'self>],
    children: &'self [&'self CrateMap<'self>],
    event_loop_factory: Option<extern "C" fn() -> ~EventLoop>,
}

#[cfg(not(windows))]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    extern {
        #[crate_map]
        static CRATE_MAP: CrateMap<'static>;
    }

    let ptr: (*CrateMap) = &'static CRATE_MAP;
    if ptr.is_null() {
        return None;
    } else {
        return Some(&'static CRATE_MAP);
    }
}

#[cfg(windows)]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    use cast::transmute;
    use c_str::ToCStr;
    use unstable::dynamic_lib::dl;

    let sym = unsafe {
        let module = dl::open_internal();
        let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
            dl::symbol(module, buf)
        };
        dl::close(module);
        sym
    };
    let ptr: (*CrateMap) = sym as *CrateMap;
    if ptr.is_null() {
        return None;
    } else {
        unsafe {
            return Some(transmute(sym));
        }
    }
}

fn version(crate_map: &CrateMap) -> i32 {
    match crate_map.version {
        2 => return 2,
        _ => return 0
    }
}

fn do_iter_crate_map<'a>(
                     crate_map: &'a CrateMap<'a>,
                     f: |&ModEntry|,
                     visited: &mut HashSet<*CrateMap<'a>>) {
    if visited.insert(crate_map as *CrateMap) {
        match version(crate_map) {
            2 => {
                let (entries, children) = (crate_map.entries, crate_map.children);
                for entry in entries.iter() {
                    f(entry);
                }
                for child in children.iter() {
                    do_iter_crate_map(*child, |x| f(x), visited);
                }
            },
            _ => fail!("invalid crate map version")
        }
    }
}

/// Iterates recursively over `crate_map` and all child crate maps
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&ModEntry|) {
    // XXX: use random numbers as keys from the OS-level RNG when there is a nice
    //        way to do this
    let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
    do_iter_crate_map(crate_map, f, &mut v);
}

#[cfg(test)]
mod tests {
    use option::None;
    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};

    #[test]
    fn iter_crate_map_duplicates() {
        let mut level3: u32 = 3;

        let entries = [
            ModEntry { name: "c::m1", log_level: &mut level3},
        ];

        let child_crate = CrateMap {
            version: 2,
            entries: entries,
            children: [],
            event_loop_factory: None,
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [],
            children: [&child_crate, &child_crate],
            event_loop_factory: None,
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == 3);
                cnt += 1;
            }
            assert!(cnt == 1);
        }
    }

    #[test]
    fn iter_crate_map_follow_children() {
        let mut level2: u32 = 2;
        let mut level3: u32 = 3;
        let child_crate2 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "c::m1", log_level: &mut level2},
                ModEntry { name: "c::m2", log_level: &mut level3},
            ],
            children: [],
            event_loop_factory: None,
        };

        let child_crate1 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f1", log_level: &mut 1},
            ],
            children: [&child_crate2],
            event_loop_factory: None,
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f2", log_level: &mut 0},
            ],
            children: [&child_crate1],
            event_loop_factory: None,
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == cnt);
                cnt += 1;
            }
            assert!(cnt == 4);
        }
    }
}
<commit_msg>std::rt: Fix crate_map on Win64<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.

use container::MutableSet;
use hashmap::HashSet;
use option::{Some, None, Option};
use vec::ImmutableVector;
use rt::rtio::EventLoop;

// Need to tell the linker on OS X to not barf on undefined symbols
// and instead look them up at runtime, which we need to resolve
// the crate_map properly.
#[cfg(target_os = "macos")]
#[link_args = "-Wl,-U,__rust_crate_map_toplevel"]
extern {}

pub struct ModEntry<'self> {
    name: &'self str,
    log_level: *mut u32
}

pub struct CrateMap<'self> {
    version: i32,
    entries: &'self [ModEntry<'self>],
    children: &'self [&'self CrateMap<'self>],
    event_loop_factory: Option<extern "C" fn() -> ~EventLoop>,
}

#[cfg(not(windows))]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    extern {
        #[crate_map]
        static CRATE_MAP: CrateMap<'static>;
    }

    let ptr: (*CrateMap) = &'static CRATE_MAP;
    if ptr.is_null() {
        return None;
    } else {
        return Some(&'static CRATE_MAP);
    }
}

#[cfg(windows)]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
    use cast::transmute;
    use c_str::ToCStr;
    use unstable::dynamic_lib::dl;

    let sym = unsafe {
        let module = dl::open_internal();
        let rust_crate_map_toplevel = if cfg!(target_arch = "x86") {
            "__rust_crate_map_toplevel"
        } else {
            "_rust_crate_map_toplevel"
        };
        let sym = do rust_crate_map_toplevel.with_c_str |buf| {
            dl::symbol(module, buf)
        };
        dl::close(module);
        sym
    };
    let ptr: (*CrateMap) = sym as *CrateMap;
    if ptr.is_null() {
        return None;
    } else {
        unsafe {
            return Some(transmute(sym));
        }
    }
}

fn version(crate_map: &CrateMap) -> i32 {
    match crate_map.version {
        2 => return 2,
        _ => return 0
    }
}

fn do_iter_crate_map<'a>(
                     crate_map: &'a CrateMap<'a>,
                     f: |&ModEntry|,
                     visited: &mut HashSet<*CrateMap<'a>>) {
    if visited.insert(crate_map as *CrateMap) {
        match version(crate_map) {
            2 => {
                let (entries, children) = (crate_map.entries, crate_map.children);
                for entry in entries.iter() {
                    f(entry);
                }
                for child in children.iter() {
                    do_iter_crate_map(*child, |x| f(x), visited);
                }
            },
            _ => fail!("invalid crate map version")
        }
    }
}

/// Iterates recursively over `crate_map` and all child crate maps
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&ModEntry|) {
    // XXX: use random numbers as keys from the OS-level RNG when there is a nice
    //        way to do this
    let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
    do_iter_crate_map(crate_map, f, &mut v);
}

#[cfg(test)]
mod tests {
    use option::None;
    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};

    #[test]
    fn iter_crate_map_duplicates() {
        let mut level3: u32 = 3;

        let entries = [
            ModEntry { name: "c::m1", log_level: &mut level3},
        ];

        let child_crate = CrateMap {
            version: 2,
            entries: entries,
            children: [],
            event_loop_factory: None,
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [],
            children: [&child_crate, &child_crate],
            event_loop_factory: None,
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == 3);
                cnt += 1;
            }
            assert!(cnt == 1);
        }
    }

    #[test]
    fn iter_crate_map_follow_children() {
        let mut level2: u32 = 2;
        let mut level3: u32 = 3;
        let child_crate2 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "c::m1", log_level: &mut level2},
                ModEntry { name: "c::m2", log_level: &mut level3},
            ],
            children: [],
            event_loop_factory: None,
        };

        let child_crate1 = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f1", log_level: &mut 1},
            ],
            children: [&child_crate2],
            event_loop_factory: None,
        };

        let root_crate = CrateMap {
            version: 2,
            entries: [
                ModEntry { name: "t::f2", log_level: &mut 0},
            ],
            children: [&child_crate1],
            event_loop_factory: None,
        };

        let mut cnt = 0;
        unsafe {
            do iter_crate_map(&root_crate) |entry| {
                assert!(*entry.log_level == cnt);
                cnt += 1;
            }
            assert!(cnt == 4);
        }
    }
}
<|endoftext|>


<commit_before>extern crate sovrin;

#[macro_use]
extern crate lazy_static;

#[path = "utils/mod.rs"]
mod utils;

use sovrin::api::ErrorCode;
use sovrin::api::pool::{sovrin_create_pool_ledger_config, sovrin_open_pool_ledger};
#[path = "../src/utils/environment.rs"]
mod environment;
use environment::EnvironmentUtils;

use std::fs;

use std::ptr::null;

use utils::callbacks::CallbacksHelpers;

use std::sync::mpsc::{channel};
use std::ffi::{CString};

#[test]
fn sovrin_create_pool_ledger_can_be_called() {
    let (sender, receiver) = channel();

    let cb = Box::new(move |err| {
        sender.send(err).unwrap();
    });

    let (command_handle, callback) = CallbacksHelpers::closure_to_create_pool_ledger_cb(cb);

    let pool_name = CString::new("test_open").unwrap();
    let pool_config = CString::new("{\"genesis_txn\": \"./test_open_src.txn\"}").unwrap();
    std::fs::File::create("./test_open_src.txn").unwrap();

    let err = sovrin_create_pool_ledger_config(command_handle,
                                               pool_name.as_ptr(),
                                               pool_config.as_ptr(),
                                               callback);

    assert_eq!(ErrorCode::Success, err);

    let err = receiver.recv().unwrap();
    std::fs::remove_file("./test_open_src.txn").unwrap();
    std::fs::remove_dir_all(EnvironmentUtils::pool_path("test_open")).unwrap();
    assert_eq!(ErrorCode::Success, err);
}

#[test]
fn sovrin_open_pool_ledger_can_be_called() {
    let (sender, receiver) = channel();
    let sender2 = sender.clone();

    let cb = Box::new(move |err, _| {
        sender.send(err).unwrap();
    });
    let cb2 = Box::new(move |err, _| {
        sender2.send(err).unwrap();
    });

    let (command_handle, callback) = CallbacksHelpers::closure_to_open_pool_ledger_cb(cb);

    let pool_name: String = "test1".to_string();
    let c_pool_name = CString::new(pool_name.as_str()).unwrap();
    let mut path = environment::EnvironmentUtils::pool_path(pool_name.as_str());
    fs::create_dir_all(path.as_path()).unwrap();
    path.push(pool_name);
    path.set_extension("txn");
    fs::File::create(path.as_path()).unwrap();

    let err = sovrin_open_pool_ledger(command_handle,
                                      c_pool_name.as_ptr(),
                                      null(),
                                      callback);

    assert_eq!(ErrorCode::Success, err);
    let err = receiver.recv().unwrap();
    assert_eq!(ErrorCode::Success, err);

    //TODO separate test to check error after open the same pool multiply times
    let (command_handle, callback) = CallbacksHelpers::closure_to_open_pool_ledger_cb(cb2);
    let err = sovrin_open_pool_ledger(command_handle,
                                      c_pool_name.as_ptr(),
                                      null(),
                                      callback);

    assert_eq!(ErrorCode::Success, err);
    let err = receiver.recv().unwrap();
    assert_eq!(ErrorCode::PoolLedgerInvalidPoolHandle, err);
}
<commit_msg>Add timeout for receiving in integration tests.<commit_after>extern crate sovrin;

#[macro_use]
extern crate lazy_static;

#[path = "utils/mod.rs"]
mod utils;

use sovrin::api::ErrorCode;
use sovrin::api::pool::{sovrin_create_pool_ledger_config, sovrin_open_pool_ledger};
#[path = "../src/utils/environment.rs"]
mod environment;
use environment::EnvironmentUtils;

use std::fs;

use std::ptr::null;

use std::time::Duration;

use utils::callbacks::CallbacksHelpers;

use std::sync::mpsc::{channel};
use std::ffi::{CString};

#[test]
fn sovrin_create_pool_ledger_can_be_called() {
    let (sender, receiver) = channel();

    let cb = Box::new(move |err| {
        sender.send(err).unwrap();
    });

    let (command_handle, callback) = CallbacksHelpers::closure_to_create_pool_ledger_cb(cb);

    let pool_name = CString::new("test_open").unwrap();
    let pool_config = CString::new("{\"genesis_txn\": \"./test_open_src.txn\"}").unwrap();
    std::fs::File::create("./test_open_src.txn").unwrap();

    let err = sovrin_create_pool_ledger_config(command_handle,
                                               pool_name.as_ptr(),
                                               pool_config.as_ptr(),
                                               callback);

    assert_eq!(ErrorCode::Success, err);

    let err = receiver.recv_timeout(Duration::from_secs(1)).unwrap();
    std::fs::remove_file("./test_open_src.txn").unwrap();
    std::fs::remove_dir_all(EnvironmentUtils::pool_path("test_open")).unwrap();
    assert_eq!(ErrorCode::Success, err);
}

#[test]
fn sovrin_open_pool_ledger_can_be_called() {
    let (sender, receiver) = channel();
    let sender2 = sender.clone();

    let cb = Box::new(move |err, _| {
        sender.send(err).unwrap();
    });
    let cb2 = Box::new(move |err, _| {
        sender2.send(err).unwrap();
    });

    let (command_handle, callback) = CallbacksHelpers::closure_to_open_pool_ledger_cb(cb);

    let pool_name: String = "test1".to_string();
    let c_pool_name = CString::new(pool_name.as_str()).unwrap();
    let mut path = environment::EnvironmentUtils::pool_path(pool_name.as_str());
    fs::create_dir_all(path.as_path()).unwrap();
    path.push(pool_name);
    path.set_extension("txn");
    fs::File::create(path.as_path()).unwrap();

    let err = sovrin_open_pool_ledger(command_handle,
                                      c_pool_name.as_ptr(),
                                      null(),
                                      callback);

    assert_eq!(ErrorCode::Success, err);
    let err = receiver.recv_timeout(Duration::from_secs(1)).unwrap();
    assert_eq!(ErrorCode::Success, err);

    //TODO separate test to check error after open the same pool multiply times
    let (command_handle, callback) = CallbacksHelpers::closure_to_open_pool_ledger_cb(cb2);
    let err = sovrin_open_pool_ledger(command_handle,
                                      c_pool_name.as_ptr(),
                                      null(),
                                      callback);

    assert_eq!(ErrorCode::Success, err);
    let err = receiver.recv_timeout(Duration::from_secs(1)).unwrap();
    assert_eq!(ErrorCode::PoolLedgerInvalidPoolHandle, err);
}
<|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.

extern mod std;
use std::oldmap;
use std::treemap::TreeMap;
use core::hashmap::linear::*;
use core::io::WriterUtil;

struct Results {
    sequential_ints: float,
    random_ints: float,
    delete_ints: float,

    sequential_strings: float,
    random_strings: float,
    delete_strings: float
}

fn timed(result: &mut float,
         op: &fn()) {
    let start = std::time::precise_time_s();
    op();
    let end = std::time::precise_time_s();
    *result = (end - start);
}

fn old_int_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) {

    {
        let map = oldmap::HashMap();
        do timed(&mut results.sequential_ints) {
            for uint::range(0, num_keys) |i| {
                map.insert(i, i+1);
            }

            for uint::range(0, num_keys) |i| {
                fail_unless!(map.get(&i) == i+1);
            }
        }
    }

    {
        let map = oldmap::HashMap();
        do timed(&mut results.random_ints) {
            for uint::range(0, num_keys) |i| {
                map.insert(rng.next() as uint, i);
            }
        }
    }

    {
        let map = oldmap::HashMap();
        for uint::range(0, num_keys) |i| {
            map.insert(i, i);;
        }

        do timed(&mut results.delete_ints) {
            for uint::range(0, num_keys) |i| {
                fail_unless!(map.remove(&i));
            }
        }
    }
}

fn old_str_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) {
    {
        let map = oldmap::HashMap();
        do timed(&mut results.sequential_strings) {
            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(i);
                map.insert(s, i);
            }

            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(i);
                fail_unless!(map.get(&s) == i);
            }
        }
    }

    {
        let map = oldmap::HashMap();
        do timed(&mut results.random_strings) {
            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(rng.next() as uint);
                map.insert(s, i);
            }
        }
    }

    {
        let map = oldmap::HashMap();
        for uint::range(0, num_keys) |i| {
            map.insert(uint::to_str(i), i);
        }
        do timed(&mut results.delete_strings) {
            for uint::range(0, num_keys) |i| {
                fail_unless!(map.remove(&uint::to_str(i)));
            }
        }
    }
}

fn linear_int_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) {
    {
        let mut map = LinearMap::new();
        do timed(&mut results.sequential_ints) {
            for uint::range(0, num_keys) |i| {
                map.insert(i, i+1);
            }

            for uint::range(0, num_keys) |i| {
                fail_unless!(map.find(&i).unwrap() == &(i+1));
            }
        }
    }

    {
        let mut map = LinearMap::new();
        do timed(&mut results.random_ints) {
            for uint::range(0, num_keys) |i| {
                map.insert(rng.next() as uint, i);
            }
        }
    }

    {
        let mut map = LinearMap::new();
        for uint::range(0, num_keys) |i| {
            map.insert(i, i);;
        }

        do timed(&mut results.delete_ints) {
            for uint::range(0, num_keys) |i| {
                fail_unless!(map.remove(&i));
            }
        }
    }
}

fn linear_str_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) {
    {
        let mut map = LinearMap::new();
        do timed(&mut results.sequential_strings) {
            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(i);
                map.insert(s, i);
            }

            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(i);
                fail_unless!(map.find(&s).unwrap() == &i);
            }
        }
    }

    {
        let mut map = LinearMap::new();
        do timed(&mut results.random_strings) {
            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(rng.next() as uint);
                map.insert(s, i);
            }
        }
    }

    {
        let mut map = LinearMap::new();
        for uint::range(0, num_keys) |i| {
            map.insert(uint::to_str(i), i);
        }
        do timed(&mut results.delete_strings) {
            for uint::range(0, num_keys) |i| {
                fail_unless!(map.remove(&uint::to_str(i)));
            }
        }
    }
}

fn tree_int_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) {
    {
        let mut map = TreeMap::new();
        do timed(&mut results.sequential_ints) {
            for uint::range(0, num_keys) |i| {
                map.insert(i, i+1);
            }

            for uint::range(0, num_keys) |i| {
                fail_unless!(map.find(&i).unwrap() == &(i+1));
            }
        }
    }

    {
        let mut map = TreeMap::new();
        do timed(&mut results.random_ints) {
            for uint::range(0, num_keys) |i| {
                map.insert(rng.next() as uint, i);
            }
        }
    }

    {
        let mut map = TreeMap::new();
        for uint::range(0, num_keys) |i| {
            map.insert(i, i);;
        }

        do timed(&mut results.delete_ints) {
            for uint::range(0, num_keys) |i| {
                fail_unless!(map.remove(&i));
            }
        }
    }
}

fn tree_str_benchmarks(rng: @rand::Rng, num_keys: uint, results: &mut Results) {
    {
        let mut map = TreeMap::new();
        do timed(&mut results.sequential_strings) {
            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(i);
                map.insert(s, i);
            }

            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(i);
                fail_unless!(map.find(&s).unwrap() == &i);
            }
        }
    }

    {
        let mut map = TreeMap::new();
        do timed(&mut results.random_strings) {
            for uint::range(0, num_keys) |i| {
                let s = uint::to_str(rng.next() as uint);
                map.insert(s, i);
            }
        }
    }

    {
        let mut map = TreeMap::new();
        for uint::range(0, num_keys) |i| {
            map.insert(uint::to_str(i), i);
        }
        do timed(&mut results.delete_strings) {
            for uint::range(0, num_keys) |i| {
                fail_unless!(map.remove(&uint::to_str(i)));
            }
        }
    }
}

fn write_header(header: &str) {
    io::stdout().write_str(header);
    io::stdout().write_str("\n");
}

fn write_row(label: &str, value: float) {
    io::stdout().write_str(fmt!("%30s %f s\n", label, value));
}

fn write_results(label: &str, results: &Results) {
    write_header(label);
    write_row("sequential_ints", results.sequential_ints);
    write_row("random_ints", results.random_ints);
    write_row("delete_ints", results.delete_ints);
    write_row("sequential_strings", results.sequential_strings);
    write_row("random_strings", results.random_strings);
    write_row("delete_strings", results.delete_strings);
}

fn empty_results() -> Results {
    Results {
        sequential_ints: 0f,
        random_ints: 0f,
        delete_ints: 0f,

        sequential_strings: 0f,
        random_strings: 0f,
        delete_strings: 0f,
    }
}

fn main() {
    let args = os::args();
    let num_keys = {
        if args.len() == 2 {
            uint::from_str(args[1]).get()
        } else {
            100 // woefully inadequate for any real measurement
        }
    };

    let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    {
        let rng = rand::seeded_rng(seed);
        let mut results = empty_results();
        old_int_benchmarks(rng, num_keys, &mut results);
        old_str_benchmarks(rng, num_keys, &mut results);
        write_results("std::oldmap::HashMap", &results);
    }

    {
        let rng = rand::seeded_rng(seed);
        let mut results = empty_results();
        linear_int_benchmarks(rng, num_keys, &mut results);
        linear_str_benchmarks(rng, num_keys, &mut results);
        write_results("core::hashmap::linear::LinearMap", &results);
    }

    {
        let rng = rand::seeded_rng(seed);
        let mut results = empty_results();
        tree_int_benchmarks(rng, num_keys, &mut results);
        tree_str_benchmarks(rng, num_keys, &mut results);
        write_results("std::treemap::TreeMap", &results);
    }
}
<commit_msg>replace the core-map benchmark<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.

extern mod std;

use core::io;
use std::time;
use std::treemap::TreeMap;
use core::hashmap::linear::{LinearMap, LinearSet};
use core::trie::TrieMap;

fn timed(label: &str, f: &fn()) {
    let start = time::precise_time_s();
    f();
    let end = time::precise_time_s();
    io::println(fmt!("  %s: %f", label, end - start));
}

fn ascending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
    io::println(" Ascending integers:");

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(i, i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&i).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&i));
        }
    }
}

fn descending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
    io::println(" Descending integers:");

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(i, i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&i).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&i));
        }
    }
}

fn vector<M: Map<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(dist[i], i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&dist[i]).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&dist[i]));
        }
    }
}

fn main() {
    let args = os::args();
    let n_keys = {
        if args.len() == 2 {
            uint::from_str(args[1]).get()
        } else {
            1000000
        }
    };

    let mut rand = vec::with_capacity(n_keys);

    {
        let rng = core::rand::seeded_rng([1, 1, 1, 1, 1, 1, 1]);
        let mut set = LinearSet::new();
        while set.len() != n_keys {
            let next = rng.next() as uint;
            if set.insert(next) {
                rand.push(next);
            }
        }
    }

    io::println(fmt!("%? keys", n_keys));

    io::println("\nTreeMap:");

    {
        let mut map = TreeMap::new::<uint, uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = TreeMap::new::<uint, uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = TreeMap::new::<uint, uint>();
        vector(&mut map, n_keys, rand);
    }

    io::println("\nLinearMap:");

    {
        let mut map = LinearMap::new::<uint, uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = LinearMap::new::<uint, uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = LinearMap::new::<uint, uint>();
        vector(&mut map, n_keys, rand);
    }

    io::println("\nTrieMap:");

    {
        let mut map = TrieMap::new::<uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = TrieMap::new::<uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = TrieMap::new::<uint>();
        vector(&mut map, n_keys, rand);
    }
}
<|endoftext|>


<commit_before>//! "Weighted" graph types

use std;
use std::ops::{Deref,DerefMut};

use smallvec::SmallVec;

use super::interface::{self, Id};

/// Trait bounds for types used as edge and node data payloads.
pub trait Data: Clone {}
impl<T> Data for T where T: Clone {}

// ----------------------------------------------------------------
// Edge

/// Weighted edge type.
#[derive(Clone,Debug)]
pub struct Edge<T: Data, I: Id> {
    source: I,
    target: I,
    data: T
}

impl<T, I> interface::Edge for Edge<T, I>
    where I: Id,
          T: Data {
    type NodeId = I;
    #[inline]
    fn endpoints(&self) -> (Self::NodeId, Self::NodeId) {
        (self.source, self.target)
    }
}

impl<T, I> interface::DirectedEdge for Edge<T, I>
    where I: Id,
          T: Data {
    #[inline]
    fn source(&self) -> I { self.source }

    #[inline]
    fn target(&self) -> I { self.target }
}

impl<T: Data, I: Id> Edge<T, I> {
    /// Create an edge with the given source & target node indices and
    /// weight data.
    pub fn new(source: I, target: I, data: T) -> Self {
        Edge{source: source, target: target, data: data}
    }
}

impl<T: Data, I: Id> Deref for Edge<T, I> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

impl<T: Data, I: Id> DerefMut for Edge<T, I> {
    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
        &mut self.data
    }
}

impl<T: Data, I: Id, I2: Copy> From<(I2, I2)> for Edge<T, I>
    where T: Default, I: From<I2> {
    fn from(u: (I2, I2)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), Default::default())
    }
}

impl<T: Data, I: Id, I2: Copy> From<(I2, I2, T)> for Edge<T, I>
    where I: From<I2> {
    fn from(u: (I2, I2, T)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), u.2)
    }
}

impl<'a, T: Data, I: Id, I2: Copy> From<&'a (I2, I2)> for Edge<T, I>
    where T: Default, I: From<I2> {
    fn from(u: &'a (I2, I2)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), Default::default())
    }
}
impl<'a, T: Data, I: Id, I2: Copy> From<&'a (I2, I2, T)> for Edge<T, I>
    where T: Clone, I: From<I2> {
    fn from(u: &'a (I2, I2, T)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), u.2.clone())
    }
}

// ----------------------------------------------------------------
// Node

///  Weighted node implementation.
///
/// A reference to the node's weight data can be obtained using the type's
/// `Deref` implementation.
///
/// ```rust
/// use cripes::util::graph::{EdgeIndex,WeightedNode};
///
/// # fn main() {
/// let n = WeightedNode::<_, EdgeIndex<u8>>::new(32);
/// assert_eq!(32, *n);
/// # }
/// ```

#[derive(Clone,Debug)]
pub struct Node<T: Data, I: Id> {
    incoming_edges: SmallVec<[I; 8]>,
    outgoing_edges: SmallVec<[I; 8]>,
    data: T
}

impl<T: Data, I: Id> Node<T, I> {
    /// Instantiate a node with the given data.
    pub fn new(data: T) -> Self {
        Node{incoming_edges: SmallVec::new(), outgoing_edges: SmallVec::new(), data: data}
    }
}

impl<T: Data, I: Id> Deref for Node<T, I> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

impl<T: Data, I: Id> DerefMut for Node<T, I> {
    #[inline]
    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
        &mut self.data
    }
}

impl<T: Data, I: Id> From<T> for Node<T, I> {
    #[inline]
    fn from(data: T) -> Self {
        Self::new(data)
    }
}

impl<T, I> interface::Node for Node<T, I>
    where T: Data, I: Id {
    type EdgeId = I;
    fn edges(&self) -> std::iter::Chain<std::slice::Iter<Self::EdgeId>,std::slice::Iter<Self::EdgeId>> {
        self.incoming_edges.iter().chain(self.outgoing_edges.iter())
    }
}

impl<T, I> interface::DirectedNode for Node<T, I>
    where T: Data, I: Id {
    impl_basic_node!(I);
}
<commit_msg>util/graph/weighted: add `.data()` observers on `Edge` and `Node`<commit_after>//! "Weighted" graph types

use std;
use std::ops::{Deref,DerefMut};

use smallvec::SmallVec;

use super::interface::{self, Id};

/// Trait bounds for types used as edge and node data payloads.
pub trait Data: Clone {}
impl<T> Data for T where T: Clone {}

// ----------------------------------------------------------------
// Edge

/// Weighted edge type.
#[derive(Clone,Debug)]
pub struct Edge<T: Data, I: Id> {
    source: I,
    target: I,
    data: T
}

impl<T, I> interface::Edge for Edge<T, I>
    where I: Id,
          T: Data {
    type NodeId = I;
    #[inline]
    fn endpoints(&self) -> (Self::NodeId, Self::NodeId) {
        (self.source, self.target)
    }
}

impl<T, I> interface::DirectedEdge for Edge<T, I>
    where I: Id,
          T: Data {
    #[inline]
    fn source(&self) -> I { self.source }

    #[inline]
    fn target(&self) -> I { self.target }
}

impl<T: Data, I: Id> Edge<T, I> {
    /// Create an edge with the given source & target node indices and
    /// weight data.
    pub fn new(source: I, target: I, data: T) -> Self {
        Edge{source: source, target: target, data: data}
    }

    /// Retrieve a reference to the edge's data (weight)
    pub fn data(&self) -> &T {
        &self.data
    }
}

impl<T: Data, I: Id> Deref for Edge<T, I> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

impl<T: Data, I: Id> DerefMut for Edge<T, I> {
    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
        &mut self.data
    }
}

impl<T: Data, I: Id, I2: Copy> From<(I2, I2)> for Edge<T, I>
    where T: Default, I: From<I2> {
    fn from(u: (I2, I2)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), Default::default())
    }
}

impl<T: Data, I: Id, I2: Copy> From<(I2, I2, T)> for Edge<T, I>
    where I: From<I2> {
    fn from(u: (I2, I2, T)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), u.2)
    }
}

impl<'a, T: Data, I: Id, I2: Copy> From<&'a (I2, I2)> for Edge<T, I>
    where T: Default, I: From<I2> {
    fn from(u: &'a (I2, I2)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), Default::default())
    }
}
impl<'a, T: Data, I: Id, I2: Copy> From<&'a (I2, I2, T)> for Edge<T, I>
    where T: Clone, I: From<I2> {
    fn from(u: &'a (I2, I2, T)) -> Self {
        Self::new(I::from(u.0), I::from(u.1), u.2.clone())
    }
}

// ----------------------------------------------------------------
// Node

///  Weighted node implementation.
///
/// A reference to the node's weight data can be obtained using the type's
/// `Deref` implementation.
///
/// ```rust
/// use cripes::util::graph::{EdgeIndex,WeightedNode};
///
/// # fn main() {
/// let n = WeightedNode::<_, EdgeIndex<u8>>::new(32);
/// assert_eq!(32, *n);
/// # }
/// ```

#[derive(Clone,Debug)]
pub struct Node<T: Data, I: Id> {
    incoming_edges: SmallVec<[I; 8]>,
    outgoing_edges: SmallVec<[I; 8]>,
    data: T
}

impl<T: Data, I: Id> Node<T, I> {
    /// Instantiate a node with the given data.
    pub fn new(data: T) -> Self {
        Node{incoming_edges: SmallVec::new(), outgoing_edges: SmallVec::new(), data: data}
    }

    /// Retrieve a reference to the nodes's data (weight)
    pub fn data(&self) -> &T {
        &self.data
    }
}

impl<T: Data, I: Id> Deref for Node<T, I> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

impl<T: Data, I: Id> DerefMut for Node<T, I> {
    #[inline]
    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
        &mut self.data
    }
}

impl<T: Data, I: Id> From<T> for Node<T, I> {
    #[inline]
    fn from(data: T) -> Self {
        Self::new(data)
    }
}

impl<T, I> interface::Node for Node<T, I>
    where T: Data, I: Id {
    type EdgeId = I;
    fn edges(&self) -> std::iter::Chain<std::slice::Iter<Self::EdgeId>,std::slice::Iter<Self::EdgeId>> {
        self.incoming_edges.iter().chain(self.outgoing_edges.iter())
    }
}

impl<T, I> interface::DirectedNode for Node<T, I>
    where T: Data, I: Id {
    impl_basic_node!(I);
}
<|endoftext|>


<commit_before>mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "9d78d1d02761b906038ba4d54c5f3427f920f5fb";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO
    "src/test/ui/const-generics/argument_order.rs",
    "src/test/ui/const-generics/closing-args-token.rs",
    "src/test/ui/const-generics/const-param-before-other-params.rs",
    "src/test/ui/const-generics/defaults/intermixed-lifetime.rs",
    "src/test/ui/inline-const/const-expr-array-init.rs",
    "src/test/ui/inline-const/const-expr-basic.rs",
    "src/test/ui/inline-const/const-expr-reference.rs",
    "src/test/ui/inline-const/const-match-pat-range.rs",
    "src/test/ui/inline-const/const-match-pat.rs",
    "src/test/ui/proc-macro/unsafe-foreign-mod.rs",
    "src/test/ui/proc-macro/unsafe-mod.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/issues/auxiliary/issue-21146-inc.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<commit_msg>Categorize new test exclusions<commit_after>mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "9d78d1d02761b906038ba4d54c5f3427f920f5fb";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: const parameter before lifetime parameter
    "src/test/ui/const-generics/argument_order.rs",
    "src/test/ui/const-generics/const-param-before-other-params.rs",
    "src/test/ui/const-generics/defaults/intermixed-lifetime.rs",

    // TODO: const block
    "src/test/ui/inline-const/const-expr-array-init.rs",
    "src/test/ui/inline-const/const-expr-basic.rs",
    "src/test/ui/inline-const/const-expr-reference.rs",
    "src/test/ui/inline-const/const-match-pat-range.rs",
    "src/test/ui/inline-const/const-match-pat.rs",

    // TODO: unsafe extern blocks
    "src/test/ui/proc-macro/unsafe-foreign-mod.rs",

    // TODO: unsafe modules
    "src/test/ui/proc-macro/unsafe-mod.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/closing-args-token.rs",
    "src/test/ui/const-generics/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/issues/auxiliary/issue-21146-inc.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<|endoftext|>


<commit_before>#![allow(clippy::manual_assert)]

mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "98ad6a5519651af36e246c0335c964dd52c554ba";

#[rustfmt::skip]
static EXCLUDE_FILES: &[&str] = &[
    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Need at least one trait in impl Trait, no such type as impl 'static
    "src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Various extensions to Rust syntax made up by rust-analyzer
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0015_use_tree.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0029_range_forms.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0068_item_modifiers.rs",
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs",
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs",
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs",

    // Placeholder syntax for "throw expressions"
    "src/test/pretty/yeet-expr.rs",
    "src/test/ui/try-trait/yeet-for-option.rs",
    "src/test/ui/try-trait/yeet-for-result.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing tools on invalid syntax
    "src/test/run-make/translation/test.rs",
    "src/test/ui/generics/issue-94432-garbage-ice.rs",
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Generated file containing a top-level expression, used with `include!`
    "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",

    // Clippy lint lists represented as expressions
    "src/tools/clippy/clippy_lints/src/lib.deprecated.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_all.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_cargo.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_complexity.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_correctness.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_internal.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_lints.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_nursery.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_perf.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_restriction.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_style.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs",

    // Not actually test cases
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/macros/include-single-expr-helper.rs",
    "src/test/ui/macros/include-single-expr-helper-1.rs",
    "src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs",
];

#[rustfmt::skip]
static EXCLUDE_DIRS: &[&str] = &[
    // Inputs that intentionally do not parse
    "src/tools/rust-analyzer/crates/parser/test_data/parser/err",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err",

    // Inputs that lex but do not necessarily parse
    "src/tools/rust-analyzer/crates/parser/test_data/lexer",

    // Inputs that used to crash rust-analyzer, but aren't necessarily supposed to parse
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/fuzz-failures",
    "src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path_string = if path_string == "tests/rust" {
        return true;
    } else if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.is_dir() {
        return !EXCLUDE_DIRS.contains(&path_string);
    }

    if path.extension().map_or(true, |e| e != "rs") {
        return false;
    }

    if path_string.starts_with("src/test/ui") || path_string.starts_with("src/test/rustdoc-ui") {
        let stderr_path = path.with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE_FILES.contains(&path_string)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE_FILES {
        if !test_src.join(exclude).is_file() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    for exclude in EXCLUDE_DIRS {
        if !test_src.join(exclude).is_dir() {
            missing += "\ntests/rust/";
            missing += exclude;
            missing += "/";
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<commit_msg>Resolve needless_borrow pedantic clippy lint<commit_after>#![allow(clippy::manual_assert)]

mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "98ad6a5519651af36e246c0335c964dd52c554ba";

#[rustfmt::skip]
static EXCLUDE_FILES: &[&str] = &[
    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Need at least one trait in impl Trait, no such type as impl 'static
    "src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Various extensions to Rust syntax made up by rust-analyzer
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0015_use_tree.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0029_range_forms.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0068_item_modifiers.rs",
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs",
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs",
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs",

    // Placeholder syntax for "throw expressions"
    "src/test/pretty/yeet-expr.rs",
    "src/test/ui/try-trait/yeet-for-option.rs",
    "src/test/ui/try-trait/yeet-for-result.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing tools on invalid syntax
    "src/test/run-make/translation/test.rs",
    "src/test/ui/generics/issue-94432-garbage-ice.rs",
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Generated file containing a top-level expression, used with `include!`
    "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",

    // Clippy lint lists represented as expressions
    "src/tools/clippy/clippy_lints/src/lib.deprecated.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_all.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_cargo.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_complexity.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_correctness.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_internal.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_lints.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_nursery.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_perf.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_restriction.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_style.rs",
    "src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs",

    // Not actually test cases
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/macros/include-single-expr-helper.rs",
    "src/test/ui/macros/include-single-expr-helper-1.rs",
    "src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs",
];

#[rustfmt::skip]
static EXCLUDE_DIRS: &[&str] = &[
    // Inputs that intentionally do not parse
    "src/tools/rust-analyzer/crates/parser/test_data/parser/err",
    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err",

    // Inputs that lex but do not necessarily parse
    "src/tools/rust-analyzer/crates/parser/test_data/lexer",

    // Inputs that used to crash rust-analyzer, but aren't necessarily supposed to parse
    "src/tools/rust-analyzer/crates/syntax/test_data/parser/fuzz-failures",
    "src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path_string = if path_string == "tests/rust" {
        return true;
    } else if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.is_dir() {
        return !EXCLUDE_DIRS.contains(&path_string);
    }

    if path.extension().map_or(true, |e| e != "rs") {
        return false;
    }

    if path_string.starts_with("src/test/ui") || path_string.starts_with("src/test/rustdoc-ui") {
        let stderr_path = path.with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE_FILES.contains(&path_string)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE_FILES {
        if !test_src.join(exclude).is_file() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    for exclude in EXCLUDE_DIRS {
        if !test_src.join(exclude).is_dir() {
            missing += "\ntests/rust/";
            missing += exclude;
            missing += "/";
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<|endoftext|>


<commit_before>mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "50171c310cd15e1b2d3723766ce64e2e4d6696fc";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: anonymous structs/unions
    // type A = struct { field: u8 };
    // https://github.com/dtolnay/syn/issues/1049
    "src/test/pretty/anonymous-types.rs",

    // TODO: destructuring assignment of tuple variant
    // let <E>::V {} = E::V();
    "src/test/ui/associated-types/associated-type-destructuring-assignment.rs",
    "src/test/ui/associated-types/associated-type-struct-construction.rs",

    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // TODO: ~const in where-clause
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs",

    // TODO: precedence of attribute on assignment stmt
    "src/tools/rustfmt/tests/source/attrib.rs",
    "src/tools/rustfmt/tests/target/attrib.rs",

    // TODO: doc comment on match arm
    "src/tools/rustfmt/tests/source/match.rs",
    "src/tools/rustfmt/tests/target/match.rs",

    // TODO: inner attribute inside block
    "src/tools/rustfmt/tests/target/attrib-block-expr.rs",

    // Rustc loses some attributes
    // https://github.com/rust-lang/rust/issues/84879
    "src/test/ui/proc-macro/issue-81555.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<commit_msg>Distinguish the two failures involving qualified braced variant<commit_after>mod progress;

use self::progress::Progress;
use anyhow::Result;
use flate2::read::GzDecoder;
use std::fs;
use std::path::Path;
use tar::Archive;
use walkdir::DirEntry;

const REVISION: &str = "50171c310cd15e1b2d3723766ce64e2e4d6696fc";

#[rustfmt::skip]
static EXCLUDE: &[&str] = &[
    // TODO: anonymous structs/unions
    // type A = struct { field: u8 };
    // https://github.com/dtolnay/syn/issues/1049
    "src/test/pretty/anonymous-types.rs",

    // TODO: qualified braced variant in expression position
    // let _ = <E>::V {};
    "src/test/ui/associated-types/associated-type-destructuring-assignment.rs",

    // TODO: qualified braced variant in pattern position
    // let <E>::V {} = e;
    "src/test/ui/associated-types/associated-type-struct-construction.rs",

    // TODO: impl ~const T {}
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/syntax.rs",

    // TODO: ~const in where-clause
    // https://github.com/dtolnay/syn/issues/1051
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-run.rs",
    "src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs",

    // TODO: precedence of attribute on assignment stmt
    "src/tools/rustfmt/tests/source/attrib.rs",
    "src/tools/rustfmt/tests/target/attrib.rs",

    // TODO: doc comment on match arm
    "src/tools/rustfmt/tests/source/match.rs",
    "src/tools/rustfmt/tests/target/match.rs",

    // TODO: inner attribute inside block
    "src/tools/rustfmt/tests/target/attrib-block-expr.rs",

    // Rustc loses some attributes
    // https://github.com/rust-lang/rust/issues/84879
    "src/test/ui/proc-macro/issue-81555.rs",

    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
    "src/test/ui/const-generics/early/closing-args-token.rs",
    "src/test/ui/const-generics/early/const-expression-parameter.rs",

    // Deprecated anonymous parameter syntax in traits
    "src/test/ui/issues/issue-13105.rs",
    "src/test/ui/issues/issue-13775.rs",
    "src/test/ui/issues/issue-34074.rs",
    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
    "src/tools/rustfmt/tests/source/trait.rs",
    "src/tools/rustfmt/tests/target/trait.rs",

    // Excessive nesting
    "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs",

    // Testing rustfmt on invalid syntax
    "src/tools/rustfmt/tests/coverage/target/comments.rs",
    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
    "src/tools/rustfmt/tests/parser/issue_4418.rs",
    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/source/type.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
    "src/tools/rustfmt/tests/target/type.rs",

    // Not actually test cases
    "src/test/rustdoc-ui/test-compile-fail2.rs",
    "src/test/rustdoc-ui/test-compile-fail3.rs",
    "src/test/ui/include-single-expr-helper.rs",
    "src/test/ui/include-single-expr-helper-1.rs",
    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
    "src/test/ui/lint/expansion-time-include.rs",
    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
    "src/test/ui/parser/auxiliary/issue-21146-inc.rs",
];

pub fn base_dir_filter(entry: &DirEntry) -> bool {
    let path = entry.path();
    if path.is_dir() {
        return true; // otherwise walkdir does not visit the files
    }
    if path.extension().map(|e| e != "rs").unwrap_or(true) {
        return false;
    }

    let mut path_string = path.to_string_lossy();
    if cfg!(windows) {
        path_string = path_string.replace('\\', "/").into();
    }
    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
        path
    } else {
        panic!("unexpected path in Rust dist: {}", path_string);
    };

    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
        return false;
    }

    if path.starts_with("src/test/ui") {
        let stderr_path = entry.path().with_extension("stderr");
        if stderr_path.exists() {
            // Expected to fail in some way
            return false;
        }
    }

    !EXCLUDE.contains(&path)
}

#[allow(dead_code)]
pub fn edition(path: &Path) -> &'static str {
    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
        "2015"
    } else {
        "2018"
    }
}

pub fn clone_rust() {
    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
        Err(_) => true,
        Ok(contents) => contents.trim() != REVISION,
    };
    if needs_clone {
        download_and_unpack().unwrap();
    }
    let mut missing = String::new();
    let test_src = Path::new("tests/rust");
    for exclude in EXCLUDE {
        if !test_src.join(exclude).exists() {
            missing += "\ntests/rust/";
            missing += exclude;
        }
    }
    if !missing.is_empty() {
        panic!("excluded test file does not exist:{}\n", missing);
    }
}

fn download_and_unpack() -> Result<()> {
    let url = format!(
        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
        REVISION
    );
    let response = reqwest::blocking::get(&url)?.error_for_status()?;
    let progress = Progress::new(response);
    let decoder = GzDecoder::new(progress);
    let mut archive = Archive::new(decoder);
    let prefix = format!("rust-{}", REVISION);

    let tests_rust = Path::new("tests/rust");
    if tests_rust.exists() {
        fs::remove_dir_all(tests_rust)?;
    }

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path = entry.path()?;
        if path == Path::new("pax_global_header") {
            continue;
        }
        let relative = path.strip_prefix(&prefix)?;
        let out = tests_rust.join(relative);
        entry.unpack(&out)?;
    }

    fs::write("tests/rust/COMMIT", REVISION)?;
    Ok(())
}
<|endoftext|>


<commit_before>use bbggez::ggez::{
	event::EventHandler,
	event::{KeyCode, KeyMods},
	graphics,
	nalgebra::{Point2, Vector2},
	timer, Context, GameResult,
};
use bbggez::{rand, rand::prelude::*};

pub struct Game {
	location: Vector2<f32>,
	rotation: f32,
}

impl Game {
	pub fn new(context: &mut Context) -> Game {
		let (arena_width, arena_height) = graphics::drawable_size(context);

		Game {
			location: Vector2::new(arena_width / 2.0, arena_height / 2.0),
			rotation: 0.0,
		}
	}

	fn handle_window_size_change(
		&self,
		context: &mut Context,
		(width, height): (f32, f32),
	) -> GameResult<()> {
		graphics::set_screen_coordinates(context, graphics::Rect::new(0.0, 0.0, width, height))
	}
}

impl EventHandler for Game {
	fn update(&mut self, context: &mut Context) -> GameResult<()> {
		let delta_time = timer::delta(context).as_secs_f32();
		let arena_size = graphics::drawable_size(context);
		self.handle_window_size_change(context, arena_size)?;

		Ok(())
	}

	fn draw(&mut self, context: &mut Context) -> GameResult<()> {
		graphics::clear(context, graphics::BLACK);

		let ship = graphics::MeshBuilder::new()
			.polyline(
				graphics::DrawMode::fill(),
				&[
					Point2::new(-7.0, -5.0),
					Point2::new(10.0, 0.0),
					Point2::new(-7.0, 5.0),
				],
				graphics::WHITE,
			)?
			.build(context)?;

		graphics::draw(
			context,
			&ship,
			graphics::DrawParam::new()
				.dest(Point2::from(self.location))
				.rotation(self.rotation),
		)?;

		graphics::present(context)
	}

	fn key_down_event(
		&mut self,
		context: &mut Context,
		keycode: KeyCode,
		_keymods: KeyMods,
		_repeat: bool,
	) {
		let delta_time = timer::delta(context).as_secs_f32();

		match keycode {
			KeyCode::Left => self.rotation += -50.0 * delta_time,
			KeyCode::Right => self.rotation += 50.0 * delta_time,
			_ => (),
		}
	}
}
<commit_msg>Created an asteroids ship<commit_after>use bbggez::ggez::{
	event::EventHandler,
	event::{KeyCode, KeyMods},
	graphics,
	nalgebra::{Point2, Vector2},
	timer, Context, GameResult,
};
use bbggez::{rand, rand::prelude::*};

pub struct Game {
	location: Vector2<f32>,
	rotation: f32,
	velocity: Vector2<f32>,
}

impl Game {
	pub fn new(context: &mut Context) -> Game {
		let (arena_width, arena_height) = graphics::drawable_size(context);

		Game {
			location: Vector2::new(arena_width / 2.0, arena_height / 2.0),
			rotation: 0.0,
			velocity: Vector2::new(0.0, 0.0),
		}
	}

	fn handle_window_size_change(
		&self,
		context: &mut Context,
		(width, height): (f32, f32),
	) -> GameResult<()> {
		graphics::set_screen_coordinates(context, graphics::Rect::new(0.0, 0.0, width, height))
	}
}

impl EventHandler for Game {
	fn update(&mut self, context: &mut Context) -> GameResult<()> {
		let delta_time = timer::delta(context).as_secs_f32();
		let arena_size = graphics::drawable_size(context);
		self.handle_window_size_change(context, arena_size)?;

		self.location += self.velocity * delta_time;

		Ok(())
	}

	fn draw(&mut self, context: &mut Context) -> GameResult<()> {
		graphics::clear(context, graphics::BLACK);
		let arena_size = graphics::drawable_size(context);

		let ship = graphics::MeshBuilder::new()
			.polyline(
				graphics::DrawMode::fill(),
				&[
					Point2::new(-7.0, -5.0),
					Point2::new(10.0, 0.0),
					Point2::new(-7.0, 5.0),
				],
				graphics::WHITE,
			)?
			.build(context)?;

		graphics::draw(
			context,
			&ship,
			graphics::DrawParam::new()
				.dest(Point2::new(self.location.x, self.location.y))
				.rotation(self.rotation),
		)?;

		graphics::present(context)
	}

	fn key_down_event(
		&mut self,
		context: &mut Context,
		keycode: KeyCode,
		_keymods: KeyMods,
		_repeat: bool,
	) {
		let delta_time = timer::delta(context).as_secs_f32();

		match keycode {
			KeyCode::Left => self.rotation += -0.1,
			KeyCode::Right => self.rotation += 0.1,
			KeyCode::Z => {
				self.velocity +=
					Vector2::new(self.rotation.cos() * 10.0, self.rotation.sin() * 10.0)
			}
			_ => (),
		}
	}
}
<|endoftext|>