diff options
Diffstat (limited to 'src')
132 files changed, 2181 insertions, 1628 deletions
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 8429e83a7aa..16149e9f277 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -73,7 +73,7 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = compile_test(config, props, testfile); if proc_res.status.success() { - fatal_ProcRes("compile-fail test compiled successfully!".to_string(), + fatal_proc_rec("compile-fail test compiled successfully!".to_string(), &proc_res); } @@ -97,7 +97,7 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = compile_test(config, props, testfile); if !proc_res.status.success() { - fatal_ProcRes("compilation failed!".to_string(), &proc_res); + fatal_proc_rec("compilation failed!".to_string(), &proc_res); } exec_compiled_test(config, props, testfile) @@ -108,7 +108,7 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { // The value our Makefile configures valgrind to return on failure static VALGRIND_ERR: int = 100; if proc_res.status.matches_exit_status(VALGRIND_ERR) { - fatal_ProcRes("run-fail test isn't valgrind-clean!".to_string(), + fatal_proc_rec("run-fail test isn't valgrind-clean!".to_string(), &proc_res); } @@ -120,7 +120,7 @@ fn check_correct_failure_status(proc_res: &ProcRes) { // The value the rust runtime returns on failure static RUST_ERR: int = 101; if !proc_res.status.matches_exit_status(RUST_ERR) { - fatal_ProcRes( + fatal_proc_rec( format!("failure produced the wrong error: {}", proc_res.status), proc_res); } @@ -131,19 +131,19 @@ fn run_rpass_test(config: &Config, props: &TestProps, testfile: &Path) { let mut proc_res = compile_test(config, props, testfile); if !proc_res.status.success() { - fatal_ProcRes("compilation failed!".to_string(), &proc_res); + fatal_proc_rec("compilation failed!".to_string(), &proc_res); } proc_res = exec_compiled_test(config, props, testfile); if !proc_res.status.success() { - fatal_ProcRes("test run failed!".to_string(), &proc_res); + fatal_proc_rec("test run failed!".to_string(), &proc_res); } } else { let proc_res = jit_test(config, props, testfile); if !proc_res.status.success() { - fatal_ProcRes("jit failed!".to_string(), &proc_res); + fatal_proc_rec("jit failed!".to_string(), &proc_res); } } } @@ -172,7 +172,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { "normal"); if !proc_res.status.success() { - fatal_ProcRes(format!("pretty-printing failed in round {}", round), + fatal_proc_rec(format!("pretty-printing failed in round {}", round), &proc_res); } @@ -204,7 +204,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = typecheck_source(config, props, testfile, actual); if !proc_res.status.success() { - fatal_ProcRes("pretty-printed source does not typecheck".to_string(), + fatal_proc_rec("pretty-printed source does not typecheck".to_string(), &proc_res); } if props.no_pretty_expanded { return } @@ -212,13 +212,13 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { // additionally, run `--pretty expanded` and try to build it. let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "expanded"); if !proc_res.status.success() { - fatal_ProcRes(format!("pretty-printing (expanded) failed"), &proc_res); + fatal_proc_rec(format!("pretty-printing (expanded) failed"), &proc_res); } let ProcRes{ stdout: expanded_src, .. } = proc_res; let proc_res = typecheck_source(config, props, testfile, expanded_src); if !proc_res.status.success() { - fatal_ProcRes(format!("pretty-printed source (expanded) does \ + fatal_proc_rec(format!("pretty-printed source (expanded) does \ not typecheck"), &proc_res); } @@ -326,7 +326,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { // compile test file (it shoud have 'compile-flags:-g' in the header) let compiler_run_result = compile_test(config, props, testfile); if !compiler_run_result.status.success() { - fatal_ProcRes("compilation failed!".to_string(), &compiler_run_result); + fatal_proc_rec("compilation failed!".to_string(), &compiler_run_result); } let exe_file = make_exe_name(config, testfile); @@ -517,7 +517,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) // compile test file (it shoud have 'compile-flags:-g' in the header) let compile_result = compile_test(config, props, testfile); if !compile_result.status.success() { - fatal_ProcRes("compilation failed!".to_string(), &compile_result); + fatal_proc_rec("compilation failed!".to_string(), &compile_result); } let exe_file = make_exe_name(config, testfile); @@ -560,7 +560,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) let debugger_run_result = run_lldb(config, &exe_file, &debugger_script); if !debugger_run_result.status.success() { - fatal_ProcRes("Error while running LLDB".to_string(), + fatal_proc_rec("Error while running LLDB".to_string(), &debugger_run_result); } @@ -720,7 +720,7 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) } } if i != num_check_lines { - fatal_ProcRes(format!("line not found in debugger output: {}", + fatal_proc_rec(format!("line not found in debugger output: {}", check_lines.get(i).unwrap()), debugger_run_result); } @@ -764,14 +764,14 @@ fn check_error_patterns(props: &TestProps, let missing_patterns = props.error_patterns.slice(next_err_idx, props.error_patterns.len()); if missing_patterns.len() == 1u { - fatal_ProcRes(format!("error pattern '{}' not found!", + fatal_proc_rec(format!("error pattern '{}' not found!", missing_patterns[0]), proc_res); } else { for pattern in missing_patterns.iter() { error(format!("error pattern '{}' not found!", *pattern)); } - fatal_ProcRes("multiple error patterns not found".to_string(), + fatal_proc_rec("multiple error patterns not found".to_string(), proc_res); } } @@ -779,7 +779,7 @@ fn check_error_patterns(props: &TestProps, fn check_no_compiler_crash(proc_res: &ProcRes) { for line in proc_res.stderr.as_slice().lines() { if line.starts_with("error: internal compiler error:") { - fatal_ProcRes("compiler encountered internal error".to_string(), + fatal_proc_rec("compiler encountered internal error".to_string(), proc_res); } } @@ -857,7 +857,7 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> , } if !was_expected && is_compiler_error_or_warning(line) { - fatal_ProcRes(format!("unexpected compiler error or warning: '{}'", + fatal_proc_rec(format!("unexpected compiler error or warning: '{}'", line), proc_res); } @@ -866,7 +866,7 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> , for (i, &flag) in found_flags.iter().enumerate() { if !flag { let ee = expected_errors.get(i); - fatal_ProcRes(format!("expected {} on line {} not found: {}", + fatal_proc_rec(format!("expected {} on line {} not found: {}", ee.kind, ee.line, ee.msg), proc_res); } @@ -1047,7 +1047,7 @@ fn compose_and_run_compiler( config.compile_lib_path.as_slice(), None); if !auxres.status.success() { - fatal_ProcRes( + fatal_proc_rec( format!("auxiliary build of {} failed to compile: ", abs_ab.display()), &auxres); @@ -1286,7 +1286,7 @@ fn error(err: String) { println!("\nerror: {}", err); } fn fatal(err: String) -> ! { error(err); fail!(); } -fn fatal_ProcRes(err: String, proc_res: &ProcRes) -> ! { +fn fatal_proc_rec(err: String, proc_res: &ProcRes) -> ! { print!("\n\ error: {}\n\ status: {}\n\ @@ -1562,35 +1562,35 @@ fn run_codegen_test(config: &Config, props: &TestProps, let mut proc_res = compile_test_and_save_bitcode(config, props, testfile); if !proc_res.status.success() { - fatal_ProcRes("compilation failed!".to_string(), &proc_res); + fatal_proc_rec("compilation failed!".to_string(), &proc_res); } proc_res = extract_function_from_bitcode(config, props, "test", testfile, ""); if !proc_res.status.success() { - fatal_ProcRes("extracting 'test' function failed".to_string(), + fatal_proc_rec("extracting 'test' function failed".to_string(), &proc_res); } proc_res = disassemble_extract(config, props, testfile, ""); if !proc_res.status.success() { - fatal_ProcRes("disassembling extract failed".to_string(), &proc_res); + fatal_proc_rec("disassembling extract failed".to_string(), &proc_res); } let mut proc_res = compile_cc_with_clang_and_save_bitcode(config, props, testfile); if !proc_res.status.success() { - fatal_ProcRes("compilation failed!".to_string(), &proc_res); + fatal_proc_rec("compilation failed!".to_string(), &proc_res); } proc_res = extract_function_from_bitcode(config, props, "test", testfile, "clang"); if !proc_res.status.success() { - fatal_ProcRes("extracting 'test' function failed".to_string(), + fatal_proc_rec("extracting 'test' function failed".to_string(), &proc_res); } proc_res = disassemble_extract(config, props, testfile, "clang"); if !proc_res.status.success() { - fatal_ProcRes("disassembling extract failed".to_string(), &proc_res); + fatal_proc_rec("disassembling extract failed".to_string(), &proc_res); } let base = output_base_name(config, testfile); diff --git a/src/doc/guide-ffi.md b/src/doc/guide-ffi.md index 81616c675de..ad80f2b46c8 100644 --- a/src/doc/guide-ffi.md +++ b/src/doc/guide-ffi.md @@ -476,6 +476,7 @@ extern crate libc; #[cfg(target_os = "win32", target_arch = "x86")] #[link(name = "kernel32")] +#[allow(non_snake_case_functions)] extern "stdcall" { fn SetEnvironmentVariableA(n: *u8, v: *u8) -> libc::c_int; } diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md index ad6ec65ef44..6b451745914 100644 --- a/src/doc/guide-tasks.md +++ b/src/doc/guide-tasks.md @@ -329,10 +329,10 @@ Here is a small example showing how to use Arcs. We wish to run concurrently sev a single large vector of floats. Each task needs the full vector to perform its duty. ~~~ -extern crate rand; extern crate sync; use sync::Arc; +use std::rand; fn pnorm(nums: &[f64], p: uint) -> f64 { nums.iter().fold(0.0, |a, b| a + b.powf(p as f64)).powf(1.0 / (p as f64)) @@ -358,7 +358,7 @@ created by the line ~~~ # extern crate sync; -# extern crate rand; +# use std::rand; # use sync::Arc; # fn main() { # let numbers = Vec::from_fn(1000000, |_| rand::random::<f64>()); @@ -372,7 +372,7 @@ reference to the underlying vector as if it were local. ~~~ # extern crate sync; -# extern crate rand; +# use std::rand; # use sync::Arc; # fn pnorm(nums: &[f64], p: uint) -> f64 { 4.0 } # fn main() { diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 011d1b2b5db..a22256650b8 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -1112,7 +1112,7 @@ let ys = xs; xs = Nil; -// `xs` can't be used again +// `xs` can be used again ~~~ A destructor call will only occur for a variable that has not been moved from, diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 546e4e52699..a8eb4b3407e 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -152,7 +152,11 @@ impl<T: Send + Share + Clone> Arc<T> { #[inline] #[experimental] pub fn make_unique<'a>(&'a mut self) -> &'a mut T { - if self.inner().strong.load(atomics::SeqCst) != 1 { + // Note that we hold a strong reference, which also counts as + // a weak reference, so we only clone if there is an + // additional reference of either kind. + if self.inner().strong.load(atomics::SeqCst) != 1 || + self.inner().weak.load(atomics::SeqCst) != 1 { *self = Arc::new(self.deref().clone()) } // This unsafety is ok because we're guaranteed that the pointer @@ -357,6 +361,20 @@ mod tests { } #[test] + fn test_cowarc_clone_weak() { + let mut cow0 = Arc::new(75u); + let cow1_weak = cow0.downgrade(); + + assert!(75 == *cow0); + assert!(75 == *cow1_weak.upgrade().unwrap()); + + *cow0.make_unique() += 1; + + assert!(76 == *cow0); + assert!(cow1_weak.upgrade().is_none()); + } + + #[test] fn test_live() { let x = Arc::new(5); let y = x.downgrade(); diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 8ded3c431d4..96d90e6ed63 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -86,6 +86,31 @@ impl<T> Rc<T> { } } +impl<T: Clone> Rc<T> { + /// Acquires a mutable pointer to the inner contents by guaranteeing that + /// the reference count is one (no sharing is possible). + /// + /// This is also referred to as a copy-on-write operation because the inner + /// data is cloned if the reference count is greater than one. + #[inline] + #[experimental] + pub fn make_unique<'a>(&'a mut self) -> &'a mut T { + // Note that we hold a strong reference, which also counts as + // a weak reference, so we only clone if there is an + // additional reference of either kind. + if self.strong() != 1 || self.weak() != 1 { + *self = Rc::new(self.deref().clone()) + } + // This unsafety is ok because we're guaranteed that the pointer + // returned is the *only* pointer that will ever be returned to T. Our + // reference count is guaranteed to be 1 at this point, and we required + // the Rc itself to be `mut`, so we're returning the only possible + // reference to the inner data. + let inner = unsafe { &mut *self._ptr }; + &mut inner.value + } +} + impl<T> Deref<T> for Rc<T> { /// Borrow the value contained in the reference-counted box #[inline(always)] @@ -234,6 +259,7 @@ impl<T> RcBoxPtr<T> for Weak<T> { } #[cfg(test)] +#[allow(experimental)] mod tests { use super::{Rc, Weak}; use std::cell::RefCell; @@ -304,4 +330,66 @@ mod tests { // hopefully we don't double-free (or leak)... } + + #[test] + fn test_cowrc_clone_make_unique() { + let mut cow0 = Rc::new(75u); + let mut cow1 = cow0.clone(); + let mut cow2 = cow1.clone(); + + assert!(75 == *cow0.make_unique()); + assert!(75 == *cow1.make_unique()); + assert!(75 == *cow2.make_unique()); + + *cow0.make_unique() += 1; + *cow1.make_unique() += 2; + *cow2.make_unique() += 3; + + assert!(76 == *cow0); + assert!(77 == *cow1); + assert!(78 == *cow2); + + // none should point to the same backing memory + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 != *cow2); + } + + #[test] + fn test_cowrc_clone_unique2() { + let mut cow0 = Rc::new(75u); + let cow1 = cow0.clone(); + let cow2 = cow1.clone(); + + assert!(75 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + *cow0.make_unique() += 1; + + assert!(76 == *cow0); + assert!(75 == *cow1); + assert!(75 == *cow2); + + // cow1 and cow2 should share the same contents + // cow0 should have a unique reference + assert!(*cow0 != *cow1); + assert!(*cow0 != *cow2); + assert!(*cow1 == *cow2); + } + + #[test] + fn test_cowrc_clone_weak() { + let mut cow0 = Rc::new(75u); + let cow1_weak = cow0.downgrade(); + + assert!(75 == *cow0); + assert!(75 == *cow1_weak.upgrade().unwrap()); + + *cow0.make_unique() += 1; + + assert!(76 == *cow0); + assert!(cow1_weak.upgrade().is_none()); + } + } diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index 0b5d499c533..54bc6989d7c 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -12,11 +12,11 @@ use std::cmp; +use std::fmt; use std::iter::RandomAccessIterator; use std::iter::{Enumerate, Repeat, Map, Zip}; use std::ops; use std::slice; -use std::string::String; use std::uint; #[deriving(Clone)] @@ -527,25 +527,6 @@ impl Bitv { } /** - * Converts `self` to a string. - * - * The resulting string has the same length as `self`, and each - * character is either '0' or '1'. - */ - pub fn to_str(&self) -> String { - let mut rs = String::new(); - for i in self.iter() { - if i { - rs.push_char('1'); - } else { - rs.push_char('0'); - } - }; - rs - } - - - /** * Compare a bitvector to a vector of `bool`. * * Both the bitvector and vector must have the same length. @@ -604,6 +585,15 @@ impl ops::Index<uint,bool> for Bitv { } } +impl fmt::Show for Bitv { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + for bit in self.iter() { + try!(write!(fmt, "{}", if bit { 1 } else { 0 })); + } + Ok(()) + } +} + #[inline] fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool { if bits == 0 { @@ -827,6 +817,21 @@ impl cmp::Eq for BitvSet { fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) } } +impl fmt::Show for BitvSet { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + try!(write!(fmt, r"\{")); + let mut first = true; + for n in self.iter() { + if !first { + try!(write!(fmt, ", ")); + } + try!(write!(fmt, "{}", n)); + first = false; + } + write!(fmt, r"\}") + } +} + impl Container for BitvSet { #[inline] fn len(&self) -> uint { self.size } @@ -980,8 +985,8 @@ mod tests { use bitv; use std::uint; - use rand; - use rand::Rng; + use std::rand; + use std::rand::Rng; static BENCH_BITS : uint = 1 << 14; @@ -1629,6 +1634,16 @@ mod tests { assert!(!v.none()); } + #[test] + fn test_bitv_set_show() { + let mut s = BitvSet::new(); + s.insert(1); + s.insert(10); + s.insert(50); + s.insert(2); + assert_eq!("{1, 2, 10, 50}".to_string(), s.to_str()); + } + fn rng() -> rand::IsaacRng { let seed = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; rand::SeedableRng::from_seed(seed) diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs index e031b07f872..fa2cb233873 100644 --- a/src/libcollections/deque.rs +++ b/src/libcollections/deque.rs @@ -44,8 +44,8 @@ pub mod bench { extern crate test; use self::test::Bencher; use std::container::MutableMap; - use rand; - use rand::Rng; + use std::rand; + use std::rand::Rng; pub fn insert_rand_n<M:MutableMap<uint,uint>>(n: uint, map: &mut M, diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 8072ee02bc0..95729919738 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -610,7 +610,7 @@ mod tests { extern crate test; use self::test::Bencher; use deque::Deque; - use rand; + use std::rand; use super::{DList, Node, ListInsertion}; pub fn check_links<T>(list: &DList<T>) { diff --git a/src/libcollections/hashmap.rs b/src/libcollections/hashmap.rs index 42b57a1ea40..c1bc379f0b7 100644 --- a/src/libcollections/hashmap.rs +++ b/src/libcollections/hashmap.rs @@ -24,8 +24,8 @@ use std::iter::{range, range_inclusive}; use std::mem::replace; use std::num; use std::option::{Option, Some, None}; -use rand; -use rand::Rng; +use std::rand; +use std::rand::Rng; use std::result::{Ok, Err}; use std::slice::ImmutableVector; @@ -2013,8 +2013,8 @@ mod test_map { let map_str = format!("{}", map); - assert!(map_str == "{1: 2, 3: 4}".to_owned() || map_str == "{3: 4, 1: 2}".to_owned()); - assert_eq!(format!("{}", empty), "{}".to_owned()); + assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string()); + assert_eq!(format!("{}", empty), "{}".to_string()); } #[test] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cbf4ae03a76..d1c75b89579 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -24,7 +24,6 @@ #![deny(deprecated_owned_vector)] -extern crate rand; extern crate debug; #[cfg(test)] extern crate test; diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs index 8e4e47405e7..932011baa56 100644 --- a/src/libcollections/smallintmap.rs +++ b/src/libcollections/smallintmap.rs @@ -296,20 +296,20 @@ mod test_map { // given a new key, initialize it with this new count, // given an existing key, add more to its count - fn addMoreToCount(_k: uint, v0: uint, v1: uint) -> uint { + fn add_more_to_count(_k: uint, v0: uint, v1: uint) -> uint { v0 + v1 } - fn addMoreToCount_simple(v0: uint, v1: uint) -> uint { + fn add_more_to_count_simple(v0: uint, v1: uint) -> uint { v0 + v1 } // count integers - map.update(3, 1, addMoreToCount_simple); - map.update_with_key(9, 1, addMoreToCount); - map.update(3, 7, addMoreToCount_simple); - map.update_with_key(5, 3, addMoreToCount); - map.update_with_key(3, 2, addMoreToCount); + map.update(3, 1, add_more_to_count_simple); + map.update_with_key(9, 1, add_more_to_count); + map.update(3, 7, add_more_to_count_simple); + map.update_with_key(5, 3, add_more_to_count); + map.update_with_key(3, 2, add_more_to_count); // check the total counts assert_eq!(map.find(&3).unwrap(), &10); diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index fb663d91131..793b562b582 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -1000,8 +1000,8 @@ impl<T: TotalOrd> Extendable<T> for TreeSet<T> { mod test_treemap { use super::{TreeMap, TreeNode}; - use rand::Rng; - use rand; + use std::rand::Rng; + use std::rand; #[test] fn find_empty() { @@ -1366,8 +1366,8 @@ mod test_treemap { let map_str = format!("{}", map); - assert!(map_str == "{1: 2, 3: 4}".to_owned()); - assert_eq!(format!("{}", empty), "{}".to_owned()); + assert!(map_str == "{1: 2, 3: 4}".to_string()); + assert_eq!(format!("{}", empty), "{}".to_string()); } #[test] @@ -1776,7 +1776,7 @@ mod test_set { let set_str = format!("{}", set); - assert!(set_str == "{1, 2}".to_owned()); - assert_eq!(format!("{}", empty), "{}".to_owned()); + assert!(set_str == "{1, 2}".to_string()); + assert_eq!(format!("{}", empty), "{}".to_string()); } } diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index 9d64b3c2394..e6df4fd87e1 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -915,7 +915,7 @@ mod test_map { mod bench_map { extern crate test; use super::TrieMap; - use rand::{weak_rng, Rng}; + use std::rand::{weak_rng, Rng}; use self::test::Bencher; #[bench] diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 94ac344db34..f463c194424 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -119,7 +119,7 @@ mod tests { use prelude::*; use super::*; use realstd::owned::{Box, AnyOwnExt}; - use realstd::str::{Str, StrAllocating}; + use realstd::str::Str; #[deriving(Eq, Show)] struct Test; diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 0c5d3151af0..6b0f0b70561 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -23,6 +23,7 @@ //! however the converse is not always true due to the above range limits //! and, as such, should be performed via the `from_u32` function.. +#![allow(non_snake_case_functions)] use mem::transmute; use option::{None, Option, Some}; @@ -607,7 +608,7 @@ mod test { use slice::ImmutableVector; use option::{Some, None}; use realstd::string::String; - use realstd::str::{Str, StrAllocating}; + use realstd::str::Str; #[test] fn test_is_lowercase() { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 13236a1f654..f41efdbc1db 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -596,7 +596,6 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result, #[cfg(test)] pub fn format(args: &Arguments) -> ::realstd::string::String { use str; - use realstd::str::StrAllocating; use realstd::io::MemWriter; fn mywrite<T: ::realstd::io::Writer>(t: &mut T, b: &[u8]) { diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 731911185ff..7ad78df2fe8 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -194,7 +194,7 @@ mod tests { use fmt::radix; use super::{Binary, Octal, Decimal, LowerHex, UpperHex}; use super::{GenericRadix, Radix}; - use realstd::str::{Str, StrAllocating}; + use realstd::str::Str; #[test] fn test_radix_base() { @@ -399,35 +399,35 @@ mod bench { mod uint { use super::test::Bencher; use fmt::radix; - use rand::{XorShiftRng, Rng}; + use realstd::rand::{weak_rng, Rng}; #[bench] fn format_bin(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:t}", rng.gen::<uint>()); }) } #[bench] fn format_oct(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:o}", rng.gen::<uint>()); }) } #[bench] fn format_dec(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:u}", rng.gen::<uint>()); }) } #[bench] fn format_hex(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:x}", rng.gen::<uint>()); }) } #[bench] fn format_base_36(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{}", radix(rng.gen::<uint>(), 36)); }) } } @@ -435,35 +435,35 @@ mod bench { mod int { use super::test::Bencher; use fmt::radix; - use rand::{XorShiftRng, Rng}; + use realstd::rand::{weak_rng, Rng}; #[bench] fn format_bin(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:t}", rng.gen::<int>()); }) } #[bench] fn format_oct(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:o}", rng.gen::<int>()); }) } #[bench] fn format_dec(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:d}", rng.gen::<int>()); }) } #[bench] fn format_hex(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{:x}", rng.gen::<int>()); }) } #[bench] fn format_base_36(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { format!("{}", radix(rng.gen::<int>(), 36)); }) } } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 56cbe2e2a30..2ff2dca0c86 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -59,7 +59,6 @@ #[cfg(test)] extern crate realcore = "core"; #[cfg(test)] extern crate libc; #[cfg(test)] extern crate native; -#[cfg(test)] extern crate rand; #[cfg(test)] extern crate realstd = "std"; #[cfg(test)] pub use cmp = realcore::cmp; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 926605dddb3..fd51ede204f 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -637,11 +637,10 @@ pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> { #[cfg(test)] mod tests { use realstd::vec::Vec; - use realstd::string::String; use result::{collect, fold, fold_}; use prelude::*; - use realstd::str::{Str, StrAllocating}; + use realstd::str::Str; use iter::range; pub fn op1() -> Result<int, &'static str> { Ok(666) } diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 059b96ffac7..edcb37dbb64 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -294,7 +294,7 @@ mod tests { use super::*; use clone::Clone; use cmp::*; - use realstd::str::{Str, StrAllocating}; + use realstd::str::Str; #[test] fn test_clone() { diff --git a/src/libcore/unicode.rs b/src/libcore/unicode.rs index 242672de296..c6fc5f16ed1 100644 --- a/src/libcore/unicode.rs +++ b/src/libcore/unicode.rs @@ -10,7 +10,7 @@ // NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly -#![allow(missing_doc, non_uppercase_statics)] +#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)] fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { diff --git a/src/libdebug/reflect.rs b/src/libdebug/reflect.rs index 367994466b2..997d3427122 100644 --- a/src/libdebug/reflect.rs +++ b/src/libdebug/reflect.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -42,11 +42,12 @@ pub fn align(size: uint, align: uint) -> uint { pub struct MovePtrAdaptor<V> { inner: V } -pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> { - MovePtrAdaptor { inner: v } -} impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> { + pub fn new(v: V) -> MovePtrAdaptor<V> { + MovePtrAdaptor { inner: v } + } + #[inline] pub fn bump(&mut self, sz: uint) { self.inner.move_ptr(|p| ((p as uint) + sz) as *u8) diff --git a/src/libdebug/repr.rs b/src/libdebug/repr.rs index 6807e73982d..e6cc9785b44 100644 --- a/src/libdebug/repr.rs +++ b/src/libdebug/repr.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -99,17 +99,6 @@ pub struct ReprVisitor<'a> { last_err: Option<io::IoError>, } -pub fn ReprVisitor<'a>(ptr: *u8, - writer: &'a mut io::Writer) -> ReprVisitor<'a> { - ReprVisitor { - ptr: ptr, - ptr_stk: vec!(), - var_stk: vec!(), - writer: writer, - last_err: None, - } -} - impl<'a> MovePtr for ReprVisitor<'a> { #[inline] fn move_ptr(&mut self, adjustment: |*u8| -> *u8) { @@ -125,6 +114,15 @@ impl<'a> MovePtr for ReprVisitor<'a> { impl<'a> ReprVisitor<'a> { // Various helpers for the TyVisitor impl + pub fn new(ptr: *u8, writer: &'a mut io::Writer) -> ReprVisitor<'a> { + ReprVisitor { + ptr: ptr, + ptr_stk: vec!(), + var_stk: vec!(), + writer: writer, + last_err: None, + } + } #[inline] pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T| -> bool) -> bool { @@ -141,16 +139,8 @@ impl<'a> ReprVisitor<'a> { #[inline] pub fn visit_ptr_inner(&mut self, ptr: *u8, inner: *TyDesc) -> bool { unsafe { - // This should call the constructor up above, but due to limiting - // issues we have to recreate it here. - let u = ReprVisitor { - ptr: ptr, - ptr_stk: vec!(), - var_stk: vec!(), - writer: mem::transmute_copy(&self.writer), - last_err: None, - }; - let mut v = reflect::MovePtrAdaptor(u); + let u = ReprVisitor::new(ptr, mem::transmute_copy(&self.writer)); + let mut v = reflect::MovePtrAdaptor::new(u); // Obviously this should not be a thing, but blame #8401 for now visit_tydesc(inner, &mut v as &mut TyVisitor); match v.unwrap().last_err { @@ -584,8 +574,8 @@ pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> { unsafe { let ptr = object as *T as *u8; let tydesc = get_tydesc::<T>(); - let u = ReprVisitor(ptr, writer); - let mut v = reflect::MovePtrAdaptor(u); + let u = ReprVisitor::new(ptr, writer); + let mut v = reflect::MovePtrAdaptor::new(u); visit_tydesc(tydesc, &mut v as &mut TyVisitor); match v.unwrap().last_err { Some(e) => Err(e), @@ -613,7 +603,7 @@ fn test_repr() { fn exact_test<T>(t: &T, e:&str) { let mut m = io::MemWriter::new(); write_repr(&mut m as &mut io::Writer, t).unwrap(); - let s = str::from_utf8(m.unwrap().as_slice()).unwrap().to_owned(); + let s = str::from_utf8(m.unwrap().as_slice()).unwrap().to_string(); assert_eq!(s.as_slice(), e); } diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 54f147dead8..8bfd2d867c1 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -108,10 +108,9 @@ pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> { #[cfg(test)] mod tests { - extern crate rand; - use super::{inflate_bytes, deflate_bytes}; - use self::rand::Rng; + use std::rand; + use std::rand::Rng; #[test] #[allow(deprecated_owned_vector)] @@ -120,7 +119,8 @@ mod tests { let mut words = vec!(); for _ in range(0, 20) { let range = r.gen_range(1u, 10); - words.push(r.gen_vec::<u8>(range)); + let v = r.gen_iter::<u8>().take(range).collect::<Vec<u8>>(); + words.push(v); } for _ in range(0, 20) { let mut input = vec![]; diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index 4584c08cbd8..31fd8950c80 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -212,7 +212,6 @@ #[cfg(test)] #[phase(syntax, link)] extern crate log; #[cfg(test)] extern crate rustuv; -extern crate rand; extern crate libc; extern crate alloc; diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index d28e74a2b80..6dc6ccb7901 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -17,7 +17,7 @@ use std::sync::deque; use std::unstable::mutex::NativeMutex; use std::raw; -use rand::{XorShiftRng, Rng, Rand}; +use std::rand::{XorShiftRng, Rng, Rand}; use TaskState; use context::Context; @@ -977,8 +977,9 @@ impl ClosureConverter for UnsafeTaskReceiver { // worry there. #[cfg(windows)] fn new_sched_rng() -> XorShiftRng { - match XorShiftRng::new() { - Ok(r) => r, + use std::rand::OsRng; + match OsRng::new() { + Ok(mut r) => r.gen(), Err(e) => { rtabort!("sched: failed to create seeded RNG: {}", e) } @@ -988,7 +989,7 @@ fn new_sched_rng() -> XorShiftRng { fn new_sched_rng() -> XorShiftRng { use libc; use std::mem; - use rand::SeedableRng; + use std::rand::SeedableRng; let fd = "/dev/urandom".with_c_str(|name| { unsafe { libc::open(name, libc::O_RDONLY, 0) } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 7b6a9122d90..3a9f8bc863b 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -71,6 +71,7 @@ */ #![allow(non_camel_case_types)] +#![allow(non_snake_case_functions)] #![allow(non_uppercase_statics)] #![allow(missing_doc)] #![allow(uppercase_variables)] diff --git a/src/libnative/io/mod.rs b/src/libnative/io/mod.rs index 0c103bc4695..240b87fda08 100644 --- a/src/libnative/io/mod.rs +++ b/src/libnative/io/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -21,6 +21,8 @@ //! play. The only dependencies of these modules are the normal system libraries //! that you would find on the respective platform. +#![allow(non_snake_case_functions)] + use libc::c_int; use libc; use std::c_str::CString; diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 5bee9489ca9..cddae53fa42 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -758,6 +758,7 @@ fn free_handle(_handle: *()) { #[cfg(unix)] fn translate_status(status: c_int) -> p::ProcessExit { + #![allow(non_snake_case_functions)] #[cfg(target_os = "linux")] #[cfg(target_os = "android")] mod imp { diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index cc35cd749d6..c6af8ac9b4b 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -1372,7 +1372,7 @@ mod biguint_tests { use std::num::{Zero, One, FromStrRadix, ToStrRadix}; use std::num::{ToPrimitive, FromPrimitive}; use std::num::CheckedDiv; - use rand::{task_rng}; + use std::rand::task_rng; use std::u64; #[test] @@ -2220,7 +2220,7 @@ mod bigint_tests { use std::num::CheckedDiv; use std::num::{Zero, One, FromStrRadix, ToStrRadix}; use std::num::{ToPrimitive, FromPrimitive}; - use rand::{task_rng}; + use std::rand::task_rng; use std::u64; #[test] diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs index 03c87eb931d..d4e689ccb5c 100644 --- a/src/librand/distributions/exponential.rs +++ b/src/librand/distributions/exponential.rs @@ -10,7 +10,8 @@ //! The exponential distribution. -use std::num::Float; +use core::num::Float; + use {Rng, Rand}; use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; @@ -58,7 +59,8 @@ impl Rand for Exp1 { /// # Example /// /// ```rust -/// use rand::distributions::{Exp, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{Exp, IndependentSample}; /// /// let exp = Exp::new(2.0); /// let v = exp.ind_sample(&mut rand::task_rng()); @@ -90,14 +92,15 @@ impl IndependentSample<f64> for Exp { #[cfg(test)] mod test { + use std::prelude::*; + use distributions::{Sample, IndependentSample}; - use {Rng, task_rng}; use super::Exp; #[test] fn test_exp() { let mut exp = Exp::new(10.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { assert!(exp.sample(&mut rng) >= 0.0); assert!(exp.ind_sample(&mut rng) >= 0.0); @@ -118,22 +121,24 @@ mod test { #[cfg(test)] mod bench { extern crate test; + + use std::prelude::*; + use self::test::Bencher; use std::mem::size_of; - use {XorShiftRng, RAND_BENCH_N}; use super::Exp; use distributions::Sample; #[bench] fn rand_exp(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = ::test::weak_rng(); let mut exp = Exp::new(2.71828 * 3.14159); b.iter(|| { - for _ in range(0, RAND_BENCH_N) { + for _ in range(0, ::RAND_BENCH_N) { exp.sample(&mut rng); } }); - b.bytes = size_of::<f64>() as u64 * RAND_BENCH_N; + b.bytes = size_of::<f64>() as u64 * ::RAND_BENCH_N; } } diff --git a/src/librand/distributions/gamma.rs b/src/librand/distributions/gamma.rs index 1bb2c35bce2..445fe9acbec 100644 --- a/src/librand/distributions/gamma.rs +++ b/src/librand/distributions/gamma.rs @@ -10,7 +10,8 @@ //! The Gamma and derived distributions. -use std::num::Float; +use core::num::Float; + use {Rng, Open01}; use super::normal::StandardNormal; use super::{IndependentSample, Sample, Exp}; @@ -34,7 +35,8 @@ use super::{IndependentSample, Sample, Exp}; /// # Example /// /// ```rust -/// use rand::distributions::{IndependentSample, Gamma}; +/// use std::rand; +/// use std::rand::distributions::{IndependentSample, Gamma}; /// /// let gamma = Gamma::new(2.0, 5.0); /// let v = gamma.ind_sample(&mut rand::task_rng()); @@ -182,7 +184,8 @@ impl IndependentSample<f64> for GammaLargeShape { /// # Example /// /// ```rust -/// use rand::distributions::{ChiSquared, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{ChiSquared, IndependentSample}; /// /// let chi = ChiSquared::new(11.0); /// let v = chi.ind_sample(&mut rand::task_rng()); @@ -238,7 +241,8 @@ impl IndependentSample<f64> for ChiSquared { /// # Example /// /// ```rust -/// use rand::distributions::{FisherF, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{FisherF, IndependentSample}; /// /// let f = FisherF::new(2.0, 32.0); /// let v = f.ind_sample(&mut rand::task_rng()); @@ -281,7 +285,8 @@ impl IndependentSample<f64> for FisherF { /// # Example /// /// ```rust -/// use rand::distributions::{StudentT, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{StudentT, IndependentSample}; /// /// let t = StudentT::new(11.0); /// let v = t.ind_sample(&mut rand::task_rng()); @@ -315,14 +320,15 @@ impl IndependentSample<f64> for StudentT { #[cfg(test)] mod test { + use std::prelude::*; + use distributions::{Sample, IndependentSample}; - use {Rng, task_rng}; use super::{ChiSquared, StudentT, FisherF}; #[test] fn test_chi_squared_one() { let mut chi = ChiSquared::new(1.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { chi.sample(&mut rng); chi.ind_sample(&mut rng); @@ -331,7 +337,7 @@ mod test { #[test] fn test_chi_squared_small() { let mut chi = ChiSquared::new(0.5); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { chi.sample(&mut rng); chi.ind_sample(&mut rng); @@ -340,7 +346,7 @@ mod test { #[test] fn test_chi_squared_large() { let mut chi = ChiSquared::new(30.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { chi.sample(&mut rng); chi.ind_sample(&mut rng); @@ -355,7 +361,7 @@ mod test { #[test] fn test_f() { let mut f = FisherF::new(2.0, 32.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { f.sample(&mut rng); f.ind_sample(&mut rng); @@ -365,7 +371,7 @@ mod test { #[test] fn test_t() { let mut t = StudentT::new(11.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { t.sample(&mut rng); t.ind_sample(&mut rng); @@ -376,36 +382,36 @@ mod test { #[cfg(test)] mod bench { extern crate test; + use std::prelude::*; use self::test::Bencher; use std::mem::size_of; use distributions::IndependentSample; - use {XorShiftRng, RAND_BENCH_N}; use super::Gamma; #[bench] fn bench_gamma_large_shape(b: &mut Bencher) { let gamma = Gamma::new(10., 1.0); - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = ::test::weak_rng(); b.iter(|| { - for _ in range(0, RAND_BENCH_N) { + for _ in range(0, ::RAND_BENCH_N) { gamma.ind_sample(&mut rng); } }); - b.bytes = size_of::<f64>() as u64 * RAND_BENCH_N; + b.bytes = size_of::<f64>() as u64 * ::RAND_BENCH_N; } #[bench] fn bench_gamma_small_shape(b: &mut Bencher) { let gamma = Gamma::new(0.1, 1.0); - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = ::test::weak_rng(); b.iter(|| { - for _ in range(0, RAND_BENCH_N) { + for _ in range(0, ::RAND_BENCH_N) { gamma.ind_sample(&mut rng); } }); - b.bytes = size_of::<f64>() as u64 * RAND_BENCH_N; + b.bytes = size_of::<f64>() as u64 * ::RAND_BENCH_N; } } diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index b3535a695ea..bb09db48802 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -20,8 +20,12 @@ that do not need to record state. */ -use std::num; -use std::num::CheckedAdd; +#![experimental] + +use core::prelude::*; +use core::num; +use core::num::CheckedAdd; + use {Rng, Rand}; pub use self::range::Range; @@ -89,30 +93,32 @@ pub struct Weighted<T> { /// # Example /// /// ```rust -/// use rand::distributions::{Weighted, WeightedChoice, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample}; /// -/// let wc = WeightedChoice::new(vec!(Weighted { weight: 2, item: 'a' }, -/// Weighted { weight: 4, item: 'b' }, -/// Weighted { weight: 1, item: 'c' })); +/// let mut items = vec!(Weighted { weight: 2, item: 'a' }, +/// Weighted { weight: 4, item: 'b' }, +/// Weighted { weight: 1, item: 'c' }); +/// let wc = WeightedChoice::new(items.as_mut_slice()); /// let mut rng = rand::task_rng(); /// for _ in range(0, 16) { /// // on average prints 'a' 4 times, 'b' 8 and 'c' twice. /// println!("{}", wc.ind_sample(&mut rng)); /// } /// ``` -pub struct WeightedChoice<T> { - items: Vec<Weighted<T>>, +pub struct WeightedChoice<'a, T> { + items: &'a mut [Weighted<T>], weight_range: Range<uint> } -impl<T: Clone> WeightedChoice<T> { +impl<'a, T: Clone> WeightedChoice<'a, T> { /// Create a new `WeightedChoice`. /// /// Fails if: /// - `v` is empty /// - the total weight is 0 /// - the total weight is larger than a `uint` can contain. - pub fn new(mut items: Vec<Weighted<T>>) -> WeightedChoice<T> { + pub fn new<'a>(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> { // strictly speaking, this is subsumed by the total weight == 0 case assert!(!items.is_empty(), "WeightedChoice::new called with no items"); @@ -122,9 +128,11 @@ impl<T: Clone> WeightedChoice<T> { // weights so we can binary search. This *could* drop elements // with weight == 0 as an optimisation. for item in items.mut_iter() { - running_total = running_total.checked_add(&item.weight) - .expect("WeightedChoice::new called with a total weight larger \ - than a uint can contain"); + running_total = match running_total.checked_add(&item.weight) { + Some(n) => n, + None => fail!("WeightedChoice::new called with a total weight \ + larger than a uint can contain") + }; item.weight = running_total; } @@ -139,11 +147,11 @@ impl<T: Clone> WeightedChoice<T> { } } -impl<T: Clone> Sample<T> for WeightedChoice<T> { +impl<'a, T: Clone> Sample<T> for WeightedChoice<'a, T> { fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) } } -impl<T: Clone> IndependentSample<T> for WeightedChoice<T> { +impl<'a, T: Clone> IndependentSample<T> for WeightedChoice<'a, T> { fn ind_sample<R: Rng>(&self, rng: &mut R) -> T { // we want to find the first element that has cumulative // weight > sample_weight, which we do by binary since the @@ -153,8 +161,8 @@ impl<T: Clone> IndependentSample<T> for WeightedChoice<T> { let sample_weight = self.weight_range.ind_sample(rng); // short circuit when it's the first item - if sample_weight < self.items.get(0).weight { - return self.items.get(0).item.clone(); + if sample_weight < self.items[0].weight { + return self.items[0].item.clone(); } let mut idx = 0; @@ -169,7 +177,7 @@ impl<T: Clone> IndependentSample<T> for WeightedChoice<T> { // one is exactly the total weight.) while modifier > 1 { let i = idx + modifier / 2; - if self.items.get(i).weight <= sample_weight { + if self.items[i].weight <= sample_weight { // we're small, so look to the right, but allow this // exact element still. idx = i; @@ -182,7 +190,7 @@ impl<T: Clone> IndependentSample<T> for WeightedChoice<T> { } modifier /= 2; } - return self.items.get(idx + 1).item.clone(); + return self.items[idx + 1].item.clone(); } } @@ -247,7 +255,9 @@ fn ziggurat<R:Rng>( #[cfg(test)] mod tests { - use {task_rng, Rng, Rand}; + use std::prelude::*; + + use {Rng, Rand}; use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample}; #[deriving(Eq, Show)] @@ -274,8 +284,8 @@ mod tests { fn test_rand_sample() { let mut rand_sample = RandSample::<ConstRand>; - assert_eq!(rand_sample.sample(&mut task_rng()), ConstRand(0)); - assert_eq!(rand_sample.ind_sample(&mut task_rng()), ConstRand(0)); + assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0)); + assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0)); } #[test] fn test_weighted_choice() { @@ -286,7 +296,8 @@ mod tests { macro_rules! t ( ($items:expr, $expected:expr) => {{ - let wc = WeightedChoice::new($items); + let mut items = $items; + let wc = WeightedChoice::new(items.as_mut_slice()); let expected = $expected; let mut rng = CountingRng { i: 0 }; @@ -332,19 +343,19 @@ mod tests { #[test] #[should_fail] fn test_weighted_choice_no_items() { - WeightedChoice::<int>::new(vec!()); + WeightedChoice::<int>::new([]); } #[test] #[should_fail] fn test_weighted_choice_zero_weight() { - WeightedChoice::new(vec!(Weighted { weight: 0, item: 0}, - Weighted { weight: 0, item: 1})); + WeightedChoice::new(&mut [Weighted { weight: 0, item: 0}, + Weighted { weight: 0, item: 1}]); } #[test] #[should_fail] fn test_weighted_choice_weight_overflows() { let x = (-1) as uint / 2; // x + x + 2 is the overflow - WeightedChoice::new(vec!(Weighted { weight: x, item: 0 }, - Weighted { weight: 1, item: 1 }, - Weighted { weight: x, item: 2 }, - Weighted { weight: 1, item: 3 })); + WeightedChoice::new(&mut [Weighted { weight: x, item: 0 }, + Weighted { weight: 1, item: 1 }, + Weighted { weight: x, item: 2 }, + Weighted { weight: 1, item: 3 }]); } } diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs index dea73945b43..47ab7d32e05 100644 --- a/src/librand/distributions/normal.rs +++ b/src/librand/distributions/normal.rs @@ -10,7 +10,8 @@ //! The normal and derived distributions. -use std::num::Float; +use core::num::Float; + use {Rng, Rand, Open01}; use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; @@ -74,7 +75,8 @@ impl Rand for StandardNormal { /// # Example /// /// ```rust -/// use rand::distributions::{Normal, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{Normal, IndependentSample}; /// /// // mean 2, standard deviation 3 /// let normal = Normal::new(2.0, 3.0); @@ -116,7 +118,8 @@ impl IndependentSample<f64> for Normal { /// # Example /// /// ```rust -/// use rand::distributions::{LogNormal, IndependentSample}; +/// use std::rand; +/// use std::rand::distributions::{LogNormal, IndependentSample}; /// /// // mean 2, standard deviation 3 /// let log_normal = LogNormal::new(2.0, 3.0); @@ -146,14 +149,15 @@ impl IndependentSample<f64> for LogNormal { #[cfg(test)] mod tests { + use std::prelude::*; + use distributions::{Sample, IndependentSample}; - use {Rng, task_rng}; use super::{Normal, LogNormal}; #[test] fn test_normal() { let mut norm = Normal::new(10.0, 10.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { norm.sample(&mut rng); norm.ind_sample(&mut rng); @@ -169,7 +173,7 @@ mod tests { #[test] fn test_log_normal() { let mut lnorm = LogNormal::new(10.0, 10.0); - let mut rng = task_rng(); + let mut rng = ::test::rng(); for _ in range(0, 1000) { lnorm.sample(&mut rng); lnorm.ind_sample(&mut rng); @@ -185,22 +189,22 @@ mod tests { #[cfg(test)] mod bench { extern crate test; + use std::prelude::*; use self::test::Bencher; use std::mem::size_of; - use {XorShiftRng, RAND_BENCH_N}; use distributions::{Sample}; use super::Normal; #[bench] fn rand_normal(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = ::test::weak_rng(); let mut normal = Normal::new(-2.71828, 3.14159); b.iter(|| { - for _ in range(0, RAND_BENCH_N) { + for _ in range(0, ::RAND_BENCH_N) { normal.sample(&mut rng); } }); - b.bytes = size_of::<f64>() as u64 * RAND_BENCH_N; + b.bytes = size_of::<f64>() as u64 * ::RAND_BENCH_N; } } diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs index cee80b62e3d..f0e1d1715a2 100644 --- a/src/librand/distributions/range.rs +++ b/src/librand/distributions/range.rs @@ -12,7 +12,9 @@ // this is surprisingly complicated to be both generic & correct -use std::num::Bounded; +use core::prelude::*; +use core::num::Bounded; + use Rng; use distributions::{Sample, IndependentSample}; @@ -33,7 +35,8 @@ use distributions::{Sample, IndependentSample}; /// # Example /// /// ```rust -/// use rand::distributions::{IndependentSample, Range}; +/// use std::rand; +/// use std::rand::distributions::{IndependentSample, Range}; /// /// fn main() { /// let between = Range::new(10u, 10000u); @@ -161,8 +164,8 @@ float_impl! { f64 } #[cfg(test)] mod tests { + use std::prelude::*; use distributions::{Sample, IndependentSample}; - use {Rng, task_rng}; use super::Range; use std::num::Bounded; @@ -179,7 +182,7 @@ mod tests { #[test] fn test_integers() { - let mut rng = task_rng(); + let mut rng = ::test::rng(); macro_rules! t ( ($($ty:ty),*) => {{ $( @@ -204,7 +207,7 @@ mod tests { #[test] fn test_floats() { - let mut rng = task_rng(); + let mut rng = ::test::rng(); macro_rules! t ( ($($ty:ty),*) => {{ $( diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 1d9da40f18b..83b86e1e158 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -10,11 +10,12 @@ //! The ISAAC random number generator. -use {Rng, SeedableRng, OSRng}; -use std::io::IoResult; -use std::iter::{range_step, Repeat}; -use std::slice::raw; -use std::mem; +use core::prelude::*; +use core::iter::{range_step, Repeat}; +use core::slice::raw; +use core::mem; + +use {Rng, SeedableRng, Rand}; static RAND_SIZE_LEN: u32 = 8; static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN; @@ -23,7 +24,7 @@ static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN; /// /// The ISAAC algorithm is generally accepted as suitable for /// cryptographic purposes, but this implementation has not be -/// verified as such. Prefer a generator like `OSRng` that defers to +/// verified as such. Prefer a generator like `OsRng` that defers to /// the operating system for cases that need high security. /// /// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number @@ -44,26 +45,6 @@ static EMPTY: IsaacRng = IsaacRng { }; impl IsaacRng { - /// Create an ISAAC random number generator with a random seed. - /// - /// This reads randomness from the operating system (via `OSRng`) - /// which may fail, any error is propagated via the `IoResult` - /// return value. - pub fn new() -> IoResult<IsaacRng> { - let mut rng = EMPTY; - let mut os_rng = try!(OSRng::new()); - unsafe { - let ptr = rng.rsl.as_mut_ptr(); - - raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| { - os_rng.fill_bytes(slice); - }) - } - - rng.init(true); - Ok(rng) - } - /// Create an ISAAC random number generator using the default /// fixed seed. pub fn new_unseeded() -> IsaacRng { @@ -221,6 +202,26 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng { } } +impl Rand for IsaacRng { + fn rand<R: Rng>(other: &mut R) -> IsaacRng { + let mut ret = EMPTY; + unsafe { + let ptr = ret.rsl.as_mut_ptr(); + + raw::mut_buf_as_slice(ptr as *mut u8, + mem::size_of_val(&ret.rsl), |slice| { + other.fill_bytes(slice); + }) + } + ret.cnt = 0; + ret.a = 0; + ret.b = 0; + ret.c = 0; + + ret.init(true); + return ret; + } +} static RAND_SIZE_64_LEN: uint = 8; static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN; @@ -230,7 +231,7 @@ static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN; /// /// The ISAAC algorithm is generally accepted as suitable for /// cryptographic purposes, but this implementation has not be -/// verified as such. Prefer a generator like `OSRng` that defers to +/// verified as such. Prefer a generator like `OsRng` that defers to /// the operating system for cases that need high security. /// /// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number @@ -252,28 +253,6 @@ static EMPTY_64: Isaac64Rng = Isaac64Rng { }; impl Isaac64Rng { - /// Create a 64-bit ISAAC random number generator with a random - /// seed. - /// - /// This reads randomness from the operating system (via `OSRng`) - /// which may fail, any error is propagated via the `IoResult` - /// return value. - pub fn new() -> IoResult<Isaac64Rng> { - let mut rng = EMPTY_64; - let mut os_rng = try!(OSRng::new()); - - unsafe { - let ptr = rng.rsl.as_mut_ptr(); - - raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| { - os_rng.fill_bytes(slice); - }) - } - - rng.init(true); - Ok(rng) - } - /// Create a 64-bit ISAAC random number generator using the /// default fixed seed. pub fn new_unseeded() -> Isaac64Rng { @@ -437,24 +416,50 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng { } } +impl Rand for Isaac64Rng { + fn rand<R: Rng>(other: &mut R) -> Isaac64Rng { + let mut ret = EMPTY_64; + unsafe { + let ptr = ret.rsl.as_mut_ptr(); + + raw::mut_buf_as_slice(ptr as *mut u8, + mem::size_of_val(&ret.rsl), |slice| { + other.fill_bytes(slice); + }) + } + ret.cnt = 0; + ret.a = 0; + ret.b = 0; + ret.c = 0; + + ret.init(true); + return ret; + } +} + #[cfg(test)] mod test { + use std::prelude::*; + + use core::iter::order; + use {Rng, SeedableRng}; use super::{IsaacRng, Isaac64Rng}; - use {Rng, SeedableRng, task_rng}; #[test] fn test_rng_32_rand_seeded() { - let s = task_rng().gen_vec::<u32>(256); + let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>(); let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice()); let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice()); - assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u)); + assert!(order::equals(ra.gen_ascii_chars().take(100), + rb.gen_ascii_chars().take(100))); } #[test] fn test_rng_64_rand_seeded() { - let s = task_rng().gen_vec::<u64>(256); + let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>(); let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice()); let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice()); - assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u)); + assert!(order::equals(ra.gen_ascii_chars().take(100), + rb.gen_ascii_chars().take(100))); } #[test] @@ -462,36 +467,38 @@ mod test { let seed = &[1, 23, 456, 7890, 12345]; let mut ra: IsaacRng = SeedableRng::from_seed(seed); let mut rb: IsaacRng = SeedableRng::from_seed(seed); - assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u)); + assert!(order::equals(ra.gen_ascii_chars().take(100), + rb.gen_ascii_chars().take(100))); } #[test] fn test_rng_64_seeded() { let seed = &[1, 23, 456, 7890, 12345]; let mut ra: Isaac64Rng = SeedableRng::from_seed(seed); let mut rb: Isaac64Rng = SeedableRng::from_seed(seed); - assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u)); + assert!(order::equals(ra.gen_ascii_chars().take(100), + rb.gen_ascii_chars().take(100))); } #[test] fn test_rng_32_reseed() { - let s = task_rng().gen_vec::<u32>(256); + let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>(); let mut r: IsaacRng = SeedableRng::from_seed(s.as_slice()); - let string1 = r.gen_ascii_str(100); + let string1: String = r.gen_ascii_chars().take(100).collect(); r.reseed(s.as_slice()); - let string2 = r.gen_ascii_str(100); + let string2: String = r.gen_ascii_chars().take(100).collect(); assert_eq!(string1, string2); } #[test] fn test_rng_64_reseed() { - let s = task_rng().gen_vec::<u64>(256); + let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>(); let mut r: Isaac64Rng = SeedableRng::from_seed(s.as_slice()); - let string1 = r.gen_ascii_str(100); + let string1: String = r.gen_ascii_chars().take(100).collect(); r.reseed(s.as_slice()); - let string2 = r.gen_ascii_str(100); + let string2: String = r.gen_ascii_chars().take(100).collect(); assert_eq!(string1, string2); } diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 4a11b692076..353ac4cfed1 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -8,96 +8,45 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! -Utilities for random number generation - -The key functions are `random()` and `Rng::gen()`. These are polymorphic -and so can be used to generate any type that implements `Rand`. Type inference -means that often a simple call to `rand::random()` or `rng.gen()` will -suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`. - -See the `distributions` submodule for sampling random numbers from -distributions like normal and exponential. - -# Task-local RNG - -There is built-in support for a RNG associated with each task stored -in task-local storage. This RNG can be accessed via `task_rng`, or -used implicitly via `random`. This RNG is normally randomly seeded -from an operating-system source of randomness, e.g. `/dev/urandom` on -Unix systems, and will automatically reseed itself from this source -after generating 32 KiB of random data. - -# Cryptographic security - -An application that requires an entropy source for cryptographic purposes -must use `OSRng`, which reads randomness from the source that the operating -system provides (e.g. `/dev/urandom` on Unixes or `CryptGenRandom()` on Windows). -The other random number generators provided by this module are not suitable -for such purposes. - -*Note*: many Unix systems provide `/dev/random` as well as `/dev/urandom`. -This module uses `/dev/urandom` for the following reasons: - -- On Linux, `/dev/random` may block if entropy pool is empty; `/dev/urandom` will not block. - This does not mean that `/dev/random` provides better output than - `/dev/urandom`; the kernel internally runs a cryptographically secure pseudorandom - number generator (CSPRNG) based on entropy pool for random number generation, - so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases. - However, this means that `/dev/urandom` can yield somewhat predictable randomness - if the entropy pool is very small, such as immediately after first booting. - If an application likely to be run soon after first booting, or on a system with very - few entropy sources, one should consider using `/dev/random` via `ReaderRng`. -- On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference - between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random` - and `/dev/urandom` may block once if the CSPRNG has not seeded yet.) - -# Examples - -```rust -use rand::Rng; - -let mut rng = rand::task_rng(); -if rng.gen() { // bool - println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>()) -} -``` - -```rust -let tuple_ptr = rand::random::<Box<(f64, char)>>(); -println!("{}", tuple_ptr) -``` -*/ +//! Interface to random number generators in Rust. +//! +//! This is an experimental library which lives underneath the standard library +//! in its dependency chain. This library is intended to define the interface +//! for random number generation and also provide utilities around doing so. It +//! is not recommended to use this library directly, but rather the official +//! interface through `std::rand`. #![crate_id = "rand#0.11.0-pre"] #![license = "MIT/ASL2"] -#![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/")] -#![feature(macro_rules, managed_boxes, phase)] -#![deny(deprecated_owned_vector)] +#![feature(macro_rules, phase, globs)] +#![no_std] +#![experimental] + +#[phase(syntax, link)] +extern crate core; +#[cfg(test)] extern crate native; #[cfg(test)] extern crate debug; +#[cfg(test)] #[phase(syntax, link)] extern crate std; #[cfg(test)] #[phase(syntax, link)] extern crate log; -use std::io::IoResult; -use std::kinds::marker; -use std::mem; -use std::string::String; +use core::prelude::*; pub use isaac::{IsaacRng, Isaac64Rng}; -pub use os::OSRng; use distributions::{Range, IndependentSample}; use distributions::range::SampleRange; +#[cfg(test)] +static RAND_BENCH_N: u64 = 100; + pub mod distributions; pub mod isaac; -pub mod os; -pub mod reader; pub mod reseeding; mod rand_impls; @@ -148,7 +97,7 @@ pub trait Rng { /// # Example /// /// ```rust - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// /// let mut v = [0u8, .. 13579]; /// task_rng().fill_bytes(v); @@ -183,7 +132,7 @@ pub trait Rng { /// # Example /// /// ```rust - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// /// let mut rng = task_rng(); /// let x: uint = rng.gen(); @@ -195,20 +144,22 @@ pub trait Rng { Rand::rand(self) } - /// Return a random vector of the specified length. + /// Return an iterator which will yield an infinite number of randomly + /// generated items. /// /// # Example /// - /// ```rust - /// use rand::{task_rng, Rng}; + /// ``` + /// use std::rand::{task_rng, Rng}; /// /// let mut rng = task_rng(); - /// let x: Vec<uint> = rng.gen_vec(10); + /// let x = rng.gen_iter::<uint>().take(10).collect::<Vec<uint>>(); /// println!("{}", x); - /// println!("{}", rng.gen_vec::<(f64, bool)>(5)); + /// println!("{}", rng.gen_iter::<(f64, bool)>().take(5) + /// .collect::<Vec<(f64, bool)>>()); /// ``` - fn gen_vec<T: Rand>(&mut self, len: uint) -> Vec<T> { - Vec::from_fn(len, |_| self.gen()) + fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> { + Generator { rng: self } } /// Generate a random value in the range [`low`, `high`). Fails if @@ -223,7 +174,7 @@ pub trait Rng { /// # Example /// /// ```rust - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// /// let mut rng = task_rng(); /// let n: uint = rng.gen_range(0u, 10); @@ -241,7 +192,7 @@ pub trait Rng { /// # Example /// /// ```rust - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// /// let mut rng = task_rng(); /// println!("{:b}", rng.gen_weighted_bool(3)); @@ -250,25 +201,18 @@ pub trait Rng { n == 0 || self.gen_range(0, n) == 0 } - /// Return a random string of the specified length composed of - /// A-Z,a-z,0-9. + /// Return an iterator of random characters from the set A-Z,a-z,0-9. /// /// # Example /// /// ```rust - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// - /// println!("{}", task_rng().gen_ascii_str(10)); + /// let s: String = task_rng().gen_ascii_chars().take(10).collect(); + /// println!("{}", s); /// ``` - fn gen_ascii_str(&mut self, len: uint) -> String { - static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\ - abcdefghijklmnopqrstuvwxyz\ - 0123456789"); - let mut s = String::with_capacity(len); - for _ in range(0, len) { - s.push_char(*self.choose(GEN_ASCII_STR_CHARSET).unwrap() as char) - } - s + fn gen_ascii_chars<'a>(&'a mut self) -> AsciiGenerator<'a, Self> { + AsciiGenerator { rng: self } } /// Return a random element from `values`. @@ -278,7 +222,7 @@ pub trait Rng { /// # Example /// /// ``` - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// /// let choices = [1, 2, 4, 8, 16, 32]; /// let mut rng = task_rng(); @@ -304,7 +248,7 @@ pub trait Rng { /// # Example /// /// ```rust - /// use rand::{task_rng, Rng}; + /// use std::rand::{task_rng, Rng}; /// /// let mut rng = task_rng(); /// let mut y = [1,2,3]; @@ -322,32 +266,35 @@ pub trait Rng { values.swap(i, self.gen_range(0u, i + 1u)); } } +} - /// Randomly sample up to `n` elements from an iterator. - /// - /// # Example - /// - /// ```rust - /// use rand::{task_rng, Rng}; - /// - /// let mut rng = task_rng(); - /// let sample = rng.sample(range(1, 100), 5); - /// println!("{}", sample); - /// ``` - fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> Vec<A> { - let mut reservoir = Vec::with_capacity(n); - for (i, elem) in iter.enumerate() { - if i < n { - reservoir.push(elem); - continue - } +/// Iterator which will generate a stream of random items. +/// +/// This iterator is created via the `gen_iter` method on `Rng`. +pub struct Generator<'a, T, R> { + rng: &'a mut R, +} - let k = self.gen_range(0, i + 1); - if k < reservoir.len() { - *reservoir.get_mut(k) = elem - } - } - reservoir +impl<'a, T: Rand, R: Rng> Iterator<T> for Generator<'a, T, R> { + fn next(&mut self) -> Option<T> { + Some(self.rng.gen()) + } +} + +/// Iterator which will continuously generate random ascii characters. +/// +/// This iterator is created via the `gen_ascii_chars` method on `Rng`. +pub struct AsciiGenerator<'a, R> { + rng: &'a mut R, +} + +impl<'a, R: Rng> Iterator<char> for AsciiGenerator<'a, R> { + fn next(&mut self) -> Option<char> { + static GEN_ASCII_STR_CHARSET: &'static [u8] = + bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\ + abcdefghijklmnopqrstuvwxyz\ + 0123456789"); + Some(*self.rng.choose(GEN_ASCII_STR_CHARSET).unwrap() as char) } } @@ -359,7 +306,7 @@ pub trait SeedableRng<Seed>: Rng { /// # Example /// /// ```rust - /// use rand::{Rng, SeedableRng, StdRng}; + /// use std::rand::{Rng, SeedableRng, StdRng}; /// /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]); /// println!("{}", rng.gen::<f64>()); @@ -373,7 +320,7 @@ pub trait SeedableRng<Seed>: Rng { /// # Example /// /// ```rust - /// use rand::{Rng, SeedableRng, StdRng}; + /// use std::rand::{Rng, SeedableRng, StdRng}; /// /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]); /// println!("{}", rng.gen::<f64>()); @@ -381,95 +328,12 @@ pub trait SeedableRng<Seed>: Rng { fn from_seed(seed: Seed) -> Self; } -/// The standard RNG. This is designed to be efficient on the current -/// platform. -#[cfg(not(target_word_size="64"))] -pub struct StdRng { rng: IsaacRng } - -/// The standard RNG. This is designed to be efficient on the current -/// platform. -#[cfg(target_word_size="64")] -pub struct StdRng { rng: Isaac64Rng } - -impl StdRng { - /// Create a randomly seeded instance of `StdRng`. - /// - /// This is a very expensive operation as it has to read - /// randomness from the operating system and use this in an - /// expensive seeding operation. If one is only generating a small - /// number of random numbers, or doesn't need the utmost speed for - /// generating each number, `task_rng` and/or `random` may be more - /// appropriate. - /// - /// Reading the randomness from the OS may fail, and any error is - /// propagated via the `IoResult` return value. - #[cfg(not(target_word_size="64"))] - pub fn new() -> IoResult<StdRng> { - IsaacRng::new().map(|r| StdRng { rng: r }) - } - /// Create a randomly seeded instance of `StdRng`. - /// - /// This is a very expensive operation as it has to read - /// randomness from the operating system and use this in an - /// expensive seeding operation. If one is only generating a small - /// number of random numbers, or doesn't need the utmost speed for - /// generating each number, `task_rng` and/or `random` may be more - /// appropriate. - /// - /// Reading the randomness from the OS may fail, and any error is - /// propagated via the `IoResult` return value. - #[cfg(target_word_size="64")] - pub fn new() -> IoResult<StdRng> { - Isaac64Rng::new().map(|r| StdRng { rng: r }) - } -} - -impl Rng for StdRng { - #[inline] - fn next_u32(&mut self) -> u32 { - self.rng.next_u32() - } - - #[inline] - fn next_u64(&mut self) -> u64 { - self.rng.next_u64() - } -} - -impl<'a> SeedableRng<&'a [uint]> for StdRng { - fn reseed(&mut self, seed: &'a [uint]) { - // the internal RNG can just be seeded from the above - // randomness. - self.rng.reseed(unsafe {mem::transmute(seed)}) - } - - fn from_seed(seed: &'a [uint]) -> StdRng { - StdRng { rng: SeedableRng::from_seed(unsafe {mem::transmute(seed)}) } - } -} - -/// Create a weak random number generator with a default algorithm and seed. -/// -/// It returns the fastest `Rng` algorithm currently available in Rust without -/// consideration for cryptography or security. If you require a specifically -/// seeded `Rng` for consistency over time you should pick one algorithm and -/// create the `Rng` yourself. -/// -/// This will read randomness from the operating system to seed the -/// generator. -pub fn weak_rng() -> XorShiftRng { - match XorShiftRng::new() { - Ok(r) => r, - Err(e) => fail!("weak_rng: failed to create seeded RNG: {}", e) - } -} - /// An Xorshift[1] random number /// generator. /// /// The Xorshift algorithm is not suitable for cryptographic purposes /// but is very fast. If you do not know for sure that it fits your -/// requirements, use a more secure one such as `IsaacRng` or `OSRng`. +/// requirements, use a more secure one such as `IsaacRng` or `OsRng`. /// /// [1]: Marsaglia, George (July 2003). ["Xorshift /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of @@ -481,6 +345,23 @@ pub struct XorShiftRng { w: u32, } +impl XorShiftRng { + /// Creates a new XorShiftRng instance which is not seeded. + /// + /// The initial values of this RNG are constants, so all generators created + /// by this function will yield the same stream of random numbers. It is + /// highly recommended that this is created through `SeedableRng` instead of + /// this function + pub fn new_unseeded() -> XorShiftRng { + XorShiftRng { + x: 0x193a6754, + y: 0xa8a7d469, + z: 0x97830e05, + w: 0x113ba7bb, + } + } +} + impl Rng for XorShiftRng { #[inline] fn next_u32(&mut self) -> u32 { @@ -521,122 +402,16 @@ impl SeedableRng<[u32, .. 4]> for XorShiftRng { } } -impl XorShiftRng { - /// Create an xor shift random number generator with a random seed. - pub fn new() -> IoResult<XorShiftRng> { - let mut s = [0u8, ..16]; - let mut r = try!(OSRng::new()); - loop { - r.fill_bytes(s); - - if !s.iter().all(|x| *x == 0) { - break; - } - } - let s: [u32, ..4] = unsafe { mem::transmute(s) }; - Ok(SeedableRng::from_seed(s)) - } -} - -/// Controls how the task-local RNG is reseeded. -struct TaskRngReseeder; - -impl reseeding::Reseeder<StdRng> for TaskRngReseeder { - fn reseed(&mut self, rng: &mut StdRng) { - *rng = match StdRng::new() { - Ok(r) => r, - Err(e) => fail!("could not reseed task_rng: {}", e) +impl Rand for XorShiftRng { + fn rand<R: Rng>(rng: &mut R) -> XorShiftRng { + let mut tuple: (u32, u32, u32, u32) = rng.gen(); + while tuple == (0, 0, 0, 0) { + tuple = rng.gen(); } + let (x, y, z, w) = tuple; + XorShiftRng { x: x, y: y, z: z, w: w } } } -static TASK_RNG_RESEED_THRESHOLD: uint = 32_768; -type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>; -/// The task-local RNG. -pub struct TaskRng { - // This points into TLS (specifically, it points to the endpoint - // of a Box stored in TLS, to make it robust against TLS moving - // things internally) and so this struct cannot be legally - // transferred between tasks *and* it's unsafe to deallocate the - // RNG other than when a task is finished. - // - // The use of unsafe code here is OK if the invariants above are - // satisfied; and it allows us to avoid (unnecessarily) using a - // GC'd or RC'd pointer. - rng: *mut TaskRngInner, - marker: marker::NoSend, -} - -/// Retrieve the lazily-initialized task-local random number -/// generator, seeded by the system. Intended to be used in method -/// chaining style, e.g. `task_rng().gen::<int>()`. -/// -/// The RNG provided will reseed itself from the operating system -/// after generating a certain amount of randomness. -/// -/// The internal RNG used is platform and architecture dependent, even -/// if the operating system random number generator is rigged to give -/// the same sequence always. If absolute consistency is required, -/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`. -pub fn task_rng() -> TaskRng { - // used to make space in TLS for a random number generator - local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>) - - match TASK_RNG_KEY.get() { - None => { - let r = match StdRng::new() { - Ok(r) => r, - Err(e) => fail!("could not initialize task_rng: {}", e) - }; - let mut rng = box reseeding::ReseedingRng::new(r, - TASK_RNG_RESEED_THRESHOLD, - TaskRngReseeder); - let ptr = &mut *rng as *mut TaskRngInner; - - TASK_RNG_KEY.replace(Some(rng)); - - TaskRng { rng: ptr, marker: marker::NoSend } - } - Some(rng) => TaskRng { - rng: &**rng as *_ as *mut TaskRngInner, - marker: marker::NoSend - } - } -} - -impl Rng for TaskRng { - fn next_u32(&mut self) -> u32 { - unsafe { (*self.rng).next_u32() } - } - - fn next_u64(&mut self) -> u64 { - unsafe { (*self.rng).next_u64() } - } - - #[inline] - fn fill_bytes(&mut self, bytes: &mut [u8]) { - unsafe { (*self.rng).fill_bytes(bytes) } - } -} - -/// Generate a random value using the task-local random number -/// generator. -/// -/// # Example -/// -/// ```rust -/// use rand::random; -/// -/// if random() { -/// let x = random(); -/// println!("{}", 2u * x); -/// } else { -/// println!("{}", random::<f64>()); -/// } -/// ``` -#[inline] -pub fn random<T: Rand>() -> T { - task_rng().gen() -} /// A wrapper for generating floating point numbers uniformly in the /// open interval `(0,1)` (not including either endpoint). @@ -647,7 +422,7 @@ pub fn random<T: Rand>() -> T { /// /// # Example /// ```rust -/// use rand::{random, Open01}; +/// use std::rand::{random, Open01}; /// /// let Open01(val) = random::<Open01<f32>>(); /// println!("f32 from (0,1): {}", val); @@ -662,263 +437,41 @@ pub struct Open01<F>(pub F); /// `[0,1)`. /// /// # Example +/// /// ```rust -/// use rand::{random, Closed01}; +/// use std::rand::{random, Closed01}; /// /// let Closed01(val) = random::<Closed01<f32>>(); /// println!("f32 from [0,1]: {}", val); /// ``` pub struct Closed01<F>(pub F); -#[cfg(test)] -mod test { - use super::{Rng, task_rng, random, SeedableRng, StdRng}; - - struct ConstRng { i: u64 } - impl Rng for ConstRng { - fn next_u32(&mut self) -> u32 { self.i as u32 } - fn next_u64(&mut self) -> u64 { self.i } - - // no fill_bytes on purpose - } - - #[test] - fn test_fill_bytes_default() { - let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 }; - - // check every remainder mod 8, both in small and big vectors. - let lengths = [0, 1, 2, 3, 4, 5, 6, 7, - 80, 81, 82, 83, 84, 85, 86, 87]; - for &n in lengths.iter() { - let mut v = Vec::from_elem(n, 0u8); - r.fill_bytes(v.as_mut_slice()); - - // use this to get nicer error messages. - for (i, &byte) in v.iter().enumerate() { - if byte == 0 { - fail!("byte {} of {} is zero", i, n) - } - } - } - } - - #[test] - fn test_gen_range() { - let mut r = task_rng(); - for _ in range(0, 1000) { - let a = r.gen_range(-3i, 42); - assert!(a >= -3 && a < 42); - assert_eq!(r.gen_range(0, 1), 0); - assert_eq!(r.gen_range(-12, -11), -12); - } - - for _ in range(0, 1000) { - let a = r.gen_range(10, 42); - assert!(a >= 10 && a < 42); - assert_eq!(r.gen_range(0, 1), 0); - assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000); - } - - } - - #[test] - #[should_fail] - fn test_gen_range_fail_int() { - let mut r = task_rng(); - r.gen_range(5i, -2); - } - - #[test] - #[should_fail] - fn test_gen_range_fail_uint() { - let mut r = task_rng(); - r.gen_range(5u, 2u); - } - - #[test] - fn test_gen_f64() { - let mut r = task_rng(); - let a = r.gen::<f64>(); - let b = r.gen::<f64>(); - debug!("{:?}", (a, b)); - } - - #[test] - fn test_gen_weighted_bool() { - let mut r = task_rng(); - assert_eq!(r.gen_weighted_bool(0u), true); - assert_eq!(r.gen_weighted_bool(1u), true); - } - - #[test] - fn test_gen_ascii_str() { - let mut r = task_rng(); - debug!("{}", r.gen_ascii_str(10u)); - debug!("{}", r.gen_ascii_str(10u)); - debug!("{}", r.gen_ascii_str(10u)); - assert_eq!(r.gen_ascii_str(0u).len(), 0u); - assert_eq!(r.gen_ascii_str(10u).len(), 10u); - assert_eq!(r.gen_ascii_str(16u).len(), 16u); - } - - #[test] - fn test_gen_vec() { - let mut r = task_rng(); - assert_eq!(r.gen_vec::<u8>(0u).len(), 0u); - assert_eq!(r.gen_vec::<u8>(10u).len(), 10u); - assert_eq!(r.gen_vec::<f64>(16u).len(), 16u); - } - - #[test] - fn test_choose() { - let mut r = task_rng(); - assert_eq!(r.choose([1, 1, 1]).map(|&x|x), Some(1)); - - let v: &[int] = &[]; - assert_eq!(r.choose(v), None); - } - - #[test] - fn test_shuffle() { - let mut r = task_rng(); - let empty: &mut [int] = &mut []; - r.shuffle(empty); - let mut one = [1]; - r.shuffle(one); - assert_eq!(one.as_slice(), &[1]); - - let mut two = [1, 2]; - r.shuffle(two); - assert!(two == [1, 2] || two == [2, 1]); - - let mut x = [1, 1, 1]; - r.shuffle(x); - assert_eq!(x.as_slice(), &[1, 1, 1]); - } - - #[test] - fn test_task_rng() { - let mut r = task_rng(); - r.gen::<int>(); - let mut v = [1, 1, 1]; - r.shuffle(v); - assert_eq!(v.as_slice(), &[1, 1, 1]); - assert_eq!(r.gen_range(0u, 1u), 0u); - } - - #[test] - fn test_random() { - // not sure how to test this aside from just getting some values - let _n : uint = random(); - let _f : f32 = random(); - let _o : Option<Option<i8>> = random(); - let _many : ((), - (Box<uint>, - @int, - Box<Option<Box<(@u32, Box<(@bool,)>)>>>), - (u8, i8, u16, i16, u32, i32, u64, i64), - (f32, (f64, (f64,)))) = random(); - } - - #[test] - fn test_sample() { - let min_val = 1; - let max_val = 100; - - let mut r = task_rng(); - let vals = range(min_val, max_val).collect::<Vec<int>>(); - let small_sample = r.sample(vals.iter(), 5); - let large_sample = r.sample(vals.iter(), vals.len() + 5); - - assert_eq!(small_sample.len(), 5); - assert_eq!(large_sample.len(), vals.len()); - - assert!(small_sample.iter().all(|e| { - **e >= min_val && **e <= max_val - })); - } - - #[test] - fn test_std_rng_seeded() { - let s = task_rng().gen_vec::<uint>(256); - let mut ra: StdRng = SeedableRng::from_seed(s.as_slice()); - let mut rb: StdRng = SeedableRng::from_seed(s.as_slice()); - assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u)); - } - - #[test] - fn test_std_rng_reseed() { - let s = task_rng().gen_vec::<uint>(256); - let mut r: StdRng = SeedableRng::from_seed(s.as_slice()); - let string1 = r.gen_ascii_str(100); - - r.reseed(s.as_slice()); - - let string2 = r.gen_ascii_str(100); - assert_eq!(string1, string2); - } +#[cfg(not(test))] +mod std { + pub use core::{option, fmt}; // fail!() } #[cfg(test)] -static RAND_BENCH_N: u64 = 100; - -#[cfg(test)] -mod bench { - extern crate test; - use self::test::Bencher; - use {XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N}; - use std::mem::size_of; - - #[bench] - fn rand_xorshift(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); - b.iter(|| { - for _ in range(0, RAND_BENCH_N) { - rng.gen::<uint>(); - } - }); - b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; - } +mod test { + use std::rand; - #[bench] - fn rand_isaac(b: &mut Bencher) { - let mut rng = IsaacRng::new().unwrap(); - b.iter(|| { - for _ in range(0, RAND_BENCH_N) { - rng.gen::<uint>(); - } - }); - b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; - } + pub struct MyRng<R> { inner: R } - #[bench] - fn rand_isaac64(b: &mut Bencher) { - let mut rng = Isaac64Rng::new().unwrap(); - b.iter(|| { - for _ in range(0, RAND_BENCH_N) { - rng.gen::<uint>(); + impl<R: rand::Rng> ::Rng for MyRng<R> { + fn next_u32(&mut self) -> u32 { + fn next<T: rand::Rng>(t: &mut T) -> u32 { + use std::rand::Rng; + t.next_u32() } - }); - b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; + next(&mut self.inner) + } } - #[bench] - fn rand_std(b: &mut Bencher) { - let mut rng = StdRng::new().unwrap(); - b.iter(|| { - for _ in range(0, RAND_BENCH_N) { - rng.gen::<uint>(); - } - }); - b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; + pub fn rng() -> MyRng<rand::TaskRng> { + MyRng { inner: rand::task_rng() } } - #[bench] - fn rand_shuffle_100(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); - let x : &mut[uint] = [1,..100]; - b.iter(|| { - rng.shuffle(x); - }) + pub fn weak_rng() -> MyRng<rand::XorShiftRng> { + MyRng { inner: rand::weak_rng() } } } diff --git a/src/librand/rand_impls.rs b/src/librand/rand_impls.rs index 5846cb5f312..458a9ba378d 100644 --- a/src/librand/rand_impls.rs +++ b/src/librand/rand_impls.rs @@ -10,9 +10,10 @@ //! The implementations of `Rand` for the built-in types. -use std::char; -use std::int; -use std::uint; +use core::prelude::*; +use core::char; +use core::int; +use core::uint; use {Rand,Rng}; @@ -214,19 +215,10 @@ impl<T:Rand> Rand for Option<T> { } } -impl<T: Rand> Rand for Box<T> { - #[inline] - fn rand<R: Rng>(rng: &mut R) -> Box<T> { box rng.gen() } -} - -impl<T: Rand + 'static> Rand for @T { - #[inline] - fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() } -} - #[cfg(test)] mod tests { - use {Rng, task_rng, Open01, Closed01}; + use std::prelude::*; + use std::rand::{Rng, task_rng, Open01, Closed01}; struct ConstantRng(u64); impl Rng for ConstantRng { diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs index fe2ff319c1c..09265f28c36 100644 --- a/src/librand/reseeding.rs +++ b/src/librand/reseeding.rs @@ -11,8 +11,10 @@ //! A wrapper around another RNG that reseeds it after it //! generates a certain number of random bytes. -use std::default::Default; +use core::prelude::*; + use {Rng, SeedableRng}; +use core::default::Default; /// How many bytes of entropy the underling RNG is allowed to generate /// before it is reseeded. @@ -76,13 +78,14 @@ impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> { } } -impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>> +impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default> SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> { fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) { self.rng.reseed(seed); self.reseeder = rsdr; self.bytes_generated = 0; } + /// Create a new `ReseedingRng` from the given reseeder and /// seed. This uses a default value for `generation_threshold`. fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> { @@ -100,8 +103,8 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>> /// # Example /// /// ```rust -/// use rand::{Rng, SeedableRng, StdRng}; -/// use rand::reseeding::{Reseeder, ReseedingRng}; +/// use std::rand::{Rng, SeedableRng, StdRng}; +/// use std::rand::reseeding::{Reseeder, ReseedingRng}; /// /// struct TickTockReseeder { tick: bool } /// impl Reseeder<StdRng> for TickTockReseeder { @@ -118,7 +121,8 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>> /// let mut rng = ReseedingRng::new(inner, 10, rsdr); /// /// // this will repeat, because it gets reseeded very regularly. -/// println!("{}", rng.gen_ascii_str(100)); +/// let s: String = rng.gen_ascii_chars().take(100).collect(); +/// println!("{}", s); /// } /// /// ``` @@ -142,6 +146,9 @@ impl Default for ReseedWithDefault { #[cfg(test)] mod test { + use std::prelude::*; + + use core::iter::order; use super::{ReseedingRng, ReseedWithDefault}; use std::default::Default; use {SeedableRng, Rng}; @@ -187,26 +194,26 @@ mod test { fn test_rng_seeded() { let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2)); let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2)); - assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u)); + assert!(order::equals(ra.gen_ascii_chars().take(100), + rb.gen_ascii_chars().take(100))); } #[test] fn test_rng_reseed() { let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3)); - let string1 = r.gen_ascii_str(100); + let string1: String = r.gen_ascii_chars().take(100).collect(); r.reseed((ReseedWithDefault, 3)); - let string2 = r.gen_ascii_str(100); + let string2: String = r.gen_ascii_chars().take(100).collect(); assert_eq!(string1, string2); } static fill_bytes_v_len: uint = 13579; #[test] fn test_rng_fill_bytes() { - use task_rng; let mut v = Vec::from_elem(fill_bytes_v_len, 0u8); - task_rng().fill_bytes(v.as_mut_slice()); + ::test::rng().fill_bytes(v.as_mut_slice()); // Sanity test: if we've gotten here, `fill_bytes` has not infinitely // recursed. diff --git a/src/libregex/re.rs b/src/libregex/re.rs index 83c1cb37158..61cf1604cd5 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -573,13 +573,13 @@ impl<'t> Replacer for NoExpand<'t> { impl<'t> Replacer for &'t str { fn reg_replace<'a>(&'a mut self, caps: &Captures) -> MaybeOwned<'a> { - Owned(caps.expand(*self).into_owned()) + Owned(caps.expand(*self)) } } impl<'a> Replacer for |&Captures|: 'a -> String { fn reg_replace<'r>(&'r mut self, caps: &Captures) -> MaybeOwned<'r> { - Owned((*self)(caps).into_owned()) + Owned((*self)(caps)) } } diff --git a/src/libregex/test/bench.rs b/src/libregex/test/bench.rs index 8dc6484a136..0e4581a401e 100644 --- a/src/libregex/test/bench.rs +++ b/src/libregex/test/bench.rs @@ -7,10 +7,12 @@ // <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. +#![allow(non_snake_case_functions)] -use rand::{Rng, task_rng}; -use stdtest::Bencher; +use std::rand::{Rng, task_rng}; use std::str; +use stdtest::Bencher; + use regex::{Regex, NoExpand}; fn bench_assert_match(b: &mut Bencher, re: Regex, text: &str) { @@ -152,10 +154,10 @@ fn easy1() -> Regex { regex!("A[AB]B[BC]C[CD]D[DE]E[EF]F[FG]G[GH]H[HI]I[IJ]J$") fn medium() -> Regex { regex!("[XYZ]ABCDEFGHIJKLMNOPQRSTUVWXYZ$") } fn hard() -> Regex { regex!("[ -~]*ABCDEFGHIJKLMNOPQRSTUVWXYZ$") } -#[allow(deprecated_owned_vector)] fn gen_text(n: uint) -> String { let mut rng = task_rng(); - let mut bytes = rng.gen_ascii_str(n).into_bytes(); + let mut bytes = rng.gen_ascii_chars().map(|n| n as u8).take(n) + .collect::<Vec<u8>>(); for (i, b) in bytes.mut_iter().enumerate() { if i % 20 == 0 { *b = '\n' as u8 diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 189562df2d0..5f53cd85705 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -69,7 +69,7 @@ pub fn llvm_err(sess: &Session, msg: String) -> ! { } } -pub fn WriteOutputFile( +pub fn write_output_file( sess: &Session, target: lib::llvm::TargetMachineRef, pm: lib::llvm::PassManagerRef, @@ -90,7 +90,7 @@ pub fn WriteOutputFile( pub mod write { use back::lto; - use back::link::{WriteOutputFile, OutputType}; + use back::link::{write_output_file, OutputType}; use back::link::{OutputTypeAssembly, OutputTypeBitcode}; use back::link::{OutputTypeExe, OutputTypeLlvmAssembly}; use back::link::{OutputTypeObject}; @@ -310,7 +310,7 @@ pub mod write { output.temp_path(OutputTypeAssembly) }; with_codegen(tm, llmod, trans.no_builtins, |cpm| { - WriteOutputFile(sess, tm, cpm, llmod, &path, + write_output_file(sess, tm, cpm, llmod, &path, lib::llvm::AssemblyFile); }); } @@ -328,7 +328,7 @@ pub mod write { match object_file { Some(ref path) => { with_codegen(tm, llmod, trans.no_builtins, |cpm| { - WriteOutputFile(sess, tm, cpm, llmod, path, + write_output_file(sess, tm, cpm, llmod, path, lib::llvm::ObjectFile); }); } @@ -339,7 +339,7 @@ pub mod write { trans.no_builtins, |cpm| { let out = output.temp_path(OutputTypeObject) .with_extension("metadata.o"); - WriteOutputFile(sess, tm, cpm, + write_output_file(sess, tm, cpm, trans.metadata_module, &out, lib::llvm::ObjectFile); }) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 95a2c558836..4a36dfd7842 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,6 +10,7 @@ #![allow(non_uppercase_pattern_statics)] #![allow(non_camel_case_types)] +#![allow(non_snake_case_functions)] #![allow(dead_code)] use std::c_str::ToCStr; diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 781222a3a6e..74a804763e8 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -19,7 +19,8 @@ use middle::lang_items; use middle::ty; use middle::typeck; -use reader = serialize::ebml::reader; +use serialize::ebml; +use serialize::ebml::reader; use std::rc::Rc; use syntax::ast; use syntax::ast_map; @@ -206,7 +207,7 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId, def: ast::DefId) -> ty::ty_param_bounds_and_ty { let cstore = &tcx.sess.cstore; let cdata = cstore.get_crate_data(class_id.krate); - let all_items = reader::get_doc(reader::Doc(cdata.data()), tag_items); + let all_items = reader::get_doc(ebml::Doc::new(cdata.data()), tag_items); let class_doc = expect(tcx.sess.diagnostic(), decoder::maybe_find_item(class_id.node, all_items), || { diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index ddd493b2c13..56b320d2a07 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -99,7 +99,7 @@ fn find_item<'a>(item_id: ast::NodeId, items: ebml::Doc<'a>) -> ebml::Doc<'a> { // Looks up an item in the given metadata and returns an ebml doc pointing // to the item data. fn lookup_item<'a>(item_id: ast::NodeId, data: &'a [u8]) -> ebml::Doc<'a> { - let items = reader::get_doc(reader::Doc(data), tag_items); + let items = reader::get_doc(ebml::Doc::new(data), tag_items); find_item(item_id, items) } @@ -383,7 +383,7 @@ pub fn get_trait_def(cdata: Cmd, tag_items_data_item_ty_param_bounds); let rp_defs = item_region_param_defs(item_doc, cdata); let sized = item_sized(item_doc); - let mut bounds = ty::EmptyBuiltinBounds(); + let mut bounds = ty::empty_builtin_bounds(); // Collect the builtin bounds from the encoded supertraits. // FIXME(#8559): They should be encoded directly. reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| { @@ -443,7 +443,7 @@ pub fn get_impl_vtables(cdata: Cmd, { let item_doc = lookup_item(id, cdata.data()); let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables); - let mut decoder = reader::Decoder(vtables_doc); + let mut decoder = reader::Decoder::new(vtables_doc); typeck::impl_res { trait_vtables: decoder.read_vtable_res(tcx, cdata), @@ -466,7 +466,7 @@ pub enum DefLike { /// Iterates over the language items in the given crate. pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool { - let root = reader::Doc(cdata.data()); + let root = ebml::Doc::new(cdata.data()); let lang_items = reader::get_doc(root, tag_lang_items); reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| { let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id); @@ -506,7 +506,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>, None => cdata }; - let other_crates_items = reader::get_doc(reader::Doc(crate_data.data()), tag_items); + let other_crates_items = reader::get_doc(ebml::Doc::new(crate_data.data()), tag_items); // Get the item. match maybe_find_item(child_def_id.node, other_crates_items) { @@ -534,7 +534,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>, |inherent_impl_def_id_doc| { let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata); - let items = reader::get_doc(reader::Doc(cdata.data()), tag_items); + let items = reader::get_doc(ebml::Doc::new(cdata.data()), tag_items); match maybe_find_item(inherent_impl_def_id.node, items) { None => {} Some(inherent_impl_doc) => { @@ -599,7 +599,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>, None => cdata }; - let other_crates_items = reader::get_doc(reader::Doc(crate_data.data()), tag_items); + let other_crates_items = reader::get_doc(ebml::Doc::new(crate_data.data()), tag_items); // Get the item. match maybe_find_item(child_def_id.node, other_crates_items) { @@ -626,7 +626,7 @@ pub fn each_child_of_item(intr: Rc<IdentInterner>, get_crate_data: GetCrateDataCb, callback: |DefLike, ast::Ident, ast::Visibility|) { // Find the item. - let root_doc = reader::Doc(cdata.data()); + let root_doc = ebml::Doc::new(cdata.data()); let items = reader::get_doc(root_doc, tag_items); let item_doc = match maybe_find_item(id, items) { None => return, @@ -647,7 +647,7 @@ pub fn each_top_level_item_of_crate(intr: Rc<IdentInterner>, callback: |DefLike, ast::Ident, ast::Visibility|) { - let root_doc = reader::Doc(cdata.data()); + let root_doc = ebml::Doc::new(cdata.data()); let misc_info_doc = reader::get_doc(root_doc, tag_misc_info); let crate_items_doc = reader::get_doc(misc_info_doc, tag_misc_info_crate_items); @@ -696,7 +696,7 @@ pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId, pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> { let data = cdata.data(); - let items = reader::get_doc(reader::Doc(data), tag_items); + let items = reader::get_doc(ebml::Doc::new(data), tag_items); let item = find_item(id, items); let mut disr_val = 0; enum_variant_ids(item, cdata).iter().map(|did| { @@ -829,7 +829,7 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances { let data = cdata.data(); let item_doc = lookup_item(id, data); let variance_doc = reader::get_doc(item_doc, tag_item_variances); - let mut decoder = reader::Decoder(variance_doc); + let mut decoder = reader::Decoder::new(variance_doc); Decodable::decode(&mut decoder).unwrap() } @@ -1078,7 +1078,7 @@ fn list_crate_attributes(md: ebml::Doc, hash: &Svh, } pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> { - get_attributes(reader::Doc(data)) + get_attributes(ebml::Doc::new(data)) } #[deriving(Clone)] @@ -1090,7 +1090,7 @@ pub struct CrateDep { pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> { let mut deps: Vec<CrateDep> = Vec::new(); - let cratedoc = reader::Doc(data); + let cratedoc = ebml::Doc::new(data); let depsdoc = reader::get_doc(cratedoc, tag_crate_deps); let mut crate_num = 1; fn docstr(doc: ebml::Doc, tag_: uint) -> String { @@ -1123,40 +1123,40 @@ fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> { } pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> { - let cratedoc = reader::Doc(data); + let cratedoc = ebml::Doc::new(data); reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| { Svh::new(doc.as_str_slice()) }) } pub fn get_crate_hash(data: &[u8]) -> Svh { - let cratedoc = reader::Doc(data); + let cratedoc = ebml::Doc::new(data); let hashdoc = reader::get_doc(cratedoc, tag_crate_hash); Svh::new(hashdoc.as_str_slice()) } pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> { - let cratedoc = reader::Doc(data); + let cratedoc = ebml::Doc::new(data); reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| { from_str(doc.as_str_slice()).unwrap() }) } pub fn get_crate_triple(data: &[u8]) -> String { - let cratedoc = reader::Doc(data); + let cratedoc = ebml::Doc::new(data); let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple); triple_doc.expect("No triple in crate").as_str().to_string() } pub fn get_crate_id(data: &[u8]) -> CrateId { - let cratedoc = reader::Doc(data); + let cratedoc = ebml::Doc::new(data); let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid); from_str(hashdoc.as_str_slice()).unwrap() } pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> { let hash = get_crate_hash(bytes); - let md = reader::Doc(bytes); + let md = ebml::Doc::new(bytes); try!(list_crate_attributes(md, &hash, out)); list_crate_deps(bytes, out) } @@ -1183,7 +1183,7 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId { } pub fn each_impl(cdata: Cmd, callback: |ast::DefId|) { - let impls_doc = reader::get_doc(reader::Doc(cdata.data()), tag_impls); + let impls_doc = reader::get_doc(ebml::Doc::new(cdata.data()), tag_impls); let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| { callback(item_def_id(impl_doc, cdata)); true @@ -1239,7 +1239,7 @@ pub fn get_trait_of_method(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) pub fn get_native_libraries(cdata: Cmd) -> Vec<(cstore::NativeLibaryKind, String)> { - let libraries = reader::get_doc(reader::Doc(cdata.data()), + let libraries = reader::get_doc(ebml::Doc::new(cdata.data()), tag_native_libraries); let mut result = Vec::new(); reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| { @@ -1255,12 +1255,12 @@ pub fn get_native_libraries(cdata: Cmd) } pub fn get_macro_registrar_fn(data: &[u8]) -> Option<ast::NodeId> { - reader::maybe_get_doc(reader::Doc(data), tag_macro_registrar_fn) + reader::maybe_get_doc(ebml::Doc::new(data), tag_macro_registrar_fn) .map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap()) } pub fn get_exported_macros(data: &[u8]) -> Vec<String> { - let macros = reader::get_doc(reader::Doc(data), + let macros = reader::get_doc(ebml::Doc::new(data), tag_exported_macros); let mut result = Vec::new(); reader::tagged_docs(macros, tag_macro_def, |macro_doc| { @@ -1273,7 +1273,7 @@ pub fn get_exported_macros(data: &[u8]) -> Vec<String> { pub fn get_dylib_dependency_formats(cdata: Cmd) -> Vec<(ast::CrateNum, cstore::LinkagePreference)> { - let formats = reader::get_doc(reader::Doc(cdata.data()), + let formats = reader::get_doc(ebml::Doc::new(cdata.data()), tag_dylib_dependency_formats); let mut result = Vec::new(); @@ -1299,7 +1299,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd) pub fn get_missing_lang_items(cdata: Cmd) -> Vec<lang_items::LangItem> { - let items = reader::get_doc(reader::Doc(cdata.data()), tag_lang_items); + let items = reader::get_doc(ebml::Doc::new(cdata.data()), tag_lang_items); let mut result = Vec::new(); reader::tagged_docs(items, tag_lang_items_missing, |missing_doc| { let item: lang_items::LangItem = diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 4012bbfef75..2295874a1b5 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1813,7 +1813,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) type_abbrevs: RefCell::new(HashMap::new()), }; - let mut ebml_w = writer::Encoder(wr); + let mut ebml_w = writer::Encoder::new(wr); encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid); encode_crate_triple(&mut ebml_w, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 9fd1fb67450..b5fc3828623 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -556,7 +556,7 @@ fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { let mut param_bounds = ty::ParamBounds { - builtin_bounds: ty::EmptyBuiltinBounds(), + builtin_bounds: ty::empty_builtin_bounds(), trait_bounds: Vec::new() }; loop { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index dbc23348e2b..aec25071249 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -120,7 +120,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata, path_as_str = Some(s); path_as_str.as_ref().map(|x| x.as_slice()) }); - let mut ast_dsr = reader::Decoder(ast_doc); + let mut ast_dsr = reader::Decoder::new(ast_doc); let from_id_range = Decodable::decode(&mut ast_dsr).unwrap(); let to_id_range = reserve_id_range(&dcx.tcx.sess, from_id_range); let xcx = &ExtendedDecodeContext { @@ -349,7 +349,7 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem { fn decode_ast(par_doc: ebml::Doc) -> ast::InlinedItem { let chi_doc = par_doc.get(c::tag_tree as uint); - let mut d = reader::Decoder(chi_doc); + let mut d = reader::Decoder::new(chi_doc); Decodable::decode(&mut d).unwrap() } @@ -395,7 +395,7 @@ fn renumber_and_map_ast(xcx: &ExtendedDecodeContext, // Encoding and decoding of ast::def fn decode_def(xcx: &ExtendedDecodeContext, doc: ebml::Doc) -> ast::Def { - let mut dsr = reader::Decoder(doc); + let mut dsr = reader::Decoder::new(doc); let def: ast::Def = Decodable::decode(&mut dsr).unwrap(); def.tr(xcx) } @@ -1317,7 +1317,7 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, } Some(value) => { let val_doc = entry_doc.get(c::tag_table_val as uint); - let mut val_dsr = reader::Decoder(val_doc); + let mut val_dsr = reader::Decoder::new(val_doc); let val_dsr = &mut val_dsr; match value { @@ -1402,7 +1402,7 @@ fn encode_item_ast(ebml_w: &mut Encoder, item: @ast::Item) { #[cfg(test)] fn decode_item_ast(par_doc: ebml::Doc) -> @ast::Item { let chi_doc = par_doc.get(c::tag_tree as uint); - let mut d = reader::Decoder(chi_doc); + let mut d = reader::Decoder::new(chi_doc); @Decodable::decode(&mut d).unwrap() } @@ -1444,10 +1444,10 @@ fn roundtrip(in_item: Option<@ast::Item>) { let in_item = in_item.unwrap(); let mut wr = MemWriter::new(); { - let mut ebml_w = writer::Encoder(&mut wr); + let mut ebml_w = writer::Encoder::new(&mut wr); encode_item_ast(&mut ebml_w, in_item); } - let ebml_doc = reader::Doc(wr.get_ref()); + let ebml_doc = ebml::Doc::new(wr.get_ref()); let out_item = decode_item_ast(ebml_doc); assert!(in_item == out_item); diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 052baac7855..77fad454e6e 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -641,6 +641,8 @@ impl<'a> CheckLoanCtxt<'a> { // with inherited mutability and with `&mut` // pointers. LpExtend(ref lp_base, mc::McInherited, _) | + LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) | + LpExtend(ref lp_base, _, LpDeref(mc::GcPtr)) | LpExtend(ref lp_base, _, LpDeref(mc::BorrowedPtr(ty::MutBorrow, _))) => { lp_base.clone() } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 2b82dd6fd57..b6614d15106 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -371,7 +371,7 @@ pub fn check_builtin_bounds(cx: &Context, bounds: ty::BuiltinBounds, any_missing: |ty::BuiltinBounds|) { let kind = ty::type_contents(cx.tcx, ty); - let mut missing = ty::EmptyBuiltinBounds(); + let mut missing = ty::empty_builtin_bounds(); for bound in bounds.iter() { if !kind.meets_bound(cx.tcx, bound) { missing.add(bound); @@ -565,6 +565,7 @@ pub fn check_cast_for_escaping_regions( } }); + #[allow(non_snake_case_functions)] fn is_ReScope(r: ty::Region) -> bool { match r { ty::ReScope(..) => true, diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index eba0bc03bf7..8cceb16b34f 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -83,6 +83,7 @@ pub enum Lint { NonCamelCaseTypes, NonUppercaseStatics, NonUppercasePatternStatics, + NonSnakeCaseFunctions, UppercaseVariables, UnnecessaryParens, TypeLimits, @@ -220,6 +221,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ default: Warn }), + ("non_snake_case_functions", + LintSpec { + lint: NonSnakeCaseFunctions, + desc: "methods and functions should have snake case names", + default: Warn + }), + ("uppercase_variables", LintSpec { lint: UppercaseVariables, @@ -1342,6 +1350,30 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::Item) { } } +fn check_snake_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) { + fn is_snake_case(ident: ast::Ident) -> bool { + let ident = token::get_ident(ident); + assert!(!ident.get().is_empty()); + let ident = ident.get().trim_chars('_'); + + let mut allow_underscore = true; + ident.chars().all(|c| { + allow_underscore = match c { + c if c.is_lowercase() || c.is_digit() => true, + '_' if allow_underscore => false, + _ => return false, + }; + true + }) + } + + if !is_snake_case(ident) { + cx.span_lint(NonSnakeCaseFunctions, span, + format!("{} `{}` should have a snake case identifier", + sort, token::get_ident(ident)).as_slice()); + } +} + fn check_item_non_uppercase_statics(cx: &Context, it: &ast::Item) { match it.node { // only check static constants @@ -1618,7 +1650,27 @@ fn check_missing_doc_item(cx: &Context, it: &ast::Item) { desc); } +#[deriving(Eq)] +enum MethodContext { + TraitDefaultImpl, + TraitImpl, + PlainImpl +} + fn check_missing_doc_method(cx: &Context, m: &ast::Method) { + // If the method is an impl for a trait, don't doc. + if method_context(cx, m) == TraitImpl { return; } + + // Otherwise, doc according to privacy. This will also check + // doc for default methods defined on traits. + check_missing_doc_attrs(cx, + Some(m.id), + m.attrs.as_slice(), + m.span, + "a method"); +} + +fn method_context(cx: &Context, m: &ast::Method) -> MethodContext { let did = ast::DefId { krate: ast::LOCAL_CRATE, node: m.id @@ -1628,25 +1680,16 @@ fn check_missing_doc_method(cx: &Context, m: &ast::Method) { None => cx.tcx.sess.span_bug(m.span, "missing method descriptor?!"), Some(md) => { match md.container { - // Always check default methods defined on traits. - ty::TraitContainer(..) => {} - // For methods defined on impls, it depends on whether - // it is an implementation for a trait or is a plain - // impl. + ty::TraitContainer(..) => TraitDefaultImpl, ty::ImplContainer(cid) => { match ty::impl_trait_ref(cx.tcx, cid) { - Some(..) => return, // impl for trait: don't doc - None => {} // plain impl: doc according to privacy + Some(..) => TraitImpl, + None => PlainImpl } } } } } - check_missing_doc_attrs(cx, - Some(m.id), - m.attrs.as_slice(), - m.span, - "a method"); } fn check_missing_doc_ty_method(cx: &Context, tm: &ast::TypeMethod) { @@ -1889,26 +1932,36 @@ impl<'a> Visitor<()> for Context<'a> { } match *fk { - visit::FkMethod(_, _, m) => { + visit::FkMethod(ident, _, m) => { self.with_lint_attrs(m.attrs.as_slice(), |cx| { check_missing_doc_method(cx, m); check_attrs_usage(cx, m.attrs.as_slice()); + match method_context(cx, m) { + PlainImpl => check_snake_case(cx, "method", ident, span), + TraitDefaultImpl => check_snake_case(cx, "trait method", ident, span), + _ => (), + } + cx.visit_ids(|v| { v.visit_fn(fk, decl, body, span, id, ()); }); recurse(cx); }) + }, + visit::FkItemFn(ident, _, _, _) => { + check_snake_case(self, "function", ident, span); + recurse(self); } _ => recurse(self), } } - fn visit_ty_method(&mut self, t: &ast::TypeMethod, _: ()) { self.with_lint_attrs(t.attrs.as_slice(), |cx| { check_missing_doc_ty_method(cx, t); check_attrs_usage(cx, t.attrs.as_slice()); + check_snake_case(cx, "trait method", t.ident, t.span); visit::walk_ty_method(cx, t, ()); }) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index beb522802fe..e0d411f9f97 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -177,7 +177,7 @@ impl<'a> Visitor<()> for IrMaps<'a> { pub fn check_crate(tcx: &ty::ctxt, krate: &Crate) { - visit::walk_crate(&mut IrMaps(tcx), krate, ()); + visit::walk_crate(&mut IrMaps::new(tcx), krate, ()); tcx.sess.abort_if_errors(); } @@ -260,21 +260,20 @@ struct IrMaps<'a> { lnks: Vec<LiveNodeKind>, } -fn IrMaps<'a>(tcx: &'a ty::ctxt) - -> IrMaps<'a> { - IrMaps { - tcx: tcx, - num_live_nodes: 0, - num_vars: 0, - live_node_map: NodeMap::new(), - variable_map: NodeMap::new(), - capture_info_map: NodeMap::new(), - var_kinds: Vec::new(), - lnks: Vec::new(), +impl<'a> IrMaps<'a> { + fn new(tcx: &'a ty::ctxt) -> IrMaps<'a> { + IrMaps { + tcx: tcx, + num_live_nodes: 0, + num_vars: 0, + live_node_map: NodeMap::new(), + variable_map: NodeMap::new(), + capture_info_map: NodeMap::new(), + var_kinds: Vec::new(), + lnks: Vec::new(), + } } -} -impl<'a> IrMaps<'a> { fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode { let ln = LiveNode(self.num_live_nodes); self.lnks.push(lnk); @@ -365,7 +364,7 @@ fn visit_fn(ir: &mut IrMaps, let _i = ::util::common::indenter(); // swap in a new set of IR maps for this function body: - let mut fn_maps = IrMaps(ir.tcx); + let mut fn_maps = IrMaps::new(ir.tcx); unsafe { debug!("creating fn_maps: {}", transmute::<&IrMaps, *IrMaps>(&fn_maps)); @@ -396,7 +395,7 @@ fn visit_fn(ir: &mut IrMaps, }; // compute liveness - let mut lsets = Liveness(&mut fn_maps, specials); + let mut lsets = Liveness::new(&mut fn_maps, specials); let entry_ln = lsets.compute(decl, body); // check for various error conditions @@ -584,19 +583,19 @@ struct Liveness<'a> { cont_ln: NodeMap<LiveNode> } -fn Liveness<'a>(ir: &'a mut IrMaps<'a>, specials: Specials) -> Liveness<'a> { - Liveness { - ir: ir, - s: specials, - successors: Vec::from_elem(ir.num_live_nodes, invalid_node()), - users: Vec::from_elem(ir.num_live_nodes * ir.num_vars, invalid_users()), - loop_scope: Vec::new(), - break_ln: NodeMap::new(), - cont_ln: NodeMap::new(), +impl<'a> Liveness<'a> { + fn new(ir: &'a mut IrMaps<'a>, specials: Specials) -> Liveness<'a> { + Liveness { + ir: ir, + s: specials, + successors: Vec::from_elem(ir.num_live_nodes, invalid_node()), + users: Vec::from_elem(ir.num_live_nodes * ir.num_vars, invalid_users()), + loop_scope: Vec::new(), + break_ln: NodeMap::new(), + cont_ln: NodeMap::new(), + } } -} -impl<'a> Liveness<'a> { fn live_node(&self, node_id: NodeId, span: Span) -> LiveNode { match self.ir.live_node_map.find(&node_id) { Some(&ln) => ln, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 1a29cff3cd6..077f61a34c6 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -549,6 +549,13 @@ enum TraitReferenceType { } impl NameBindings { + fn new() -> NameBindings { + NameBindings { + type_def: RefCell::new(None), + value_def: RefCell::new(None), + } + } + /// Creates a new module in this set of name bindings. fn define_module(&self, parent_link: ParentLink, @@ -749,49 +756,42 @@ impl NameBindings { } } -fn NameBindings() -> NameBindings { - NameBindings { - type_def: RefCell::new(None), - value_def: RefCell::new(None), - } -} - /// Interns the names of the primitive types. struct PrimitiveTypeTable { primitive_types: HashMap<Name, PrimTy>, } impl PrimitiveTypeTable { + fn new() -> PrimitiveTypeTable { + let mut table = PrimitiveTypeTable { + primitive_types: HashMap::new() + }; + + table.intern("bool", TyBool); + table.intern("char", TyChar); + table.intern("f32", TyFloat(TyF32)); + table.intern("f64", TyFloat(TyF64)); + table.intern("f128", TyFloat(TyF128)); + table.intern("int", TyInt(TyI)); + table.intern("i8", TyInt(TyI8)); + table.intern("i16", TyInt(TyI16)); + table.intern("i32", TyInt(TyI32)); + table.intern("i64", TyInt(TyI64)); + table.intern("str", TyStr); + table.intern("uint", TyUint(TyU)); + table.intern("u8", TyUint(TyU8)); + table.intern("u16", TyUint(TyU16)); + table.intern("u32", TyUint(TyU32)); + table.intern("u64", TyUint(TyU64)); + + table + } + fn intern(&mut self, string: &str, primitive_type: PrimTy) { self.primitive_types.insert(token::intern(string), primitive_type); } } -fn PrimitiveTypeTable() -> PrimitiveTypeTable { - let mut table = PrimitiveTypeTable { - primitive_types: HashMap::new() - }; - - table.intern("bool", TyBool); - table.intern("char", TyChar); - table.intern("f32", TyFloat(TyF32)); - table.intern("f64", TyFloat(TyF64)); - table.intern("f128", TyFloat(TyF128)); - table.intern("int", TyInt(TyI)); - table.intern("i8", TyInt(TyI8)); - table.intern("i16", TyInt(TyI16)); - table.intern("i32", TyInt(TyI32)); - table.intern("i64", TyInt(TyI64)); - table.intern("str", TyStr); - table.intern("uint", TyUint(TyU)); - table.intern("u8", TyUint(TyU8)); - table.intern("u16", TyUint(TyU16)); - table.intern("u32", TyUint(TyU32)); - table.intern("u64", TyUint(TyU64)); - - return table; -} - fn namespace_error_to_str(ns: NamespaceError) -> &'static str { match ns { @@ -802,62 +802,6 @@ fn namespace_error_to_str(ns: NamespaceError) -> &'static str { } } -fn Resolver<'a>(session: &'a Session, - lang_items: &'a LanguageItems, - crate_span: Span) -> Resolver<'a> { - let graph_root = NameBindings(); - - graph_root.define_module(NoParentLink, - Some(DefId { krate: 0, node: 0 }), - NormalModuleKind, - false, - true, - crate_span); - - let current_module = graph_root.get_module(); - - let this = Resolver { - session: session, - lang_items: lang_items, - - // The outermost module has def ID 0; this is not reflected in the - // AST. - - graph_root: graph_root, - - method_map: RefCell::new(FnvHashMap::new()), - structs: FnvHashMap::new(), - - unresolved_imports: 0, - - current_module: current_module, - value_ribs: RefCell::new(Vec::new()), - type_ribs: RefCell::new(Vec::new()), - label_ribs: RefCell::new(Vec::new()), - - current_trait_ref: None, - current_self_type: None, - - self_ident: special_idents::self_, - type_self_ident: special_idents::type_self, - - primitive_type_table: PrimitiveTypeTable(), - - namespaces: vec!(TypeNS, ValueNS), - - def_map: RefCell::new(NodeMap::new()), - export_map2: RefCell::new(NodeMap::new()), - trait_map: NodeMap::new(), - used_imports: HashSet::new(), - external_exports: DefIdSet::new(), - last_private: NodeMap::new(), - - emit_errors: true, - }; - - this -} - /// The main resolver class. struct Resolver<'a> { session: &'a Session, @@ -957,6 +901,57 @@ impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> { } impl<'a> Resolver<'a> { + fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) -> Resolver<'a> { + let graph_root = NameBindings::new(); + + graph_root.define_module(NoParentLink, + Some(DefId { krate: 0, node: 0 }), + NormalModuleKind, + false, + true, + crate_span); + + let current_module = graph_root.get_module(); + + Resolver { + session: session, + lang_items: lang_items, + + // The outermost module has def ID 0; this is not reflected in the + // AST. + + graph_root: graph_root, + + method_map: RefCell::new(FnvHashMap::new()), + structs: FnvHashMap::new(), + + unresolved_imports: 0, + + current_module: current_module, + value_ribs: RefCell::new(Vec::new()), + type_ribs: RefCell::new(Vec::new()), + label_ribs: RefCell::new(Vec::new()), + + current_trait_ref: None, + current_self_type: None, + + self_ident: special_idents::self_, + type_self_ident: special_idents::type_self, + + primitive_type_table: PrimitiveTypeTable::new(), + + namespaces: vec!(TypeNS, ValueNS), + + def_map: RefCell::new(NodeMap::new()), + export_map2: RefCell::new(NodeMap::new()), + trait_map: NodeMap::new(), + used_imports: HashSet::new(), + external_exports: DefIdSet::new(), + last_private: NodeMap::new(), + + emit_errors: true, + } + } /// The main name resolution procedure. fn resolve(&mut self, krate: &ast::Crate) { self.build_reduced_graph(krate); @@ -1017,7 +1012,7 @@ impl<'a> Resolver<'a> { let child = module_.children.borrow().find_copy(&name.name); match child { None => { - let child = Rc::new(NameBindings()); + let child = Rc::new(NameBindings::new()); module_.children.borrow_mut().insert(name.name, child.clone()); child } @@ -5574,7 +5569,7 @@ pub fn resolve_crate(session: &Session, lang_items: &LanguageItems, krate: &Crate) -> CrateMap { - let mut resolver = Resolver(session, lang_items, krate.span); + let mut resolver = Resolver::new(session, lang_items, krate.span); resolver.resolve(krate); let Resolver { def_map, export_map2, trait_map, last_private, external_exports, .. } = resolver; diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 494f6591d39..86ddd5e0e98 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -997,7 +997,7 @@ fn match_datum(bcx: &Block, */ let ty = node_id_type(bcx, pat_id); - Datum(val, ty, Lvalue) + Datum::new(val, ty, Lvalue) } @@ -1297,7 +1297,7 @@ fn store_non_ref_bindings<'a>( match binding_info.trmode { TrByValue(lldest) => { let llval = Load(bcx, binding_info.llmatch); // get a T* - let datum = Datum(llval, binding_info.ty, Lvalue); + let datum = Datum::new(llval, binding_info.ty, Lvalue); bcx = datum.store_to(bcx, lldest); match opt_cleanup_scope { @@ -1334,7 +1334,7 @@ fn insert_lllocals<'a>(bcx: &'a Block<'a>, TrByRef => binding_info.llmatch }; - let datum = Datum(llval, binding_info.ty, Lvalue); + let datum = Datum::new(llval, binding_info.ty, Lvalue); fcx.schedule_drop_mem(cleanup_scope, llval, binding_info.ty); debug!("binding {:?} to {}", @@ -2081,7 +2081,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>, // we emit extra-debug-info, which requires local allocas :(. let arg_val = arg.add_clean(bcx.fcx, arg_scope); bcx.fcx.llargs.borrow_mut() - .insert(pat.id, Datum(arg_val, arg_ty, Lvalue)); + .insert(pat.id, Datum::new(arg_val, arg_ty, Lvalue)); bcx } else { mk_binding_alloca( @@ -2122,7 +2122,7 @@ fn mk_binding_alloca<'a,A>(bcx: &'a Block<'a>, // Now that memory is initialized and has cleanup scheduled, // create the datum and insert into the local variable map. - let datum = Datum(llval, var_ty, Lvalue); + let datum = Datum::new(llval, var_ty, Lvalue); let mut llmap = match binding_mode { BindLocal => bcx.fcx.lllocals.borrow_mut(), BindArgument => bcx.fcx.llargs.borrow_mut() @@ -2183,7 +2183,7 @@ fn bind_irrefutable_pat<'a>( ast::BindByValue(_) => { // By value binding: move the value that `val` // points at into the binding's stack slot. - let d = Datum(val, ty, Lvalue); + let d = Datum::new(val, ty, Lvalue); d.store_to(bcx, llval) } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index db19fa521ce..7ef6038d715 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -70,7 +70,7 @@ pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::InlineAsm) .connect(",") .as_slice()); - let mut clobbers = getClobbers(); + let mut clobbers = get_clobbers(); if !ia.clobbers.get().is_empty() && !clobbers.is_empty() { clobbers = format!("{},{}", ia.clobbers.get(), clobbers); } else { @@ -135,12 +135,12 @@ pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::InlineAsm) #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] -fn getClobbers() -> String { +fn get_clobbers() -> String { "".to_string() } #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] -fn getClobbers() -> String { +fn get_clobbers() -> String { "~{dirflag},~{fpsr},~{flags}".to_string() } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 386ad66ebd6..464e8cff0fa 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1210,7 +1210,7 @@ pub fn create_datums_for_fn_args(fcx: &FunctionContext, let llarg = unsafe { llvm::LLVMGetParam(fcx.llfn, fcx.arg_pos(i) as c_uint) }; - datum::Datum(llarg, arg_ty, arg_kind(fcx, arg_ty)) + datum::Datum::new(llarg, arg_ty, arg_kind(fcx, arg_ty)) }).collect() } diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 352ebc3834b..e04454d4a68 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -9,6 +9,7 @@ // except according to those terms. #![allow(dead_code)] // FFI wrappers +#![allow(non_snake_case_functions)] use lib::llvm::llvm; use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect}; diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 9e8d6926f12..9ca66f4c3b0 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -460,5 +460,5 @@ pub fn make_closure_from_bare_fn<'a>(bcx: &'a Block<'a>, let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def, fn_ptr, true); fill_fn_pair(bcx, scratch.val, wrapper, C_null(Type::i8p(bcx.ccx()))); - DatumBlock(bcx, scratch.to_expr_datum()) + DatumBlock::new(bcx, scratch.to_expr_datum()) } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 7e63c1a18f7..0530e2a7463 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(non_camel_case_types)] +#![allow(non_camel_case_types, non_snake_case_functions)] //! Code that is useful in various trans modules. @@ -21,7 +21,6 @@ use middle::lang_items::LangItem; use middle::trans::build; use middle::trans::cleanup; use middle::trans::datum; -use middle::trans::datum::{Datum, Lvalue}; use middle::trans::debuginfo; use middle::trans::type_::Type; use middle::ty; diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 1e0d3e16ab1..af9e614a17e 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -71,8 +71,10 @@ pub struct Rvalue { pub mode: RvalueMode } -pub fn Rvalue(m: RvalueMode) -> Rvalue { - Rvalue { mode: m } +impl Rvalue { + pub fn new(m: RvalueMode) -> Rvalue { + Rvalue { mode: m } + } } // Make Datum linear for more type safety. @@ -89,25 +91,15 @@ pub enum RvalueMode { ByValue, } -pub fn Datum<K:KindOps>(val: ValueRef, ty: ty::t, kind: K) -> Datum<K> { - Datum { val: val, ty: ty, kind: kind } -} - -pub fn DatumBlock<'a, K>(bcx: &'a Block<'a>, - datum: Datum<K>) - -> DatumBlock<'a, K> { - DatumBlock { bcx: bcx, datum: datum } -} - pub fn immediate_rvalue(val: ValueRef, ty: ty::t) -> Datum<Rvalue> { - return Datum(val, ty, Rvalue(ByValue)); + return Datum::new(val, ty, Rvalue::new(ByValue)); } pub fn immediate_rvalue_bcx<'a>(bcx: &'a Block<'a>, val: ValueRef, ty: ty::t) -> DatumBlock<'a, Rvalue> { - return DatumBlock(bcx, immediate_rvalue(val, ty)) + return DatumBlock::new(bcx, immediate_rvalue(val, ty)) } @@ -136,7 +128,7 @@ pub fn lvalue_scratch_datum<'a, A>(bcx: &'a Block<'a>, let bcx = populate(arg, bcx, scratch); bcx.fcx.schedule_drop_mem(scope, scratch, ty); - DatumBlock(bcx, Datum(scratch, ty, Lvalue)) + DatumBlock::new(bcx, Datum::new(scratch, ty, Lvalue)) } pub fn rvalue_scratch_datum(bcx: &Block, @@ -155,7 +147,7 @@ pub fn rvalue_scratch_datum(bcx: &Block, let llty = type_of::type_of(bcx.ccx(), ty); let scratch = alloca_maybe_zeroed(bcx, llty, name, false); - Datum(scratch, ty, Rvalue(ByRef)) + Datum::new(scratch, ty, Rvalue::new(ByRef)) } pub fn appropriate_rvalue_mode(ccx: &CrateContext, ty: ty::t) -> RvalueMode { @@ -320,7 +312,7 @@ impl Datum<Rvalue> { match self.kind.mode { ByRef => { add_rvalue_clean(ByRef, fcx, scope, self.val, self.ty); - DatumBlock(bcx, Datum(self.val, self.ty, Lvalue)) + DatumBlock::new(bcx, Datum::new(self.val, self.ty, Lvalue)) } ByValue => { @@ -334,11 +326,11 @@ impl Datum<Rvalue> { pub fn to_ref_datum<'a>(self, bcx: &'a Block<'a>) -> DatumBlock<'a, Rvalue> { let mut bcx = bcx; match self.kind.mode { - ByRef => DatumBlock(bcx, self), + ByRef => DatumBlock::new(bcx, self), ByValue => { let scratch = rvalue_scratch_datum(bcx, self.ty, "to_ref"); bcx = self.store_to(bcx, scratch.val); - DatumBlock(bcx, scratch) + DatumBlock::new(bcx, scratch) } } } @@ -352,10 +344,10 @@ impl Datum<Rvalue> { } ByValue => { match self.kind.mode { - ByValue => DatumBlock(bcx, self), + ByValue => DatumBlock::new(bcx, self), ByRef => { let llval = load(bcx, self.val, self.ty); - DatumBlock(bcx, Datum(llval, self.ty, Rvalue(ByValue))) + DatumBlock::new(bcx, Datum::new(llval, self.ty, Rvalue::new(ByValue))) } } } @@ -378,8 +370,8 @@ impl Datum<Expr> { -> R { let Datum { val, ty, kind } = self; match kind { - LvalueExpr => if_lvalue(Datum(val, ty, Lvalue)), - RvalueExpr(r) => if_rvalue(Datum(val, ty, r)), + LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)), + RvalueExpr(r) => if_rvalue(Datum::new(val, ty, r)), } } @@ -455,7 +447,7 @@ impl Datum<Expr> { expr_id: ast::NodeId) -> DatumBlock<'a, Lvalue> { self.match_kind( - |l| DatumBlock(bcx, l), + |l| DatumBlock::new(bcx, l), |r| { let scope = cleanup::temporary_scope(bcx.tcx(), expr_id); r.to_lvalue_datum_in_scope(bcx, name, scope) @@ -478,16 +470,16 @@ impl Datum<Expr> { ByRef => { let scratch = rvalue_scratch_datum(bcx, l.ty, name); bcx = l.store_to(bcx, scratch.val); - DatumBlock(bcx, scratch) + DatumBlock::new(bcx, scratch) } ByValue => { let v = load(bcx, l.val, l.ty); bcx = l.kind.post_store(bcx, l.val, l.ty); - DatumBlock(bcx, Datum(v, l.ty, Rvalue(ByValue))) + DatumBlock::new(bcx, Datum::new(v, l.ty, Rvalue::new(ByValue))) } } }, - |r| DatumBlock(bcx, r)) + |r| DatumBlock::new(bcx, r)) } } @@ -550,6 +542,10 @@ fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef { * Generic methods applicable to any sort of datum. */ impl<K:KindOps> Datum<K> { + pub fn new(val: ValueRef, ty: ty::t, kind: K) -> Datum<K> { + Datum { val: val, ty: ty, kind: kind } + } + pub fn to_expr_datum(self) -> Datum<Expr> { let Datum { val, ty, kind } = self; Datum { val: val, ty: ty, kind: kind.to_expr_kind() } @@ -663,9 +659,15 @@ impl<K:KindOps> Datum<K> { } } +impl <'a, K> DatumBlock<'a, K> { + pub fn new(bcx: &'a Block<'a>, datum: Datum<K>) -> DatumBlock<'a, K> { + DatumBlock { bcx: bcx, datum: datum } + } +} + impl<'a, K:KindOps> DatumBlock<'a, K> { pub fn to_expr_datumblock(self) -> DatumBlock<'a, Expr> { - DatumBlock(self.bcx, self.datum.to_expr_datum()) + DatumBlock::new(self.bcx, self.datum.to_expr_datum()) } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 25f780a0eab..43d0d71154c 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -941,6 +941,7 @@ fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool !cx.reachable.contains(&node_id) } +#[allow(non_snake_case_functions)] fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { return unsafe { llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) @@ -1208,33 +1209,108 @@ fn pointer_type_metadata(cx: &CrateContext, return ptr_metadata; } +//=------------------------------------------------------------------------------------------------- +// Common facilities for record-like types (structs, enums, tuples) +//=------------------------------------------------------------------------------------------------- + +enum MemberOffset { + FixedMemberOffset { bytes: uint }, + // For ComputedMemberOffset, the offset is read from the llvm type definition + ComputedMemberOffset +} + +// Description of a type member, which can either be a regular field (as in structs or tuples) or +// an enum variant +struct MemberDescription { + name: String, + llvm_type: Type, + type_metadata: DIType, + offset: MemberOffset, +} + +// A factory for MemberDescriptions. It produces a list of member descriptions for some record-like +// type. MemberDescriptionFactories are used to defer the creation of type member descriptions in +// order to break cycles arising from recursive type definitions. enum MemberDescriptionFactory { - StructMD(StructMemberDescriptionFactory), - TupleMD(TupleMemberDescriptionFactory), - GeneralMD(GeneralMemberDescriptionFactory), - EnumVariantMD(EnumVariantMemberDescriptionFactory) + StructMDF(StructMemberDescriptionFactory), + TupleMDF(TupleMemberDescriptionFactory), + EnumMDF(EnumMemberDescriptionFactory), + VariantMDF(VariantMemberDescriptionFactory) } impl MemberDescriptionFactory { - fn create_member_descriptions(&self, cx: &CrateContext) - -> Vec<MemberDescription> { + fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> { match *self { - StructMD(ref this) => { + StructMDF(ref this) => { this.create_member_descriptions(cx) } - TupleMD(ref this) => { + TupleMDF(ref this) => { this.create_member_descriptions(cx) } - GeneralMD(ref this) => { + EnumMDF(ref this) => { this.create_member_descriptions(cx) } - EnumVariantMD(ref this) => { + VariantMDF(ref this) => { this.create_member_descriptions(cx) } } } } +// A description of some recursive type. It can either be already finished (as with FinalMetadata) +// or it is not yet finished, but contains all information needed to generate the missing parts of +// the description. See the documentation section on Recursive Types at the top of this file for +// more information. +enum RecursiveTypeDescription { + UnfinishedMetadata { + cache_id: uint, + metadata_stub: DICompositeType, + llvm_type: Type, + file_metadata: DIFile, + member_description_factory: MemberDescriptionFactory, + }, + FinalMetadata(DICompositeType) +} + +impl RecursiveTypeDescription { + // Finishes up the description of the type in question (mostly by providing descriptions of the + // fields of the given type) and returns the final type metadata. + fn finalize(&self, cx: &CrateContext) -> DICompositeType { + match *self { + FinalMetadata(metadata) => metadata, + UnfinishedMetadata { + cache_id, + metadata_stub, + llvm_type, + file_metadata, + ref member_description_factory + } => { + // Insert the stub into the cache in order to allow recursive references ... + debug_context(cx).created_types.borrow_mut() + .insert(cache_id, metadata_stub); + + // ... then create the member descriptions ... + let member_descriptions = member_description_factory.create_member_descriptions(cx); + + // ... and attach them to the stub to complete it. + set_members_of_composite_type(cx, + metadata_stub, + llvm_type, + member_descriptions.as_slice(), + file_metadata, + codemap::DUMMY_SP); + return metadata_stub; + } + } + } +} + + +//=------------------------------------------------------------------------------------------------- +// Structs +//=------------------------------------------------------------------------------------------------- + +// Creates MemberDescriptions for the fields of a struct struct StructMemberDescriptionFactory { fields: Vec<ty::field>, is_simd: bool, @@ -1248,7 +1324,7 @@ impl StructMemberDescriptionFactory { } let field_size = if self.is_simd { - machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) + machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) as uint } else { 0xdeadbeef }; @@ -1262,7 +1338,7 @@ impl StructMemberDescriptionFactory { let offset = if self.is_simd { assert!(field_size != 0xdeadbeef); - FixedMemberOffset { bytes: i as u64 * field_size } + FixedMemberOffset { bytes: i * field_size } } else { ComputedMemberOffset }; @@ -1305,7 +1381,7 @@ fn prepare_struct_metadata(cx: &CrateContext, metadata_stub: struct_metadata_stub, llvm_type: struct_llvm_type, file_metadata: file_metadata, - member_description_factory: StructMD(StructMemberDescriptionFactory { + member_description_factory: StructMDF(StructMemberDescriptionFactory { fields: fields, is_simd: ty::type_is_simd(cx.tcx(), struct_type), span: span, @@ -1313,49 +1389,12 @@ fn prepare_struct_metadata(cx: &CrateContext, } } -enum RecursiveTypeDescription { - UnfinishedMetadata { - cache_id: uint, - metadata_stub: DICompositeType, - llvm_type: Type, - file_metadata: DIFile, - member_description_factory: MemberDescriptionFactory, - }, - FinalMetadata(DICompositeType) -} -impl RecursiveTypeDescription { - - fn finalize(&self, cx: &CrateContext) -> DICompositeType { - match *self { - FinalMetadata(metadata) => metadata, - UnfinishedMetadata { - cache_id, - metadata_stub, - llvm_type, - file_metadata, - ref member_description_factory - } => { - // Insert the stub into the cache in order to allow recursive references ... - debug_context(cx).created_types.borrow_mut() - .insert(cache_id, metadata_stub); - - // ... then create the member descriptions ... - let member_descriptions = member_description_factory.create_member_descriptions(cx); - - // ... and attach them to the stub to complete it. - set_members_of_composite_type(cx, - metadata_stub, - llvm_type, - member_descriptions.as_slice(), - file_metadata, - codemap::DUMMY_SP); - return metadata_stub; - } - } - } -} +//=------------------------------------------------------------------------------------------------- +// Tuples +//=------------------------------------------------------------------------------------------------- +// Creates MemberDescriptions for the fields of a tuple struct TupleMemberDescriptionFactory { component_types: Vec<ty::t> , span: Span, @@ -1396,72 +1435,209 @@ fn prepare_tuple_metadata(cx: &CrateContext, span), llvm_type: tuple_llvm_type, file_metadata: file_metadata, - member_description_factory: TupleMD(TupleMemberDescriptionFactory { + member_description_factory: TupleMDF(TupleMemberDescriptionFactory { component_types: Vec::from_slice(component_types), span: span, }) } } -struct GeneralMemberDescriptionFactory { + +//=------------------------------------------------------------------------------------------------- +// Enums +//=------------------------------------------------------------------------------------------------- + +// Describes the members of an enum value: An enum is described as a union of structs in DWARF. This +// MemberDescriptionFactory provides the description for the members of this union; so for every +// variant of the given enum, this factory will produce one MemberDescription (all with no name and +// a fixed offset of zero bytes). +struct EnumMemberDescriptionFactory { type_rep: Rc<adt::Repr>, variants: Rc<Vec<Rc<ty::VariantInfo>>>, - discriminant_type_metadata: ValueRef, + discriminant_type_metadata: Option<DIType>, containing_scope: DIScope, file_metadata: DIFile, span: Span, } -impl GeneralMemberDescriptionFactory { - fn create_member_descriptions(&self, cx: &CrateContext) - -> Vec<MemberDescription> { - // Capture type_rep, so we don't have to copy the struct_defs array - let struct_defs = match *self.type_rep { - adt::General(_, ref struct_defs) => struct_defs, - _ => cx.sess().bug("unreachable") - }; - - struct_defs - .iter() - .enumerate() - .map(|(i, struct_def)| { - let (variant_type_metadata, variant_llvm_type, member_desc_factory) = +impl EnumMemberDescriptionFactory { + fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> { + match *self.type_rep { + adt::General(_, ref struct_defs) => { + let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata + .expect("")); + + struct_defs + .iter() + .enumerate() + .map(|(i, struct_def)| { + let (variant_type_metadata, variant_llvm_type, member_desc_factory) = + describe_enum_variant(cx, + struct_def, + &**self.variants.get(i), + discriminant_info, + self.containing_scope, + self.file_metadata, + self.span); + + let member_descriptions = member_desc_factory + .create_member_descriptions(cx); + + set_members_of_composite_type(cx, + variant_type_metadata, + variant_llvm_type, + member_descriptions.as_slice(), + self.file_metadata, + codemap::DUMMY_SP); + MemberDescription { + name: "".to_string(), + llvm_type: variant_llvm_type, + type_metadata: variant_type_metadata, + offset: FixedMemberOffset { bytes: 0 }, + } + }).collect() + }, + adt::Univariant(ref struct_def, _) => { + assert!(self.variants.len() <= 1); + + if self.variants.len() == 0 { + vec![] + } else { + let (variant_type_metadata, variant_llvm_type, member_description_factory) = + describe_enum_variant(cx, + struct_def, + &**self.variants.get(0), + NoDiscriminant, + self.containing_scope, + self.file_metadata, + self.span); + + let member_descriptions = + member_description_factory.create_member_descriptions(cx); + + set_members_of_composite_type(cx, + variant_type_metadata, + variant_llvm_type, + member_descriptions.as_slice(), + self.file_metadata, + codemap::DUMMY_SP); + vec![ + MemberDescription { + name: "".to_string(), + llvm_type: variant_llvm_type, + type_metadata: variant_type_metadata, + offset: FixedMemberOffset { bytes: 0 }, + } + ] + } + } + adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => { + // As far as debuginfo is concerned, the pointer this enum represents is still + // wrapped in a struct. This is to make the DWARF representation of enums uniform. + + // First create a description of the artifical wrapper struct: + let non_null_variant = self.variants.get(non_null_variant_index as uint); + let non_null_variant_ident = non_null_variant.name; + let non_null_variant_name = token::get_ident(non_null_variant_ident); + + // The llvm type and metadata of the pointer + let non_null_llvm_type = type_of::type_of(cx, nnty); + let non_null_type_metadata = type_metadata(cx, nnty, self.span); + + // The type of the artificial struct wrapping the pointer + let artificial_struct_llvm_type = Type::struct_(cx, &[non_null_llvm_type], false); + + // For the metadata of the wrapper struct, we need to create a MemberDescription + // of the struct's single field. + let sole_struct_member_description = MemberDescription { + name: match non_null_variant.arg_names { + Some(ref names) => token::get_ident(*names.get(0)).get().to_string(), + None => "".to_string() + }, + llvm_type: non_null_llvm_type, + type_metadata: non_null_type_metadata, + offset: FixedMemberOffset { bytes: 0 }, + }; + + // Now we can create the metadata of the artificial struct + let artificial_struct_metadata = + composite_type_metadata(cx, + artificial_struct_llvm_type, + non_null_variant_name.get(), + &[sole_struct_member_description], + self.containing_scope, + self.file_metadata, + codemap::DUMMY_SP); + + // Encode the information about the null variant in the union member's name + let null_variant_index = (1 - non_null_variant_index) as uint; + let null_variant_ident = self.variants.get(null_variant_index).name; + let null_variant_name = token::get_ident(null_variant_ident); + let union_member_name = format!("RUST$ENCODED$ENUM${}${}", 0, null_variant_name); + + // Finally create the (singleton) list of descriptions of union members + vec![ + MemberDescription { + name: union_member_name, + llvm_type: artificial_struct_llvm_type, + type_metadata: artificial_struct_metadata, + offset: FixedMemberOffset { bytes: 0 }, + } + ] + }, + adt::StructWrappedNullablePointer { nonnull: ref struct_def, nndiscr, ptrfield, ..} => { + // Create a description of the non-null variant + let (variant_type_metadata, variant_llvm_type, member_description_factory) = describe_enum_variant(cx, struct_def, - &**self.variants.get(i), - Some(self.discriminant_type_metadata), + &**self.variants.get(nndiscr as uint), + OptimizedDiscriminant(ptrfield), self.containing_scope, self.file_metadata, self.span); - let member_descriptions = - member_desc_factory.create_member_descriptions(cx); + let variant_member_descriptions = + member_description_factory.create_member_descriptions(cx); set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - member_descriptions.as_slice(), + variant_member_descriptions.as_slice(), self.file_metadata, codemap::DUMMY_SP); - MemberDescription { - name: "".to_string(), - llvm_type: variant_llvm_type, - type_metadata: variant_type_metadata, - offset: FixedMemberOffset { bytes: 0 }, - } - }).collect() + + // Encode the information about the null variant in the union member's name + let null_variant_index = (1 - nndiscr) as uint; + let null_variant_ident = self.variants.get(null_variant_index).name; + let null_variant_name = token::get_ident(null_variant_ident); + let union_member_name = format!("RUST$ENCODED$ENUM${}${}", + ptrfield, + null_variant_name); + + // Create the (singleton) list of descriptions of union members + vec![ + MemberDescription { + name: union_member_name, + llvm_type: variant_llvm_type, + type_metadata: variant_type_metadata, + offset: FixedMemberOffset { bytes: 0 }, + } + ] + }, + adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.") + } } } -struct EnumVariantMemberDescriptionFactory { +// Creates MemberDescriptions for the fields of a single enum variant +struct VariantMemberDescriptionFactory { args: Vec<(String, ty::t)> , discriminant_type_metadata: Option<DIType>, span: Span, } -impl EnumVariantMemberDescriptionFactory { - fn create_member_descriptions(&self, cx: &CrateContext) - -> Vec<MemberDescription> { +impl VariantMemberDescriptionFactory { + fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> { self.args.iter().enumerate().map(|(i, &(ref name, ty))| { MemberDescription { name: name.to_string(), @@ -1476,10 +1652,19 @@ impl EnumVariantMemberDescriptionFactory { } } +enum EnumDiscriminantInfo { + RegularDiscriminant(DIType), + OptimizedDiscriminant(uint), + NoDiscriminant +} + +// Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type of the variant, and +// (3) a MemberDescriptionFactory for producing the descriptions of the fields of the variant. This +// is a rudimentary version of a full RecursiveTypeDescription. fn describe_enum_variant(cx: &CrateContext, struct_def: &adt::Struct, variant_info: &ty::VariantInfo, - discriminant_type_metadata: Option<DIType>, + discriminant_info: EnumDiscriminantInfo, containing_scope: DIScope, file_metadata: DIFile, span: Span) @@ -1491,7 +1676,7 @@ fn describe_enum_variant(cx: &CrateContext, .collect::<Vec<_>>() .as_slice(), struct_def.packed); - // Could some consistency checks here: size, align, field count, discr type + // Could do some consistency checks here: size, align, field count, discr type // Find the source code location of the variant's definition let variant_definition_span = if variant_info.id.krate == ast::LOCAL_CRATE { @@ -1520,9 +1705,10 @@ fn describe_enum_variant(cx: &CrateContext, }; // If this is not a univariant enum, there is also the (unnamed) discriminant field - if discriminant_type_metadata.is_some() { - arg_names.insert(0, "".to_string()); - } + match discriminant_info { + RegularDiscriminant(_) => arg_names.insert(0, "".to_string()), + _ => { /* do nothing */ } + }; // Build an array of (field name, field type) pairs to be captured in the factory closure. let args: Vec<(String, ty::t)> = arg_names.iter() @@ -1531,9 +1717,12 @@ fn describe_enum_variant(cx: &CrateContext, .collect(); let member_description_factory = - EnumVariantMD(EnumVariantMemberDescriptionFactory { + VariantMDF(VariantMemberDescriptionFactory { args: args, - discriminant_type_metadata: discriminant_type_metadata, + discriminant_type_metadata: match discriminant_info { + RegularDiscriminant(discriminant_type_metadata) => Some(discriminant_type_metadata), + _ => None + }, span: span, }); @@ -1551,21 +1740,6 @@ fn prepare_enum_metadata(cx: &CrateContext, let loc = span_start(cx, definition_span); let file_metadata = file_metadata(cx, loc.file.name.as_slice()); - // For empty enums there is an early exit. Just describe it as an empty struct with the - // appropriate type name - if ty::type_is_empty(cx.tcx(), enum_type) { - let empty_type_metadata = composite_type_metadata( - cx, - Type::nil(cx), - enum_name.as_slice(), - [], - containing_scope, - file_metadata, - definition_span); - - return FinalMetadata(empty_type_metadata); - } - let variants = ty::enum_variants(cx.tcx(), enum_def_id); let enumerators_metadata: Vec<DIDescriptor> = variants @@ -1626,92 +1800,52 @@ fn prepare_enum_metadata(cx: &CrateContext, let type_rep = adt::represent_type(cx, enum_type); - return match *type_rep { + let discriminant_type_metadata = match *type_rep { adt::CEnum(inttype, _, _) => { - FinalMetadata(discriminant_type_metadata(inttype)) - } - adt::Univariant(ref struct_def, _) => { - assert!(variants.len() == 1); - let (metadata_stub, - variant_llvm_type, - member_description_factory) = - describe_enum_variant(cx, - struct_def, - &**variants.get(0), - None, - containing_scope, - file_metadata, - span); - UnfinishedMetadata { - cache_id: cache_id_for_type(enum_type), - metadata_stub: metadata_stub, - llvm_type: variant_llvm_type, - file_metadata: file_metadata, - member_description_factory: member_description_factory - } - } - adt::General(inttype, _) => { - let discriminant_type_metadata = discriminant_type_metadata(inttype); - let enum_llvm_type = type_of::type_of(cx, enum_type); - let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type); - let unique_id = generate_unique_type_id("DI_ENUM_"); - - let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| { - unique_id.as_slice().with_c_str(|unique_id| { - unsafe { - llvm::LLVMDIBuilderCreateUnionType( - DIB(cx), - containing_scope, - enum_name, - file_metadata, - loc.line as c_uint, - bytes_to_bits(enum_type_size), - bytes_to_bits(enum_type_align), - 0, // Flags - ptr::null(), - 0, // RuntimeLang - unique_id) - } - }) - }); + return FinalMetadata(discriminant_type_metadata(inttype)) + }, + adt::RawNullablePointer { .. } | + adt::StructWrappedNullablePointer { .. } | + adt::Univariant(..) => None, + adt::General(inttype, _) => Some(discriminant_type_metadata(inttype)), + }; - UnfinishedMetadata { - cache_id: cache_id_for_type(enum_type), - metadata_stub: enum_metadata, - llvm_type: enum_llvm_type, - file_metadata: file_metadata, - member_description_factory: GeneralMD(GeneralMemberDescriptionFactory { - type_rep: type_rep.clone(), - variants: variants, - discriminant_type_metadata: discriminant_type_metadata, - containing_scope: containing_scope, - file_metadata: file_metadata, - span: span, - }), - } - } - adt::RawNullablePointer { nnty, .. } => { - FinalMetadata(type_metadata(cx, nnty, span)) - } - adt::StructWrappedNullablePointer { nonnull: ref struct_def, nndiscr, .. } => { - let (metadata_stub, - variant_llvm_type, - member_description_factory) = - describe_enum_variant(cx, - struct_def, - &**variants.get(nndiscr as uint), - None, - containing_scope, - file_metadata, - span); - UnfinishedMetadata { - cache_id: cache_id_for_type(enum_type), - metadata_stub: metadata_stub, - llvm_type: variant_llvm_type, - file_metadata: file_metadata, - member_description_factory: member_description_factory + let enum_llvm_type = type_of::type_of(cx, enum_type); + let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type); + let unique_id = generate_unique_type_id("DI_ENUM_"); + + let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| { + unique_id.as_slice().with_c_str(|unique_id| { + unsafe { + llvm::LLVMDIBuilderCreateUnionType( + DIB(cx), + containing_scope, + enum_name, + file_metadata, + loc.line as c_uint, + bytes_to_bits(enum_type_size), + bytes_to_bits(enum_type_align), + 0, // Flags + ptr::null(), + 0, // RuntimeLang + unique_id) } - } + }) + }); + + return UnfinishedMetadata { + cache_id: cache_id_for_type(enum_type), + metadata_stub: enum_metadata, + llvm_type: enum_llvm_type, + file_metadata: file_metadata, + member_description_factory: EnumMDF(EnumMemberDescriptionFactory { + type_rep: type_rep.clone(), + variants: variants, + discriminant_type_metadata: discriminant_type_metadata, + containing_scope: containing_scope, + file_metadata: file_metadata, + span: span, + }), }; fn get_enum_discriminant_name(cx: &CrateContext, def_id: ast::DefId) -> token::InternedString { @@ -1725,19 +1859,6 @@ fn prepare_enum_metadata(cx: &CrateContext, } } -enum MemberOffset { - FixedMemberOffset { bytes: u64 }, - // For ComputedMemberOffset, the offset is read from the llvm type definition - ComputedMemberOffset -} - -struct MemberDescription { - name: String, - llvm_type: Type, - type_metadata: DIType, - offset: MemberOffset, -} - /// Creates debug information for a composite type, that is, anything that results in a LLVM struct. /// /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums. @@ -2367,6 +2488,7 @@ fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext { } #[inline] +#[allow(non_snake_case_functions)] fn DIB(cx: &CrateContext) -> DIBuilderRef { cx.dbg_cx.get_ref().builder } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index b551b9b1fd7..1f997c36c42 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -152,7 +152,7 @@ pub fn trans<'a>(bcx: &'a Block<'a>, let datum = unpack_datum!(bcx, trans_unadjusted(bcx, expr)); let datum = unpack_datum!(bcx, apply_adjustments(bcx, expr, datum)); bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, expr.id); - return DatumBlock(bcx, datum); + return DatumBlock::new(bcx, datum); } fn apply_adjustments<'a>(bcx: &'a Block<'a>, @@ -168,7 +168,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>, let mut datum = datum; let adjustment = match bcx.tcx().adjustments.borrow().find_copy(&expr.id) { None => { - return DatumBlock(bcx, datum); + return DatumBlock::new(bcx, datum); } Some(adj) => { adj } }; @@ -244,7 +244,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>, let scratch = rvalue_scratch_datum(bcx, slice_ty, "__adjust"); Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])); Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])); - DatumBlock(bcx, scratch.to_expr_datum()) + DatumBlock::new(bcx, scratch.to_expr_datum()) } fn add_env<'a>(bcx: &'a Block<'a>, @@ -282,7 +282,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>, let mut datum = source_datum.to_expr_datum(); datum.ty = target_obj_ty; - DatumBlock(bcx, datum) + DatumBlock::new(bcx, datum) } } @@ -357,7 +357,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>, let scratch = unpack_datum!( bcx, scratch.to_appropriate_datum(bcx)); - DatumBlock(bcx, scratch.to_expr_datum()) + DatumBlock::new(bcx, scratch.to_expr_datum()) } } }; @@ -365,7 +365,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>, fn nil<'a>(bcx: &'a Block<'a>, ty: ty::t) -> DatumBlock<'a, Expr> { let llval = C_undef(type_of::type_of(bcx.ccx(), ty)); let datum = immediate_rvalue(llval, ty); - DatumBlock(bcx, datum.to_expr_datum()) + DatumBlock::new(bcx, datum.to_expr_datum()) } } @@ -394,7 +394,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>, let datum = unpack_datum!( bcx, tvec::trans_uniq_vstore(bcx, expr, contents)); bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id); - DatumBlock(bcx, datum) + DatumBlock::new(bcx, datum) } ast::ExprBox(_, contents) => { // Special case for `box T`. (The other case, for GC, is handled @@ -494,7 +494,7 @@ fn trans_index<'a>(bcx: &'a Block<'a>, }); let elt = InBoundsGEP(bcx, base, [ix_val]); let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to()); - DatumBlock(bcx, Datum(elt, vt.unit_ty, LvalueExpr)) + DatumBlock::new(bcx, Datum::new(elt, vt.unit_ty, LvalueExpr)) } fn trans_def<'a>(bcx: &'a Block<'a>, @@ -559,10 +559,10 @@ fn trans_def<'a>(bcx: &'a Block<'a>, let did = get_did(bcx.ccx(), did); let val = get_val(bcx, did, const_ty); - DatumBlock(bcx, Datum(val, const_ty, LvalueExpr)) + DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr)) } _ => { - DatumBlock(bcx, trans_local_var(bcx, def).to_expr_datum()) + DatumBlock::new(bcx, trans_local_var(bcx, def).to_expr_datum()) } } } @@ -845,7 +845,7 @@ fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>, }; let fn_ty = expr_ty(bcx, ref_expr); - DatumBlock(bcx, Datum(llfn, fn_ty, RvalueExpr(Rvalue(ByValue)))) + DatumBlock::new(bcx, Datum::new(llfn, fn_ty, RvalueExpr(Rvalue::new(ByValue)))) } pub fn trans_local_var<'a>(bcx: &'a Block<'a>, @@ -863,7 +863,7 @@ pub fn trans_local_var<'a>(bcx: &'a Block<'a>, // Can't move upvars, so this is never a ZeroMemLastUse. let local_ty = node_id_type(bcx, nid); match bcx.fcx.llupvars.borrow().find(&nid) { - Some(&val) => Datum(val, local_ty, Lvalue), + Some(&val) => Datum::new(val, local_ty, Lvalue), None => { bcx.sess().bug(format!( "trans_local_var: no llval for upvar {:?} found", @@ -1664,7 +1664,7 @@ fn auto_ref<'a>(bcx: &'a Block<'a>, // Construct the resulting datum, using what was the "by ref" // ValueRef of type `referent_ty` to be the "by value" ValueRef // of type `&referent_ty`. - DatumBlock(bcx, Datum(llref, ptr_ty, RvalueExpr(Rvalue(ByValue)))) + DatumBlock::new(bcx, Datum::new(llref, ptr_ty, RvalueExpr(Rvalue::new(ByValue)))) } fn deref_multiple<'a>(bcx: &'a Block<'a>, @@ -1717,7 +1717,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>, let val = unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call, datum, None, None)); let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)); - Datum(val, ref_ty, RvalueExpr(Rvalue(ByValue))) + Datum::new(val, ref_ty, RvalueExpr(Rvalue::new(ByValue))) } None => { // Not overloaded. We already have a pointer we know how to deref. @@ -1740,7 +1740,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>, let llptrref = datum.to_llref(); let llptr = Load(bcx, llptrref); let llbody = GEPi(bcx, llptr, [0u, abi::box_field_body]); - DatumBlock(bcx, Datum(llbody, content_ty, LvalueExpr)) + DatumBlock::new(bcx, Datum::new(llbody, content_ty, LvalueExpr)) } ty::ty_ptr(ty::mt { ty: content_ty, .. }) | @@ -1758,7 +1758,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>, // rvalue for non-owning pointers like &T or *T, in which // case cleanup *is* scheduled elsewhere, by the true // owner (or, in the case of *T, by the user). - DatumBlock(bcx, Datum(ptr, content_ty, LvalueExpr)) + DatumBlock::new(bcx, Datum::new(ptr, content_ty, LvalueExpr)) } } } @@ -1818,10 +1818,10 @@ fn deref_once<'a>(bcx: &'a Block<'a>, (Load(bcx, datum.val), LvalueExpr) } RvalueExpr(Rvalue { mode: ByRef }) => { - (Load(bcx, datum.val), RvalueExpr(Rvalue(ByRef))) + (Load(bcx, datum.val), RvalueExpr(Rvalue::new(ByRef))) } RvalueExpr(Rvalue { mode: ByValue }) => { - (datum.val, RvalueExpr(Rvalue(ByRef))) + (datum.val, RvalueExpr(Rvalue::new(ByRef))) } }; diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index aeb7a4641c0..eea8ce44a9d 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -309,7 +309,7 @@ pub fn trans_intrinsic(ccx: &CrateContext, let mode = appropriate_rvalue_mode(ccx, tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, - kind: Rvalue(mode)}; + kind: Rvalue::new(mode)}; bcx = src.store_to(bcx, get_param(decl, first_real_arg)); RetVoid(bcx); } diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 446d2967139..a2d460e9162 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -257,7 +257,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>, alloc_fn, [ llptrval, llsizeval ], Some(expr::SaveIn(lldestval.val))).bcx; - return DatumBlock(bcx, lldestval).to_expr_datumblock(); + return DatumBlock::new(bcx, lldestval).to_expr_datumblock(); } _ => {} } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 07033d2bd4a..4dc66427d7f 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -840,11 +840,11 @@ pub enum BuiltinBound { BoundShare, } -pub fn EmptyBuiltinBounds() -> BuiltinBounds { +pub fn empty_builtin_bounds() -> BuiltinBounds { EnumSet::empty() } -pub fn AllBuiltinBounds() -> BuiltinBounds { +pub fn all_builtin_bounds() -> BuiltinBounds { let mut set = EnumSet::empty(); set.add(BoundStatic); set.add(BoundSend); @@ -2833,7 +2833,7 @@ pub fn adjust_ty(cx: &ctxt, ty::ClosureTy {fn_style: b.fn_style, onceness: ast::Many, store: store, - bounds: ty::AllBuiltinBounds(), + bounds: ty::all_builtin_bounds(), sig: b.sig.clone()}) } ref b => { @@ -4303,7 +4303,7 @@ pub fn visitor_object_ty(tcx: &ctxt, trait_ref.def_id, trait_ref.substs.clone(), RegionTraitStore(region, ast::MutMutable), - EmptyBuiltinBounds()))) + empty_builtin_bounds()))) } pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 9cc5d2d73ca..5323d4468c9 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -907,7 +907,7 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar match (ast_bounds, store) { (&Some(ref bound_vec), _) => { - let mut builtin_bounds = ty::EmptyBuiltinBounds(); + let mut builtin_bounds = ty::empty_builtin_bounds(); for ast_bound in bound_vec.iter() { match *ast_bound { ast::TraitTyParamBound(ref b) => { @@ -942,10 +942,10 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar }, // &'static Trait is sugar for &'static Trait:'static. (&None, ty::RegionTraitStore(ty::ReStatic, _)) => { - let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundStatic); set + let mut set = ty::empty_builtin_bounds(); set.add(ty::BoundStatic); set } // No bounds are automatically applied for &'r Trait or ~Trait (&None, ty::RegionTraitStore(..)) | - (&None, ty::UniqTraitStore) => ty::EmptyBuiltinBounds(), + (&None, ty::UniqTraitStore) => ty::empty_builtin_bounds(), } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index ec2fa0dab55..735bec4f4db 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -274,12 +274,12 @@ fn construct_transformed_self_ty_for_object( let r = r.subst(tcx, &substs); // handle Early-Bound lifetime ty::mk_trait(tcx, trait_def_id, substs, RegionTraitStore(r, mt.mutbl), - ty::EmptyBuiltinBounds()) + ty::empty_builtin_bounds()) } ty::ty_uniq(_) => { // must be SelfUniq ty::mk_trait(tcx, trait_def_id, substs, UniqTraitStore, - ty::EmptyBuiltinBounds()) + ty::empty_builtin_bounds()) } _ => { tcx.sess.span_bug(span, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f3881abead2..1987f4b0751 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2335,7 +2335,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, } _ => { // Not an error! Means we're inferring the closure type - let mut bounds = ty::EmptyBuiltinBounds(); + let mut bounds = ty::empty_builtin_bounds(); let onceness = match expr.node { ast::ExprProc(..) => { bounds.add(ty::BoundSend); diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 5e67cb54ccc..0d7bbdee3ce 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -472,7 +472,7 @@ fn fixup_substs(vcx: &VtableContext, let t = ty::mk_trait(tcx, id, substs, ty::RegionTraitStore(ty::ReStatic, ast::MutImmutable), - ty::EmptyBuiltinBounds()); + ty::empty_builtin_bounds()); fixup_ty(vcx, span, t, is_early).map(|t_f| { match ty::get(t_f).sty { ty::ty_trait(ref inner) => inner.substs.clone(), @@ -574,7 +574,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) { }); let param_bounds = ty::ParamBounds { - builtin_bounds: ty::EmptyBuiltinBounds(), + builtin_bounds: ty::empty_builtin_bounds(), trait_bounds: vec!(target_trait_ref) }; let vtables = @@ -766,7 +766,7 @@ pub fn resolve_impl(tcx: &ty::ctxt, // purpose of this is to check for supertrait impls, // but that falls out of doing this. let param_bounds = ty::ParamBounds { - builtin_bounds: ty::EmptyBuiltinBounds(), + builtin_bounds: ty::empty_builtin_bounds(), trait_bounds: vec!(Rc::new(impl_trait_ref)) }; let t = ty::node_id_to_type(tcx, impl_item.id); diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 447f8dfa278..4d07d227dc7 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -347,7 +347,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { ident: special_idents::self_, def_id: dummy_defid, bounds: Rc::new(ty::ParamBounds { - builtin_bounds: ty::EmptyBuiltinBounds(), + builtin_bounds: ty::empty_builtin_bounds(), trait_bounds: vec!(self_trait_ref) }), default: None @@ -418,7 +418,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, let self_ty = ty::mk_self(ccx.tcx, local_def(id)); let mut ty_trait_refs: Vec<Rc<ty::TraitRef>> = Vec::new(); - let mut bounds = ty::EmptyBuiltinBounds(); + let mut bounds = ty::empty_builtin_bounds(); for ast_trait_ref in ast_trait_refs.iter() { let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, ast_trait_ref); // FIXME(#8559): Need to instantiate the trait_ref whether or not it's a @@ -1094,7 +1094,7 @@ fn ty_generics(ccx: &CrateCtxt, */ let mut param_bounds = ty::ParamBounds { - builtin_bounds: ty::EmptyBuiltinBounds(), + builtin_bounds: ty::empty_builtin_bounds(), trait_bounds: Vec::new() }; for ast_bound in ast_bounds.iter() { diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index e073d4fcbd7..d560b1c9a99 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -22,7 +22,6 @@ pub use middle::typeck::infer::resolve::{resolve_nested_tvar}; pub use middle::typeck::infer::resolve::{resolve_rvar}; use collections::HashMap; -use collections::SmallIntMap; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, Vid}; use middle::ty; use middle::ty_fold; @@ -258,27 +257,20 @@ pub fn fixup_err_to_str(f: fixup_err) -> String { } } -fn new_ValsAndBindings<V:Clone,T:Clone>() -> ValsAndBindings<V, T> { - ValsAndBindings { - vals: SmallIntMap::new(), - bindings: Vec::new() - } -} - pub fn new_infer_ctxt<'a>(tcx: &'a ty::ctxt) -> InferCtxt<'a> { InferCtxt { tcx: tcx, - ty_var_bindings: RefCell::new(new_ValsAndBindings()), + ty_var_bindings: RefCell::new(ValsAndBindings::new()), ty_var_counter: Cell::new(0), - int_var_bindings: RefCell::new(new_ValsAndBindings()), + int_var_bindings: RefCell::new(ValsAndBindings::new()), int_var_counter: Cell::new(0), - float_var_bindings: RefCell::new(new_ValsAndBindings()), + float_var_bindings: RefCell::new(ValsAndBindings::new()), float_var_counter: Cell::new(0), - region_vars: RegionVarBindings(tcx), + region_vars: RegionVarBindings::new(tcx), } } @@ -679,7 +671,7 @@ impl<'a> InferCtxt<'a> { trait_ref.def_id, trait_ref.substs.clone(), ty::UniqTraitStore, - ty::EmptyBuiltinBounds()); + ty::empty_builtin_bounds()); let dummy1 = self.resolve_type_vars_if_possible(dummy0); match ty::get(dummy1).sty { ty::ty_trait(box ty::TyTrait { ref def_id, ref substs, .. }) => { diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index 0efbe733367..c964530a5f9 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -143,21 +143,21 @@ pub struct RegionVarBindings<'a> { values: RefCell<Option<Vec<VarValue> >>, } -pub fn RegionVarBindings<'a>(tcx: &'a ty::ctxt) -> RegionVarBindings<'a> { - RegionVarBindings { - tcx: tcx, - var_origins: RefCell::new(Vec::new()), - values: RefCell::new(None), - constraints: RefCell::new(HashMap::new()), - lubs: RefCell::new(HashMap::new()), - glbs: RefCell::new(HashMap::new()), - skolemization_count: Cell::new(0), - bound_count: Cell::new(0), - undo_log: RefCell::new(Vec::new()) +impl<'a> RegionVarBindings<'a> { + pub fn new(tcx: &'a ty::ctxt) -> RegionVarBindings<'a> { + RegionVarBindings { + tcx: tcx, + var_origins: RefCell::new(Vec::new()), + values: RefCell::new(None), + constraints: RefCell::new(HashMap::new()), + lubs: RefCell::new(HashMap::new()), + glbs: RefCell::new(HashMap::new()), + skolemization_count: Cell::new(0), + bound_count: Cell::new(0), + undo_log: RefCell::new(Vec::new()) + } } -} -impl<'a> RegionVarBindings<'a> { pub fn in_snapshot(&self) -> bool { self.undo_log.borrow().len() > 0 } diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index f36b9862850..867e52056a7 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -30,6 +30,15 @@ pub struct ValsAndBindings<V, T> { pub bindings: Vec<(V, VarValue<V, T>)> , } +impl<V:Clone, T:Clone> ValsAndBindings<V, T> { + pub fn new() -> ValsAndBindings<V, T> { + ValsAndBindings { + vals: SmallIntMap::new(), + bindings: Vec::new() + } + } +} + pub struct Node<V, T> { pub root: V, pub possible_types: T, diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index f24bd661c8c..fea6748660b 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -141,6 +141,7 @@ mod imp { static LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002; + #[allow(non_snake_case_functions)] extern "system" { fn LockFileEx(hFile: libc::HANDLE, dwFlags: libc::DWORD, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7af1eb21aea..3b3f4378d67 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -356,7 +356,7 @@ impl fmt::Show for clean::Type { } } } - ret.into_owned() + ret }) } clean::Proc(ref decl) => { diff --git a/src/librustuv/homing.rs b/src/librustuv/homing.rs index b9025397b8d..5bb9c70f047 100644 --- a/src/librustuv/homing.rs +++ b/src/librustuv/homing.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -88,7 +88,7 @@ pub trait HomingIO { /// This function will move tasks to run on their home I/O scheduler. Note /// that this function does *not* pin the task to the I/O scheduler, but /// rather it simply moves it to running on the I/O scheduler. - fn go_to_IO_home(&mut self) -> uint { + fn go_to_io_home(&mut self) -> uint { let _f = ForbidUnwind::new("going home"); let cur_loop_id = local_id(); @@ -118,7 +118,7 @@ pub trait HomingIO { /// move the local task to its I/O scheduler and then return an RAII wrapper /// which will return the task home. fn fire_homing_missile(&mut self) -> HomingMissile { - HomingMissile { io_home: self.go_to_IO_home() } + HomingMissile { io_home: self.go_to_io_home() } } } diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index 5d2f229beb6..5a8759540c8 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -261,7 +261,6 @@ impl<'a> FromBase64 for &'a str { #[cfg(test)] mod tests { extern crate test; - extern crate rand; use self::test::Bencher; use base64::{Config, FromBase64, ToBase64, STANDARD, URL_SAFE}; @@ -335,7 +334,7 @@ mod tests { #[test] fn test_base64_random() { - use self::rand::{task_rng, random, Rng}; + use std::rand::{task_rng, random, Rng}; for _ in range(0, 1000) { let times = task_rng().gen_range(1u, 100); diff --git a/src/libserialize/ebml.rs b/src/libserialize/ebml.rs index 67045476f6d..9ba2c2cd258 100644 --- a/src/libserialize/ebml.rs +++ b/src/libserialize/ebml.rs @@ -26,6 +26,10 @@ pub struct Doc<'a> { } impl<'doc> Doc<'doc> { + pub fn new(data: &'doc [u8]) -> Doc<'doc> { + Doc { data: data, start: 0u, end: data.len() } + } + pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> { reader::get_doc(*self, tag) } @@ -192,10 +196,6 @@ pub mod reader { } } - pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> { - Doc { data: data, start: 0u, end: data.len() } - } - pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> { let elt_tag = try!(vuint_at(data, start)); let elt_size = try!(vuint_at(data, elt_tag.next)); @@ -296,14 +296,14 @@ pub mod reader { pos: uint, } - pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> { - Decoder { - parent: d, - pos: d.start + impl<'doc> Decoder<'doc> { + pub fn new(d: Doc<'doc>) -> Decoder<'doc> { + Decoder { + parent: d, + pos: d.start + } } - } - impl<'doc> Decoder<'doc> { fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> { if self.pos < self.parent.end { let TaggedDoc { tag: r_tag, doc: r_doc } = @@ -673,15 +673,15 @@ pub mod writer { }) } - pub fn Encoder<'a, W: Writer + Seek>(w: &'a mut W) -> Encoder<'a, W> { - Encoder { - writer: w, - size_positions: vec!(), - } - } - // FIXME (#2741): Provide a function to write the standard ebml header. impl<'a, W: Writer + Seek> Encoder<'a, W> { + pub fn new(w: &'a mut W) -> Encoder<'a, W> { + Encoder { + writer: w, + size_positions: vec!(), + } + } + /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME. pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> { Encoder { @@ -1020,6 +1020,7 @@ pub mod writer { #[cfg(test)] mod tests { + use super::Doc; use ebml::reader; use ebml::writer; use {Encodable, Decodable}; @@ -1081,11 +1082,11 @@ mod tests { debug!("v == {}", v); let mut wr = MemWriter::new(); { - let mut ebml_w = writer::Encoder(&mut wr); + let mut ebml_w = writer::Encoder::new(&mut wr); let _ = v.encode(&mut ebml_w); } - let ebml_doc = reader::Doc(wr.get_ref()); - let mut deser = reader::Decoder(ebml_doc); + let ebml_doc = Doc::new(wr.get_ref()); + let mut deser = reader::Decoder::new(ebml_doc); let v1 = Decodable::decode(&mut deser).unwrap(); debug!("v1 == {}", v1); assert_eq!(v, v1); @@ -1099,6 +1100,7 @@ mod tests { #[cfg(test)] mod bench { + #![allow(non_snake_case_functions)] extern crate test; use self::test::Bencher; use ebml::reader; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index c1bc68b3e12..b63ccbef55f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -120,12 +120,10 @@ #[cfg(test)] extern crate debug; #[cfg(test)] #[phase(syntax, link)] extern crate log; -// Make and rand accessible for benchmarking/testcases -#[cfg(test)] extern crate rand; - extern crate alloc; extern crate core; extern crate libc; +extern crate core_rand = "rand"; // Make std testable by not duplicating lang items. See #2912 #[cfg(test)] extern crate realstd = "std"; @@ -208,6 +206,7 @@ pub mod slice; pub mod vec; pub mod str; pub mod string; +pub mod rand; pub mod ascii; diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 1efe83217f4..20f5927c9bd 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -819,84 +819,84 @@ mod bench { mod uint { use super::test::Bencher; - use rand::{XorShiftRng, Rng}; + use rand::{weak_rng, Rng}; use num::ToStrRadix; #[bench] fn to_str_bin(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<uint>().to_str_radix(2); }) } #[bench] fn to_str_oct(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<uint>().to_str_radix(8); }) } #[bench] fn to_str_dec(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<uint>().to_str_radix(10); }) } #[bench] fn to_str_hex(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<uint>().to_str_radix(16); }) } #[bench] fn to_str_base_36(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<uint>().to_str_radix(36); }) } } mod int { use super::test::Bencher; - use rand::{XorShiftRng, Rng}; + use rand::{weak_rng, Rng}; use num::ToStrRadix; #[bench] fn to_str_bin(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<int>().to_str_radix(2); }) } #[bench] fn to_str_oct(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<int>().to_str_radix(8); }) } #[bench] fn to_str_dec(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<int>().to_str_radix(10); }) } #[bench] fn to_str_hex(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<int>().to_str_radix(16); }) } #[bench] fn to_str_base_36(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { rng.gen::<int>().to_str_radix(36); }) } } mod f64 { use super::test::Bencher; - use rand::{XorShiftRng, Rng}; + use rand::{weak_rng, Rng}; use f64; #[bench] fn float_to_str(b: &mut Bencher) { - let mut rng = XorShiftRng::new().unwrap(); + let mut rng = weak_rng(); b.iter(|| { f64::to_str(rng.gen()); }) } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index f960228c63c..7e6d3c0606f 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -27,6 +27,7 @@ */ #![allow(missing_doc)] +#![allow(non_snake_case_functions)] use clone::Clone; use container::Container; @@ -1513,7 +1514,8 @@ mod tests { fn make_rand_name() -> String { let mut rng = rand::task_rng(); - let n = format!("TEST{}", rng.gen_ascii_str(10u).as_slice()); + let n = format!("TEST{}", rng.gen_ascii_chars().take(10u) + .collect::<String>()); assert!(getenv(n.as_slice()).is_none()); n } diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs new file mode 100644 index 00000000000..61a2ffd383d --- /dev/null +++ b/src/libstd/rand/mod.rs @@ -0,0 +1,525 @@ +// 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. + +/*! + +Utilities for random number generation + +The key functions are `random()` and `Rng::gen()`. These are polymorphic +and so can be used to generate any type that implements `Rand`. Type inference +means that often a simple call to `rand::random()` or `rng.gen()` will +suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`. + +See the `distributions` submodule for sampling random numbers from +distributions like normal and exponential. + +# Task-local RNG + +There is built-in support for a RNG associated with each task stored +in task-local storage. This RNG can be accessed via `task_rng`, or +used implicitly via `random`. This RNG is normally randomly seeded +from an operating-system source of randomness, e.g. `/dev/urandom` on +Unix systems, and will automatically reseed itself from this source +after generating 32 KiB of random data. + +# Cryptographic security + +An application that requires an entropy source for cryptographic purposes +must use `OsRng`, which reads randomness from the source that the operating +system provides (e.g. `/dev/urandom` on Unixes or `CryptGenRandom()` on Windows). +The other random number generators provided by this module are not suitable +for such purposes. + +*Note*: many Unix systems provide `/dev/random` as well as `/dev/urandom`. +This module uses `/dev/urandom` for the following reasons: + +- On Linux, `/dev/random` may block if entropy pool is empty; `/dev/urandom` will not block. + This does not mean that `/dev/random` provides better output than + `/dev/urandom`; the kernel internally runs a cryptographically secure pseudorandom + number generator (CSPRNG) based on entropy pool for random number generation, + so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases. + However, this means that `/dev/urandom` can yield somewhat predictable randomness + if the entropy pool is very small, such as immediately after first booting. + If an application likely to be run soon after first booting, or on a system with very + few entropy sources, one should consider using `/dev/random` via `ReaderRng`. +- On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference + between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random` + and `/dev/urandom` may block once if the CSPRNG has not seeded yet.) + +# Examples + +```rust +use std::rand; +use std::rand::Rng; + +let mut rng = rand::task_rng(); +if rng.gen() { // bool + println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>()) +} +``` + +```rust +use std::rand; + +let tuple = rand::random::<(f64, char)>(); +println!("{}", tuple) +``` +*/ + +use cell::RefCell; +use clone::Clone; +use io::IoResult; +use iter::Iterator; +use mem; +use option::{Some, None}; +use rc::Rc; +use result::{Ok, Err}; +use vec::Vec; + +#[cfg(not(target_word_size="64"))] +use IsaacWordRng = core_rand::IsaacRng; +#[cfg(target_word_size="64")] +use IsaacWordRng = core_rand::Isaac64Rng; + +pub use core_rand::{Rand, Rng, SeedableRng, Open01, Closed01}; +pub use core_rand::{XorShiftRng, IsaacRng, Isaac64Rng}; +pub use core_rand::{distributions, reseeding}; +pub use rand::os::OsRng; + +pub mod os; +pub mod reader; + +/// The standard RNG. This is designed to be efficient on the current +/// platform. +pub struct StdRng { rng: IsaacWordRng } + +impl StdRng { + /// Create a randomly seeded instance of `StdRng`. + /// + /// This is a very expensive operation as it has to read + /// randomness from the operating system and use this in an + /// expensive seeding operation. If one is only generating a small + /// number of random numbers, or doesn't need the utmost speed for + /// generating each number, `task_rng` and/or `random` may be more + /// appropriate. + /// + /// Reading the randomness from the OS may fail, and any error is + /// propagated via the `IoResult` return value. + pub fn new() -> IoResult<StdRng> { + OsRng::new().map(|mut r| StdRng { rng: r.gen() }) + } +} + +impl Rng for StdRng { + #[inline] + fn next_u32(&mut self) -> u32 { + self.rng.next_u32() + } + + #[inline] + fn next_u64(&mut self) -> u64 { + self.rng.next_u64() + } +} + +impl<'a> SeedableRng<&'a [uint]> for StdRng { + fn reseed(&mut self, seed: &'a [uint]) { + // the internal RNG can just be seeded from the above + // randomness. + self.rng.reseed(unsafe {mem::transmute(seed)}) + } + + fn from_seed(seed: &'a [uint]) -> StdRng { + StdRng { rng: SeedableRng::from_seed(unsafe {mem::transmute(seed)}) } + } +} + +/// Create a weak random number generator with a default algorithm and seed. +/// +/// It returns the fastest `Rng` algorithm currently available in Rust without +/// consideration for cryptography or security. If you require a specifically +/// seeded `Rng` for consistency over time you should pick one algorithm and +/// create the `Rng` yourself. +/// +/// This will read randomness from the operating system to seed the +/// generator. +pub fn weak_rng() -> XorShiftRng { + match OsRng::new() { + Ok(mut r) => r.gen(), + Err(e) => fail!("weak_rng: failed to create seeded RNG: {}", e) + } +} + +/// Controls how the task-local RNG is reseeded. +struct TaskRngReseeder; + +impl reseeding::Reseeder<StdRng> for TaskRngReseeder { + fn reseed(&mut self, rng: &mut StdRng) { + *rng = match StdRng::new() { + Ok(r) => r, + Err(e) => fail!("could not reseed task_rng: {}", e) + } + } +} +static TASK_RNG_RESEED_THRESHOLD: uint = 32_768; +type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>; + +/// The task-local RNG. +pub struct TaskRng { + rng: Rc<RefCell<TaskRngInner>>, +} + +/// Retrieve the lazily-initialized task-local random number +/// generator, seeded by the system. Intended to be used in method +/// chaining style, e.g. `task_rng().gen::<int>()`. +/// +/// The RNG provided will reseed itself from the operating system +/// after generating a certain amount of randomness. +/// +/// The internal RNG used is platform and architecture dependent, even +/// if the operating system random number generator is rigged to give +/// the same sequence always. If absolute consistency is required, +/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`. +pub fn task_rng() -> TaskRng { + // used to make space in TLS for a random number generator + local_data_key!(TASK_RNG_KEY: Rc<RefCell<TaskRngInner>>) + + match TASK_RNG_KEY.get() { + None => { + let r = match StdRng::new() { + Ok(r) => r, + Err(e) => fail!("could not initialize task_rng: {}", e) + }; + let rng = reseeding::ReseedingRng::new(r, + TASK_RNG_RESEED_THRESHOLD, + TaskRngReseeder); + let rng = Rc::new(RefCell::new(rng)); + TASK_RNG_KEY.replace(Some(rng.clone())); + + TaskRng { rng: rng } + } + Some(rng) => TaskRng { rng: rng.clone() } + } +} + +impl Rng for TaskRng { + fn next_u32(&mut self) -> u32 { + self.rng.borrow_mut().next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.rng.borrow_mut().next_u64() + } + + #[inline] + fn fill_bytes(&mut self, bytes: &mut [u8]) { + self.rng.borrow_mut().fill_bytes(bytes) + } +} + +/// Generate a random value using the task-local random number +/// generator. +/// +/// # Example +/// +/// ```rust +/// use std::rand::random; +/// +/// if random() { +/// let x = random(); +/// println!("{}", 2u * x); +/// } else { +/// println!("{}", random::<f64>()); +/// } +/// ``` +#[inline] +pub fn random<T: Rand>() -> T { + task_rng().gen() +} + +/// Randomly sample up to `n` elements from an iterator. +/// +/// # Example +/// +/// ```rust +/// use std::rand::{task_rng, sample}; +/// +/// let mut rng = task_rng(); +/// let sample = sample(&mut rng, range(1, 100), 5); +/// println!("{}", sample); +/// ``` +pub fn sample<T, I: Iterator<T>, R: Rng>(rng: &mut R, + mut iter: I, + amt: uint) -> Vec<T> { + let mut reservoir: Vec<T> = iter.by_ref().take(amt).collect(); + for (i, elem) in iter.enumerate() { + let k = rng.gen_range(0, i + 1 + amt); + if k < amt { + *reservoir.get_mut(k) = elem; + } + } + return reservoir; +} + +#[cfg(test)] +mod test { + use prelude::*; + use super::{Rng, task_rng, random, SeedableRng, StdRng, sample}; + use iter::order; + + struct ConstRng { i: u64 } + impl Rng for ConstRng { + fn next_u32(&mut self) -> u32 { self.i as u32 } + fn next_u64(&mut self) -> u64 { self.i } + + // no fill_bytes on purpose + } + + #[test] + fn test_fill_bytes_default() { + let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 }; + + // check every remainder mod 8, both in small and big vectors. + let lengths = [0, 1, 2, 3, 4, 5, 6, 7, + 80, 81, 82, 83, 84, 85, 86, 87]; + for &n in lengths.iter() { + let mut v = Vec::from_elem(n, 0u8); + r.fill_bytes(v.as_mut_slice()); + + // use this to get nicer error messages. + for (i, &byte) in v.iter().enumerate() { + if byte == 0 { + fail!("byte {} of {} is zero", i, n) + } + } + } + } + + #[test] + fn test_gen_range() { + let mut r = task_rng(); + for _ in range(0, 1000) { + let a = r.gen_range(-3i, 42); + assert!(a >= -3 && a < 42); + assert_eq!(r.gen_range(0, 1), 0); + assert_eq!(r.gen_range(-12, -11), -12); + } + + for _ in range(0, 1000) { + let a = r.gen_range(10, 42); + assert!(a >= 10 && a < 42); + assert_eq!(r.gen_range(0, 1), 0); + assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000); + } + + } + + #[test] + #[should_fail] + fn test_gen_range_fail_int() { + let mut r = task_rng(); + r.gen_range(5i, -2); + } + + #[test] + #[should_fail] + fn test_gen_range_fail_uint() { + let mut r = task_rng(); + r.gen_range(5u, 2u); + } + + #[test] + fn test_gen_f64() { + let mut r = task_rng(); + let a = r.gen::<f64>(); + let b = r.gen::<f64>(); + debug!("{}", (a, b)); + } + + #[test] + fn test_gen_weighted_bool() { + let mut r = task_rng(); + assert_eq!(r.gen_weighted_bool(0u), true); + assert_eq!(r.gen_weighted_bool(1u), true); + } + + #[test] + fn test_gen_ascii_str() { + let mut r = task_rng(); + assert_eq!(r.gen_ascii_chars().take(0).len(), 0u); + assert_eq!(r.gen_ascii_chars().take(10).len(), 10u); + assert_eq!(r.gen_ascii_chars().take(16).len(), 16u); + } + + #[test] + fn test_gen_vec() { + let mut r = task_rng(); + assert_eq!(r.gen_iter::<u8>().take(0).len(), 0u); + assert_eq!(r.gen_iter::<u8>().take(10).len(), 10u); + assert_eq!(r.gen_iter::<f64>().take(16).len(), 16u); + } + + #[test] + fn test_choose() { + let mut r = task_rng(); + assert_eq!(r.choose([1, 1, 1]).map(|&x|x), Some(1)); + + let v: &[int] = &[]; + assert_eq!(r.choose(v), None); + } + + #[test] + fn test_shuffle() { + let mut r = task_rng(); + let empty: &mut [int] = &mut []; + r.shuffle(empty); + let mut one = [1]; + r.shuffle(one); + assert_eq!(one.as_slice(), &[1]); + + let mut two = [1, 2]; + r.shuffle(two); + assert!(two == [1, 2] || two == [2, 1]); + + let mut x = [1, 1, 1]; + r.shuffle(x); + assert_eq!(x.as_slice(), &[1, 1, 1]); + } + + #[test] + fn test_task_rng() { + let mut r = task_rng(); + r.gen::<int>(); + let mut v = [1, 1, 1]; + r.shuffle(v); + assert_eq!(v.as_slice(), &[1, 1, 1]); + assert_eq!(r.gen_range(0u, 1u), 0u); + } + + #[test] + fn test_random() { + // not sure how to test this aside from just getting some values + let _n : uint = random(); + let _f : f32 = random(); + let _o : Option<Option<i8>> = random(); + let _many : ((), + (uint, + int, + Option<(u32, (bool,))>), + (u8, i8, u16, i16, u32, i32, u64, i64), + (f32, (f64, (f64,)))) = random(); + } + + #[test] + fn test_sample() { + let min_val = 1; + let max_val = 100; + + let mut r = task_rng(); + let vals = range(min_val, max_val).collect::<Vec<int>>(); + let small_sample = sample(&mut r, vals.iter(), 5); + let large_sample = sample(&mut r, vals.iter(), vals.len() + 5); + + assert_eq!(small_sample.len(), 5); + assert_eq!(large_sample.len(), vals.len()); + + assert!(small_sample.iter().all(|e| { + **e >= min_val && **e <= max_val + })); + } + + #[test] + fn test_std_rng_seeded() { + let s = task_rng().gen_iter::<uint>().take(256).collect::<Vec<uint>>(); + let mut ra: StdRng = SeedableRng::from_seed(s.as_slice()); + let mut rb: StdRng = SeedableRng::from_seed(s.as_slice()); + assert!(order::equals(ra.gen_ascii_chars().take(100), + rb.gen_ascii_chars().take(100))); + } + + #[test] + fn test_std_rng_reseed() { + let s = task_rng().gen_iter::<uint>().take(256).collect::<Vec<uint>>(); + let mut r: StdRng = SeedableRng::from_seed(s.as_slice()); + let string1 = r.gen_ascii_chars().take(100).collect::<String>(); + + r.reseed(s.as_slice()); + + let string2 = r.gen_ascii_chars().take(100).collect::<String>(); + assert_eq!(string1, string2); + } +} + +#[cfg(test)] +static RAND_BENCH_N: u64 = 100; + +#[cfg(test)] +mod bench { + extern crate test; + use prelude::*; + + use self::test::Bencher; + use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N}; + use super::{OsRng, weak_rng}; + use mem::size_of; + + #[bench] + fn rand_xorshift(b: &mut Bencher) { + let mut rng: XorShiftRng = OsRng::new().unwrap().gen(); + b.iter(|| { + for _ in range(0, RAND_BENCH_N) { + rng.gen::<uint>(); + } + }); + b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; + } + + #[bench] + fn rand_isaac(b: &mut Bencher) { + let mut rng: IsaacRng = OsRng::new().unwrap().gen(); + b.iter(|| { + for _ in range(0, RAND_BENCH_N) { + rng.gen::<uint>(); + } + }); + b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; + } + + #[bench] + fn rand_isaac64(b: &mut Bencher) { + let mut rng: Isaac64Rng = OsRng::new().unwrap().gen(); + b.iter(|| { + for _ in range(0, RAND_BENCH_N) { + rng.gen::<uint>(); + } + }); + b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; + } + + #[bench] + fn rand_std(b: &mut Bencher) { + let mut rng = StdRng::new().unwrap(); + b.iter(|| { + for _ in range(0, RAND_BENCH_N) { + rng.gen::<uint>(); + } + }); + b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N; + } + + #[bench] + fn rand_shuffle_100(b: &mut Bencher) { + let mut rng = weak_rng(); + let x : &mut[uint] = [1,..100]; + b.iter(|| { + rng.shuffle(x); + }) + } +} diff --git a/src/librand/os.rs b/src/libstd/rand/os.rs index 0e1d01a45c9..284d41d3208 100644 --- a/src/librand/os.rs +++ b/src/libstd/rand/os.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -11,13 +11,15 @@ //! Interfaces to the operating system provided random number //! generators. -pub use self::imp::OSRng; +pub use self::imp::OsRng; #[cfg(unix)] mod imp { - use Rng; - use reader::ReaderRng; - use std::io::{IoResult, File}; + use io::{IoResult, File}; + use path::Path; + use rand::Rng; + use rand::reader::ReaderRng; + use result::{Ok, Err}; /// A random number generator that retrieves randomness straight from /// the operating system. Platform sources: @@ -29,21 +31,21 @@ mod imp { /// /// This does not block. #[cfg(unix)] - pub struct OSRng { + pub struct OsRng { inner: ReaderRng<File> } - impl OSRng { - /// Create a new `OSRng`. - pub fn new() -> IoResult<OSRng> { + impl OsRng { + /// Create a new `OsRng`. + pub fn new() -> IoResult<OsRng> { let reader = try!(File::open(&Path::new("/dev/urandom"))); let reader_rng = ReaderRng::new(reader); - Ok(OSRng { inner: reader_rng }) + Ok(OsRng { inner: reader_rng }) } } - impl Rng for OSRng { + impl Rng for OsRng { fn next_u32(&mut self) -> u32 { self.inner.next_u32() } @@ -60,12 +62,16 @@ mod imp { mod imp { extern crate libc; - use Rng; - use std::io::{IoResult, IoError}; - use std::mem; - use std::os; - use std::rt::stack; + use container::Container; + use io::{IoResult, IoError}; + use mem; + use ops::Drop; + use os; + use rand::Rng; + use result::{Ok, Err}; + use rt::stack; use self::libc::{c_ulong, DWORD, BYTE, LPCSTR, BOOL}; + use slice::MutableVector; type HCRYPTPROV = c_ulong; @@ -78,7 +84,7 @@ mod imp { /// service provider with the `PROV_RSA_FULL` type. /// /// This does not block. - pub struct OSRng { + pub struct OsRng { hcryptprov: HCRYPTPROV } @@ -87,6 +93,7 @@ mod imp { static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000; static NTE_BAD_SIGNATURE: DWORD = 0x80090006; + #[allow(non_snake_case_functions)] extern "system" { fn CryptAcquireContextA(phProv: *mut HCRYPTPROV, pszContainer: LPCSTR, @@ -99,9 +106,9 @@ mod imp { fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL; } - impl OSRng { - /// Create a new `OSRng`. - pub fn new() -> IoResult<OSRng> { + impl OsRng { + /// Create a new `OsRng`. + pub fn new() -> IoResult<OsRng> { let mut hcp = 0; let mut ret = unsafe { CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR, @@ -148,12 +155,12 @@ mod imp { if ret == 0 { Err(IoError::last_error()) } else { - Ok(OSRng { hcryptprov: hcp }) + Ok(OsRng { hcryptprov: hcp }) } } } - impl Rng for OSRng { + impl Rng for OsRng { fn next_u32(&mut self) -> u32 { let mut v = [0u8, .. 4]; self.fill_bytes(v); @@ -175,7 +182,7 @@ mod imp { } } - impl Drop for OSRng { + impl Drop for OsRng { fn drop(&mut self) { let ret = unsafe { CryptReleaseContext(self.hcryptprov, 0) @@ -189,13 +196,15 @@ mod imp { #[cfg(test)] mod test { - use super::OSRng; - use Rng; - use std::task; + use prelude::*; + + use super::OsRng; + use rand::Rng; + use task; #[test] fn test_os_rng() { - let mut r = OSRng::new().unwrap(); + let mut r = OsRng::new().unwrap(); r.next_u32(); r.next_u64(); @@ -217,7 +226,7 @@ mod test { // deschedule to attempt to interleave things as much // as possible (XXX: is this a good test?) - let mut r = OSRng::new().unwrap(); + let mut r = OsRng::new().unwrap(); task::deschedule(); let mut v = [0u8, .. 1000]; diff --git a/src/librand/reader.rs b/src/libstd/rand/reader.rs index e800f64463b..170884073f3 100644 --- a/src/librand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -10,7 +10,10 @@ //! A wrapper around any Reader to treat it as an RNG. -use Rng; +use container::Container; +use io::Reader; +use rand::Rng; +use result::{Ok, Err}; /// An RNG that reads random bytes straight from a `Reader`. This will /// work best with an infinite reader, but this is not required. @@ -20,7 +23,7 @@ use Rng; /// # Example /// /// ```rust -/// use rand::{reader, Rng}; +/// use std::rand::{reader, Rng}; /// use std::io::MemReader; /// /// let mut rng = reader::ReaderRng::new(MemReader::new(vec!(1,2,3,4,5,6,7,8))); @@ -70,10 +73,12 @@ impl<R: Reader> Rng for ReaderRng<R> { #[cfg(test)] #[allow(deprecated_owned_vector)] mod test { + use prelude::*; + use super::ReaderRng; - use std::io::MemReader; - use std::mem; - use Rng; + use io::MemReader; + use mem; + use rand::Rng; #[test] fn test_reader_rng_u64() { diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 02535ccee51..f21dcdf2a46 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -42,11 +42,12 @@ pub fn align(size: uint, align: uint) -> uint { pub struct MovePtrAdaptor<V> { inner: V } -pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> { - MovePtrAdaptor { inner: v } -} impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> { + pub fn new(v: V) -> MovePtrAdaptor<V> { + MovePtrAdaptor { inner: v } + } + #[inline] pub fn bump(&mut self, sz: uint) { self.inner.move_ptr(|p| ((p as uint) + sz) as *u8) diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index 969c20d8b55..0621cbf35fe 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -110,17 +110,6 @@ pub struct ReprVisitor<'a> { last_err: Option<io::IoError>, } -pub fn ReprVisitor<'a>(ptr: *u8, - writer: &'a mut io::Writer) -> ReprVisitor<'a> { - ReprVisitor { - ptr: ptr, - ptr_stk: vec!(), - var_stk: vec!(), - writer: writer, - last_err: None, - } -} - impl<'a> MovePtr for ReprVisitor<'a> { #[inline] fn move_ptr(&mut self, adjustment: |*u8| -> *u8) { @@ -136,6 +125,15 @@ impl<'a> MovePtr for ReprVisitor<'a> { impl<'a> ReprVisitor<'a> { // Various helpers for the TyVisitor impl + pub fn new(ptr: *u8, writer: &'a mut io::Writer) -> ReprVisitor<'a> { + ReprVisitor { + ptr: ptr, + ptr_stk: vec!(), + var_stk: vec!(), + writer: writer, + last_err: None, + } + } #[inline] pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T| -> bool) -> bool { @@ -152,16 +150,8 @@ impl<'a> ReprVisitor<'a> { #[inline] pub fn visit_ptr_inner(&mut self, ptr: *u8, inner: *TyDesc) -> bool { unsafe { - // This should call the constructor up above, but due to limiting - // issues we have to recreate it here. - let u = ReprVisitor { - ptr: ptr, - ptr_stk: vec!(), - var_stk: vec!(), - writer: ::mem::transmute_copy(&self.writer), - last_err: None, - }; - let mut v = reflect::MovePtrAdaptor(u); + let u = ReprVisitor::new(ptr, ::mem::transmute_copy(&self.writer)); + let mut v = reflect::MovePtrAdaptor::new(u); // Obviously this should not be a thing, but blame #8401 for now visit_tydesc(inner, &mut v as &mut TyVisitor); match v.unwrap().last_err { @@ -592,8 +582,8 @@ pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> { unsafe { let ptr = object as *T as *u8; let tydesc = get_tydesc::<T>(); - let u = ReprVisitor(ptr, writer); - let mut v = reflect::MovePtrAdaptor(u); + let u = ReprVisitor::new(ptr, writer); + let mut v = reflect::MovePtrAdaptor::new(u); visit_tydesc(tydesc, &mut v as &mut TyVisitor); match v.unwrap().last_err { Some(e) => Err(e), diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index f4cb770544c..ac421bf78be 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -518,6 +518,7 @@ mod imp { use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; use slice::ImmutableVector; + #[allow(non_snake_case_functions)] extern "system" { fn GetCurrentProcess() -> libc::HANDLE; fn GetCurrentThread() -> libc::HANDLE; diff --git a/src/libstd/rt/libunwind.rs b/src/libstd/rt/libunwind.rs index 4fd610d7423..00301e71b0d 100644 --- a/src/libstd/rt/libunwind.rs +++ b/src/libstd/rt/libunwind.rs @@ -11,6 +11,7 @@ //! Unwind library interface #![allow(non_camel_case_types)] +#![allow(non_snake_case_functions)] #![allow(dead_code)] // these are just bindings use libc; diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs index 6cc9604dc59..81dcf909706 100644 --- a/src/libstd/rt/thread.rs +++ b/src/libstd/rt/thread.rs @@ -199,6 +199,7 @@ mod imp { SwitchToThread(); } + #[allow(non_snake_case_functions)] extern "system" { fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, diff --git a/src/libstd/rt/thread_local_storage.rs b/src/libstd/rt/thread_local_storage.rs index 2551c89972e..a3ebcbafff8 100644 --- a/src/libstd/rt/thread_local_storage.rs +++ b/src/libstd/rt/thread_local_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -86,6 +86,7 @@ pub unsafe fn destroy(key: Key) { } #[cfg(windows)] +#[allow(non_snake_case_functions)] extern "system" { fn TlsAlloc() -> DWORD; fn TlsFree(dwTlsIndex: DWORD) -> BOOL; diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs index e5c0cc3babd..55bea068641 100644 --- a/src/libstd/slice.rs +++ b/src/libstd/slice.rs @@ -1303,7 +1303,8 @@ mod tests { use realstd::clone::Clone; for len in range(4u, 25) { for _ in range(0, 100) { - let mut v = task_rng().gen_vec::<uint>(len); + let mut v = task_rng().gen_iter::<uint>().take(len) + .collect::<Vec<uint>>(); let mut v1 = v.clone(); v.as_mut_slice().sort(); @@ -2321,7 +2322,7 @@ mod bench { fn sort_random_small(b: &mut Bencher) { let mut rng = weak_rng(); b.iter(|| { - let mut v = rng.gen_vec::<u64>(5); + let mut v = rng.gen_iter::<u64>().take(5).collect::<Vec<u64>>(); v.as_mut_slice().sort(); }); b.bytes = 5 * mem::size_of::<u64>() as u64; @@ -2331,7 +2332,7 @@ mod bench { fn sort_random_medium(b: &mut Bencher) { let mut rng = weak_rng(); b.iter(|| { - let mut v = rng.gen_vec::<u64>(100); + let mut v = rng.gen_iter::<u64>().take(100).collect::<Vec<u64>>(); v.as_mut_slice().sort(); }); b.bytes = 100 * mem::size_of::<u64>() as u64; @@ -2341,7 +2342,7 @@ mod bench { fn sort_random_large(b: &mut Bencher) { let mut rng = weak_rng(); b.iter(|| { - let mut v = rng.gen_vec::<u64>(10000); + let mut v = rng.gen_iter::<u64>().take(10000).collect::<Vec<u64>>(); v.as_mut_slice().sort(); }); b.bytes = 10000 * mem::size_of::<u64>() as u64; @@ -2362,7 +2363,8 @@ mod bench { fn sort_big_random_small(b: &mut Bencher) { let mut rng = weak_rng(); b.iter(|| { - let mut v = rng.gen_vec::<BigSortable>(5); + let mut v = rng.gen_iter::<BigSortable>().take(5) + .collect::<Vec<BigSortable>>(); v.sort(); }); b.bytes = 5 * mem::size_of::<BigSortable>() as u64; @@ -2372,7 +2374,8 @@ mod bench { fn sort_big_random_medium(b: &mut Bencher) { let mut rng = weak_rng(); b.iter(|| { - let mut v = rng.gen_vec::<BigSortable>(100); + let mut v = rng.gen_iter::<BigSortable>().take(100) + .collect::<Vec<BigSortable>>(); v.sort(); }); b.bytes = 100 * mem::size_of::<BigSortable>() as u64; @@ -2382,7 +2385,8 @@ mod bench { fn sort_big_random_large(b: &mut Bencher) { let mut rng = weak_rng(); b.iter(|| { - let mut v = rng.gen_vec::<BigSortable>(10000); + let mut v = rng.gen_iter::<BigSortable>().take(10000) + .collect::<Vec<BigSortable>>(); v.sort(); }); b.bytes = 10000 * mem::size_of::<BigSortable>() as u64; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 274a1b06863..6538809c8f1 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -79,7 +79,7 @@ use mem; use option::{None, Option, Some}; use result::Result; use slice::Vector; -use slice::{ImmutableVector, MutableVector, CloneableVector}; +use slice::{ImmutableVector, MutableVector}; use string::String; use vec::Vec; @@ -503,7 +503,7 @@ pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> { res.push_bytes(v.slice(subseqidx, total)) }; } - Owned(res.into_owned()) + Owned(res.into_string()) } /* @@ -608,7 +608,7 @@ impl<'a> Str for MaybeOwned<'a> { impl<'a> StrAllocating for MaybeOwned<'a> { #[inline] - fn into_owned(self) -> String { + fn into_string(self) -> String { match self { Slice(s) => s.to_string(), Owned(s) => s @@ -723,7 +723,7 @@ Section: Trait implementations /// Any string that can be represented as a slice pub trait StrAllocating: Str { /// Convert `self` into a `String`, not making a copy if possible. - fn into_owned(self) -> String; + fn into_string(self) -> String; /// Convert `self` into a `String`. #[inline] @@ -731,10 +731,10 @@ pub trait StrAllocating: Str { String::from_str(self.as_slice()) } - /// Convert `self` into a `String`, not making a copy if possible. - #[inline] - fn into_string(self) -> String { - self.into_owned() + #[allow(missing_doc)] + #[deprecated = "replaced by .into_string()"] + fn into_owned(self) -> String { + self.into_string() } /// Escape each char in `s` with `char::escape_default`. @@ -889,7 +889,7 @@ pub trait StrAllocating: Str { impl<'a> StrAllocating for &'a str { #[inline] - fn into_owned(self) -> String { + fn into_string(self) -> String { self.to_string() } } @@ -1045,7 +1045,7 @@ mod tests { #[test] fn test_concat() { fn t(v: &[String], s: &str) { - assert_eq!(v.concat(), s.to_str().into_owned()); + assert_eq!(v.concat(), s.to_str().into_string()); } t(["you".to_string(), "know".to_string(), "I'm".to_string(), "no".to_string(), "good".to_string()], "youknowI'mnogood"); @@ -1057,7 +1057,7 @@ mod tests { #[test] fn test_connect() { fn t(v: &[String], sep: &str, s: &str) { - assert_eq!(v.connect(sep), s.to_str().into_owned()); + assert_eq!(v.connect(sep), s.to_str().into_string()); } t(["you".to_string(), "know".to_string(), "I'm".to_string(), "no".to_string(), "good".to_string()], @@ -1070,7 +1070,7 @@ mod tests { #[test] fn test_concat_slices() { fn t(v: &[&str], s: &str) { - assert_eq!(v.concat(), s.to_str().into_owned()); + assert_eq!(v.concat(), s.to_str().into_string()); } t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood"); let v: &[&str] = []; @@ -1081,7 +1081,7 @@ mod tests { #[test] fn test_connect_slices() { fn t(v: &[&str], sep: &str, s: &str) { - assert_eq!(v.connect(sep), s.to_str().into_owned()); + assert_eq!(v.connect(sep), s.to_str().into_string()); } t(["you", "know", "I'm", "no", "good"], " ", "you know I'm no good"); @@ -2162,9 +2162,9 @@ mod tests { } #[test] - fn test_maybe_owned_into_owned() { - assert_eq!(Slice("abcde").into_owned(), "abcde".to_string()); - assert_eq!(Owned("abcde".to_string()).into_owned(), "abcde".to_string()); + fn test_maybe_owned_into_string() { + assert_eq!(Slice("abcde").into_string(), "abcde".to_string()); + assert_eq!(Owned("abcde".to_string()).into_string(), "abcde".to_string()); } #[test] diff --git a/src/libstd/string.rs b/src/libstd/string.rs index dce96cb2e8f..0edbaf99210 100644 --- a/src/libstd/string.rs +++ b/src/libstd/string.rs @@ -323,11 +323,6 @@ impl Str for String { impl StrAllocating for String { #[inline] - fn into_owned(self) -> String { - self - } - - #[inline] fn into_string(self) -> String { self } diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index 81eb51107ba..6c406a7c847 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -317,6 +317,7 @@ pub mod dl { FreeLibrary(handle as *libc::c_void); () } + #[allow(non_snake_case_functions)] extern "system" { fn SetLastError(error: libc::size_t); fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void; diff --git a/src/libstd/unstable/mutex.rs b/src/libstd/unstable/mutex.rs index 04da7dab6c6..4e51e714777 100644 --- a/src/libstd/unstable/mutex.rs +++ b/src/libstd/unstable/mutex.rs @@ -543,6 +543,7 @@ mod imp { libc::CloseHandle(block); } + #[allow(non_snake_case_functions)] extern "system" { fn CreateEventA(lpSecurityAttributes: LPSECURITY_ATTRIBUTES, bManualReset: BOOL, diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index bc53d2bec8d..089cd772bb4 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -159,6 +159,7 @@ impl fmt::Show for Abi { } } +#[allow(non_snake_case_functions)] #[test] fn lookup_Rust() { let abi = lookup("Rust"); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d6af10ddc18..656ae80e12d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -26,6 +26,7 @@ use serialize::{Encodable, Decodable, Encoder, Decoder}; /// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future. pub type P<T> = @T; +#[allow(non_snake_case_functions)] /// Construct a P<T> from a T value. pub fn P<T: 'static>(value: T) -> P<T> { @value diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 397b99925c8..5314b39f805 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -23,7 +23,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt, let trait_def = TraitDef { span: span, attributes: Vec::new(), - path: Path::new(vec!("rand", "Rand")), + path: Path::new(vec!("std", "rand", "Rand")), additional_bounds: Vec::new(), generics: LifetimeBounds::empty(), methods: vec!( @@ -33,7 +33,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt, lifetimes: Vec::new(), bounds: vec!(("R", ast::StaticSize, - vec!( Path::new(vec!("rand", "Rng")) ))) + vec!( Path::new(vec!("std", "rand", "Rng")) ))) }, explicit_self: None, args: vec!( @@ -58,6 +58,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") }; let rand_ident = vec!( + cx.ident_of("std"), cx.ident_of("rand"), cx.ident_of("Rand"), cx.ident_of("rand") diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 6ac3becf0b6..fdaa3b5630a 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -223,7 +223,7 @@ fn marksof_internal(ctxt: SyntaxContext, return result; }, Mark(mark, tl) => { - xorPush(&mut result, mark); + xor_push(&mut result, mark); loopvar = tl; }, Rename(_,name,tl) => { @@ -253,7 +253,7 @@ pub fn outer_mark(ctxt: SyntaxContext) -> Mrk { // Push a name... unless it matches the one on top, in which // case pop and discard (so two of the same marks cancel) -fn xorPush(marks: &mut Vec<Mrk>, mark: Mrk) { +fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) { if (marks.len() > 0) && (*marks.last().unwrap() == mark) { marks.pop().unwrap(); } else { @@ -264,26 +264,27 @@ fn xorPush(marks: &mut Vec<Mrk>, mark: Mrk) { #[cfg(test)] mod tests { use ast::*; - use super::{resolve, xorPush, new_mark_internal, new_sctable_internal}; + use super::{resolve, xor_push, new_mark_internal, new_sctable_internal}; use super::{new_rename_internal, marksof_internal, resolve_internal}; use super::{SCTable, EmptyCtxt, Mark, Rename, IllegalCtxt}; use collections::HashMap; - #[test] fn xorpush_test () { + #[test] + fn xorpush_test () { let mut s = Vec::new(); - xorPush(&mut s, 14); + xor_push(&mut s, 14); assert_eq!(s.clone(), vec!(14)); - xorPush(&mut s, 14); + xor_push(&mut s, 14); assert_eq!(s.clone(), Vec::new()); - xorPush(&mut s, 14); + xor_push(&mut s, 14); assert_eq!(s.clone(), vec!(14)); - xorPush(&mut s, 15); + xor_push(&mut s, 15); assert_eq!(s.clone(), vec!(14, 15)); - xorPush(&mut s, 16); + xor_push(&mut s, 16); assert_eq!(s.clone(), vec!(14, 15, 16)); - xorPush(&mut s, 16); + xor_push(&mut s, 16); assert_eq!(s.clone(), vec!(14, 15)); - xorPush(&mut s, 15); + xor_push(&mut s, 15); assert_eq!(s.clone(), vec!(14)); } @@ -331,7 +332,8 @@ mod tests { } } - #[test] fn test_unfold_refold(){ + #[test] + fn test_unfold_refold(){ let mut t = new_sctable_internal(); let test_sc = vec!(M(3),R(id(101,0),14),M(9)); @@ -364,7 +366,8 @@ mod tests { } } - #[test] fn test_marksof () { + #[test] + fn test_marksof () { let stopname = 242; let name1 = 243; let mut t = new_sctable_internal(); @@ -397,7 +400,8 @@ mod tests { } - #[test] fn resolve_tests () { + #[test] + fn resolve_tests () { let a = 40; let mut t = new_sctable_internal(); let mut rt = HashMap::new(); @@ -447,13 +451,15 @@ mod tests { assert_eq!(resolve_internal(id(a,a50_to_a51_b),&mut t, &mut rt),50);} } - #[test] fn mtwt_resolve_test(){ + #[test] + fn mtwt_resolve_test(){ let a = 40; assert_eq!(resolve(id(a,EMPTY_CTXT)),a); } - #[test] fn hashing_tests () { + #[test] + fn hashing_tests () { let mut t = new_sctable_internal(); assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2); assert_eq!(new_mark_internal(13,EMPTY_CTXT,&mut t),3); @@ -462,7 +468,8 @@ mod tests { // I'm assuming that the rename table will behave the same.... } - #[test] fn resolve_table_hashing_tests() { + #[test] + fn resolve_table_hashing_tests() { let mut t = new_sctable_internal(); let mut rt = HashMap::new(); assert_eq!(rt.len(),0); diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index a92802aa338..65733793d6c 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -402,7 +402,7 @@ pub fn parse(sess: &ParseSess, } rdr.next_token(); } else /* bb_eis.len() == 1 */ { - let mut rust_parser = Parser(sess, cfg.clone(), box rdr.clone()); + let mut rust_parser = Parser::new(sess, cfg.clone(), box rdr.clone()); let mut ei = bb_eis.pop().unwrap(); match ei.elts.get(ei.idx).node { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index c69e5f9ba0f..0622bf76ab9 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -171,7 +171,7 @@ fn generic_extension(cx: &ExtCtxt, let trncbr = new_tt_reader(&cx.parse_sess().span_diagnostic, Some(named_matches), rhs); - let p = Parser(cx.parse_sess(), cx.cfg(), box trncbr); + let p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr); // Let the context choose how to interpret the result. // Weird, but useful for X-macros. return box ParserAnyMacro { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ce89a7dec39..3132f91c09b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -256,7 +256,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>) // parsing tt's probably shouldn't require a parser at all. let cfg = Vec::new(); let srdr = lexer::new_string_reader(&sess.span_diagnostic, filemap); - let mut p1 = Parser(sess, cfg, box srdr); + let mut p1 = Parser::new(sess, cfg, box srdr); p1.parse_all_token_trees() } @@ -265,7 +265,7 @@ pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec<ast::TokenTree>, cfg: ast::CrateConfig) -> Parser<'a> { let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts); - Parser(sess, cfg, box trdr) + Parser::new(sess, cfg, box trdr) } // abort if necessary diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 6a0a3c9ff81..f045a7fe120 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -19,7 +19,7 @@ removed. use ast::{Expr, ExprLit, LitNil}; use codemap::{Span, respan}; -use parse::parser::Parser; +use parse::parser; use parse::token; /// The specific types of unsupported syntax @@ -45,7 +45,7 @@ pub trait ParserObsoleteMethods { fn eat_obsolete_ident(&mut self, ident: &str) -> bool; } -impl<'a> ParserObsoleteMethods for Parser<'a> { +impl<'a> ParserObsoleteMethods for parser::Parser<'a> { /// Reports an obsolete syntax non-fatal error. fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) { let (kind_str, desc) = match kind { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1902df30b99..00c07ce59f9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -278,50 +278,11 @@ struct ParsedItemsAndViewItems { attrs_remaining: Vec<Attribute> , view_items: Vec<ViewItem> , items: Vec<@Item> , - foreign_items: Vec<@ForeignItem> } + foreign_items: Vec<@ForeignItem> +} /* ident is handled by common.rs */ -pub fn Parser<'a>( - sess: &'a ParseSess, - cfg: ast::CrateConfig, - mut rdr: Box<Reader:>) - -> Parser<'a> { - let tok0 = rdr.next_token(); - let span = tok0.sp; - let placeholder = TokenAndSpan { - tok: token::UNDERSCORE, - sp: span, - }; - - Parser { - reader: rdr, - interner: token::get_ident_interner(), - sess: sess, - cfg: cfg, - token: tok0.tok, - span: span, - last_span: span, - last_token: None, - buffer: [ - placeholder.clone(), - placeholder.clone(), - placeholder.clone(), - placeholder.clone(), - ], - buffer_start: 0, - buffer_end: 0, - tokens_consumed: 0, - restriction: UNRESTRICTED, - quote_depth: 0, - obsolete_set: HashSet::new(), - mod_path_stack: Vec::new(), - open_braces: Vec::new(), - owns_directory: true, - root_module_name: None, - } -} - pub struct Parser<'a> { pub sess: &'a ParseSess, // the current token: @@ -362,6 +323,41 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool { } impl<'a> Parser<'a> { + pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig, mut rdr: Box<Reader:>) -> Parser<'a> { + let tok0 = rdr.next_token(); + let span = tok0.sp; + let placeholder = TokenAndSpan { + tok: token::UNDERSCORE, + sp: span, + }; + + Parser { + reader: rdr, + interner: token::get_ident_interner(), + sess: sess, + cfg: cfg, + token: tok0.tok, + span: span, + last_span: span, + last_token: None, + buffer: [ + placeholder.clone(), + placeholder.clone(), + placeholder.clone(), + placeholder.clone(), + ], + buffer_start: 0, + buffer_end: 0, + tokens_consumed: 0, + restriction: UNRESTRICTED, + quote_depth: 0, + obsolete_set: HashSet::new(), + mod_path_stack: Vec::new(), + open_braces: Vec::new(), + owns_directory: true, + root_module_name: None, + } + } // convert a token to a string using self's reader pub fn token_to_str(token: &token::Token) -> String { token::to_str(token) @@ -4537,7 +4533,7 @@ impl<'a> Parser<'a> { Some(abi) => Some(abi), None => { self.span_err( - self.span, + self.last_span, format!("illegal ABI: expected one of [{}], \ found `{}`", abi::all_names().connect(", "), diff --git a/src/libterm/win.rs b/src/libterm/win.rs index 837ddf566ef..00e90fc3cde 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -27,6 +27,7 @@ pub struct WinConsole<T> { background: color::Color, } +#[allow(non_snake_case_functions)] #[link(name = "kernel32")] extern "system" { fn SetConsoleTextAttribute(handle: libc::HANDLE, attr: libc::WORD) -> libc::BOOL; diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index 99dd7d8503c..c157d83ced1 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -67,21 +67,19 @@ Examples of string representations: // test harness access #[cfg(test)] extern crate test; - -extern crate rand; extern crate serialize; -use std::mem::{transmute,transmute_copy}; use std::char::Char; use std::default::Default; use std::fmt; use std::from_str::FromStr; use std::hash::Hash; +use std::mem::{transmute,transmute_copy}; use std::num::FromStrRadix; -use std::str; +use std::rand; +use std::rand::Rng; use std::slice; - -use rand::Rng; +use std::str; use serialize::{Encoder, Encodable, Decoder, Decodable}; @@ -194,7 +192,7 @@ impl Uuid { /// of random numbers. Use the rand::Rand trait to supply /// a custom generator if required. pub fn new_v4() -> Uuid { - let ub = rand::task_rng().gen_vec(16); + let ub = rand::task_rng().gen_iter::<u8>().take(16).collect::<Vec<_>>(); let mut uuid = Uuid{ bytes: [0, .. 16] }; slice::bytes::copy_memory(uuid.bytes, ub.as_slice()); uuid.set_variant(VariantRFC4122); @@ -510,7 +508,7 @@ impl<T: Decoder<E>, E> Decodable<T, E> for Uuid { impl rand::Rand for Uuid { #[inline] fn rand<R: rand::Rng>(rng: &mut R) -> Uuid { - let ub = rng.gen_vec(16); + let ub = rng.gen_iter::<u8>().take(16).collect::<Vec<_>>(); let mut uuid = Uuid{ bytes: [0, .. 16] }; slice::bytes::copy_memory(uuid.bytes, ub.as_slice()); uuid.set_variant(VariantRFC4122); @@ -522,13 +520,13 @@ impl rand::Rand for Uuid { #[cfg(test)] mod test { extern crate collections; - extern crate rand; use super::{Uuid, VariantMicrosoft, VariantNCS, VariantRFC4122, Version1Mac, Version2Dce, Version3Md5, Version4Random, Version5Sha1}; use std::str; use std::io::MemWriter; + use std::rand; #[test] fn test_nil() { @@ -788,7 +786,7 @@ mod test { #[test] fn test_rand_rand() { let mut rng = rand::task_rng(); - let u: Box<Uuid> = rand::Rand::rand(&mut rng); + let u: Uuid = rand::Rand::rand(&mut rng); let ub = u.as_bytes(); assert!(ub.len() == 16); @@ -797,14 +795,16 @@ mod test { #[test] fn test_serialize_round_trip() { - use serialize::ebml; + use serialize::ebml::Doc; + use serialize::ebml::writer::Encoder; + use serialize::ebml::reader::Decoder; use serialize::{Encodable, Decodable}; let u = Uuid::new_v4(); let mut wr = MemWriter::new(); - let _ = u.encode(&mut ebml::writer::Encoder(&mut wr)); - let doc = ebml::reader::Doc(wr.get_ref()); - let u2 = Decodable::decode(&mut ebml::reader::Decoder(doc)).unwrap(); + let _ = u.encode(&mut Encoder::new(&mut wr)); + let doc = Doc::new(wr.get_ref()); + let u2 = Decodable::decode(&mut Decoder::new(doc)).unwrap(); assert_eq!(u, u2); } diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index d53a8968421..bf50736b7e6 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -12,11 +12,11 @@ #![feature(macro_rules)] -extern crate rand; extern crate time; use time::precise_time_s; -use rand::Rng; +use std::rand; +use std::rand::Rng; use std::mem::swap; use std::os; use std::str; diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 27540cc5bbf..816a7529212 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -11,10 +11,8 @@ // Multi-language Perlin noise benchmark. // See https://github.com/nsf/pnoise for timings and alternative implementations. -extern crate rand; - use std::f32::consts::PI; -use rand::{Rng, StdRng}; +use std::rand::{Rng, StdRng}; struct Vec2 { x: f32, diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index c6a678828c1..c038a056569 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(phase)] +#![allow(non_snake_case_functions)] #[phase(syntax)] extern crate green; extern crate sync; diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 9235882d1f4..c0ea6f8617d 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -11,6 +11,7 @@ // ignore-pretty very bad with line comments #![feature(managed_boxes)] +#![allow(non_snake_case_functions)] use std::io; use std::io::stdio::StdReader; diff --git a/src/test/compile-fail/borrowck-issue-14498.rs b/src/test/compile-fail/borrowck-issue-14498.rs new file mode 100644 index 00000000000..45dda5fee5a --- /dev/null +++ b/src/test/compile-fail/borrowck-issue-14498.rs @@ -0,0 +1,63 @@ +// 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. + +// This tests that we can't modify Box<&mut T> contents while they +// are borrowed. + +struct A { a: int } +struct B<'a> { a: Box<&'a mut int> } + +fn borrow_in_var_from_var() { + let mut x: int = 1; + let y = box &mut x; + let p = &y; + let q = &***p; + **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed + drop(p); + drop(q); +} + +fn borrow_in_var_from_field() { + let mut x = A { a: 1 }; + let y = box &mut x.a; + let p = &y; + let q = &***p; + **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed + drop(p); + drop(q); +} + +fn borrow_in_field_from_var() { + let mut x: int = 1; + let y = B { a: box &mut x }; + let p = &y.a; + let q = &***p; + **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed + drop(p); + drop(q); +} + +fn borrow_in_field_from_field() { + let mut x = A { a: 1 }; + let y = B { a: box &mut x.a }; + let p = &y.a; + let q = &***p; + **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed + drop(p); + drop(q); +} + +fn main() { + borrow_in_var_from_var(); + borrow_in_var_from_field(); + borrow_in_field_from_var(); + borrow_in_field_from_field(); +} + diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/compile-fail/issue-8537.rs new file mode 100644 index 00000000000..dba9e751f71 --- /dev/null +++ b/src/test/compile-fail/issue-8537.rs @@ -0,0 +1,15 @@ +// 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. + +pub extern + "invalid-abi" //~ ERROR illegal ABI +fn foo() {} + +fn main() {} diff --git a/src/test/compile-fail/lint-non-snake-case-functions.rs b/src/test/compile-fail/lint-non-snake-case-functions.rs new file mode 100644 index 00000000000..02ab85aff3b --- /dev/null +++ b/src/test/compile-fail/lint-non-snake-case-functions.rs @@ -0,0 +1,51 @@ +// 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. + +#![deny(non_snake_case_functions)] +#![allow(dead_code)] + +struct Foo; + +impl Foo { + fn Foo_Method() {} + //~^ ERROR method `Foo_Method` should have a snake case identifier + + // Don't allow two underscores in a row + fn foo__method(&self) {} + //~^ ERROR method `foo__method` should have a snake case identifier + + pub fn xyZ(&mut self) {} + //~^ ERROR method `xyZ` should have a snake case identifier +} + +trait X { + fn ABC(); + //~^ ERROR trait method `ABC` should have a snake case identifier + + fn a_b_C(&self) {} + //~^ ERROR trait method `a_b_C` should have a snake case identifier + + fn something__else(&mut self); + //~^ ERROR trait method `something__else` should have a snake case identifier +} + +impl X for Foo { + // These errors should be caught at the trait definition not the impl + fn ABC() {} + fn something__else(&mut self) {} +} + +fn Cookie() {} +//~^ ERROR function `Cookie` should have a snake case identifier + +pub fn bi_S_Cuit() {} +//~^ ERROR function `bi_S_Cuit` should have a snake case identifier + +fn main() { } diff --git a/src/test/compile-fail/task-rng-isnt-sendable.rs b/src/test/compile-fail/task-rng-isnt-sendable.rs index 8b9d4de9f04..366e1fd4dca 100644 --- a/src/test/compile-fail/task-rng-isnt-sendable.rs +++ b/src/test/compile-fail/task-rng-isnt-sendable.rs @@ -10,11 +10,11 @@ // ensure that the TaskRng isn't/doesn't become accidentally sendable. -extern crate rand; +use std::rand; fn test_send<S: Send>() {} pub fn main() { - test_send::<::rand::TaskRng>(); - //~^ ERROR: incompatible type `rand::TaskRng`, which does not fulfill `Send` + test_send::<rand::TaskRng>(); + //~^ ERROR: incompatible type `std::rand::TaskRng`, which does not fulfill `Send` } diff --git a/src/test/debuginfo/borrowed-enum.rs b/src/test/debuginfo/borrowed-enum.rs index 7126aec2391..a377d68a33d 100644 --- a/src/test/debuginfo/borrowed-enum.rs +++ b/src/test/debuginfo/borrowed-enum.rs @@ -22,7 +22,7 @@ // gdb-check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}} // gdb-command:print *univariant_ref -// gdb-check:$3 = {4820353753753434} +// gdb-check:$3 = {{4820353753753434}} #![allow(unused_variable)] #![feature(struct_variant)] diff --git a/src/test/debuginfo/generic-struct-style-enum.rs b/src/test/debuginfo/generic-struct-style-enum.rs index 498d0981e35..eddf4dfd755 100644 --- a/src/test/debuginfo/generic-struct-style-enum.rs +++ b/src/test/debuginfo/generic-struct-style-enum.rs @@ -27,7 +27,7 @@ // gdb-check:$3 = {{Case3, a = 0, b = 22873, c = 22873, d = 22873, e = 22873}, {Case3, a = 0, b = 1499027801, c = 1499027801}, {Case3, a = 0, b = 6438275382588823897}} // gdb-command:print univariant -// gdb-check:$4 = {a = -1} +// gdb-check:$4 = {{a = -1}} #![feature(struct_variant)] diff --git a/src/test/debuginfo/generic-tuple-style-enum.rs b/src/test/debuginfo/generic-tuple-style-enum.rs index 16a665ca8c6..07f7546068c 100644 --- a/src/test/debuginfo/generic-tuple-style-enum.rs +++ b/src/test/debuginfo/generic-tuple-style-enum.rs @@ -27,7 +27,7 @@ // gdb-check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}} // gdb-command:print univariant -// gdb-check:$4 = {-1} +// gdb-check:$4 = {{-1}} // NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be diff --git a/src/test/debuginfo/managed-enum.rs b/src/test/debuginfo/managed-enum.rs index 7899e0c6a9b..36e75812deb 100644 --- a/src/test/debuginfo/managed-enum.rs +++ b/src/test/debuginfo/managed-enum.rs @@ -22,7 +22,7 @@ // gdb-check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}} // gdb-command:print univariant->val -// gdb-check:$3 = {-9747455} +// gdb-check:$3 = {{-9747455}} #![allow(unused_variable)] #![feature(struct_variant, managed_boxes)] diff --git a/src/test/debuginfo/option-like-enum.rs b/src/test/debuginfo/option-like-enum.rs index 803d0aed593..04cd7e13863 100644 --- a/src/test/debuginfo/option-like-enum.rs +++ b/src/test/debuginfo/option-like-enum.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-tidy-linelength // ignore-android: FIXME(#10381) // compile-flags:-g @@ -16,19 +17,19 @@ // gdb-command:finish // gdb-command:print some -// gdb-check:$1 = (u32 *) 0x12345678 +// gdb-check:$1 = {RUST$ENCODED$ENUM$0$None = {0x12345678}} // gdb-command:print none -// gdb-check:$2 = (u32 *) 0x0 +// gdb-check:$2 = {RUST$ENCODED$ENUM$0$None = {0x0}} // gdb-command:print full -// gdb-check:$3 = {454545, 0x87654321, 9988} +// gdb-check:$3 = {RUST$ENCODED$ENUM$1$Empty = {454545, 0x87654321, 9988}} // gdb-command:print empty->discr // gdb-check:$4 = (int *) 0x0 // gdb-command:print droid -// gdb-check:$5 = {id = 675675, range = 10000001, internals = 0x43218765} +// gdb-check:$5 = {RUST$ENCODED$ENUM$2$Void = {id = 675675, range = 10000001, internals = 0x43218765}} // gdb-command:print void_droid->internals // gdb-check:$6 = (int *) 0x0 diff --git a/src/test/debuginfo/recursive-struct.rs b/src/test/debuginfo/recursive-struct.rs index aa13072eb53..518ef62fe9a 100644 --- a/src/test/debuginfo/recursive-struct.rs +++ b/src/test/debuginfo/recursive-struct.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-tidy-linelength // ignore-android: FIXME(#10381) #![feature(managed_boxes)] @@ -20,53 +21,53 @@ // gdb-command:print stack_unique.value // gdb-check:$1 = 0 -// gdb-command:print stack_unique.next->value +// gdb-command:print stack_unique.next.RUST$ENCODED$ENUM$0$Empty.val->value // gdb-check:$2 = 1 // gdb-command:print unique_unique->value // gdb-check:$3 = 2 -// gdb-command:print unique_unique->next->value +// gdb-command:print unique_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value // gdb-check:$4 = 3 // gdb-command:print box_unique->val.value // gdb-check:$5 = 4 -// gdb-command:print box_unique->val.next->value +// gdb-command:print box_unique->val.next.RUST$ENCODED$ENUM$0$Empty.val->value // gdb-check:$6 = 5 // gdb-command:print vec_unique[0].value // gdb-check:$7 = 6.5 -// gdb-command:print vec_unique[0].next->value +// gdb-command:print vec_unique[0].next.RUST$ENCODED$ENUM$0$Empty.val->value // gdb-check:$8 = 7.5 // gdb-command:print borrowed_unique->value // gdb-check:$9 = 8.5 -// gdb-command:print borrowed_unique->next->value +// gdb-command:print borrowed_unique->next.RUST$ENCODED$ENUM$0$Empty.val->value // gdb-check:$10 = 9.5 // MANAGED // gdb-command:print stack_managed.value // gdb-check:$11 = 10 -// gdb-command:print stack_managed.next.val->value +// gdb-command:print stack_managed.next.RUST$ENCODED$ENUM$0$Empty.val->val.value // gdb-check:$12 = 11 // gdb-command:print unique_managed->value // gdb-check:$13 = 12 -// gdb-command:print unique_managed->next.val->value +// gdb-command:print unique_managed->next.RUST$ENCODED$ENUM$0$Empty.val->val.value // gdb-check:$14 = 13 // gdb-command:print box_managed.val->value // gdb-check:$15 = 14 -// gdb-command:print box_managed->val->next.val->value +// gdb-command:print box_managed->val->next.RUST$ENCODED$ENUM$0$Empty.val->val.value // gdb-check:$16 = 15 // gdb-command:print vec_managed[0].value // gdb-check:$17 = 16.5 -// gdb-command:print vec_managed[0].next.val->value +// gdb-command:print vec_managed[0].next.RUST$ENCODED$ENUM$0$Empty.val->val.value // gdb-check:$18 = 17.5 // gdb-command:print borrowed_managed->value // gdb-check:$19 = 18.5 -// gdb-command:print borrowed_managed->next.val->value +// gdb-command:print borrowed_managed->next.RUST$ENCODED$ENUM$0$Empty.val->val.value // gdb-check:$20 = 19.5 // LONG CYCLE @@ -97,7 +98,7 @@ // gdb-command:print (*****long_cycle_w_anonymous_types).value // gdb-check:$31 = 30 -// gdb-command:print (*****((*****long_cycle_w_anonymous_types).next)).value +// gdb-command:print (*****((*****long_cycle_w_anonymous_types).next.RUST$ENCODED$ENUM$0$Empty.val)).value // gdb-check:$32 = 31 // gdb-command:continue diff --git a/src/test/debuginfo/struct-in-enum.rs b/src/test/debuginfo/struct-in-enum.rs index ee971d71cfc..0cba56ad320 100644 --- a/src/test/debuginfo/struct-in-enum.rs +++ b/src/test/debuginfo/struct-in-enum.rs @@ -24,7 +24,7 @@ // gdb-check:$2 = {{Case2, 0, {x = 286331153, y = 286331153, z = 4369}}, {Case2, 0, 1229782938247303441, 4369}} // gdb-command:print univariant -// gdb-check:$3 = {{x = 123, y = 456, z = 789}} +// gdb-check:$3 = {{{x = 123, y = 456, z = 789}}} #![allow(unused_variable)] diff --git a/src/test/debuginfo/struct-style-enum.rs b/src/test/debuginfo/struct-style-enum.rs index 1a51db1a005..70d4d709d23 100644 --- a/src/test/debuginfo/struct-style-enum.rs +++ b/src/test/debuginfo/struct-style-enum.rs @@ -27,7 +27,7 @@ // gdb-check:$3 = {{Case3, a = 0, b = 22873, c = 22873, d = 22873, e = 22873}, {Case3, a = 0, b = 1499027801, c = 1499027801}, {Case3, a = 0, b = 6438275382588823897}} // gdb-command:print univariant -// gdb-check:$4 = {a = -1} +// gdb-check:$4 = {{a = -1}} #![allow(unused_variable)] #![feature(struct_variant)] diff --git a/src/test/debuginfo/tuple-style-enum.rs b/src/test/debuginfo/tuple-style-enum.rs index dc922b45005..81c72d16886 100644 --- a/src/test/debuginfo/tuple-style-enum.rs +++ b/src/test/debuginfo/tuple-style-enum.rs @@ -27,7 +27,7 @@ // gdb-check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}} // gdb-command:print univariant -// gdb-check:$4 = {-1} +// gdb-check:$4 = {{-1}} #![allow(unused_variable)] diff --git a/src/test/debuginfo/unique-enum.rs b/src/test/debuginfo/unique-enum.rs index f85ec6a8da3..3949a315adc 100644 --- a/src/test/debuginfo/unique-enum.rs +++ b/src/test/debuginfo/unique-enum.rs @@ -22,7 +22,7 @@ // gdb-check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}} // gdb-command:print *univariant -// gdb-check:$3 = {123234} +// gdb-check:$3 = {{123234}} #![allow(unused_variable)] #![feature(struct_variant)] diff --git a/src/test/run-make/unicode-input/multiple_files.rs b/src/test/run-make/unicode-input/multiple_files.rs index e41c5d1b626..3711503ee2b 100644 --- a/src/test/run-make/unicode-input/multiple_files.rs +++ b/src/test/run-make/unicode-input/multiple_files.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate rand; -use rand::{task_rng, Rng}; - use std::{char, os, str}; use std::io::{File, Command}; +use std::rand::{task_rng, Rng}; // creates unicode_input_multiple_files_{main,chars}.rs, where the // former imports the latter. `_chars` just contains an indentifier diff --git a/src/test/run-make/unicode-input/span_length.rs b/src/test/run-make/unicode-input/span_length.rs index b875f676982..ebb03435fe4 100644 --- a/src/test/run-make/unicode-input/span_length.rs +++ b/src/test/run-make/unicode-input/span_length.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate rand; -use rand::{task_rng, Rng}; - use std::{char, os, str}; use std::io::{File, Command}; +use std::rand::{task_rng, Rng}; // creates a file with `fn main() { <random ident> }` and checks the // compiler emits a span of the appropriate length (for the diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index 304325906d7..217878892d6 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -33,12 +33,12 @@ fn test_ebml<'a, 'b, A: Decodable<EBReader::Decoder<'b>> >(a1: &A) { let mut wr = std::io::MemWriter::new(); - let mut ebml_w = EBWriter::Encoder(&mut wr); + let mut ebml_w = EBwriter::Encoder::new(&mut wr); a1.encode(&mut ebml_w); let bytes = wr.get_ref(); - let d: serialize::ebml::Doc<'a> = EBReader::Doc(bytes); - let mut decoder: EBReader::Decoder<'a> = EBReader::Decoder(d); + let d: serialize::ebml::Doc<'a> = EBDoc::new(bytes); + let mut decoder: EBReader::Decoder<'a> = EBreader::Decoder::new(d); let a2: A = Decodable::decode(&mut decoder); assert!(*a1 == a2); } diff --git a/src/test/run-pass/deriving-encodable-decodable.rs b/src/test/run-pass/deriving-encodable-decodable.rs index 2e47940a26c..2e6b3b8e800 100644 --- a/src/test/run-pass/deriving-encodable-decodable.rs +++ b/src/test/run-pass/deriving-encodable-decodable.rs @@ -22,6 +22,7 @@ use std::io::MemWriter; use rand::{random, Rand}; use serialize::{Encodable, Decodable}; use serialize::ebml; +use serialize::ebml::Doc; use serialize::ebml::writer::Encoder; use serialize::ebml::reader::Decoder; @@ -58,10 +59,10 @@ fn roundtrip<'a, T: Rand + Eq + Encodable<Encoder<'a>> + Decodable<Decoder<'a>>>() { let obj: T = random(); let mut w = MemWriter::new(); - let mut e = Encoder(&mut w); + let mut e = Encoder::new(&mut w); obj.encode(&mut e); - let doc = ebml::reader::Doc(@w.get_ref()); - let mut dec = Decoder(doc); + let doc = ebml::Doc::new(@w.get_ref()); + let mut dec = Decoder::new(doc); let obj2 = Decodable::decode(&mut dec); assert!(obj == obj2); } diff --git a/src/test/run-pass/deriving-rand.rs b/src/test/run-pass/deriving-rand.rs index c455aebbe46..4e9592950d3 100644 --- a/src/test/run-pass/deriving-rand.rs +++ b/src/test/run-pass/deriving-rand.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - #![feature(struct_variant)] -extern crate rand; +use std::rand; #[deriving(Rand)] struct A; diff --git a/src/test/run-pass/issue-11881.rs b/src/test/run-pass/issue-11881.rs index 7e51c6ad2ae..913e09dd8cb 100644 --- a/src/test/run-pass/issue-11881.rs +++ b/src/test/run-pass/issue-11881.rs @@ -43,7 +43,7 @@ fn encode_ebml<'a, T: Encodable<writer::Encoder<'a, MemWriter>, std::io::IoError>>(val: &T, wr: &'a mut MemWriter) { - let mut encoder = writer::Encoder(wr); + let mut encoder = writer::Encoder::new(wr); val.encode(&mut encoder); } diff --git a/src/test/run-pass/vector-sort-failure-safe.rs b/src/test/run-pass/vector-sort-failure-safe.rs index 00bc95b36f7..e5f1c48464d 100644 --- a/src/test/run-pass/vector-sort-failure-safe.rs +++ b/src/test/run-pass/vector-sort-failure-safe.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate rand; - use std::task; -use rand::{task_rng, Rng}; +use std::rand::{task_rng, Rng}; static MAX_LEN: uint = 20; static mut drop_counts: [uint, .. MAX_LEN] = [0, .. MAX_LEN]; @@ -46,7 +44,9 @@ pub fn main() { // len can't go above 64. for len in range(2u, MAX_LEN) { for _ in range(0, 10) { - let main = task_rng().gen_vec::<DropCounter>(len); + let main = task_rng().gen_iter::<DropCounter>() + .take(len) + .collect::<Vec<DropCounter>>(); // work out the total number of comparisons required to sort // this array... |
