diff --git a/README.md b/README.md index 065c4ed7c7bcb..b6a73730d351c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ # The Rust Programming Language This is a compiler for Rust, including standard libraries, tools and -documentation. +documentation. Rust is a systems programming language that is fast, +memory safe and multithreaded, but does not employ a garbage collector +or otherwise impose significant runtime overhead. ## Quick Start -Read ["Installing Rust"][install] from [The Book][trpl]. +Read ["Installing Rust"] from [The Book]. -[install]: http://doc.rust-lang.org/book/installing-rust.html -[trpl]: http://doc.rust-lang.org/book/index.html +["Installing Rust"]: http://doc.rust-lang.org/book/installing-rust.html +[The Book]: http://doc.rust-lang.org/book/index.html ## Building from Source @@ -19,22 +21,14 @@ Read ["Installing Rust"][install] from [The Book][trpl]. * `curl` * `git` -2. Download and build Rust: - - You can either download a [tarball] or build directly from the [repo]. - - To build from the [tarball] do: - - $ curl -O https://static.rust-lang.org/dist/rustc-nightly-src.tar.gz - $ tar -xzf rustc-nightly-src.tar.gz - $ cd rustc-nightly - - Or to build from the [repo] do: +2. Clone the [source] with `git`: $ git clone https://github.com/rust-lang/rust.git $ cd rust - Now that you have Rust's source code, you can configure and build it: +[source]: https://github.com/rust-lang/rust + +3. Build and install: $ ./configure $ make && make install @@ -46,7 +40,10 @@ Read ["Installing Rust"][install] from [The Book][trpl]. When complete, `make install` will place several programs into `/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the - API-documentation tool. + API-documentation tool. This install does not include [Cargo], + Rust's package manager, which you may also want to build. + +[Cargo]: https://github.com/rust-lang/cargo ### Building on Windows @@ -72,9 +69,6 @@ $ pacman -S base-devel $ ./configure $ make && make install -[repo]: https://github.com/rust-lang/rust -[tarball]: https://static.rust-lang.org/dist/rustc-nightly-src.tar.gz - ## Notes Since the Rust compiler is written in Rust, it must be built by a @@ -94,9 +88,9 @@ supported build environments that are most likely to work. Rust currently needs about 1.5 GiB of RAM to build without swapping; if it hits swap, it will take a very long time to build. -There is a lot more documentation in the [wiki]. +There is more advice about hacking on Rust in [CONTRIBUTING.md]. -[wiki]: https://github.com/rust-lang/rust/wiki +[CONTRIBUTING.md]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md ## Getting help @@ -114,6 +108,14 @@ The Rust community congregates in a few places: To contribute to Rust, please see [CONTRIBUTING.md](CONTRIBUTING.md). +Rust has an [IRC] culture and most real-time collaboration happens in a +variety of channels on Mozilla's IRC network, irc.mozilla.org. The +most popular channel is [#rust], a venue for general discussion about +Rust, and a good place to ask for help, + +[IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat +[#rust]: irc://irc.mozilla.org/rust + ## License Rust is primarily distributed under the terms of both the MIT license diff --git a/configure b/configure index ec1e741fb9c5b..d1b27a96f93b9 100755 --- a/configure +++ b/configure @@ -1056,6 +1056,7 @@ do make_dir $h/test/run-pass-fulldeps make_dir $h/test/run-fail make_dir $h/test/compile-fail + make_dir $h/test/parse-fail make_dir $h/test/compile-fail-fulldeps make_dir $h/test/bench make_dir $h/test/perf diff --git a/mk/tests.mk b/mk/tests.mk index d859772437074..692d28bfad3d5 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -174,12 +174,12 @@ check-notidy: cleantmptestlogs cleantestlibs all check-stage2 check-lite: cleantestlibs cleantmptestlogs \ $(foreach crate,$(TEST_TARGET_CRATES),check-stage2-$(crate)) \ check-stage2-rpass check-stage2-rpass-valgrind \ - check-stage2-rfail check-stage2-cfail check-stage2-rmake + check-stage2-rfail check-stage2-cfail check-stage2-pfail check-stage2-rmake $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log # Only check the 'reference' tests: rpass/cfail/rfail/rmake. check-ref: cleantestlibs cleantmptestlogs check-stage2-rpass check-stage2-rpass-valgrind \ - check-stage2-rfail check-stage2-cfail check-stage2-rmake + check-stage2-rfail check-stage2-cfail check-stage2-pfail check-stage2-rmake $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log # Only check the docs. @@ -291,6 +291,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \ check-stage$(1)-T-$(2)-H-$(3)-rpass-exec \ check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \ check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \ + check-stage$(1)-T-$(2)-H-$(3)-pfail-exec \ check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \ check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \ check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \ @@ -470,7 +471,8 @@ RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS) RPASS_FULL_TESTS := $(RPASS_FULL_RS) CFAIL_FULL_TESTS := $(CFAIL_FULL_RS) RFAIL_TESTS := $(RFAIL_RS) -CFAIL_TESTS := $(CFAIL_RS) $(PFAIL_RS) +CFAIL_TESTS := $(CFAIL_RS) +PFAIL_TESTS := $(PFAIL_RS) BENCH_TESTS := $(BENCH_RS) PERF_TESTS := $(PERF_RS) PRETTY_TESTS := $(PRETTY_RS) @@ -508,6 +510,11 @@ CTEST_BUILD_BASE_cfail = compile-fail CTEST_MODE_cfail = compile-fail CTEST_RUNTOOL_cfail = $(CTEST_RUNTOOL) +CTEST_SRC_BASE_pfail = parse-fail +CTEST_BUILD_BASE_pfail = parse-fail +CTEST_MODE_pfail = parse-fail +CTEST_RUNTOOL_pfail = $(CTEST_RUNTOOL) + CTEST_SRC_BASE_bench = bench CTEST_BUILD_BASE_bench = bench CTEST_MODE_bench = run-pass @@ -630,6 +637,7 @@ CTEST_DEPS_rpass-full_$(1)-T-$(2)-H-$(3) = $$(RPASS_FULL_TESTS) $$(CSREQ$(1)_T_$ CTEST_DEPS_cfail-full_$(1)-T-$(2)-H-$(3) = $$(CFAIL_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3)) CTEST_DEPS_rfail_$(1)-T-$(2)-H-$(3) = $$(RFAIL_TESTS) CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS) +CTEST_DEPS_pfail_$(1)-T-$(2)-H-$(3) = $$(PFAIL_TESTS) CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS) CTEST_DEPS_perf_$(1)-T-$(2)-H-$(3) = $$(PERF_TESTS) CTEST_DEPS_debuginfo-gdb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_GDB_TESTS) @@ -698,7 +706,7 @@ endif endef -CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail bench perf debuginfo-gdb debuginfo-lldb codegen +CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail pfail bench perf debuginfo-gdb debuginfo-lldb codegen $(foreach host,$(CFG_HOST), \ $(eval $(foreach target,$(CFG_TARGET), \ @@ -857,6 +865,7 @@ TEST_GROUPS = \ cfail-full \ rfail \ cfail \ + pfail \ bench \ perf \ rmake \ diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index df2981a6c8334..2c046d252799e 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -15,6 +15,7 @@ use std::str::FromStr; #[derive(Clone, Copy, PartialEq, Debug)] pub enum Mode { CompileFail, + ParseFail, RunFail, RunPass, RunPassValgrind, @@ -29,6 +30,7 @@ impl FromStr for Mode { fn from_str(s: &str) -> Result { match s { "compile-fail" => Ok(CompileFail), + "parse-fail" => Ok(ParseFail), "run-fail" => Ok(RunFail), "run-pass" => Ok(RunPass), "run-pass-valgrind" => Ok(RunPassValgrind), @@ -45,6 +47,7 @@ impl fmt::Display for Mode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(match *self { CompileFail => "compile-fail", + ParseFail => "parse-fail", RunFail => "run-fail", RunPass => "run-pass", RunPassValgrind => "run-pass-valgrind", diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 86710d50d8a06..278ce5565d9fc 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -21,6 +21,7 @@ #![feature(test)] #![feature(unicode)] #![feature(env)] +#![feature(core)] #![deny(warnings)] @@ -72,7 +73,7 @@ pub fn parse_config(args: Vec ) -> Config { reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"), reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"), reqopt("", "mode", "which sort of compile tests to run", - "(compile-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"), + "(compile-fail|parse-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"), optflag("", "ignored", "run tests marked as ignored"), optopt("", "runtool", "supervisor program to run tests under \ (eg. emulator, valgrind)", "PROGRAM"), diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 658c0cb3f4e83..1cbb8742bbc5a 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -11,7 +11,7 @@ use self::TargetLocation::*; use common::Config; -use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb}; +use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb}; use common::{Codegen, DebugInfoLldb}; use errors; use header::TestProps; @@ -66,6 +66,7 @@ pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) { debug!("loaded props"); match config.mode { CompileFail => run_cfail_test(&config, &props, &testfile), + ParseFail => run_cfail_test(&config, &props, &testfile), RunFail => run_rfail_test(&config, &props, &testfile), RunPass => run_rpass_test(&config, &props, &testfile), RunPassValgrind => run_valgrind_test(&config, &props, &testfile), @@ -88,7 +89,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_proc_rec("compile-fail test compiled successfully!", + fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[], &proc_res); } @@ -688,7 +689,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) .unwrap() .to_string(); - script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[])[]); + script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[]); script_str.push_str("type summary add --no-value "); script_str.push_str("--python-function lldb_rust_formatters.print_val "); script_str.push_str("-x \".*\" --category Rust\n"); @@ -1133,7 +1134,7 @@ fn compile_test_(config: &Config, props: &TestProps, // FIXME (#9639): This needs to handle non-utf8 paths let mut link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string()); - link_args.extend(extra_args.iter().map(|s| s.clone())); + link_args.extend(extra_args.iter().cloned()); let args = make_compile_args(config, props, link_args, diff --git a/src/doc/reference.md b/src/doc/reference.md index 70baebf0d30ac..db940947040d4 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -572,7 +572,7 @@ the final namespace qualifier is omitted. Two examples of paths with type arguments: ``` -# struct HashMap; +# struct HashMap(K,V); # fn f() { # fn id(t: T) -> T { t } type T = HashMap; // Type arguments used in a type expression @@ -1599,7 +1599,7 @@ pointer values (pointing to a type for which an implementation of the given trait is in scope) to pointers to the trait name, used as a type. ``` -# trait Shape { } +# trait Shape { fn dummy(&self) { } } # impl Shape for i32 { } # let mycircle = 0i32; let myshape: Box = Box::new(mycircle) as Box; @@ -1630,8 +1630,8 @@ let x: f64 = Num::from_i32(42); Traits may inherit from other traits. For example, in ``` -trait Shape { fn area() -> f64; } -trait Circle : Shape { fn radius() -> f64; } +trait Shape { fn area(&self) -> f64; } +trait Circle : Shape { fn radius(&self) -> f64; } ``` the syntax `Circle : Shape` means that types that implement `Circle` must also @@ -1725,7 +1725,7 @@ type parameters taken by the trait it implements. Implementation parameters are written after the `impl` keyword. ``` -# trait Seq { } +# trait Seq { fn dummy(&self, _: T) { } } impl Seq for Vec { /* ... */ } @@ -3583,7 +3583,7 @@ An example of each kind: ```{rust} let vec: Vec = vec![1, 2, 3]; let arr: [i32; 3] = [1, 2, 3]; -let s: &[i32] = &vec[]; +let s: &[i32] = &vec[..]; ``` As you can see, the `vec!` macro allows you to create a `Vec` easily. The diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index f2b95f19edce2..97e826579fd9b 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -435,8 +435,8 @@ extern { } fn main() { - let prompt = CString::from_slice(b"[my-awesome-shell] $"); - unsafe { + let prompt = CString::new("[my-awesome-shell] $").unwrap(); + unsafe { rl_prompt = prompt.as_ptr(); println!("{:?}", rl_prompt); @@ -541,6 +541,6 @@ pub extern fn hello_rust() -> *const u8 { The `extern` makes this function adhere to the C calling convention, as discussed above in "[Foreign Calling -Conventions](guide-ffi.html#foreign-calling-conventions)". The `no_mangle` +Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle` attribute turns off Rust's name mangling, so that it is easier to link to. diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md index 122cffe36975f..9e82e48fd18b7 100644 --- a/src/doc/trpl/patterns.md +++ b/src/doc/trpl/patterns.md @@ -180,7 +180,7 @@ If you want to match against a slice or array, you can use `&`: fn main() { let v = vec!["match_this", "1"]; - match &v[] { + match &v[..] { ["match_this", second] => println!("The second element is {}", second), _ => {}, } diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 3830d7fe29532..934e6ab215916 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -73,7 +73,6 @@ use core::prelude::*; use core::atomic; use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst}; -use core::borrow::BorrowFrom; use core::fmt; use core::cmp::{Ordering}; use core::default::Default; @@ -244,12 +243,6 @@ impl Clone for Arc { } } -impl BorrowFrom> for T { - fn borrow_from(owned: &Arc) -> &T { - &**owned - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Arc { type Target = T; @@ -605,11 +598,19 @@ impl Default for Arc { fn default() -> Arc { Arc::new(Default::default()) } } +#[cfg(stage0)] impl> Hash for Arc { fn hash(&self, state: &mut H) { (**self).hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Arc { + fn hash(&self, state: &mut H) { + (**self).hash(state) + } +} #[cfg(test)] mod tests { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 340a8d59612f2..a3516bd667b7a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -10,13 +10,14 @@ //! A pointer type for heap allocation. //! -//! `Box`, casually referred to as a 'box', provides the simplest form of heap allocation in -//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of -//! scope. +//! `Box`, casually referred to as a 'box', provides the simplest form of +//! heap allocation in Rust. Boxes provide ownership for this allocation, and +//! drop their contents when they go out of scope. //! -//! Boxes are useful in two situations: recursive data structures, and occasionally when returning -//! data. [The Pointer chapter of the Book](../../../book/pointers.html#best-practices-1) explains -//! these cases in detail. +//! Boxes are useful in two situations: recursive data structures, and +//! occasionally when returning data. [The Pointer chapter of the +//! Book](../../../book/pointers.html#best-practices-1) explains these cases in +//! detail. //! //! # Examples //! @@ -58,8 +59,8 @@ use core::ops::{Deref, DerefMut}; use core::ptr::Unique; use core::raw::TraitObject; -/// A value that represents the heap. This is the default place that the `box` keyword allocates -/// into when no place is supplied. +/// A value that represents the heap. This is the default place that the `box` +/// keyword allocates into when no place is supplied. /// /// The following two examples are equivalent: /// @@ -219,12 +220,20 @@ impl Ord for Box { #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Box {} +#[cfg(stage0)] impl> Hash for Box { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Box { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} /// Extension methods for an owning `Any` trait object. #[unstable(feature = "alloc", diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b3c2638f3ae28..bc349ebebdeed 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -73,7 +73,6 @@ #![feature(unboxed_closures)] #![feature(unsafe_no_drop_flag)] #![feature(core)] -#![feature(hash)] #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")), feature(libc))] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f361c36ec8fa7..9d39511543188 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -144,13 +144,12 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::borrow::BorrowFrom; use core::cell::Cell; use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; use core::default::Default; use core::fmt; -use core::hash::{self, Hash}; +use core::hash::{Hasher, Hash}; use core::marker; use core::mem::{transmute, min_align_of, size_of, forget}; use core::nonzero::NonZero; @@ -349,12 +348,6 @@ impl Rc { } } -impl BorrowFrom> for T { - fn borrow_from(owned: &Rc) -> &T { - &**owned - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Rc { type Target = T; @@ -599,12 +592,20 @@ impl Ord for Rc { } // FIXME (#18248) Make `T` `Sized?` -impl> Hash for Rc { +#[cfg(stage0)] +impl> Hash for Rc { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Rc { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Rc { diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 4cd3d587580f0..b43f9adfb26d9 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -96,7 +96,7 @@ pub struct Arena<'longer_than_self> { head: RefCell, copy_head: RefCell, chunks: RefCell>, - _invariant: marker::InvariantLifetime<'longer_than_self>, + _marker: marker::PhantomData<*mut &'longer_than_self()>, } impl<'a> Arena<'a> { @@ -111,7 +111,7 @@ impl<'a> Arena<'a> { head: RefCell::new(chunk(initial_size, false)), copy_head: RefCell::new(chunk(initial_size, true)), chunks: RefCell::new(Vec::new()), - _invariant: marker::InvariantLifetime, + _marker: marker::PhantomData, } } } @@ -361,6 +361,8 @@ pub struct TypedArena { } struct TypedArenaChunk { + marker: marker::PhantomData, + /// Pointer to the next arena segment. next: *mut TypedArenaChunk, diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 6196d94b5a6bd..9f549fd723771 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -650,8 +650,8 @@ impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BinaryHeap { - fn from_iter>(iter: Iter) -> BinaryHeap { - BinaryHeap::from_vec(iter.collect()) + fn from_iter>(iter: I) -> BinaryHeap { + BinaryHeap::from_vec(iter.into_iter().collect()) } } @@ -677,7 +677,8 @@ impl<'a, T> IntoIterator for &'a BinaryHeap where T: Ord { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BinaryHeap { - fn extend>(&mut self, iter: Iter) { + fn extend>(&mut self, iterable: I) { + let iter = iterable.into_iter(); let (lower, _) = iter.size_hint(); self.reserve(lower); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 0b762788b208a..11c576eab1525 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// FIXME(Gankro): Bitv and BitvSet are very tightly coupled. Ideally (for -// maintenance), they should be in separate files/modules, with BitvSet only -// using Bitv's public API. This will be hard for performance though, because -// `Bitv` will not want to leak its internal representation while its internal +// FIXME(Gankro): BitVec and BitSet are very tightly coupled. Ideally (for +// maintenance), they should be in separate files/modules, with BitSet only +// using BitVec's public API. This will be hard for performance though, because +// `BitVec` will not want to leak its internal representation while its internal // representation as `u32`s must be assumed for best performance. -// FIXME(tbu-): `Bitv`'s methods shouldn't be `union`, `intersection`, but +// FIXME(tbu-): `BitVec`'s methods shouldn't be `union`, `intersection`, but // rather `or` and `and`. // (1) Be careful, most things can overflow here because the amount of bits in @@ -25,8 +25,8 @@ // methods rely on it (for *CORRECTNESS*). // (3) Make sure that the unused bits in the last word are zeroed out, again // other methods rely on it for *CORRECTNESS*. -// (4) `BitvSet` is tightly coupled with `Bitv`, so any changes you make in -// `Bitv` will need to be reflected in `BitvSet`. +// (4) `BitSet` is tightly coupled with `BitVec`, so any changes you make in +// `BitVec` will need to be reflected in `BitSet`. //! Collections implemented with bit vectors. //! @@ -38,17 +38,17 @@ //! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes //! //! ``` -//! use std::collections::{BitvSet, Bitv}; +//! use std::collections::{BitSet, BitVec}; //! use std::num::Float; //! use std::iter; //! //! let max_prime = 10000; //! -//! // Store the primes as a BitvSet +//! // Store the primes as a BitSet //! let primes = { //! // Assume all numbers are prime to begin, and then we //! // cross off non-primes progressively -//! let mut bv = Bitv::from_elem(max_prime, true); +//! let mut bv = BitVec::from_elem(max_prime, true); //! //! // Neither 0 nor 1 are prime //! bv.set(0, false); @@ -62,7 +62,7 @@ //! for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) } //! } //! } -//! BitvSet::from_bitv(bv) +//! BitSet::from_bit_vec(bv) //! }; //! //! // Simple primality tests below our max bound @@ -75,7 +75,7 @@ //! } //! println!(""); //! -//! // We can manipulate the internal Bitv +//! // We can manipulate the internal BitVec //! let num_primes = primes.get_ref().iter().filter(|x| *x).count(); //! println!("There are {} primes below {}", num_primes, max_prime); //! ``` @@ -94,7 +94,7 @@ use core::num::Int; use core::ops::Index; use core::slice; use core::{u8, u32, usize}; -use bitv_set; //so meta +use bit_set; //so meta use Vec; @@ -112,7 +112,7 @@ fn reverse_bits(byte: u8) -> u8 { // Take two BitV's, and return iterators of their words, where the shorter one // has been padded with 0's -fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) { +fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWords<'b>) { let a_len = a.storage.len(); let b_len = b.storage.len(); @@ -134,9 +134,9 @@ static FALSE: bool = false; /// # Examples /// /// ```rust -/// use std::collections::Bitv; +/// use std::collections::BitVec; /// -/// let mut bv = Bitv::from_elem(10, false); +/// let mut bv = BitVec::from_elem(10, false); /// /// // insert all primes less than 10 /// bv.set(2, true); @@ -158,7 +158,7 @@ static FALSE: bool = false; /// ``` #[unstable(feature = "collections", reason = "RFC 509")] -pub struct Bitv { +pub struct BitVec { /// Internal representation of the bit vector storage: Vec, /// The number of valid bits in the internal representation @@ -166,7 +166,7 @@ pub struct Bitv { } // FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing) -impl Index for Bitv { +impl Index for BitVec { type Output = bool; #[inline] @@ -202,12 +202,12 @@ fn mask_for_bits(bits: usize) -> u32 { !0u32 >> (u32::BITS - bits % u32::BITS) % u32::BITS } -impl Bitv { +impl BitVec { /// Applies the given operation to the blocks of self and other, and sets /// self to be the result. This relies on the caller not to corrupt the /// last word. #[inline] - fn process(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 { + fn process(&mut self, other: &BitVec, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 { assert_eq!(self.len(), other.len()); // This could theoretically be a `debug_assert!`. assert_eq!(self.storage.len(), other.storage.len()); @@ -235,7 +235,7 @@ impl Bitv { } /// An operation might screw up the unused bits in the last block of the - /// `Bitv`. As per (3), it's assumed to be all 0s. This method fixes it up. + /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up. fn fix_last_block(&mut self) { let extra_bits = self.len() % u32::BITS; if extra_bits > 0 { @@ -245,44 +245,44 @@ impl Bitv { } } - /// Creates an empty `Bitv`. + /// Creates an empty `BitVec`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; - /// let mut bv = Bitv::new(); + /// use std::collections::BitVec; + /// let mut bv = BitVec::new(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> Bitv { - Bitv { storage: Vec::new(), nbits: 0 } + pub fn new() -> BitVec { + BitVec { storage: Vec::new(), nbits: 0 } } - /// Creates a `Bitv` that holds `nbits` elements, setting each element + /// Creates a `BitVec` that holds `nbits` elements, setting each element /// to `bit`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(10, false); + /// let mut bv = BitVec::from_elem(10, false); /// assert_eq!(bv.len(), 10); /// for x in bv.iter() { /// assert_eq!(x, false); /// } /// ``` - pub fn from_elem(nbits: usize, bit: bool) -> Bitv { + pub fn from_elem(nbits: usize, bit: bool) -> BitVec { let nblocks = blocks_for_bits(nbits); - let mut bitv = Bitv { + let mut bit_vec = BitVec { storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(), nbits: nbits }; - bitv.fix_last_block(); - bitv + bit_vec.fix_last_block(); + bit_vec } - /// Constructs a new, empty `Bitv` with the specified capacity. + /// Constructs a new, empty `BitVec` with the specified capacity. /// /// The bitvector will be able to hold at least `capacity` bits without /// reallocating. If `capacity` is 0, it will not allocate. @@ -290,38 +290,38 @@ impl Bitv { /// It is important to note that this function does not specify the /// *length* of the returned bitvector, but only the *capacity*. #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(nbits: usize) -> Bitv { - Bitv { + pub fn with_capacity(nbits: usize) -> BitVec { + BitVec { storage: Vec::with_capacity(blocks_for_bits(nbits)), nbits: 0, } } - /// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits, + /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits, /// with the most significant bits of each byte coming first. Each /// bit becomes `true` if equal to 1 or `false` if equal to 0. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b10100000, 0b00010010]); + /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]); /// assert!(bv.eq_vec(&[true, false, true, false, /// false, false, false, false, /// false, false, false, true, /// false, false, true, false])); /// ``` - pub fn from_bytes(bytes: &[u8]) -> Bitv { + pub fn from_bytes(bytes: &[u8]) -> BitVec { let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow"); - let mut bitv = Bitv::with_capacity(len); + let mut bit_vec = BitVec::with_capacity(len); let complete_words = bytes.len() / 4; let extra_bytes = bytes.len() % 4; - bitv.nbits = len; + bit_vec.nbits = len; for i in 0..complete_words { - bitv.storage.push( + bit_vec.storage.push( ((reverse_bits(bytes[i * 4 + 0]) as u32) << 0) | ((reverse_bits(bytes[i * 4 + 1]) as u32) << 8) | ((reverse_bits(bytes[i * 4 + 2]) as u32) << 16) | @@ -334,29 +334,29 @@ impl Bitv { for (i, &byte) in bytes[complete_words*4..].iter().enumerate() { last_word |= (reverse_bits(byte) as u32) << (i * 8); } - bitv.storage.push(last_word); + bit_vec.storage.push(last_word); } - bitv + bit_vec } - /// Creates a `Bitv` of the specified length where the value at each index + /// Creates a `BitVec` of the specified length where the value at each index /// is `f(index)`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_fn(5, |i| { i % 2 == 0 }); + /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 }); /// assert!(bv.eq_vec(&[true, false, true, false, true])); /// ``` - pub fn from_fn(len: usize, mut f: F) -> Bitv where F: FnMut(usize) -> bool { - let mut bitv = Bitv::from_elem(len, false); + pub fn from_fn(len: usize, mut f: F) -> BitVec where F: FnMut(usize) -> bool { + let mut bit_vec = BitVec::from_elem(len, false); for i in 0..len { - bitv.set(i, f(i)); + bit_vec.set(i, f(i)); } - bitv + bit_vec } /// Retrieves the value at index `i`, or `None` if the index is out of bounds. @@ -364,9 +364,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b01100000]); + /// let bv = BitVec::from_bytes(&[0b01100000]); /// assert_eq!(bv.get(0), Some(false)); /// assert_eq!(bv.get(1), Some(true)); /// assert_eq!(bv.get(100), None); @@ -396,9 +396,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(5, false); + /// let mut bv = BitVec::from_elem(5, false); /// bv.set(3, true); /// assert_eq!(bv[3], true); /// ``` @@ -420,14 +420,14 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let before = 0b01100000; /// let after = 0b11111111; /// - /// let mut bv = Bitv::from_bytes(&[before]); + /// let mut bv = BitVec::from_bytes(&[before]); /// bv.set_all(); - /// assert_eq!(bv, Bitv::from_bytes(&[after])); + /// assert_eq!(bv, BitVec::from_bytes(&[after])); /// ``` #[inline] pub fn set_all(&mut self) { @@ -440,14 +440,14 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let before = 0b01100000; /// let after = 0b10011111; /// - /// let mut bv = Bitv::from_bytes(&[before]); + /// let mut bv = BitVec::from_bytes(&[before]); /// bv.negate(); - /// assert_eq!(bv, Bitv::from_bytes(&[after])); + /// assert_eq!(bv, BitVec::from_bytes(&[after])); /// ``` #[inline] pub fn negate(&mut self) { @@ -468,20 +468,20 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let a = 0b01100100; /// let b = 0b01011010; /// let res = 0b01111110; /// - /// let mut a = Bitv::from_bytes(&[a]); - /// let b = Bitv::from_bytes(&[b]); + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); /// /// assert!(a.union(&b)); - /// assert_eq!(a, Bitv::from_bytes(&[res])); + /// assert_eq!(a, BitVec::from_bytes(&[res])); /// ``` #[inline] - pub fn union(&mut self, other: &Bitv) -> bool { + pub fn union(&mut self, other: &BitVec) -> bool { self.process(other, |w1, w2| w1 | w2) } @@ -498,20 +498,20 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let a = 0b01100100; /// let b = 0b01011010; /// let res = 0b01000000; /// - /// let mut a = Bitv::from_bytes(&[a]); - /// let b = Bitv::from_bytes(&[b]); + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); /// /// assert!(a.intersect(&b)); - /// assert_eq!(a, Bitv::from_bytes(&[res])); + /// assert_eq!(a, BitVec::from_bytes(&[res])); /// ``` #[inline] - pub fn intersect(&mut self, other: &Bitv) -> bool { + pub fn intersect(&mut self, other: &BitVec) -> bool { self.process(other, |w1, w2| w1 & w2) } @@ -528,27 +528,27 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let a = 0b01100100; /// let b = 0b01011010; /// let a_b = 0b00100100; // a - b /// let b_a = 0b00011010; // b - a /// - /// let mut bva = Bitv::from_bytes(&[a]); - /// let bvb = Bitv::from_bytes(&[b]); + /// let mut bva = BitVec::from_bytes(&[a]); + /// let bvb = BitVec::from_bytes(&[b]); /// /// assert!(bva.difference(&bvb)); - /// assert_eq!(bva, Bitv::from_bytes(&[a_b])); + /// assert_eq!(bva, BitVec::from_bytes(&[a_b])); /// - /// let bva = Bitv::from_bytes(&[a]); - /// let mut bvb = Bitv::from_bytes(&[b]); + /// let bva = BitVec::from_bytes(&[a]); + /// let mut bvb = BitVec::from_bytes(&[b]); /// /// assert!(bvb.difference(&bva)); - /// assert_eq!(bvb, Bitv::from_bytes(&[b_a])); + /// assert_eq!(bvb, BitVec::from_bytes(&[b_a])); /// ``` #[inline] - pub fn difference(&mut self, other: &Bitv) -> bool { + pub fn difference(&mut self, other: &BitVec) -> bool { self.process(other, |w1, w2| w1 & !w2) } @@ -557,9 +557,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(5, true); + /// let mut bv = BitVec::from_elem(5, true); /// assert_eq!(bv.all(), true); /// /// bv.set(1, false); @@ -581,15 +581,15 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b01110100, 0b10010010]); + /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]); /// assert_eq!(bv.iter().filter(|x| *x).count(), 7); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter { - Iter { bitv: self, next_idx: 0, end_idx: self.nbits } + Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits } } /// Returns `true` if all bits are 0. @@ -597,9 +597,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(10, false); + /// let mut bv = BitVec::from_elem(10, false); /// assert_eq!(bv.none(), true); /// /// bv.set(3, true); @@ -614,9 +614,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(10, false); + /// let mut bv = BitVec::from_elem(10, false); /// assert_eq!(bv.any(), false); /// /// bv.set(3, true); @@ -628,33 +628,33 @@ impl Bitv { } /// Organises the bits into bytes, such that the first bit in the - /// `Bitv` becomes the high-order bit of the first byte. If the - /// size of the `Bitv` is not a multiple of eight then trailing bits + /// `BitVec` becomes the high-order bit of the first byte. If the + /// size of the `BitVec` is not a multiple of eight then trailing bits /// will be filled-in with `false`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(3, true); + /// let mut bv = BitVec::from_elem(3, true); /// bv.set(1, false); /// /// assert_eq!(bv.to_bytes(), vec!(0b10100000)); /// - /// let mut bv = Bitv::from_elem(9, false); + /// let mut bv = BitVec::from_elem(9, false); /// bv.set(2, true); /// bv.set(8, true); /// /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); /// ``` pub fn to_bytes(&self) -> Vec { - fn bit(bitv: &Bitv, byte: usize, bit: usize) -> u8 { + fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 { let offset = byte * 8 + bit; - if offset >= bitv.nbits { + if offset >= bit_vec.nbits { 0 } else { - (bitv[offset] as u8) << (7 - bit) + (bit_vec[offset] as u8) << (7 - bit) } } @@ -672,19 +672,19 @@ impl Bitv { ).collect() } - /// Compares a `Bitv` to a slice of `bool`s. - /// Both the `Bitv` and slice must have the same length. + /// Compares a `BitVec` to a slice of `bool`s. + /// Both the `BitVec` and slice must have the same length. /// /// # Panics /// - /// Panics if the `Bitv` and slice are of different length. + /// Panics if the `BitVec` and slice are of different length. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b10100000]); + /// let bv = BitVec::from_bytes(&[0b10100000]); /// /// assert!(bv.eq_vec(&[true, false, true, false, /// false, false, false, false])); @@ -694,7 +694,7 @@ impl Bitv { iter::order::eq(self.iter(), v.iter().cloned()) } - /// Shortens a `Bitv`, dropping excess elements. + /// Shortens a `BitVec`, dropping excess elements. /// /// If `len` is greater than the vector's current length, this has no /// effect. @@ -702,9 +702,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_bytes(&[0b01001011]); + /// let mut bv = BitVec::from_bytes(&[0b01001011]); /// bv.truncate(2); /// assert!(bv.eq_vec(&[false, true])); /// ``` @@ -719,7 +719,7 @@ impl Bitv { } /// Reserves capacity for at least `additional` more bits to be inserted in the given - /// `Bitv`. The collection may reserve more space to avoid frequent reallocations. + /// `BitVec`. The collection may reserve more space to avoid frequent reallocations. /// /// # Panics /// @@ -728,9 +728,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(3, false); + /// let mut bv = BitVec::from_elem(3, false); /// bv.reserve(10); /// assert_eq!(bv.len(), 3); /// assert!(bv.capacity() >= 13); @@ -745,7 +745,7 @@ impl Bitv { } /// Reserves the minimum capacity for exactly `additional` more bits to be inserted in the - /// given `Bitv`. Does nothing if the capacity is already sufficient. + /// given `BitVec`. Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it requests. Therefore /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future @@ -758,9 +758,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(3, false); + /// let mut bv = BitVec::from_elem(3, false); /// bv.reserve(10); /// assert_eq!(bv.len(), 3); /// assert!(bv.capacity() >= 13); @@ -780,9 +780,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::new(); + /// let mut bv = BitVec::new(); /// bv.reserve(10); /// assert!(bv.capacity() >= 10); /// ``` @@ -792,7 +792,7 @@ impl Bitv { self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX) } - /// Grows the `Bitv` in-place, adding `n` copies of `value` to the `Bitv`. + /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`. /// /// # Panics /// @@ -801,9 +801,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_bytes(&[0b01001011]); + /// let mut bv = BitVec::from_bytes(&[0b01001011]); /// bv.grow(2, true); /// assert_eq!(bv.len(), 10); /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000)); @@ -846,14 +846,14 @@ impl Bitv { self.fix_last_block(); } - /// Removes the last bit from the Bitv, and returns it. Returns None if the Bitv is empty. + /// Removes the last bit from the BitVec, and returns it. Returns None if the BitVec is empty. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_bytes(&[0b01001001]); + /// let mut bv = BitVec::from_bytes(&[0b01001001]); /// assert_eq!(bv.pop(), Some(true)); /// assert_eq!(bv.pop(), Some(false)); /// assert_eq!(bv.len(), 6); @@ -881,9 +881,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::new(); + /// let mut bv = BitVec::new(); /// bv.push(true); /// bv.push(false); /// assert!(bv.eq_vec(&[true, false])); @@ -917,24 +917,25 @@ impl Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Bitv { +impl Default for BitVec { #[inline] - fn default() -> Bitv { Bitv::new() } + fn default() -> BitVec { BitVec::new() } } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for Bitv { - fn from_iter>(iterator: I) -> Bitv { - let mut ret = Bitv::new(); - ret.extend(iterator); +impl FromIterator for BitVec { + fn from_iter>(iter: I) -> BitVec { + let mut ret = BitVec::new(); + ret.extend(iter); ret } } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for Bitv { +impl Extend for BitVec { #[inline] - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); let (min, _) = iterator.size_hint(); self.reserve(min); for element in iterator { @@ -944,37 +945,37 @@ impl Extend for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Bitv { +impl Clone for BitVec { #[inline] - fn clone(&self) -> Bitv { - Bitv { storage: self.storage.clone(), nbits: self.nbits } + fn clone(&self) -> BitVec { + BitVec { storage: self.storage.clone(), nbits: self.nbits } } #[inline] - fn clone_from(&mut self, source: &Bitv) { + fn clone_from(&mut self, source: &BitVec) { self.nbits = source.nbits; self.storage.clone_from(&source.storage); } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Bitv { +impl PartialOrd for BitVec { #[inline] - fn partial_cmp(&self, other: &Bitv) -> Option { + fn partial_cmp(&self, other: &BitVec) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Bitv { +impl Ord for BitVec { #[inline] - fn cmp(&self, other: &Bitv) -> Ordering { + fn cmp(&self, other: &BitVec) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Bitv { +impl fmt::Debug for BitVec { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for bit in self { try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 })); @@ -984,7 +985,8 @@ impl fmt::Debug for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl hash::Hash for Bitv { +#[cfg(stage0)] +impl hash::Hash for BitVec { fn hash(&self, state: &mut S) { self.nbits.hash(state); for elem in self.blocks() { @@ -992,11 +994,21 @@ impl hash::Hash for Bitv { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl hash::Hash for BitVec { + fn hash(&self, state: &mut H) { + self.nbits.hash(state); + for elem in self.blocks() { + elem.hash(state); + } + } +} #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for Bitv { +impl cmp::PartialEq for BitVec { #[inline] - fn eq(&self, other: &Bitv) -> bool { + fn eq(&self, other: &BitVec) -> bool { if self.nbits != other.nbits { return false; } @@ -1005,13 +1017,13 @@ impl cmp::PartialEq for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for Bitv {} +impl cmp::Eq for BitVec {} -/// An iterator for `Bitv`. +/// An iterator for `BitVec`. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Iter<'a> { - bitv: &'a Bitv, + bit_vec: &'a BitVec, next_idx: usize, end_idx: usize, } @@ -1025,7 +1037,7 @@ impl<'a> Iterator for Iter<'a> { if self.next_idx != self.end_idx { let idx = self.next_idx; self.next_idx += 1; - Some(self.bitv[idx]) + Some(self.bit_vec[idx]) } else { None } @@ -1043,7 +1055,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> { fn next_back(&mut self) -> Option { if self.next_idx != self.end_idx { self.end_idx -= 1; - Some(self.bitv[self.end_idx]) + Some(self.bit_vec[self.end_idx]) } else { None } @@ -1065,13 +1077,13 @@ impl<'a> RandomAccessIterator for Iter<'a> { if index >= self.indexable() { None } else { - Some(self.bitv[index]) + Some(self.bit_vec[index]) } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> IntoIterator for &'a Bitv { +impl<'a> IntoIterator for &'a BitVec { type Item = bool; type IntoIter = Iter<'a>; @@ -1090,10 +1102,10 @@ impl<'a> IntoIterator for &'a Bitv { /// # Examples /// /// ``` -/// use std::collections::{BitvSet, Bitv}; +/// use std::collections::{BitSet, BitVec}; /// /// // It's a regular set -/// let mut s = BitvSet::new(); +/// let mut s = BitSet::new(); /// s.insert(0); /// s.insert(3); /// s.insert(7); @@ -1104,8 +1116,8 @@ impl<'a> IntoIterator for &'a Bitv { /// println!("There is no 7"); /// } /// -/// // Can initialize from a `Bitv` -/// let other = BitvSet::from_bitv(Bitv::from_bytes(&[0b11010000])); +/// // Can initialize from a `BitVec` +/// let other = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11010000])); /// /// s.union_with(&other); /// @@ -1114,115 +1126,115 @@ impl<'a> IntoIterator for &'a Bitv { /// println!("{}", x); /// } /// -/// // Can convert back to a `Bitv` -/// let bv: Bitv = s.into_bitv(); +/// // Can convert back to a `BitVec` +/// let bv: BitVec = s.into_bit_vec(); /// assert!(bv[3]); /// ``` #[derive(Clone)] #[unstable(feature = "collections", reason = "RFC 509")] -pub struct BitvSet { - bitv: Bitv, +pub struct BitSet { + bit_vec: BitVec, } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for BitvSet { +impl Default for BitSet { #[inline] - fn default() -> BitvSet { BitvSet::new() } + fn default() -> BitSet { BitSet::new() } } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for BitvSet { - fn from_iter>(iterator: I) -> BitvSet { - let mut ret = BitvSet::new(); - ret.extend(iterator); +impl FromIterator for BitSet { + fn from_iter>(iter: I) -> BitSet { + let mut ret = BitSet::new(); + ret.extend(iter); ret } } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for BitvSet { +impl Extend for BitSet { #[inline] - fn extend>(&mut self, iterator: I) { - for i in iterator { + fn extend>(&mut self, iter: I) { + for i in iter { self.insert(i); } } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for BitvSet { +impl PartialOrd for BitSet { #[inline] - fn partial_cmp(&self, other: &BitvSet) -> Option { + fn partial_cmp(&self, other: &BitSet) -> Option { let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::partial_cmp(a_iter, b_iter) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for BitvSet { +impl Ord for BitSet { #[inline] - fn cmp(&self, other: &BitvSet) -> Ordering { + fn cmp(&self, other: &BitSet) -> Ordering { let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::cmp(a_iter, b_iter) } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for BitvSet { +impl cmp::PartialEq for BitSet { #[inline] - fn eq(&self, other: &BitvSet) -> bool { + fn eq(&self, other: &BitSet) -> bool { let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::eq(a_iter, b_iter) } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for BitvSet {} +impl cmp::Eq for BitSet {} -impl BitvSet { - /// Creates a new empty `BitvSet`. +impl BitSet { + /// Creates a new empty `BitSet`. /// /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> BitvSet { - BitvSet { bitv: Bitv::new() } + pub fn new() -> BitSet { + BitSet { bit_vec: BitVec::new() } } - /// Creates a new `BitvSet` with initially no contents, able to + /// Creates a new `BitSet` with initially no contents, able to /// hold `nbits` elements without resizing. /// /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::with_capacity(100); + /// let mut s = BitSet::with_capacity(100); /// assert!(s.capacity() >= 100); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(nbits: usize) -> BitvSet { - let bitv = Bitv::from_elem(nbits, false); - BitvSet::from_bitv(bitv) + pub fn with_capacity(nbits: usize) -> BitSet { + let bit_vec = BitVec::from_elem(nbits, false); + BitSet::from_bit_vec(bit_vec) } - /// Creates a new `BitvSet` from the given bit vector. + /// Creates a new `BitSet` from the given bit vector. /// /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let bv = Bitv::from_bytes(&[0b01100000]); - /// let s = BitvSet::from_bitv(bv); + /// let bv = BitVec::from_bytes(&[0b01100000]); + /// let s = BitSet::from_bit_vec(bv); /// /// // Print 1, 2 in arbitrary order /// for x in s.iter() { @@ -1230,8 +1242,16 @@ impl BitvSet { /// } /// ``` #[inline] - pub fn from_bitv(bitv: Bitv) -> BitvSet { - BitvSet { bitv: bitv } + pub fn from_bit_vec(bit_vec: BitVec) -> BitSet { + BitSet { bit_vec: bit_vec } + } + + /// Deprecated: use `from_bit_vec`. + #[inline] + #[deprecated(since = "1.0.0", reason = "renamed to from_bit_vec")] + #[unstable(feature = "collections")] + pub fn from_bitv(bit_vec: BitVec) -> BitSet { + BitSet { bit_vec: bit_vec } } /// Returns the capacity in bits for this bit vector. Inserting any @@ -1240,19 +1260,19 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::with_capacity(100); + /// let mut s = BitSet::with_capacity(100); /// assert!(s.capacity() >= 100); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn capacity(&self) -> usize { - self.bitv.capacity() + self.bit_vec.capacity() } - /// Reserves capacity for the given `BitvSet` to contain `len` distinct elements. In the case - /// of `BitvSet` this means reallocations will not occur as long as all inserted elements + /// Reserves capacity for the given `BitSet` to contain `len` distinct elements. In the case + /// of `BitSet` this means reallocations will not occur as long as all inserted elements /// are less than `len`. /// /// The collection may reserve more space to avoid frequent reallocations. @@ -1261,22 +1281,22 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.reserve_len(10); /// assert!(s.capacity() >= 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve_len(&mut self, len: usize) { - let cur_len = self.bitv.len(); + let cur_len = self.bit_vec.len(); if len >= cur_len { - self.bitv.reserve(len - cur_len); + self.bit_vec.reserve(len - cur_len); } } - /// Reserves the minimum capacity for the given `BitvSet` to contain `len` distinct elements. - /// In the case of `BitvSet` this means reallocations will not occur as long as all inserted + /// Reserves the minimum capacity for the given `BitSet` to contain `len` distinct elements. + /// In the case of `BitSet` this means reallocations will not occur as long as all inserted /// elements are less than `len`. /// /// Note that the allocator may give the collection more space than it requests. Therefore @@ -1287,17 +1307,17 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.reserve_len_exact(10); /// assert!(s.capacity() >= 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve_len_exact(&mut self, len: usize) { - let cur_len = self.bitv.len(); + let cur_len = self.bit_vec.len(); if len >= cur_len { - self.bitv.reserve_exact(len - cur_len); + self.bit_vec.reserve_exact(len - cur_len); } } @@ -1307,19 +1327,19 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.insert(0); /// s.insert(3); /// - /// let bv = s.into_bitv(); + /// let bv = s.into_bit_vec(); /// assert!(bv[0]); /// assert!(bv[3]); /// ``` #[inline] - pub fn into_bitv(self) -> Bitv { - self.bitv + pub fn into_bit_vec(self) -> BitVec { + self.bit_vec } /// Returns a reference to the underlying bit vector. @@ -1327,44 +1347,44 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.insert(0); /// /// let bv = s.get_ref(); /// assert_eq!(bv[0], true); /// ``` #[inline] - pub fn get_ref(&self) -> &Bitv { - &self.bitv + pub fn get_ref(&self) -> &BitVec { + &self.bit_vec } #[inline] - fn other_op(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 { - // Unwrap Bitvs - let self_bitv = &mut self.bitv; - let other_bitv = &other.bitv; + fn other_op(&mut self, other: &BitSet, mut f: F) where F: FnMut(u32, u32) -> u32 { + // Unwrap BitVecs + let self_bit_vec = &mut self.bit_vec; + let other_bit_vec = &other.bit_vec; - let self_len = self_bitv.len(); - let other_len = other_bitv.len(); + let self_len = self_bit_vec.len(); + let other_len = other_bit_vec.len(); // Expand the vector if necessary if self_len < other_len { - self_bitv.grow(other_len - self_len, false); + self_bit_vec.grow(other_len - self_len, false); } // virtually pad other with 0's for equal lengths let other_words = { - let (_, result) = match_words(self_bitv, other_bitv); + let (_, result) = match_words(self_bit_vec, other_bit_vec); result }; // Apply values found in other for (i, w) in other_words { - let old = self_bitv.storage[i]; + let old = self_bit_vec.storage[i]; let new = f(old, w); - self_bitv.storage[i] = new; + self_bit_vec.storage[i] = new; } } @@ -1373,9 +1393,9 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.insert(32183231); /// s.remove(&32183231); /// @@ -1389,25 +1409,25 @@ impl BitvSet { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn shrink_to_fit(&mut self) { - let bitv = &mut self.bitv; + let bit_vec = &mut self.bit_vec; // Obtain original length - let old_len = bitv.storage.len(); + let old_len = bit_vec.storage.len(); // Obtain coarse trailing zero length - let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count(); + let n = bit_vec.storage.iter().rev().take_while(|&&n| n == 0).count(); // Truncate let trunc_len = cmp::max(old_len - n, 1); - bitv.storage.truncate(trunc_len); - bitv.nbits = trunc_len * u32::BITS; + bit_vec.storage.truncate(trunc_len); + bit_vec.nbits = trunc_len * u32::BITS; } - /// Iterator over each u32 stored in the `BitvSet`. + /// Iterator over each u32 stored in the `BitSet`. /// /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let s = BitvSet::from_bitv(Bitv::from_bytes(&[0b01001010])); + /// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010])); /// /// // Print 1, 4, 6 in arbitrary order /// for x in s.iter() { @@ -1416,7 +1436,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> bitv_set::Iter { + pub fn iter(&self) -> bit_set::Iter { SetIter {set: self, next_idx: 0} } @@ -1426,10 +1446,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 0, 1, 2, 4 in arbitrary order /// for x in a.union(&b) { @@ -1438,7 +1458,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn union<'a>(&'a self, other: &'a BitvSet) -> Union<'a> { + pub fn union<'a>(&'a self, other: &'a BitSet) -> Union<'a> { fn or(w1: u32, w2: u32) -> u32 { w1 | w2 } Union(TwoBitPositions { @@ -1456,10 +1476,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 2 /// for x in a.intersection(&b) { @@ -1468,9 +1488,9 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Intersection<'a> { + pub fn intersection<'a>(&'a self, other: &'a BitSet) -> Intersection<'a> { fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 } - let min = cmp::min(self.bitv.len(), other.bitv.len()); + let min = cmp::min(self.bit_vec.len(), other.bit_vec.len()); Intersection(TwoBitPositions { set: self, other: other, @@ -1486,10 +1506,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 1, 4 in arbitrary order /// for x in a.difference(&b) { @@ -1505,7 +1525,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn difference<'a>(&'a self, other: &'a BitvSet) -> Difference<'a> { + pub fn difference<'a>(&'a self, other: &'a BitSet) -> Difference<'a> { fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 } Difference(TwoBitPositions { @@ -1524,10 +1544,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 0, 1, 4 in arbitrary order /// for x in a.symmetric_difference(&b) { @@ -1536,7 +1556,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> SymmetricDifference<'a> { + pub fn symmetric_difference<'a>(&'a self, other: &'a BitSet) -> SymmetricDifference<'a> { fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 } SymmetricDifference(TwoBitPositions { @@ -1553,21 +1573,21 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let res = 0b11101000; /// - /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res])); + /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res])); /// /// a.union_with(&b); /// assert_eq!(a, res); /// ``` #[inline] - pub fn union_with(&mut self, other: &BitvSet) { + pub fn union_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 | w2); } @@ -1576,21 +1596,21 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let res = 0b00100000; /// - /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res])); + /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res])); /// /// a.intersect_with(&b); /// assert_eq!(a, res); /// ``` #[inline] - pub fn intersect_with(&mut self, other: &BitvSet) { + pub fn intersect_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 & w2); } @@ -1600,29 +1620,29 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let a_b = 0b01001000; // a - b /// let b_a = 0b10000000; // b - a /// - /// let mut bva = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let bva_b = BitvSet::from_bitv(Bitv::from_bytes(&[a_b])); - /// let bvb_a = BitvSet::from_bitv(Bitv::from_bytes(&[b_a])); + /// let mut bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let bva_b = BitSet::from_bit_vec(BitVec::from_bytes(&[a_b])); + /// let bvb_a = BitSet::from_bit_vec(BitVec::from_bytes(&[b_a])); /// /// bva.difference_with(&bvb); /// assert_eq!(bva, bva_b); /// - /// let bva = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let mut bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b])); + /// let bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let mut bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); /// /// bvb.difference_with(&bva); /// assert_eq!(bvb, bvb_a); /// ``` #[inline] - pub fn difference_with(&mut self, other: &BitvSet) { + pub fn difference_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 & !w2); } @@ -1632,21 +1652,21 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let res = 0b11001000; /// - /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res])); + /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res])); /// /// a.symmetric_difference_with(&b); /// assert_eq!(a, res); /// ``` #[inline] - pub fn symmetric_difference_with(&mut self, other: &BitvSet) { + pub fn symmetric_difference_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 ^ w2); } @@ -1654,57 +1674,57 @@ impl BitvSet { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { - self.bitv.blocks().fold(0, |acc, n| acc + n.count_ones()) + self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones()) } /// Returns whether there are no bits set in this set #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { - self.bitv.none() + self.bit_vec.none() } /// Clears all bits in this set #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - self.bitv.clear(); + self.bit_vec.clear(); } /// Returns `true` if this set contains the specified integer. #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &usize) -> bool { - let bitv = &self.bitv; - *value < bitv.nbits && bitv[*value] + let bit_vec = &self.bit_vec; + *value < bit_vec.nbits && bit_vec[*value] } /// Returns `true` if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_disjoint(&self, other: &BitvSet) -> bool { + pub fn is_disjoint(&self, other: &BitSet) -> bool { self.intersection(other).next().is_none() } /// Returns `true` if the set is a subset of another. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_subset(&self, other: &BitvSet) -> bool { - let self_bitv = &self.bitv; - let other_bitv = &other.bitv; - let other_blocks = blocks_for_bits(other_bitv.len()); + pub fn is_subset(&self, other: &BitSet) -> bool { + let self_bit_vec = &self.bit_vec; + let other_bit_vec = &other.bit_vec; + let other_blocks = blocks_for_bits(other_bit_vec.len()); // Check that `self` intersect `other` is self - self_bitv.blocks().zip(other_bitv.blocks()).all(|(w1, w2)| w1 & w2 == w1) && + self_bit_vec.blocks().zip(other_bit_vec.blocks()).all(|(w1, w2)| w1 & w2 == w1) && // Make sure if `self` has any more blocks than `other`, they're all 0 - self_bitv.blocks().skip(other_blocks).all(|w| w == 0) + self_bit_vec.blocks().skip(other_blocks).all(|w| w == 0) } /// Returns `true` if the set is a superset of another. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_superset(&self, other: &BitvSet) -> bool { + pub fn is_superset(&self, other: &BitSet) -> bool { other.is_subset(self) } @@ -1717,12 +1737,12 @@ impl BitvSet { } // Ensure we have enough space to hold the new element - let len = self.bitv.len(); + let len = self.bit_vec.len(); if value >= len { - self.bitv.grow(value - len + 1, false) + self.bit_vec.grow(value - len + 1, false) } - self.bitv.set(value, true); + self.bit_vec.set(value, true); return true; } @@ -1734,16 +1754,16 @@ impl BitvSet { return false; } - self.bitv.set(*value, false); + self.bit_vec.set(*value, false); return true; } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for BitvSet { +impl fmt::Debug for BitSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "BitvSet {{")); + try!(write!(fmt, "BitSet {{")); let mut first = true; for n in self { if !first { @@ -1756,27 +1776,37 @@ impl fmt::Debug for BitvSet { } } -impl hash::Hash for BitvSet { +#[cfg(stage0)] +impl hash::Hash for BitSet { fn hash(&self, state: &mut S) { for pos in self { pos.hash(state); } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl hash::Hash for BitSet { + fn hash(&self, state: &mut H) { + for pos in self { + pos.hash(state); + } + } +} -/// An iterator for `BitvSet`. +/// An iterator for `BitSet`. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct SetIter<'a> { - set: &'a BitvSet, + set: &'a BitSet, next_idx: usize } -/// An iterator combining two `BitvSet` iterators. +/// An iterator combining two `BitSet` iterators. #[derive(Clone)] struct TwoBitPositions<'a> { - set: &'a BitvSet, - other: &'a BitvSet, + set: &'a BitSet, + other: &'a BitSet, merge: fn(u32, u32) -> u32, current_word: u32, next_idx: usize @@ -1796,7 +1826,7 @@ impl<'a> Iterator for SetIter<'a> { type Item = usize; fn next(&mut self) -> Option { - while self.next_idx < self.set.bitv.len() { + while self.next_idx < self.set.bit_vec.len() { let idx = self.next_idx; self.next_idx += 1; @@ -1810,7 +1840,7 @@ impl<'a> Iterator for SetIter<'a> { #[inline] fn size_hint(&self) -> (usize, Option) { - (0, Some(self.set.bitv.len() - self.next_idx)) + (0, Some(self.set.bit_vec.len() - self.next_idx)) } } @@ -1819,20 +1849,20 @@ impl<'a> Iterator for TwoBitPositions<'a> { type Item = usize; fn next(&mut self) -> Option { - while self.next_idx < self.set.bitv.len() || - self.next_idx < self.other.bitv.len() { + while self.next_idx < self.set.bit_vec.len() || + self.next_idx < self.other.bit_vec.len() { let bit_idx = self.next_idx % u32::BITS; if bit_idx == 0 { - let s_bitv = &self.set.bitv; - let o_bitv = &self.other.bitv; + let s_bit_vec = &self.set.bit_vec; + let o_bit_vec = &self.other.bit_vec; // Merging the two words is a bit of an awkward dance since - // one Bitv might be longer than the other + // one BitVec might be longer than the other let word_idx = self.next_idx / u32::BITS; - let w1 = if word_idx < s_bitv.storage.len() { - s_bitv.storage[word_idx] + let w1 = if word_idx < s_bit_vec.storage.len() { + s_bit_vec.storage[word_idx] } else { 0 }; - let w2 = if word_idx < o_bitv.storage.len() { - o_bitv.storage[word_idx] + let w2 = if word_idx < o_bit_vec.storage.len() { + o_bit_vec.storage[word_idx] } else { 0 }; self.current_word = (self.merge)(w1, w2); } @@ -1847,7 +1877,7 @@ impl<'a> Iterator for TwoBitPositions<'a> { #[inline] fn size_hint(&self) -> (usize, Option) { - let cap = cmp::max(self.set.bitv.len(), self.other.bitv.len()); + let cap = cmp::max(self.set.bit_vec.len(), self.other.bit_vec.len()); (0, Some(cap - self.next_idx)) } } @@ -1885,7 +1915,7 @@ impl<'a> Iterator for SymmetricDifference<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> IntoIterator for &'a BitvSet { +impl<'a> IntoIterator for &'a BitSet { type Item = usize; type IntoIter = SetIter<'a>; @@ -1899,20 +1929,20 @@ mod tests { use prelude::*; use core::u32; - use super::Bitv; + use super::BitVec; #[test] fn test_to_str() { - let zerolen = Bitv::new(); + let zerolen = BitVec::new(); assert_eq!(format!("{:?}", zerolen), ""); - let eightbits = Bitv::from_elem(8, false); + let eightbits = BitVec::from_elem(8, false); assert_eq!(format!("{:?}", eightbits), "00000000") } #[test] fn test_0_elements() { - let act = Bitv::new(); + let act = BitVec::new(); let exp = Vec::new(); assert!(act.eq_vec(&exp)); assert!(act.none() && act.all()); @@ -1920,17 +1950,17 @@ mod tests { #[test] fn test_1_element() { - let mut act = Bitv::from_elem(1, false); + let mut act = BitVec::from_elem(1, false); assert!(act.eq_vec(&[false])); assert!(act.none() && !act.all()); - act = Bitv::from_elem(1, true); + act = BitVec::from_elem(1, true); assert!(act.eq_vec(&[true])); assert!(!act.none() && act.all()); } #[test] fn test_2_elements() { - let mut b = Bitv::from_elem(2, false); + let mut b = BitVec::from_elem(2, false); b.set(0, true); b.set(1, false); assert_eq!(format!("{:?}", b), "10"); @@ -1942,18 +1972,18 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); assert!((act.eq_vec( &[false, false, false, false, false, false, false, false, false, false]))); assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(10, true); + act = BitVec::from_elem(10, true); assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true]))); assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -1963,7 +1993,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); act.set(5, true); act.set(6, true); act.set(7, true); @@ -1973,7 +2003,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); act.set(0, true); act.set(3, true); act.set(6, true); @@ -1987,7 +2017,7 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); assert!(act.eq_vec( &[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, @@ -1995,7 +2025,7 @@ mod tests { assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(31, true); + act = BitVec::from_elem(31, true); assert!(act.eq_vec( &[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -2003,7 +2033,7 @@ mod tests { assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -2019,7 +2049,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(16, true); act.set(17, true); act.set(18, true); @@ -2035,7 +2065,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(24, true); act.set(25, true); act.set(26, true); @@ -2050,7 +2080,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(3, true); act.set(17, true); act.set(30, true); @@ -2066,7 +2096,7 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); assert!(act.eq_vec( &[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, @@ -2074,7 +2104,7 @@ mod tests { assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(32, true); + act = BitVec::from_elem(32, true); assert!(act.eq_vec( &[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -2082,7 +2112,7 @@ mod tests { assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -2098,7 +2128,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(16, true); act.set(17, true); act.set(18, true); @@ -2114,7 +2144,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(24, true); act.set(25, true); act.set(26, true); @@ -2130,7 +2160,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(3, true); act.set(17, true); act.set(30, true); @@ -2147,7 +2177,7 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); assert!(act.eq_vec( &[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, @@ -2155,7 +2185,7 @@ mod tests { assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(33, true); + act = BitVec::from_elem(33, true); assert!(act.eq_vec( &[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -2163,7 +2193,7 @@ mod tests { assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -2179,7 +2209,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(16, true); act.set(17, true); act.set(18, true); @@ -2195,7 +2225,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(24, true); act.set(25, true); act.set(26, true); @@ -2211,7 +2241,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(3, true); act.set(17, true); act.set(30, true); @@ -2226,24 +2256,24 @@ mod tests { #[test] fn test_equal_differing_sizes() { - let v0 = Bitv::from_elem(10, false); - let v1 = Bitv::from_elem(11, false); + let v0 = BitVec::from_elem(10, false); + let v1 = BitVec::from_elem(11, false); assert!(v0 != v1); } #[test] fn test_equal_greatly_differing_sizes() { - let v0 = Bitv::from_elem(10, false); - let v1 = Bitv::from_elem(110, false); + let v0 = BitVec::from_elem(10, false); + let v1 = BitVec::from_elem(110, false); assert!(v0 != v1); } #[test] fn test_equal_sneaky_small() { - let mut a = Bitv::from_elem(1, false); + let mut a = BitVec::from_elem(1, false); a.set(0, true); - let mut b = Bitv::from_elem(1, true); + let mut b = BitVec::from_elem(1, true); b.set(0, true); assert_eq!(a, b); @@ -2251,12 +2281,12 @@ mod tests { #[test] fn test_equal_sneaky_big() { - let mut a = Bitv::from_elem(100, false); + let mut a = BitVec::from_elem(100, false); for i in 0..100 { a.set(i, true); } - let mut b = Bitv::from_elem(100, true); + let mut b = BitVec::from_elem(100, true); for i in 0..100 { b.set(i, true); } @@ -2266,18 +2296,18 @@ mod tests { #[test] fn test_from_bytes() { - let bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); + let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); let str = concat!("10110110", "00000000", "11111111"); - assert_eq!(format!("{:?}", bitv), str); + assert_eq!(format!("{:?}", bit_vec), str); } #[test] fn test_to_bytes() { - let mut bv = Bitv::from_elem(3, true); + let mut bv = BitVec::from_elem(3, true); bv.set(1, false); assert_eq!(bv.to_bytes(), vec!(0b10100000)); - let mut bv = Bitv::from_elem(9, false); + let mut bv = BitVec::from_elem(9, false); bv.set(2, true); bv.set(8, true); assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); @@ -2286,32 +2316,32 @@ mod tests { #[test] fn test_from_bools() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); - assert_eq!(format!("{:?}", bitv), "1011"); + let bit_vec: BitVec = bools.iter().map(|n| *n).collect(); + assert_eq!(format!("{:?}", bit_vec), "1011"); } #[test] fn test_to_bools() { let bools = vec![false, false, true, false, false, true, true, false]; - assert_eq!(Bitv::from_bytes(&[0b00100110]).iter().collect::>(), bools); + assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::>(), bools); } #[test] - fn test_bitv_iterator() { + fn test_bit_vec_iterator() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); + let bit_vec: BitVec = bools.iter().map(|n| *n).collect(); - assert_eq!(bitv.iter().collect::>(), bools); + assert_eq!(bit_vec.iter().collect::>(), bools); let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect(); - let bitv: Bitv = long.iter().map(|n| *n).collect(); - assert_eq!(bitv.iter().collect::>(), long) + let bit_vec: BitVec = long.iter().map(|n| *n).collect(); + assert_eq!(bit_vec.iter().collect::>(), long) } #[test] fn test_small_difference() { - let mut b1 = Bitv::from_elem(3, false); - let mut b2 = Bitv::from_elem(3, false); + let mut b1 = BitVec::from_elem(3, false); + let mut b2 = BitVec::from_elem(3, false); b1.set(0, true); b1.set(1, true); b2.set(1, true); @@ -2324,8 +2354,8 @@ mod tests { #[test] fn test_big_difference() { - let mut b1 = Bitv::from_elem(100, false); - let mut b2 = Bitv::from_elem(100, false); + let mut b1 = BitVec::from_elem(100, false); + let mut b2 = BitVec::from_elem(100, false); b1.set(0, true); b1.set(40, true); b2.set(40, true); @@ -2338,7 +2368,7 @@ mod tests { #[test] fn test_small_clear() { - let mut b = Bitv::from_elem(14, true); + let mut b = BitVec::from_elem(14, true); assert!(!b.none() && b.all()); b.clear(); assert!(b.none() && !b.all()); @@ -2346,16 +2376,16 @@ mod tests { #[test] fn test_big_clear() { - let mut b = Bitv::from_elem(140, true); + let mut b = BitVec::from_elem(140, true); assert!(!b.none() && b.all()); b.clear(); assert!(b.none() && !b.all()); } #[test] - fn test_bitv_lt() { - let mut a = Bitv::from_elem(5, false); - let mut b = Bitv::from_elem(5, false); + fn test_bit_vec_lt() { + let mut a = BitVec::from_elem(5, false); + let mut b = BitVec::from_elem(5, false); assert!(!(a < b) && !(b < a)); b.set(2, true); @@ -2370,8 +2400,8 @@ mod tests { #[test] fn test_ord() { - let mut a = Bitv::from_elem(5, false); - let mut b = Bitv::from_elem(5, false); + let mut a = BitVec::from_elem(5, false); + let mut b = BitVec::from_elem(5, false); assert!(a <= b && a >= b); a.set(1, true); @@ -2385,26 +2415,26 @@ mod tests { #[test] - fn test_small_bitv_tests() { - let v = Bitv::from_bytes(&[0]); + fn test_small_bit_vec_tests() { + let v = BitVec::from_bytes(&[0]); assert!(!v.all()); assert!(!v.any()); assert!(v.none()); - let v = Bitv::from_bytes(&[0b00010100]); + let v = BitVec::from_bytes(&[0b00010100]); assert!(!v.all()); assert!(v.any()); assert!(!v.none()); - let v = Bitv::from_bytes(&[0xFF]); + let v = BitVec::from_bytes(&[0xFF]); assert!(v.all()); assert!(v.any()); assert!(!v.none()); } #[test] - fn test_big_bitv_tests() { - let v = Bitv::from_bytes(&[ // 88 bits + fn test_big_bit_vec_tests() { + let v = BitVec::from_bytes(&[ // 88 bits 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); @@ -2412,7 +2442,7 @@ mod tests { assert!(!v.any()); assert!(v.none()); - let v = Bitv::from_bytes(&[ // 88 bits + let v = BitVec::from_bytes(&[ // 88 bits 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0]); @@ -2420,7 +2450,7 @@ mod tests { assert!(v.any()); assert!(!v.none()); - let v = Bitv::from_bytes(&[ // 88 bits + let v = BitVec::from_bytes(&[ // 88 bits 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); @@ -2430,8 +2460,8 @@ mod tests { } #[test] - fn test_bitv_push_pop() { - let mut s = Bitv::from_elem(5 * u32::BITS - 2, false); + fn test_bit_vec_push_pop() { + let mut s = BitVec::from_elem(5 * u32::BITS - 2, false); assert_eq!(s.len(), 5 * u32::BITS - 2); assert_eq!(s[5 * u32::BITS - 3], false); s.push(true); @@ -2453,29 +2483,29 @@ mod tests { } #[test] - fn test_bitv_truncate() { - let mut s = Bitv::from_elem(5 * u32::BITS, true); + fn test_bit_vec_truncate() { + let mut s = BitVec::from_elem(5 * u32::BITS, true); - assert_eq!(s, Bitv::from_elem(5 * u32::BITS, true)); + assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true)); assert_eq!(s.len(), 5 * u32::BITS); s.truncate(4 * u32::BITS); - assert_eq!(s, Bitv::from_elem(4 * u32::BITS, true)); + assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true)); assert_eq!(s.len(), 4 * u32::BITS); // Truncating to a size > s.len() should be a noop s.truncate(5 * u32::BITS); - assert_eq!(s, Bitv::from_elem(4 * u32::BITS, true)); + assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true)); assert_eq!(s.len(), 4 * u32::BITS); s.truncate(3 * u32::BITS - 10); - assert_eq!(s, Bitv::from_elem(3 * u32::BITS - 10, true)); + assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true)); assert_eq!(s.len(), 3 * u32::BITS - 10); s.truncate(0); - assert_eq!(s, Bitv::from_elem(0, true)); + assert_eq!(s, BitVec::from_elem(0, true)); assert_eq!(s.len(), 0); } #[test] - fn test_bitv_reserve() { - let mut s = Bitv::from_elem(5 * u32::BITS, true); + fn test_bit_vec_reserve() { + let mut s = BitVec::from_elem(5 * u32::BITS, true); // Check capacity assert!(s.capacity() >= 5 * u32::BITS); s.reserve(2 * u32::BITS); @@ -2498,25 +2528,25 @@ mod tests { } #[test] - fn test_bitv_grow() { - let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010]); - bitv.grow(32, true); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010, + fn test_bit_vec_grow() { + let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]); + bit_vec.grow(32, true); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF])); - bitv.grow(64, false); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010, + bit_vec.grow(64, false); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0])); - bitv.grow(16, true); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010, + bit_vec.grow(16, true); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF])); } #[test] - fn test_bitv_extend() { - let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); - let ext = Bitv::from_bytes(&[0b01001001, 0b10010010, 0b10111101]); - bitv.extend(ext.iter()); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111, + fn test_bit_vec_extend() { + let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); + let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]); + bit_vec.extend(ext.iter()); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111, 0b01001001, 0b10010010, 0b10111101])); } } @@ -2525,14 +2555,14 @@ mod tests { #[cfg(test)] -mod bitv_bench { +mod bit_vec_bench { use std::prelude::v1::*; use std::rand; use std::rand::Rng; use std::u32; use test::{Bencher, black_box}; - use super::Bitv; + use super::BitVec; static BENCH_BITS : usize = 1 << 14; @@ -2544,67 +2574,67 @@ mod bitv_bench { #[bench] fn bench_usize_small(b: &mut Bencher) { let mut r = rng(); - let mut bitv = 0 as usize; + let mut bit_vec = 0 as usize; b.iter(|| { for _ in 0..100 { - bitv |= 1 << ((r.next_u32() as usize) % u32::BITS); + bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_set_big_fixed(b: &mut Bencher) { + fn bench_bit_set_big_fixed(b: &mut Bencher) { let mut r = rng(); - let mut bitv = Bitv::from_elem(BENCH_BITS, false); + let mut bit_vec = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { for _ in 0..100 { - bitv.set((r.next_u32() as usize) % BENCH_BITS, true); + bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_set_big_variable(b: &mut Bencher) { + fn bench_bit_set_big_variable(b: &mut Bencher) { let mut r = rng(); - let mut bitv = Bitv::from_elem(BENCH_BITS, false); + let mut bit_vec = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { for _ in 0..100 { - bitv.set((r.next_u32() as usize) % BENCH_BITS, r.gen()); + bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen()); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_set_small(b: &mut Bencher) { + fn bench_bit_set_small(b: &mut Bencher) { let mut r = rng(); - let mut bitv = Bitv::from_elem(u32::BITS, false); + let mut bit_vec = BitVec::from_elem(u32::BITS, false); b.iter(|| { for _ in 0..100 { - bitv.set((r.next_u32() as usize) % u32::BITS, true); + bit_vec.set((r.next_u32() as usize) % u32::BITS, true); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_big_union(b: &mut Bencher) { - let mut b1 = Bitv::from_elem(BENCH_BITS, false); - let b2 = Bitv::from_elem(BENCH_BITS, false); + fn bench_bit_vec_big_union(b: &mut Bencher) { + let mut b1 = BitVec::from_elem(BENCH_BITS, false); + let b2 = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { b1.union(&b2) }) } #[bench] - fn bench_bitv_small_iter(b: &mut Bencher) { - let bitv = Bitv::from_elem(u32::BITS, false); + fn bench_bit_vec_small_iter(b: &mut Bencher) { + let bit_vec = BitVec::from_elem(u32::BITS, false); b.iter(|| { let mut sum = 0; for _ in 0..10 { - for pres in &bitv { + for pres in &bit_vec { sum += pres as usize; } } @@ -2613,11 +2643,11 @@ mod bitv_bench { } #[bench] - fn bench_bitv_big_iter(b: &mut Bencher) { - let bitv = Bitv::from_elem(BENCH_BITS, false); + fn bench_bit_vec_big_iter(b: &mut Bencher) { + let bit_vec = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { let mut sum = 0; - for pres in &bitv { + for pres in &bit_vec { sum += pres as usize; } sum @@ -2632,27 +2662,27 @@ mod bitv_bench { #[cfg(test)] -mod bitv_set_test { +mod bit_set_test { use prelude::*; use std::iter::range_step; - use super::{Bitv, BitvSet}; + use super::{BitVec, BitSet}; #[test] - fn test_bitv_set_show() { - let mut s = BitvSet::new(); + fn test_bit_set_show() { + let mut s = BitSet::new(); s.insert(1); s.insert(10); s.insert(50); s.insert(2); - assert_eq!("BitvSet {1, 2, 10, 50}", format!("{:?}", s)); + assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s)); } #[test] - fn test_bitv_set_from_usizes() { + fn test_bit_set_from_usizes() { let usizes = vec![0, 2, 2, 3]; - let a: BitvSet = usizes.into_iter().collect(); - let mut b = BitvSet::new(); + let a: BitSet = usizes.into_iter().collect(); + let mut b = BitSet::new(); b.insert(0); b.insert(2); b.insert(3); @@ -2660,14 +2690,14 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_iterator() { + fn test_bit_set_iterator() { let usizes = vec![0, 2, 2, 3]; - let bitv: BitvSet = usizes.into_iter().collect(); + let bit_vec: BitSet = usizes.into_iter().collect(); - let idxs: Vec<_> = bitv.iter().collect(); + let idxs: Vec<_> = bit_vec.iter().collect(); assert_eq!(idxs, vec![0, 2, 3]); - let long: BitvSet = (0..10000).filter(|&n| n % 2 == 0).collect(); + let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect(); let real: Vec<_> = range_step(0, 10000, 2).collect(); let idxs: Vec<_> = long.iter().collect(); @@ -2675,12 +2705,12 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_frombitv_init() { + fn test_bit_set_frombit_vec_init() { let bools = [true, false]; let lengths = [10, 64, 100]; for &b in &bools { for &l in &lengths { - let bitset = BitvSet::from_bitv(Bitv::from_elem(l, b)); + let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b)); assert_eq!(bitset.contains(&1), b); assert_eq!(bitset.contains(&(l-1)), b); assert!(!bitset.contains(&l)); @@ -2689,9 +2719,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_masking() { - let b = Bitv::from_elem(140, true); - let mut bs = BitvSet::from_bitv(b); + fn test_bit_vec_masking() { + let b = BitVec::from_elem(140, true); + let mut bs = BitSet::from_bit_vec(b); assert!(bs.contains(&139)); assert!(!bs.contains(&140)); assert!(bs.insert(150)); @@ -2702,8 +2732,8 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_basic() { - let mut b = BitvSet::new(); + fn test_bit_set_basic() { + let mut b = BitSet::new(); assert!(b.insert(3)); assert!(!b.insert(3)); assert!(b.contains(&3)); @@ -2717,9 +2747,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_intersection() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_intersection() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(11)); assert!(a.insert(1)); @@ -2740,9 +2770,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_difference() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_difference() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(3)); @@ -2759,9 +2789,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_symmetric_difference() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_symmetric_difference() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(3)); @@ -2780,9 +2810,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_union() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_union() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(3)); assert!(a.insert(5)); @@ -2805,9 +2835,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_subset() { - let mut set1 = BitvSet::new(); - let mut set2 = BitvSet::new(); + fn test_bit_set_subset() { + let mut set1 = BitSet::new(); + let mut set2 = BitSet::new(); assert!(set1.is_subset(&set2)); // {} {} set2.insert(100); @@ -2831,11 +2861,11 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_is_disjoint() { - let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01000000])); - let c = BitvSet::new(); - let d = BitvSet::from_bitv(Bitv::from_bytes(&[0b00110000])); + fn test_bit_set_is_disjoint() { + let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000])); + let c = BitSet::new(); + let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000])); assert!(!a.is_disjoint(&d)); assert!(!d.is_disjoint(&a)); @@ -2849,19 +2879,19 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_union_with() { + fn test_bit_set_union_with() { //a should grow to include larger elements - let mut a = BitvSet::new(); + let mut a = BitSet::new(); a.insert(0); - let mut b = BitvSet::new(); + let mut b = BitSet::new(); b.insert(5); - let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100])); + let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100])); a.union_with(&b); assert_eq!(a, expected); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010])); let c = a.clone(); a.union_with(&b); b.union_with(&c); @@ -2870,10 +2900,10 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_intersect_with() { + fn test_bit_set_intersect_with() { // Explicitly 0'ed bits - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); let c = a.clone(); a.intersect_with(&b); b.intersect_with(&c); @@ -2881,8 +2911,8 @@ mod bitv_set_test { assert!(b.is_empty()); // Uninitialized bits should behave like 0's - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::new(); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::new(); let c = a.clone(); a.intersect_with(&b); b.intersect_with(&c); @@ -2890,8 +2920,8 @@ mod bitv_set_test { assert!(b.is_empty()); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010])); let c = a.clone(); a.intersect_with(&b); b.intersect_with(&c); @@ -2900,22 +2930,22 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_difference_with() { + fn test_bit_set_difference_with() { // Explicitly 0'ed bits - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); a.difference_with(&b); assert!(a.is_empty()); // Uninitialized bits should behave like 0's - let mut a = BitvSet::new(); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b11111111])); + let mut a = BitSet::new(); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111])); a.difference_with(&b); assert!(a.is_empty()); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010])); let c = a.clone(); a.difference_with(&b); b.difference_with(&c); @@ -2924,27 +2954,27 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_symmetric_difference_with() { + fn test_bit_set_symmetric_difference_with() { //a should grow to include larger elements - let mut a = BitvSet::new(); + let mut a = BitSet::new(); a.insert(0); a.insert(1); - let mut b = BitvSet::new(); + let mut b = BitSet::new(); b.insert(1); b.insert(5); - let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100])); + let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100])); a.symmetric_difference_with(&b); assert_eq!(a, expected); - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::new(); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::new(); let c = a.clone(); a.symmetric_difference_with(&b); assert_eq!(a, c); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b11100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010])); let c = a.clone(); a.symmetric_difference_with(&b); b.symmetric_difference_with(&c); @@ -2953,10 +2983,10 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_eq() { - let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); - let c = BitvSet::new(); + fn test_bit_set_eq() { + let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); + let c = BitSet::new(); assert!(a == a); assert!(a != b); @@ -2967,10 +2997,10 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_cmp() { - let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); - let c = BitvSet::new(); + fn test_bit_set_cmp() { + let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); + let c = BitSet::new(); assert_eq!(a.cmp(&b), Greater); assert_eq!(a.cmp(&c), Greater); @@ -2981,8 +3011,8 @@ mod bitv_set_test { } #[test] - fn test_bitv_remove() { - let mut a = BitvSet::new(); + fn test_bit_vec_remove() { + let mut a = BitSet::new(); assert!(a.insert(1)); assert!(a.remove(&1)); @@ -2996,8 +3026,8 @@ mod bitv_set_test { } #[test] - fn test_bitv_clone() { - let mut a = BitvSet::new(); + fn test_bit_vec_clone() { + let mut a = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(100)); @@ -3020,14 +3050,14 @@ mod bitv_set_test { #[cfg(test)] -mod bitv_set_bench { +mod bit_set_bench { use std::prelude::v1::*; use std::rand; use std::rand::Rng; use std::u32; use test::{Bencher, black_box}; - use super::{Bitv, BitvSet}; + use super::{BitVec, BitSet}; static BENCH_BITS : usize = 1 << 14; @@ -3037,36 +3067,36 @@ mod bitv_set_bench { } #[bench] - fn bench_bitvset_small(b: &mut Bencher) { + fn bench_bit_vecset_small(b: &mut Bencher) { let mut r = rng(); - let mut bitv = BitvSet::new(); + let mut bit_vec = BitSet::new(); b.iter(|| { for _ in 0..100 { - bitv.insert((r.next_u32() as usize) % u32::BITS); + bit_vec.insert((r.next_u32() as usize) % u32::BITS); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitvset_big(b: &mut Bencher) { + fn bench_bit_vecset_big(b: &mut Bencher) { let mut r = rng(); - let mut bitv = BitvSet::new(); + let mut bit_vec = BitSet::new(); b.iter(|| { for _ in 0..100 { - bitv.insert((r.next_u32() as usize) % BENCH_BITS); + bit_vec.insert((r.next_u32() as usize) % BENCH_BITS); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitvset_iter(b: &mut Bencher) { - let bitv = BitvSet::from_bitv(Bitv::from_fn(BENCH_BITS, + fn bench_bit_vecset_iter(b: &mut Bencher) { + let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS, |idx| {idx % 3 == 0})); b.iter(|| { let mut sum = 0; - for idx in &bitv { + for idx in &bit_vec { sum += idx as usize; } sum diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs new file mode 100644 index 0000000000000..901d7a73b51ed --- /dev/null +++ b/src/libcollections/borrow.rs @@ -0,0 +1,316 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A module for working with borrowed data. + +#![stable(feature = "rust1", since = "1.0.0")] + +use core::clone::Clone; +use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use core::hash::{Hash, Hasher}; +use core::marker::Sized; +use core::ops::Deref; +use core::option::Option; + +use fmt; +use alloc::{rc, arc}; + +use self::Cow::*; + +/// A trait for borrowing data. +/// +/// In general, there may be several ways to "borrow" a piece of data. The +/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` +/// (a mutable borrow). But types like `Vec` provide additional kinds of +/// borrows: the borrowed slices `&[T]` and `&mut [T]`. +/// +/// When writing generic code, it is often desirable to abstract over all ways +/// of borrowing data from a given type. That is the role of the `Borrow` +/// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given +/// type can be borrowed as multiple different types. In particular, `Vec: +/// Borrow>` and `Vec: Borrow<[T]>`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Borrow { + /// Immutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow(&self) -> &Borrowed; +} + +/// A trait for mutably borrowing data. +/// +/// Similar to `Borrow`, but for mutable borrows. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BorrowMut : Borrow { + /// Mutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow_mut(&mut self) -> &mut Borrowed; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for T { + fn borrow(&self) -> &T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl BorrowMut for T { + fn borrow_mut(&mut self) -> &mut T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a mut T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> BorrowMut for &'a mut T { + fn borrow_mut(&mut self) -> &mut T { &mut **self } +} + +impl Borrow for rc::Rc { + fn borrow(&self) -> &T { &**self } +} + +impl Borrow for arc::Arc { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Borrow for Cow<'a, B> where B: ToOwned, ::Owned: 'a { + fn borrow(&self) -> &B { + &**self + } +} + +/// A generalization of Clone to borrowed data. +/// +/// Some types make it possible to go from borrowed to owned, usually by +/// implementing the `Clone` trait. But `Clone` works only for going from `&T` +/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data +/// from any borrow of a given type. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ToOwned { + #[stable(feature = "rust1", since = "1.0.0")] + type Owned: Borrow; + + /// Create owned data from borrowed data, usually by copying. + #[stable(feature = "rust1", since = "1.0.0")] + fn to_owned(&self) -> Self::Owned; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for T where T: Clone { + type Owned = T; + fn to_owned(&self) -> T { self.clone() } +} + +/// A clone-on-write smart pointer. +/// +/// The type `Cow` is a smart pointer providing clone-on-write functionality: it +/// can enclose and provide immutable access to borrowed data, and clone the +/// data lazily when mutation or ownership is required. The type is designed to +/// work with general borrowed data via the `Borrow` trait. +/// +/// `Cow` implements both `Deref`, which means that you can call +/// non-mutating methods directly on the data it encloses. If mutation +/// is desired, `to_mut` will obtain a mutable references to an owned +/// value, cloning if necessary. +/// +/// # Example +/// +/// ```rust +/// use std::borrow::Cow; +/// +/// fn abs_all(input: &mut Cow<[int]>) { +/// for i in 0..input.len() { +/// let v = input[i]; +/// if v < 0 { +/// // clones into a vector the first time (if not already owned) +/// input.to_mut()[i] = -v; +/// } +/// } +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned { + /// Borrowed data. + #[stable(feature = "rust1", since = "1.0.0")] + Borrowed(&'a B), + + /// Owned data. + #[stable(feature = "rust1", since = "1.0.0")] + Owned(::Owned) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned { + fn clone(&self) -> Cow<'a, B> { + match *self { + Borrowed(b) => Borrowed(b), + Owned(ref o) => { + let b: &B = o.borrow(); + Owned(b.to_owned()) + }, + } + } +} + +impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned { + /// Acquire a mutable reference to the owned form of the data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn to_mut(&mut self) -> &mut ::Owned { + match *self { + Borrowed(borrowed) => { + *self = Owned(borrowed.to_owned()); + self.to_mut() + } + Owned(ref mut owned) => owned + } + } + + /// Extract the owned data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_owned(self) -> ::Owned { + match self { + Borrowed(borrowed) => borrowed.to_owned(), + Owned(owned) => owned + } + } + + /// Returns true if this `Cow` wraps a borrowed value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + _ => false, + } + } + + /// Returns true if this `Cow` wraps an owned value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_owned(&self) -> bool { + match *self { + Owned(_) => true, + _ => false, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned { + type Target = B; + + fn deref(&self) -> &B { + match *self { + Borrowed(borrowed) => borrowed, + Owned(ref owned) => owned.borrow() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned { + #[inline] + fn cmp(&self, other: &Cow<'a, B>) -> Ordering { + Ord::cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, B> where + B: PartialEq + ToOwned, C: ToOwned, +{ + #[inline] + fn eq(&self, other: &Cow<'b, C>) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned, +{ + #[inline] + fn partial_cmp(&self, other: &Cow<'a, B>) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where + B: fmt::Debug + ToOwned, + ::Owned: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Debug::fmt(b, f), + Owned(ref o) => fmt::Debug::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where + B: fmt::Display + ToOwned, + ::Owned: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Display::fmt(b, f), + Owned(ref o) => fmt::Display::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] +impl<'a, B: ?Sized, S: Hasher> Hash for Cow<'a, B> where B: Hash + ToOwned +{ + #[inline] + fn hash(&self, state: &mut S) { + Hash::hash(&**self, state) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned +{ + #[inline] + fn hash(&self, state: &mut H) { + Hash::hash(&**self, state) + } +} + +/// Trait for moving into a `Cow` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { + /// Moves `self` into `Cow` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_cow(self) -> Cow<'a, B>; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { + fn into_cow(self) -> Cow<'a, B> { + self + } +} diff --git a/src/libcollections/borrow_stage0.rs b/src/libcollections/borrow_stage0.rs new file mode 100644 index 0000000000000..c1d74b16ce6bc --- /dev/null +++ b/src/libcollections/borrow_stage0.rs @@ -0,0 +1,313 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A module for working with borrowed data. + +#![stable(feature = "rust1", since = "1.0.0")] + +use core::clone::Clone; +use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use core::hash::{Hash, Hasher}; +use core::marker::Sized; +use core::ops::Deref; +use core::option::Option; + +use fmt; +use alloc::{rc, arc}; + +use self::Cow::*; + +/// A trait for borrowing data. +/// +/// In general, there may be several ways to "borrow" a piece of data. The +/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` +/// (a mutable borrow). But types like `Vec` provide additional kinds of +/// borrows: the borrowed slices `&[T]` and `&mut [T]`. +/// +/// When writing generic code, it is often desirable to abstract over all ways +/// of borrowing data from a given type. That is the role of the `Borrow` +/// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given +/// type can be borrowed as multiple different types. In particular, `Vec: +/// Borrow>` and `Vec: Borrow<[T]>`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Borrow { + /// Immutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow(&self) -> &Borrowed; +} + +/// A trait for mutably borrowing data. +/// +/// Similar to `Borrow`, but for mutable borrows. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BorrowMut : Borrow { + /// Mutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow_mut(&mut self) -> &mut Borrowed; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for T { + fn borrow(&self) -> &T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl BorrowMut for T { + fn borrow_mut(&mut self) -> &mut T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a mut T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> BorrowMut for &'a mut T { + fn borrow_mut(&mut self) -> &mut T { &mut **self } +} + +impl Borrow for rc::Rc { + fn borrow(&self) -> &T { &**self } +} + +impl Borrow for arc::Arc { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Borrow for Cow<'a, B> where B: ToOwned, ::Owned: 'a { + fn borrow(&self) -> &B { + &**self + } +} + +/// A generalization of Clone to borrowed data. +/// +/// Some types make it possible to go from borrowed to owned, usually by +/// implementing the `Clone` trait. But `Clone` works only for going from `&T` +/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data +/// from any borrow of a given type. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ToOwned { + #[stable(feature = "rust1", since = "1.0.0")] + type Owned: Borrow; + + /// Create owned data from borrowed data, usually by copying. + #[stable(feature = "rust1", since = "1.0.0")] + fn to_owned(&self) -> Self::Owned; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for T where T: Clone { + type Owned = T; + fn to_owned(&self) -> T { self.clone() } +} + +/// A clone-on-write smart pointer. +/// +/// The type `Cow` is a smart pointer providing clone-on-write functionality: it +/// can enclose and provide immutable access to borrowed data, and clone the +/// data lazily when mutation or ownership is required. The type is designed to +/// work with general borrowed data via the `Borrow` trait. +/// +/// `Cow` implements both `Deref`, which means that you can call +/// non-mutating methods directly on the data it encloses. If mutation +/// is desired, `to_mut` will obtain a mutable references to an owned +/// value, cloning if necessary. +/// +/// # Example +/// +/// ```rust +/// use std::borrow::Cow; +/// +/// fn abs_all(input: &mut Cow<[int]>) { +/// for i in 0..input.len() { +/// let v = input[i]; +/// if v < 0 { +/// // clones into a vector the first time (if not already owned) +/// input.to_mut()[i] = -v; +/// } +/// } +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned { + /// Borrowed data. + #[stable(feature = "rust1", since = "1.0.0")] + Borrowed(&'a B), + + /// Owned data. + #[stable(feature = "rust1", since = "1.0.0")] + Owned(::Owned) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned { + fn clone(&self) -> Cow<'a, B> { + match *self { + Borrowed(b) => Borrowed(b), + Owned(ref o) => { + let b: &B = o.borrow(); + Owned(b.to_owned()) + }, + } + } +} + +impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned, ::Owned: 'a { + /// Acquire a mutable reference to the owned form of the data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn to_mut(&mut self) -> &mut ::Owned where ::Owned: 'a { + match *self { + Borrowed(borrowed) => { + *self = Owned(borrowed.to_owned()); + self.to_mut() + } + Owned(ref mut owned) => owned + } + } + + /// Extract the owned data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_owned(self) -> ::Owned { + match self { + Borrowed(borrowed) => borrowed.to_owned(), + Owned(owned) => owned + } + } + + /// Returns true if this `Cow` wraps a borrowed value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + _ => false, + } + } + + /// Returns true if this `Cow` wraps an owned value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_owned(&self) -> bool { + match *self { + Owned(_) => true, + _ => false, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Deref for Cow<'a, B> where + B: ToOwned, ::Owned: 'a +{ + type Target = B; + + fn deref(&self) -> &B { + match *self { + Borrowed(borrowed) => borrowed, + Owned(ref owned) => owned.borrow() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned, ::Owned: 'a {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Ord for Cow<'a, B> where + B: Ord + ToOwned, ::Owned: 'a +{ + #[inline] + fn cmp(&self, other: &Cow<'a, B>) -> Ordering { + Ord::cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, B> where + B: PartialEq + ToOwned, C: ToOwned, + ::Owned: 'a, ::Owned: 'b, +{ + #[inline] + fn eq(&self, other: &Cow<'b, C>) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where + B: PartialOrd + ToOwned, ::Owned: 'a +{ + #[inline] + fn partial_cmp(&self, other: &Cow<'a, B>) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where + B: fmt::Debug + ToOwned, + ::Owned: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Debug::fmt(b, f), + Owned(ref o) => fmt::Debug::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where + B: fmt::Display + ToOwned, + ::Owned: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Display::fmt(b, f), + Owned(ref o) => fmt::Display::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized, S: Hasher> Hash for Cow<'a, B> where + B: Hash + ToOwned, ::Owned: 'a +{ + #[inline] + fn hash(&self, state: &mut S) { + Hash::hash(&**self, state) + } +} + +/// Trait for moving into a `Cow` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { + /// Moves `self` into `Cow` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_cow(self) -> Cow<'a, B>; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { + fn into_cow(self) -> Cow<'a, B> { + self + } +} diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 747211e923859..7823f536c7a21 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -19,7 +19,6 @@ use self::Entry::*; use core::prelude::*; -use core::borrow::BorrowFrom; use core::cmp::Ordering; use core::default::Default; use core::fmt::Debug; @@ -29,7 +28,8 @@ use core::ops::{Index, IndexMut}; use core::{iter, fmt, mem}; use Bound::{self, Included, Excluded, Unbounded}; -use ring_buf::RingBuf; +use borrow::Borrow; +use vec_deque::VecDeque; use self::Continuation::{Continue, Finished}; use self::StackOp::*; @@ -75,7 +75,7 @@ pub struct BTreeMap { /// An abstract base over-which all other BTree iterators are built. struct AbsIter { - traversals: RingBuf, + traversals: VecDeque, size: usize, } @@ -208,7 +208,7 @@ impl BTreeMap { /// assert_eq!(map.get(&2), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn get(&self, key: &Q) -> Option<&V> where Q: BorrowFrom + Ord { + pub fn get(&self, key: &Q) -> Option<&V> where K: Borrow, Q: Ord { let mut cur_node = &self.root; loop { match Node::search(cur_node, key) { @@ -240,7 +240,7 @@ impl BTreeMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn contains_key(&self, key: &Q) -> bool where Q: BorrowFrom + Ord { + pub fn contains_key(&self, key: &Q) -> bool where K: Borrow, Q: Ord { self.get(key).is_some() } @@ -264,7 +264,7 @@ impl BTreeMap { /// ``` // See `get` for implementation notes, this is basically a copy-paste with mut's added #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom + Ord { + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where K: Borrow, Q: Ord { // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration let mut temp_node = &mut self.root; loop { @@ -434,7 +434,7 @@ impl BTreeMap { /// assert_eq!(map.remove(&1), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn remove(&mut self, key: &Q) -> Option where Q: BorrowFrom + Ord { + pub fn remove(&mut self, key: &Q) -> Option where K: Borrow, Q: Ord { // See `swap` for a more thorough description of the stuff going on in here let mut stack = stack::PartialSearchStack::new(self); loop { @@ -512,13 +512,22 @@ mod stack { use super::super::node::handle; use vec::Vec; + struct InvariantLifetime<'id>( + marker::PhantomData<::core::cell::Cell<&'id ()>>); + + impl<'id> InvariantLifetime<'id> { + fn new() -> InvariantLifetime<'id> { + InvariantLifetime(marker::PhantomData) + } + } + /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime /// parameter is invariant. This means that wherever an `IdRef` is expected, only an `IdRef` /// with the exact requested lifetime can be used. This is in contrast to normal references, /// where `&'static` can be used in any function expecting any lifetime reference. pub struct IdRef<'id, T: 'id> { inner: &'id mut T, - marker: marker::InvariantLifetime<'id> + _marker: InvariantLifetime<'id>, } impl<'id, T> Deref for IdRef<'id, T> { @@ -560,7 +569,7 @@ mod stack { pub struct Pusher<'id, 'a, K:'a, V:'a> { map: &'a mut BTreeMap, stack: Stack, - marker: marker::InvariantLifetime<'id> + _marker: InvariantLifetime<'id>, } impl<'a, K, V> PartialSearchStack<'a, K, V> { @@ -595,11 +604,11 @@ mod stack { let pusher = Pusher { map: self.map, stack: self.stack, - marker: marker::InvariantLifetime + _marker: InvariantLifetime::new(), }; let node = IdRef { inner: unsafe { &mut *self.next }, - marker: marker::InvariantLifetime + _marker: InvariantLifetime::new(), }; closure(pusher, node) @@ -826,7 +835,7 @@ mod stack { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(K, V)> for BTreeMap { - fn from_iter>(iter: T) -> BTreeMap { + fn from_iter>(iter: T) -> BTreeMap { let mut map = BTreeMap::new(); map.extend(iter); map @@ -836,13 +845,14 @@ impl FromIterator<(K, V)> for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Extend<(K, V)> for BTreeMap { #[inline] - fn extend>(&mut self, iter: T) { + fn extend>(&mut self, iter: T) { for (k, v) in iter { self.insert(k, v); } } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl, V: Hash> Hash for BTreeMap { fn hash(&self, state: &mut S) { @@ -851,6 +861,15 @@ impl, V: Hash> Hash for BTreeMap { } } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for BTreeMap { + fn hash(&self, state: &mut H) { + for elt in self { + elt.hash(state); + } + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Default for BTreeMap { @@ -903,7 +922,7 @@ impl Debug for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Index for BTreeMap - where Q: BorrowFrom + Ord + where K: Borrow, Q: Ord { type Output = V; @@ -914,7 +933,7 @@ impl Index for BTreeMap #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for BTreeMap - where Q: BorrowFrom + Ord + where K: Borrow, Q: Ord { fn index_mut(&mut self, key: &Q) -> &mut V { self.get_mut(key).expect("no entry found for key") @@ -1189,7 +1208,7 @@ impl BTreeMap { pub fn iter(&self) -> Iter { let len = self.len(); // NB. The initial capacity for ringbuf is large enough to avoid reallocs in many cases. - let mut lca = RingBuf::new(); + let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(&self.root)); Iter { inner: AbsIter { @@ -1221,7 +1240,7 @@ impl BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] pub fn iter_mut(&mut self) -> IterMut { let len = self.len(); - let mut lca = RingBuf::new(); + let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(&mut self.root)); IterMut { inner: AbsIter { @@ -1250,7 +1269,7 @@ impl BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] pub fn into_iter(self) -> IntoIter { let len = self.len(); - let mut lca = RingBuf::new(); + let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(self.root)); IntoIter { inner: AbsIter { @@ -1342,7 +1361,7 @@ macro_rules! range_impl { // A deque that encodes two search paths containing (left-to-right): // a series of truncated-from-the-left iterators, the LCA's doubly-truncated iterator, // and a series of truncated-from-the-right iterators. - let mut traversals = RingBuf::new(); + let mut traversals = VecDeque::new(); let (root, min, max) = ($root, $min, $max); let mut leftmost = None; diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 24523d4dcc9d3..f0fc12da7275e 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -18,13 +18,15 @@ pub use self::TraversalItem::*; use core::prelude::*; -use core::borrow::BorrowFrom; use core::cmp::Ordering::{Greater, Less, Equal}; use core::iter::Zip; +use core::marker::PhantomData; use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; use core::{slice, mem, ptr, cmp, num, raw}; -use alloc::heap; +use alloc::heap::{self, EMPTY}; + +use borrow::Borrow; /// Represents the result of an Insertion: either the item fit, or the node had to split pub enum InsertionResult { @@ -57,8 +59,8 @@ pub struct Node { keys: Unique, vals: Unique, - // In leaf nodes, this will be null, and no space will be allocated for edges. - edges: Unique>, + // In leaf nodes, this will be None, and no space will be allocated for edges. + edges: Option>>, // At any given time, there will be `_len` keys, `_len` values, and (in an internal node) // `_len + 1` edges. In a leaf node, there will never be any edges. @@ -278,8 +280,11 @@ impl Drop for RawItems { #[unsafe_destructor] impl Drop for Node { fn drop(&mut self) { - if self.keys.ptr.is_null() { - // We have already cleaned up this node. + if self.keys.is_null() { + // Since we have #[unsafe_no_drop_flag], we have to watch + // out for a null value being stored in self.keys. (Using + // null is technically a violation of the `Unique` + // requirements, though.) return; } @@ -292,7 +297,7 @@ impl Drop for Node { self.destroy(); } - self.keys.ptr = ptr::null_mut(); + self.keys = unsafe { Unique::new(0 as *mut K) }; } } @@ -308,9 +313,9 @@ impl Node { let (vals_offset, edges_offset) = calculate_offsets_generic::(capacity, false); Node { - keys: Unique(buffer as *mut K), - vals: Unique(buffer.offset(vals_offset as isize) as *mut V), - edges: Unique(buffer.offset(edges_offset as isize) as *mut Node), + keys: Unique::new(buffer as *mut K), + vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V), + edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node)), _len: 0, _capacity: capacity, } @@ -326,9 +331,9 @@ impl Node { let (vals_offset, _) = calculate_offsets_generic::(capacity, true); Node { - keys: Unique(buffer as *mut K), - vals: Unique(unsafe { buffer.offset(vals_offset as isize) as *mut V }), - edges: Unique(ptr::null_mut()), + keys: unsafe { Unique::new(buffer as *mut K) }, + vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) }, + edges: None, _len: 0, _capacity: capacity, } @@ -337,18 +342,18 @@ impl Node { unsafe fn destroy(&mut self) { let (alignment, size) = calculate_allocation_generic::(self.capacity(), self.is_leaf()); - heap::deallocate(self.keys.ptr as *mut u8, size, alignment); + heap::deallocate(*self.keys as *mut u8, size, alignment); } #[inline] pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) { unsafe {( mem::transmute(raw::Slice { - data: self.keys.ptr, + data: *self.keys as *const K, len: self.len() }), mem::transmute(raw::Slice { - data: self.vals.ptr, + data: *self.vals as *const V, len: self.len() }) )} @@ -367,8 +372,12 @@ impl Node { &[] } else { unsafe { + let data = match self.edges { + None => heap::EMPTY as *const Node, + Some(ref p) => **p as *const Node, + }; mem::transmute(raw::Slice { - data: self.edges.ptr, + data: data, len: self.len() + 1 }) } @@ -524,7 +533,8 @@ impl Clone for Node { #[derive(Copy)] pub struct Handle { node: NodeRef, - index: usize + index: usize, + marker: PhantomData<(Type, NodeType)>, } pub mod handle { @@ -543,13 +553,13 @@ impl Node { /// `Found` will be yielded with the matching index. If it doesn't find an exact match, /// `GoDown` will be yielded with the index of the subtree the key must lie in. pub fn search>>(node: NodeRef, key: &Q) - -> SearchResult where Q: BorrowFrom + Ord { + -> SearchResult where K: Borrow, Q: Ord { // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V). // For the B configured as of this writing (B = 6), binary search was *significantly* // worse for usizes. match node.as_slices_internal().search_linear(key) { - (index, true) => Found(Handle { node: node, index: index }), - (index, false) => GoDown(Handle { node: node, index: index }), + (index, true) => Found(Handle { node: node, index: index, marker: PhantomData }), + (index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }), } } } @@ -586,7 +596,7 @@ impl Node { /// If the node has any children pub fn is_leaf(&self) -> bool { - self.edges.ptr.is_null() + self.edges.is_none() } /// if the node has too few elements @@ -618,7 +628,8 @@ impl Handle where pub fn as_raw(&mut self) -> Handle<*mut Node, Type, NodeType> { Handle { node: &mut *self.node as *mut _, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -630,7 +641,8 @@ impl Handle<*mut Node, Type, NodeType> { pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node, Type, NodeType> { Handle { node: &*self.node, - index: self.index + index: self.index, + marker: PhantomData, } } @@ -640,7 +652,8 @@ impl Handle<*mut Node, Type, NodeType> { pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node, Type, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -688,12 +701,14 @@ impl>, Type> Handle Handle where unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node, handle::KV, NodeType> { Handle { node: &mut *self.node, - index: self.index - 1 + index: self.index - 1, + marker: PhantomData, } } @@ -836,7 +852,8 @@ impl Handle where unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node, handle::KV, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -876,7 +893,8 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node, handle::KV, NodeType pub fn into_left_edge(self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -926,7 +944,8 @@ impl Handle where pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } @@ -935,7 +954,8 @@ impl Handle where pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, - index: self.index + 1 + index: self.index + 1, + marker: PhantomData, } } } @@ -1044,7 +1064,8 @@ impl Node { debug_assert!(index < self.len(), "kv_handle index out of bounds"); Handle { node: self, - index: index + index: index, + marker: PhantomData, } } @@ -1064,7 +1085,7 @@ impl Node { vals: RawItems::from_slice(self.vals()), edges: RawItems::from_slice(self.edges()), - ptr: self.keys.ptr as *mut u8, + ptr: *self.keys as *mut u8, capacity: self.capacity(), is_leaf: self.is_leaf() }, @@ -1491,9 +1512,9 @@ macro_rules! node_slice_impl { impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> { /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match). fn search_linear(&self, key: &Q) -> (usize, bool) - where Q: BorrowFrom + Ord { + where K: Borrow, Q: Ord { for (i, k) in self.keys.iter().enumerate() { - match key.cmp(BorrowFrom::borrow_from(k)) { + match key.cmp(k.borrow()) { Greater => {}, Equal => return (i, true), Less => return (i, false), diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 7ef887b70cc6c..929b2f5804303 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -13,7 +13,6 @@ use core::prelude::*; -use core::borrow::BorrowFrom; use core::cmp::Ordering::{self, Less, Greater, Equal}; use core::default::Default; use core::fmt::Debug; @@ -21,6 +20,7 @@ use core::fmt; use core::iter::{Peekable, Map, FromIterator, IntoIterator}; use core::ops::{BitOr, BitAnd, BitXor, Sub}; +use borrow::Borrow; use btree_map::{BTreeMap, Keys}; use Bound; @@ -336,7 +336,7 @@ impl BTreeSet { /// assert_eq!(set.contains(&4), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn contains(&self, value: &Q) -> bool where Q: BorrowFrom + Ord { + pub fn contains(&self, value: &Q) -> bool where T: Borrow, Q: Ord { self.map.contains_key(value) } @@ -466,14 +466,14 @@ impl BTreeSet { /// assert_eq!(set.remove(&2), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn remove(&mut self, value: &Q) -> bool where Q: BorrowFrom + Ord { + pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, Q: Ord { self.map.remove(value).is_some() } } #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BTreeSet { - fn from_iter>(iter: Iter) -> BTreeSet { + fn from_iter>(iter: I) -> BTreeSet { let mut set = BTreeSet::new(); set.extend(iter); set @@ -503,7 +503,7 @@ impl<'a, T> IntoIterator for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BTreeSet { #[inline] - fn extend>(&mut self, iter: Iter) { + fn extend>(&mut self, iter: Iter) { for elem in iter { self.insert(elem); } diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index d5403ca5d9b19..0c95742606083 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -14,6 +14,7 @@ //! representation to hold C-like enum variants. use core::prelude::*; +use core::marker; use core::fmt; use core::num::Int; use core::iter::{FromIterator, IntoIterator}; @@ -26,7 +27,8 @@ use core::ops::{Sub, BitOr, BitAnd, BitXor}; pub struct EnumSet { // We must maintain the invariant that no bits are set // for which no variant exists - bits: usize + bits: usize, + marker: marker::PhantomData, } impl Copy for EnumSet {} @@ -86,7 +88,7 @@ impl EnumSet { #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] pub fn new() -> EnumSet { - EnumSet {bits: 0} + EnumSet {bits: 0, marker: marker::PhantomData} } /// Returns the number of elements in the given `EnumSet`. @@ -130,12 +132,14 @@ impl EnumSet { /// Returns the union of both `EnumSets`. pub fn union(&self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits | e.bits} + EnumSet {bits: self.bits | e.bits, + marker: marker::PhantomData} } /// Returns the intersection of both `EnumSets`. pub fn intersection(&self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & e.bits} + EnumSet {bits: self.bits & e.bits, + marker: marker::PhantomData} } /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before @@ -175,7 +179,7 @@ impl Sub for EnumSet { type Output = EnumSet; fn sub(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & !e.bits} + EnumSet {bits: self.bits & !e.bits, marker: marker::PhantomData} } } @@ -183,7 +187,7 @@ impl BitOr for EnumSet { type Output = EnumSet; fn bitor(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits | e.bits} + EnumSet {bits: self.bits | e.bits, marker: marker::PhantomData} } } @@ -191,7 +195,7 @@ impl BitAnd for EnumSet { type Output = EnumSet; fn bitand(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & e.bits} + EnumSet {bits: self.bits & e.bits, marker: marker::PhantomData} } } @@ -199,7 +203,7 @@ impl BitXor for EnumSet { type Output = EnumSet; fn bitxor(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits ^ e.bits} + EnumSet {bits: self.bits ^ e.bits, marker: marker::PhantomData} } } @@ -207,6 +211,7 @@ impl BitXor for EnumSet { pub struct Iter { index: usize, bits: usize, + marker: marker::PhantomData, } // FIXME(#19839) Remove in favor of `#[derive(Clone)]` @@ -215,13 +220,14 @@ impl Clone for Iter { Iter { index: self.index, bits: self.bits, + marker: marker::PhantomData, } } } impl Iter { fn new(bits: usize) -> Iter { - Iter { index: 0, bits: bits } + Iter { index: 0, bits: bits, marker: marker::PhantomData } } } @@ -250,9 +256,9 @@ impl Iterator for Iter { } impl FromIterator for EnumSet { - fn from_iter>(iterator: I) -> EnumSet { + fn from_iter>(iter: I) -> EnumSet { let mut ret = EnumSet::new(); - ret.extend(iterator); + ret.extend(iter); ret } } @@ -268,8 +274,8 @@ impl<'a, E> IntoIterator for &'a EnumSet where E: CLike { } impl Extend for EnumSet { - fn extend>(&mut self, iterator: I) { - for element in iterator { + fn extend>(&mut self, iter: I) { + for element in iter { self.insert(element); } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cacbf3bce80f0..6569ab9c05acd 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -26,7 +26,6 @@ #![feature(box_syntax)] #![feature(box_patterns)] #![feature(core)] -#![feature(hash)] #![feature(staged_api)] #![feature(unboxed_closures)] #![feature(unicode)] @@ -49,17 +48,33 @@ extern crate alloc; #[cfg(test)] #[macro_use] extern crate log; pub use binary_heap::BinaryHeap; -pub use bitv::Bitv; -pub use bitv_set::BitvSet; +pub use bit_vec::BitVec; +pub use bit_set::BitSet; pub use btree_map::BTreeMap; pub use btree_set::BTreeSet; -pub use dlist::DList; +pub use linked_list::LinkedList; pub use enum_set::EnumSet; -pub use ring_buf::RingBuf; +pub use vec_deque::VecDeque; pub use string::String; pub use vec::Vec; pub use vec_map::VecMap; +#[deprecated(since = "1.0.0", reason = "renamed to vec_deque")] +#[unstable(feature = "collections")] +pub use vec_deque as ring_buf; + +#[deprecated(since = "1.0.0", reason = "renamed to linked_list")] +#[unstable(feature = "collections")] +pub use linked_list as dlist; + +#[deprecated(since = "1.0.0", reason = "renamed to bit_vec")] +#[unstable(feature = "collections")] +pub use bit_vec as bitv; + +#[deprecated(since = "1.0.0", reason = "renamed to bit_set")] +#[unstable(feature = "collections")] +pub use bit_set as bitv_set; + // Needed for the vec! macro pub use alloc::boxed; @@ -71,27 +86,42 @@ mod macros; pub mod binary_heap; mod bit; mod btree; -pub mod dlist; +pub mod linked_list; pub mod enum_set; pub mod fmt; -pub mod ring_buf; +pub mod vec_deque; pub mod slice; pub mod str; pub mod string; pub mod vec; pub mod vec_map; +#[cfg(stage0)] +#[path = "borrow_stage0.rs"] +pub mod borrow; + +#[cfg(not(stage0))] +pub mod borrow; + #[unstable(feature = "collections", reason = "RFC 509")] -pub mod bitv { - pub use bit::{Bitv, Iter}; +pub mod bit_vec { + pub use bit::{BitVec, Iter}; + + #[deprecated(since = "1.0.0", reason = "renamed to BitVec")] + #[unstable(feature = "collections")] + pub use bit::BitVec as Bitv; } #[unstable(feature = "collections", reason = "RFC 509")] -pub mod bitv_set { - pub use bit::{BitvSet, Union, Intersection, Difference, SymmetricDifference}; +pub mod bit_set { + pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference}; pub use bit::SetIter as Iter; + + #[deprecated(since = "1.0.0", reason = "renamed to BitSet")] + #[unstable(feature = "collections")] + pub use bit::BitSet as BitvSet; } #[stable(feature = "rust1", since = "1.0.0")] @@ -117,7 +147,6 @@ mod std { #[cfg(test)] mod prelude { // from core. - pub use core::borrow::IntoCow; pub use core::clone::Clone; pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord}; pub use core::cmp::Ordering::{Less, Equal, Greater}; @@ -143,6 +172,7 @@ mod prelude { pub use unicode::char::CharExt; // from collections. + pub use borrow::IntoCow; pub use slice::SliceConcatExt; pub use string::{String, ToString}; pub use vec::Vec; diff --git a/src/libcollections/dlist.rs b/src/libcollections/linked_list.rs similarity index 85% rename from src/libcollections/dlist.rs rename to src/libcollections/linked_list.rs index eb1bf93c0aafc..c142819a51896 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/linked_list.rs @@ -10,13 +10,13 @@ //! A doubly-linked list with owned nodes. //! -//! The `DList` allows pushing and popping elements at either end and is thus +//! The `LinkedList` allows pushing and popping elements at either end and is thus //! efficiently usable as a double-ended queue. -// DList is constructed like a singly-linked list over the field `next`. +// LinkedList is constructed like a singly-linked list over the field `next`. // including the last link being None; each Node owns its `next` field. // -// Backlinks over DList::prev are raw pointers that form a full chain in +// Backlinks over LinkedList::prev are raw pointers that form a full chain in // the reverse direction. #![stable(feature = "rust1", since = "1.0.0")] @@ -27,14 +27,20 @@ use alloc::boxed::Box; use core::cmp::Ordering; use core::default::Default; use core::fmt; -use core::hash::{Writer, Hasher, Hash}; +use core::hash::{Hasher, Hash}; +#[cfg(stage0)] +use core::hash::Writer; use core::iter::{self, FromIterator, IntoIterator}; use core::mem; use core::ptr; +#[deprecated(since = "1.0.0", reason = "renamed to LinkedList")] +#[unstable(feature = "collections")] +pub use LinkedList as DList; + /// A doubly-linked list. #[stable(feature = "rust1", since = "1.0.0")] -pub struct DList { +pub struct LinkedList { length: usize, list_head: Link, list_tail: Rawlink>, @@ -56,7 +62,7 @@ struct Node { value: T, } -/// An iterator over references to the items of a `DList`. +/// An iterator over references to the items of a `LinkedList`. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T:'a> { head: &'a Link, @@ -76,20 +82,20 @@ impl<'a, T> Clone for Iter<'a, T> { } } -/// An iterator over mutable references to the items of a `DList`. +/// An iterator over mutable references to the items of a `LinkedList`. #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T:'a> { - list: &'a mut DList, + list: &'a mut LinkedList, head: Rawlink>, tail: Rawlink>, nelem: usize, } -/// An iterator over mutable references to the items of a `DList`. +/// An iterator over mutable references to the items of a `LinkedList`. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - list: DList + list: LinkedList } /// Rawlink is a type like Option but for holding a raw pointer @@ -147,7 +153,7 @@ fn link_with_prev(mut next: Box>, prev: Rawlink>) } // private methods -impl DList { +impl LinkedList { /// Add a Node first in the list #[inline] fn push_front_node(&mut self, mut new_head: Box>) { @@ -207,18 +213,18 @@ impl DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for DList { +impl Default for LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn default() -> DList { DList::new() } + fn default() -> LinkedList { LinkedList::new() } } -impl DList { - /// Creates an empty `DList`. +impl LinkedList { + /// Creates an empty `LinkedList`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> DList { - DList{list_head: None, list_tail: Rawlink::none(), length: 0} + pub fn new() -> LinkedList { + LinkedList{list_head: None, list_tail: Rawlink::none(), length: 0} } /// Moves all elements from `other` to the end of the list. @@ -231,10 +237,10 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut a = DList::new(); - /// let mut b = DList::new(); + /// let mut a = LinkedList::new(); + /// let mut b = LinkedList::new(); /// a.push_back(1); /// a.push_back(2); /// b.push_back(3); @@ -247,7 +253,7 @@ impl DList { /// } /// println!("{}", b.len()); // prints 0 /// ``` - pub fn append(&mut self, other: &mut DList) { + pub fn append(&mut self, other: &mut LinkedList) { match self.list_tail.resolve() { None => { self.length = other.length; @@ -301,16 +307,16 @@ impl DList { IntoIter{list: self} } - /// Returns `true` if the `DList` is empty. + /// Returns `true` if the `LinkedList` is empty. /// /// This operation should compute in O(1) time. /// /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert!(dl.is_empty()); /// /// dl.push_front("foo"); @@ -322,16 +328,16 @@ impl DList { self.list_head.is_none() } - /// Returns the length of the `DList`. + /// Returns the length of the `LinkedList`. /// /// This operation should compute in O(1) time. /// /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// /// dl.push_front(2); /// assert_eq!(dl.len(), 1); @@ -349,16 +355,16 @@ impl DList { self.length } - /// Removes all elements from the `DList`. + /// Removes all elements from the `LinkedList`. /// /// This operation should compute in O(n) time. /// /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// /// dl.push_front(2); /// dl.push_front(1); @@ -373,7 +379,7 @@ impl DList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - *self = DList::new() + *self = LinkedList::new() } /// Provides a reference to the front element, or `None` if the list is @@ -382,9 +388,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.front(), None); /// /// dl.push_front(1); @@ -403,9 +409,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.front(), None); /// /// dl.push_front(1); @@ -430,9 +436,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.back(), None); /// /// dl.push_back(1); @@ -451,9 +457,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.back(), None); /// /// dl.push_back(1); @@ -479,9 +485,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// /// dl.push_front(2); /// assert_eq!(dl.front().unwrap(), &2); @@ -503,9 +509,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// assert_eq!(d.pop_front(), None); /// /// d.push_front(1); @@ -526,9 +532,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// d.push_back(1); /// d.push_back(3); /// assert_eq!(3, *d.back().unwrap()); @@ -544,9 +550,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// assert_eq!(d.pop_back(), None); /// d.push_back(1); /// d.push_back(3); @@ -569,9 +575,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// /// d.push_front(1); /// d.push_front(2); @@ -583,13 +589,13 @@ impl DList { /// assert_eq!(splitted.pop_front(), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn split_off(&mut self, at: usize) -> DList { + pub fn split_off(&mut self, at: usize) -> LinkedList { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::replace(self, DList::new()); + return mem::replace(self, LinkedList::new()); } else if at == len { - return DList::new(); + return LinkedList::new(); } // Below, we iterate towards the `i-1`th node, either from the start or the end, @@ -612,7 +618,7 @@ impl DList { iter.tail }; - let mut splitted_list = DList { + let mut splitted_list = LinkedList { list_head: None, list_tail: self.list_tail, length: len - at @@ -628,9 +634,9 @@ impl DList { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for DList { +impl Drop for LinkedList { fn drop(&mut self) { - // Dissolve the dlist in backwards direction + // Dissolve the linked_list in backwards direction // Just dropping the list_head can lead to stack exhaustion // when length is >> 1_000_000 let mut tail = self.list_tail; @@ -761,9 +767,9 @@ impl<'a, A> IterMut<'a, A> { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut list: DList<_> = vec![1, 3, 4].into_iter().collect(); + /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect(); /// /// { /// let mut it = list.iter_mut(); @@ -788,9 +794,9 @@ impl<'a, A> IterMut<'a, A> { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut list: DList<_> = vec![1, 2, 3].into_iter().collect(); + /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect(); /// /// let mut it = list.iter_mut(); /// assert_eq!(it.next().unwrap(), &1); @@ -829,16 +835,16 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for DList { - fn from_iter>(iterator: T) -> DList { +impl FromIterator for LinkedList { + fn from_iter>(iter: T) -> LinkedList { let mut ret = DList::new(); - ret.extend(iterator); + ret.extend(iter); ret } } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for DList { +impl IntoIterator for LinkedList { type Item = T; type IntoIter = IntoIter; @@ -848,7 +854,7 @@ impl IntoIterator for DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a DList { +impl<'a, T> IntoIterator for &'a LinkedList { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -857,7 +863,7 @@ impl<'a, T> IntoIterator for &'a DList { } } -impl<'a, T> IntoIterator for &'a mut DList { +impl<'a, T> IntoIterator for &'a mut LinkedList { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -867,54 +873,54 @@ impl<'a, T> IntoIterator for &'a mut DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for DList { - fn extend>(&mut self, iterator: T) { - for elt in iterator { self.push_back(elt); } +impl Extend for LinkedList { + fn extend>(&mut self, iter: T) { + for elt in iter { self.push_back(elt); } } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for DList { - fn eq(&self, other: &DList) -> bool { +impl PartialEq for LinkedList { + fn eq(&self, other: &LinkedList) -> bool { self.len() == other.len() && iter::order::eq(self.iter(), other.iter()) } - fn ne(&self, other: &DList) -> bool { + fn ne(&self, other: &LinkedList) -> bool { self.len() != other.len() || iter::order::ne(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for DList {} +impl Eq for LinkedList {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for DList { - fn partial_cmp(&self, other: &DList) -> Option { +impl PartialOrd for LinkedList { + fn partial_cmp(&self, other: &LinkedList) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for DList { +impl Ord for LinkedList { #[inline] - fn cmp(&self, other: &DList) -> Ordering { + fn cmp(&self, other: &LinkedList) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for DList { - fn clone(&self) -> DList { - self.iter().map(|x| x.clone()).collect() +impl Clone for LinkedList { + fn clone(&self) -> LinkedList { + self.iter().cloned().collect() } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for DList { +impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "DList [")); + try!(write!(f, "LinkedList [")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -926,7 +932,8 @@ impl fmt::Debug for DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl> Hash for DList { +#[cfg(stage0)] +impl> Hash for LinkedList { fn hash(&self, state: &mut S) { self.len().hash(state); for elt in self { @@ -934,6 +941,16 @@ impl> Hash for DList { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for LinkedList { + fn hash(&self, state: &mut H) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } + } +} #[cfg(test)] mod tests { @@ -944,9 +961,9 @@ mod tests { use test::Bencher; use test; - use super::{DList, Node}; + use super::{LinkedList, Node}; - pub fn check_links(list: &DList) { + pub fn check_links(list: &LinkedList) { let mut len = 0; let mut last_ptr: Option<&Node> = None; let mut node_ptr: &Node; @@ -980,7 +997,7 @@ mod tests { #[test] fn test_basic() { - let mut m = DList::new(); + let mut m = LinkedList::new(); assert_eq!(m.pop_front(), None); assert_eq!(m.pop_back(), None); assert_eq!(m.pop_front(), None); @@ -999,7 +1016,7 @@ mod tests { m.push_back(box 7); assert_eq!(m.pop_front(), Some(box 1)); - let mut n = DList::new(); + let mut n = LinkedList::new(); n.push_front(2); n.push_front(3); { @@ -1019,21 +1036,21 @@ mod tests { } #[cfg(test)] - fn generate_test() -> DList { + fn generate_test() -> LinkedList { list_from(&[0,1,2,3,4,5,6]) } #[cfg(test)] - fn list_from(v: &[T]) -> DList { - v.iter().map(|x| (*x).clone()).collect() + fn list_from(v: &[T]) -> LinkedList { + v.iter().cloned().collect() } #[test] fn test_append() { // Empty to empty { - let mut m = DList::::new(); - let mut n = DList::new(); + let mut m = LinkedList::::new(); + let mut n = LinkedList::new(); m.append(&mut n); check_links(&m); assert_eq!(m.len(), 0); @@ -1041,8 +1058,8 @@ mod tests { } // Non-empty to empty { - let mut m = DList::new(); - let mut n = DList::new(); + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); n.push_back(2); m.append(&mut n); check_links(&m); @@ -1053,8 +1070,8 @@ mod tests { } // Empty to non-empty { - let mut m = DList::new(); - let mut n = DList::new(); + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); m.push_back(2); m.append(&mut n); check_links(&m); @@ -1089,7 +1106,7 @@ mod tests { fn test_split_off() { // singleton { - let mut m = DList::new(); + let mut m = LinkedList::new(); m.push_back(1); let p = m.split_off(0); @@ -1130,7 +1147,7 @@ mod tests { // no-op on the last index { - let mut m = DList::new(); + let mut m = LinkedList::new(); m.push_back(1); let p = m.split_off(1); @@ -1148,7 +1165,7 @@ mod tests { for (i, elt) in m.iter().enumerate() { assert_eq!(i as i32, *elt); } - let mut n = DList::new(); + let mut n = LinkedList::new(); assert_eq!(n.iter().next(), None); n.push_front(4); let mut it = n.iter(); @@ -1160,7 +1177,7 @@ mod tests { #[test] fn test_iterator_clone() { - let mut n = DList::new(); + let mut n = LinkedList::new(); n.push_back(2); n.push_back(3); n.push_back(4); @@ -1174,7 +1191,7 @@ mod tests { #[test] fn test_iterator_double_end() { - let mut n = DList::new(); + let mut n = LinkedList::new(); assert_eq!(n.iter().next(), None); n.push_front(4); n.push_front(5); @@ -1196,7 +1213,7 @@ mod tests { for (i, elt) in m.iter().rev().enumerate() { assert_eq!((6 - i) as i32, *elt); } - let mut n = DList::new(); + let mut n = LinkedList::new(); assert_eq!(n.iter().rev().next(), None); n.push_front(4); let mut it = n.iter().rev(); @@ -1215,7 +1232,7 @@ mod tests { len -= 1; } assert_eq!(len, 0); - let mut n = DList::new(); + let mut n = LinkedList::new(); assert!(n.iter_mut().next().is_none()); n.push_front(4); n.push_back(5); @@ -1229,7 +1246,7 @@ mod tests { #[test] fn test_iterator_mut_double_end() { - let mut n = DList::new(); + let mut n = LinkedList::new(); assert!(n.iter_mut().next_back().is_none()); n.push_front(4); n.push_front(5); @@ -1278,7 +1295,7 @@ mod tests { for (i, elt) in m.iter_mut().rev().enumerate() { assert_eq!((6 - i) as i32, *elt); } - let mut n = DList::new(); + let mut n = LinkedList::new(); assert!(n.iter_mut().rev().next().is_none()); n.push_front(4); let mut it = n.iter_mut().rev(); @@ -1313,8 +1330,8 @@ mod tests { #[test] fn test_hash() { - let mut x = DList::new(); - let mut y = DList::new(); + let mut x = LinkedList::new(); + let mut y = LinkedList::new(); assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y)); @@ -1382,16 +1399,16 @@ mod tests { #[test] fn test_show() { - let list: DList<_> = (0..10).collect(); - assert_eq!(format!("{:?}", list), "DList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + let list: LinkedList<_> = (0..10).collect(); + assert_eq!(format!("{:?}", list), "LinkedList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); - let list: DList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect(); - assert_eq!(format!("{:?}", list), "DList [\"just\", \"one\", \"test\", \"more\"]"); + let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect(); + assert_eq!(format!("{:?}", list), "LinkedList [\"just\", \"one\", \"test\", \"more\"]"); } #[cfg(test)] fn fuzz_test(sz: i32) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); let mut v = vec![]; for i in 0..sz { check_links(&m); @@ -1432,13 +1449,13 @@ mod tests { fn bench_collect_into(b: &mut test::Bencher) { let v = &[0; 64]; b.iter(|| { - let _: DList<_> = v.iter().cloned().collect(); + let _: LinkedList<_> = v.iter().cloned().collect(); }) } #[bench] fn bench_push_front(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_front(0); }) @@ -1446,7 +1463,7 @@ mod tests { #[bench] fn bench_push_back(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_back(0); }) @@ -1454,7 +1471,7 @@ mod tests { #[bench] fn bench_push_back_pop_back(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_back(0); m.pop_back(); @@ -1463,7 +1480,7 @@ mod tests { #[bench] fn bench_push_front_pop_front(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_front(0); m.pop_front(); @@ -1473,7 +1490,7 @@ mod tests { #[bench] fn bench_iter(b: &mut test::Bencher) { let v = &[0; 128]; - let m: DList<_> = v.iter().cloned().collect(); + let m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter().count() == 128); }) @@ -1481,7 +1498,7 @@ mod tests { #[bench] fn bench_iter_mut(b: &mut test::Bencher) { let v = &[0; 128]; - let mut m: DList<_> = v.iter().cloned().collect(); + let mut m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter_mut().count() == 128); }) @@ -1489,7 +1506,7 @@ mod tests { #[bench] fn bench_iter_rev(b: &mut test::Bencher) { let v = &[0; 128]; - let m: DList<_> = v.iter().cloned().collect(); + let m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter().rev().count() == 128); }) @@ -1497,7 +1514,7 @@ mod tests { #[bench] fn bench_iter_mut_rev(b: &mut test::Bencher) { let v = &[0; 128]; - let mut m: DList<_> = v.iter().cloned().collect(); + let mut m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter_mut().rev().count() == 128); }) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 06ae8127c00fb..776b8b3af147c 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -88,7 +88,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use alloc::boxed::Box; -use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned}; use core::clone::Clone; use core::cmp::Ordering::{self, Greater, Less}; use core::cmp::{self, Ord, PartialEq}; @@ -105,6 +104,7 @@ use core::result::Result; use core::slice as core_slice; use self::Direction::*; +use borrow::{Borrow, BorrowMut, ToOwned}; use vec::Vec; pub use core::slice::{Chunks, AsSlice, Windows}; @@ -1175,18 +1175,19 @@ impl ElementSwaps { // Standard trait implementations for slices //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "collections", reason = "trait is unstable")] -impl BorrowFrom> for [T] { - fn borrow_from(owned: &Vec) -> &[T] { &owned[] } +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow<[T]> for Vec { + fn borrow(&self) -> &[T] { &self[..] } } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl BorrowFromMut> for [T] { - fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { &mut owned[] } +#[stable(feature = "rust1", since = "1.0.0")] +impl BorrowMut<[T]> for Vec { + fn borrow_mut(&mut self) -> &mut [T] { &mut self[..] } } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl ToOwned> for [T] { +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for [T] { + type Owned = Vec; fn to_owned(&self) -> Vec { self.to_vec() } } @@ -1743,7 +1744,7 @@ mod tests { #[test] fn test_slice_from() { let vec: &[_] = &[1, 2, 3, 4]; - assert_eq!(&vec[], vec); + assert_eq!(&vec[..], vec); let b: &[_] = &[3, 4]; assert_eq!(&vec[2..], b); let b: &[_] = &[]; @@ -2264,15 +2265,15 @@ mod tests { #[test] fn test_total_ord() { let c = &[1, 2, 3]; - [1, 2, 3, 4][].cmp(c) == Greater; + [1, 2, 3, 4][..].cmp(c) == Greater; let c = &[1, 2, 3, 4]; - [1, 2, 3][].cmp(c) == Less; + [1, 2, 3][..].cmp(c) == Less; let c = &[1, 2, 3, 6]; - [1, 2, 3, 4][].cmp(c) == Equal; + [1, 2, 3, 4][..].cmp(c) == Equal; let c = &[1, 2, 3, 4, 5, 6]; - [1, 2, 3, 4, 5, 5, 5, 5][].cmp(c) == Less; + [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less; let c = &[1, 2, 3, 4]; - [2, 2][].cmp(c) == Greater; + [2, 2][..].cmp(c) == Greater; } #[test] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 2d4dc2bcf30d3..ec0a487acdc77 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -55,7 +55,6 @@ use self::RecompositionState::*; use self::DecompositionType::*; -use core::borrow::{BorrowFrom, ToOwned}; use core::char::CharExt; use core::clone::Clone; use core::iter::AdditiveIterator; @@ -68,7 +67,8 @@ use core::slice::AsSlice; use core::str as core_str; use unicode::str::{UnicodeStr, Utf16Encoder}; -use ring_buf::RingBuf; +use vec_deque::VecDeque; +use borrow::{Borrow, ToOwned}; use slice::SliceExt; use string::String; use unicode; @@ -261,7 +261,7 @@ enum RecompositionState { pub struct Recompositions<'a> { iter: Decompositions<'a>, state: RecompositionState, - buffer: RingBuf, + buffer: VecDeque, composee: Option, last_ccc: Option } @@ -386,13 +386,14 @@ macro_rules! utf8_acc_cont_byte { ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32) } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl BorrowFrom for str { - fn borrow_from(owned: &String) -> &str { &owned[] } +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for String { + fn borrow(&self) -> &str { &self[..] } } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl ToOwned for str { +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for str { + type Owned = String; fn to_owned(&self) -> String { unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) @@ -466,7 +467,7 @@ pub trait StrExt: Index { reason = "this functionality may be moved to libunicode")] fn nfd_chars(&self) -> Decompositions { Decompositions { - iter: self[].chars(), + iter: self[..].chars(), buffer: Vec::new(), sorted: false, kind: Canonical @@ -480,7 +481,7 @@ pub trait StrExt: Index { reason = "this functionality may be moved to libunicode")] fn nfkd_chars(&self) -> Decompositions { Decompositions { - iter: self[].chars(), + iter: self[..].chars(), buffer: Vec::new(), sorted: false, kind: Compatible @@ -496,7 +497,7 @@ pub trait StrExt: Index { Recompositions { iter: self.nfd_chars(), state: Composing, - buffer: RingBuf::new(), + buffer: VecDeque::new(), composee: None, last_ccc: None } @@ -511,7 +512,7 @@ pub trait StrExt: Index { Recompositions { iter: self.nfkd_chars(), state: Composing, - buffer: RingBuf::new(), + buffer: VecDeque::new(), composee: None, last_ccc: None } @@ -530,7 +531,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn contains(&self, pat: &str) -> bool { - core_str::StrExt::contains(&self[], pat) + core_str::StrExt::contains(&self[..], pat) } /// Returns true if a string contains a char pattern. @@ -547,7 +548,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might get removed in favour of a more generic contains()")] fn contains_char(&self, pat: P) -> bool { - core_str::StrExt::contains_char(&self[], pat) + core_str::StrExt::contains_char(&self[..], pat) } /// An iterator over the characters of `self`. Note, this iterates @@ -561,7 +562,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn chars(&self) -> Chars { - core_str::StrExt::chars(&self[]) + core_str::StrExt::chars(&self[..]) } /// An iterator over the bytes of `self` @@ -574,13 +575,13 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn bytes(&self) -> Bytes { - core_str::StrExt::bytes(&self[]) + core_str::StrExt::bytes(&self[..]) } /// An iterator over the characters of `self` and their byte offsets. #[stable(feature = "rust1", since = "1.0.0")] fn char_indices(&self) -> CharIndices { - core_str::StrExt::char_indices(&self[]) + core_str::StrExt::char_indices(&self[..]) } /// An iterator over substrings of `self`, separated by characters @@ -603,7 +604,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn split(&self, pat: P) -> Split

{ - core_str::StrExt::split(&self[], pat) + core_str::StrExt::split(&self[..], pat) } /// An iterator over substrings of `self`, separated by characters @@ -630,7 +631,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn splitn(&self, count: usize, pat: P) -> SplitN

{ - core_str::StrExt::splitn(&self[], count, pat) + core_str::StrExt::splitn(&self[..], count, pat) } /// An iterator over substrings of `self`, separated by characters @@ -659,7 +660,7 @@ pub trait StrExt: Index { /// ``` #[unstable(feature = "collections", reason = "might get removed")] fn split_terminator(&self, pat: P) -> SplitTerminator

{ - core_str::StrExt::split_terminator(&self[], pat) + core_str::StrExt::split_terminator(&self[..], pat) } /// An iterator over substrings of `self`, separated by characters @@ -680,7 +681,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn rsplitn(&self, count: usize, pat: P) -> RSplitN

{ - core_str::StrExt::rsplitn(&self[], count, pat) + core_str::StrExt::rsplitn(&self[..], count, pat) } /// An iterator over the start and end indices of the disjoint @@ -706,7 +707,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might have its iterator type changed")] fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> { - core_str::StrExt::match_indices(&self[], pat) + core_str::StrExt::match_indices(&self[..], pat) } /// An iterator over the substrings of `self` separated by the pattern `sep`. @@ -723,7 +724,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might get removed in the future in favor of a more generic split()")] fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a> { - core_str::StrExt::split_str(&self[], pat) + core_str::StrExt::split_str(&self[..], pat) } /// An iterator over the lines of a string (subsequences separated @@ -739,7 +740,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines(&self) -> Lines { - core_str::StrExt::lines(&self[]) + core_str::StrExt::lines(&self[..]) } /// An iterator over the lines of a string, separated by either @@ -755,7 +756,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines_any(&self) -> LinesAny { - core_str::StrExt::lines_any(&self[]) + core_str::StrExt::lines_any(&self[..]) } /// Deprecated: use `s[a .. b]` instead. @@ -802,7 +803,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "may have yet to prove its worth")] fn slice_chars(&self, begin: usize, end: usize) -> &str { - core_str::StrExt::slice_chars(&self[], begin, end) + core_str::StrExt::slice_chars(&self[..], begin, end) } /// Takes a bytewise (not UTF-8) slice from a string. @@ -813,7 +814,7 @@ pub trait StrExt: Index { /// the entire slice as well. #[stable(feature = "rust1", since = "1.0.0")] unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str { - core_str::StrExt::slice_unchecked(&self[], begin, end) + core_str::StrExt::slice_unchecked(&self[..], begin, end) } /// Returns true if the pattern `pat` is a prefix of the string. @@ -825,7 +826,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn starts_with(&self, pat: &str) -> bool { - core_str::StrExt::starts_with(&self[], pat) + core_str::StrExt::starts_with(&self[..], pat) } /// Returns true if the pattern `pat` is a suffix of the string. @@ -837,7 +838,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn ends_with(&self, pat: &str) -> bool { - core_str::StrExt::ends_with(&self[], pat) + core_str::StrExt::ends_with(&self[..], pat) } /// Returns a string with all pre- and suffixes that match @@ -857,7 +858,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trim_matches(&self, pat: P) -> &str { - core_str::StrExt::trim_matches(&self[], pat) + core_str::StrExt::trim_matches(&self[..], pat) } /// Returns a string with all prefixes that match @@ -877,7 +878,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trim_left_matches(&self, pat: P) -> &str { - core_str::StrExt::trim_left_matches(&self[], pat) + core_str::StrExt::trim_left_matches(&self[..], pat) } /// Returns a string with all suffixes that match @@ -897,7 +898,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trim_right_matches(&self, pat: P) -> &str { - core_str::StrExt::trim_right_matches(&self[], pat) + core_str::StrExt::trim_right_matches(&self[..], pat) } /// Check that `index`-th byte lies at the start and/or end of a @@ -926,7 +927,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn is_char_boundary(&self, index: usize) -> bool { - core_str::StrExt::is_char_boundary(&self[], index) + core_str::StrExt::is_char_boundary(&self[..], index) } /// Pluck a character out of a string and return the index of the next @@ -985,7 +986,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_range_at(&self, start: usize) -> CharRange { - core_str::StrExt::char_range_at(&self[], start) + core_str::StrExt::char_range_at(&self[..], start) } /// Given a byte position and a str, return the previous char and its position. @@ -1001,7 +1002,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_range_at_reverse(&self, start: usize) -> CharRange { - core_str::StrExt::char_range_at_reverse(&self[], start) + core_str::StrExt::char_range_at_reverse(&self[..], start) } /// Plucks the character starting at the `i`th byte of a string. @@ -1022,7 +1023,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_at(&self, i: usize) -> char { - core_str::StrExt::char_at(&self[], i) + core_str::StrExt::char_at(&self[..], i) } /// Plucks the character ending at the `i`th byte of a string. @@ -1034,7 +1035,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_at_reverse(&self, i: usize) -> char { - core_str::StrExt::char_at_reverse(&self[], i) + core_str::StrExt::char_at_reverse(&self[..], i) } /// Work with the byte buffer of a string as a byte slice. @@ -1046,7 +1047,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn as_bytes(&self) -> &[u8] { - core_str::StrExt::as_bytes(&self[]) + core_str::StrExt::as_bytes(&self[..]) } /// Returns the byte index of the first character of `self` that @@ -1074,7 +1075,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn find(&self, pat: P) -> Option { - core_str::StrExt::find(&self[], pat) + core_str::StrExt::find(&self[..], pat) } /// Returns the byte index of the last character of `self` that @@ -1102,7 +1103,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn rfind(&self, pat: P) -> Option { - core_str::StrExt::rfind(&self[], pat) + core_str::StrExt::rfind(&self[..], pat) } /// Returns the byte index of the first matching substring @@ -1127,7 +1128,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might get removed in favor of a more generic find in the future")] fn find_str(&self, needle: &str) -> Option { - core_str::StrExt::find_str(&self[], needle) + core_str::StrExt::find_str(&self[..], needle) } /// Retrieves the first character from a string slice and returns @@ -1151,7 +1152,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "awaiting conventions about shifting and slices")] fn slice_shift_char(&self) -> Option<(char, &str)> { - core_str::StrExt::slice_shift_char(&self[]) + core_str::StrExt::slice_shift_char(&self[..]) } /// Returns the byte offset of an inner slice relative to an enclosing outer slice. @@ -1171,7 +1172,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "awaiting convention about comparability of arbitrary slices")] fn subslice_offset(&self, inner: &str) -> usize { - core_str::StrExt::subslice_offset(&self[], inner) + core_str::StrExt::subslice_offset(&self[..], inner) } /// Return an unsafe pointer to the strings buffer. @@ -1182,14 +1183,14 @@ pub trait StrExt: Index { #[stable(feature = "rust1", since = "1.0.0")] #[inline] fn as_ptr(&self) -> *const u8 { - core_str::StrExt::as_ptr(&self[]) + core_str::StrExt::as_ptr(&self[..]) } /// Return an iterator of `u16` over the string encoded as UTF-16. #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn utf16_units(&self) -> Utf16Units { - Utf16Units { encoder: Utf16Encoder::new(self[].chars()) } + Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) } } /// Return the number of bytes in this string @@ -1203,7 +1204,7 @@ pub trait StrExt: Index { #[stable(feature = "rust1", since = "1.0.0")] #[inline] fn len(&self) -> usize { - core_str::StrExt::len(&self[]) + core_str::StrExt::len(&self[..]) } /// Returns true if this slice contains no bytes @@ -1216,7 +1217,7 @@ pub trait StrExt: Index { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn is_empty(&self) -> bool { - core_str::StrExt::is_empty(&self[]) + core_str::StrExt::is_empty(&self[..]) } /// Parse this string into the specified type. @@ -1230,7 +1231,7 @@ pub trait StrExt: Index { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn parse(&self) -> Result { - core_str::StrExt::parse(&self[]) + core_str::StrExt::parse(&self[..]) } /// Returns an iterator over the @@ -1255,7 +1256,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn graphemes(&self, is_extended: bool) -> Graphemes { - UnicodeStr::graphemes(&self[], is_extended) + UnicodeStr::graphemes(&self[..], is_extended) } /// Returns an iterator over the grapheme clusters of self and their byte offsets. @@ -1271,7 +1272,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices { - UnicodeStr::grapheme_indices(&self[], is_extended) + UnicodeStr::grapheme_indices(&self[..], is_extended) } /// An iterator over the words of a string (subsequences separated @@ -1288,7 +1289,7 @@ pub trait StrExt: Index { #[unstable(feature = "str_words", reason = "the precise algorithm to use is unclear")] fn words(&self) -> Words { - UnicodeStr::words(&self[]) + UnicodeStr::words(&self[..]) } /// Returns a string's displayed width in columns, treating control @@ -1303,25 +1304,25 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn width(&self, is_cjk: bool) -> usize { - UnicodeStr::width(&self[], is_cjk) + UnicodeStr::width(&self[..], is_cjk) } /// Returns a string with leading and trailing whitespace removed. #[stable(feature = "rust1", since = "1.0.0")] fn trim(&self) -> &str { - UnicodeStr::trim(&self[]) + UnicodeStr::trim(&self[..]) } /// Returns a string with leading whitespace removed. #[stable(feature = "rust1", since = "1.0.0")] fn trim_left(&self) -> &str { - UnicodeStr::trim_left(&self[]) + UnicodeStr::trim_left(&self[..]) } /// Returns a string with trailing whitespace removed. #[stable(feature = "rust1", since = "1.0.0")] fn trim_right(&self) -> &str { - UnicodeStr::trim_right(&self[]) + UnicodeStr::trim_right(&self[..]) } } @@ -2704,7 +2705,7 @@ mod tests { &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]), ]; - for &(s, g) in &test_same[] { + for &(s, g) in &test_same[..] { // test forward iterator assert!(order::equals(s.graphemes(true), g.iter().cloned())); assert!(order::equals(s.graphemes(false), g.iter().cloned())); diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 69fd28d172368..3b179d0b94c97 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -16,12 +16,11 @@ use core::prelude::*; -use core::borrow::{Cow, IntoCow}; use core::default::Default; use core::error::Error; use core::fmt; use core::hash; -use core::iter::FromIterator; +use core::iter::{IntoIterator, FromIterator}; use core::mem; use core::ops::{self, Deref, Add, Index}; use core::ptr; @@ -29,6 +28,7 @@ use core::raw::Slice as RawSlice; use unicode::str as unicode_str; use unicode::str::Utf16Item; +use borrow::{Cow, IntoCow}; use str::{self, CharRange, FromStr, Utf8Error}; use vec::{DerefVec, Vec, as_vec}; @@ -142,7 +142,7 @@ impl String { /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> { + pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> { let mut i = 0; match str::from_utf8(v) { Ok(s) => return Cow::Borrowed(s), @@ -709,18 +709,18 @@ impl Error for FromUtf16Error { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for String { - fn from_iter>(iterator: I) -> String { + fn from_iter>(iter: I) -> String { let mut buf = String::new(); - buf.extend(iterator); + buf.extend(iter); buf } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a> FromIterator<&'a str> for String { - fn from_iter>(iterator: I) -> String { + fn from_iter>(iter: I) -> String { let mut buf = String::new(); - buf.extend(iterator); + buf.extend(iter); buf } } @@ -728,7 +728,8 @@ impl<'a> FromIterator<&'a str> for String { #[unstable(feature = "collections", reason = "waiting on Extend stabilization")] impl Extend for String { - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); let (lower_bound, _) = iterator.size_hint(); self.reserve(lower_bound); for ch in iterator { @@ -740,7 +741,8 @@ impl Extend for String { #[unstable(feature = "collections", reason = "waiting on Extend stabilization")] impl<'a> Extend<&'a str> for String { - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); // A guess that at least one byte per iterator element will be needed. let (lower_bound, _) = iterator.size_hint(); self.reserve(lower_bound); @@ -780,10 +782,10 @@ macro_rules! impl_eq { } impl_eq! { String, &'a str } -impl_eq! { CowString<'a>, String } +impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> PartialEq<&'b str> for CowString<'a> { +impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> { #[inline] fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) } #[inline] @@ -791,11 +793,11 @@ impl<'a, 'b> PartialEq<&'b str> for CowString<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> PartialEq> for &'b str { +impl<'a, 'b> PartialEq> for &'b str { #[inline] - fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) } #[inline] - fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) } } #[unstable(feature = "collections", reason = "waiting on Str stabilization")] @@ -833,12 +835,21 @@ impl fmt::Debug for String { } #[unstable(feature = "collections", reason = "waiting on Hash stabilization")] +#[cfg(stage0)] impl hash::Hash for String { #[inline] fn hash(&self, hasher: &mut H) { (**self).hash(hasher) } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl hash::Hash for String { + #[inline] + fn hash(&self, hasher: &mut H) { + (**self).hash(hasher) + } +} #[unstable(feature = "collections", reason = "recent addition, needs more experience")] @@ -857,7 +868,7 @@ impl ops::Index> for String { type Output = str; #[inline] fn index(&self, index: &ops::Range) -> &str { - &self[][*index] + &self[..][*index] } } #[stable(feature = "rust1", since = "1.0.0")] @@ -865,7 +876,7 @@ impl ops::Index> for String { type Output = str; #[inline] fn index(&self, index: &ops::RangeTo) -> &str { - &self[][*index] + &self[..][*index] } } #[stable(feature = "rust1", since = "1.0.0")] @@ -873,7 +884,7 @@ impl ops::Index> for String { type Output = str; #[inline] fn index(&self, index: &ops::RangeFrom) -> &str { - &self[][*index] + &self[..][*index] } } #[stable(feature = "rust1", since = "1.0.0")] @@ -891,7 +902,7 @@ impl ops::Deref for String { #[inline] fn deref(&self) -> &str { - unsafe { mem::transmute(&self.vec[]) } + unsafe { mem::transmute(&self.vec[..]) } } } @@ -958,31 +969,34 @@ impl ToString for T { } } -impl IntoCow<'static, String, str> for String { +#[stable(feature = "rust1", since = "1.0.0")] +impl IntoCow<'static, str> for String { #[inline] - fn into_cow(self) -> CowString<'static> { + fn into_cow(self) -> Cow<'static, str> { Cow::Owned(self) } } -impl<'a> IntoCow<'a, String, str> for &'a str { +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> IntoCow<'a, str> for &'a str { #[inline] - fn into_cow(self) -> CowString<'a> { + fn into_cow(self) -> Cow<'a, str> { Cow::Borrowed(self) } } -/// A clone-on-write string -#[stable(feature = "rust1", since = "1.0.0")] -pub type CowString<'a> = Cow<'a, String, str>; - -impl<'a> Str for CowString<'a> { +impl<'a> Str for Cow<'a, str> { #[inline] fn as_slice<'b>(&'b self) -> &'b str { &**self } } +/// A clone-on-write string +#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")] +#[stable(feature = "rust1", since = "1.0.0")] +pub type CowString<'a> = Cow<'a, str>; + #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Write for String { #[inline] @@ -1287,7 +1301,7 @@ mod tests { #[test] fn test_slicing() { let s = "foobar".to_string(); - assert_eq!("foobar", &s[]); + assert_eq!("foobar", &s[..]); assert_eq!("foo", &s[..3]); assert_eq!("bar", &s[3..]); assert_eq!("oob", &s[1..4]); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..1cc2a5235abec 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -50,24 +50,26 @@ use core::prelude::*; use alloc::boxed::Box; use alloc::heap::{EMPTY, allocate, reallocate, deallocate}; -use core::borrow::{Cow, IntoCow}; use core::cmp::max; use core::cmp::{Ordering}; use core::default::Default; use core::fmt; use core::hash::{self, Hash}; +use core::intrinsics::assume; use core::iter::{repeat, FromIterator, IntoIterator}; -use core::marker::{self, ContravariantLifetime, InvariantType}; +use core::marker::PhantomData; use core::mem; -use core::nonzero::NonZero; use core::num::{Int, UnsignedInt}; use core::ops::{Index, IndexMut, Deref, Add}; use core::ops; use core::ptr; +use core::ptr::Unique; use core::raw::Slice as RawSlice; use core::slice; use core::usize; +use borrow::{Cow, IntoCow}; + /// A growable list type, written `Vec` but pronounced 'vector.' /// /// # Examples @@ -137,10 +139,9 @@ use core::usize; #[unsafe_no_drop_flag] #[stable(feature = "rust1", since = "1.0.0")] pub struct Vec { - ptr: NonZero<*mut T>, + ptr: Unique, len: usize, cap: usize, - _own: marker::PhantomData, } unsafe impl Send for Vec { } @@ -249,10 +250,9 @@ impl Vec { pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Vec { Vec { - ptr: NonZero::new(ptr), + ptr: Unique::new(ptr), len: length, cap: capacity, - _own: marker::PhantomData, } } @@ -373,7 +373,7 @@ impl Vec { self.len * mem::size_of::(), mem::min_align_of::()) as *mut T; if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); + self.ptr = Unique::new(ptr); } self.cap = self.len; } @@ -655,7 +655,7 @@ impl Vec { unsafe { let ptr = alloc_or_realloc(*self.ptr, old_size, size); if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); + self.ptr = Unique::new(ptr); } self.cap = max(self.cap, 2) * 2; } @@ -756,7 +756,7 @@ impl Vec { Drain { ptr: begin, end: end, - marker: ContravariantLifetime, + marker: PhantomData, } } } @@ -871,6 +871,8 @@ impl Vec { end_t: unsafe { start.offset(offset) }, start_u: start as *mut U, end_u: start as *mut U, + + _marker: PhantomData, }; // start_t // start_u @@ -967,8 +969,7 @@ impl Vec { let mut pv = PartialVecZeroSized:: { num_t: vec.len(), num_u: 0, - marker_t: InvariantType, - marker_u: InvariantType, + marker: PhantomData, }; unsafe { mem::forget(vec); } @@ -1226,7 +1227,7 @@ impl Vec { unsafe { let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::(), size); if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); + self.ptr = Unique::new(ptr); } self.cap = capacity; } @@ -1302,12 +1303,21 @@ impl Clone for Vec { } } +#[cfg(stage0)] impl> Hash for Vec { #[inline] fn hash(&self, state: &mut S) { Hash::hash(&**self, state) } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for Vec { + #[inline] + fn hash(&self, state: &mut H) { + Hash::hash(&**self, state) + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Index for Vec { @@ -1407,7 +1417,8 @@ impl ops::DerefMut for Vec { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for Vec { #[inline] - fn from_iter>(mut iterator: I) -> Vec { + fn from_iter>(iterable: I) -> Vec { + let mut iterator = iterable.into_iter(); let (lower, _) = iterator.size_hint(); let mut vector = Vec::with_capacity(lower); @@ -1480,7 +1491,8 @@ impl<'a, T> IntoIterator for &'a mut Vec { #[unstable(feature = "collections", reason = "waiting on Extend stability")] impl Extend for Vec { #[inline] - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); let (lower, _) = iterator.size_hint(); self.reserve(lower); for element in iterator { @@ -1517,34 +1529,34 @@ macro_rules! impl_eq { impl_eq! { Vec, &'b [B] } impl_eq! { Vec, &'b mut [B] } -impl<'a, A, B> PartialEq> for CowVec<'a, A> where A: PartialEq + Clone { +impl<'a, A, B> PartialEq> for Cow<'a, [A]> where A: PartialEq + Clone { #[inline] fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } } -impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { +impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { #[inline] - fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) } #[inline] - fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) } } macro_rules! impl_eq_for_cowvec { ($rhs:ty) => { - impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq + Clone { + impl<'a, 'b, A, B> PartialEq<$rhs> for Cow<'a, [A]> where A: PartialEq + Clone { #[inline] fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } } - impl<'a, 'b, A, B> PartialEq> for $rhs where A: Clone, B: PartialEq { + impl<'a, 'b, A, B> PartialEq> for $rhs where A: Clone, B: PartialEq { #[inline] - fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) } #[inline] - fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) } } } } @@ -1552,8 +1564,7 @@ macro_rules! impl_eq_for_cowvec { impl_eq_for_cowvec! { &'b [B] } impl_eq_for_cowvec! { &'b mut [B] } -#[unstable(feature = "collections", - reason = "waiting on PartialOrd stability")] +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for Vec { #[inline] fn partial_cmp(&self, other: &Vec) -> Option { @@ -1561,10 +1572,10 @@ impl PartialOrd for Vec { } } -#[unstable(feature = "collections", reason = "waiting on Eq stability")] +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for Vec {} -#[unstable(feature = "collections", reason = "waiting on Ord stability")] +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for Vec { #[inline] fn cmp(&self, other: &Vec) -> Ordering { @@ -1587,8 +1598,12 @@ impl AsSlice for Vec { #[stable(feature = "rust1", since = "1.0.0")] fn as_slice(&self) -> &[T] { unsafe { + let p = *self.ptr; + if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot + assume(p != 0 as *mut T); + } mem::transmute(RawSlice { - data: *self.ptr, + data: p, len: self.len }) } @@ -1643,26 +1658,26 @@ impl fmt::Debug for Vec { // Clone-on-write //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "collections", - reason = "unclear how valuable this alias is")] /// A clone-on-write vector -pub type CowVec<'a, T> = Cow<'a, Vec, [T]>; +#[deprecated(since = "1.0.0", reason = "use Cow<'a, [T]> instead")] +#[unstable(feature = "collections")] +pub type CowVec<'a, T> = Cow<'a, [T]>; #[unstable(feature = "collections")] -impl<'a, T> FromIterator for CowVec<'a, T> where T: Clone { - fn from_iter>(it: I) -> CowVec<'a, T> { +impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { + fn from_iter>(it: I) -> Cow<'a, [T]> { Cow::Owned(FromIterator::from_iter(it)) } } -impl<'a, T: 'a> IntoCow<'a, Vec, [T]> for Vec where T: Clone { - fn into_cow(self) -> CowVec<'a, T> { +impl<'a, T: 'a> IntoCow<'a, [T]> for Vec where T: Clone { + fn into_cow(self) -> Cow<'a, [T]> { Cow::Owned(self) } } -impl<'a, T> IntoCow<'a, Vec, [T]> for &'a [T] where T: Clone { - fn into_cow(self) -> CowVec<'a, T> { +impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone { + fn into_cow(self) -> Cow<'a, [T]> { Cow::Borrowed(self) } } @@ -1779,10 +1794,10 @@ impl Drop for IntoIter { #[unsafe_no_drop_flag] #[unstable(feature = "collections", reason = "recently added as part of collections reform 2")] -pub struct Drain<'a, T> { +pub struct Drain<'a, T:'a> { ptr: *const T, end: *const T, - marker: ContravariantLifetime<'a>, + marker: PhantomData<&'a T>, } #[stable(feature = "rust1", since = "1.0.0")] @@ -1867,9 +1882,9 @@ impl<'a, T> Drop for Drain<'a, T> { /// Wrapper type providing a `&Vec` reference via `Deref`. #[unstable(feature = "collections")] -pub struct DerefVec<'a, T> { +pub struct DerefVec<'a, T:'a> { x: Vec, - l: ContravariantLifetime<'a> + l: PhantomData<&'a T>, } #[unstable(feature = "collections")] @@ -1897,7 +1912,7 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> { unsafe { DerefVec { x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()), - l: ContravariantLifetime::<'a> + l: PhantomData, } } } @@ -1921,6 +1936,8 @@ struct PartialVecNonZeroSized { end_u: *mut U, start_t: *mut T, end_t: *mut T, + + _marker: PhantomData, } /// An owned, partially type-converted vector of zero-sized elements. @@ -1930,8 +1947,7 @@ struct PartialVecNonZeroSized { struct PartialVecZeroSized { num_t: usize, num_u: usize, - marker_t: InvariantType, - marker_u: InvariantType, + marker: PhantomData<::core::cell::Cell<(T,U)>>, } #[unsafe_destructor] @@ -2589,7 +2605,7 @@ mod tests { b.bytes = src_len as u64; b.iter(|| { - let dst = src.clone()[].to_vec(); + let dst = src.clone()[..].to_vec(); assert_eq!(dst.len(), src_len); assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); }); diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/vec_deque.rs similarity index 88% rename from src/libcollections/ring_buf.rs rename to src/libcollections/vec_deque.rs index 6dcdb21f8000b..3ba22a41ff740 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/vec_deque.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! RingBuf is a double-ended queue, which is implemented with the help of a -//! growing circular buffer. +//! VecDeque is a double-ended queue, which is implemented with the help of a +//! growing ring buffer. //! //! This queue has `O(1)` amortized inserts and removals from both ends of the //! container. It also has `O(1)` indexing like a vector. The contained elements @@ -28,20 +28,26 @@ use core::marker; use core::mem; use core::num::{Int, UnsignedInt}; use core::ops::{Index, IndexMut}; -use core::ptr; +use core::ptr::{self, Unique}; use core::raw::Slice as RawSlice; -use core::hash::{Writer, Hash, Hasher}; +use core::hash::{Hash, Hasher}; +#[cfg(stage0)] use core::hash::Writer; use core::cmp; use alloc::heap; +#[deprecated(since = "1.0.0", reason = "renamed to VecDeque")] +#[unstable(feature = "collections")] +pub use VecDeque as RingBuf; + static INITIAL_CAPACITY: usize = 7; // 2^3 - 1 static MINIMUM_CAPACITY: usize = 1; // 2 - 1 -/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently. +/// `VecDeque` is a growable ring buffer, which can be used as a +/// double-ended queue efficiently. #[stable(feature = "rust1", since = "1.0.0")] -pub struct RingBuf { +pub struct VecDeque { // tail and head are pointers into the buffer. Tail always points // to the first element that could be read, Head always points // to where data should be written. @@ -51,30 +57,30 @@ pub struct RingBuf { tail: usize, head: usize, cap: usize, - ptr: *mut T + ptr: Unique, } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for RingBuf {} +unsafe impl Send for VecDeque {} #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for RingBuf {} +unsafe impl Sync for VecDeque {} #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for RingBuf { - fn clone(&self) -> RingBuf { +impl Clone for VecDeque { + fn clone(&self) -> VecDeque { self.iter().cloned().collect() } } #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for RingBuf { +impl Drop for VecDeque { fn drop(&mut self) { self.clear(); unsafe { if mem::size_of::() != 0 { - heap::deallocate(self.ptr as *mut u8, + heap::deallocate(*self.ptr as *mut u8, self.cap * mem::size_of::(), mem::min_align_of::()) } @@ -83,22 +89,22 @@ impl Drop for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for RingBuf { +impl Default for VecDeque { #[inline] - fn default() -> RingBuf { RingBuf::new() } + fn default() -> VecDeque { VecDeque::new() } } -impl RingBuf { +impl VecDeque { /// Turn ptr into a slice #[inline] unsafe fn buffer_as_slice(&self) -> &[T] { - mem::transmute(RawSlice { data: self.ptr, len: self.cap }) + mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap }) } /// Turn ptr into a mut slice #[inline] unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] { - mem::transmute(RawSlice { data: self.ptr, len: self.cap }) + mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap }) } /// Moves an element out of the buffer @@ -149,48 +155,48 @@ impl RingBuf { } } -impl RingBuf { - /// Creates an empty `RingBuf`. +impl VecDeque { + /// Creates an empty `VecDeque`. #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> RingBuf { - RingBuf::with_capacity(INITIAL_CAPACITY) + pub fn new() -> VecDeque { + VecDeque::with_capacity(INITIAL_CAPACITY) } - /// Creates an empty `RingBuf` with space for at least `n` elements. + /// Creates an empty `VecDeque` with space for at least `n` elements. #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(n: usize) -> RingBuf { + pub fn with_capacity(n: usize) -> VecDeque { // +1 since the ringbuffer always leaves one space empty let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); assert!(cap > n, "capacity overflow"); let size = cap.checked_mul(mem::size_of::()) .expect("capacity overflow"); - let ptr = if mem::size_of::() != 0 { - unsafe { + let ptr = unsafe { + if mem::size_of::() != 0 { let ptr = heap::allocate(size, mem::min_align_of::()) as *mut T;; if ptr.is_null() { ::alloc::oom() } - ptr + Unique::new(ptr) + } else { + Unique::new(heap::EMPTY as *mut T) } - } else { - heap::EMPTY as *mut T }; - RingBuf { + VecDeque { tail: 0, head: 0, cap: cap, - ptr: ptr + ptr: ptr, } } - /// Retrieves an element in the `RingBuf` by index. + /// Retrieves an element in the `VecDeque` by index. /// /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); @@ -206,14 +212,14 @@ impl RingBuf { } } - /// Retrieves an element in the `RingBuf` mutably by index. + /// Retrieves an element in the `VecDeque` mutably by index. /// /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); @@ -245,9 +251,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); @@ -266,15 +272,15 @@ impl RingBuf { } } - /// Returns the number of elements the `RingBuf` can hold without + /// Returns the number of elements the `VecDeque` can hold without /// reallocating. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let buf: RingBuf = RingBuf::with_capacity(10); + /// let buf: VecDeque = VecDeque::with_capacity(10); /// assert!(buf.capacity() >= 10); /// ``` #[inline] @@ -282,7 +288,7 @@ impl RingBuf { pub fn capacity(&self) -> usize { self.cap - 1 } /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the - /// given `RingBuf`. Does nothing if the capacity is already sufficient. + /// given `VecDeque`. Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it requests. Therefore /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future @@ -295,9 +301,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf = vec![1].into_iter().collect(); + /// let mut buf: VecDeque = vec![1].into_iter().collect(); /// buf.reserve_exact(10); /// assert!(buf.capacity() >= 11); /// ``` @@ -316,9 +322,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf = vec![1].into_iter().collect(); + /// let mut buf: VecDeque = vec![1].into_iter().collect(); /// buf.reserve(10); /// assert!(buf.capacity() >= 11); /// ``` @@ -335,11 +341,12 @@ impl RingBuf { let new = count.checked_mul(mem::size_of::()) .expect("capacity overflow"); unsafe { - self.ptr = heap::reallocate(self.ptr as *mut u8, - old, - new, - mem::min_align_of::()) as *mut T; - if self.ptr.is_null() { ::alloc::oom() } + let ptr = heap::reallocate(*self.ptr as *mut u8, + old, + new, + mem::min_align_of::()) as *mut T; + if ptr.is_null() { ::alloc::oom() } + self.ptr = Unique::new(ptr); } } @@ -390,9 +397,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::with_capacity(15); + /// let mut buf = VecDeque::with_capacity(15); /// buf.extend(0..4); /// assert_eq!(buf.capacity(), 15); /// buf.shrink_to_fit(); @@ -453,11 +460,12 @@ impl RingBuf { let old = self.cap * mem::size_of::(); let new_size = target_cap * mem::size_of::(); unsafe { - self.ptr = heap::reallocate(self.ptr as *mut u8, - old, - new_size, - mem::min_align_of::()) as *mut T; - if self.ptr.is_null() { ::alloc::oom() } + let ptr = heap::reallocate(*self.ptr as *mut u8, + old, + new_size, + mem::min_align_of::()) as *mut T; + if ptr.is_null() { ::alloc::oom() } + self.ptr = Unique::new(ptr); } } self.cap = target_cap; @@ -475,9 +483,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(10); /// buf.push_back(15); @@ -498,9 +506,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(3); /// buf.push_back(4); @@ -521,9 +529,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(3); /// buf.push_back(4); @@ -539,8 +547,8 @@ impl RingBuf { tail: self.tail, head: self.head, cap: self.cap, - ptr: self.ptr, - marker: marker::ContravariantLifetime, + ptr: *self.ptr, + marker: marker::PhantomData, } } @@ -553,7 +561,7 @@ impl RingBuf { } /// Returns a pair of slices which contain, in order, the contents of the - /// `RingBuf`. + /// `VecDeque`. #[inline] #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] @@ -573,7 +581,7 @@ impl RingBuf { } /// Returns a pair of slices which contain, in order, the contents of the - /// `RingBuf`. + /// `VecDeque`. #[inline] #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] @@ -596,14 +604,14 @@ impl RingBuf { } } - /// Returns the number of elements in the `RingBuf`. + /// Returns the number of elements in the `VecDeque`. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// assert_eq!(v.len(), 0); /// v.push_back(1); /// assert_eq!(v.len(), 1); @@ -616,9 +624,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// assert!(v.is_empty()); /// v.push_front(1); /// assert!(!v.is_empty()); @@ -626,15 +634,15 @@ impl RingBuf { #[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { self.len() == 0 } - /// Creates a draining iterator that clears the `RingBuf` and iterates over + /// Creates a draining iterator that clears the `VecDeque` and iterates over /// the removed items from start to end. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// v.push_back(1); /// assert_eq!(v.drain().next(), Some(1)); /// assert!(v.is_empty()); @@ -653,9 +661,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// v.push_back(1); /// v.clear(); /// assert!(v.is_empty()); @@ -672,9 +680,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.front(), None); /// /// d.push_back(1); @@ -692,9 +700,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.front_mut(), None); /// /// d.push_back(1); @@ -716,9 +724,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.back(), None); /// /// d.push_back(1); @@ -736,9 +744,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.back(), None); /// /// d.push_back(1); @@ -761,9 +769,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// d.push_back(1); /// d.push_back(2); /// @@ -787,9 +795,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// d.push_front(1); /// d.push_front(2); /// assert_eq!(d.front(), Some(&2)); @@ -811,9 +819,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(1); /// buf.push_back(3); /// assert_eq!(3, *buf.back().unwrap()); @@ -836,9 +844,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// assert_eq!(buf.pop_back(), None); /// buf.push_back(1); /// buf.push_back(3); @@ -870,9 +878,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// assert_eq!(buf.swap_back_remove(0), None); /// buf.push_back(5); /// buf.push_back(99); @@ -903,9 +911,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// assert_eq!(buf.swap_front_remove(0), None); /// buf.push_back(15); /// buf.push_back(5); @@ -936,9 +944,9 @@ impl RingBuf { /// /// # Examples /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(10); /// buf.push_back(12); /// buf.insert(1,11); @@ -1138,9 +1146,9 @@ impl RingBuf { /// /// # Examples /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(10); /// buf.push_back(12); @@ -1309,9 +1317,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf<_> = vec![1,2,3].into_iter().collect(); + /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect(); /// let buf2 = buf.split_off(1); /// // buf = [1], buf2 = [2, 3] /// assert_eq!(buf.len(), 1); @@ -1325,7 +1333,7 @@ impl RingBuf { assert!(at <= len, "`at` out of bounds"); let other_len = len - at; - let mut other = RingBuf::with_capacity(other_len); + let mut other = VecDeque::with_capacity(other_len); unsafe { let (first_half, second_half) = self.as_slices(); @@ -1336,7 +1344,7 @@ impl RingBuf { // `at` lies in the first half. let amount_in_first = first_len - at; - ptr::copy_nonoverlapping_memory(other.ptr, + ptr::copy_nonoverlapping_memory(*other.ptr, first_half.as_ptr().offset(at as isize), amount_in_first); @@ -1349,7 +1357,7 @@ impl RingBuf { // in the first half. let offset = at - first_len; let amount_in_second = second_len - offset; - ptr::copy_nonoverlapping_memory(other.ptr, + ptr::copy_nonoverlapping_memory(*other.ptr, second_half.as_ptr().offset(offset as isize), amount_in_second); } @@ -1371,10 +1379,10 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf<_> = vec![1, 2, 3].into_iter().collect(); - /// let mut buf2: RingBuf<_> = vec![4, 5, 6].into_iter().collect(); + /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect(); + /// let mut buf2: VecDeque<_> = vec![4, 5, 6].into_iter().collect(); /// buf.append(&mut buf2); /// assert_eq!(buf.len(), 6); /// assert_eq!(buf2.len(), 0); @@ -1388,16 +1396,16 @@ impl RingBuf { } } -impl RingBuf { +impl VecDeque { /// Modifies the ringbuf in-place so that `len()` is equal to new_len, /// either by removing excess elements or by appending copies of a value to the back. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(10); /// buf.push_back(15); @@ -1434,7 +1442,7 @@ fn count(tail: usize, head: usize, size: usize) -> usize { (head - tail) & (size - 1) } -/// `RingBuf` iterator. +/// `VecDeque` iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T:'a> { ring: &'a [T], @@ -1511,14 +1519,14 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> { // FIXME This was implemented differently from Iter because of a problem // with returning the mutable reference. I couldn't find a way to // make the lifetime checker happy so, but there should be a way. -/// `RingBuf` mutable iterator. +/// `VecDeque` mutable iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T:'a> { ptr: *mut T, tail: usize, head: usize, cap: usize, - marker: marker::ContravariantLifetime<'a>, + marker: marker::PhantomData<&'a mut T>, } #[stable(feature = "rust1", since = "1.0.0")] @@ -1563,10 +1571,10 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} -/// A by-value RingBuf iterator +/// A by-value VecDeque iterator #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - inner: RingBuf, + inner: VecDeque, } #[stable(feature = "rust1", since = "1.0.0")] @@ -1596,11 +1604,11 @@ impl DoubleEndedIterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for IntoIter {} -/// A draining RingBuf iterator +/// A draining VecDeque iterator #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] pub struct Drain<'a, T: 'a> { - inner: &'a mut RingBuf, + inner: &'a mut VecDeque, } #[unsafe_destructor] @@ -1641,33 +1649,34 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for RingBuf { - fn eq(&self, other: &RingBuf) -> bool { +impl PartialEq for VecDeque { + fn eq(&self, other: &VecDeque) -> bool { self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for RingBuf {} +impl Eq for VecDeque {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for RingBuf { - fn partial_cmp(&self, other: &RingBuf) -> Option { +impl PartialOrd for VecDeque { + fn partial_cmp(&self, other: &VecDeque) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for RingBuf { +impl Ord for VecDeque { #[inline] - fn cmp(&self, other: &RingBuf) -> Ordering { + fn cmp(&self, other: &VecDeque) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl> Hash for RingBuf { +#[cfg(stage0)] +impl> Hash for VecDeque { fn hash(&self, state: &mut S) { self.len().hash(state); for elt in self { @@ -1675,9 +1684,19 @@ impl> Hash for RingBuf { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for VecDeque { + fn hash(&self, state: &mut H) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } + } +} #[stable(feature = "rust1", since = "1.0.0")] -impl Index for RingBuf { +impl Index for VecDeque { type Output = A; #[inline] @@ -1687,7 +1706,7 @@ impl Index for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for RingBuf { +impl IndexMut for VecDeque { #[inline] fn index_mut(&mut self, i: &usize) -> &mut A { self.get_mut(*i).expect("Out of bounds access") @@ -1695,17 +1714,18 @@ impl IndexMut for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for RingBuf { - fn from_iter>(iterator: T) -> RingBuf { +impl FromIterator for VecDeque { + fn from_iter>(iterable: T) -> VecDeque { + let iterator = iterable.into_iter(); let (lower, _) = iterator.size_hint(); - let mut deq = RingBuf::with_capacity(lower); + let mut deq = VecDeque::with_capacity(lower); deq.extend(iterator); deq } } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for RingBuf { +impl IntoIterator for VecDeque { type Item = T; type IntoIter = IntoIter; @@ -1715,7 +1735,7 @@ impl IntoIterator for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a RingBuf { +impl<'a, T> IntoIterator for &'a VecDeque { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1725,7 +1745,7 @@ impl<'a, T> IntoIterator for &'a RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a mut RingBuf { +impl<'a, T> IntoIterator for &'a mut VecDeque { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -1735,18 +1755,18 @@ impl<'a, T> IntoIterator for &'a mut RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for RingBuf { - fn extend>(&mut self, iterator: T) { - for elt in iterator { +impl Extend for VecDeque { + fn extend>(&mut self, iter: T) { + for elt in iter { self.push_back(elt); } } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for RingBuf { +impl fmt::Debug for VecDeque { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "RingBuf [")); + try!(write!(f, "VecDeque [")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1768,12 +1788,12 @@ mod tests { use test::Bencher; use test; - use super::RingBuf; + use super::VecDeque; #[test] #[allow(deprecated)] fn test_simple() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert_eq!(d.len(), 0); d.push_front(17); d.push_front(42); @@ -1812,7 +1832,7 @@ mod tests { #[cfg(test)] fn test_parameterized(a: T, b: T, c: T, d: T) { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); assert_eq!(deq.len(), 0); deq.push_front(a.clone()); deq.push_front(b.clone()); @@ -1843,7 +1863,7 @@ mod tests { #[test] fn test_push_front_grow() { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 0..66 { deq.push_front(i); } @@ -1853,7 +1873,7 @@ mod tests { assert_eq!(deq[i], 65 - i); } - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 0..66 { deq.push_back(i); } @@ -1865,7 +1885,7 @@ mod tests { #[test] fn test_index() { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 1..4 { deq.push_front(i); } @@ -1875,7 +1895,7 @@ mod tests { #[test] #[should_fail] fn test_index_out_of_bounds() { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 1..4 { deq.push_front(i); } @@ -1885,14 +1905,14 @@ mod tests { #[bench] fn bench_new(b: &mut test::Bencher) { b.iter(|| { - let ring: RingBuf = RingBuf::new(); + let ring: VecDeque = VecDeque::new(); test::black_box(ring); }) } #[bench] fn bench_push_back_100(b: &mut test::Bencher) { - let mut deq = RingBuf::with_capacity(101); + let mut deq = VecDeque::with_capacity(101); b.iter(|| { for i in 0..100 { deq.push_back(i); @@ -1904,7 +1924,7 @@ mod tests { #[bench] fn bench_push_front_100(b: &mut test::Bencher) { - let mut deq = RingBuf::with_capacity(101); + let mut deq = VecDeque::with_capacity(101); b.iter(|| { for i in 0..100 { deq.push_front(i); @@ -1916,7 +1936,7 @@ mod tests { #[bench] fn bench_pop_back_100(b: &mut test::Bencher) { - let mut deq= RingBuf::::with_capacity(101); + let mut deq= VecDeque::::with_capacity(101); b.iter(|| { deq.head = 100; @@ -1929,7 +1949,7 @@ mod tests { #[bench] fn bench_pop_front_100(b: &mut test::Bencher) { - let mut deq = RingBuf::::with_capacity(101); + let mut deq = VecDeque::::with_capacity(101); b.iter(|| { deq.head = 100; @@ -1943,7 +1963,7 @@ mod tests { #[bench] fn bench_grow_1025(b: &mut test::Bencher) { b.iter(|| { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 0..1025 { deq.push_front(i); } @@ -1953,7 +1973,7 @@ mod tests { #[bench] fn bench_iter_1000(b: &mut test::Bencher) { - let ring: RingBuf<_> = (0..1000).collect(); + let ring: VecDeque<_> = (0..1000).collect(); b.iter(|| { let mut sum = 0; @@ -1966,7 +1986,7 @@ mod tests { #[bench] fn bench_mut_iter_1000(b: &mut test::Bencher) { - let mut ring: RingBuf<_> = (0..1000).collect(); + let mut ring: VecDeque<_> = (0..1000).collect(); b.iter(|| { let mut sum = 0; @@ -1986,9 +2006,9 @@ mod tests { #[derive(Clone, PartialEq, Debug)] enum Taggypar { - Onepar(i32), - Twopar(i32, i32), - Threepar(i32, i32, i32), + Onepar(T), + Twopar(T, T), + Threepar(T, T, T), } #[derive(Clone, PartialEq, Debug)] @@ -2027,17 +2047,17 @@ mod tests { #[test] fn test_with_capacity() { - let mut d = RingBuf::with_capacity(0); + let mut d = VecDeque::with_capacity(0); d.push_back(1); assert_eq!(d.len(), 1); - let mut d = RingBuf::with_capacity(50); + let mut d = VecDeque::with_capacity(50); d.push_back(1); assert_eq!(d.len(), 1); } #[test] fn test_with_capacity_non_power_two() { - let mut d3 = RingBuf::with_capacity(3); + let mut d3 = VecDeque::with_capacity(3); d3.push_back(1); // X = None, | = lo @@ -2062,7 +2082,7 @@ mod tests { d3.push_back(15); // There used to be a bug here about how the - // RingBuf made growth assumptions about the + // VecDeque made growth assumptions about the // underlying Vec which didn't hold and lead // to corruption. // (Vec grows to next power of two) @@ -2078,7 +2098,7 @@ mod tests { #[test] fn test_reserve_exact() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); d.push_back(0); d.reserve_exact(50); assert!(d.capacity() >= 51); @@ -2086,7 +2106,7 @@ mod tests { #[test] fn test_reserve() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); d.push_back(0); d.reserve(50); assert!(d.capacity() >= 51); @@ -2094,7 +2114,7 @@ mod tests { #[test] fn test_swap() { - let mut d: RingBuf<_> = (0..5).collect(); + let mut d: VecDeque<_> = (0..5).collect(); d.pop_front(); d.swap(0, 3); assert_eq!(d.iter().cloned().collect::>(), vec!(4, 2, 3, 1)); @@ -2102,7 +2122,7 @@ mod tests { #[test] fn test_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert_eq!(d.iter().next(), None); assert_eq!(d.iter().size_hint(), (0, Some(0))); @@ -2134,7 +2154,7 @@ mod tests { #[test] fn test_rev_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert_eq!(d.iter().rev().next(), None); for i in 0..5 { @@ -2154,7 +2174,7 @@ mod tests { #[test] fn test_mut_rev_iter_wrap() { - let mut d = RingBuf::with_capacity(3); + let mut d = VecDeque::with_capacity(3); assert!(d.iter_mut().rev().next().is_none()); d.push_back(1); @@ -2169,7 +2189,7 @@ mod tests { #[test] fn test_mut_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert!(d.iter_mut().next().is_none()); for i in 0..3 { @@ -2192,7 +2212,7 @@ mod tests { #[test] fn test_mut_rev_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert!(d.iter_mut().rev().next().is_none()); for i in 0..3 { @@ -2218,7 +2238,7 @@ mod tests { // Empty iter { - let d: RingBuf = RingBuf::new(); + let d: VecDeque = VecDeque::new(); let mut iter = d.into_iter(); assert_eq!(iter.size_hint(), (0, Some(0))); @@ -2228,7 +2248,7 @@ mod tests { // simple iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2239,7 +2259,7 @@ mod tests { // wrapped iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2253,7 +2273,7 @@ mod tests { // partially used { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2277,7 +2297,7 @@ mod tests { // Empty iter { - let mut d: RingBuf = RingBuf::new(); + let mut d: VecDeque = VecDeque::new(); { let mut iter = d.drain(); @@ -2292,7 +2312,7 @@ mod tests { // simple iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2303,7 +2323,7 @@ mod tests { // wrapped iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2317,7 +2337,7 @@ mod tests { // partially used { - let mut d: RingBuf<_> = RingBuf::new(); + let mut d: VecDeque<_> = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2343,12 +2363,12 @@ mod tests { fn test_from_iter() { use core::iter; let v = vec!(1,2,3,4,5,6,7); - let deq: RingBuf<_> = v.iter().cloned().collect(); + let deq: VecDeque<_> = v.iter().cloned().collect(); let u: Vec<_> = deq.iter().cloned().collect(); assert_eq!(u, v); let seq = iter::count(0, 2).take(256); - let deq: RingBuf<_> = seq.collect(); + let deq: VecDeque<_> = seq.collect(); for (i, &x) in deq.iter().enumerate() { assert_eq!(2*i, x); } @@ -2357,7 +2377,7 @@ mod tests { #[test] fn test_clone() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); d.push_front(17); d.push_front(42); d.push_back(137); @@ -2374,13 +2394,13 @@ mod tests { #[test] fn test_eq() { - let mut d = RingBuf::new(); - assert!(d == RingBuf::with_capacity(0)); + let mut d = VecDeque::new(); + assert!(d == VecDeque::with_capacity(0)); d.push_front(137); d.push_front(17); d.push_front(42); d.push_back(137); - let mut e = RingBuf::with_capacity(0); + let mut e = VecDeque::with_capacity(0); e.push_back(42); e.push_back(17); e.push_back(137); @@ -2390,13 +2410,13 @@ mod tests { e.push_back(0); assert!(e != d); e.clear(); - assert!(e == RingBuf::new()); + assert!(e == VecDeque::new()); } #[test] fn test_hash() { - let mut x = RingBuf::new(); - let mut y = RingBuf::new(); + let mut x = VecDeque::new(); + let mut y = VecDeque::new(); x.push_back(1); x.push_back(2); @@ -2413,8 +2433,8 @@ mod tests { #[test] fn test_ord() { - let x = RingBuf::new(); - let mut y = RingBuf::new(); + let x = VecDeque::new(); + let mut y = VecDeque::new(); y.push_back(1); y.push_back(2); y.push_back(3); @@ -2426,13 +2446,13 @@ mod tests { #[test] fn test_show() { - let ringbuf: RingBuf<_> = (0..10).collect(); - assert_eq!(format!("{:?}", ringbuf), "RingBuf [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + let ringbuf: VecDeque<_> = (0..10).collect(); + assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); - let ringbuf: RingBuf<_> = vec!["just", "one", "test", "more"].iter() + let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter() .cloned() .collect(); - assert_eq!(format!("{:?}", ringbuf), "RingBuf [\"just\", \"one\", \"test\", \"more\"]"); + assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]"); } #[test] @@ -2445,7 +2465,7 @@ mod tests { } } - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(Elem); ring.push_front(Elem); ring.push_back(Elem); @@ -2465,7 +2485,7 @@ mod tests { } } - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(Elem); ring.push_front(Elem); ring.push_back(Elem); @@ -2489,7 +2509,7 @@ mod tests { } } - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(Elem); ring.push_front(Elem); ring.push_back(Elem); @@ -2505,7 +2525,7 @@ mod tests { fn test_reserve_grow() { // test growth path A // [T o o H] -> [T o o H . . . . ] - let mut ring = RingBuf::with_capacity(4); + let mut ring = VecDeque::with_capacity(4); for i in 0..3 { ring.push_back(i); } @@ -2516,7 +2536,7 @@ mod tests { // test growth path B // [H T o o] -> [. T o o H . . . ] - let mut ring = RingBuf::with_capacity(4); + let mut ring = VecDeque::with_capacity(4); for i in 0..1 { ring.push_back(i); assert_eq!(ring.pop_front(), Some(i)); @@ -2531,7 +2551,7 @@ mod tests { // test growth path C // [o o H T] -> [o o H . . . . T ] - let mut ring = RingBuf::with_capacity(4); + let mut ring = VecDeque::with_capacity(4); for i in 0..3 { ring.push_back(i); assert_eq!(ring.pop_front(), Some(i)); @@ -2547,7 +2567,7 @@ mod tests { #[test] fn test_get() { - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(0); assert_eq!(ring.get(0), Some(&0)); assert_eq!(ring.get(1), None); @@ -2579,7 +2599,7 @@ mod tests { #[test] fn test_get_mut() { - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); for i in 0..3 { ring.push_back(i); } @@ -2605,7 +2625,7 @@ mod tests { fn test(back: bool) { // This test checks that every single combination of tail position and length is tested. // Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); let usable_cap = tester.capacity(); let final_len = usable_cap / 2; @@ -2649,7 +2669,7 @@ mod tests { // This test checks that every single combination of tail position, length, and // insertion position is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2683,7 +2703,7 @@ mod tests { // This test checks that every single combination of tail position, length, and // removal position is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2720,7 +2740,7 @@ mod tests { // This test checks that every single combination of head and tail position, // is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2749,7 +2769,7 @@ mod tests { #[test] fn test_front() { - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(10); ring.push_back(20); assert_eq!(ring.front(), Some(&10)); @@ -2761,7 +2781,7 @@ mod tests { #[test] fn test_as_slices() { - let mut ring: RingBuf = RingBuf::with_capacity(127); + let mut ring: VecDeque = VecDeque::with_capacity(127); let cap = ring.capacity() as i32; let first = cap/2; let last = cap - first; @@ -2789,7 +2809,7 @@ mod tests { #[test] fn test_as_mut_slices() { - let mut ring: RingBuf = RingBuf::with_capacity(127); + let mut ring: VecDeque = VecDeque::with_capacity(127); let cap = ring.capacity() as i32; let first = cap/2; let last = cap - first; @@ -2820,7 +2840,7 @@ mod tests { // This test checks that every single combination of tail position, length, and // split position is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2855,8 +2875,8 @@ mod tests { #[test] fn test_append() { - let mut a: RingBuf<_> = vec![1, 2, 3].into_iter().collect(); - let mut b: RingBuf<_> = vec![4, 5, 6].into_iter().collect(); + let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect(); + let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect(); // normal append a.append(&mut b); diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 82ccfd0614fd5..54589a3142345 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -20,7 +20,8 @@ use core::prelude::*; use core::cmp::Ordering; use core::default::Default; use core::fmt; -use core::hash::{Hash, Writer, Hasher}; +use core::hash::{Hash, Hasher}; +#[cfg(stage0)] use core::hash::Writer; use core::iter::{Enumerate, FilterMap, Map, FromIterator, IntoIterator}; use core::iter; use core::mem::replace; @@ -99,6 +100,7 @@ impl Default for VecMap { fn default() -> VecMap { VecMap::new() } } +#[stable(feature = "rust1", since = "1.0.0")] impl Clone for VecMap { #[inline] fn clone(&self) -> VecMap { @@ -111,6 +113,7 @@ impl Clone for VecMap { } } +#[cfg(stage0)] impl> Hash for VecMap { fn hash(&self, state: &mut S) { // In order to not traverse the `VecMap` twice, count the elements @@ -123,6 +126,20 @@ impl> Hash for VecMap { count.hash(state); } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for VecMap { + fn hash(&self, state: &mut H) { + // In order to not traverse the `VecMap` twice, count the elements + // during iteration. + let mut count: usize = 0; + for elt in self { + elt.hash(state); + count += 1; + } + count.hash(state); + } +} impl VecMap { /// Creates an empty `VecMap`. @@ -661,7 +678,7 @@ impl fmt::Debug for VecMap { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(usize, V)> for VecMap { - fn from_iter>(iter: Iter) -> VecMap { + fn from_iter>(iter: I) -> VecMap { let mut map = VecMap::new(); map.extend(iter); map @@ -700,7 +717,7 @@ impl<'a, T> IntoIterator for &'a mut VecMap { #[stable(feature = "rust1", since = "1.0.0")] impl Extend<(usize, V)> for VecMap { - fn extend>(&mut self, iter: Iter) { + fn extend>(&mut self, iter: I) { for (k, v) in iter { self.insert(k, v); } @@ -859,7 +876,7 @@ pub struct IntoIter { } #[unstable(feature = "collections")] -pub struct Drain<'a, V> { +pub struct Drain<'a, V:'a> { iter: FilterMap< Enumerate>>, fn((usize, Option)) -> Option<(usize, V)>> diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 838ca4e478b72..afb5d95c9f8d7 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -17,7 +17,7 @@ use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use fmt; -use hash::{Hash, Hasher, self}; +use hash::{Hash, self}; use iter::IntoIterator; use marker::Copy; use ops::Deref; @@ -35,16 +35,24 @@ macro_rules! array_impls { } } - impl> Hash for [T; $N] { + #[cfg(stage0)] + impl> Hash for [T; $N] { fn hash(&self, state: &mut S) { - Hash::hash(&self[], state) + Hash::hash(&self[..], state) + } + } + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for [T; $N] { + fn hash(&self, state: &mut H) { + Hash::hash(&self[..], state) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&&self[], f) + fmt::Debug::fmt(&&self[..], f) } } @@ -72,11 +80,11 @@ macro_rules! array_impls { impl PartialEq<[B; $N]> for [A; $N] where A: PartialEq { #[inline] fn eq(&self, other: &[B; $N]) -> bool { - &self[] == &other[] + &self[..] == &other[..] } #[inline] fn ne(&self, other: &[B; $N]) -> bool { - &self[] != &other[] + &self[..] != &other[..] } } @@ -87,11 +95,11 @@ macro_rules! array_impls { { #[inline(always)] fn eq(&self, other: &Rhs) -> bool { - PartialEq::eq(&self[], &**other) + PartialEq::eq(&self[..], &**other) } #[inline(always)] fn ne(&self, other: &Rhs) -> bool { - PartialEq::ne(&self[], &**other) + PartialEq::ne(&self[..], &**other) } } @@ -102,11 +110,11 @@ macro_rules! array_impls { { #[inline(always)] fn eq(&self, other: &[B; $N]) -> bool { - PartialEq::eq(&**self, &other[]) + PartialEq::eq(&**self, &other[..]) } #[inline(always)] fn ne(&self, other: &[B; $N]) -> bool { - PartialEq::ne(&**self, &other[]) + PartialEq::ne(&**self, &other[..]) } } @@ -117,23 +125,23 @@ macro_rules! array_impls { impl PartialOrd for [T; $N] { #[inline] fn partial_cmp(&self, other: &[T; $N]) -> Option { - PartialOrd::partial_cmp(&&self[], &&other[]) + PartialOrd::partial_cmp(&&self[..], &&other[..]) } #[inline] fn lt(&self, other: &[T; $N]) -> bool { - PartialOrd::lt(&&self[], &&other[]) + PartialOrd::lt(&&self[..], &&other[..]) } #[inline] fn le(&self, other: &[T; $N]) -> bool { - PartialOrd::le(&&self[], &&other[]) + PartialOrd::le(&&self[..], &&other[..]) } #[inline] fn ge(&self, other: &[T; $N]) -> bool { - PartialOrd::ge(&&self[], &&other[]) + PartialOrd::ge(&&self[..], &&other[..]) } #[inline] fn gt(&self, other: &[T; $N]) -> bool { - PartialOrd::gt(&&self[], &&other[]) + PartialOrd::gt(&&self[..], &&other[..]) } } @@ -141,7 +149,7 @@ macro_rules! array_impls { impl Ord for [T; $N] { #[inline] fn cmp(&self, other: &[T; $N]) -> Ordering { - Ord::cmp(&&self[], &&other[]) + Ord::cmp(&&self[..], &&other[..]) } } )+ diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 05d864accc130..6afe5b2257d27 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -76,6 +76,7 @@ use marker::Sync; use intrinsics; use cell::UnsafeCell; +use marker::PhantomData; /// A boolean type which can be safely shared between threads. #[stable(feature = "rust1", since = "1.0.0")] @@ -105,6 +106,7 @@ unsafe impl Sync for AtomicUsize {} #[stable(feature = "rust1", since = "1.0.0")] pub struct AtomicPtr { p: UnsafeCell, + _marker: PhantomData<*mut T>, } unsafe impl Sync for AtomicPtr {} @@ -791,7 +793,8 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn new(p: *mut T) -> AtomicPtr { - AtomicPtr { p: UnsafeCell::new(p as usize) } + AtomicPtr { p: UnsafeCell::new(p as usize), + _marker: PhantomData } } /// Loads a value from the pointer. diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs deleted file mode 100644 index 035443e9c3f35..0000000000000 --- a/src/libcore/borrow.rs +++ /dev/null @@ -1,265 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A module for working with borrowed data. -//! -//! # The `BorrowFrom` traits -//! -//! In general, there may be several ways to "borrow" a piece of data. The -//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` -//! (a mutable borrow). But types like `Vec` provide additional kinds of -//! borrows: the borrowed slices `&[T]` and `&mut [T]`. -//! -//! When writing generic code, it is often desirable to abstract over all ways -//! of borrowing data from a given type. That is the role of the `BorrowFrom` -//! trait: if `T: BorrowFrom`, then `&T` can be borrowed from `&U`. A given -//! type can be borrowed as multiple different types. In particular, `Vec: -//! BorrowFrom>` and `[T]: BorrowFrom>`. -//! -//! # The `ToOwned` trait -//! -//! Some types make it possible to go from borrowed to owned, usually by -//! implementing the `Clone` trait. But `Clone` works only for going from `&T` -//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data -//! from any borrow of a given type. -//! -//! # The `Cow` (clone-on-write) type -//! -//! The type `Cow` is a smart pointer providing clone-on-write functionality: it -//! can enclose and provide immutable access to borrowed data, and clone the -//! data lazily when mutation or ownership is required. The type is designed to -//! work with general borrowed data via the `BorrowFrom` trait. -//! -//! `Cow` implements both `Deref`, which means that you can call -//! non-mutating methods directly on the data it encloses. If mutation -//! is desired, `to_mut` will obtain a mutable references to an owned -//! value, cloning if necessary. - -#![unstable(feature = "core", - reason = "recently added as part of collections reform")] - -use clone::Clone; -use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; -use fmt; -use marker::Sized; -use ops::Deref; -use option::Option; -use self::Cow::*; - -/// A trait for borrowing data. -#[old_orphan_check] -pub trait BorrowFrom { - /// Immutably borrow from an owned value. - fn borrow_from(owned: &Owned) -> &Self; -} - -/// A trait for mutably borrowing data. -#[old_orphan_check] -pub trait BorrowFromMut : BorrowFrom { - /// Mutably borrow from an owned value. - fn borrow_from_mut(owned: &mut Owned) -> &mut Self; -} - -impl BorrowFrom for T { - fn borrow_from(owned: &T) -> &T { owned } -} - -impl BorrowFromMut for T { - fn borrow_from_mut(owned: &mut T) -> &mut T { owned } -} - -impl<'a, T: ?Sized> BorrowFrom<&'a T> for T { - fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned } -} - -impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T { - fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned } -} - -impl<'a, T: ?Sized> BorrowFromMut<&'a mut T> for T { - fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned } -} - -impl<'a, T, B: ?Sized> BorrowFrom> for B where B: ToOwned { - fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B { - &**owned - } -} - -/// Trait for moving into a `Cow` -#[old_orphan_check] -pub trait IntoCow<'a, T, B: ?Sized> { - /// Moves `self` into `Cow` - fn into_cow(self) -> Cow<'a, T, B>; -} - -impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned { - fn into_cow(self) -> Cow<'a, T, B> { - self - } -} - -/// A generalization of Clone to borrowed data. -#[old_orphan_check] -pub trait ToOwned: BorrowFrom { - /// Create owned data from borrowed data, usually by copying. - fn to_owned(&self) -> Owned; -} - -impl ToOwned for T where T: Clone { - fn to_owned(&self) -> T { self.clone() } -} - -/// A clone-on-write smart pointer. -/// -/// # Example -/// -/// ```rust -/// use std::borrow::Cow; -/// -/// fn abs_all(input: &mut Cow, [int]>) { -/// for i in 0..input.len() { -/// let v = input[i]; -/// if v < 0 { -/// // clones into a vector the first time (if not already owned) -/// input.to_mut()[i] = -v; -/// } -/// } -/// } -/// ``` -pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned { - /// Borrowed data. - Borrowed(&'a B), - - /// Owned data. - Owned(T) -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned { - fn clone(&self) -> Cow<'a, T, B> { - match *self { - Borrowed(b) => Borrowed(b), - Owned(ref o) => { - let b: &B = BorrowFrom::borrow_from(o); - Owned(b.to_owned()) - }, - } - } -} - -impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned { - /// Acquire a mutable reference to the owned form of the data. - /// - /// Copies the data if it is not already owned. - pub fn to_mut(&mut self) -> &mut T { - match *self { - Borrowed(borrowed) => { - *self = Owned(borrowed.to_owned()); - self.to_mut() - } - Owned(ref mut owned) => owned - } - } - - /// Extract the owned data. - /// - /// Copies the data if it is not already owned. - pub fn into_owned(self) -> T { - match self { - Borrowed(borrowed) => borrowed.to_owned(), - Owned(owned) => owned - } - } - - /// Returns true if this `Cow` wraps a borrowed value - pub fn is_borrowed(&self) -> bool { - match *self { - Borrowed(_) => true, - _ => false, - } - } - - /// Returns true if this `Cow` wraps an owned value - pub fn is_owned(&self) -> bool { - match *self { - Owned(_) => true, - _ => false, - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned { - type Target = B; - - fn deref(&self) -> &B { - match *self { - Borrowed(borrowed) => borrowed, - Owned(ref owned) => BorrowFrom::borrow_from(owned) - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned { - #[inline] - fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering { - Ord::cmp(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, T, B> where - B: PartialEq + ToOwned, - C: ToOwned, -{ - #[inline] - fn eq(&self, other: &Cow<'b, U, C>) -> bool { - PartialEq::eq(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned { - #[inline] - fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option { - PartialOrd::partial_cmp(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where - B: fmt::Debug + ToOwned, - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Borrowed(ref b) => fmt::Debug::fmt(b, f), - Owned(ref o) => fmt::Debug::fmt(o, f), - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where - B: fmt::Display + ToOwned, - T: fmt::Display, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Borrowed(ref b) => fmt::Display::fmt(b, f), - Owned(ref o) => fmt::Display::fmt(o, f), - } - } -} diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 19ec245300d02..b37bad5f7546c 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -215,7 +215,7 @@ impl Ord for Ordering { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn cmp(&self, other: &Ordering) -> Ordering { - (*self as int).cmp(&(*other as int)) + (*self as i32).cmp(&(*other as i32)) } } @@ -224,7 +224,7 @@ impl PartialOrd for Ordering { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn partial_cmp(&self, other: &Ordering) -> Option { - (*self as int).partial_cmp(&(*other as int)) + (*self as i32).partial_cmp(&(*other as i32)) } } @@ -482,7 +482,7 @@ mod impls { } partial_eq_impl! { - bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 + bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } macro_rules! eq_impl { @@ -492,7 +492,7 @@ mod impls { )*) } - eq_impl! { () bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 } + eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } macro_rules! partial_ord_impl { ($($t:ty)*) => ($( @@ -535,7 +535,7 @@ mod impls { } } - partial_ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } + partial_ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } macro_rules! ord_impl { ($($t:ty)*) => ($( @@ -565,7 +565,7 @@ mod impls { } } - ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 } + ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } // & pointers diff --git a/src/libcore/default.rs b/src/libcore/default.rs index d79b613f58949..7f46d9cbe5021 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -16,7 +16,7 @@ //! //! ``` //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! } //! ``` @@ -28,7 +28,7 @@ //! //! #[derive(Default)] //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! } //! @@ -56,7 +56,7 @@ //! //! #[derive(Default)] //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! baz: Kind, //! } @@ -73,7 +73,7 @@ //! # use std::default::Default; //! # #[derive(Default)] //! # struct SomeOptions { -//! # foo: int, +//! # foo: i32, //! # bar: f32, //! # } //! fn main() { @@ -93,7 +93,7 @@ /// ``` /// #[derive(Default)] /// struct SomeOptions { -/// foo: int, +/// foo: i32, /// bar: f32, /// } /// ``` @@ -113,7 +113,7 @@ pub trait Default { /// /// let i: i8 = Default::default(); /// let (x, y): (Option, f64) = Default::default(); - /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default(); + /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default(); /// ``` /// /// Making your own: @@ -150,13 +150,13 @@ default_impl! { (), () } default_impl! { bool, false } default_impl! { char, '\x00' } -default_impl! { uint, 0 } +default_impl! { usize, 0 } default_impl! { u8, 0 } default_impl! { u16, 0 } default_impl! { u32, 0 } default_impl! { u64, 0 } -default_impl! { int, 0 } +default_impl! { isize, 0 } default_impl! { i8, 0 } default_impl! { i16, 0 } default_impl! { i32, 0 } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 67c8c9fec09ab..a2c1bbc03317e 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -16,7 +16,7 @@ use any; use cell::{Cell, RefCell, Ref, RefMut, BorrowState}; use char::CharExt; use iter::{Iterator, IteratorExt}; -use marker::{Copy, Sized}; +use marker::{Copy, PhantomData, Sized}; use mem; use option::Option; use option::Option::{Some, None}; @@ -914,6 +914,11 @@ impl Debug for () { f.pad("()") } } +impl Debug for PhantomData { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("PhantomData") + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Debug for Cell { diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index a5d2618eff948..2e83334b93732 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -35,7 +35,7 @@ //! the trait `Hash`: //! //! ```rust -//! use std::hash::{hash, Hash, Hasher, Writer, SipHasher}; +//! use std::hash::{hash, Hash, Hasher, SipHasher}; //! //! struct Person { //! id: uint, @@ -43,8 +43,8 @@ //! phone: u64, //! } //! -//! impl Hash for Person { -//! fn hash(&self, state: &mut H) { +//! impl Hash for Person { +//! fn hash(&self, state: &mut H) { //! self.id.hash(state); //! self.phone.hash(state); //! } @@ -56,15 +56,12 @@ //! assert_eq!(hash::<_, SipHasher>(&person1), hash::<_, SipHasher>(&person2)); //! ``` -#![unstable(feature = "hash", - reason = "module was recently redesigned")] +#![stable(feature = "rust1", since = "1.0.0")] use prelude::*; -use borrow::{Cow, ToOwned}; use default::Default; use mem; -use num::Int; pub use self::sip::SipHasher; @@ -76,22 +73,123 @@ mod sip; /// to compute the hash. Specific implementations of this trait may specialize /// for particular instances of `H` in order to be able to optimize the hashing /// behavior. +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Hash { + /// Feeds this value into the state given, updating the hasher as necessary. + #[stable(feature = "rust1", since = "1.0.0")] + fn hash(&self, state: &mut H); + + /// Feeds a slice of this type into the state provided. + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn hash_slice(data: &[Self], state: &mut H) where Self: Sized { + for piece in data { + piece.hash(state); + } + } +} + +/// A hashable type. +/// +/// The `H` type parameter is an abstract hash state that is used by the `Hash` +/// to compute the hash. Specific implementations of this trait may specialize +/// for particular instances of `H` in order to be able to optimize the hashing +/// behavior. +#[cfg(stage0)] pub trait Hash { /// Feeds this value into the state given, updating the hasher as necessary. fn hash(&self, state: &mut H); } /// A trait which represents the ability to hash an arbitrary stream of bytes. +#[stable(feature = "rust1", since = "1.0.0")] pub trait Hasher { /// Result type of one run of hashing generated by this hasher. + #[cfg(stage0)] type Output; /// Resets this hasher back to its initial state (as if it were just /// created). + #[cfg(stage0)] fn reset(&mut self); /// Completes a round of hashing, producing the output hash generated. + #[cfg(stage0)] fn finish(&self) -> Self::Output; + + /// Completes a round of hashing, producing the output hash generated. + #[cfg(not(stage0))] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn finish(&self) -> u64; + + /// Writes some data into this `Hasher` + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + fn write(&mut self, bytes: &[u8]); + + /// Write a single `u8` into this hasher + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u8(&mut self, i: u8) { self.write(&[i]) } + /// Write a single `u16` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u16(&mut self, i: u16) { + self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) }) + } + /// Write a single `u32` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u32(&mut self, i: u32) { + self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) }) + } + /// Write a single `u64` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u64(&mut self, i: u64) { + self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) }) + } + /// Write a single `usize` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_usize(&mut self, i: usize) { + if cfg!(target_pointer_width = "32") { + self.write_u32(i as u32) + } else { + self.write_u64(i as u64) + } + } + + /// Write a single `i8` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) } + /// Write a single `i16` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) } + /// Write a single `i32` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) } + /// Write a single `i64` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) } + /// Write a single `isize` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) } } /// A common bound on the `Hasher` parameter to `Hash` implementations in order @@ -99,6 +197,7 @@ pub trait Hasher { #[unstable(feature = "hash", reason = "this trait will likely be replaced by io::Writer")] #[allow(missing_docs)] +#[cfg(stage0)] pub trait Writer { fn write(&mut self, bytes: &[u8]); } @@ -107,148 +206,292 @@ pub trait Writer { /// /// The specified value will be hashed with this hasher and then the resulting /// hash will be returned. +#[cfg(stage0)] pub fn hash, H: Hasher + Default>(value: &T) -> H::Output { let mut h: H = Default::default(); value.hash(&mut h); h.finish() } +/// Hash a value with the default SipHasher algorithm (two initial keys of 0). +/// +/// The specified value will be hashed with this hasher and then the resulting +/// hash will be returned. +#[cfg(not(stage0))] +#[unstable(feature = "hash", reason = "module was recently redesigned")] +pub fn hash(value: &T) -> u64 { + let mut h: H = Default::default(); + value.hash(&mut h); + h.finish() +} + ////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_hash { - ($ty:ident, $uty:ident) => { - impl Hash for $ty { - #[inline] - fn hash(&self, state: &mut S) { - let a: [u8; ::$ty::BYTES] = unsafe { - mem::transmute((*self as $uty).to_le() as $ty) - }; - state.write(&a) +#[cfg(stage0)] +mod impls { + use prelude::*; + + use mem; + use num::Int; + use super::*; + + macro_rules! impl_hash { + ($ty:ident, $uty:ident) => { + impl Hash for $ty { + #[inline] + fn hash(&self, state: &mut S) { + let a: [u8; ::$ty::BYTES] = unsafe { + mem::transmute(*self) + }; + state.write(&a) + } } } } -} -impl_hash! { u8, u8 } -impl_hash! { u16, u16 } -impl_hash! { u32, u32 } -impl_hash! { u64, u64 } -impl_hash! { uint, uint } -impl_hash! { i8, u8 } -impl_hash! { i16, u16 } -impl_hash! { i32, u32 } -impl_hash! { i64, u64 } -impl_hash! { int, uint } - -impl Hash for bool { - #[inline] - fn hash(&self, state: &mut S) { - (*self as u8).hash(state); + impl_hash! { u8, u8 } + impl_hash! { u16, u16 } + impl_hash! { u32, u32 } + impl_hash! { u64, u64 } + impl_hash! { uint, uint } + impl_hash! { i8, u8 } + impl_hash! { i16, u16 } + impl_hash! { i32, u32 } + impl_hash! { i64, u64 } + impl_hash! { int, uint } + + impl Hash for bool { + #[inline] + fn hash(&self, state: &mut S) { + (*self as u8).hash(state); + } } -} -impl Hash for char { - #[inline] - fn hash(&self, state: &mut S) { - (*self as u32).hash(state); + impl Hash for char { + #[inline] + fn hash(&self, state: &mut S) { + (*self as u32).hash(state); + } } -} -impl Hash for str { - #[inline] - fn hash(&self, state: &mut S) { - state.write(self.as_bytes()); - 0xffu8.hash(state) + impl Hash for str { + #[inline] + fn hash(&self, state: &mut S) { + state.write(self.as_bytes()); + 0xffu8.hash(state) + } } -} -macro_rules! impl_hash_tuple { - () => ( - impl Hash for () { - #[inline] - fn hash(&self, _state: &mut S) {} - } - ); - - ( $($name:ident)+) => ( - impl),*> Hash for ($($name,)*) { - #[inline] - #[allow(non_snake_case)] - fn hash(&self, state: &mut S) { - match *self { - ($(ref $name,)*) => { - $( - $name.hash(state); - )* + macro_rules! impl_hash_tuple { + () => ( + impl Hash for () { + #[inline] + fn hash(&self, _state: &mut S) {} + } + ); + + ( $($name:ident)+) => ( + impl),*> Hash for ($($name,)*) { + #[inline] + #[allow(non_snake_case)] + fn hash(&self, state: &mut S) { + match *self { + ($(ref $name,)*) => { + $( + $name.hash(state); + )* + } } } } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + impl> Hash for [T] { + #[inline] + fn hash(&self, state: &mut S) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } } - ); -} + } -impl_hash_tuple! {} -impl_hash_tuple! { A } -impl_hash_tuple! { A B } -impl_hash_tuple! { A B C } -impl_hash_tuple! { A B C D } -impl_hash_tuple! { A B C D E } -impl_hash_tuple! { A B C D E F } -impl_hash_tuple! { A B C D E F G } -impl_hash_tuple! { A B C D E F G H } -impl_hash_tuple! { A B C D E F G H I } -impl_hash_tuple! { A B C D E F G H I J } -impl_hash_tuple! { A B C D E F G H I J K } -impl_hash_tuple! { A B C D E F G H I J K L } - -impl> Hash for [T] { - #[inline] - fn hash(&self, state: &mut S) { - self.len().hash(state); - for elt in self { - elt.hash(state); + + impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a T { + #[inline] + fn hash(&self, state: &mut S) { + (**self).hash(state); } } -} + impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a mut T { + #[inline] + fn hash(&self, state: &mut S) { + (**self).hash(state); + } + } -impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a T { - #[inline] - fn hash(&self, state: &mut S) { - (**self).hash(state); + impl Hash for *const T { + #[inline] + fn hash(&self, state: &mut S) { + // NB: raw-pointer Hash does _not_ dereference + // to the target; it just gives you the pointer-bytes. + (*self as uint).hash(state); + } } -} -impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a mut T { - #[inline] - fn hash(&self, state: &mut S) { - (**self).hash(state); + impl Hash for *mut T { + #[inline] + fn hash(&self, state: &mut S) { + // NB: raw-pointer Hash does _not_ dereference + // to the target; it just gives you the pointer-bytes. + (*self as uint).hash(state); + } } } -impl Hash for *const T { - #[inline] - fn hash(&self, state: &mut S) { - // NB: raw-pointer Hash does _not_ dereference - // to the target; it just gives you the pointer-bytes. - (*self as uint).hash(state); +#[cfg(not(stage0))] +mod impls { + use prelude::*; + + use slice; + use super::*; + + macro_rules! impl_write { + ($(($ty:ident, $meth:ident),)*) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for $ty { + fn hash(&self, state: &mut H) { + state.$meth(*self) + } + + fn hash_slice(data: &[$ty], state: &mut H) { + let newlen = data.len() * ::$ty::BYTES; + let ptr = data.as_ptr() as *const u8; + state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) + } + } + )*} } -} -impl Hash for *mut T { - #[inline] - fn hash(&self, state: &mut S) { - // NB: raw-pointer Hash does _not_ dereference - // to the target; it just gives you the pointer-bytes. - (*self as uint).hash(state); + impl_write! { + (u8, write_u8), + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (usize, write_usize), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (isize, write_isize), } -} -impl<'a, T, B: ?Sized, S: Hasher> Hash for Cow<'a, T, B> - where B: Hash + ToOwned -{ - #[inline] - fn hash(&self, state: &mut S) { - Hash::hash(&**self, state) + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for bool { + fn hash(&self, state: &mut H) { + state.write_u8(*self as u8) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for char { + fn hash(&self, state: &mut H) { + state.write_u32(*self as u32) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for str { + fn hash(&self, state: &mut H) { + state.write(self.as_bytes()); + state.write_u8(0xff) + } + } + + macro_rules! impl_hash_tuple { + () => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for () { + fn hash(&self, _state: &mut H) {} + } + ); + + ( $($name:ident)+) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($name: Hash),*> Hash for ($($name,)*) { + #[allow(non_snake_case)] + fn hash(&self, state: &mut S) { + let ($(ref $name,)*) = *self; + $($name.hash(state);)* + } + } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for [T] { + fn hash(&self, state: &mut H) { + self.len().hash(state); + Hash::hash_slice(self, state) + } + } + + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a T { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a mut T { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for *const T { + fn hash(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for *mut T { + fn hash(&self, state: &mut H) { + state.write_usize(*self as usize) + } } } diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index d405d0d28beb3..ce8917cc20589 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -15,7 +15,9 @@ use prelude::*; use default::Default; -use super::{Hasher, Writer}; +use super::Hasher; +#[cfg(stage0)] +use super::Writer; /// An implementation of SipHash 2-4. /// @@ -30,6 +32,7 @@ use super::{Hasher, Writer}; /// strong, this implementation has not been reviewed for such purposes. /// As such, all cryptographic uses of this implementation are strongly /// discouraged. +#[stable(feature = "rust1", since = "1.0.0")] pub struct SipHasher { k0: u64, k1: u64, @@ -88,12 +91,14 @@ macro_rules! compress { impl SipHasher { /// Creates a new `SipHasher` with the two initial keys set to 0. #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> SipHasher { SipHasher::new_with_keys(0, 0) } /// Creates a `SipHasher` that is keyed off the provided keys. #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher { let mut state = SipHasher { k0: key0, @@ -114,10 +119,16 @@ impl SipHasher { #[unstable(feature = "hash")] #[deprecated(since = "1.0.0", reason = "renamed to finish")] pub fn result(&self) -> u64 { self.finish() } -} -impl Writer for SipHasher { - #[inline] + fn reset(&mut self) { + self.length = 0; + self.v0 = self.k0 ^ 0x736f6d6570736575; + self.v1 = self.k1 ^ 0x646f72616e646f6d; + self.v2 = self.k0 ^ 0x6c7967656e657261; + self.v3 = self.k1 ^ 0x7465646279746573; + self.ntail = 0; + } + fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -164,16 +175,28 @@ impl Writer for SipHasher { } } +#[cfg(stage0)] +impl Writer for SipHasher { + #[inline] + fn write(&mut self, msg: &[u8]) { + self.write(msg) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] impl Hasher for SipHasher { + #[cfg(stage0)] type Output = u64; + #[cfg(stage0)] fn reset(&mut self) { - self.length = 0; - self.v0 = self.k0 ^ 0x736f6d6570736575; - self.v1 = self.k1 ^ 0x646f72616e646f6d; - self.v2 = self.k0 ^ 0x6c7967656e657261; - self.v3 = self.k1 ^ 0x7465646279746573; - self.ntail = 0; + self.reset(); + } + + #[inline] + #[cfg(not(stage0))] + fn write(&mut self, msg: &[u8]) { + self.write(msg) } fn finish(&self) -> u64 { @@ -199,6 +222,7 @@ impl Hasher for SipHasher { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Clone for SipHasher { #[inline] fn clone(&self) -> SipHasher { @@ -216,6 +240,7 @@ impl Clone for SipHasher { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Default for SipHasher { fn default() -> SipHasher { SipHasher::new() diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 050c144b74299..b2ee95963878e 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -50,10 +50,10 @@ pub type GlueFn = extern "Rust" fn(*const i8); #[derive(Copy)] pub struct TyDesc { // sizeof(T) - pub size: uint, + pub size: usize, // alignof(T) - pub align: uint, + pub align: usize, // Called when a value of type `T` is no longer needed pub drop_glue: GlueFn, @@ -186,15 +186,15 @@ extern "rust-intrinsic" { /// would *exactly* overwrite a value. When laid out in vectors /// and structures there may be additional padding between /// elements. - pub fn size_of() -> uint; + pub fn size_of() -> usize; /// Move a value to an uninitialized memory location. /// /// Drop glue is not run on the destination. pub fn move_val_init(dst: &mut T, src: T); - pub fn min_align_of() -> uint; - pub fn pref_align_of() -> uint; + pub fn min_align_of() -> usize; + pub fn pref_align_of() -> usize; /// Get a static pointer to a type descriptor. pub fn get_tydesc() -> *const TyDesc; @@ -253,7 +253,7 @@ extern "rust-intrinsic" { /// /// This is implemented as an intrinsic to avoid converting to and from an /// integer, since the conversion would throw away aliasing information. - pub fn offset(dst: *const T, offset: int) -> *const T; + pub fn offset(dst: *const T, offset: isize) -> *const T; /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may *not* overlap. @@ -294,7 +294,7 @@ extern "rust-intrinsic" { /// } /// ``` #[unstable(feature = "core")] - pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint); + pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may overlap. @@ -324,13 +324,13 @@ extern "rust-intrinsic" { /// ``` /// #[unstable(feature = "core")] - pub fn copy_memory(dst: *mut T, src: *const T, count: uint); + pub fn copy_memory(dst: *mut T, src: *const T, count: usize); /// Invokes memset on the specified pointer, setting `count * size_of::()` /// bytes of memory starting at `dst` to `c`. #[unstable(feature = "core", reason = "uncertain about naming and semantics")] - pub fn set_memory(dst: *mut T, val: u8, count: uint); + pub fn set_memory(dst: *mut T, val: u8, count: usize); /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of @@ -338,19 +338,19 @@ extern "rust-intrinsic" { /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, - count: uint); + count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. - pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: uint); + pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count` * `size_of::()` and an alignment of /// `min_align_of::()`. /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. - pub fn volatile_set_memory(dst: *mut T, val: u8, count: uint); + pub fn volatile_set_memory(dst: *mut T, val: u8, count: usize); /// Perform a volatile load from the `src` pointer. pub fn volatile_load(src: *const T) -> T; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index fffba1561a380..8fb10b5b2dc2a 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -62,6 +62,7 @@ use clone::Clone; use cmp; use cmp::Ord; use default::Default; +use marker; use mem; use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; @@ -113,9 +114,9 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ built from an iterator over elements of type `{A}`"] pub trait FromIterator { - /// Build a container with elements from an external iterator. + /// Build a container with elements from something iterable. #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter>(iterator: T) -> Self; + fn from_iter>(iterator: T) -> Self; } /// Conversion into an `Iterator` @@ -147,7 +148,7 @@ impl IntoIterator for I { pub trait Extend { /// Extend a container with the elements yielded by an arbitrary iterator #[stable(feature = "rust1", since = "1.0.0")] - fn extend>(&mut self, iterator: T); + fn extend>(&mut self, iterable: T); } /// An extension trait providing numerous methods applicable to all iterators. @@ -332,7 +333,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let xs = [100, 200, 300]; - /// let mut it = xs.iter().map(|x| *x).peekable(); + /// let mut it = xs.iter().cloned().peekable(); /// assert_eq!(*it.peek().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 200); @@ -522,11 +523,11 @@ pub trait IteratorExt: Iterator + Sized { /// /// let a = [1, 4, 2, 3, 8, 9, 6]; /// let sum = a.iter() - /// .map(|&x| x) - /// .inspect(|&x| println!("filtering {}", x)) - /// .filter(|&x| x % 2 == 0) - /// .inspect(|&x| println!("{} made it through", x)) - /// .sum(); + /// .map(|x| *x) + /// .inspect(|&x| println!("filtering {}", x)) + /// .filter(|&x| x % 2 == 0) + /// .inspect(|&x| println!("{} made it through", x)) + /// .sum(); /// println!("{}", sum); /// ``` #[inline] @@ -561,7 +562,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// let b: Vec<_> = a.iter().map(|&x| x).collect(); + /// let b: Vec<_> = a.iter().cloned().collect(); /// assert_eq!(a, b); /// ``` #[inline] @@ -937,7 +938,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let a = [(1, 2), (3, 4)]; - /// let (left, right): (Vec<_>, Vec<_>) = a.iter().map(|&x| x).unzip(); + /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); /// assert_eq!([1, 3], left); /// assert_eq!([2, 4], right); /// ``` @@ -947,7 +948,7 @@ pub trait IteratorExt: Iterator + Sized { FromB: Default + Extend, Self: Iterator, { - struct SizeHint(usize, Option); + struct SizeHint(usize, Option, marker::PhantomData); impl Iterator for SizeHint { type Item = A; @@ -961,8 +962,8 @@ pub trait IteratorExt: Iterator + Sized { let mut ts: FromA = Default::default(); let mut us: FromB = Default::default(); - ts.extend(SizeHint(lo, hi)); - us.extend(SizeHint(lo, hi)); + ts.extend(SizeHint(lo, hi, marker::PhantomData)); + us.extend(SizeHint(lo, hi, marker::PhantomData)); for (t, u) in self { ts.extend(Some(t).into_iter()); @@ -1142,7 +1143,7 @@ pub trait AdditiveIterator { /// use std::iter::AdditiveIterator; /// /// let a = [1i32, 2, 3, 4, 5]; - /// let mut it = a.iter().map(|&x| x); + /// let mut it = a.iter().cloned(); /// assert!(it.sum() == 15); /// ``` fn sum(self) -> A; @@ -1305,6 +1306,23 @@ impl ExactSizeIterator for Cloned where I: ExactSizeIterator, {} +#[unstable(feature = "core", reason = "trait is experimental")] +impl RandomAccessIterator for Cloned where + T: Clone, + D: Deref, + I: RandomAccessIterator +{ + #[inline] + fn indexable(&self) -> usize { + self.it.indexable() + } + + #[inline] + fn idx(&mut self, index: usize) -> Option { + self.it.idx(index).cloned() + } +} + /// An iterator that repeats endlessly #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -2047,8 +2065,8 @@ pub struct Scan { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Scan where - F: FnMut(&mut St, I::Item) -> Option, +impl, St, F> Iterator for Scan where + F: FnMut(&mut St, A) -> Option, { type Item = B; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index f0c60ffe4bf66..3c58480ff0cfa 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -126,7 +126,6 @@ pub mod default; pub mod any; pub mod atomic; -pub mod borrow; pub mod cell; pub mod char; pub mod panicking; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 56e1c5dedc1ce..d284eb341792b 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -26,6 +26,10 @@ #![stable(feature = "rust1", since = "1.0.0")] use clone::Clone; +use cmp; +use option::Option; +use hash::Hash; +use hash::Hasher; /// Types able to be transferred across thread boundaries. #[unstable(feature = "core", @@ -37,12 +41,11 @@ pub unsafe trait Send: 'static { // empty. } /// Types able to be transferred across thread boundaries. -#[unstable(feature = "core", - reason = "will be overhauled with new lifetime rules; see RFC 458")] +#[stable(feature = "rust1", since = "1.0.0")] #[lang="send"] #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] #[cfg(not(stage0))] -pub unsafe trait Send { +pub unsafe trait Send : MarkerTrait { // empty. } @@ -50,7 +53,7 @@ pub unsafe trait Send { #[stable(feature = "rust1", since = "1.0.0")] #[lang="sized"] #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] -pub trait Sized { +pub trait Sized : MarkerTrait { // Empty. } @@ -155,7 +158,7 @@ pub trait Sized { /// change: that second example would fail to compile if we made `Foo` non-`Copy`. #[stable(feature = "rust1", since = "1.0.0")] #[lang="copy"] -pub trait Copy { +pub trait Copy : MarkerTrait { // Empty. } @@ -204,236 +207,179 @@ pub trait Copy { /// around the value(s) which can be mutated when behind a `&` /// reference; not doing this is undefined behaviour (for example, /// `transmute`-ing from `&T` to `&mut T` is illegal). -#[unstable(feature = "core", - reason = "will be overhauled with new lifetime rules; see RFC 458")] +#[stable(feature = "rust1", since = "1.0.0")] #[lang="sync"] #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] -pub unsafe trait Sync { +pub unsafe trait Sync : MarkerTrait { // Empty } -/// A marker type that indicates to the compiler that the instances -/// of the type itself owns instances of the type parameter `T`. -/// -/// This is used to indicate that one or more instances of the type -/// `T` could be dropped when instances of the type itself is dropped, -/// though that may not be apparent from the other structure of the -/// type itself. For example, the type may hold a `*mut T`, which the -/// compiler does not automatically treat as owned. +/// A type which is considered "not POD", meaning that it is not +/// implicitly copyable. This is typically embedded in other types to +/// ensure that they are never copied, even if they lack a destructor. #[unstable(feature = "core", - reason = "Newly added to deal with scoping and destructor changes")] -#[lang="phantom_data"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct PhantomData; + reason = "likely to change with new variance strategy")] +#[lang="no_copy_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct NoCopy; -impl Copy for PhantomData {} -impl Clone for PhantomData { - fn clone(&self) -> PhantomData { *self } +/// A type which is considered managed by the GC. This is typically +/// embedded in other types. +#[unstable(feature = "core", + reason = "likely to change with new variance strategy")] +#[lang="managed_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Managed; + +macro_rules! impls{ + ($t: ident) => ( + #[cfg(stage0)] + impl Hash for $t { + #[inline] + fn hash(&self, _: &mut S) { + } + } + #[cfg(not(stage0))] + impl Hash for $t { + #[inline] + fn hash(&self, _: &mut H) { + } + } + + impl cmp::PartialEq for $t { + fn eq(&self, _other: &$t) -> bool { + true + } + } + + impl cmp::Eq for $t { + } + + impl cmp::PartialOrd for $t { + fn partial_cmp(&self, _other: &$t) -> Option { + Option::Some(cmp::Ordering::Equal) + } + } + + impl cmp::Ord for $t { + fn cmp(&self, _other: &$t) -> cmp::Ordering { + cmp::Ordering::Equal + } + } + + impl Copy for $t { } + + impl Clone for $t { + fn clone(&self) -> $t { + $t + } + } + ) } -/// A marker type whose type parameter `T` is considered to be -/// covariant with respect to the type itself. This is (typically) -/// used to indicate that an instance of the type `T` is being stored -/// into memory and read from, even though that may not be apparent. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -/// -/// *Note:* It is very unusual to have to add a covariant constraint. -/// If you are not sure, you probably want to use `InvariantType`. +/// `MarkerTrait` is intended to be used as the supertrait for traits +/// that don't have any methods but instead serve just to designate +/// categories of types. An example would be the `Send` trait, which +/// indicates types that are sendable: `Send` does not itself offer +/// any methods, but instead is used to gate access to data. +/// +/// FIXME. Better documentation needed here! +pub trait MarkerTrait : PhantomFn { } +impl MarkerTrait for T { } + +/// `PhantomFn` is a marker trait for use with traits that contain +/// type or lifetime parameters that do not appear in any of their +/// methods. In that case, you can either remove those parameters, or +/// add a `PhantomFn` supertrait that reflects the signature of +/// methods that compiler should "pretend" exists. This most commonly +/// occurs for traits with no methods: in that particular case, you +/// can extend `MarkerTrait`, which is equivalent to +/// `PhantomFn`. /// /// # Example /// -/// Given a struct `S` that includes a type parameter `T` -/// but does not actually *reference* that type parameter: +/// As an example, consider a trait with no methods like `Even`, meant +/// to represent types that are "even": /// -/// ```ignore -/// use std::mem; -/// -/// struct S { x: *() } -/// fn get(s: &S) -> T { -/// unsafe { -/// let x: *T = mem::transmute(s.x); -/// *x -/// } -/// } +/// ```rust,ignore +/// trait Even { } /// ``` /// -/// The type system would currently infer that the value of -/// the type parameter `T` is irrelevant, and hence a `S` is -/// a subtype of `S>` (or, for that matter, `S` for -/// any `U`). But this is incorrect because `get()` converts the -/// `*()` into a `*T` and reads from it. Therefore, we should include the -/// a marker field `CovariantType` to inform the type checker that -/// `S` is a subtype of `S` if `T` is a subtype of `U` -/// (for example, `S<&'static int>` is a subtype of `S<&'a int>` -/// for some lifetime `'a`, but not the other way around). -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="covariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct CovariantType; - -impl Copy for CovariantType {} -impl Clone for CovariantType { - fn clone(&self) -> CovariantType { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// contravariant with respect to the type itself. This is (typically) -/// used to indicate that an instance of the type `T` will be consumed -/// (but not read from), even though that may not be apparent. +/// In this case, because the implicit parameter `Self` is unused, the +/// compiler will issue an error. The only purpose of this trait is to +/// categorize types (and hence instances of those types) as "even" or +/// not, so if we *were* going to have a method, it might look like: /// -/// For more information about variance, refer to this Wikipedia -/// article . +/// ```rust,ignore +/// trait Even { +/// fn is_even(self) -> bool { true } +/// } +/// ``` /// -/// *Note:* It is very unusual to have to add a contravariant constraint. -/// If you are not sure, you probably want to use `InvariantType`. +/// Therefore, we can model a method like this as follows: /// -/// # Example +/// ```rust +/// use std::marker::PhantomFn; +/// trait Even : PhantomFn { } +/// ``` /// -/// Given a struct `S` that includes a type parameter `T` -/// but does not actually *reference* that type parameter: +/// Another equivalent, but clearer, option would be to use +/// `MarkerTrait`: /// +/// ```rust +/// use std::marker::MarkerTrait; +/// trait Even : MarkerTrait { } /// ``` -/// use std::mem; -/// -/// struct S { x: *const () } -/// fn get(s: &S, v: T) { -/// unsafe { -/// let x: fn(T) = mem::transmute(s.x); -/// x(v) -/// } -/// } -/// ``` -/// -/// The type system would currently infer that the value of -/// the type parameter `T` is irrelevant, and hence a `S` is -/// a subtype of `S>` (or, for that matter, `S` for -/// any `U`). But this is incorrect because `get()` converts the -/// `*()` into a `fn(T)` and then passes a value of type `T` to it. -/// -/// Supplying a `ContravariantType` marker would correct the -/// problem, because it would mark `S` so that `S` is only a -/// subtype of `S` if `U` is a subtype of `T`; given that the -/// function requires arguments of type `T`, it must also accept -/// arguments of type `U`, hence such a conversion is safe. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="contravariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct ContravariantType; - -impl Copy for ContravariantType {} -impl Clone for ContravariantType { - fn clone(&self) -> ContravariantType { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// invariant with respect to the type itself. This is (typically) -/// used to indicate that instances of the type `T` may be read or -/// written, even though that may not be apparent. /// -/// For more information about variance, refer to this Wikipedia -/// article . +/// # Parameters /// -/// # Example +/// - `A` represents the type of the method's argument. You can use a +/// tuple to represent "multiple" arguments. Any types appearing here +/// will be considered "contravariant". +/// - `R`, if supplied, represents the method's return type. This defaults +/// to `()` as it is rarely needed. /// -/// The Cell type is an example of an `InvariantType` which uses unsafe -/// code to achieve "interior" mutability: +/// # Additional reading /// -/// ``` -/// struct Cell { value: T } -/// ``` +/// More details and background can be found in [RFC 738][738]. /// -/// The type system would infer that `value` is only read here -/// and never written, but in fact `Cell` uses unsafe code to achieve -/// interior mutability. In order to get correct behavior, the -/// `InvariantType` marker must be applied. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="invariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct InvariantType; - -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -impl Copy for InvariantType {} -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -impl Clone for InvariantType { - fn clone(&self) -> InvariantType { *self } -} - -/// As `CovariantType`, but for lifetime parameters. Using -/// `CovariantLifetime<'a>` indicates that it is ok to substitute -/// a *longer* lifetime for `'a` than the one you originally -/// started with (e.g., you could convert any lifetime `'foo` to -/// `'static`). You almost certainly want `ContravariantLifetime` -/// instead, or possibly `InvariantLifetime`. The only case where -/// it would be appropriate is that you have a (type-casted, and -/// hence hidden from the type system) function pointer with a -/// signature like `fn(&'a T)` (and no other uses of `'a`). In -/// this case, it is ok to substitute a larger lifetime for `'a` -/// (e.g., `fn(&'static T)`), because the function is only -/// becoming more selective in terms of what it accepts as -/// argument. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="covariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct CovariantLifetime<'a>; +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md +#[lang="phantom_fn"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait PhantomFn { } -/// As `ContravariantType`, but for lifetime parameters. Using -/// `ContravariantLifetime<'a>` indicates that it is ok to -/// substitute a *shorter* lifetime for `'a` than the one you -/// originally started with (e.g., you could convert `'static` to -/// any lifetime `'foo`). This is appropriate for cases where you -/// have an unsafe pointer that is actually a pointer into some -/// memory with lifetime `'a`, and thus you want to limit the -/// lifetime of your data structure to `'a`. An example of where -/// this is used is the iterator for vectors. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="contravariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct ContravariantLifetime<'a>; +#[cfg(stage0)] // built into the trait matching system after stage0 +impl PhantomFn for U { } -/// As `InvariantType`, but for lifetime parameters. Using -/// `InvariantLifetime<'a>` indicates that it is not ok to -/// substitute any other lifetime for `'a` besides its original -/// value. This is appropriate for cases where you have an unsafe -/// pointer that is actually a pointer into memory with lifetime `'a`, -/// and this pointer is itself stored in an inherently mutable -/// location (such as a `Cell`). -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="invariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct InvariantLifetime<'a>; +/// Specific to stage0. You should not be seeing these docs! +#[cfg(stage0)] +#[lang="covariant_type"] // only relevant to stage0 +pub struct PhantomData; -/// A type which is considered "not POD", meaning that it is not -/// implicitly copyable. This is typically embedded in other types to -/// ensure that they are never copied, even if they lack a destructor. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="no_copy_bound"] -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct NoCopy; +/// `PhantomData` is a way to tell the compiler about fake fields. +/// Phantom data is required whenever type parameters are not used. +/// The idea is that if the compiler encounters a `PhantomData` +/// instance, it will behave *as if* an instance of the type `T` were +/// present for the purpose of various automatic analyses. +/// +/// For example, embedding a `PhantomData` will inform the compiler +/// that one or more instances of the type `T` could be dropped when +/// instances of the type itself is dropped, though that may not be +/// apparent from the other structure of the type itself. This is +/// commonly necessary if the structure is using an unsafe pointer +/// like `*mut T` whose referent may be dropped when the type is +/// dropped, as a `*mut T` is otherwise not treated as owned. +/// +/// FIXME. Better documentation and examples of common patterns needed +/// here! For now, please see [RFC 738][738] for more information. +/// +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md +#[cfg(not(stage0))] +#[lang="phantom_data"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct PhantomData; -/// A type which is considered managed by the GC. This is typically -/// embedded in other types. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="managed_bound"] -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Managed; +impls! { PhantomData } #[cfg(not(stage0))] mod impls { @@ -442,3 +388,40 @@ mod impls { unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} } + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")] +#[lang="contravariant_lifetime"] +pub struct ContravariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData`")] +#[lang="covariant_lifetime"] +pub struct CovariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData>`")] +#[lang="invariant_lifetime"] +pub struct InvariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData`")] +#[lang="contravariant_type"] +pub struct ContravariantType; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData`")] +#[lang="covariant_type"] +#[cfg(not(stage0))] +pub struct CovariantType; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData>`")] +#[lang="invariant_type"] +pub struct InvariantType; diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 5644f76306929..230587b726fd1 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -10,15 +10,14 @@ //! Exposes the NonZero lang item which provides optimization hints. +use marker::{Sized, MarkerTrait}; use ops::Deref; -use ptr::Unique; /// Unsafe trait to indicate what types are usable with the NonZero struct -pub unsafe trait Zeroable {} +pub unsafe trait Zeroable : MarkerTrait {} -unsafe impl Zeroable for *const T {} -unsafe impl Zeroable for *mut T {} -unsafe impl Zeroable for Unique { } +unsafe impl Zeroable for *const T {} +unsafe impl Zeroable for *mut T {} unsafe impl Zeroable for isize {} unsafe impl Zeroable for usize {} unsafe impl Zeroable for i8 {} diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9a89682127fb1..abfef72a5dbc3 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -149,7 +149,7 @@ use clone::Clone; use cmp::{Eq, Ord}; use default::Default; use iter::{ExactSizeIterator}; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator}; use mem; use ops::{Deref, FnOnce}; use result::Result::{Ok, Err}; @@ -909,7 +909,7 @@ impl> FromIterator> for Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter>>(iter: I) -> Option { + fn from_iter>>(iter: I) -> Option { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -934,7 +934,7 @@ impl> FromIterator> for Option { } } - let mut adapter = Adapter { iter: iter, found_none: false }; + let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; let v: V = FromIterator::from_iter(adapter.by_ref()); if adapter.found_none { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 072c60c7036cf..16b84dcf18e24 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -91,8 +91,10 @@ use mem; use clone::Clone; use intrinsics; +use ops::Deref; use option::Option::{self, Some, None}; -use marker::{self, Send, Sized, Sync}; +use marker::{PhantomData, Send, Sized, Sync}; +use nonzero::NonZero; use cmp::{PartialEq, Eq, Ord, PartialOrd}; use cmp::Ordering::{self, Less, Equal, Greater}; @@ -303,7 +305,7 @@ impl PtrExt for *const T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn is_null(self) -> bool { self as usize == 0 } + fn is_null(self) -> bool { self == 0 as *const T } #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -330,7 +332,7 @@ impl PtrExt for *mut T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn is_null(self) -> bool { self as usize == 0 } + fn is_null(self) -> bool { self == 0 as *mut T } #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -517,15 +519,16 @@ impl PartialOrd for *mut T { /// A wrapper around a raw `*mut T` that indicates that the possessor /// of this wrapper owns the referent. This in turn implies that the -/// `Unique` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a -/// raw `*mut T` (which conveys no particular ownership semantics). -/// Useful for building abstractions like `Vec` or `Box`, which +/// `Unique` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw +/// `*mut T` (which conveys no particular ownership semantics). It +/// also implies that the referent of the pointer should not be +/// modified without a unique path to the `Unique` reference. Useful +/// for building abstractions like `Vec` or `Box`, which /// internally use raw pointers to manage the memory that they own. #[unstable(feature = "core", reason = "recently added to this module")] -pub struct Unique { - /// The wrapped `*mut T`. - pub ptr: *mut T, - _own: marker::PhantomData, +pub struct Unique { + pointer: NonZero<*const T>, + _marker: PhantomData, } /// `Unique` pointers are `Send` if `T` is `Send` because the data they @@ -542,25 +545,34 @@ unsafe impl Send for Unique { } #[unstable(feature = "core", reason = "recently added to this module")] unsafe impl Sync for Unique { } -impl Unique { - /// Returns a null Unique. +impl Unique { + /// Create a new `Unique`. #[unstable(feature = "core", reason = "recently added to this module")] - pub fn null() -> Unique { - Unique(null_mut()) + pub unsafe fn new(ptr: *mut T) -> Unique { + Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData } } - /// Return an (unsafe) pointer into the memory owned by `self`. + /// Dereference the content. #[unstable(feature = "core", reason = "recently added to this module")] - pub unsafe fn offset(self, offset: isize) -> *mut T { - self.ptr.offset(offset) + pub unsafe fn get(&self) -> &T { + &**self.pointer + } + + /// Mutably dereference the content. + #[unstable(feature = "core", + reason = "recently added to this module")] + pub unsafe fn get_mut(&mut self) -> &mut T { + &mut ***self } } -/// Creates a `Unique` wrapped around `ptr`, taking ownership of the -/// data referenced by `ptr`. -#[allow(non_snake_case)] -pub fn Unique(ptr: *mut T) -> Unique { - Unique { ptr: ptr, _own: marker::PhantomData } +impl Deref for Unique { + type Target = *mut T; + + #[inline] + fn deref<'a>(&'a self) -> &'a *mut T { + unsafe { mem::transmute(&*self.pointer) } + } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 1a874ee178ba0..23e936a75d709 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -230,7 +230,8 @@ use self::Result::{Ok, Err}; use clone::Clone; use fmt; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, + FromIterator, ExactSizeIterator, IntoIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; use slice::AsSlice; @@ -906,7 +907,7 @@ impl> FromIterator> for Result { /// assert!(res == Ok(vec!(2, 3))); /// ``` #[inline] - fn from_iter>>(iter: I) -> Result { + fn from_iter>>(iter: I) -> Result { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -931,7 +932,7 @@ impl> FromIterator> for Result { } } - let mut adapter = Adapter { iter: iter, err: None }; + let mut adapter = Adapter { iter: iter.into_iter(), err: None }; let v: V = FromIterator::from_iter(adapter.by_ref()); match adapter.err { diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index bbfe7e58ef4ac..a86da53b372a9 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -140,11 +140,11 @@ impl SliceExt for [T] { if mem::size_of::() == 0 { Iter {ptr: p, end: (p as usize + self.len()) as *const T, - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } else { Iter {ptr: p, end: p.offset(self.len() as isize), - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } } } @@ -279,11 +279,11 @@ impl SliceExt for [T] { if mem::size_of::() == 0 { IterMut {ptr: p, end: (p as usize + self.len()) as *mut T, - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } else { IterMut {ptr: p, end: p.offset(self.len() as isize), - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } } } @@ -733,7 +733,7 @@ macro_rules! make_slice { pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, - marker: marker::ContravariantLifetime<'a> + _marker: marker::PhantomData<&'a T>, } #[unstable(feature = "core")] @@ -790,7 +790,7 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { - fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, marker: self.marker } } + fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } } #[unstable(feature = "core", reason = "trait is experimental")] @@ -823,7 +823,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> { pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, - marker: marker::ContravariantLifetime<'a>, + _marker: marker::PhantomData<&'a mut T>, } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ce26abe606dd4..eec997b9f10fc 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1280,7 +1280,7 @@ mod traits { /// Any string that can be represented as a slice #[unstable(feature = "core", reason = "Instead of taking this bound generically, this trait will be \ - replaced with one of slicing syntax (&foo[]), deref coercions, or \ + replaced with one of slicing syntax (&foo[..]), deref coercions, or \ a more generic conversion trait")] pub trait Str { /// Work with `self` as a slice. diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs index fd0d3c676a45a..9b6af182f729c 100644 --- a/src/libcoretest/hash/mod.rs +++ b/src/libcoretest/hash/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::mem; -use std::hash::{Hash, Hasher, Writer}; +use std::hash::{Hash, Hasher}; use std::default::Default; struct MyHasher { @@ -22,25 +22,19 @@ impl Default for MyHasher { } } -impl Writer for MyHasher { - // Most things we'll just add up the bytes. +impl Hasher for MyHasher { fn write(&mut self, buf: &[u8]) { for byte in buf { self.hash += *byte as u64; } } -} - -impl Hasher for MyHasher { - type Output = u64; - fn reset(&mut self) { self.hash = 0; } fn finish(&self) -> u64 { self.hash } } #[test] fn test_writer_hasher() { - fn hash>(t: &T) -> u64 { + fn hash(t: &T) -> u64 { ::std::hash::hash::<_, MyHasher>(t) } @@ -90,9 +84,9 @@ struct Custom { hash: u64 } struct CustomHasher { output: u64 } impl Hasher for CustomHasher { - type Output = u64; - fn reset(&mut self) { self.output = 0; } fn finish(&self) -> u64 { self.output } + fn write(&mut self, data: &[u8]) { panic!() } + fn write_u64(&mut self, data: u64) { self.output = data; } } impl Default for CustomHasher { @@ -101,15 +95,15 @@ impl Default for CustomHasher { } } -impl Hash for Custom { - fn hash(&self, state: &mut CustomHasher) { - state.output = self.hash; +impl Hash for Custom { + fn hash(&self, state: &mut H) { + state.write_u64(self.hash); } } #[test] fn test_custom_state() { - fn hash>(t: &T) -> u64 { + fn hash(t: &T) -> u64 { ::std::hash::hash::<_, CustomHasher>(t) } diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 7eb0fb97bed2a..39a590c730743 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -91,7 +91,7 @@ fn test_iterator_chain() { assert_eq!(i, expected.len()); let ys = count(30, 10).take(4); - let mut it = xs.iter().map(|&x| x).chain(ys); + let mut it = xs.iter().cloned().chain(ys); let mut i = 0; for x in it { assert_eq!(x, expected[i]); @@ -119,7 +119,7 @@ fn test_iterator_enumerate() { #[test] fn test_iterator_peekable() { let xs = vec![0, 1, 2, 3, 4, 5]; - let mut it = xs.iter().map(|&x|x).peekable(); + let mut it = xs.iter().cloned().peekable(); assert_eq!(it.len(), 6); assert_eq!(it.peek().unwrap(), &0); @@ -259,12 +259,12 @@ fn test_inspect() { let mut n = 0; let ys = xs.iter() - .map(|&x| x) + .cloned() .inspect(|_| n += 1) .collect::>(); assert_eq!(n, xs.len()); - assert_eq!(&xs[], &ys[]); + assert_eq!(&xs[..], &ys[..]); } #[test] @@ -329,33 +329,33 @@ fn test_iterator_len() { #[test] fn test_iterator_sum() { let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).sum(), 6); - assert_eq!(v.iter().map(|&x| x).sum(), 55); - assert_eq!(v[..0].iter().map(|&x| x).sum(), 0); + assert_eq!(v[..4].iter().cloned().sum(), 6); + assert_eq!(v.iter().cloned().sum(), 55); + assert_eq!(v[..0].iter().cloned().sum(), 0); } #[test] fn test_iterator_product() { let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).product(), 0); - assert_eq!(v[1..5].iter().map(|&x| x).product(), 24); - assert_eq!(v[..0].iter().map(|&x| x).product(), 1); + assert_eq!(v[..4].iter().cloned().product(), 0); + assert_eq!(v[1..5].iter().cloned().product(), 24); + assert_eq!(v[..0].iter().cloned().product(), 1); } #[test] fn test_iterator_max() { let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).max(), Some(3)); - assert_eq!(v.iter().map(|&x| x).max(), Some(10)); - assert_eq!(v[..0].iter().map(|&x| x).max(), None); + assert_eq!(v[..4].iter().cloned().max(), Some(3)); + assert_eq!(v.iter().cloned().max(), Some(10)); + assert_eq!(v[..0].iter().cloned().max(), None); } #[test] fn test_iterator_min() { let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).min(), Some(0)); - assert_eq!(v.iter().map(|&x| x).min(), Some(0)); - assert_eq!(v[..0].iter().map(|&x| x).min(), None); + assert_eq!(v[..4].iter().cloned().min(), Some(0)); + assert_eq!(v.iter().cloned().min(), Some(0)); + assert_eq!(v[..0].iter().cloned().min(), None); } #[test] @@ -373,7 +373,7 @@ fn test_iterator_size_hint() { assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None)); assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None)); assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None)); - assert_eq!(c.clone().chain(vi.clone().map(|&i| i)).size_hint(), (uint::MAX, None)); + assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None)); assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10))); assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None)); assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None)); @@ -398,7 +398,7 @@ fn test_iterator_size_hint() { #[test] fn test_collect() { let a = vec![1, 2, 3, 4, 5]; - let b: Vec = a.iter().map(|&x| x).collect(); + let b: Vec = a.iter().cloned().collect(); assert!(a == b); } @@ -471,7 +471,7 @@ fn test_rev() { let mut it = xs.iter(); it.next(); it.next(); - assert!(it.rev().map(|&x| x).collect::>() == + assert!(it.rev().cloned().collect::>() == vec![16, 14, 12, 10, 8, 6]); } @@ -508,7 +508,7 @@ fn test_double_ended_map() { #[test] fn test_double_ended_enumerate() { let xs = [1, 2, 3, 4, 5, 6]; - let mut it = xs.iter().map(|&x| x).enumerate(); + let mut it = xs.iter().cloned().enumerate(); assert_eq!(it.next(), Some((0, 1))); assert_eq!(it.next(), Some((1, 2))); assert_eq!(it.next_back(), Some((5, 6))); @@ -522,8 +522,8 @@ fn test_double_ended_enumerate() { fn test_double_ended_zip() { let xs = [1, 2, 3, 4, 5, 6]; let ys = [1, 2, 3, 7]; - let a = xs.iter().map(|&x| x); - let b = ys.iter().map(|&x| x); + let a = xs.iter().cloned(); + let b = ys.iter().cloned(); let mut it = a.zip(b); assert_eq!(it.next(), Some((1, 1))); assert_eq!(it.next(), Some((2, 2))); @@ -713,7 +713,7 @@ fn test_random_access_inspect() { fn test_random_access_map() { let xs = [1, 2, 3, 4, 5]; - let mut it = xs.iter().map(|x| *x); + let mut it = xs.iter().cloned(); assert_eq!(xs.len(), it.indexable()); for (i, elt) in xs.iter().enumerate() { assert_eq!(Some(*elt), it.idx(i)); diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 421ce76caaf46..5aeb330b78b54 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -92,7 +92,7 @@ fn test_transmute_copy() { #[test] fn test_transmute() { - trait Foo {} + trait Foo { fn dummy(&self) { } } impl Foo for int {} let a = box 100 as Box; diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 9c2e242c10509..57456bfb1a79b 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -171,8 +171,8 @@ fn test_set_memory() { #[test] fn test_unsized_unique() { let xs: &mut [_] = &mut [1, 2, 3]; - let ptr = Unique(xs as *mut [_]); - let ys = unsafe { &mut *ptr.ptr }; + let ptr = unsafe { Unique::new(xs as *mut [_]) }; + let ys = unsafe { &mut **ptr }; let zs: &mut [_] = &mut [1, 2, 3]; assert!(ys == zs); } diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs index 6d5cc38ef0a74..46c7730cc6470 100644 --- a/src/libcoretest/slice.rs +++ b/src/libcoretest/slice.rs @@ -43,13 +43,13 @@ fn iterator_to_slice() { { let mut iter = data.iter(); - assert_eq!(&iter[], &other_data[]); + assert_eq!(&iter[..], &other_data[..]); iter.next(); - assert_eq!(&iter[], &other_data[1..]); + assert_eq!(&iter[..], &other_data[1..]); iter.next_back(); - assert_eq!(&iter[], &other_data[1..2]); + assert_eq!(&iter[..], &other_data[1..2]); let s = iter.as_slice(); iter.next(); @@ -57,17 +57,17 @@ fn iterator_to_slice() { } { let mut iter = data.iter_mut(); - assert_eq!(&iter[], &other_data[]); + assert_eq!(&iter[..], &other_data[..]); // mutability: assert!(&mut iter[] == other_data); iter.next(); - assert_eq!(&iter[], &other_data[1..]); + assert_eq!(&iter[..], &other_data[1..]); assert!(&mut iter[] == &mut other_data[1..]); iter.next_back(); - assert_eq!(&iter[], &other_data[1..2]); + assert_eq!(&iter[..], &other_data[1..2]); assert!(&mut iter[] == &mut other_data[1..2]); let s = iter.into_slice(); diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index ff6400a11dfe8..24660b3f396c1 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -45,13 +45,13 @@ pub struct Bytes { impl Deref for Bytes { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { slice::from_raw_parts_mut(self.ptr.ptr, self.len) } + unsafe { slice::from_raw_parts(*self.ptr, self.len) } } } impl Drop for Bytes { fn drop(&mut self) { - unsafe { libc::free(self.ptr.ptr as *mut _); } + unsafe { libc::free(*self.ptr as *mut _); } } } @@ -84,7 +84,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option { &mut outsz, flags); if !res.is_null() { - let res = Unique(res as *mut u8); + let res = Unique::new(res as *mut u8); Some(Bytes { ptr: res, len: outsz as uint }) } else { None @@ -110,7 +110,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option { &mut outsz, flags); if !res.is_null() { - let res = Unique(res as *mut u8); + let res = Unique::new(res as *mut u8); Some(Bytes { ptr: res, len: outsz as uint }) } else { None diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 1c7e97d784c68..be77622ac1db7 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -215,11 +215,11 @@ impl<'a> Parser<'a> { } Some((_, other)) => { self.err(&format!("expected `{:?}`, found `{:?}`", c, - other)[]); + other)); } None => { self.err(&format!("expected `{:?}` but string was terminated", - c)[]); + c)); } } } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index c743119f40909..fdd7f7395c2b7 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -287,7 +287,7 @@ impl OptGroup { impl Matches { fn opt_vals(&self, nm: &str) -> Vec { - match find_opt(&self.opts[], Name::from_str(nm)) { + match find_opt(&self.opts[..], Name::from_str(nm)) { Some(id) => self.vals[id].clone(), None => panic!("No option '{}' defined", nm) } @@ -326,7 +326,7 @@ impl Matches { /// Returns the string argument supplied to one of several matching options or `None`. pub fn opts_str(&self, names: &[String]) -> Option { for nm in names { - match self.opt_val(&nm[]) { + match self.opt_val(&nm[..]) { Some(Val(ref s)) => return Some(s.clone()), _ => () } @@ -593,7 +593,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { while i < l { let cur = args[i].clone(); let curlen = cur.len(); - if !is_arg(&cur[]) { + if !is_arg(&cur[..]) { free.push(cur); } else if cur == "--" { let mut j = i + 1; @@ -667,7 +667,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { v.push(Val((i_arg.clone()) .unwrap())); } else if name_pos < names.len() || i + 1 == l || - is_arg(&args[i + 1][]) { + is_arg(&args[i + 1][..]) { let v = &mut vals[optid]; v.push(Given); } else { @@ -730,7 +730,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { 0 => {} 1 => { row.push('-'); - row.push_str(&short_name[]); + row.push_str(&short_name[..]); row.push(' '); } _ => panic!("the short name should only be 1 ascii char long"), @@ -741,7 +741,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { 0 => {} _ => { row.push_str("--"); - row.push_str(&long_name[]); + row.push_str(&long_name[..]); row.push(' '); } } @@ -749,10 +749,10 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { // arg match hasarg { No => {} - Yes => row.push_str(&hint[]), + Yes => row.push_str(&hint[..]), Maybe => { row.push('['); - row.push_str(&hint[]); + row.push_str(&hint[..]); row.push(']'); } } @@ -765,7 +765,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { row.push(' '); } } else { - row.push_str(&desc_sep[]); + row.push_str(&desc_sep[..]); } // Normalize desc to contain words separated by one space character @@ -777,14 +777,14 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { // FIXME: #5516 should be graphemes not codepoints let mut desc_rows = Vec::new(); - each_split_within(&desc_normalized_whitespace[], 54, |substr| { + each_split_within(&desc_normalized_whitespace[..], 54, |substr| { desc_rows.push(substr.to_string()); true }); // FIXME: #5516 should be graphemes not codepoints // wrapped description - row.push_str(&desc_rows.connect(&desc_sep[])[]); + row.push_str(&desc_rows.connect(&desc_sep[..])[]); row }); @@ -803,10 +803,10 @@ fn format_option(opt: &OptGroup) -> String { // Use short_name is possible, but fallback to long_name. if opt.short_name.len() > 0 { line.push('-'); - line.push_str(&opt.short_name[]); + line.push_str(&opt.short_name[..]); } else { line.push_str("--"); - line.push_str(&opt.long_name[]); + line.push_str(&opt.long_name[..]); } if opt.hasarg != No { @@ -814,7 +814,7 @@ fn format_option(opt: &OptGroup) -> String { if opt.hasarg == Maybe { line.push('['); } - line.push_str(&opt.hint[]); + line.push_str(&opt.hint[..]); if opt.hasarg == Maybe { line.push(']'); } @@ -836,7 +836,7 @@ pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String { line.push_str(&opts.iter() .map(format_option) .collect::>() - .connect(" ")[]); + .connect(" ")[..]); line } diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 230deabee0034..acd52c752e8aa 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -275,15 +275,12 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(int_uint)] #![feature(collections)] -#![feature(core)] #![feature(old_io)] use self::LabelText::*; -use std::borrow::IntoCow; +use std::borrow::{IntoCow, Cow}; use std::old_io; -use std::string::CowString; -use std::vec::CowVec; /// The text for a graphviz label on a node or edge. pub enum LabelText<'a> { @@ -291,7 +288,7 @@ pub enum LabelText<'a> { /// /// Occurrences of backslashes (`\`) are escaped, and thus appear /// as backslashes in the rendered label. - LabelStr(CowString<'a>), + LabelStr(Cow<'a, str>), /// This kind of label uses the graphviz label escString type: /// http://www.graphviz.org/content/attrs#kescString @@ -303,7 +300,7 @@ pub enum LabelText<'a> { /// to break a line (centering the line preceding the `\n`), there /// are also the escape sequences `\l` which left-justifies the /// preceding line and `\r` which right-justifies it. - EscStr(CowString<'a>), + EscStr(Cow<'a, str>), } // There is a tension in the design of the labelling API. @@ -340,7 +337,7 @@ pub enum LabelText<'a> { /// `Id` is a Graphviz `ID`. pub struct Id<'a> { - name: CowString<'a>, + name: Cow<'a, str>, } impl<'a> Id<'a> { @@ -358,7 +355,7 @@ impl<'a> Id<'a> { /// /// Passing an invalid string (containing spaces, brackets, /// quotes, ...) will return an empty `Err` value. - pub fn new>(name: Name) -> Result, ()> { + pub fn new>(name: Name) -> Result, ()> { let name = name.into_cow(); { let mut chars = name.chars(); @@ -387,7 +384,7 @@ impl<'a> Id<'a> { &*self.name } - pub fn name(self) -> CowString<'a> { + pub fn name(self) -> Cow<'a, str> { self.name } } @@ -427,11 +424,11 @@ pub trait Labeller<'a,N,E> { } impl<'a> LabelText<'a> { - pub fn label>(s: S) -> LabelText<'a> { + pub fn label>(s: S) -> LabelText<'a> { LabelStr(s.into_cow()) } - pub fn escaped>(s: S) -> LabelText<'a> { + pub fn escaped>(s: S) -> LabelText<'a> { EscStr(s.into_cow()) } @@ -455,7 +452,7 @@ impl<'a> LabelText<'a> { pub fn escape(&self) -> String { match self { &LabelStr(ref s) => s.escape_default(), - &EscStr(ref s) => LabelText::escape_str(&s[]), + &EscStr(ref s) => LabelText::escape_str(&s[..]), } } @@ -463,7 +460,7 @@ impl<'a> LabelText<'a> { /// yields same content as self. The result obeys the law /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for /// all `lt: LabelText`. - fn pre_escaped_content(self) -> CowString<'a> { + fn pre_escaped_content(self) -> Cow<'a, str> { match self { EscStr(s) => s, LabelStr(s) => if s.contains_char('\\') { @@ -484,13 +481,13 @@ impl<'a> LabelText<'a> { let mut prefix = self.pre_escaped_content().into_owned(); let suffix = suffix.pre_escaped_content(); prefix.push_str(r"\n\n"); - prefix.push_str(&suffix[]); + prefix.push_str(&suffix[..]); EscStr(prefix.into_cow()) } } -pub type Nodes<'a,N> = CowVec<'a,N>; -pub type Edges<'a,E> = CowVec<'a,E>; +pub type Nodes<'a,N> = Cow<'a,[N]>; +pub type Edges<'a,E> = Cow<'a,[E]>; // (The type parameters in GraphWalk should be associated items, // when/if Rust supports such.) @@ -678,7 +675,7 @@ mod tests { impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph { fn graph_id(&'a self) -> Id<'a> { - Id::new(&self.name[]).unwrap() + Id::new(&self.name[..]).unwrap() } fn node_id(&'a self, n: &Node) -> Id<'a> { id_name(n) diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 4dab07acfd2a0..c2c7f20ce9cdf 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -287,7 +287,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { // Test the literal string from args against the current filter, if there // is one. match unsafe { FILTER.as_ref() } { - Some(filter) if !args.to_string().contains(&filter[]) => return, + Some(filter) if !args.to_string().contains(&filter[..]) => return, _ => {} } @@ -382,7 +382,7 @@ fn enabled(level: u32, // Search for the longest match, the vector is assumed to be pre-sorted. for directive in iter.rev() { match directive.name { - Some(ref name) if !module.starts_with(&name[]) => {}, + Some(ref name) if !module.starts_with(&name[..]) => {}, Some(..) | None => { return level <= directive.level } @@ -397,7 +397,7 @@ fn enabled(level: u32, /// `Once` primitive (and this function is called from that primitive). fn init() { let (mut directives, filter) = match env::var("RUST_LOG") { - Ok(spec) => directive::parse_logging_spec(&spec[]), + Ok(spec) => directive::parse_logging_spec(&spec[..]), Err(..) => (Vec::new(), None), }; diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index d1d24cea8714e..5a85552dc384e 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -21,6 +21,7 @@ use core::prelude::*; use core::num::{Float, Int}; +use core::marker::PhantomData; use {Rng, Rand}; @@ -56,7 +57,13 @@ pub trait IndependentSample: Sample { /// A wrapper for generating types that implement `Rand` via the /// `Sample` & `IndependentSample` traits. -pub struct RandSample; +pub struct RandSample { _marker: PhantomData } + +impl RandSample { + pub fn new() -> RandSample { + RandSample { _marker: PhantomData } + } +} impl Sample for RandSample { fn sample(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) } @@ -285,7 +292,7 @@ mod tests { #[test] fn test_rand_sample() { - let mut rand_sample = RandSample::; + let mut rand_sample = RandSample::::new(); assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0)); assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0)); diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index f15523fc010b6..701749ff3443f 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -215,7 +215,7 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng { fn reseed(&mut self, seed: &'a [u32]) { // make the seed into [seed[0], seed[1], ..., seed[seed.len() // - 1], 0, 0, ...], to fill rng.rsl. - let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u32)); + let seed_iter = seed.iter().cloned().chain(repeat(0u32)); for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) { *rsl_elem = seed_elem; @@ -458,7 +458,7 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng { fn reseed(&mut self, seed: &'a [u64]) { // make the seed into [seed[0], seed[1], ..., seed[seed.len() // - 1], 0, 0, ...], to fill rng.rsl. - let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u64)); + let seed_iter = seed.iter().cloned().chain(repeat(0u64)); for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) { *rsl_elem = seed_elem; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 915c70bbf8ce1..7588bf7c5158e 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -41,6 +41,7 @@ extern crate core; #[cfg(test)] #[macro_use] extern crate log; use core::prelude::*; +use core::marker::PhantomData; pub use isaac::{IsaacRng, Isaac64Rng}; pub use chacha::ChaChaRng; @@ -206,7 +207,7 @@ pub trait Rng : Sized { /// .collect::>()); /// ``` fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> { - Generator { rng: self } + Generator { rng: self, _marker: PhantomData } } /// Generate a random value in the range [`low`, `high`). @@ -317,6 +318,7 @@ pub trait Rng : Sized { /// This iterator is created via the `gen_iter` method on `Rng`. pub struct Generator<'a, T, R:'a> { rng: &'a mut R, + _marker: PhantomData } impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index eb51046d7c9a7..dc81e89902bb4 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -37,7 +37,7 @@ use util::ppaux::{ty_to_string}; use util::nodemap::{FnvHashMap, NodeSet}; use lint::{Level, Context, LintPass, LintArray, Lint}; -use std::collections::BitvSet; +use std::collections::BitSet; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::num::SignedInt; use std::{cmp, slice}; @@ -508,7 +508,7 @@ impl BoxPointers { if n_uniq > 0 { let s = ty_to_string(cx.tcx, ty); let m = format!("type uses owned (Box type) pointers: {}", s); - cx.span_lint(BOX_POINTERS, span, &m[]); + cx.span_lint(BOX_POINTERS, span, &m[..]); } } } @@ -736,7 +736,7 @@ impl LintPass for UnusedResults { } } else { let attrs = csearch::get_item_attrs(&cx.sess().cstore, did); - warned |= check_must_use(cx, &attrs[], s.span); + warned |= check_must_use(cx, &attrs[..], s.span); } } _ => {} @@ -803,7 +803,7 @@ impl NonCamelCaseTypes { } else { format!("{} `{}` should have a camel case name such as `{}`", sort, s, c) }; - cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[]); + cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]); } } } @@ -950,7 +950,7 @@ impl NonSnakeCase { if !is_snake_case(ident) { let sc = NonSnakeCase::to_snake_case(&s); - if sc != &s[] { + if sc != &s[..] { cx.span_lint(NON_SNAKE_CASE, span, &*format!("{} `{}` should have a snake case name such as `{}`", sort, s, sc)); @@ -1033,7 +1033,7 @@ impl NonUpperCaseGlobals { if s.chars().any(|c| c.is_lowercase()) { let uc: String = NonSnakeCase::to_snake_case(&s).chars() .map(|c| c.to_uppercase()).collect(); - if uc != &s[] { + if uc != &s[..] { cx.span_lint(NON_UPPER_CASE_GLOBALS, span, &format!("{} `{}` should have an upper case name such as `{}`", sort, s, uc)); @@ -1196,7 +1196,7 @@ impl LintPass for UnusedImportBraces { let m = format!("braces around {} is unnecessary", &token::get_ident(*name)); cx.span_lint(UNUSED_IMPORT_BRACES, item.span, - &m[]); + &m[..]); }, _ => () } @@ -1474,7 +1474,7 @@ impl LintPass for MissingDoc { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { attr.check_name("doc") && match attr.meta_item_list() { None => false, - Some(l) => attr::contains_name(&l[], "hidden"), + Some(l) => attr::contains_name(&l[..], "hidden"), } }); self.doc_hidden_stack.push(doc_hidden); @@ -1702,7 +1702,7 @@ impl Stability { _ => format!("use of {} item", label) }; - cx.span_lint(lint, span, &msg[]); + cx.span_lint(lint, span, &msg[..]); } } } @@ -1791,7 +1791,7 @@ impl LintPass for UnconditionalRecursion { let mut work_queue = vec![cfg.entry]; let mut reached_exit_without_self_call = false; let mut self_call_spans = vec![]; - let mut visited = BitvSet::new(); + let mut visited = BitSet::new(); while let Some(idx) = work_queue.pop() { let cfg_id = idx.node_id(); diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 42a6861f452a6..068c179d3431f 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -125,11 +125,11 @@ impl LintStore { match (sess, from_plugin) { // We load builtin lints first, so a duplicate is a compiler bug. // Use early_error when handling -W help with no crate. - (None, _) => early_error(&msg[]), - (Some(sess), false) => sess.bug(&msg[]), + (None, _) => early_error(&msg[..]), + (Some(sess), false) => sess.bug(&msg[..]), // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[]), + (Some(sess), true) => sess.err(&msg[..]), } } @@ -150,11 +150,11 @@ impl LintStore { match (sess, from_plugin) { // We load builtin lints first, so a duplicate is a compiler bug. // Use early_error when handling -W help with no crate. - (None, _) => early_error(&msg[]), - (Some(sess), false) => sess.bug(&msg[]), + (None, _) => early_error(&msg[..]), + (Some(sess), false) => sess.bug(&msg[..]), // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[]), + (Some(sess), true) => sess.err(&msg[..]), } } } @@ -251,8 +251,8 @@ impl LintStore { let warning = format!("lint {} has been renamed to {}", lint_name, new_name); match span { - Some(span) => sess.span_warn(span, &warning[]), - None => sess.warn(&warning[]), + Some(span) => sess.span_warn(span, &warning[..]), + None => sess.warn(&warning[..]), }; Some(lint_id) } @@ -262,13 +262,13 @@ impl LintStore { pub fn process_command_line(&mut self, sess: &Session) { for &(ref lint_name, level) in &sess.opts.lint_opts { - match self.find_lint(&lint_name[], sess, None) { + match self.find_lint(&lint_name[..], sess, None) { Some(lint_id) => self.set_level(lint_id, (level, CommandLine)), None => { match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone())) .collect::>>() - .get(&lint_name[]) { + .get(&lint_name[..]) { Some(v) => { v.iter() .map(|lint_id: &LintId| @@ -411,15 +411,15 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint, if level == Forbid { level = Deny; } match (level, span) { - (Warn, Some(sp)) => sess.span_warn(sp, &msg[]), - (Warn, None) => sess.warn(&msg[]), - (Deny, Some(sp)) => sess.span_err(sp, &msg[]), - (Deny, None) => sess.err(&msg[]), + (Warn, Some(sp)) => sess.span_warn(sp, &msg[..]), + (Warn, None) => sess.warn(&msg[..]), + (Deny, Some(sp)) => sess.span_err(sp, &msg[..]), + (Deny, None) => sess.err(&msg[..]), _ => sess.bug("impossible level in raw_emit_lint"), } if let Some(note) = note { - sess.note(¬e[]); + sess.note(¬e[..]); } if let Some(span) = def { @@ -503,7 +503,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match self.lints.find_lint(&lint_name, &self.tcx.sess, Some(span)) { Some(lint_id) => vec![(lint_id, level, span)], None => { - match self.lints.lint_groups.get(&lint_name[]) { + match self.lints.lint_groups.get(&lint_name[..]) { Some(&(ref v, _)) => v.iter() .map(|lint_id: &LintId| (*lint_id, level, span)) @@ -729,7 +729,7 @@ impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> { None => {} Some(lints) => { for (lint_id, span, msg) in lints { - self.span_lint(lint_id.lint, span, &msg[]) + self.span_lint(lint_id.lint, span, &msg[..]) } } } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 5dc23d27ee11b..bdcc10ebceca0 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -185,12 +185,20 @@ impl PartialEq for LintId { impl Eq for LintId { } +#[cfg(stage0)] impl hash::Hash for LintId { fn hash(&self, state: &mut S) { let ptr = self.lint as *const Lint; ptr.hash(state); } } +#[cfg(not(stage0))] +impl hash::Hash for LintId { + fn hash(&self, state: &mut H) { + let ptr = self.lint as *const Lint; + ptr.hash(state); + } +} impl LintId { /// Get the `LintId` for a `Lint`. diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 0871c36d892c6..d48a404176ace 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -183,7 +183,7 @@ impl<'a> CrateReader<'a> { let name = match *path_opt { Some((ref path_str, _)) => { let name = path_str.to_string(); - validate_crate_name(Some(self.sess), &name[], + validate_crate_name(Some(self.sess), &name[..], Some(i.span)); name } @@ -321,7 +321,7 @@ impl<'a> CrateReader<'a> { let source = self.sess.cstore.get_used_crate_source(cnum).unwrap(); if let Some(locs) = self.sess.opts.externs.get(name) { let found = locs.iter().any(|l| { - let l = fs::realpath(&Path::new(&l[])).ok(); + let l = fs::realpath(&Path::new(&l[..])).ok(); source.dylib.as_ref().map(|p| &p.0) == l.as_ref() || source.rlib.as_ref().map(|p| &p.0) == l.as_ref() }); @@ -459,8 +459,8 @@ impl<'a> CrateReader<'a> { let mut load_ctxt = loader::Context { sess: self.sess, span: span, - ident: &ident[], - crate_name: &name[], + ident: &ident[..], + crate_name: &name[..], hash: None, filesearch: self.sess.host_filesearch(PathKind::Crate), target: &self.sess.host, @@ -562,7 +562,7 @@ impl<'a> CrateReader<'a> { name, config::host_triple(), self.sess.opts.target_triple); - self.sess.span_err(span, &message[]); + self.sess.span_err(span, &message[..]); self.sess.abort_if_errors(); } @@ -575,7 +575,7 @@ impl<'a> CrateReader<'a> { let message = format!("plugin `{}` only found in rlib format, \ but must be available in dylib format", name); - self.sess.span_err(span, &message[]); + self.sess.span_err(span, &message[..]); // No need to abort because the loading code will just ignore this // empty dylib. None diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 0a3e173b35ee5..a3f7d57da6748 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -139,8 +139,7 @@ impl CStore { pub fn get_used_crate_source(&self, cnum: ast::CrateNum) -> Option { self.used_crate_sources.borrow_mut() - .iter().find(|source| source.cnum == cnum) - .map(|source| source.clone()) + .iter().find(|source| source.cnum == cnum).cloned() } pub fn reset(&self) { @@ -218,7 +217,7 @@ impl CStore { pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { - self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x) + self.extern_mod_crate_map.borrow().get(&emod_id).cloned() } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 3123fa31abdd1..42a70cec5dfee 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -163,7 +163,7 @@ fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) { rbml_w.end_tag(); rbml_w.start_tag(tag_mod_child); - rbml_w.wr_str(&s[]); + rbml_w.wr_str(&s[..]); rbml_w.end_tag(); } @@ -353,9 +353,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let fields = ty::lookup_struct_fields(ecx.tcx, def_id); let idx = encode_info_for_struct(ecx, rbml_w, - &fields[], + &fields[..], index); - encode_struct_fields(rbml_w, &fields[], def_id); + encode_struct_fields(rbml_w, &fields[..], def_id); encode_index(rbml_w, idx, write_i64); } } @@ -1158,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext, class itself */ let idx = encode_info_for_struct(ecx, rbml_w, - &fields[], + &fields[..], index); /* Index the class*/ @@ -1181,7 +1181,7 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - encode_struct_fields(rbml_w, &fields[], def_id); + encode_struct_fields(rbml_w, &fields[..], def_id); encode_inlined_item(ecx, rbml_w, IIItemRef(item)); @@ -1588,6 +1588,7 @@ fn encode_info_for_items(ecx: &EncodeContext, // Path and definition ID indexing +#[cfg(stage0)] fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: F) where F: FnMut(&mut SeekableMemWriter, &T), T: Hash, @@ -1628,6 +1629,47 @@ fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: rbml_w.end_tag(); rbml_w.end_tag(); } +#[cfg(not(stage0))] +fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: F) where + F: FnMut(&mut SeekableMemWriter, &T), + T: Hash, +{ + let mut buckets: Vec>> = (0..256u16).map(|_| Vec::new()).collect(); + for elt in index { + let mut s = SipHasher::new(); + elt.val.hash(&mut s); + let h = s.finish() as uint; + (&mut buckets[h % 256]).push(elt); + } + + rbml_w.start_tag(tag_index); + let mut bucket_locs = Vec::new(); + rbml_w.start_tag(tag_index_buckets); + for bucket in &buckets { + bucket_locs.push(rbml_w.writer.tell().unwrap()); + rbml_w.start_tag(tag_index_buckets_bucket); + for elt in bucket { + rbml_w.start_tag(tag_index_buckets_bucket_elt); + assert!(elt.pos < 0xffff_ffff); + { + let wr: &mut SeekableMemWriter = rbml_w.writer; + wr.write_be_u32(elt.pos as u32); + } + write_fn(rbml_w.writer, &elt.val); + rbml_w.end_tag(); + } + rbml_w.end_tag(); + } + rbml_w.end_tag(); + rbml_w.start_tag(tag_index_table); + for pos in &bucket_locs { + assert!(*pos < 0xffff_ffff); + let wr: &mut SeekableMemWriter = rbml_w.writer; + wr.write_be_u32(*pos as u32); + } + rbml_w.end_tag(); + rbml_w.end_tag(); +} fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) { let wr: &mut SeekableMemWriter = writer; diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 3158ccd076522..01d1f4e7011f8 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -322,7 +322,7 @@ impl<'a> Context<'a> { &Some(ref r) => format!("{} which `{}` depends on", message, r.ident) }; - self.sess.span_err(self.span, &message[]); + self.sess.span_err(self.span, &message[..]); if self.rejected_via_triple.len() > 0 { let mismatches = self.rejected_via_triple.iter(); @@ -404,7 +404,7 @@ impl<'a> Context<'a> { None => return FileDoesntMatch, Some(file) => file, }; - let (hash, rlib) = if file.starts_with(&rlib_prefix[]) && + let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") { (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())], true) @@ -413,7 +413,7 @@ impl<'a> Context<'a> { (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())], false) } else { - if file.starts_with(&staticlib_prefix[]) && + if file.starts_with(&staticlib_prefix[..]) && file.ends_with(".a") { staticlibs.push(CrateMismatch { path: path.clone(), @@ -627,7 +627,7 @@ impl<'a> Context<'a> { let mut rlibs = HashMap::new(); let mut dylibs = HashMap::new(); { - let locs = locs.iter().map(|l| Path::new(&l[])).filter(|loc| { + let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", self.crate_name, loc.display())[]); @@ -645,8 +645,8 @@ impl<'a> Context<'a> { return true } else { let (ref prefix, ref suffix) = dylibname; - if file.starts_with(&prefix[]) && - file.ends_with(&suffix[]) { + if file.starts_with(&prefix[..]) && + file.ends_with(&suffix[..]) { return true } } @@ -744,7 +744,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result abi::Abi { assert_eq!(next(st), '['); scan(st, |c| c == ']', |bytes| { let abi_str = str::from_utf8(bytes).unwrap(); - abi::lookup(&abi_str[]).expect(abi_str) + abi::lookup(&abi_str[..]).expect(abi_str) }) } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c3302debdfaff..ae10eb686b010 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -134,7 +134,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, // Do an Option dance to use the path after it is moved below. let s = ast_map::path_to_string(path.iter().cloned()); path_as_str = Some(s); - path_as_str.as_ref().map(|x| &x[]) + path_as_str.as_ref().map(|x| &x[..]) }); let mut ast_dsr = reader::Decoder::new(ast_doc); let from_id_range = Decodable::decode(&mut ast_dsr).unwrap(); diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs index 1f0fe4f1acaea..46b4a51c9d6fe 100644 --- a/src/librustc/middle/cfg/graphviz.rs +++ b/src/librustc/middle/cfg/graphviz.rs @@ -92,7 +92,7 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> { let s = replace_newline_with_backslash_l(s); label.push_str(&format!("exiting scope_{} {}", i, - &s[])[]); + &s[..])[]); } dot::LabelText::EscStr(label.into_cow()) } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 03456f8529028..86c59b24e3e93 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -25,7 +25,7 @@ use middle::ty::*; use middle::ty; use std::cmp::Ordering; use std::fmt; -use std::iter::{range_inclusive, AdditiveIterator, FromIterator, repeat}; +use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat}; use std::num::Float; use std::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat}; @@ -76,7 +76,7 @@ impl<'a> fmt::Debug for Matrix<'a> { pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0) }).collect(); - let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1; + let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1; let br = repeat('+').take(total_width).collect::(); try!(write!(f, "{}\n", br)); for row in pretty_printed_matrix { @@ -94,8 +94,8 @@ impl<'a> fmt::Debug for Matrix<'a> { } impl<'a> FromIterator> for Matrix<'a> { - fn from_iter>>(iterator: T) -> Matrix<'a> { - Matrix(iterator.collect()) + fn from_iter>>(iter: T) -> Matrix<'a> { + Matrix(iter.into_iter().collect()) } } @@ -200,7 +200,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) { } // Fourth, check for unreachable arms. - check_arms(cx, &inlined_arms[], source); + check_arms(cx, &inlined_arms[..], source); // Finally, check if the whole match expression is exhaustive. // Check for empty enum, because is_useful only works on inhabited types. @@ -291,7 +291,7 @@ fn check_arms(cx: &MatchCheckCtxt, for pat in pats { let v = vec![&**pat]; - match is_useful(cx, &seen, &v[], LeaveOutWitness) { + match is_useful(cx, &seen, &v[..], LeaveOutWitness) { NotUseful => { match source { ast::MatchSource::IfLetDesugar { .. } => { @@ -351,7 +351,7 @@ fn raw_pat<'a>(p: &'a Pat) -> &'a Pat { fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) { match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) { UsefulWithWitness(pats) => { - let witness = match &pats[] { + let witness = match &pats[..] { [ref witness] => &**witness, [] => DUMMY_WILD_PAT, _ => unreachable!() @@ -360,7 +360,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast: ast::MatchSource::ForLoopDesugar => { // `witness` has the form `Some()`, peel off the `Some` let witness = match witness.node { - ast::PatEnum(_, Some(ref pats)) => match &pats[] { + ast::PatEnum(_, Some(ref pats)) => match &pats[..] { [ref pat] => &**pat, _ => unreachable!(), }, @@ -664,7 +664,7 @@ fn is_useful(cx: &MatchCheckCtxt, UsefulWithWitness(pats) => UsefulWithWitness({ let arity = constructor_arity(cx, &c, left_ty); let mut result = { - let pat_slice = &pats[]; + let pat_slice = &pats[..]; let subpats: Vec<_> = (0..arity).map(|i| { pat_slice.get(i).map_or(DUMMY_WILD_PAT, |p| &**p) }).collect(); @@ -711,10 +711,10 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix, witness: WitnessPreference) -> Usefulness { let arity = constructor_arity(cx, &ctor, lty); let matrix = Matrix(m.iter().filter_map(|r| { - specialize(cx, &r[], &ctor, 0, arity) + specialize(cx, &r[..], &ctor, 0, arity) }).collect()); match specialize(cx, v, &ctor, 0, arity) { - Some(v) => is_useful(cx, &matrix, &v[], witness), + Some(v) => is_useful(cx, &matrix, &v[..], witness), None => NotUseful } } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 3d03cd946c48f..5bf7422dbc0d4 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -62,7 +62,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, None => None, Some(ast_map::NodeItem(it)) => match it.node { ast::ItemEnum(ast::EnumDef { ref variants }, _) => { - variant_expr(&variants[], variant_def.node) + variant_expr(&variants[..], variant_def.node) } _ => None }, @@ -83,7 +83,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, // NOTE this doesn't do the right thing, it compares inlined // NodeId's to the original variant_def's NodeId, but they // come from different crates, so they will likely never match. - variant_expr(&variants[], variant_def.node).map(|e| e.id) + variant_expr(&variants[..], variant_def.node).map(|e| e.id) } _ => None }, @@ -209,7 +209,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val { match eval_const_expr_partial(tcx, e, None) { Ok(r) => r, - Err(s) => tcx.sess.span_fatal(e.span, &s[]) + Err(s) => tcx.sess.span_fatal(e.span, &s[..]) } } @@ -501,7 +501,7 @@ fn lit_to_const(lit: &ast::Lit, ty_hint: Option) -> const_val { match lit.node { ast::LitStr(ref s, _) => const_str((*s).clone()), ast::LitBinary(ref data) => { - const_binary(Rc::new(data.iter().map(|x| *x).collect())) + const_binary(data.clone()) } ast::LitByte(n) => const_uint(n as u64), ast::LitChar(n) => const_uint(n as u64), @@ -552,14 +552,14 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>, let a = match eval_const_expr_partial(tcx, a, ty_hint) { Ok(a) => a, Err(s) => { - tcx.sess.span_err(a.span, &s[]); + tcx.sess.span_err(a.span, &s[..]); return None; } }; let b = match eval_const_expr_partial(tcx, b, ty_hint) { Ok(b) => b, Err(s) => { - tcx.sess.span_err(b.span, &s[]); + tcx.sess.span_err(b.span, &s[..]); return None; } }; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index b792a44d4d89a..085d5cbc347e5 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -89,7 +89,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> { } fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap) -> CFGIndex { - let opt_cfgindex = index.get(&id).map(|&i|i); + let opt_cfgindex = index.get(&id).cloned(); opt_cfgindex.unwrap_or_else(|| { panic!("nodeid_to_index does not have entry for NodeId {}", id); }) @@ -312,7 +312,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let mut t = on_entry.to_vec(); self.apply_gen_kill(cfgidx, &mut t); temp_bits = t; - &temp_bits[] + &temp_bits[..] } }; debug!("{} each_bit_for_node({:?}, cfgidx={:?}) bits={}", @@ -400,7 +400,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let mut changed = false; for &node_id in &edge.data.exiting_scopes { - let opt_cfg_idx = self.nodeid_to_index.get(&node_id).map(|&i|i); + let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned(); match opt_cfg_idx { Some(cfg_idx) => { let (start, end) = self.compute_id_range(cfg_idx); @@ -421,7 +421,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let bits = &mut self.kills[start.. end]; debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [before]", self.analysis_name, flow_exit, mut_bits_to_string(bits)); - bits.clone_from_slice(&orig_kills[]); + bits.clone_from_slice(&orig_kills[..]); debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [after]", self.analysis_name, flow_exit, mut_bits_to_string(bits)); } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index b2335f91ad986..ff78deb8d12ea 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -321,7 +321,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool { for attr in lint::gather_attrs(attrs) { match attr { Ok((ref name, lint::Allow, _)) - if &name[] == dead_code => return true, + if &name[..] == dead_code => return true, _ => (), } } diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 6d35a82d153cd..ad9f4eade5c90 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session, // Collect what we've got so far in the return vector. let mut ret = (1..sess.cstore.next_crate_num()).map(|i| { - match formats.get(&i).map(|v| *v) { + match formats.get(&i).cloned() { v @ Some(cstore::RequireDynamic) => v, _ => None, } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 8dbac7f515ea8..e99d214742a0b 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -29,7 +29,6 @@ use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticClosure}; use util::ppaux::Repr; -use std::marker; use syntax::{ast, ast_util}; use syntax::ptr::P; use syntax::codemap::Span; @@ -128,16 +127,14 @@ pub enum MatchMode { MovingMatch, } -#[derive(PartialEq,Debug)] -enum TrackMatchMode { +#[derive(Copy, PartialEq, Debug)] +enum TrackMatchMode { Unknown, Definite(MatchMode), Conflicting, } -impl marker::Copy for TrackMatchMode {} - -impl TrackMatchMode { +impl TrackMatchMode { // Builds up the whole match mode for a pattern from its constituent // parts. The lattice looks like this: // @@ -931,7 +928,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { return true; } - fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode { + fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode { let mut mode = Unknown; for pat in &arm.pats { self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode); @@ -966,7 +963,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { fn determine_pat_move_mode(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &ast::Pat, - mode: &mut TrackMatchMode) { + mode: &mut TrackMatchMode) { debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()), pat.repr(self.tcx())); return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| { @@ -1166,7 +1163,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { let msg = format!("Pattern has unexpected def: {:?} and type {}", def, cmt_pat.ty.repr(tcx)); - tcx.sess.span_bug(pat.span, &msg[]) + tcx.sess.span_bug(pat.span, &msg[..]) } } } diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 4dd7a4a226629..436f04fc9e9cf 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -34,7 +34,7 @@ use std::fmt::{Formatter, Error, Debug}; use std::usize; -use std::collections::BitvSet; +use std::collections::BitSet; pub struct Graph { nodes: Vec> , @@ -292,7 +292,7 @@ impl Graph { DepthFirstTraversal { graph: self, stack: vec![start], - visited: BitvSet::new() + visited: BitSet::new() } } } @@ -300,7 +300,7 @@ impl Graph { pub struct DepthFirstTraversal<'g, N:'g, E:'g> { graph: &'g Graph, stack: Vec, - visited: BitvSet + visited: BitSet } impl<'g, N, E> Iterator for DepthFirstTraversal<'g, N, E> { diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs new file mode 100644 index 0000000000000..93c80fb754f71 --- /dev/null +++ b/src/librustc/middle/infer/bivariate.rs @@ -0,0 +1,145 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Applies the "bivariance relationship" to two types and/or regions. +//! If (A,B) are bivariant then either A <: B or B <: A. It occurs +//! when type/lifetime parameters are unconstrained. Usually this is +//! an error, but we permit it in the specific case where a type +//! parameter is constrained in a where-clause via an associated type. +//! +//! There are several ways one could implement bivariance. You could +//! just do nothing at all, for example, or you could fully verify +//! that one of the two subtyping relationships hold. We choose to +//! thread a middle line: we relate types up to regions, but ignore +//! all region relationships. +//! +//! At one point, handling bivariance in this fashion was necessary +//! for inference, but I'm actually not sure if that is true anymore. +//! In particular, it might be enough to say (A,B) are bivariant for +//! all (A,B). + +use middle::ty::{BuiltinBounds}; +use middle::ty::{self, Ty}; +use middle::ty::TyVar; +use middle::infer::combine::*; +use middle::infer::{cres}; +use middle::infer::type_variable::{BiTo}; +use util::ppaux::{Repr}; + +use syntax::ast::{Unsafety}; + +pub struct Bivariate<'f, 'tcx: 'f> { + fields: CombineFields<'f, 'tcx> +} + +#[allow(non_snake_case)] +pub fn Bivariate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Bivariate<'f, 'tcx> { + Bivariate { fields: cf } +} + +impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> { + fn tag(&self) -> String { "Bivariate".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } + + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Contravariant => self.tys(a, b), + ty::Bivariant => self.tys(a, b), + } + } + + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Contravariant => self.regions(a, b), + ty::Bivariant => self.regions(a, b), + } + } + + fn regions(&self, a: ty::Region, _: ty::Region) -> cres<'tcx, ty::Region> { + Ok(a) + } + + fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { + debug!("mts({} <: {})", + a.repr(self.fields.infcx.tcx), + b.repr(self.fields.infcx.tcx)); + + if a.mutbl != b.mutbl { return Err(ty::terr_mutability); } + let t = try!(self.tys(a.ty, b.ty)); + Ok(ty::mt { mutbl: a.mutbl, ty: t }) + } + + fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { + if a != b { + Err(ty::terr_unsafety_mismatch(expected_found(self, a, b))) + } else { + Ok(a) + } + } + + fn builtin_bounds(&self, + a: BuiltinBounds, + b: BuiltinBounds) + -> cres<'tcx, BuiltinBounds> + { + if a != b { + Err(ty::terr_builtin_bounds(expected_found(self, a, b))) + } else { + Ok(a) + } + } + + fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { + debug!("{}.tys({}, {})", self.tag(), + a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx)); + if a == b { return Ok(a); } + + let infcx = self.fields.infcx; + let a = infcx.type_variables.borrow().replace_if_possible(a); + let b = infcx.type_variables.borrow().replace_if_possible(b); + match (&a.sty, &b.sty) { + (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => { + infcx.type_variables.borrow_mut().relate_vars(a_id, BiTo, b_id); + Ok(a) + } + + (&ty::ty_infer(TyVar(a_id)), _) => { + try!(self.fields.instantiate(b, BiTo, a_id)); + Ok(a) + } + + (_, &ty::ty_infer(TyVar(b_id))) => { + try!(self.fields.instantiate(a, BiTo, b_id)); + Ok(a) + } + + _ => { + super_tys(self, a, b) + } + } + } + + fn binders(&self, a: &ty::Binder, b: &ty::Binder) -> cres<'tcx, ty::Binder> + where T : Combineable<'tcx> + { + let a1 = ty::erase_late_bound_regions(self.tcx(), a); + let b1 = ty::erase_late_bound_regions(self.tcx(), b); + let c = try!(Combineable::combine(self, &a1, &b1)); + Ok(ty::Binder(c)) + } +} diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index daa820f43b57e..0eeafb767d8a6 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -32,6 +32,7 @@ // is also useful to track which value is the "expected" value in // terms of error reporting. +use super::bivariate::Bivariate; use super::equate::Equate; use super::glb::Glb; use super::lub::Lub; @@ -39,7 +40,7 @@ use super::sub::Sub; use super::unify::InferCtxtMethodsForSimplyUnifiableTypes; use super::{InferCtxt, cres}; use super::{MiscVariable, TypeTrace}; -use super::type_variable::{RelationDir, EqTo, SubtypeOf, SupertypeOf}; +use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf}; use middle::subst; use middle::subst::{ErasedRegions, NonerasedRegions, Substs}; @@ -48,7 +49,7 @@ use middle::ty::{IntType, UintType}; use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; use middle::ty_fold; -use middle::ty_fold::{TypeFoldable}; +use middle::ty_fold::{TypeFolder, TypeFoldable}; use util::ppaux::Repr; use std::rc::Rc; @@ -58,41 +59,32 @@ use syntax::abi; use syntax::codemap::Span; pub trait Combine<'tcx> : Sized { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>; fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx } fn tag(&self) -> String; - fn a_is_expected(&self) -> bool; - fn trace(&self) -> TypeTrace<'tcx>; - fn equate<'a>(&'a self) -> Equate<'a, 'tcx>; - fn sub<'a>(&'a self) -> Sub<'a, 'tcx>; - fn lub<'a>(&'a self) -> Lub<'a, 'tcx>; - fn glb<'a>(&'a self) -> Glb<'a, 'tcx>; + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx>; + + fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields().infcx } + fn a_is_expected(&self) -> bool { self.fields().a_is_expected } + fn trace(&self) -> TypeTrace<'tcx> { self.fields().trace.clone() } + fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { self.fields().equate() } + fn bivariate<'a>(&'a self) -> Bivariate<'a, 'tcx> { self.fields().bivariate() } + + fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { self.fields().sub() } + fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields().clone()) } + fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields().clone()) } fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>>; - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>; + + fn tys_with_variance(&self, variance: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>>; + fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>; - fn tps(&self, - _: subst::ParamSpace, - as_: &[Ty<'tcx>], - bs: &[Ty<'tcx>]) - -> cres<'tcx, Vec>> { - // FIXME -- In general, we treat variance a bit wrong - // here. For historical reasons, we treat tps and Self - // as invariant. This is overly conservative. - - if as_.len() != bs.len() { - return Err(ty::terr_ty_param_size(expected_found(self, - as_.len(), - bs.len()))); - } + fn regions_with_variance(&self, variance: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region>; - try!(as_.iter().zip(bs.iter()) - .map(|(a, b)| self.equate().tys(*a, *b)) - .collect::>>()); - Ok(as_.to_vec()) - } + fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>; fn substs(&self, item_def_id: ast::DefId, @@ -100,6 +92,11 @@ pub trait Combine<'tcx> : Sized { b_subst: &subst::Substs<'tcx>) -> cres<'tcx, subst::Substs<'tcx>> { + debug!("substs: item_def_id={} a_subst={} b_subst={}", + item_def_id.repr(self.infcx().tcx), + a_subst.repr(self.infcx().tcx), + b_subst.repr(self.infcx().tcx)); + let variances = if self.infcx().tcx.variance_computed.get() { Some(ty::item_variances(self.infcx().tcx, item_def_id)) } else { @@ -119,7 +116,8 @@ pub trait Combine<'tcx> : Sized { for &space in &subst::ParamSpace::all() { let a_tps = a_subst.types.get_slice(space); let b_tps = b_subst.types.get_slice(space); - let tps = try!(self.tps(space, a_tps, b_tps)); + let t_variances = variances.map(|v| v.types.get_slice(space)); + let tps = try!(relate_type_params(self, t_variances, a_tps, b_tps)); substs.types.replace(space, tps); } @@ -132,20 +130,7 @@ pub trait Combine<'tcx> : Sized { for &space in &subst::ParamSpace::all() { let a_regions = a.get_slice(space); let b_regions = b.get_slice(space); - - let mut invariance = Vec::new(); - let r_variances = match variances { - Some(variances) => { - variances.regions.get_slice(space) - } - None => { - for _ in a_regions { - invariance.push(ty::Invariant); - } - &invariance[] - } - }; - + let r_variances = variances.map(|v| v.regions.get_slice(space)); let regions = try!(relate_region_params(self, r_variances, a_regions, @@ -157,13 +142,34 @@ pub trait Combine<'tcx> : Sized { return Ok(substs); + fn relate_type_params<'tcx, C: Combine<'tcx>>(this: &C, + variances: Option<&[ty::Variance]>, + a_tys: &[Ty<'tcx>], + b_tys: &[Ty<'tcx>]) + -> cres<'tcx, Vec>> + { + if a_tys.len() != b_tys.len() { + return Err(ty::terr_ty_param_size(expected_found(this, + a_tys.len(), + b_tys.len()))); + } + + range(0, a_tys.len()).map(|i| { + let a_ty = a_tys[i]; + let b_ty = b_tys[i]; + let v = variances.map_or(ty::Invariant, |v| v[i]); + this.tys_with_variance(v, a_ty, b_ty) + }).collect() + } + fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C, - variances: &[ty::Variance], + variances: Option<&[ty::Variance]>, a_rs: &[ty::Region], b_rs: &[ty::Region]) - -> cres<'tcx, Vec> { + -> cres<'tcx, Vec> + { let tcx = this.infcx().tcx; - let num_region_params = variances.len(); + let num_region_params = a_rs.len(); debug!("relate_region_params(\ a_rs={}, \ @@ -173,22 +179,18 @@ pub trait Combine<'tcx> : Sized { b_rs.repr(tcx), variances.repr(tcx)); - assert_eq!(num_region_params, a_rs.len()); + assert_eq!(num_region_params, + variances.map_or(num_region_params, + |v| v.len())); + assert_eq!(num_region_params, b_rs.len()); - let mut rs = vec!(); - for i in 0..num_region_params { + + (0..a_rs.len()).map(|i| { let a_r = a_rs[i]; let b_r = b_rs[i]; - let variance = variances[i]; - let r = match variance { - ty::Invariant => this.equate().regions(a_r, b_r), - ty::Covariant => this.regions(a_r, b_r), - ty::Contravariant => this.contraregions(a_r, b_r), - ty::Bivariant => Ok(a_r), - }; - rs.push(try!(r)); - } - Ok(rs) + let variance = variances.map_or(ty::Invariant, |v| v[i]); + this.regions_with_variance(variance, a_r, b_r) + }).collect() } } @@ -241,7 +243,7 @@ pub trait Combine<'tcx> : Sized { } fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - self.contratys(a, b).and_then(|t| Ok(t)) + self.tys_with_variance(ty::Contravariant, a, b).and_then(|t| Ok(t)) } fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>; @@ -309,7 +311,7 @@ pub trait Combine<'tcx> : Sized { b: &ty::ExistentialBounds<'tcx>) -> cres<'tcx, ty::ExistentialBounds<'tcx>> { - let r = try!(self.contraregions(a.region_bound, b.region_bound)); + let r = try!(self.regions_with_variance(ty::Contravariant, a.region_bound, b.region_bound)); let nb = try!(self.builtin_bounds(a.builtin_bounds, b.builtin_bounds)); let pb = try!(self.projection_bounds(&a.projection_bounds, &b.projection_bounds)); Ok(ty::ExistentialBounds { region_bound: r, @@ -322,11 +324,6 @@ pub trait Combine<'tcx> : Sized { b: ty::BuiltinBounds) -> cres<'tcx, ty::BuiltinBounds>; - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region>; - - fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>; - fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) @@ -540,7 +537,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, } (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { - let r = try!(this.contraregions(*a_r, *b_r)); + let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r)); + // FIXME(14985) If we have mutable references to trait objects, we // used to use covariant subtyping. I have preserved this behaviour, // even though it is probably incorrect. So don't go down the usual @@ -644,6 +642,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { Equate((*self).clone()) } + fn bivariate(&self) -> Bivariate<'f, 'tcx> { + Bivariate((*self).clone()) + } + fn sub(&self) -> Sub<'f, 'tcx> { Sub((*self).clone()) } @@ -697,7 +699,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { EqTo => { self.generalize(a_ty, b_vid, false) } - SupertypeOf | SubtypeOf => { + BiTo | SupertypeOf | SubtypeOf => { self.generalize(a_ty, b_vid, true) } }); @@ -721,6 +723,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { // to associate causes/spans with each of the relations in // the stack to get this right. match dir { + BiTo => { + try!(self.bivariate().tys(a_ty, b_ty)); + } + EqTo => { try!(self.equate().tys(a_ty, b_ty)); } @@ -730,7 +736,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { } SupertypeOf => { - try!(self.sub().contratys(a_ty, b_ty)); + try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty)); } } } diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs index f0bde22286488..7194e20b0cf65 100644 --- a/src/librustc/middle/infer/equate.rs +++ b/src/librustc/middle/infer/equate.rs @@ -13,11 +13,7 @@ use middle::ty::{self, Ty}; use middle::ty::TyVar; use middle::infer::combine::*; use middle::infer::{cres}; -use middle::infer::glb::Glb; -use middle::infer::InferCtxt; -use middle::infer::lub::Lub; -use middle::infer::sub::Sub; -use middle::infer::{TypeTrace, Subtype}; +use middle::infer::{Subtype}; use middle::infer::type_variable::{EqTo}; use util::ppaux::{Repr}; @@ -33,21 +29,20 @@ pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "eq".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } + fn tag(&self) -> String { "Equate".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } - - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { + fn tys_with_variance(&self, _: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + // Once we're equating, it doesn't matter what the variance is. self.tys(a, b) } - fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> { + fn regions_with_variance(&self, _: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + // Once we're equating, it doesn't matter what the variance is. self.regions(a, b) } diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 72b33613c66aa..53032f9b9ac64 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -200,9 +200,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ref trace_origins, ref same_regions) => { if !same_regions.is_empty() { - self.report_processed_errors(&var_origins[], - &trace_origins[], - &same_regions[]); + self.report_processed_errors(&var_origins[..], + &trace_origins[..], + &same_regions[..]); } } } @@ -675,6 +675,17 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { sup, ""); } + infer::Operand(span) => { + self.tcx.sess.span_err( + span, + "lifetime of operand does not outlive \ + the operation"); + note_and_explain_region( + self.tcx, + "the operand is only valid for ", + sup, + ""); + } infer::AddrOf(span) => { self.tcx.sess.span_err( span, @@ -824,7 +835,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { let parent = self.tcx.map.get_parent(scope_id); let parent_node = self.tcx.map.find(parent); let taken = lifetimes_in_scope(self.tcx, scope_id); - let life_giver = LifeGiver::with_taken(&taken[]); + let life_giver = LifeGiver::with_taken(&taken[..]); let node_inner = match parent_node { Some(ref node) => match *node { ast_map::NodeItem(ref item) => { @@ -924,7 +935,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { fn rebuild(&self) -> (ast::FnDecl, Option, ast::Generics) { - let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone()); + let mut expl_self_opt = self.expl_self_opt.cloned(); let mut inputs = self.fn_decl.inputs.clone(); let mut output = self.fn_decl.output.clone(); let mut ty_params = self.generics.ty_params.clone(); @@ -942,7 +953,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { } expl_self_opt = self.rebuild_expl_self(expl_self_opt, lifetime, &anon_nums, ®ion_names); - inputs = self.rebuild_args_ty(&inputs[], lifetime, + inputs = self.rebuild_args_ty(&inputs[..], lifetime, &anon_nums, ®ion_names); output = self.rebuild_output(&output, lifetime, &anon_nums, ®ion_names); ty_params = self.rebuild_ty_params(ty_params, lifetime, @@ -1426,7 +1437,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { opt_explicit_self, generics); let msg = format!("consider using an explicit lifetime \ parameter as shown: {}", suggested_fn); - self.tcx.sess.span_help(span, &msg[]); + self.tcx.sess.span_help(span, &msg[..]); } fn report_inference_failure(&self, @@ -1593,6 +1604,11 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { span, "...so that return value is valid for the call"); } + infer::Operand(span) => { + self.tcx.sess.span_err( + span, + "...so that operand is valid for operation"); + } infer::AddrOf(span) => { self.tcx.sess.span_note( span, @@ -1771,7 +1787,7 @@ impl LifeGiver { s.push_str(&num_to_string(self.counter.get())[]); if !self.taken.contains(&s) { lifetime = name_to_dummy_lifetime( - token::str_to_ident(&s[]).name); + token::str_to_ident(&s[..]).name); self.generated.borrow_mut().push(lifetime); break; } diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs index ff0c2d92f45ee..33303808e8491 100644 --- a/src/librustc/middle/infer/glb.rs +++ b/src/librustc/middle/infer/glb.rs @@ -10,12 +10,9 @@ use super::combine::*; use super::lattice::*; -use super::equate::Equate; use super::higher_ranked::HigherRankedRelations; -use super::lub::Lub; -use super::sub::Sub; -use super::{cres, InferCtxt}; -use super::{TypeTrace, Subtype}; +use super::{cres}; +use super::Subtype; use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; @@ -34,15 +31,30 @@ pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "glb".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } + fn tag(&self) -> String { "Glb".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Bivariant => self.bivariate().tys(a, b), + ty::Contravariant => self.lub().tys(a, b), + } + } + + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Bivariant => self.bivariate().regions(a, b), + ty::Contravariant => self.lub().regions(a, b), + } + } fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { let tcx = self.fields.infcx.tcx; @@ -75,10 +87,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { } } - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - self.lub().tys(a, b) - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { match (a, b) { (Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal), @@ -104,11 +112,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b)) } - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region> { - self.lub().regions(a, b) - } - fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { super_lattice_tys(self, a, b) } diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 4469e27a5b05a..a729156c88b35 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -31,7 +31,7 @@ pub trait HigherRankedRelations<'tcx> { where T : Combineable<'tcx>; } -trait InferCtxtExt<'tcx> { +trait InferCtxtExt { fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec; fn region_vars_confined_to_snapshot(&self, @@ -371,7 +371,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, })) } -impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> { +impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> { fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec { self.region_vars.tainted(&snapshot.region_vars_snapshot, r) } diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs index 204560e87ee3b..3570effa9fa70 100644 --- a/src/librustc/middle/infer/lub.rs +++ b/src/librustc/middle/infer/lub.rs @@ -9,13 +9,10 @@ // except according to those terms. use super::combine::*; -use super::equate::Equate; -use super::glb::Glb; use super::higher_ranked::HigherRankedRelations; use super::lattice::*; -use super::sub::Sub; -use super::{cres, InferCtxt}; -use super::{TypeTrace, Subtype}; +use super::{cres}; +use super::{Subtype}; use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; @@ -34,15 +31,30 @@ pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "lub".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } + fn tag(&self) -> String { "Lub".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Bivariant => self.bivariate().tys(a, b), + ty::Contravariant => self.glb().tys(a, b), + } + } + + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Bivariant => self.bivariate().regions(a, b), + ty::Contravariant => self.glb().regions(a, b), + } + } fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { let tcx = self.tcx(); @@ -70,10 +82,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { } } - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - self.glb().tys(a, b) - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { match (a, b) { (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe), @@ -90,11 +98,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { Ok(a.intersection(b)) } - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region> { - self.glb().regions(a, b) - } - fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> { debug!("{}.regions({}, {})", self.tag(), diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 00e377d65fea7..b0576ff55ff73 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -45,6 +45,7 @@ use self::lub::Lub; use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes}; use self::error_reporting::ErrorReporting; +pub mod bivariate; pub mod combine; pub mod equate; pub mod error_reporting; @@ -209,6 +210,9 @@ pub enum SubregionOrigin<'tcx> { // Region in return type of invoked fn must enclose call CallReturn(Span), + // Operands must be in scope + Operand(Span), + // Region resulting from a `&` expr must enclose the `&` expr AddrOf(Span), @@ -1194,6 +1198,7 @@ impl<'tcx> SubregionOrigin<'tcx> { CallRcvr(a) => a, CallArg(a) => a, CallReturn(a) => a, + Operand(a) => a, AddrOf(a) => a, AutoBorrow(a) => a, SafeDestructor(a) => a, @@ -1257,6 +1262,7 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> { CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)), CallArg(a) => format!("CallArg({})", a.repr(tcx)), CallReturn(a) => format!("CallReturn({})", a.repr(tcx)), + Operand(a) => format!("Operand({})", a.repr(tcx)), AddrOf(a) => format!("AddrOf({})", a.repr(tcx)), AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)), SafeDestructor(a) => format!("SafeDestructor({})", a.repr(tcx)), diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 5cdfdcc7c9b6c..b4fd34f206fa7 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -977,7 +977,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { self.expansion(&mut var_data); self.contraction(&mut var_data); let values = - self.extract_values_and_collect_conflicts(&var_data[], + self.extract_values_and_collect_conflicts(&var_data[..], errors); self.collect_concrete_region_errors(&values, errors); values diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs index 1e0d14544ff88..33da3092b2a25 100644 --- a/src/librustc/middle/infer/sub.rs +++ b/src/librustc/middle/infer/sub.rs @@ -10,12 +10,8 @@ use super::combine::*; use super::{cres, CresCompare}; -use super::equate::Equate; -use super::glb::Glb; use super::higher_ranked::HigherRankedRelations; -use super::InferCtxt; -use super::lub::Lub; -use super::{TypeTrace, Subtype}; +use super::{Subtype}; use super::type_variable::{SubtypeOf, SupertypeOf}; use middle::ty::{BuiltinBounds}; @@ -37,28 +33,30 @@ pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "sub".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } - - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } - - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - Sub(self.fields.switch_expected()).tys(b, a) + fn tag(&self) -> String { "Sub".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } + + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Bivariant => self.bivariate().tys(a, b), + ty::Contravariant => Sub(self.fields.switch_expected()).tys(b, a), + } } - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region> { - let opp = CombineFields { - a_is_expected: !self.fields.a_is_expected, - ..self.fields.clone() - }; - Sub(opp).regions(b, a) - } + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Bivariant => self.bivariate().regions(a, b), + ty::Contravariant => Sub(self.fields.switch_expected()).regions(b, a), + } + } fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> { debug!("{}.regions({}, {})", diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs index 9b8a4a844120d..a856137af090a 100644 --- a/src/librustc/middle/infer/type_variable.rs +++ b/src/librustc/middle/infer/type_variable.rs @@ -14,6 +14,7 @@ use self::UndoEntry::*; use middle::ty::{self, Ty}; use std::cmp::min; +use std::marker::PhantomData; use std::mem; use std::u32; use util::snapshot_vec as sv; @@ -42,13 +43,13 @@ enum UndoEntry { Relate(ty::TyVid, ty::TyVid), } -struct Delegate<'tcx>; +struct Delegate<'tcx>(PhantomData<&'tcx ()>); type Relation = (RelationDir, ty::TyVid); #[derive(Copy, PartialEq, Debug)] pub enum RelationDir { - SubtypeOf, SupertypeOf, EqTo + SubtypeOf, SupertypeOf, EqTo, BiTo } impl RelationDir { @@ -56,14 +57,15 @@ impl RelationDir { match self { SubtypeOf => SupertypeOf, SupertypeOf => SubtypeOf, - EqTo => EqTo + EqTo => EqTo, + BiTo => BiTo, } } } impl<'tcx> TypeVariableTable<'tcx> { pub fn new() -> TypeVariableTable<'tcx> { - TypeVariableTable { values: sv::SnapshotVec::new(Delegate) } + TypeVariableTable { values: sv::SnapshotVec::new(Delegate(PhantomData)) } } fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec { diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs index 235f3f994c65e..0675cec6f69b5 100644 --- a/src/librustc/middle/infer/unify.rs +++ b/src/librustc/middle/infer/unify.rs @@ -18,6 +18,7 @@ use middle::infer::{uok, ures}; use middle::infer::InferCtxt; use std::cell::RefCell; use std::fmt::Debug; +use std::marker::PhantomData; use syntax::ast; use util::snapshot_vec as sv; @@ -79,7 +80,7 @@ pub struct UnificationTable { /// made during the snapshot may either be *committed* or *rolled back*. pub struct Snapshot { // Link snapshot to the key type `K` of the table. - marker: marker::CovariantType, + marker: marker::PhantomData, snapshot: sv::Snapshot, } @@ -92,7 +93,7 @@ pub struct Node { } #[derive(Copy)] -pub struct Delegate; +pub struct Delegate(PhantomData); // We can't use V:LatticeValue, much as I would like to, // because frequently the pattern is that V=Option for some @@ -102,14 +103,14 @@ pub struct Delegate; impl UnificationTable { pub fn new() -> UnificationTable { UnificationTable { - values: sv::SnapshotVec::new(Delegate), + values: sv::SnapshotVec::new(Delegate(PhantomData)), } } /// Starts a new snapshot. Each snapshot must be either /// rolled back or committed in a "LIFO" (stack) order. pub fn snapshot(&mut self) -> Snapshot { - Snapshot { marker: marker::CovariantType::, + Snapshot { marker: marker::PhantomData::, snapshot: self.values.start_snapshot() } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index e13a5672778e2..56c5928a132b1 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -147,18 +147,12 @@ struct LanguageItemCollector<'a> { impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> { fn visit_item(&mut self, item: &ast::Item) { - match extract(&item.attrs) { - Some(value) => { - let item_index = self.item_refs.get(&value[]).map(|x| *x); - - match item_index { - Some(item_index) => { - self.collect_item(item_index, local_def(item.id), item.span) - } - None => {} - } + if let Some(value) = extract(&item.attrs) { + let item_index = self.item_refs.get(&value[..]).cloned(); + + if let Some(item_index) = item_index { + self.collect_item(item_index, local_def(item.id), item.span) } - None => {} } visit::walk_item(self, item); @@ -312,12 +306,13 @@ lets_do_this! { ExchangeHeapLangItem, "exchange_heap", exchange_heap; OwnedBoxLangItem, "owned_box", owned_box; + PhantomFnItem, "phantom_fn", phantom_fn; PhantomDataItem, "phantom_data", phantom_data; + // Deprecated: CovariantTypeItem, "covariant_type", covariant_type; ContravariantTypeItem, "contravariant_type", contravariant_type; InvariantTypeItem, "invariant_type", invariant_type; - CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime; ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime; InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d4fe09793131f..e58136fb3f4e4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1119,7 +1119,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // Uninteresting cases: just propagate in rev exec order ast::ExprVec(ref exprs) => { - self.propagate_through_exprs(&exprs[], succ) + self.propagate_through_exprs(&exprs[..], succ) } ast::ExprRepeat(ref element, ref count) => { @@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } else { succ }; - let succ = self.propagate_through_exprs(&args[], succ); + let succ = self.propagate_through_exprs(&args[..], succ); self.propagate_through_expr(&**f, succ) } @@ -1156,11 +1156,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } else { succ }; - self.propagate_through_exprs(&args[], succ) + self.propagate_through_exprs(&args[..], succ) } ast::ExprTup(ref exprs) => { - self.propagate_through_exprs(&exprs[], succ) + self.propagate_through_exprs(&exprs[..], succ) } ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2f0462ab8c338..e539f6ae6cb93 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -407,7 +407,7 @@ impl RegionMaps { pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.scope_map.borrow().get(&id).map(|x| *x) + self.scope_map.borrow().get(&id).cloned() } #[allow(dead_code)] // used in middle::cfg diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index e91d7d8c52cde..3ba08c1032031 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -562,7 +562,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec Substs<'tcx> { } pub fn self_ty(&self) -> Option> { - self.types.get_self().map(|&t| t) + self.types.get_self().cloned() } pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 3a7522cafee90..e199a60c370e3 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -10,24 +10,27 @@ //! See `doc.rs` for high-level documentation +use super::Normalized; use super::SelectionContext; -use super::{Obligation, ObligationCause}; +use super::{ObligationCause}; +use super::PredicateObligation; use super::project; use super::util; use middle::subst::{Subst, TypeSpace}; -use middle::ty::{self, Ty}; -use middle::infer::InferCtxt; +use middle::ty::{self, ToPolyTraitRef, Ty}; +use middle::infer::{self, InferCtxt}; use std::collections::HashSet; use std::rc::Rc; use syntax::ast; use syntax::codemap::DUMMY_SP; use util::ppaux::Repr; -pub fn impl_can_satisfy(infcx: &InferCtxt, - impl1_def_id: ast::DefId, - impl2_def_id: ast::DefId) - -> bool +/// True if there exist types that satisfy both of the two given impls. +pub fn overlapping_impls(infcx: &InferCtxt, + impl1_def_id: ast::DefId, + impl2_def_id: ast::DefId) + -> bool { debug!("impl_can_satisfy(\ impl1_def_id={}, \ @@ -35,28 +38,68 @@ pub fn impl_can_satisfy(infcx: &InferCtxt, impl1_def_id.repr(infcx.tcx), impl2_def_id.repr(infcx.tcx)); - let param_env = ty::empty_parameter_environment(infcx.tcx); - let mut selcx = SelectionContext::intercrate(infcx, ¶m_env); - let cause = ObligationCause::dummy(); - - // `impl1` provides an implementation of `Foo for Z`. - let impl1_substs = - util::fresh_substs_for_impl(infcx, DUMMY_SP, impl1_def_id); - let impl1_trait_ref = - (*ty::impl_trait_ref(infcx.tcx, impl1_def_id).unwrap()).subst(infcx.tcx, &impl1_substs); - let impl1_trait_ref = - project::normalize(&mut selcx, cause.clone(), &impl1_trait_ref); - - // Determine whether `impl2` can provide an implementation for those - // same types. - let obligation = Obligation::new(cause, - ty::Binder(ty::TraitPredicate { - trait_ref: Rc::new(impl1_trait_ref.value), - })); - debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx)); - selcx.evaluate_impl(impl2_def_id, &obligation) && - impl1_trait_ref.obligations.iter().all( - |o| selcx.evaluate_obligation(o)) + let param_env = &ty::empty_parameter_environment(infcx.tcx); + let selcx = &mut SelectionContext::intercrate(infcx, param_env); + infcx.probe(|_| { + overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) + }) +} + +/// Can the types from impl `a` be used to satisfy impl `b`? +/// (Including all conditions) +fn overlap(selcx: &mut SelectionContext, + a_def_id: ast::DefId, + b_def_id: ast::DefId) + -> bool +{ + let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id); + let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id); + + // Does `a <: b` hold? If not, no overlap. + if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(), + true, + infer::Misc(DUMMY_SP), + a_trait_ref.to_poly_trait_ref(), + b_trait_ref.to_poly_trait_ref()) { + return false; + } + + // Are any of the obligations unsatisfiable? If so, no overlap. + a_obligations.iter() + .chain(b_obligations.iter()) + .all(|o| selcx.evaluate_obligation(o)) +} + +/// Instantiate fresh variables for all bound parameters of the impl +/// and return the impl trait ref with those variables substituted. +fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, + impl_def_id: ast::DefId) + -> (Rc>, + Vec>) +{ + let impl_substs = + &util::fresh_substs_for_impl(selcx.infcx(), DUMMY_SP, impl_def_id); + let impl_trait_ref = + ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap(); + let impl_trait_ref = + impl_trait_ref.subst(selcx.tcx(), impl_substs); + let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = + project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref); + + let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id); + let predicates = predicates.instantiate(selcx.tcx(), impl_substs); + let Normalized { value: predicates, obligations: normalization_obligations2 } = + project::normalize(selcx, ObligationCause::dummy(), &predicates); + let impl_obligations = + util::predicates_for_generics(selcx.tcx(), ObligationCause::dummy(), 0, &predicates); + + let impl_obligations: Vec<_> = + impl_obligations.into_iter() + .chain(normalization_obligations1.into_iter()) + .chain(normalization_obligations2.into_iter()) + .collect(); + + (impl_trait_ref, impl_obligations) } pub enum OrphanCheckErr<'tcx> { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 57c9fa7a4d964..a63dcfc24a10e 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -28,6 +28,7 @@ use util::ppaux::{Repr, UserString}; pub use self::error_reporting::report_fulfillment_errors; pub use self::error_reporting::suggest_new_overflow_limit; pub use self::coherence::orphan_check; +pub use self::coherence::overlapping_impls; pub use self::coherence::OrphanCheckErr; pub use self::fulfill::{FulfillmentContext, RegionObligation}; pub use self::project::MismatchedProjectionTypes; @@ -270,16 +271,6 @@ pub struct VtableObjectData<'tcx> { pub object_ty: Ty<'tcx>, } -/// True if there exist types that satisfy both of the two given impls. -pub fn overlapping_impls(infcx: &InferCtxt, - impl1_def_id: ast::DefId, - impl2_def_id: ast::DefId) - -> bool -{ - coherence::impl_can_satisfy(infcx, impl1_def_id, impl2_def_id) && - coherence::impl_can_satisfy(infcx, impl2_def_id, impl1_def_id) -} - /// Creates predicate obligations from the generic bounds. pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>, cause: ObligationCause<'tcx>, diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index b2701ae875c0c..f10f7eb3951c7 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -20,7 +20,7 @@ use super::supertraits; use super::elaborate_predicates; -use middle::subst::{self, SelfSpace}; +use middle::subst::{self, SelfSpace, TypeSpace}; use middle::traits; use middle::ty::{self, Ty}; use std::rc::Rc; @@ -31,6 +31,10 @@ pub enum ObjectSafetyViolation<'tcx> { /// Self : Sized declared on the trait SizedSelf, + /// Supertrait reference references `Self` an in illegal location + /// (e.g. `trait Foo : Bar`) + SupertraitSelf, + /// Method has something illegal Method(Rc>, MethodViolationCode), } @@ -57,7 +61,7 @@ pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>, { // Because we query yes/no results frequently, we keep a cache: let cached_result = - tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).map(|&r| r); + tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).cloned(); let result = cached_result.unwrap_or_else(|| { @@ -110,6 +114,9 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>, if trait_has_sized_self(tcx, trait_def_id) { violations.push(ObjectSafetyViolation::SizedSelf); } + if supertraits_reference_self(tcx, trait_def_id) { + violations.push(ObjectSafetyViolation::SupertraitSelf); + } debug!("object_safety_violations_for_trait(trait_def_id={}) = {}", trait_def_id.repr(tcx), @@ -118,6 +125,35 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>, violations } +fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>, + trait_def_id: ast::DefId) + -> bool +{ + let trait_def = ty::lookup_trait_def(tcx, trait_def_id); + let trait_ref = trait_def.trait_ref.clone(); + let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref)); + predicates + .into_iter() + .any(|predicate| { + match predicate { + ty::Predicate::Trait(ref data) => { + // In the case of a trait predicate, we can skip the "self" type. + Some(data.def_id()) != tcx.lang_items.phantom_fn() && + data.0.trait_ref.substs.types.get_slice(TypeSpace) + .iter() + .cloned() + .any(is_self) + } + ty::Predicate::Projection(..) | + ty::Predicate::TypeOutlives(..) | + ty::Predicate::RegionOutlives(..) | + ty::Predicate::Equate(..) => { + false + } + } + }) +} + fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>, trait_def_id: ast::DefId) -> bool @@ -138,11 +174,7 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>, .any(|predicate| { match predicate { ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => { - let self_ty = trait_pred.0.self_ty(); - match self_ty.sty { - ty::ty_param(ref data) => data.space == subst::SelfSpace, - _ => false, - } + is_self(trait_pred.0.self_ty()) } ty::Predicate::Projection(..) | ty::Predicate::Trait(..) | @@ -295,8 +327,17 @@ impl<'tcx> Repr<'tcx> for ObjectSafetyViolation<'tcx> { match *self { ObjectSafetyViolation::SizedSelf => format!("SizedSelf"), + ObjectSafetyViolation::SupertraitSelf => + format!("SupertraitSelf"), ObjectSafetyViolation::Method(ref m, code) => format!("Method({},{:?})", m.repr(tcx), code), } } } + +fn is_self<'tcx>(ty: Ty<'tcx>) -> bool { + match ty.sty { + ty::ty_param(ref data) => data.space == subst::SelfSpace, + _ => false, + } +} diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 027415de998df..0e29892084175 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -132,6 +132,7 @@ pub enum MethodMatchedData { /// parameters) that would have to be inferred from the impl. #[derive(PartialEq,Eq,Debug,Clone)] enum SelectionCandidate<'tcx> { + PhantomFnCandidate, BuiltinCandidate(ty::BuiltinBound), ParamCandidate(ty::PolyTraitRef<'tcx>), ImplCandidate(ast::DefId), @@ -736,7 +737,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { let cache = self.pick_candidate_cache(); let hashmap = cache.hashmap.borrow(); - hashmap.get(&cache_fresh_trait_pred.0.trait_ref).map(|c| (*c).clone()) + hashmap.get(&cache_fresh_trait_pred.0.trait_ref).cloned() } fn insert_candidate_cache(&mut self, @@ -793,8 +794,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { stack: &TraitObligationStack<'o, 'tcx>) -> Result, SelectionError<'tcx>> { - // Check for overflow. - let TraitObligationStack { obligation, .. } = *stack; let mut candidates = SelectionCandidateSet { @@ -802,6 +801,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ambiguous: false }; + // Check for the `PhantomFn` trait. This is really just a + // special annotation that is *always* considered to match, no + // matter what the type parameters are etc. + if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) { + candidates.vec.push(PhantomFnCandidate); + return Ok(candidates); + } + // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. @@ -996,7 +1003,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let all_bounds = util::transitive_bounds( - self.tcx(), &caller_trait_refs[]); + self.tcx(), &caller_trait_refs[..]); let matching_bounds = all_bounds.filter( @@ -1521,7 +1528,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::substd_enum_variants(self.tcx(), def_id, substs) .iter() .flat_map(|variant| variant.args.iter()) - .map(|&ty| ty) + .cloned() .collect(); nominal(self, bound, def_id, types) } @@ -1629,6 +1636,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { try!(self.confirm_builtin_candidate(obligation, builtin_bound)))) } + PhantomFnCandidate | ErrorCandidate => { Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() })) } @@ -2295,6 +2303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> { fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { match *self { + PhantomFnCandidate => format!("PhantomFnCandidate"), ErrorCandidate => format!("ErrorCandidate"), BuiltinCandidate(b) => format!("BuiltinCandidate({:?})", b), ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e3eda02b0a842..e9908397f9703 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -68,15 +68,16 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; use util::nodemap::{FnvHashMap}; use arena::TypedArena; -use std::borrow::{BorrowFrom, Cow}; +use std::borrow::{Borrow, Cow}; use std::cell::{Cell, RefCell}; use std::cmp; use std::fmt; -use std::hash::{Hash, Writer, SipHasher, Hasher}; +use std::hash::{Hash, SipHasher, Hasher}; +#[cfg(stage0)] use std::hash::Writer; use std::mem; use std::ops; use std::rc::Rc; -use std::vec::CowVec; +use std::vec::{CowVec, IntoIter}; use collections::enum_set::{EnumSet, CLike}; use std::collections::{HashMap, HashSet}; use syntax::abi; @@ -958,11 +959,18 @@ impl<'tcx> PartialEq for TyS<'tcx> { } impl<'tcx> Eq for TyS<'tcx> {} +#[cfg(stage0)] impl<'tcx, S: Writer + Hasher> Hash for TyS<'tcx> { fn hash(&self, s: &mut S) { (self as *const _).hash(s) } } +#[cfg(not(stage0))] +impl<'tcx> Hash for TyS<'tcx> { + fn hash(&self, s: &mut H) { + (self as *const _).hash(s) + } +} pub type Ty<'tcx> = &'tcx TyS<'tcx>; @@ -980,15 +988,22 @@ impl<'tcx> PartialEq for InternedTy<'tcx> { impl<'tcx> Eq for InternedTy<'tcx> {} +#[cfg(stage0)] impl<'tcx, S: Writer + Hasher> Hash for InternedTy<'tcx> { fn hash(&self, s: &mut S) { self.ty.sty.hash(s) } } +#[cfg(not(stage0))] +impl<'tcx> Hash for InternedTy<'tcx> { + fn hash(&self, s: &mut H) { + self.ty.sty.hash(s) + } +} -impl<'tcx> BorrowFrom> for sty<'tcx> { - fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> { - &ty.ty.sty +impl<'tcx> Borrow> for InternedTy<'tcx> { + fn borrow<'a>(&'a self) -> &'a sty<'tcx> { + &self.ty.sty } } @@ -2004,6 +2019,40 @@ impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } impl<'tcx> Predicate<'tcx> { + /// Iterates over the types in this predicate. Note that in all + /// cases this is skipping over a binder, so late-bound regions + /// with depth 0 are bound by the predicate. + pub fn walk_tys(&self) -> IntoIter> { + let vec: Vec<_> = match *self { + ty::Predicate::Trait(ref data) => { + data.0.trait_ref.substs.types.as_slice().to_vec() + } + ty::Predicate::Equate(ty::Binder(ref data)) => { + vec![data.0, data.1] + } + ty::Predicate::TypeOutlives(ty::Binder(ref data)) => { + vec![data.0] + } + ty::Predicate::RegionOutlives(..) => { + vec![] + } + ty::Predicate::Projection(ref data) => { + let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice(); + trait_inputs.iter() + .cloned() + .chain(Some(data.0.ty).into_iter()) + .collect() + } + }; + + // The only reason to collect into a vector here is that I was + // too lazy to make the full (somewhat complicated) iterator + // type that would be needed here. But I wanted this fn to + // return an iterator conceptually, rather than a `Vec`, so as + // to be closer to `Ty::walk`. + vec.into_iter() + } + pub fn has_escaping_regions(&self) -> bool { match *self { Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(), @@ -2331,7 +2380,7 @@ impl ClosureKind { }; match result { Ok(trait_did) => trait_did, - Err(err) => cx.sess.fatal(&err[]), + Err(err) => cx.sess.fatal(&err[..]), } } } @@ -2665,7 +2714,7 @@ impl FlagComputation { } &ty_tup(ref ts) => { - self.add_tys(&ts[]); + self.add_tys(&ts[..]); } &ty_bare_fn(_, ref f) => { @@ -2836,7 +2885,7 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>, def_id: ast::DefId, input_tys: &[Ty<'tcx>], output: Ty<'tcx>) -> Ty<'tcx> { - let input_args = input_tys.iter().map(|ty| *ty).collect(); + let input_args = input_tys.iter().cloned().collect(); mk_bare_fn(cx, Some(def_id), cx.mk_bare_fn(BareFnTy { @@ -2959,6 +3008,13 @@ impl<'tcx> TyS<'tcx> { assert_eq!(r, Some(self)); walker } + + pub fn as_opt_param_ty(&self) -> Option { + match self.sty { + ty::ty_param(ref d) => Some(d.clone()), + _ => None, + } + } } pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F) @@ -3451,7 +3507,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { ty_struct(did, substs) => { let flds = struct_fields(cx, did, substs); let mut res = - TypeContents::union(&flds[], + TypeContents::union(&flds[..], |f| tc_mt(cx, f.mt, cache)); if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) { @@ -3474,14 +3530,14 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { } ty_tup(ref tys) => { - TypeContents::union(&tys[], + TypeContents::union(&tys[..], |ty| tc_ty(cx, *ty, cache)) } ty_enum(did, substs) => { let variants = substd_enum_variants(cx, did, substs); let mut res = - TypeContents::union(&variants[], |variant| { + TypeContents::union(&variants[..], |variant| { TypeContents::union(&variant.args[], |arg_ty| { tc_ty(cx, *arg_ty, cache) @@ -3805,7 +3861,7 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) -> Representability { match ty.sty { ty_tup(ref ts) => { - find_nonrepresentable(cx, sp, seen, ts.iter().map(|ty| *ty)) + find_nonrepresentable(cx, sp, seen, ts.iter().cloned()) } // Fixed-length vectors. // FIXME(#11924) Behavior undecided for zero-length vectors. @@ -4112,7 +4168,7 @@ pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>, variant: Option) -> Option> { match (&ty.sty, variant) { - (&ty_tup(ref v), None) => v.get(i).map(|&t| t), + (&ty_tup(ref v), None) => v.get(i).cloned(), (&ty_struct(def_id, substs), None) => lookup_struct_fields(cx, def_id) @@ -4933,7 +4989,7 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { } pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { - cx.provided_method_sources.borrow().get(&id).map(|x| *x) + cx.provided_method_sources.borrow().get(&id).cloned() } pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) @@ -4944,7 +5000,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) match item.node { ItemTrait(_, _, _, ref ms) => { let (_, p) = - ast_util::split_trait_methods(&ms[]); + ast_util::split_trait_methods(&ms[..]); p.iter() .map(|m| { match impl_or_trait_item( @@ -6600,7 +6656,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, } /// A free variable referred to in a function. -#[derive(Copy, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] pub struct Freevar { /// The variable being accessed free. pub def: def::Def, @@ -6625,7 +6681,7 @@ pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where { match tcx.freevars.borrow().get(&fid) { None => f(&[]), - Some(d) => f(&d[]) + Some(d) => f(&d[..]) } } diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index ee3fd681a0052..60a9ffc7d2e13 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -55,7 +55,7 @@ pub fn check_crate(krate: &ast::Crate, pub fn link_name(attrs: &[ast::Attribute]) -> Option { lang_items::extract(attrs).and_then(|name| { - $(if &name[] == stringify!($name) { + $(if &name[..] == stringify!($name) { Some(InternedString::new(stringify!($sym))) } else)* { None diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index 1895cbcb5421e..b3bc898748fdc 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -111,19 +111,19 @@ impl<'a> PluginLoader<'a> { // inside this crate, so continue would spew "macro undefined" // errors Err(err) => { - self.sess.span_fatal(span, &err[]) + self.sess.span_fatal(span, &err[..]) } }; unsafe { let registrar = - match lib.symbol(&symbol[]) { + match lib.symbol(&symbol[..]) { Ok(registrar) => { mem::transmute::<*mut u8,PluginRegistrarFun>(registrar) } // again fatal if we can't register macros Err(err) => { - self.sess.span_fatal(span, &err[]) + self.sess.span_fatal(span, &err[..]) } }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5768539b2cd76..93a25de0491fe 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -629,7 +629,7 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig { append_configuration(&mut user_cfg, InternedString::new("test")) } let mut v = user_cfg.into_iter().collect::>(); - v.push_all(&default_cfg[]); + v.push_all(&default_cfg[..]); v } @@ -824,7 +824,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec ) -> ast::CrateConfig { pub fn build_session_options(matches: &getopts::Matches) -> Options { let unparsed_crate_types = matches.opt_strs("crate-type"); let crate_types = parse_crate_types_from_list(unparsed_crate_types) - .unwrap_or_else(|e| early_error(&e[])); + .unwrap_or_else(|e| early_error(&e[..])); let mut lint_opts = vec!(); let mut describe_lints = false; @@ -923,7 +923,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let mut search_paths = SearchPaths::new(); for s in &matches.opt_strs("L") { - search_paths.add_path(&s[]); + search_paths.add_path(&s[..]); } let libs = matches.opt_strs("l").into_iter().map(|s| { @@ -981,7 +981,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { --debuginfo"); } - let color = match matches.opt_str("color").as_ref().map(|s| &s[]) { + let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) { Some("auto") => Auto, Some("always") => Always, Some("never") => Never, @@ -1119,7 +1119,7 @@ mod test { let sessopts = build_session_options(matches); let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess); - assert!((attr::contains_name(&cfg[], "test"))); + assert!((attr::contains_name(&cfg[..], "test"))); } // When the user supplies --test and --cfg test, don't implicitly add diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index bd44dbe78f543..c1c5518887577 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -75,13 +75,13 @@ impl Session { } pub fn span_err(&self, sp: Span, msg: &str) { match split_msg_into_multilines(msg) { - Some(msg) => self.diagnostic().span_err(sp, &msg[]), + Some(msg) => self.diagnostic().span_err(sp, &msg[..]), None => self.diagnostic().span_err(sp, msg) } } pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) { match split_msg_into_multilines(msg) { - Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[], code), + Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code), None => self.diagnostic().span_err_with_code(sp, msg, code) } } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index d3d0f56c3ce90..c9d50b9cecf84 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -13,7 +13,8 @@ use std::cell::{RefCell, Cell}; use std::collections::HashMap; use std::fmt::Debug; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; +#[cfg(stage0)] use std::hash::Hasher; use std::iter::repeat; use std::time::Duration; use std::collections::hash_state::HashState; @@ -144,11 +145,54 @@ pub fn block_query

(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) - /// Efficiency note: This is implemented in an inefficient way because it is typically invoked on /// very small graphs. If the graphs become larger, a more efficient graph representation and /// algorithm would probably be advised. +#[cfg(stage0)] pub fn can_reach(edges_map: &HashMap, S>, source: T, destination: T) -> bool where S: HashState, ::Hasher: Hasher, - T: Hash< ::Hasher> + Eq + Clone, + T: Hash<::Hasher> + Eq + Clone, +{ + if source == destination { + return true; + } + + // Do a little breadth-first-search here. The `queue` list + // doubles as a way to detect if we've seen a particular FR + // before. Note that we expect this graph to be an *extremely + // shallow* tree. + let mut queue = vec!(source); + let mut i = 0; + while i < queue.len() { + match edges_map.get(&queue[i]) { + Some(edges) => { + for target in edges { + if *target == destination { + return true; + } + + if !queue.iter().any(|x| x == target) { + queue.push((*target).clone()); + } + } + } + None => {} + } + i += 1; + } + return false; +} +/// K: Eq + Hash, V, S, H: Hasher +/// +/// Determines whether there exists a path from `source` to `destination`. The graph is defined by +/// the `edges_map`, which maps from a node `S` to a list of its adjacent nodes `T`. +/// +/// Efficiency note: This is implemented in an inefficient way because it is typically invoked on +/// very small graphs. If the graphs become larger, a more efficient graph representation and +/// algorithm would probably be advised. +#[cfg(not(stage0))] +pub fn can_reach(edges_map: &HashMap, S>, source: T, + destination: T) -> bool + where S: HashState, T: Hash + Eq + Clone, { if source == destination { return true; @@ -206,12 +250,57 @@ pub fn can_reach(edges_map: &HashMap, S>, source: T, /// } /// ``` #[inline(always)] +#[cfg(stage0)] pub fn memoized(cache: &RefCell>, arg: T, f: F) -> U where T: Clone + Hash<::Hasher> + Eq, U: Clone, S: HashState, ::Hasher: Hasher, F: FnOnce(T) -> U, +{ + let key = arg.clone(); + let result = cache.borrow().get(&key).cloned(); + match result { + Some(result) => result, + None => { + let result = f(arg); + cache.borrow_mut().insert(key, result.clone()); + result + } + } +} +/// Memoizes a one-argument closure using the given RefCell containing +/// a type implementing MutableMap to serve as a cache. +/// +/// In the future the signature of this function is expected to be: +/// ``` +/// pub fn memoized>( +/// cache: &RefCell, +/// f: &|T| -> U +/// ) -> impl |T| -> U { +/// ``` +/// but currently it is not possible. +/// +/// # Example +/// ``` +/// struct Context { +/// cache: RefCell> +/// } +/// +/// fn factorial(ctxt: &Context, n: uint) -> uint { +/// memoized(&ctxt.cache, n, |n| match n { +/// 0 | 1 => n, +/// _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1) +/// }) +/// } +/// ``` +#[inline(always)] +#[cfg(not(stage0))] +pub fn memoized(cache: &RefCell>, arg: T, f: F) -> U + where T: Clone + Hash + Eq, + U: Clone, + S: HashState, + F: FnOnce(T) -> U, { let key = arg.clone(); let result = cache.borrow().get(&key).map(|result| result.clone()); diff --git a/src/librustc/util/lev_distance.rs b/src/librustc/util/lev_distance.rs index ca1bb7d7a9404..10a7b2abea80b 100644 --- a/src/librustc/util/lev_distance.rs +++ b/src/librustc/util/lev_distance.rs @@ -48,7 +48,7 @@ fn test_lev_distance() { for c in (0u32..MAX as u32) .filter_map(|i| from_u32(i)) .map(|i| i.to_string()) { - assert_eq!(lev_distance(&c[], &c[]), 0); + assert_eq!(lev_distance(&c[..], &c[..]), 0); } let a = "\nMäry häd ä little lämb\n\nLittle lämb\n"; diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index f8e3defe19d63..1b07ce789e77c 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -15,7 +15,8 @@ use std::collections::hash_state::{DefaultState}; use std::collections::{HashMap, HashSet}; use std::default::Default; -use std::hash::{Hasher, Writer, Hash}; +use std::hash::{Hasher, Hash}; +#[cfg(stage0)] use std::hash::Writer; use syntax::ast; pub type FnvHashMap = HashMap>; @@ -27,12 +28,22 @@ pub type DefIdMap = FnvHashMap; pub type NodeSet = FnvHashSet; pub type DefIdSet = FnvHashSet; +#[cfg(stage0)] pub fn FnvHashMap + Eq, V>() -> FnvHashMap { Default::default() } +#[cfg(stage0)] pub fn FnvHashSet + Eq>() -> FnvHashSet { Default::default() } +#[cfg(not(stage0))] +pub fn FnvHashMap() -> FnvHashMap { + Default::default() +} +#[cfg(not(stage0))] +pub fn FnvHashSet() -> FnvHashSet { + Default::default() +} pub fn NodeMap() -> NodeMap { FnvHashMap() } pub fn DefIdMap() -> DefIdMap { FnvHashMap() } @@ -52,12 +63,14 @@ impl Default for FnvHasher { fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) } } +#[cfg(stage0)] impl Hasher for FnvHasher { type Output = u64; fn reset(&mut self) { *self = Default::default(); } fn finish(&self) -> u64 { self.0 } } +#[cfg(stage0)] impl Writer for FnvHasher { fn write(&mut self, bytes: &[u8]) { let FnvHasher(mut hash) = *self; @@ -68,3 +81,16 @@ impl Writer for FnvHasher { *self = FnvHasher(hash); } } + +#[cfg(not(stage0))] +impl Hasher for FnvHasher { + fn write(&mut self, bytes: &[u8]) { + let FnvHasher(mut hash) = *self; + for byte in bytes { + hash = hash ^ (*byte as u64); + hash = hash * 0x100000001b3; + } + *self = FnvHasher(hash); + } + fn finish(&self) -> u64 { self.0 } +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d54199a679a26..1d46c011bb32e 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -28,7 +28,8 @@ use middle::ty_fold::TypeFoldable; use std::collections::HashMap; use std::collections::hash_state::HashState; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; +#[cfg(stage0)] use std::hash::Hasher; use std::rc::Rc; use syntax::abi; use syntax::ast_map; @@ -292,7 +293,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { Some(def_id) => { s.push_str(" {"); let path_str = ty::item_path_str(cx, def_id); - s.push_str(&path_str[]); + s.push_str(&path_str[..]); s.push_str("}"); } None => { } @@ -376,7 +377,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { .iter() .map(|elem| ty_to_string(cx, *elem)) .collect::>(); - match &strs[] { + match &strs[..] { [ref string] => format!("({},)", string), strs => format!("({})", strs.connect(", ")) } @@ -508,13 +509,26 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>, // avoid those ICEs. let generics = get_generics(); + let has_self = substs.self_ty().is_some(); let tps = substs.types.get_slice(subst::TypeSpace); let ty_params = generics.types.get_slice(subst::TypeSpace); let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some()); let num_defaults = if has_defaults { ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| { match def.default { - Some(default) => default.subst(cx, substs) == actual, + Some(default) => { + if !has_self && ty::type_has_self(default) { + // In an object type, there is no `Self`, and + // thus if the default value references Self, + // the user will be required to give an + // explicit value. We can't even do the + // substitution below to check without causing + // an ICE. (#18956). + false + } else { + default.subst(cx, substs) == actual + } + } None => false } }).count() @@ -625,7 +639,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for [T] { impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - repr_vec(tcx, &self[]) + repr_vec(tcx, &self[..]) } } @@ -633,7 +647,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice { // autoderef cannot convert the &[T] handler impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - repr_vec(tcx, &self[]) + repr_vec(tcx, &self[..]) } } @@ -673,7 +687,7 @@ impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> { &base, trait_ref.substs, trait_ref.def_id, - &projection_bounds[], + &projection_bounds[..], || ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone()) } } @@ -1259,7 +1273,7 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder } }) }); - let names: Vec<_> = names.iter().map(|s| &s[]).collect(); + let names: Vec<_> = names.iter().map(|s| &s[..]).collect(); let value_str = unbound_value.user_string(tcx); if names.len() == 0 { @@ -1420,6 +1434,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder { } } +#[cfg(stage0)] impl<'tcx, S, K, V> Repr<'tcx> for HashMap where K: Hash<::Hasher> + Eq + Repr<'tcx>, V: Repr<'tcx>, @@ -1435,6 +1450,21 @@ impl<'tcx, S, K, V> Repr<'tcx> for HashMap } } +#[cfg(not(stage0))] +impl<'tcx, S, K, V> Repr<'tcx> for HashMap + where K: Hash + Eq + Repr<'tcx>, + V: Repr<'tcx>, + S: HashState, +{ + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + format!("HashMap({})", + self.iter() + .map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx))) + .collect::>() + .connect(", ")) + } +} + impl<'tcx, T, U> Repr<'tcx> for ty::OutlivesPredicate where T : Repr<'tcx> + TypeFoldable<'tcx>, U : Repr<'tcx> + TypeFoldable<'tcx>, diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index b779963a21917..c45ee258342ec 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -53,7 +53,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, args: &str, cwd: Option<&Path>, paths: &[&Path]) -> ProcessOutput { let ar = match *maybe_ar_prog { - Some(ref ar) => &ar[], + Some(ref ar) => &ar[..], None => "ar" }; let mut cmd = Command::new(ar); @@ -84,7 +84,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, o }, Err(e) => { - handler.err(&format!("could not exec `{}`: {}", &ar[], + handler.err(&format!("could not exec `{}`: {}", &ar[..], e)[]); handler.abort_if_errors(); panic!("rustc::back::archive::run_ar() should not reach this point"); @@ -101,10 +101,10 @@ pub fn find_library(name: &str, osprefix: &str, ossuffix: &str, for path in search_paths { debug!("looking for {} inside {:?}", name, path.display()); - let test = path.join(&oslibname[]); + let test = path.join(&oslibname[..]); if test.exists() { return test } if oslibname != unixlibname { - let test = path.join(&unixlibname[]); + let test = path.join(&unixlibname[..]); if test.exists() { return test } } } @@ -192,12 +192,12 @@ impl<'a> ArchiveBuilder<'a> { // as simple comparison is not enough - there // might be also an extra name suffix let obj_start = format!("{}", name); - let obj_start = &obj_start[]; + let obj_start = &obj_start[..]; // Ignoring all bytecode files, no matter of // name let bc_ext = ".bytecode.deflate"; - self.add_archive(rlib, &name[], |fname: &str| { + self.add_archive(rlib, &name[..], |fname: &str| { let skip_obj = lto && fname.starts_with(obj_start) && fname.ends_with(".o"); skip_obj || fname.ends_with(bc_ext) || fname == METADATA_FILENAME @@ -234,7 +234,7 @@ impl<'a> ArchiveBuilder<'a> { // allow running `ar s file.a` to update symbols only. if self.should_update_symbols { run_ar(self.archive.handler, &self.archive.maybe_ar_prog, - "s", Some(self.work_dir.path()), &args[]); + "s", Some(self.work_dir.path()), &args[..]); } return self.archive; } @@ -254,7 +254,7 @@ impl<'a> ArchiveBuilder<'a> { // Add the archive members seen so far, without updating the // symbol table (`S`). run_ar(self.archive.handler, &self.archive.maybe_ar_prog, - "cruS", Some(self.work_dir.path()), &args[]); + "cruS", Some(self.work_dir.path()), &args[..]); args.clear(); args.push(&abs_dst); @@ -269,7 +269,7 @@ impl<'a> ArchiveBuilder<'a> { // necessary. let flags = if self.should_update_symbols { "crus" } else { "cruS" }; run_ar(self.archive.handler, &self.archive.maybe_ar_prog, - flags, Some(self.work_dir.path()), &args[]); + flags, Some(self.work_dir.path()), &args[..]); self.archive } @@ -312,7 +312,7 @@ impl<'a> ArchiveBuilder<'a> { } else { filename }; - let new_filename = self.work_dir.path().join(&filename[]); + let new_filename = self.work_dir.path().join(&filename[..]); try!(fs::rename(file, &new_filename)); self.members.push(Path::new(filename)); } diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 36bbd4b987297..e7419d4bec307 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -40,12 +40,9 @@ pub fn get_rpath_flags(config: RPathConfig) -> Vec where debug!("preparing the RPATH!"); let libs = config.used_crates.clone(); - let libs = libs.into_iter().filter_map(|(_, l)| { - l.map(|p| p.clone()) - }).collect::>(); - - let rpaths = get_rpaths(config, &libs[]); - flags.push_all(&rpaths_to_flags(&rpaths[])[]); + let libs = libs.into_iter().filter_map(|(_, l)| l).collect::>(); + let rpaths = get_rpaths(config, &libs[..]); + flags.push_all(&rpaths_to_flags(&rpaths[..])); flags } @@ -82,14 +79,14 @@ fn get_rpaths(mut config: RPathConfig, libs: &[Path]) -> Vec } } - log_rpaths("relative", &rel_rpaths[]); - log_rpaths("fallback", &fallback_rpaths[]); + log_rpaths("relative", &rel_rpaths[..]); + log_rpaths("fallback", &fallback_rpaths[..]); let mut rpaths = rel_rpaths; - rpaths.push_all(&fallback_rpaths[]); + rpaths.push_all(&fallback_rpaths[..]); // Remove duplicates - let rpaths = minimize_rpaths(&rpaths[]); + let rpaths = minimize_rpaths(&rpaths[..]); return rpaths; } @@ -139,7 +136,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec { let mut set = HashSet::new(); let mut minimized = Vec::new(); for rpath in rpaths { - if set.insert(&rpath[]) { + if set.insert(&rpath[..]) { minimized.push(rpath.clone()); } } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 692e6b474fd27..01a5f0d6e20f8 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -254,18 +254,18 @@ impl Target { macro_rules! key { ($key_name:ident) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[]).map(|o| o.as_string() + obj.find(&name[..]).map(|o| o.as_string() .map(|s| base.options.$key_name = s.to_string())); } ); ($key_name:ident, bool) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[]) + obj.find(&name[..]) .map(|o| o.as_boolean() .map(|s| base.options.$key_name = s)); } ); ($key_name:ident, list) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[]).map(|o| o.as_array() + obj.find(&name[..]).map(|o| o.as_array() .map(|v| base.options.$key_name = v.iter() .map(|a| a.as_string().unwrap().to_string()).collect() ) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index a18e8b16e8bac..abe01d193b492 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -656,7 +656,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { &self.bccx.loan_path_to_string(move_path)[]) }; - self.bccx.span_err(span, &err_message[]); + self.bccx.span_err(span, &err_message[..]); self.bccx.span_note( loan_span, &format!("borrow of `{}` occurs here", diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index bee1ada28e314..c873831cb0f65 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -38,7 +38,7 @@ enum Fragment { // This represents the collection of all but one of the elements // from an array at the path described by the move path index. // Note that attached MovePathIndex should have mem_categorization - // of InteriorElement (i.e. array dereference `&foo[]`). + // of InteriorElement (i.e. array dereference `&foo[..]`). AllButOneFrom(MovePathIndex), } @@ -198,11 +198,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { // First, filter out duplicates moved.sort(); moved.dedup(); - debug!("fragments 1 moved: {:?}", path_lps(&moved[])); + debug!("fragments 1 moved: {:?}", path_lps(&moved[..])); assigned.sort(); assigned.dedup(); - debug!("fragments 1 assigned: {:?}", path_lps(&assigned[])); + debug!("fragments 1 assigned: {:?}", path_lps(&assigned[..])); // Second, build parents from the moved and assigned. for m in &moved { @@ -222,14 +222,14 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { parents.sort(); parents.dedup(); - debug!("fragments 2 parents: {:?}", path_lps(&parents[])); + debug!("fragments 2 parents: {:?}", path_lps(&parents[..])); // Third, filter the moved and assigned fragments down to just the non-parents - moved.retain(|f| non_member(*f, &parents[])); - debug!("fragments 3 moved: {:?}", path_lps(&moved[])); + moved.retain(|f| non_member(*f, &parents[..])); + debug!("fragments 3 moved: {:?}", path_lps(&moved[..])); - assigned.retain(|f| non_member(*f, &parents[])); - debug!("fragments 3 assigned: {:?}", path_lps(&assigned[])); + assigned.retain(|f| non_member(*f, &parents[..])); + debug!("fragments 3 assigned: {:?}", path_lps(&assigned[..])); // Fourth, build the leftover from the moved, assigned, and parents. for m in &moved { @@ -247,16 +247,16 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { unmoved.sort(); unmoved.dedup(); - debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[])); + debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[..])); // Fifth, filter the leftover fragments down to its core. unmoved.retain(|f| match *f { AllButOneFrom(_) => true, - Just(mpi) => non_member(mpi, &parents[]) && - non_member(mpi, &moved[]) && - non_member(mpi, &assigned[]) + Just(mpi) => non_member(mpi, &parents[..]) && + non_member(mpi, &moved[..]) && + non_member(mpi, &assigned[..]) }); - debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[])); + debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[..])); // Swap contents back in. fragments.unmoved_fragments = unmoved; @@ -437,7 +437,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>, let msg = format!("type {} ({:?}) is not fragmentable", parent_ty.repr(tcx), sty_and_variant_info); let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id)); - tcx.sess.opt_span_bug(opt_span, &msg[]) + tcx.sess.opt_span_bug(opt_span, &msg[..]) } } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 93d97a054a4b3..518e4bc472ca4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -137,7 +137,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt, check_loans::check_loans(this, &loan_dfcx, flowed_moves, - &all_loans[], + &all_loans[..], id, decl, body); diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index 56bf3ae7fd5a3..39c9d9ba6ad24 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { set.push_str(", "); } let loan_str = self.borrowck_ctxt.loan_path_to_string(&*lp); - set.push_str(&loan_str[]); + set.push_str(&loan_str[..]); saw_some = true; true }); diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index c2677cc3fd0b3..b7cfda2809257 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -20,7 +20,6 @@ #![allow(non_camel_case_types)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 728ff64759998..a260997f60594 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -85,7 +85,7 @@ pub fn compile_input(sess: Session, let expanded_crate = match phase_2_configure_and_expand(&sess, krate, - &id[], + &id[..], addl_plugins) { None => return, Some(k) => k @@ -99,20 +99,20 @@ pub fn compile_input(sess: Session, &sess, outdir, &expanded_crate, - &id[])); + &id[..])); let mut forest = ast_map::Forest::new(expanded_crate); let arenas = ty::CtxtArenas::new(); let ast_map = assign_node_ids_and_map(&sess, &mut forest); - write_out_deps(&sess, input, &outputs, &id[]); + write_out_deps(&sess, input, &outputs, &id[..]); controller_entry_point!(after_write_deps, CompileState::state_after_write_deps(input, &sess, outdir, &ast_map, - &id[])); + &id[..])); let analysis = phase_3_run_analysis_passes(sess, ast_map, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ac91a0098ea75..2550432c8101a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -272,7 +272,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { -> Compilation { match matches.opt_str("explain") { Some(ref code) => { - match descriptions.find_description(&code[]) { + match descriptions.find_description(&code[..]) { Some(ref description) => { println!("{}", description); } @@ -582,7 +582,7 @@ Available lint options: for lint in lints { let name = lint.name_lower().replace("_", "-"); println!(" {} {:7.7} {}", - padded(&name[]), lint.default_level.as_str(), lint.desc); + padded(&name[..]), lint.default_level.as_str(), lint.desc); } println!("\n"); }; @@ -612,7 +612,7 @@ Available lint options: let desc = to.into_iter().map(|x| x.as_str().replace("_", "-")) .collect::>().connect(", "); println!(" {} {}", - padded(&name[]), desc); + padded(&name[..]), desc); } println!("\n"); }; @@ -678,7 +678,7 @@ pub fn handle_options(mut args: Vec) -> Option { } let matches = - match getopts::getopts(&args[], &config::optgroups()[]) { + match getopts::getopts(&args[..], &config::optgroups()[]) { Ok(m) => m, Err(f_stable_attempt) => { // redo option parsing, including unstable options this time, @@ -803,7 +803,7 @@ pub fn monitor(f: F) { "run with `RUST_BACKTRACE=1` for a backtrace".to_string(), ]; for note in &xs { - emitter.emit(None, ¬e[], None, diagnostic::Note) + emitter.emit(None, ¬e[..], None, diagnostic::Note) } match r.read_to_string() { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 5dfef6c775e1e..0fbfa5fd89dd7 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -383,7 +383,7 @@ impl UserIdentifiedItem { ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()), ItemViaPath(ref parts) => - NodesMatchingSuffix(map.nodes_matching_suffix(&parts[])), + NodesMatchingSuffix(map.nodes_matching_suffix(&parts[..])), } } @@ -395,7 +395,7 @@ impl UserIdentifiedItem { user_option, self.reconstructed_input(), is_wrong_because); - sess.fatal(&message[]) + sess.fatal(&message[..]) }; let mut saw_node = ast::DUMMY_NODE_ID; @@ -522,7 +522,7 @@ pub fn pretty_print_input(sess: Session, let is_expanded = needs_expansion(&ppm); let compute_ast_map = needs_ast_map(&ppm, &opt_uii); let krate = if compute_ast_map { - match driver::phase_2_configure_and_expand(&sess, krate, &id[], None) { + match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) { None => return, Some(k) => k } @@ -541,7 +541,7 @@ pub fn pretty_print_input(sess: Session, }; let src_name = driver::source_name(input); - let src = sess.codemap().get_filemap(&src_name[]) + let src = sess.codemap().get_filemap(&src_name[..]) .src.as_bytes().to_vec(); let mut rdr = MemReader::new(src); @@ -632,8 +632,8 @@ pub fn pretty_print_input(sess: Session, // point to what was found, if there's an // accessible span. match ast_map.opt_span(nodeid) { - Some(sp) => sess.span_fatal(sp, &message[]), - None => sess.fatal(&message[]) + Some(sp) => sess.span_fatal(sp, &message[..]), + None => sess.fatal(&message[..]) } } } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 7105a6cc48882..fbbd72e2c76be 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -254,7 +254,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { output_ty: Ty<'tcx>) -> Ty<'tcx> { - let input_args = input_tys.iter().map(|ty| *ty).collect(); + let input_args = input_tys.iter().cloned().collect(); ty::mk_bare_fn(self.infcx.tcx, None, self.infcx.tcx.mk_bare_fn(ty::BareFnTy { @@ -278,7 +278,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> { let name = format!("T{}", index); - ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[])) + ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[..])) } pub fn re_early_bound(&self, diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs index d3555e4c04363..14a99026aac8a 100644 --- a/src/librustc_llvm/archive_ro.rs +++ b/src/librustc_llvm/archive_ro.rs @@ -30,7 +30,7 @@ impl ArchiveRO { /// raised. pub fn open(dst: &Path) -> Option { unsafe { - let s = CString::from_slice(dst.as_vec()); + let s = CString::new(dst.as_vec()).unwrap(); let ar = ::LLVMRustOpenArchive(s.as_ptr()); if ar.is_null() { None @@ -44,7 +44,7 @@ impl ArchiveRO { pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> { unsafe { let mut size = 0 as libc::size_t; - let file = CString::from_slice(file.as_bytes()); + let file = CString::new(file).unwrap(); let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(), &mut size); if ptr.is_null() { diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index aa90d7c851ba6..09a187befb213 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -25,7 +25,6 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(libc)] #![feature(link_args)] @@ -2149,7 +2148,7 @@ impl Drop for TargetData { } pub fn mk_target_data(string_rep: &str) -> TargetData { - let string_rep = CString::from_slice(string_rep.as_bytes()); + let string_rep = CString::new(string_rep).unwrap(); TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 96e146fc894f9..5662a74a53d34 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -585,10 +585,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { match result { None => true, Some((span, msg, note)) => { - self.tcx.sess.span_err(span, &msg[]); + self.tcx.sess.span_err(span, &msg[..]); match note { Some((span, msg)) => { - self.tcx.sess.span_note(span, &msg[]) + self.tcx.sess.span_note(span, &msg[..]) } None => {}, } @@ -690,7 +690,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { UnnamedField(idx) => format!("field #{} of {} is private", idx + 1, struct_desc), }; - self.tcx.sess.span_err(span, &msg[]); + self.tcx.sess.span_err(span, &msg[..]); } // Given the ID of a method, checks to ensure it's in scope. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 874c8f2a9402d..333d32d76b6d5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -20,7 +20,6 @@ #![feature(alloc)] #![feature(collections)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] @@ -1072,7 +1071,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &import_directive.module_path[], import_directive.subclass), help); - self.resolve_error(span, &msg[]); + self.resolve_error(span, &msg[..]); } Indeterminate => break, // Bail out. We'll come around next time. Success(()) => () // Good. Continue. @@ -1102,7 +1101,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .iter() .map(|seg| seg.identifier.name) .collect(); - self.names_to_string(&names[]) + self.names_to_string(&names[..]) } fn import_directive_subclass_to_string(&mut self, @@ -1166,7 +1165,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let module_path = &import_directive.module_path; debug!("(resolving import for module) resolving import `{}::...` in `{}`", - self.names_to_string(&module_path[]), + self.names_to_string(&module_path[..]), self.module_to_string(&*module_)); // First, resolve the module path for the directive, if necessary. @@ -1175,7 +1174,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some((self.graph_root.get_module(), LastMod(AllPublic))) } else { match self.resolve_module_path(module_.clone(), - &module_path[], + &module_path[..], DontUseLexicalScope, import_directive.span, ImportSearch) { @@ -1768,7 +1767,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ValueNS => "value", }, &token::get_name(name)); - span_err!(self.session, import_span, E0252, "{}", &msg[]); + span_err!(self.session, import_span, E0252, "{}", &msg[..]); } Some(_) | None => {} } @@ -1783,7 +1782,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) { let msg = format!("`{}` is not directly importable", token::get_name(name)); - span_err!(self.session, import_span, E0253, "{}", &msg[]); + span_err!(self.session, import_span, E0253, "{}", &msg[..]); } } @@ -1804,7 +1803,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { crate in this module \ (maybe you meant `use {0}::*`?)", &token::get_name(name)); - span_err!(self.session, import_span, E0254, "{}", &msg[]); + span_err!(self.session, import_span, E0254, "{}", &msg[..]); } Some(_) | None => {} } @@ -1826,7 +1825,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("import `{}` conflicts with value \ in this module", &token::get_name(name)); - span_err!(self.session, import_span, E0255, "{}", &msg[]); + span_err!(self.session, import_span, E0255, "{}", &msg[..]); if let Some(span) = value.value_span { self.session.span_note(span, "conflicting value here"); @@ -1844,7 +1843,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("import `{}` conflicts with type in \ this module", &token::get_name(name)); - span_err!(self.session, import_span, E0256, "{}", &msg[]); + span_err!(self.session, import_span, E0256, "{}", &msg[..]); if let Some(span) = ty.type_span { self.session.span_note(span, "note conflicting type here") @@ -1857,7 +1856,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("inherent implementations \ are only allowed on types \ defined in the current module"); - span_err!(self.session, span, E0257, "{}", &msg[]); + span_err!(self.session, span, E0257, "{}", &msg[..]); self.session.span_note(import_span, "import from other module here") } @@ -1866,7 +1865,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("import `{}` conflicts with existing \ submodule", &token::get_name(name)); - span_err!(self.session, import_span, E0258, "{}", &msg[]); + span_err!(self.session, import_span, E0258, "{}", &msg[..]); if let Some(span) = ty.type_span { self.session.span_note(span, "note conflicting module here") @@ -1920,18 +1919,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { -> ResolveResult<(Rc, LastPrivate)> { fn search_parent_externals(needle: Name, module: &Rc) -> Option> { - module.external_module_children.borrow() - .get(&needle).cloned() - .map(|_| module.clone()) - .or_else(|| { - match module.parent_link.clone() { - ModuleParentLink(parent, _) => { - search_parent_externals(needle, - &parent.upgrade().unwrap()) + match module.external_module_children.borrow().get(&needle) { + Some(_) => Some(module.clone()), + None => match module.parent_link { + ModuleParentLink(ref parent, _) => { + search_parent_externals(needle, &parent.upgrade().unwrap()) } _ => None } - }) + } } let mut search_module = module_; @@ -1953,7 +1949,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let segment_name = token::get_name(name); let module_name = self.module_to_string(&*search_module); let mut span = span; - let msg = if "???" == &module_name[] { + let msg = if "???" == &module_name[..] { span.hi = span.lo + Pos::from_usize(segment_name.len()); match search_parent_externals(name, @@ -2066,7 +2062,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match module_prefix_result { Failed(None) => { let mpath = self.names_to_string(module_path); - let mpath = &mpath[]; + let mpath = &mpath[..]; match mpath.rfind(':') { Some(idx) => { let msg = format!("Could not find `{}` in `{}`", @@ -2369,11 +2365,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut containing_module; let mut i; let first_module_path_string = token::get_name(module_path[0]); - if "self" == &first_module_path_string[] { + if "self" == &first_module_path_string[..] { containing_module = self.get_nearest_normal_module_parent_or_self(module_); i = 1; - } else if "super" == &first_module_path_string[] { + } else if "super" == &first_module_path_string[..] { containing_module = self.get_nearest_normal_module_parent_or_self(module_); i = 0; // We'll handle `super` below. @@ -2384,7 +2380,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Now loop through all the `super`s we find. while i < module_path.len() { let string = token::get_name(module_path[i]); - if "super" != &string[] { + if "super" != &string[..] { break } debug!("(resolving module prefix) resolving `super` at {}", @@ -2515,7 +2511,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else { let err = format!("unresolved import (maybe you meant `{}::*`?)", sn); - self.resolve_error((*imports)[index].span, &err[]); + self.resolve_error((*imports)[index].span, &err[..]); } } @@ -2853,7 +2849,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { generics, implemented_traits, &**self_type, - &impl_items[]); + &impl_items[..]); } ItemTrait(_, ref generics, ref bounds, ref trait_items) => { @@ -3196,7 +3192,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str); - self.resolve_error(trait_reference.path.span, &msg[]); + self.resolve_error(trait_reference.path.span, &msg[..]); } Some(def) => { match def { @@ -3624,7 +3620,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None => { let msg = format!("use of undeclared type name `{}`", self.path_names_to_string(path)); - self.resolve_error(ty.span, &msg[]); + self.resolve_error(ty.span, &msg[..]); } } } @@ -3825,7 +3821,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { def: {:?}", result); let msg = format!("`{}` does not name a structure", self.path_names_to_string(path)); - self.resolve_error(path.span, &msg[]); + self.resolve_error(path.span, &msg[..]); } } } @@ -4082,7 +4078,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let last_private; let module = self.current_module.clone(); match self.resolve_module_path(module, - &module_path[], + &module_path[..], UseLexicalScope, path.span, PathSearch) { @@ -4140,7 +4136,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let containing_module; let last_private; match self.resolve_module_path_from_root(root_module, - &module_path[], + &module_path[..], 0, path.span, PathSearch, @@ -4150,7 +4146,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some((span, msg)) => (span, msg), None => { let msg = format!("Use of undeclared module `::{}`", - self.names_to_string(&module_path[])); + self.names_to_string(&module_path[..])); (path.span, msg) } }; @@ -4309,7 +4305,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } else { match this.resolve_module_path(root, - &name_path[], + &name_path[..], UseLexicalScope, span, PathSearch) { @@ -4347,7 +4343,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::>(); // Look for a method in the current self type's impl module. - match get_module(self, path.span, &name_path[]) { + match get_module(self, path.span, &name_path[..]) { Some(module) => match module.children.borrow().get(&name) { Some(binding) => { let p_str = self.path_names_to_string(&path); @@ -4568,7 +4564,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { def: {:?}", result); let msg = format!("`{}` does not name a structure", self.path_names_to_string(path)); - self.resolve_error(path.span, &msg[]); + self.resolve_error(path.span, &msg[..]); } } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 9f26e9182ab1e..ef849bb3dca05 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -127,7 +127,7 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { let validate = |s: String, span: Option| { - creader::validate_crate_name(sess, &s[], span); + creader::validate_crate_name(sess, &s[..], span); s }; @@ -141,11 +141,11 @@ pub fn find_crate_name(sess: Option<&Session>, if let Some(sess) = sess { if let Some(ref s) = sess.opts.crate_name { if let Some((attr, ref name)) = attr_crate_name { - if *s != &name[] { + if *s != &name[..] { let msg = format!("--crate-name and #[crate_name] are \ required to match, but `{}` != `{}`", s, name); - sess.span_err(attr.span, &msg[]); + sess.span_err(attr.span, &msg[..]); } } return validate(s.clone(), None); @@ -195,7 +195,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>, symbol_hasher.input_str("-"); symbol_hasher.input_str(link_meta.crate_hash.as_str()); for meta in &*tcx.sess.crate_metadata.borrow() { - symbol_hasher.input_str(&meta[]); + symbol_hasher.input_str(&meta[..]); } symbol_hasher.input_str("-"); symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)[]); @@ -262,7 +262,7 @@ pub fn sanitize(s: &str) -> String { if result.len() > 0 && result.as_bytes()[0] != '_' as u8 && ! (result.as_bytes()[0] as char).is_xid_start() { - return format!("_{}", &result[]); + return format!("_{}", &result[..]); } return result; @@ -331,17 +331,17 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl hash.push(EXTRA_CHARS.as_bytes()[extra2] as char); hash.push(EXTRA_CHARS.as_bytes()[extra3] as char); - exported_name(path, &hash[]) + exported_name(path, &hash[..]) } pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, name: &str) -> String { let s = ppaux::ty_to_string(ccx.tcx(), t); - let path = [PathName(token::intern(&s[])), + let path = [PathName(token::intern(&s[..])), gensym_name(name)]; let hash = get_symbol_hash(ccx, t); - mangle(path.iter().cloned(), Some(&hash[])) + mangle(path.iter().cloned(), Some(&hash[..])) } pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String { @@ -541,7 +541,7 @@ fn link_rlib<'a>(sess: &'a Session, for &(ref l, kind) in &*sess.cstore.get_used_libraries().borrow() { match kind { cstore::NativeStatic => { - ab.add_native_library(&l[]).unwrap(); + ab.add_native_library(&l[..]).unwrap(); } cstore::NativeFramework | cstore::NativeUnknown => {} } @@ -619,7 +619,7 @@ fn link_rlib<'a>(sess: &'a Session, e)[]) }; - let bc_data_deflated = match flate::deflate_bytes(&bc_data[]) { + let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) { Some(compressed) => compressed, None => sess.fatal(&format!("failed to compress bytecode from {}", bc_filename.display())[]) @@ -678,7 +678,7 @@ fn write_rlib_bytecode_object_v1(writer: &mut T, try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) }; try! { writer.write_le_u32(1) }; try! { writer.write_le_u64(bc_data_deflated_size) }; - try! { writer.write_all(&bc_data_deflated[]) }; + try! { writer.write_all(&bc_data_deflated[..]) }; let number_of_bytes_written_so_far = RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id @@ -733,7 +733,7 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) { continue } }; - ab.add_rlib(&p, &name[], sess.lto()).unwrap(); + ab.add_rlib(&p, &name[..], sess.lto()).unwrap(); let native_libs = csearch::get_native_libraries(&sess.cstore, cnum); all_native_libs.extend(native_libs.into_iter()); @@ -769,7 +769,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, // The invocations of cc share some flags across platforms let pname = get_cc_prog(sess); - let mut cmd = Command::new(&pname[]); + let mut cmd = Command::new(&pname[..]); cmd.args(&sess.target.target.options.pre_link_args[]); link_args(&mut cmd, sess, dylib, tmpdir.path(), @@ -798,7 +798,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, sess.note(&format!("{:?}", &cmd)[]); let mut output = prog.error.clone(); output.push_all(&prog.output[]); - sess.note(str::from_utf8(&output[]).unwrap()); + sess.note(str::from_utf8(&output[..]).unwrap()); sess.abort_if_errors(); } debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap()); @@ -868,7 +868,7 @@ fn link_args(cmd: &mut Command, let mut v = b"-Wl,-force_load,".to_vec(); v.push_all(morestack.as_vec()); - cmd.arg(&v[]); + cmd.arg(&v[..]); } else { cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); } @@ -993,7 +993,7 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec(); v.push_all(out_filename.filename().unwrap()); - cmd.arg(&v[]); + cmd.arg(&v[..]); } } else { cmd.arg("-shared"); @@ -1029,7 +1029,7 @@ fn link_args(cmd: &mut Command, // with any #[link_args] attributes found inside the crate let empty = Vec::new(); cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty)[]); - cmd.args(&used_link_args[]); + cmd.args(&used_link_args[..]); } // # Native library linking @@ -1086,14 +1086,14 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { } else { // -force_load is the OSX equivalent of --whole-archive, but it // involves passing the full path to the library to link. - let lib = archive::find_library(&l[], + let lib = archive::find_library(&l[..], &sess.target.target.options.staticlib_prefix, &sess.target.target.options.staticlib_suffix, - &search_path[], + &search_path[..], &sess.diagnostic().handler); let mut v = b"-Wl,-force_load,".to_vec(); v.push_all(lib.as_vec()); - cmd.arg(&v[]); + cmd.arg(&v[..]); } } if takes_hints { @@ -1106,7 +1106,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { cmd.arg(format!("-l{}", l)); } cstore::NativeFramework => { - cmd.arg("-framework").arg(&l[]); + cmd.arg("-framework").arg(&l[..]); } cstore::NativeStatic => unreachable!(), } @@ -1248,7 +1248,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, let mut v = "-l".as_bytes().to_vec(); v.push_all(unlib(&sess.target, cratepath.filestem().unwrap())); - cmd.arg(&v[]); + cmd.arg(&v[..]); } } @@ -1290,7 +1290,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) { } cstore::NativeFramework => { cmd.arg("-framework"); - cmd.arg(&lib[]); + cmd.arg(&lib[..]); } cstore::NativeStatic => { sess.bug("statics shouldn't be propagated"); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index 0331b6171f36c..0a0f2a9c18627 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -132,7 +132,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, bc_decoded.len() as libc::size_t) { write::llvm_err(sess.diagnostic().handler(), format!("failed to load bc of `{}`", - &name[])); + &name[..])); } }); } @@ -140,7 +140,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, // Internalize everything but the reachable symbols of the current module let cstrs: Vec = reachable.iter().map(|s| { - CString::from_slice(s.as_bytes()) + CString::new(s.clone()).unwrap() }).collect(); let arr: Vec<*const libc::c_char> = cstrs.iter().map(|c| c.as_ptr()).collect(); let ptr = arr.as_ptr(); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 9934d9993d61d..86b720d3fc171 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -22,7 +22,7 @@ use syntax::codemap; use syntax::diagnostic; use syntax::diagnostic::{Emitter, Handler, Level, mk_handler}; -use std::ffi::{self, CString}; +use std::ffi::{CStr, CString}; use std::old_io::Command; use std::old_io::fs; use std::iter::Unfold; @@ -47,14 +47,14 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); if cstr == ptr::null() { - handler.fatal(&msg[]); + handler.fatal(&msg[..]); } else { - let err = ffi::c_str_to_bytes(&cstr); + let err = CStr::from_ptr(cstr).to_bytes(); let err = String::from_utf8_lossy(err).to_string(); libc::free(cstr as *mut _); handler.fatal(&format!("{}: {}", - &msg[], - &err[])[]); + &msg[..], + &err[..])[]); } } } @@ -67,7 +67,7 @@ pub fn write_output_file( output: &Path, file_type: llvm::FileType) { unsafe { - let output_c = CString::from_slice(output.as_vec()); + let output_c = CString::new(output.as_vec()).unwrap(); let result = llvm::LLVMRustWriteOutputFile( target, pm, m, output_c.as_ptr(), file_type); if !result { @@ -105,7 +105,7 @@ impl SharedEmitter { Some(ref code) => { handler.emit_with_code(None, &diag.msg[], - &code[], + &code[..], diag.lvl); }, None => { @@ -165,7 +165,7 @@ fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel { fn create_target_machine(sess: &Session) -> TargetMachineRef { let reloc_model_arg = match sess.opts.cg.relocation_model { - Some(ref s) => &s[], + Some(ref s) => &s[..], None => &sess.target.target.options.relocation_model[] }; let reloc_model = match reloc_model_arg { @@ -198,7 +198,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef { let fdata_sections = ffunction_sections; let code_model_arg = match sess.opts.cg.code_model { - Some(ref s) => &s[], + Some(ref s) => &s[..], None => &sess.target.target.options.code_model[] }; @@ -221,13 +221,13 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef { let triple = &sess.target.target.llvm_target[]; let tm = unsafe { - let triple = CString::from_slice(triple.as_bytes()); + let triple = CString::new(triple.as_bytes()).unwrap(); let cpu = match sess.opts.cg.target_cpu { Some(ref s) => &**s, None => &*sess.target.target.options.cpu }; - let cpu = CString::from_slice(cpu.as_bytes()); - let features = CString::from_slice(target_feature(sess).as_bytes()); + let cpu = CString::new(cpu.as_bytes()).unwrap(); + let features = CString::new(target_feature(sess).as_bytes()).unwrap(); llvm::LLVMRustCreateTargetMachine( triple.as_ptr(), cpu.as_ptr(), features.as_ptr(), code_model, @@ -365,7 +365,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) .expect("non-UTF8 SMDiagnostic"); - report_inline_asm(cgcx, &msg[], cookie); + report_inline_asm(cgcx, &msg[..], cookie); } unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { @@ -380,7 +380,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo } llvm::diagnostic::Optimization(opt) => { - let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name)) + let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes()) .ok() .expect("got a non-UTF8 pass name from LLVM"); let enabled = match cgcx.remark { @@ -424,7 +424,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_no_opt_bc { let ext = format!("{}.no-opt.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -440,7 +440,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, // If we're verifying or linting, add them to the function pass // manager. let addpass = |pass: &str| { - let pass = CString::from_slice(pass.as_bytes()); + let pass = CString::new(pass).unwrap(); llvm::LLVMRustAddPass(fpm, pass.as_ptr()) }; if !config.no_verify { assert!(addpass("verify")); } @@ -453,7 +453,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, } for pass in &config.passes { - let pass = CString::from_slice(pass.as_bytes()); + let pass = CString::new(pass.clone()).unwrap(); if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) { cgcx.handler.warn(&format!("unknown pass {:?}, ignoring", pass)); } @@ -477,7 +477,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_lto_bc { let name = format!("{}.lto.bc", name_extra); let out = output_names.with_extension(&name); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } }, @@ -511,7 +511,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_bc { let ext = format!("{}.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -519,7 +519,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_ir { let ext = format!("{}.ll", name_extra); let out = output_names.with_extension(&ext); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); with_codegen(tm, llmod, config.no_builtins, |cpm| { llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr()); }) @@ -711,7 +711,7 @@ pub fn run_passes(sess: &Session, }; let pname = get_cc_prog(sess); - let mut cmd = Command::new(&pname[]); + let mut cmd = Command::new(&pname[..]); cmd.args(&sess.target.target.options.pre_link_args[]); cmd.arg("-nostdlib"); @@ -829,12 +829,12 @@ pub fn run_passes(sess: &Session, for i in 0..trans.modules.len() { if modules_config.emit_obj { let ext = format!("{}.o", i); - remove(sess, &crate_output.with_extension(&ext[])); + remove(sess, &crate_output.with_extension(&ext[..])); } if modules_config.emit_bc && !keep_numbered_bitcode { let ext = format!("{}.bc", i); - remove(sess, &crate_output.with_extension(&ext[])); + remove(sess, &crate_output.with_extension(&ext[..])); } } @@ -960,7 +960,7 @@ fn run_work_multithreaded(sess: &Session, pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { let pname = get_cc_prog(sess); - let mut cmd = Command::new(&pname[]); + let mut cmd = Command::new(&pname[..]); cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject)) .arg(outputs.temp_path(config::OutputTypeAssembly)); @@ -975,7 +975,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { sess.note(&format!("{:?}", &cmd)[]); let mut note = prog.error.clone(); note.push_all(&prog.output[]); - sess.note(str::from_utf8(¬e[]).unwrap()); + sess.note(str::from_utf8(¬e[..]).unwrap()); sess.abort_if_errors(); } }, @@ -1004,7 +1004,7 @@ unsafe fn configure_llvm(sess: &Session) { let mut llvm_args = Vec::new(); { let mut add = |arg: &str| { - let s = CString::from_slice(arg.as_bytes()); + let s = CString::new(arg).unwrap(); llvm_args.push(s.as_ptr()); llvm_c_strs.push(s); }; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 4606200d058c6..3deca436a1f90 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -28,7 +28,6 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(env)] diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index cdcd917ee5eb4..8d2a2d51ee423 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -155,7 +155,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; self.fmt.sub_mod_ref_str(path.span, *span, - &qualname[], + &qualname[..], self.cur_scope); } } @@ -178,7 +178,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; self.fmt.sub_mod_ref_str(path.span, *span, - &qualname[], + &qualname[..], self.cur_scope); } } @@ -197,7 +197,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { let (ref span, ref qualname) = sub_paths[len-2]; self.fmt.sub_type_ref_str(path.span, *span, - &qualname[]); + &qualname[..]); // write the other sub-paths if len <= 2 { @@ -207,7 +207,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { for &(ref span, ref qualname) in sub_paths { self.fmt.sub_mod_ref_str(path.span, *span, - &qualname[], + &qualname[..], self.cur_scope); } } @@ -280,7 +280,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { id, qualname, &path_to_string(p)[], - &typ[]); + &typ[..]); } self.collected_paths.clear(); } @@ -356,7 +356,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident())); - let qualname = &qualname[]; + let qualname = &qualname[..]; // record the decl for this def (if it has one) let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx, @@ -436,9 +436,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { Some(sub_span) => self.fmt.field_str(field.span, Some(sub_span), field.node.id, - &name[], - &qualname[], - &typ[], + &name[..], + &qualname[..], + &typ[..], scope_id), None => self.sess.span_bug(field.span, &format!("Could not find sub-span for field {}", @@ -470,7 +470,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.typedef_str(full_span, Some(*param_ss), param.id, - &name[], + &name[..], ""); } self.visit_generics(generics); @@ -487,10 +487,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.fn_str(item.span, sub_span, item.id, - &qualname[], + &qualname[..], self.cur_scope); - self.process_formals(&decl.inputs, &qualname[]); + self.process_formals(&decl.inputs, &qualname[..]); // walk arg and return types for arg in &decl.inputs { @@ -504,7 +504,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { // walk the body self.nest(item.id, |v| v.visit_block(&*body)); - self.process_generic_params(ty_params, item.span, &qualname[], item.id); + self.process_generic_params(ty_params, item.span, &qualname[..], item.id); } fn process_static(&mut self, @@ -526,8 +526,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { sub_span, item.id, &get_ident(item.ident), - &qualname[], - &value[], + &qualname[..], + &value[..], &ty_to_string(&*typ)[], self.cur_scope); @@ -549,7 +549,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { sub_span, item.id, &get_ident(item.ident), - &qualname[], + &qualname[..], "", &ty_to_string(&*typ)[], self.cur_scope); @@ -575,17 +575,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { sub_span, item.id, ctor_id, - &qualname[], + &qualname[..], self.cur_scope, - &val[]); + &val[..]); // fields for field in &def.fields { - self.process_struct_field_def(field, &qualname[], item.id); + self.process_struct_field_def(field, &qualname[..], item.id); self.visit_ty(&*field.node.ty); } - self.process_generic_params(ty_params, item.span, &qualname[], item.id); + self.process_generic_params(ty_params, item.span, &qualname[..], item.id); } fn process_enum(&mut self, @@ -598,9 +598,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { Some(sub_span) => self.fmt.enum_str(item.span, Some(sub_span), item.id, - &enum_name[], + &enum_name[..], self.cur_scope, - &val[]), + &val[..]), None => self.sess.span_bug(item.span, &format!("Could not find subspan for enum {}", enum_name)[]), @@ -619,9 +619,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.span.span_for_first_ident(variant.span), variant.node.id, name, - &qualname[], - &enum_name[], - &val[], + &qualname[..], + &enum_name[..], + &val[..], item.id); for arg in args { self.visit_ty(&*arg.ty); @@ -637,9 +637,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.span.span_for_first_ident(variant.span), variant.node.id, ctor_id, - &qualname[], - &enum_name[], - &val[], + &qualname[..], + &enum_name[..], + &val[..], item.id); for field in &struct_def.fields { @@ -650,7 +650,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } } - self.process_generic_params(ty_params, item.span, &enum_name[], item.id); + self.process_generic_params(ty_params, item.span, &enum_name[..], item.id); } fn process_impl(&mut self, @@ -724,9 +724,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.trait_str(item.span, sub_span, item.id, - &qualname[], + &qualname[..], self.cur_scope, - &val[]); + &val[..]); // super-traits for super_bound in &**trait_refs { @@ -758,7 +758,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } // walk generics and methods - self.process_generic_params(generics, item.span, &qualname[], item.id); + self.process_generic_params(generics, item.span, &qualname[..], item.id); for method in methods { self.visit_trait_item(method) } @@ -776,9 +776,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.mod_str(item.span, sub_span, item.id, - &qualname[], + &qualname[..], self.cur_scope, - &filename[]); + &filename[..]); self.nest(item.id, |v| visit::walk_mod(v, m)); } @@ -990,7 +990,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.cur_scope); // walk receiver and args - visit::walk_exprs(self, &args[]); + visit::walk_exprs(self, &args[..]); } fn process_pat(&mut self, p:&ast::Pat) { @@ -1164,7 +1164,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { item.id, cnum, name, - &location[], + &location[..], self.cur_scope); } ast::ItemFn(ref decl, _, _, ref ty_params, ref body) => @@ -1196,8 +1196,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { self.fmt.typedef_str(item.span, sub_span, item.id, - &qualname[], - &value[]); + &qualname[..], + &value[..]); self.visit_ty(&**ty); self.process_generic_params(ty_params, item.span, &qualname, item.id); @@ -1260,7 +1260,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { }; qualname.push_str(&get_ident(method_type.ident)); - let qualname = &qualname[]; + let qualname = &qualname[..]; let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn); self.fmt.method_decl_str(method_type.span, @@ -1401,7 +1401,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { let mut id = String::from_str("$"); id.push_str(&ex.id.to_string()[]); - self.process_formals(&decl.inputs, &id[]); + self.process_formals(&decl.inputs, &id[..]); // walk arg and return types for arg in &decl.inputs { @@ -1464,7 +1464,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { Some(p.span), id, &path_to_string(p)[], - &value[], + &value[..], "") } def::DefVariant(..) | def::DefTy(..) | def::DefStruct(..) => { @@ -1520,8 +1520,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { sub_span, id, &path_to_string(p)[], - &value[], - &typ[]); + &value[..], + &typ[..]); } self.collected_paths.clear(); @@ -1603,7 +1603,7 @@ pub fn process_crate(sess: &Session, cur_scope: 0 }; - visitor.dump_crate_info(&cratename[], krate); + visitor.dump_crate_info(&cratename[..], krate); visit::walk_crate(&mut visitor, krate); } diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs index 3bd04ed29d4a1..08e36bb1d85bb 100644 --- a/src/librustc_trans/save/recorder.rs +++ b/src/librustc_trans/save/recorder.rs @@ -43,7 +43,7 @@ impl Recorder { assert!(self.dump_spans); let result = format!("span,kind,{},{},text,\"{}\"\n", kind, su.extent_str(span), escape(su.snippet(span))); - self.record(&result[]); + self.record(&result[..]); } } @@ -170,14 +170,14 @@ impl<'a> FmtStrs<'a> { if s.len() > 1020 { &s[..1020] } else { - &s[] + &s[..] } }); let pairs = fields.iter().zip(values); let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from_str(v)))); Some(strs.fold(String::new(), |mut s, ss| { - s.push_str(&ss[]); + s.push_str(&ss[..]); s })) } @@ -205,9 +205,9 @@ impl<'a> FmtStrs<'a> { }; let mut result = String::from_str(label); - result.push_str(&values_str[]); + result.push_str(&values_str[..]); result.push_str("\n"); - self.recorder.record(&result[]); + self.recorder.record(&result[..]); } pub fn record_with_span(&mut self, @@ -238,7 +238,7 @@ impl<'a> FmtStrs<'a> { None => return, }; let result = format!("{},{}{}\n", label, self.span.extent_str(sub_span), values_str); - self.recorder.record(&result[]); + self.recorder.record(&result[..]); } pub fn check_and_record(&mut self, diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index b0ed6f9e727a2..2826afb71a2c2 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -566,7 +566,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>( param_env: param_env, }; enter_match(bcx, dm, m, col, val, |pats| - check_match::specialize(&mcx, &pats[], &ctor, col, variant_size) + check_match::specialize(&mcx, &pats[..], &ctor, col, variant_size) ) } @@ -987,7 +987,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if has_nested_bindings(m, col) { let expanded = expand_nested_bindings(bcx, m, col, val); compile_submatch_continue(bcx, - &expanded[], + &expanded[..], vals, chk, col, @@ -1233,10 +1233,10 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val); let mut opt_vals = unpacked; - opt_vals.push_all(&vals_left[]); + opt_vals.push_all(&vals_left[..]); compile_submatch(opt_cx, - &opt_ms[], - &opt_vals[], + &opt_ms[..], + &opt_vals[..], branch_chk.as_ref().unwrap_or(chk), has_genuine_default); } @@ -1255,8 +1255,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } _ => { compile_submatch(else_cx, - &defaults[], - &vals_left[], + &defaults[..], + &vals_left[..], chk, has_genuine_default); } @@ -1468,7 +1468,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>, && arm.pats.last().unwrap().node == ast::PatWild(ast::PatWildSingle) }); - compile_submatch(bcx, &matches[], &[discr_datum.val], &chk, has_default); + compile_submatch(bcx, &matches[..], &[discr_datum.val], &chk, has_default); let mut arm_cxs = Vec::new(); for arm_data in &arm_datas { @@ -1482,7 +1482,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>, arm_cxs.push(bcx); } - bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[]); + bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[..]); return bcx; } diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index ddd720f1e84a8..eaf6eaa2f089d 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -155,7 +155,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Repr<'tcx> { match t.sty { ty::ty_tup(ref elems) => { - Univariant(mk_struct(cx, &elems[], false, t), false) + Univariant(mk_struct(cx, &elems[..], false, t), false) } ty::ty_struct(def_id, substs) => { let fields = ty::lookup_struct_fields(cx.tcx(), def_id); @@ -167,13 +167,13 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag(); if dtor { ftys.push(cx.tcx().types.bool); } - Univariant(mk_struct(cx, &ftys[], packed, t), dtor) + Univariant(mk_struct(cx, &ftys[..], packed, t), dtor) } ty::ty_closure(def_id, _, substs) => { let typer = NormalizingClosureTyper::new(cx.tcx()); let upvars = typer.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::>(); - Univariant(mk_struct(cx, &upvar_types[], false, t), false) + Univariant(mk_struct(cx, &upvar_types[..], false, t), false) } ty::ty_enum(def_id, substs) => { let cases = get_cases(cx.tcx(), def_id, substs); @@ -187,7 +187,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // (Typechecking will reject discriminant-sizing attrs.) assert_eq!(hint, attr::ReprAny); let ftys = if dtor { vec!(cx.tcx().types.bool) } else { vec!() }; - return Univariant(mk_struct(cx, &ftys[], false, t), + return Univariant(mk_struct(cx, &ftys[..], false, t), dtor); } @@ -219,7 +219,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, assert_eq!(hint, attr::ReprAny); let mut ftys = cases[0].tys.clone(); if dtor { ftys.push(cx.tcx().types.bool); } - return Univariant(mk_struct(cx, &ftys[], false, t), + return Univariant(mk_struct(cx, &ftys[..], false, t), dtor); } @@ -320,10 +320,10 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity)); ftys.push_all(&c.tys[]); if dtor { ftys.push(cx.tcx().types.bool); } - mk_struct(cx, &ftys[], false, t) + mk_struct(cx, &ftys[..], false, t) }).collect(); - ensure_enum_fits_in_address_space(cx, &fields[], t); + ensure_enum_fits_in_address_space(cx, &fields[..], t); General(ity, fields, dtor) } @@ -453,9 +453,9 @@ fn mk_struct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .map(|&ty| type_of::sizing_type_of(cx, ty)).collect() }; - ensure_struct_fits_in_address_space(cx, &lltys[], packed, scapegoat); + ensure_struct_fits_in_address_space(cx, &lltys[..], packed, scapegoat); - let llty_rec = Type::struct_(cx, &lltys[], packed); + let llty_rec = Type::struct_(cx, &lltys[..], packed); Struct { size: machine::llsize_of_alloc(cx, llty_rec), align: machine::llalign_of_min(cx, llty_rec), @@ -659,7 +659,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // of the size. // // FIXME #10604: this breaks when vector types are present. - let (size, align) = union_size_and_align(&sts[]); + let (size, align) = union_size_and_align(&sts[..]); let align_s = align as u64; assert_eq!(size % align_s, 0); let align_units = size / align_s - 1; @@ -682,10 +682,10 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Type::array(&discr_ty, align_s / discr_size - 1), fill_ty]; match name { - None => Type::struct_(cx, &fields[], false), + None => Type::struct_(cx, &fields[..], false), Some(name) => { let mut llty = Type::named_struct(cx, name); - llty.set_struct_body(&fields[], false); + llty.set_struct_body(&fields[..], false); llty } } @@ -763,7 +763,7 @@ pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, discrfield: &DiscrField, scrutinee: ValueRef) -> ValueRef { - let llptrptr = GEPi(bcx, scrutinee, &discrfield[]); + let llptrptr = GEPi(bcx, scrutinee, &discrfield[..]); let llptr = Load(bcx, llptrptr); let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)), DebugLoc::None) @@ -851,7 +851,7 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, } StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => { if discr != nndiscr { - let llptrptr = GEPi(bcx, val, &discrfield[]); + let llptrptr = GEPi(bcx, val, &discrfield[..]); let llptrty = val_ty(llptrptr).element_type(); Store(bcx, C_null(llptrty), llptrptr) } @@ -933,7 +933,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v let val = if needs_cast { let ccx = bcx.ccx(); let fields = st.fields.iter().map(|&ty| type_of::type_of(ccx, ty)).collect::>(); - let real_ty = Type::struct_(ccx, &fields[], st.packed); + let real_ty = Type::struct_(ccx, &fields[..], st.packed); PointerCast(bcx, val, real_ty.ptr_to()) } else { val @@ -972,7 +972,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let fields = case.fields.iter().map(|&ty| type_of::type_of(bcx.ccx(), ty)).collect::>(); - let real_ty = Type::struct_(ccx, &fields[], case.packed); + let real_ty = Type::struct_(ccx, &fields[..], case.packed); let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to()); variant_cx = f(variant_cx, case, variant_value); @@ -1045,18 +1045,18 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr } General(ity, ref cases, _) => { let case = &cases[discr as uint]; - let (max_sz, _) = union_size_and_align(&cases[]); + let (max_sz, _) = union_size_and_align(&cases[..]); let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true); let mut f = vec![lldiscr]; f.push_all(vals); - let mut contents = build_const_struct(ccx, case, &f[]); + let mut contents = build_const_struct(ccx, case, &f[..]); contents.push_all(&[padding(ccx, max_sz - case.size)]); - C_struct(ccx, &contents[], false) + C_struct(ccx, &contents[..], false) } Univariant(ref st, _dro) => { assert!(discr == 0); let contents = build_const_struct(ccx, st, vals); - C_struct(ccx, &contents[], st.packed) + C_struct(ccx, &contents[..], st.packed) } RawNullablePointer { nndiscr, nnty, .. } => { if discr == nndiscr { @@ -1080,7 +1080,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr }).collect::>(); C_struct(ccx, &build_const_struct(ccx, nonnull, - &vals[])[], + &vals[..])[], false) } } diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs index e419be65fc4cc..a3bd0cf6b1a62 100644 --- a/src/librustc_trans/trans/asm.rs +++ b/src/librustc_trans/trans/asm.rs @@ -71,7 +71,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) callee::DontAutorefArg) }) }).collect::>(); - inputs.push_all(&ext_inputs[]); + inputs.push_all(&ext_inputs[..]); // no failure occurred preparing operands, no need to cleanup fcx.pop_custom_cleanup_scope(temp_scope); @@ -91,18 +91,18 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) if !clobbers.is_empty() { clobbers.push(','); } - clobbers.push_str(&more_clobbers[]); + clobbers.push_str(&more_clobbers[..]); } // Add the clobbers to our constraints list if clobbers.len() != 0 && constraints.len() != 0 { constraints.push(','); - constraints.push_str(&clobbers[]); + constraints.push_str(&clobbers[..]); } else { - constraints.push_str(&clobbers[]); + constraints.push_str(&clobbers[..]); } - debug!("Asm Constraints: {}", &constraints[]); + debug!("Asm Constraints: {}", &constraints[..]); let num_outputs = outputs.len(); @@ -112,7 +112,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) } else if num_outputs == 1 { output_types[0] } else { - Type::struct_(bcx.ccx(), &output_types[], false) + Type::struct_(bcx.ccx(), &output_types[..], false) }; let dialect = match ia.dialect { @@ -120,8 +120,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) ast::AsmIntel => llvm::AD_Intel }; - let asm = CString::from_slice(ia.asm.as_bytes()); - let constraints = CString::from_slice(constraints.as_bytes()); + let asm = CString::new(ia.asm.as_bytes()).unwrap(); + let constraints = CString::new(constraints).unwrap(); let r = InlineAsmCall(bcx, asm.as_ptr(), constraints.as_ptr(), diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7f7b5cd800660..3091c852f5587 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -86,7 +86,7 @@ use util::nodemap::NodeMap; use arena::TypedArena; use libc::{c_uint, uint64_t}; -use std::ffi::{self, CString}; +use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; use std::collections::HashSet; use std::mem; @@ -186,7 +186,7 @@ impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> { pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv, ty: Type, output: ty::FnOutput) -> ValueRef { - let buf = CString::from_slice(name.as_bytes()); + let buf = CString::new(name).unwrap(); let llfn: ValueRef = unsafe { llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf.as_ptr(), ty.to_ref()) }; @@ -247,7 +247,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>, let f = decl_rust_fn(ccx, fn_ty, name); let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did); - set_llvm_fn_attrs(ccx, &attrs[], f); + set_llvm_fn_attrs(ccx, &attrs[..], f); ccx.externs().borrow_mut().insert(name.to_string(), f); f @@ -340,7 +340,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, None => () } unsafe { - let buf = CString::from_slice(name.as_bytes()); + let buf = CString::new(name.clone()).unwrap(); let c = llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf.as_ptr()); // Thread-local statics in some other crate need to *always* be linked // against in a thread-local fashion, so we need to be sure to apply the @@ -523,7 +523,7 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::mk_nil(ccx.tcx())); get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), - &name[], + &name[..], llvm::CCallConv, llty, dtor_ty) @@ -898,14 +898,14 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::ty_bare_fn(_, ref fn_ty) => { match ccx.sess().target.target.adjust_abi(fn_ty.abi) { Rust | RustCall => { - get_extern_rust_fn(ccx, t, &name[], did) + get_extern_rust_fn(ccx, t, &name[..], did) } RustIntrinsic => { ccx.sess().bug("unexpected intrinsic in trans_external_path") } _ => { foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, - &name[]) + &name[..]) } } } @@ -947,7 +947,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llresult = Invoke(bcx, llfn, - &llargs[], + &llargs[..], normal_bcx.llbb, landing_pad, Some(attributes), @@ -961,7 +961,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llresult = Call(bcx, llfn, - &llargs[], + &llargs[..], Some(attributes), debug_loc); return (llresult, bcx); @@ -1219,19 +1219,6 @@ pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>, p } -pub fn arrayalloca(cx: Block, ty: Type, v: ValueRef) -> ValueRef { - let _icx = push_ctxt("arrayalloca"); - if cx.unreachable.get() { - unsafe { - return llvm::LLVMGetUndef(ty.to_ref()); - } - } - debuginfo::clear_source_location(cx.fcx); - let p = ArrayAlloca(cx, ty, v); - call_lifetime_start(cx, p); - p -} - // Creates the alloca slot which holds the pointer to the slot for the final return value pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, output_type: Ty<'tcx>) -> ValueRef { @@ -1646,7 +1633,7 @@ fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, "argtuple", arg_scope_id)); let untupled_arg_types = match monomorphized_arg_types[0].sty { - ty::ty_tup(ref types) => &types[], + ty::ty_tup(ref types) => &types[..], _ => { bcx.tcx().sess.span_bug(args[0].pat.span, "first arg to `rust-call` ABI function \ @@ -1834,12 +1821,12 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let arg_datums = if abi != RustCall { create_datums_for_fn_args(&fcx, - &monomorphized_arg_types[]) + &monomorphized_arg_types[..]) } else { create_datums_for_fn_args_under_call_abi( bcx, arg_scope, - &monomorphized_arg_types[]) + &monomorphized_arg_types[..]) }; bcx = match closure_env { @@ -1855,7 +1842,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg_scope, &decl.inputs[], arg_datums, - &monomorphized_arg_types[]) + &monomorphized_arg_types[..]) } }; @@ -2000,7 +1987,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, bcx = expr::trans_adt(bcx, result_ty, disr, - &fields[], + &fields[..], None, expr::SaveIn(llresult), debug_loc); @@ -2070,7 +2057,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx ty::erase_late_bound_regions( ccx.tcx(), &ty::ty_fn_args(ctor_ty)); - let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[]); + let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[..]); if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) { let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot"); @@ -2315,7 +2302,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => { meth::trans_impl(ccx, item.ident, - &impl_items[], + &impl_items[..], generics, item.id); } @@ -2430,7 +2417,7 @@ fn register_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => panic!("expected bare rust fn") }; - let llfn = decl_rust_fn(ccx, node_type, &sym[]); + let llfn = decl_rust_fn(ccx, node_type, &sym[..]); finish_register_fn(ccx, sp, sym, node_id, llfn); llfn } @@ -2475,7 +2462,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty< match fn_sig.inputs[1].sty { ty::ty_tup(ref t_in) => { - inputs.push_all(&t_in[]); + inputs.push_all(&t_in[..]); inputs } _ => ccx.sess().bug("expected tuple'd inputs") @@ -2611,7 +2598,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext, debug!("register_fn_llvmty id={} sym={}", node_id, sym); let llfn = decl_fn(ccx, - &sym[], + &sym[..], cc, llfty, ty::FnConverging(ty::mk_nil(ccx.tcx()))); @@ -2667,7 +2654,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, let (start_fn, args) = if use_start_lang_item { let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) { Ok(id) => id, - Err(s) => { ccx.sess().fatal(&s[]); } + Err(s) => { ccx.sess().fatal(&s[..]); } }; let start_fn = if start_def_id.krate == ast::LOCAL_CRATE { get_item_val(ccx, start_def_id.node) @@ -2783,12 +2770,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { } else { llvm::LLVMTypeOf(v) }; - if contains_null(&sym[]) { + if contains_null(&sym[..]) { ccx.sess().fatal( &format!("Illegal null byte in export_name \ value: `{}`", sym)[]); } - let buf = CString::from_slice(sym.as_bytes()); + let buf = CString::new(sym.clone()).unwrap(); let g = llvm::LLVMAddGlobal(ccx.llmod(), llty, buf.as_ptr()); @@ -2826,7 +2813,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { §)[]); } unsafe { - let buf = CString::from_slice(sect.as_bytes()); + let buf = CString::new(sect.as_bytes()).unwrap(); llvm::LLVMSetSection(v, buf.as_ptr()); } }, @@ -2988,12 +2975,12 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec { Some(compressed) => compressed, None => cx.sess().fatal("failed to compress metadata"), }); - let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[]); + let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]); let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false); let name = format!("rust_metadata_{}_{}", cx.link_meta().crate_name, cx.link_meta().crate_hash); - let buf = CString::from_vec(name.into_bytes()); + let buf = CString::new(name).unwrap(); let llglobal = unsafe { llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(), buf.as_ptr()) @@ -3001,7 +2988,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec { unsafe { llvm::LLVMSetInitializer(llglobal, llconst); let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx); - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); llvm::LLVMSetSection(llglobal, name.as_ptr()) } return metadata; @@ -3039,8 +3026,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { continue } - let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val)) - .to_vec(); + let name = CStr::from_ptr(llvm::LLVMGetValueName(val)) + .to_bytes().to_vec(); declared.insert(name); } } @@ -3056,8 +3043,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { continue } - let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val)) - .to_vec(); + let name = CStr::from_ptr(llvm::LLVMGetValueName(val)) + .to_bytes().to_vec(); if !declared.contains(&name) && !reachable.contains(str::from_utf8(&name).unwrap()) { llvm::SetLinkage(val, llvm::InternalLinkage); @@ -3211,7 +3198,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) reachable.push("rust_eh_personality_catch".to_string()); if codegen_units > 1 { - internalize_symbols(&shared_ccx, &reachable.iter().map(|x| x.clone()).collect()); + internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect()); } let metadata_module = ModuleTranslation { diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs index e268c2f0d5cc2..8199e6189c93b 100644 --- a/src/librustc_trans/trans/builder.rs +++ b/src/librustc_trans/trans/builder.rs @@ -431,7 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if name.is_empty() { llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname()) } else { - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), name.as_ptr()) } @@ -567,7 +567,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { let v = ixs.iter().map(|i| C_i32(self.ccx, *i as i32)).collect::>(); self.count_insn("gepi"); - self.inbounds_gep(base, &v[]) + self.inbounds_gep(base, &v[..]) } } @@ -775,8 +775,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let s = format!("{} ({})", text, self.ccx.sess().codemap().span_to_string(sp)); - debug!("{}", &s[]); - self.add_comment(&s[]); + debug!("{}", &s[..]); + self.add_comment(&s[..]); } } @@ -786,7 +786,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let comment_text = format!("{} {}", "#", sanitized.replace("\n", "\n\t# ")); self.count_insn("inlineasm"); - let comment_text = CString::from_vec(comment_text.into_bytes()); + let comment_text = CString::new(comment_text).unwrap(); let asm = unsafe { llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(), comment_text.as_ptr(), noname(), False, @@ -813,7 +813,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }).collect::>(); debug!("Asm Output Type: {}", self.ccx.tn().type_to_string(output)); - let fty = Type::func(&argtys[], &output); + let fty = Type::func(&argtys[..], &output); unsafe { let v = llvm::LLVMInlineAsm( fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index bda8b8938b76c..3d3e35cd776f0 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -323,7 +323,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( let llfn = decl_internal_rust_fn(ccx, tuple_fn_ty, - &function_name[]); + &function_name[..]); // let empty_substs = tcx.mk_substs(Substs::trans_empty()); @@ -359,7 +359,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( DebugLoc::None, bare_fn_ty, |bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) }, - ArgVals(&llargs[]), + ArgVals(&llargs[..]), dest).bcx; finish_fn(&fcx, bcx, sig.output, DebugLoc::None); @@ -792,7 +792,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, // Invoke the actual rust fn and update bcx/llresult. let (llret, b) = base::invoke(bcx, llfn, - &llargs[], + &llargs[..], callee_ty, debug_loc); bcx = b; @@ -833,7 +833,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, callee_ty, llfn, opt_llretslot.unwrap(), - &llargs[], + &llargs[..], arg_tys, debug_loc); } diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 1c831090e3eaf..85e53618f6da9 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -764,7 +764,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx let name = scope.block_name("clean"); debug!("generating cleanups for {}", name); let bcx_in = self.new_block(label.is_unwind(), - &name[], + &name[..], None); let mut bcx_out = bcx_in; for cleanup in scope.cleanups.iter().rev() { @@ -811,7 +811,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx Some(llbb) => { return llbb; } None => { let name = last_scope.block_name("unwind"); - pad_bcx = self.new_block(true, &name[], None); + pad_bcx = self.new_block(true, &name[..], None); last_scope.cached_landing_pad = Some(pad_bcx.llbb); } } diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index f92df999e6049..1d4bbd79d7105 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -158,7 +158,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc mangle_internal_name_by_path_and_seq(path, "closure") }); - let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[]); + let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[..]); // set an inline hint for all closures set_inline_hint(llfn); @@ -208,7 +208,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, let function_type = typer.closure_type(closure_id, param_substs); let freevars: Vec = - ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect()); + ty::with_freevars(tcx, id, |fv| fv.iter().cloned().collect()); let sig = ty::erase_late_bound_regions(tcx, &function_type.sig); @@ -221,7 +221,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, &[], sig.output, function_type.abi, - ClosureEnv::Closure(&freevars[])); + ClosureEnv::Closure(&freevars[..])); // Don't hoist this to the top of the function. It's perfectly legitimate // to have a zero-size closure (in which case dest will be `Ignore`) and diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index ac9a982f2983f..a9cda94bebac5 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -488,7 +488,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { opt_node_id: Option) -> Block<'a, 'tcx> { unsafe { - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn, name.as_ptr()); @@ -757,7 +757,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef { pub fn C_floating(s: &str, t: Type) -> ValueRef { unsafe { - let s = CString::from_slice(s.as_bytes()); + let s = CString::new(s).unwrap(); llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr()) } } @@ -835,7 +835,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va !null_terminated as Bool); let gsym = token::gensym("str"); - let buf = CString::from_vec(format!("str{}", gsym.usize()).into_bytes()); + let buf = CString::new(format!("str{}", gsym.usize())); + let buf = buf.unwrap(); let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr()); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); @@ -1161,8 +1162,8 @@ pub fn langcall(bcx: Block, Err(s) => { let msg = format!("{} {}", msg, s); match span { - Some(span) => bcx.tcx().sess.span_fatal(span, &msg[]), - None => bcx.tcx().sess.fatal(&msg[]), + Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]), + None => bcx.tcx().sess.fatal(&msg[..]), } } } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 86f5589556a78..7705b53ee38c6 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -75,7 +75,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) ast::LitBool(b) => C_bool(cx, b), ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()), ast::LitBinary(ref data) => { - let g = addr_of(cx, C_bytes(cx, &data[]), "binary", e.id); + let g = addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id); let base = ptrcast(g, Type::i8p(cx)); let prev_const = cx.const_unsized().borrow_mut() .insert(base, g); @@ -611,8 +611,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast::ExprTup(ref es) => { let repr = adt::represent_type(cx, ety); - let vals = map_list(&es[]); - adt::trans_const(cx, &*repr, 0, &vals[]) + let vals = map_list(&es[..]); + adt::trans_const(cx, &*repr, 0, &vals[..]) } ast::ExprStruct(_, ref fs, ref base_opt) => { let repr = adt::represent_type(cx, ety); @@ -642,9 +642,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } }).collect::>(); if ty::type_is_simd(cx.tcx(), ety) { - C_vector(&cs[]) + C_vector(&cs[..]) } else { - adt::trans_const(cx, &*repr, discr, &cs[]) + adt::trans_const(cx, &*repr, discr, &cs[..]) } }) } @@ -655,9 +655,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .collect::>(); // If the vector contains enums, an LLVM array won't work. if vs.iter().any(|vi| val_ty(*vi) != llunitty) { - C_struct(cx, &vs[], false) + C_struct(cx, &vs[..], false) } else { - C_array(llunitty, &vs[]) + C_array(llunitty, &vs[..]) } } ast::ExprRepeat(ref elem, ref count) => { @@ -671,9 +671,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let unit_val = const_expr(cx, &**elem, param_substs).0; let vs: Vec<_> = repeat(unit_val).take(n).collect(); if val_ty(unit_val) != llunitty { - C_struct(cx, &vs[], false) + C_struct(cx, &vs[..], false) } else { - C_array(llunitty, &vs[]) + C_array(llunitty, &vs[..]) } } ast::ExprPath(_) | ast::ExprQPath(_) => { @@ -715,14 +715,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast::ExprCall(ref callee, ref args) => { let opt_def = cx.tcx().def_map.borrow().get(&callee.id).cloned(); - let arg_vals = map_list(&args[]); + let arg_vals = map_list(&args[..]); match opt_def { Some(def::DefStruct(_)) => { if ty::type_is_simd(cx.tcx(), ety) { - C_vector(&arg_vals[]) + C_vector(&arg_vals[..]) } else { let repr = adt::represent_type(cx, ety); - adt::trans_const(cx, &*repr, 0, &arg_vals[]) + adt::trans_const(cx, &*repr, 0, &arg_vals[..]) } } Some(def::DefVariant(enum_did, variant_did, _)) => { @@ -733,7 +733,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, adt::trans_const(cx, &*repr, vinfo.disr_val, - &arg_vals[]) + &arg_vals[..]) } _ => cx.sess().span_bug(e.span, "expected a struct or variant def") } diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 96506291b5aae..eb07bdb7ba11b 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -225,15 +225,15 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> { unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) { let llcx = llvm::LLVMContextCreate(); - let mod_name = CString::from_slice(mod_name.as_bytes()); + let mod_name = CString::new(mod_name).unwrap(); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); - let data_layout = &*sess.target.target.data_layout; - let data_layout = CString::from_slice(data_layout.as_bytes()); + let data_layout = sess.target.target.data_layout.as_bytes(); + let data_layout = CString::new(data_layout).unwrap(); llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); - let llvm_target = &*sess.target.target.llvm_target; - let llvm_target = CString::from_slice(llvm_target.as_bytes()); + let llvm_target = sess.target.target.llvm_target.as_bytes(); + let llvm_target = CString::new(llvm_target).unwrap(); llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); (llcx, llmod) } @@ -288,7 +288,7 @@ impl<'tcx> SharedCrateContext<'tcx> { // such as a function name in the module. // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = format!("{}.{}.rs", crate_name, i); - let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[]); + let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[..]); shared_ccx.local_ccxs.push(local_ccx); } diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index e6cd44676cefb..26e12a1af403d 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -177,7 +177,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } let name = format!("then-block-{}-", thn.id); - let then_bcx_in = bcx.fcx.new_id_block(&name[], thn.id); + let then_bcx_in = bcx.fcx.new_id_block(&name[..], thn.id); let then_bcx_out = trans_block(then_bcx_in, &*thn, dest); trans::debuginfo::clear_source_location(bcx.fcx); @@ -378,7 +378,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem); let bcx = callee::trans_lang_call(bcx, did, - &args[], + &args[..], Some(expr::Ignore), call_info.debug_loc()).bcx; Unreachable(bcx); @@ -407,7 +407,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem); let bcx = callee::trans_lang_call(bcx, did, - &args[], + &args[..], Some(expr::Ignore), call_info.debug_loc()).bcx; Unreachable(bcx); diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 23498089c5839..fc0129239aac7 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -299,7 +299,7 @@ impl<'tcx> TypeMap<'tcx> { if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() { let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id); cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!", - &unique_type_id_str[])[]); + &unique_type_id_str[..])[]); } } @@ -380,14 +380,14 @@ impl<'tcx> TypeMap<'tcx> { self.get_unique_type_id_of_type(cx, component_type); let component_type_id = self.get_unique_type_id_as_string(component_type_id); - unique_type_id.push_str(&component_type_id[]); + unique_type_id.push_str(&component_type_id[..]); } }, ty::ty_uniq(inner_type) => { unique_type_id.push('~'); let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => { unique_type_id.push('*'); @@ -397,7 +397,7 @@ impl<'tcx> TypeMap<'tcx> { let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => { unique_type_id.push('&'); @@ -407,7 +407,7 @@ impl<'tcx> TypeMap<'tcx> { let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_vec(inner_type, optional_length) => { match optional_length { @@ -421,7 +421,7 @@ impl<'tcx> TypeMap<'tcx> { let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_trait(ref trait_data) => { unique_type_id.push_str("trait "); @@ -452,7 +452,7 @@ impl<'tcx> TypeMap<'tcx> { self.get_unique_type_id_of_type(cx, parameter_type); let parameter_type_id = self.get_unique_type_id_as_string(parameter_type_id); - unique_type_id.push_str(¶meter_type_id[]); + unique_type_id.push_str(¶meter_type_id[..]); unique_type_id.push(','); } @@ -465,7 +465,7 @@ impl<'tcx> TypeMap<'tcx> { ty::FnConverging(ret_ty) => { let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty); let return_type_id = self.get_unique_type_id_as_string(return_type_id); - unique_type_id.push_str(&return_type_id[]); + unique_type_id.push_str(&return_type_id[..]); } ty::FnDiverging => { unique_type_id.push_str("!"); @@ -538,7 +538,7 @@ impl<'tcx> TypeMap<'tcx> { type_map.get_unique_type_id_of_type(cx, type_parameter); let param_type_id = type_map.get_unique_type_id_as_string(param_type_id); - output.push_str(¶m_type_id[]); + output.push_str(¶m_type_id[..]); output.push(','); } @@ -568,7 +568,7 @@ impl<'tcx> TypeMap<'tcx> { self.get_unique_type_id_of_type(cx, parameter_type); let parameter_type_id = self.get_unique_type_id_as_string(parameter_type_id); - unique_type_id.push_str(¶meter_type_id[]); + unique_type_id.push_str(¶meter_type_id[..]); unique_type_id.push(','); } @@ -582,7 +582,7 @@ impl<'tcx> TypeMap<'tcx> { ty::FnConverging(ret_ty) => { let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty); let return_type_id = self.get_unique_type_id_as_string(return_type_id); - unique_type_id.push_str(&return_type_id[]); + unique_type_id.push_str(&return_type_id[..]); } ty::FnDiverging => { unique_type_id.push_str("!"); @@ -806,11 +806,11 @@ pub fn create_global_var_metadata(cx: &CrateContext, let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id)); let var_name = token::get_ident(ident).to_string(); let linkage_name = - namespace_node.mangled_name_of_contained_item(&var_name[]); + namespace_node.mangled_name_of_contained_item(&var_name[..]); let var_scope = namespace_node.scope; - let var_name = CString::from_slice(var_name.as_bytes()); - let linkage_name = CString::from_slice(linkage_name.as_bytes()); + let var_name = CString::new(var_name).unwrap(); + let linkage_name = CString::new(linkage_name).unwrap(); unsafe { llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx), var_scope, @@ -1287,7 +1287,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match expr.node { ast::ExprClosure(_, ref fn_decl, ref top_level_block) => { let name = format!("fn{}", token::gensym("fn")); - let name = token::str_to_ident(&name[]); + let name = token::str_to_ident(&name[..]); (name, &**fn_decl, // This is not quite right. It should actually inherit // the generics of the enclosing function. @@ -1366,7 +1366,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (linkage_name, containing_scope) = if has_path { let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id)); let linkage_name = namespace_node.mangled_name_of_contained_item( - &function_name[]); + &function_name[..]); let containing_scope = namespace_node.scope; (linkage_name, containing_scope) } else { @@ -1379,8 +1379,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id); - let function_name = CString::from_slice(function_name.as_bytes()); - let linkage_name = CString::from_slice(linkage_name.as_bytes()); + let function_name = CString::new(function_name).unwrap(); + let linkage_name = CString::new(linkage_name).unwrap(); let fn_metadata = unsafe { llvm::LLVMDIBuilderCreateFunction( DIB(cx), @@ -1451,7 +1451,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP)); } - return create_DIArray(DIB(cx), &signature[]); + return create_DIArray(DIB(cx), &signature[..]); } fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, @@ -1486,7 +1486,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, actual_self_type, true); - name_to_append_suffix_to.push_str(&actual_self_type_name[]); + name_to_append_suffix_to.push_str(&actual_self_type_name[..]); if generics.is_type_parameterized() { name_to_append_suffix_to.push_str(","); @@ -1501,7 +1501,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let ident = special_idents::type_self; let ident = token::get_ident(ident); - let name = CString::from_slice(ident.as_bytes()); + let name = CString::new(ident.as_bytes()).unwrap(); let param_metadata = unsafe { llvm::LLVMDIBuilderCreateTemplateTypeParameter( DIB(cx), @@ -1525,7 +1525,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let actual_type_name = compute_debuginfo_type_name(cx, actual_type, true); - name_to_append_suffix_to.push_str(&actual_type_name[]); + name_to_append_suffix_to.push_str(&actual_type_name[..]); if index != generics.ty_params.len() - 1 { name_to_append_suffix_to.push_str(","); @@ -1535,7 +1535,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if cx.sess().opts.debuginfo == FullDebugInfo { let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP); let ident = token::get_ident(ident); - let name = CString::from_slice(ident.as_bytes()); + let name = CString::new(ident.as_bytes()).unwrap(); let param_metadata = unsafe { llvm::LLVMDIBuilderCreateTemplateTypeParameter( DIB(cx), @@ -1552,7 +1552,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, name_to_append_suffix_to.push('>'); - return create_DIArray(DIB(cx), &template_params[]); + return create_DIArray(DIB(cx), &template_params[..]); } } @@ -1601,7 +1601,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { path_bytes.insert(1, prefix[1]); } - CString::from_vec(path_bytes) + CString::new(path_bytes).unwrap() } _ => fallback_path(cx) } @@ -1614,8 +1614,8 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { (option_env!("CFG_VERSION")).expect("CFG_VERSION")); let compile_unit_name = compile_unit_name.as_ptr(); - let work_dir = CString::from_slice(work_dir.as_vec()); - let producer = CString::from_slice(producer.as_bytes()); + let work_dir = CString::new(work_dir.as_vec()).unwrap(); + let producer = CString::new(producer).unwrap(); let flags = "\0"; let split_name = "\0"; return unsafe { @@ -1632,7 +1632,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { }; fn fallback_path(cx: &CrateContext) -> CString { - CString::from_slice(cx.link_meta().crate_name.as_bytes()) + CString::new(cx.link_meta().crate_name.clone()).unwrap() } } @@ -1646,7 +1646,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let cx: &CrateContext = bcx.ccx(); let filename = span_start(cx, span).file.name.clone(); - let file_metadata = file_metadata(cx, &filename[]); + let file_metadata = file_metadata(cx, &filename[..]); let name = token::get_ident(variable_ident); let loc = span_start(cx, span); @@ -1658,7 +1658,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, CapturedVariable => (0, DW_TAG_auto_variable) }; - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name.as_bytes()).unwrap(); match (variable_access, [].as_slice()) { (DirectVariable { alloca }, address_operations) | (IndirectVariable {alloca, address_operations}, _) => { @@ -1724,8 +1724,8 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { full_path }; - let file_name = CString::from_slice(file_name.as_bytes()); - let work_dir = CString::from_slice(work_dir.as_bytes()); + let file_name = CString::new(file_name).unwrap(); + let work_dir = CString::new(work_dir).unwrap(); let file_metadata = unsafe { llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(), work_dir.as_ptr()) @@ -1800,7 +1800,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let llvm_type = type_of::type_of(cx, t); let (size, align) = size_and_align_of(cx, llvm_type); - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); let ty_metadata = unsafe { llvm::LLVMDIBuilderCreateBasicType( DIB(cx), @@ -1820,7 +1820,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let pointer_llvm_type = type_of::type_of(cx, pointer_type); let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type); let name = compute_debuginfo_type_name(cx, pointer_type, false); - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); let ptr_metadata = unsafe { llvm::LLVMDIBuilderCreatePointerType( DIB(cx), @@ -1959,7 +1959,7 @@ impl<'tcx> RecursiveTypeDescription<'tcx> { set_members_of_composite_type(cx, metadata_stub, llvm_type, - &member_descriptions[]); + &member_descriptions[..]); return MetadataCreationResult::new(metadata_stub, true); } } @@ -2031,7 +2031,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let struct_metadata_stub = create_struct_stub(cx, struct_llvm_type, - &struct_name[], + &struct_name[..], unique_type_id, containing_scope); @@ -2098,7 +2098,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unique_type_id, create_struct_stub(cx, tuple_llvm_type, - &tuple_name[], + &tuple_name[..], unique_type_id, UNKNOWN_SCOPE_METADATA), tuple_llvm_type, @@ -2158,7 +2158,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - &member_descriptions[]); + &member_descriptions[..]); MemberDescription { name: "".to_string(), llvm_type: variant_llvm_type, @@ -2191,7 +2191,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - &member_descriptions[]); + &member_descriptions[..]); vec![ MemberDescription { name: "".to_string(), @@ -2291,7 +2291,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - &variant_member_descriptions[]); + &variant_member_descriptions[..]); // Encode the information about the null variant in the union // member's name. @@ -2445,7 +2445,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .iter() .map(|v| { let token = token::get_name(v.name); - let name = CString::from_slice(token.as_bytes()); + let name = CString::new(token.as_bytes()).unwrap(); unsafe { llvm::LLVMDIBuilderCreateEnumerator( DIB(cx), @@ -2475,7 +2475,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, codemap::DUMMY_SP); let discriminant_name = get_enum_discriminant_name(cx, enum_def_id); - let name = CString::from_slice(discriminant_name.as_bytes()); + let name = CString::new(discriminant_name.as_bytes()).unwrap(); let discriminant_type_metadata = unsafe { llvm::LLVMDIBuilderCreateEnumerationType( DIB(cx), @@ -2518,8 +2518,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .borrow() .get_unique_type_id_as_string(unique_type_id); - let enum_name = CString::from_slice(enum_name.as_bytes()); - let unique_type_id_str = CString::from_slice(unique_type_id_str.as_bytes()); + let enum_name = CString::new(enum_name).unwrap(); + let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap(); let enum_metadata = unsafe { llvm::LLVMDIBuilderCreateUnionType( DIB(cx), @@ -2644,7 +2644,8 @@ fn set_members_of_composite_type(cx: &CrateContext, ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i) }; - let member_name = CString::from_slice(member_description.name.as_bytes()); + let member_name = member_description.name.as_bytes(); + let member_name = CString::new(member_name).unwrap(); unsafe { llvm::LLVMDIBuilderCreateMemberType( DIB(cx), @@ -2662,7 +2663,7 @@ fn set_members_of_composite_type(cx: &CrateContext, .collect(); unsafe { - let type_array = create_DIArray(DIB(cx), &member_metadata[]); + let type_array = create_DIArray(DIB(cx), &member_metadata[..]); llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array); } } @@ -2681,8 +2682,8 @@ fn create_struct_stub(cx: &CrateContext, let unique_type_id_str = debug_context(cx).type_map .borrow() .get_unique_type_id_as_string(unique_type_id); - let name = CString::from_slice(struct_type_name.as_bytes()); - let unique_type_id = CString::from_slice(unique_type_id_str.as_bytes()); + let name = CString::new(struct_type_name).unwrap(); + let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap(); let metadata_stub = unsafe { // LLVMDIBuilderCreateStructType() wants an empty array. A null // pointer will lead to hard to trace and debug LLVM assertions @@ -2763,7 +2764,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let member_llvm_types = slice_llvm_type.field_types(); assert!(slice_layout_is_correct(cx, - &member_llvm_types[], + &member_llvm_types[..], element_type)); let member_descriptions = [ MemberDescription { @@ -2789,7 +2790,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let metadata = composite_type_metadata(cx, slice_llvm_type, - &slice_type_name[], + &slice_type_name[..], unique_type_id, &member_descriptions, UNKNOWN_SCOPE_METADATA, @@ -2838,7 +2839,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, llvm::LLVMDIBuilderCreateSubroutineType( DIB(cx), UNKNOWN_FILE_METADATA, - create_DIArray(DIB(cx), &signature_metadata[])) + create_DIArray(DIB(cx), &signature_metadata[..])) }, false); } @@ -2864,7 +2865,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type); cx.sess().bug(&format!("debuginfo: Unexpected trait-object type in \ trait_pointer_metadata(): {}", - &pp_type_name[])[]); + &pp_type_name[..])[]); } }; @@ -2878,7 +2879,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, composite_type_metadata(cx, trait_llvm_type, - &trait_type_name[], + &trait_type_name[..], unique_type_id, &[], containing_scope, @@ -2998,7 +2999,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::ty_tup(ref elements) => { prepare_tuple_metadata(cx, t, - &elements[], + &elements[..], unique_type_id, usage_site_span).finalize(cx) } @@ -3022,9 +3023,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, type id '{}' to already be in \ the debuginfo::TypeMap but it \ was not. (Ty = {})", - &unique_type_id_str[], + &unique_type_id_str[..], ppaux::ty_to_string(cx.tcx(), t)); - cx.sess().span_bug(usage_site_span, &error_message[]); + cx.sess().span_bug(usage_site_span, &error_message[..]); } }; @@ -3037,9 +3038,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, UniqueTypeId maps in \ debuginfo::TypeMap. \ UniqueTypeId={}, Ty={}", - &unique_type_id_str[], + &unique_type_id_str[..], ppaux::ty_to_string(cx.tcx(), t)); - cx.sess().span_bug(usage_site_span, &error_message[]); + cx.sess().span_bug(usage_site_span, &error_message[..]); } } None => { @@ -3128,7 +3129,7 @@ fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool { attributes.iter().any(|attr| { let meta_item: &ast::MetaItem = &*attr.node.value; match meta_item.node { - ast::MetaWord(ref value) => &value[] == "no_debug", + ast::MetaWord(ref value) => &value[..] == "no_debug", _ => false } }) @@ -3971,8 +3972,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc ptr::null_mut() }; let namespace_name = token::get_name(name); - let namespace_name = CString::from_slice(namespace_name - .as_bytes()); + let namespace_name = CString::new(namespace_name.as_bytes()).unwrap(); let scope = unsafe { llvm::LLVMDIBuilderCreateNameSpace( DIB(cx), @@ -4020,7 +4020,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc(bcx: Block<'blk, 'tcx>, controlflow::trans_if(bcx, expr.id, &**cond, &**thn, els.as_ref().map(|e| &**e), dest) } ast::ExprMatch(ref discr, ref arms, _) => { - _match::trans_match(bcx, expr, &**discr, &arms[], dest) + _match::trans_match(bcx, expr, &**discr, &arms[..], dest) } ast::ExprBlock(ref blk) => { controlflow::trans_block(bcx, &**blk, dest) } ast::ExprStruct(_, ref fields, ref base) => { trans_struct(bcx, - &fields[], + &fields[..], base.as_ref().map(|e| &**e), expr.span, expr.id, @@ -1118,7 +1118,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_adt(bcx, expr_ty(bcx, expr), 0, - &numbered_fields[], + &numbered_fields[..], None, dest, expr.debug_loc()) @@ -1153,13 +1153,13 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_overloaded_call(bcx, expr, &**f, - &args[], + &args[..], Some(dest)) } else { callee::trans_call(bcx, expr, &**f, - callee::ArgExprs(&args[]), + callee::ArgExprs(&args[..]), dest) } } @@ -1167,7 +1167,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, callee::trans_method_call(bcx, expr, &*args[0], - callee::ArgExprs(&args[]), + callee::ArgExprs(&args[..]), dest) } ast::ExprBinary(op, ref lhs, ref rhs) => { @@ -1197,7 +1197,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let trait_ref = bcx.tcx().object_cast_map.borrow() .get(&expr.id) - .map(|t| (*t).clone()) + .cloned() .unwrap(); let trait_ref = bcx.monomorphize(&trait_ref); let datum = unpack_datum!(bcx, trans(bcx, &**val)); @@ -1354,11 +1354,11 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, ty::ty_struct(did, substs) => { let fields = struct_fields(tcx, did, substs); let fields = monomorphize::normalize_associated_type(tcx, &fields); - op(0, &fields[]) + op(0, &fields[..]) } ty::ty_tup(ref v) => { - op(0, &tup_fields(&v[])[]) + op(0, &tup_fields(&v[..])[]) } ty::ty_enum(_, substs) => { @@ -1378,7 +1378,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, tcx, enum_id, variant_id); let fields = struct_fields(tcx, variant_id, substs); let fields = monomorphize::normalize_associated_type(tcx, &fields); - op(variant_info.disr_val, &fields[]) + op(variant_info.disr_val, &fields[..]) } _ => { tcx.sess.bug("resolve didn't map this expr to a \ diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 8f0e4e647b5b3..4508fe21a65fa 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -135,7 +135,7 @@ pub fn register_static(ccx: &CrateContext, }; unsafe { // Declare a symbol `foo` with the desired linkage. - let buf = CString::from_slice(ident.as_bytes()); + let buf = CString::new(ident.as_bytes()).unwrap(); let g1 = llvm::LLVMAddGlobal(ccx.llmod(), llty2.to_ref(), buf.as_ptr()); llvm::SetLinkage(g1, linkage); @@ -148,7 +148,7 @@ pub fn register_static(ccx: &CrateContext, // zero. let mut real_name = "_rust_extern_with_linkage_".to_string(); real_name.push_str(&ident); - let real_name = CString::from_vec(real_name.into_bytes()); + let real_name = CString::new(real_name).unwrap(); let g2 = llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), real_name.as_ptr()); llvm::SetLinkage(g2, llvm::InternalLinkage); @@ -158,7 +158,7 @@ pub fn register_static(ccx: &CrateContext, } None => unsafe { // Generate an external declaration. - let buf = CString::from_slice(ident.as_bytes()); + let buf = CString::new(ident.as_bytes()).unwrap(); llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf.as_ptr()) } } @@ -238,7 +238,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, _ => ccx.sess().bug("trans_native_call called on non-function type") }; let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig); - let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[]); + let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]); let fn_type = cabi::compute_abi_info(ccx, &llsig.llarg_tys[], llsig.llret_ty, @@ -370,7 +370,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llforeign_retval = CallWithConv(bcx, llfn, - &llargs_foreign[], + &llargs_foreign[..], cc, Some(attrs), call_debug_loc); @@ -611,7 +611,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ccx.tcx().map.path_to_string(id), id, t.repr(tcx)); - let llfn = base::decl_internal_rust_fn(ccx, t, &ps[]); + let llfn = base::decl_internal_rust_fn(ccx, t, &ps[..]); base::set_llvm_fn_attrs(ccx, attrs, llfn); base::trans_fn(ccx, decl, body, llfn, param_substs, id, &[]); llfn @@ -974,7 +974,7 @@ fn lltype_for_fn_from_foreign_types(ccx: &CrateContext, tys: &ForeignTypes) -> T if tys.fn_sig.variadic { Type::variadic_func(&llargument_tys, &llreturn_ty) } else { - Type::func(&llargument_tys[], &llreturn_ty) + Type::func(&llargument_tys[..], &llreturn_ty) } } diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index af90e1ec5c5dd..268b65c6ceb30 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -170,7 +170,7 @@ pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Val let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) { Some(old_sym) => { - let glue = decl_cdecl_fn(ccx, &old_sym[], llfnty, ty::mk_nil(ccx.tcx())); + let glue = decl_cdecl_fn(ccx, &old_sym[..], llfnty, ty::mk_nil(ccx.tcx())); (glue, None) }, None => { @@ -304,7 +304,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, class_did, &[get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil(bcx.tcx())); - let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, DebugLoc::None); + let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[..], dtor_ty, DebugLoc::None); variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope); variant_cx @@ -513,7 +513,7 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) let llalign = llalign_of(ccx, llty); let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc"); debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name); - let buf = CString::from_slice(name.as_bytes()); + let buf = CString::new(name.clone()).unwrap(); let gvar = unsafe { llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(), buf.as_ptr()) @@ -541,7 +541,7 @@ fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, ccx, t, &format!("glue_{}", name)[]); - let llfn = decl_cdecl_fn(ccx, &fn_nm[], llfnty, ty::mk_nil(ccx.tcx())); + let llfn = decl_cdecl_fn(ccx, &fn_nm[..], llfnty, ty::mk_nil(ccx.tcx())); note_unique_llvm_symbol(ccx, fn_nm.clone()); return (fn_nm, llfn); } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 5687247561e9c..a1b66ed94f06b 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -166,7 +166,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let name = token::get_ident(foreign_item.ident); // For `transmute` we can just trans the input expr directly into dest - if &name[] == "transmute" { + if &name[..] == "transmute" { let llret_ty = type_of::type_of(ccx, ret_ty.unwrap()); match args { callee::ArgExprs(arg_exprs) => { @@ -274,13 +274,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let call_debug_location = DebugLoc::At(call_info.id, call_info.span); // These are the only intrinsic functions that diverge. - if &name[] == "abort" { + if &name[..] == "abort" { let llfn = ccx.get_intrinsic(&("llvm.trap")); Call(bcx, llfn, &[], None, call_debug_location); fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); Unreachable(bcx); return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to())); - } else if &name[] == "unreachable" { + } else if &name[..] == "unreachable" { fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); Unreachable(bcx); return Result::new(bcx, C_nil(ccx)); @@ -307,7 +307,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, }; let simple = get_simple_intrinsic(ccx, &*foreign_item); - let llval = match (simple, &name[]) { + let llval = match (simple, &name[..]) { (Some(llfn), _) => { Call(bcx, llfn, &llargs, None, call_debug_location) } diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 30797344da810..ec48ab0d34a06 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -131,7 +131,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, hash = format!("h{}", state.finish()); ccx.tcx().map.with_path(fn_id.node, |path| { - exported_name(path, &hash[]) + exported_name(path, &hash[..]) }) }; @@ -141,9 +141,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let mut hash_id = Some(hash_id); let mut mk_lldecl = |abi: abi::Abi| { let lldecl = if abi != abi::Rust { - foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[]) + foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[..]) } else { - decl_internal_rust_fn(ccx, mono_ty, &s[]) + decl_internal_rust_fn(ccx, mono_ty, &s[..]) }; ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl); @@ -182,7 +182,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, if abi != abi::Rust { foreign::trans_rust_fn_with_foreign_abi( ccx, &**decl, &**body, &[], d, psubsts, fn_id.node, - Some(&hash[])); + Some(&hash[..])); } else { trans_fn(ccx, &**decl, &**body, d, psubsts, fn_id.node, &[]); } @@ -206,7 +206,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, trans_enum_variant(ccx, parent, &*v, - &args[], + &args[..], this_tv.disr_val, psubsts, d); diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 456e27967f5a6..7b59e0258ee22 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -171,33 +171,27 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let vt = vec_types_from_expr(bcx, content_expr); let count = elements_required(bcx, content_expr); debug!(" vt={}, count={}", vt.to_string(ccx), count); - let llcount = C_uint(ccx, count); let fixed_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty, Some(count)); - let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to(); + let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty); - let llfixed = if count == 0 { - // Just create a zero-sized alloca to preserve - // the non-null invariant of the inner slice ptr - let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); - BitCast(bcx, llfixed, llfixed_ty) - } else { - // Make a fixed-length backing array and allocate it on the stack. - let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); + // Always create an alloca even if zero-sized, to preserve + // the non-null invariant of the inner slice ptr + let llfixed = base::alloca(bcx, llfixed_ty, ""); + if count > 0 { // Arrange for the backing array to be cleaned up. - let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty); let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id); - fcx.schedule_lifetime_end(cleanup_scope, llfixed_casted); - fcx.schedule_drop_mem(cleanup_scope, llfixed_casted, fixed_ty); + fcx.schedule_lifetime_end(cleanup_scope, llfixed); + fcx.schedule_drop_mem(cleanup_scope, llfixed, fixed_ty); // Generate the content into the backing array. - bcx = write_content(bcx, &vt, slice_expr, - content_expr, SaveIn(llfixed)); - - llfixed_casted + // llfixed has type *[T x N], but we want the type *T, + // so use GEP to convert + bcx = write_content(bcx, &vt, slice_expr, content_expr, + SaveIn(GEPi(bcx, llfixed, &[0, 0]))); }; immediate_rvalue_bcx(bcx, llfixed, vec_ty).to_expr_datumblock() @@ -426,49 +420,27 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("tvec::iter_vec_loop"); let fcx = bcx.fcx; - let next_bcx = fcx.new_temp_block("expr_repeat: while next"); let loop_bcx = fcx.new_temp_block("expr_repeat"); - let cond_bcx = fcx.new_temp_block("expr_repeat: loop cond"); - let body_bcx = fcx.new_temp_block("expr_repeat: body: set"); - let inc_bcx = fcx.new_temp_block("expr_repeat: body: inc"); - Br(bcx, loop_bcx.llbb, DebugLoc::None); - - let loop_counter = { - // i = 0 - let i = alloca(loop_bcx, bcx.ccx().int_type(), "__i"); - Store(loop_bcx, C_uint(bcx.ccx(), 0_u32), i); + let next_bcx = fcx.new_temp_block("expr_repeat: next"); - Br(loop_bcx, cond_bcx.llbb, DebugLoc::None); - i - }; - - { // i < count - let lhs = Load(cond_bcx, loop_counter); - let rhs = count; - let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs, DebugLoc::None); - - CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None); - } + Br(bcx, loop_bcx.llbb, DebugLoc::None); - { // loop body - let i = Load(body_bcx, loop_counter); - let lleltptr = if vt.llunit_alloc_size == 0 { - data_ptr - } else { - InBoundsGEP(body_bcx, data_ptr, &[i]) - }; - let body_bcx = f(body_bcx, lleltptr, vt.unit_ty); + let loop_counter = Phi(loop_bcx, bcx.ccx().int_type(), + &[C_uint(bcx.ccx(), 0 as usize)], &[bcx.llbb]); - Br(body_bcx, inc_bcx.llbb, DebugLoc::None); - } + let bcx = loop_bcx; - { // i += 1 - let i = Load(inc_bcx, loop_counter); - let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1_u32), DebugLoc::None); - Store(inc_bcx, plusone, loop_counter); + let lleltptr = if vt.llunit_alloc_size == 0 { + data_ptr + } else { + InBoundsGEP(bcx, data_ptr, &[loop_counter]) + }; + let bcx = f(bcx, lleltptr, vt.unit_ty); + let plusone = Add(bcx, loop_counter, C_uint(bcx.ccx(), 1us), DebugLoc::None); + AddIncomingToPhi(loop_counter, plusone, bcx.llbb); - Br(inc_bcx, cond_bcx.llbb, DebugLoc::None); - } + let cond_val = ICmp(bcx, llvm::IntULT, plusone, count, DebugLoc::None); + CondBr(bcx, cond_val, loop_bcx.llbb, next_bcx.llbb, DebugLoc::None); next_bcx } diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index e3e4ca62c262f..ad83135a0d46f 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -163,7 +163,7 @@ impl Type { } pub fn named_struct(ccx: &CrateContext, name: &str) -> Type { - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr())) } diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 9d1c0fadefcd2..489b56bbe6825 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -67,7 +67,7 @@ pub fn untuple_arguments_if_necessary<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, abi: abi::Abi) -> Vec> { if abi != abi::RustCall { - return inputs.iter().map(|x| (*x).clone()).collect() + return inputs.iter().cloned().collect() } if inputs.len() == 0 { @@ -144,7 +144,7 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty)); atys.extend(input_tys); - Type::func(&atys[], &lloutputtype) + Type::func(&atys[..], &lloutputtype) } // Given a function type and a count of ty params, construct an llvm type @@ -332,7 +332,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { let repr = adt::represent_type(cx, t); let tps = substs.types.get_slice(subst::TypeSpace); let name = llvm_type_name(cx, an_enum, did, tps); - adt::incomplete_type_of(cx, &*repr, &name[]) + adt::incomplete_type_of(cx, &*repr, &name[..]) } ty::ty_closure(did, _, ref substs) => { // Only create the named struct, but don't fill it in. We @@ -343,7 +343,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { // contents of the VecPerParamSpace to to construct the llvm // name let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice()); - adt::incomplete_type_of(cx, &*repr, &name[]) + adt::incomplete_type_of(cx, &*repr, &name[..]) } ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => { @@ -399,7 +399,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { let repr = adt::represent_type(cx, t); let tps = substs.types.get_slice(subst::TypeSpace); let name = llvm_type_name(cx, a_struct, did, tps); - adt::incomplete_type_of(cx, &*repr, &name[]) + adt::incomplete_type_of(cx, &*repr, &name[..]) } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0183b3474a509..e3c1c66f78c9c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -404,17 +404,30 @@ fn create_substs_for_ast_path<'tcx>( let actual_supplied_ty_param_count = substs.types.len(TypeSpace); for param in &ty_param_defs[actual_supplied_ty_param_count..] { - match param.default { - Some(default) => { + if let Some(default) = param.default { + // If we are converting an object type, then the + // `Self` parameter is unknown. However, some of the + // other type parameters may reference `Self` in their + // defaults. This will lead to an ICE if we are not + // careful! + if self_ty.is_none() && ty::type_has_self(default) { + tcx.sess.span_err( + span, + &format!("the type parameter `{}` must be explicitly specified \ + in an object type because its default value `{}` references \ + the type `Self`", + param.name.user_string(tcx), + default.user_string(tcx))); + substs.types.push(TypeSpace, tcx.types.err); + } else { // This is a default type parameter. let default = default.subst_spanned(tcx, &substs, Some(span)); substs.types.push(TypeSpace, default); } - None => { - tcx.sess.span_bug(span, "extra parameter without default"); - } + } else { + tcx.sess.span_bug(span, "extra parameter without default"); } } @@ -1139,14 +1152,14 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None) } ast::TyObjectSum(ref ty, ref bounds) => { - match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[]) { + match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[..]) { Ok((trait_ref, projection_bounds)) => { trait_ref_to_object_type(this, rscope, ast_ty.span, trait_ref, projection_bounds, - &bounds[]) + &bounds[..]) } Err(ErrorReported) => { this.tcx().types.err @@ -1185,7 +1198,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn)) } ast::TyPolyTraitRef(ref bounds) => { - conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[]) + conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[..]) } ast::TyPath(ref path, id) => { let a_def = match tcx.def_map.borrow().get(&id) { @@ -1424,7 +1437,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, // Skip the first argument if `self` is present. &self_and_input_tys[1..] } else { - &self_and_input_tys[] + &self_and_input_tys[..] }; let (ior, lfp) = find_implied_output_region(input_tys, input_pats); @@ -1623,7 +1636,7 @@ fn conv_ty_poly_trait_ref<'tcx>( ast_bounds: &[ast::TyParamBound]) -> Ty<'tcx> { - let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[]); + let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[..]); let mut projection_bounds = Vec::new(); let main_trait_bound = if !partitioned_bounds.trait_bounds.is_empty() { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0d30741978a5a..34c52981b794d 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -162,7 +162,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, check_pat_enum(pcx, pat, &path, Some(&[]), expected); } ast::PatEnum(ref path, ref subpats) => { - let subpats = subpats.as_ref().map(|v| &v[]); + let subpats = subpats.as_ref().map(|v| &v[..]); check_pat_enum(pcx, pat, path, subpats, expected); } ast::PatStruct(ref path, ref fields, etc) => { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 7354ea7377c36..0ad15456df98f 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -256,7 +256,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, check_argument_types(fcx, call_expr.span, &fn_sig.inputs, - &expected_arg_tys[], + &expected_arg_tys[..], arg_exprs, AutorefArgs::No, fn_sig.variadic, diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs index da25719baaa4a..4aaaf4ffe5ab3 100644 --- a/src/librustc_typeck/check/implicator.rs +++ b/src/librustc_typeck/check/implicator.rs @@ -329,6 +329,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { fn accumulate_from_assoc_types_transitive(&mut self, data: &ty::PolyTraitPredicate<'tcx>) { + debug!("accumulate_from_assoc_types_transitive({})", + data.repr(self.tcx())); + for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) { match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) { Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); } @@ -340,6 +343,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { fn accumulate_from_assoc_types(&mut self, trait_ref: Rc>) { + debug!("accumulate_from_assoc_types({})", + trait_ref.repr(self.tcx())); + let trait_def_id = trait_ref.def_id; let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); let assoc_type_projections: Vec<_> = @@ -347,6 +353,8 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { .iter() .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name)) .collect(); + debug!("accumulate_from_assoc_types: assoc_type_projections={}", + assoc_type_projections.repr(self.tcx())); let tys = match self.fully_normalize(&assoc_type_projections) { Ok(tys) => { tys } Err(ErrorReported) => { return; } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 82bd4ae87ffae..978fbbbcffc33 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -901,7 +901,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("applicable_candidates: {}", applicable_candidates.repr(self.tcx())); if applicable_candidates.len() > 1 { - match self.collapse_candidates_to_trait_pick(&applicable_candidates[]) { + match self.collapse_candidates_to_trait_pick(&applicable_candidates[..]) { Some(pick) => { return Some(Ok(pick)); } None => { } } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 063300a1d7280..1639772103b7a 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -172,7 +172,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"}, one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}); - fcx.sess().fileline_help(span, &msg[]); + fcx.sess().fileline_help(span, &msg[..]); for (i, trait_did) in candidates.iter().enumerate() { fcx.sess().fileline_help(span, @@ -218,7 +218,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}, name = method_ustring); - fcx.sess().fileline_help(span, &msg[]); + fcx.sess().fileline_help(span, &msg[..]); for (i, trait_info) in candidates.iter().enumerate() { fcx.sess().fileline_help(span, @@ -306,10 +306,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { // Crate-local: // // meh. - struct Visitor<'a, 'b: 'a, 'tcx: 'a + 'b> { + struct Visitor<'a> { traits: &'a mut AllTraitsVec, } - impl<'v,'a, 'b, 'tcx> visit::Visitor<'v> for Visitor<'a, 'b, 'tcx> { + impl<'v, 'a> visit::Visitor<'v> for Visitor<'a> { fn visit_item(&mut self, i: &'v ast::Item) { match i.node { ast::ItemTrait(..) => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3c2888e227803..e443b4d0e606a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -638,7 +638,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, // Remember return type so that regionck can access it later. let mut fn_sig_tys: Vec = arg_tys.iter() - .map(|&ty| ty) + .cloned() .collect(); if let ty::FnConverging(ret_ty) = ret_ty { @@ -2208,7 +2208,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_argument_types(fcx, sp, - &err_inputs[], + &err_inputs[..], &[], args_no_rcvr, autoref_args, @@ -2227,7 +2227,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_argument_types(fcx, sp, &fty.sig.0.inputs[1..], - &expected_arg_tys[], + &expected_arg_tys[..], args_no_rcvr, autoref_args, fty.sig.0.variadic, @@ -3054,7 +3054,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ty::ty_struct(base_id, substs) => { debug!("struct named {}", ppaux::ty_to_string(tcx, base_t)); let fields = ty::lookup_struct_fields(tcx, base_id); - fcx.lookup_field_ty(expr.span, base_id, &fields[], + fcx.lookup_field_ty(expr.span, base_id, &fields[..], field.node.name, &(*substs)) } _ => None @@ -3154,7 +3154,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if tuple_like { debug!("tuple struct named {}", ppaux::ty_to_string(tcx, base_t)); let fields = ty::lookup_struct_fields(tcx, base_id); - fcx.lookup_tup_field_ty(expr.span, base_id, &fields[], + fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..], idx.node, &(*substs)) } else { None @@ -3219,7 +3219,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, for field in ast_fields { let mut expected_field_type = tcx.types.err; - let pair = class_field_map.get(&field.ident.node.name).map(|x| *x); + let pair = class_field_map.get(&field.ident.node.name).cloned(); match pair { None => { fcx.type_error_message( @@ -3327,7 +3327,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, class_id, id, fcx.ccx.tcx.mk_substs(struct_substs), - &class_fields[], + &class_fields[..], fields, base_expr.is_none(), None); @@ -3370,7 +3370,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, variant_id, id, fcx.ccx.tcx.mk_substs(substitutions), - &variant_fields[], + &variant_fields[..], fields, true, Some(enum_id)); @@ -3731,10 +3731,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.write_ty(id, fcx.node_ty(b.id)); } ast::ExprCall(ref callee, ref args) => { - callee::check_call(fcx, expr, &**callee, &args[], expected); + callee::check_call(fcx, expr, &**callee, &args[..], expected); } ast::ExprMethodCall(ident, ref tps, ref args) => { - check_method_call(fcx, expr, ident, &args[], &tps[], expected, lvalue_pref); + check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref); let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a)); let args_err = arg_tys.fold(false, |rest_err, a| { @@ -3821,7 +3821,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ast::ExprTup(ref elts) => { let flds = expected.only_has_type(fcx).and_then(|ty| { match ty.sty { - ty::ty_tup(ref flds) => Some(&flds[]), + ty::ty_tup(ref flds) => Some(&flds[..]), _ => None } }); @@ -3851,11 +3851,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprStruct(ref path, ref fields, ref base_expr) => { // Resolve the path. - let def = tcx.def_map.borrow().get(&id).map(|i| *i); + let def = tcx.def_map.borrow().get(&id).cloned(); let struct_id = match def { Some(def::DefVariant(enum_id, variant_id, true)) => { check_struct_enum_variant(fcx, id, expr.span, enum_id, - variant_id, &fields[]); + variant_id, &fields[..]); enum_id } Some(def::DefTrait(def_id)) => { @@ -3864,7 +3864,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, pprust::path_to_string(path)); check_struct_fields_on_error(fcx, id, - &fields[], + &fields[..], base_expr); def_id }, @@ -3877,7 +3877,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, id, expr.span, struct_did, - &fields[], + &fields[..], base_expr.as_ref().map(|e| &**e)); } _ => { @@ -3886,7 +3886,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, pprust::path_to_string(path)); check_struct_fields_on_error(fcx, id, - &fields[], + &fields[..], base_expr); } } @@ -5231,10 +5231,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { } }; (n_tps, inputs, ty::FnConverging(output)) - } else if &name[] == "abort" || &name[] == "unreachable" { + } else if &name[..] == "abort" || &name[..] == "unreachable" { (0, Vec::new(), ty::FnDiverging) } else { - let (n_tps, inputs, output) = match &name[] { + let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), ty::mk_nil(tcx)), "size_of" | "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.uint), @@ -5259,7 +5259,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "get_tydesc" => { let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) { Ok(t) => t, - Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[]); } + Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[..]); } }; let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 4e5550a2106a9..82abff8c425f4 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -294,8 +294,8 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { let len = self.region_bound_pairs.len(); let old_body_id = self.set_body_id(body.id); - self.relate_free_regions(&fn_sig[], body.id, span); - link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[]); + self.relate_free_regions(&fn_sig[..], body.id, span); + link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[..]); self.visit_block(body); self.visit_region_obligations(body.id); self.region_bound_pairs.truncate(len); @@ -626,6 +626,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { visit::walk_expr(rcx, expr); } + ast::ExprBinary(_, ref lhs, ref rhs) => { + // If you do `x OP y`, then the types of `x` and `y` must + // outlive the operation you are performing. + let lhs_ty = rcx.resolve_expr_type_adjusted(&**lhs); + let rhs_ty = rcx.resolve_expr_type_adjusted(&**rhs); + for &ty in [lhs_ty, rhs_ty].iter() { + type_must_outlive(rcx, + infer::Operand(expr.span), + ty, + ty::ReScope(CodeExtent::from_node_id(expr.id))); + } + visit::walk_expr(rcx, expr); + } + ast::ExprUnary(op, ref lhs) if has_method_map => { let implicitly_ref_args = !ast_util::is_by_value_unop(op); @@ -690,7 +704,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { } ast::ExprMatch(ref discr, ref arms, _) => { - link_match(rcx, &**discr, &arms[]); + link_match(rcx, &**discr, &arms[..]); visit::walk_expr(rcx, expr); } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 2e7eff68bd509..3666b69d1c678 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -126,6 +126,13 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>, "the trait cannot require that `Self : Sized`"); } + ObjectSafetyViolation::SupertraitSelf => { + tcx.sess.span_note( + span, + "the trait cannot use `Self` as a type parameter \ + in the supertrait listing"); + } + ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => { tcx.sess.span_note( span, diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index d124282d39128..2601c4d275291 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -10,21 +10,22 @@ use astconv::AstConv; use check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck}; +use constrained_type_params::identify_constrained_type_params; use CrateCtxt; use middle::region; -use middle::subst; +use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace}; use middle::traits; use middle::ty::{self, Ty}; use middle::ty::liberate_late_bound_regions; use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty}; -use util::ppaux::Repr; +use util::ppaux::{Repr, UserString}; use std::collections::HashSet; use syntax::ast; use syntax::ast_util::{local_def}; use syntax::attr; use syntax::codemap::Span; -use syntax::parse::token; +use syntax::parse::token::{self, special_idents}; use syntax::visit; use syntax::visit::Visitor; @@ -38,6 +39,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() } } + fn tcx(&self) -> &ty::ctxt<'tcx> { + self.ccx.tcx + } + /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are /// well-formed, meaning that they do not require any constraints not declared in the struct /// definition itself. For example, this definition would be illegal: @@ -96,19 +101,29 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { ast::ItemConst(..) => { self.check_item_type(item); } - ast::ItemStruct(ref struct_def, _) => { - self.check_type_defn(item, |fcx| vec![struct_variant(fcx, &**struct_def)]); + ast::ItemStruct(ref struct_def, ref ast_generics) => { + self.check_type_defn(item, |fcx| { + vec![struct_variant(fcx, &**struct_def)] + }); + + self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemEnum(ref enum_def, _) => { - self.check_type_defn(item, |fcx| enum_variants(fcx, enum_def)); + ast::ItemEnum(ref enum_def, ref ast_generics) => { + self.check_type_defn(item, |fcx| { + enum_variants(fcx, enum_def) + }); + + self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(..) => { + ast::ItemTrait(_, ref ast_generics, _, _) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); reject_non_type_param_bounds( ccx.tcx, item.span, &trait_predicates); + self.check_variances(item, ast_generics, &trait_predicates, + self.tcx().lang_items.phantom_fn()); } _ => {} } @@ -276,6 +291,123 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { } }); } + + fn check_variances_for_type_defn(&self, + item: &ast::Item, + ast_generics: &ast::Generics) + { + let item_def_id = local_def(item.id); + let predicates = ty::lookup_predicates(self.tcx(), item_def_id); + self.check_variances(item, + ast_generics, + &predicates, + self.tcx().lang_items.phantom_data()); + } + + fn check_variances(&self, + item: &ast::Item, + ast_generics: &ast::Generics, + ty_predicates: &ty::GenericPredicates<'tcx>, + suggested_marker_id: Option) + { + let variance_lang_items = &[ + self.tcx().lang_items.phantom_fn(), + self.tcx().lang_items.phantom_data(), + ]; + + let item_def_id = local_def(item.id); + let is_lang_item = variance_lang_items.iter().any(|n| *n == Some(item_def_id)); + if is_lang_item { + return; + } + + let variances = ty::item_variances(self.tcx(), item_def_id); + + let mut constrained_parameters: HashSet<_> = + variances.types + .iter_enumerated() + .filter(|&(_, _, &variance)| variance != ty::Bivariant) + .map(|(space, index, _)| self.param_ty(ast_generics, space, index)) + .collect(); + + identify_constrained_type_params(self.tcx(), + ty_predicates.predicates.as_slice(), + None, + &mut constrained_parameters); + + for (space, index, _) in variances.types.iter_enumerated() { + let param_ty = self.param_ty(ast_generics, space, index); + if constrained_parameters.contains(¶m_ty) { + continue; + } + let span = self.ty_param_span(ast_generics, item, space, index); + self.report_bivariance(span, param_ty.name, suggested_marker_id); + } + + for (space, index, &variance) in variances.regions.iter_enumerated() { + if variance != ty::Bivariant { + continue; + } + + assert_eq!(space, TypeSpace); + let span = ast_generics.lifetimes[index].lifetime.span; + let name = ast_generics.lifetimes[index].lifetime.name; + self.report_bivariance(span, name, suggested_marker_id); + } + } + + fn param_ty(&self, + ast_generics: &ast::Generics, + space: ParamSpace, + index: usize) + -> ty::ParamTy + { + let name = match space { + TypeSpace => ast_generics.ty_params[index].ident.name, + SelfSpace => special_idents::type_self.name, + FnSpace => self.tcx().sess.bug("Fn space occupied?"), + }; + + ty::ParamTy { space: space, idx: index as u32, name: name } + } + + fn ty_param_span(&self, + ast_generics: &ast::Generics, + item: &ast::Item, + space: ParamSpace, + index: usize) + -> Span + { + match space { + TypeSpace => ast_generics.ty_params[index].span, + SelfSpace => item.span, + FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"), + } + } + + fn report_bivariance(&self, + span: Span, + param_name: ast::Name, + suggested_marker_id: Option) + { + self.tcx().sess.span_err( + span, + &format!("parameter `{}` is never used", + param_name.user_string(self.tcx()))[]); + + match suggested_marker_id { + Some(def_id) => { + self.tcx().sess.span_help( + span, + format!("consider removing `{}` or using a marker such as `{}`", + param_name.user_string(self.tcx()), + ty::item_path_str(self.tcx(), def_id)).as_slice()); + } + None => { + // no lang items, no help! + } + } + } } // Reject any predicates that do not involve a type parameter. @@ -343,9 +475,9 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { match fk { visit::FkFnBlock | visit::FkItemFn(..) => {} visit::FkMethod(..) => { - match ty::impl_or_trait_item(self.ccx.tcx, local_def(id)) { + match ty::impl_or_trait_item(self.tcx(), local_def(id)) { ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { - reject_shadowing_type_parameters(self.ccx.tcx, span, &ty_method.generics) + reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics) } _ => {} } @@ -359,14 +491,14 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { &ast::TraitItem::ProvidedMethod(_) | &ast::TraitItem::TypeTraitItem(_) => {}, &ast::TraitItem::RequiredMethod(ref method) => { - match ty::impl_or_trait_item(self.ccx.tcx, local_def(method.id)) { + match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) { ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { reject_non_type_param_bounds( - self.ccx.tcx, + self.tcx(), method.span, &ty_method.predicates); reject_shadowing_type_parameters( - self.ccx.tcx, + self.tcx(), method.span, &ty_method.generics); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 44e850a073800..0b78af18e2617 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -87,6 +87,7 @@ There are some shortcomings in this design: use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region}; use middle::def; +use constrained_type_params::identify_constrained_type_params; use middle::lang_items::SizedTraitLangItem; use middle::region; use middle::resolve_lifetime; @@ -268,7 +269,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, ast::TupleVariantKind(ref args) if args.len() > 0 => { let rs = ExplicitRscope; let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, &*va.ty)).collect(); - ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[], enum_scheme.ty) + ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[..], enum_scheme.ty) } ast::TupleVariantKind(_) => { @@ -313,7 +314,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, trait_id, &trait_def.generics, &trait_predicates, - &trait_items[], + &trait_items[..], &m.id, &m.ident.name, &m.explicit_self, @@ -328,7 +329,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, trait_id, &trait_def.generics, &trait_predicates, - &trait_items[], + &trait_items[..], &m.id, &m.pe_ident().name, m.pe_explicit_self(), @@ -871,7 +872,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, local_def(field.node.id)].ty).collect(); let ctor_fn_ty = ty::mk_ctor_fn(tcx, local_def(ctor_id), - &inputs[], + &inputs[..], selfty); write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty); tcx.tcache.borrow_mut().insert(local_def(ctor_id), @@ -1358,7 +1359,7 @@ fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics); ty_generics(ccx, subst::FnSpace, - &early_lifetimes[], + &early_lifetimes[..], &generics.ty_params[], &generics.where_clause, base_generics) @@ -1960,51 +1961,15 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, let mut input_parameters: HashSet<_> = impl_trait_ref.iter() .flat_map(|t| t.input_types().iter()) // Types in trait ref, if any - .chain(Some(impl_scheme.ty).iter()) // Self type, always + .chain(Some(impl_scheme.ty).iter()) // Self type, always .flat_map(|t| t.walk()) - .filter_map(to_opt_param_ty) + .filter_map(|t| t.as_opt_param_ty()) .collect(); - loop { - let num_inputs = input_parameters.len(); - - let projection_predicates = - impl_predicates.predicates - .iter() - .filter_map(|predicate| { - match *predicate { - // Ignore higher-ranked binders. For the purposes - // of this check, they don't matter because they - // only affect named regions, and we're just - // concerned about type parameters here. - ty::Predicate::Projection(ref data) => Some(data.0.clone()), - _ => None, - } - }); - - for projection in projection_predicates { - // Special case: watch out for some kind of sneaky attempt - // to project out an associated type defined by this very trait. - if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref { - continue; - } - - let relies_only_on_inputs = - projection.projection_ty.trait_ref.input_types().iter() - .flat_map(|t| t.walk()) - .filter_map(to_opt_param_ty) - .all(|t| input_parameters.contains(&t)); - - if relies_only_on_inputs { - input_parameters.extend( - projection.ty.walk().filter_map(to_opt_param_ty)); - } - } - - if input_parameters.len() == num_inputs { - break; - } - } + identify_constrained_type_params(tcx, + impl_predicates.predicates.as_slice(), + impl_trait_ref, + &mut input_parameters); for (index, ty_param) in ast_generics.ty_params.iter().enumerate() { let param_ty = ty::ParamTy { space: TypeSpace, @@ -2025,11 +1990,4 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, } } } - - fn to_opt_param_ty<'tcx>(ty: Ty<'tcx>) -> Option { - match ty.sty { - ty::ty_param(ref d) => Some(d.clone()), - _ => None, - } - } } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs new file mode 100644 index 0000000000000..83d7e98500007 --- /dev/null +++ b/src/librustc_typeck/constrained_type_params.rs @@ -0,0 +1,61 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use middle::ty::{self}; + +use std::collections::HashSet; +use std::rc::Rc; + +pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>, + predicates: &[ty::Predicate<'tcx>], + impl_trait_ref: Option>>, + input_parameters: &mut HashSet) +{ + loop { + let num_inputs = input_parameters.len(); + + let projection_predicates = + predicates.iter() + .filter_map(|predicate| { + match *predicate { + // Ignore higher-ranked binders. For the purposes + // of this check, they don't matter because they + // only affect named regions, and we're just + // concerned about type parameters here. + ty::Predicate::Projection(ref data) => Some(data.0.clone()), + _ => None, + } + }); + + for projection in projection_predicates { + // Special case: watch out for some kind of sneaky attempt + // to project out an associated type defined by this very trait. + if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref { + continue; + } + + let relies_only_on_inputs = + projection.projection_ty.trait_ref.input_types() + .iter() + .flat_map(|t| t.walk()) + .filter_map(|t| t.as_opt_param_ty()) + .all(|t| input_parameters.contains(&t)); + + if relies_only_on_inputs { + input_parameters.extend( + projection.ty.walk().filter_map(|t| t.as_opt_param_ty())); + } + } + + if input_parameters.len() == num_inputs { + break; + } + } +} diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 7498dc8179d75..b5dca0bd4f6f4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -123,6 +123,7 @@ mod check; mod rscope; mod astconv; mod collect; +mod constrained_type_params; mod coherence; mod variance; diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index d5883d8bf864b..1adcf133bf3e0 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -187,6 +187,22 @@ //! and the definition-site variance of the [corresponding] type parameter //! of a class `C` is `V1`, then the variance of `X` in the type expression //! `C` is `V3 = V1.xform(V2)`. +//! +//! ### Constraints +//! +//! If I have a struct or enum with where clauses: +//! +//! struct Foo { ... } +//! +//! you might wonder whether the variance of `T` with respect to `Bar` +//! affects the variance `T` with respect to `Foo`. I claim no. The +//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t +//! `Foo`. And then we have a `Foo` that is upcast to `Foo`, where +//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold. In that +//! case, the upcast will be illegal, but not because of a variance +//! failure, but rather because the target type `Foo` is itself just +//! not well-formed. Basically we get to assume well-formedness of all +//! types involved before considering variance. use self::VarianceTerm::*; use self::ParamKind::*; @@ -199,7 +215,6 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace} use middle::ty::{self, Ty}; use std::fmt; use std::rc::Rc; -use std::iter::repeat; use syntax::ast; use syntax::ast_map; use syntax::ast_util; @@ -258,6 +273,11 @@ struct TermsContext<'a, 'tcx: 'a> { empty_variances: Rc, + // For marker types, UnsafeCell, and other lang items where + // variance is hardcoded, records the item-id and the hardcoded + // variance. + lang_items: Vec<(ast::NodeId, Vec)>, + // Maps from the node id of a type/generic parameter to the // corresponding inferred index. inferred_map: NodeMap, @@ -269,7 +289,7 @@ struct TermsContext<'a, 'tcx: 'a> { #[derive(Copy, Debug, PartialEq)] enum ParamKind { TypeParam, - RegionParam + RegionParam, } struct InferredInfo<'a> { @@ -279,6 +299,11 @@ struct InferredInfo<'a> { index: uint, param_id: ast::NodeId, term: VarianceTermPtr<'a>, + + // Initial value to use for this parameter when inferring + // variance. For most parameters, this is Bivariant. But for lang + // items and input type parameters on traits, it is different. + initial_variance: ty::Variance, } fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, @@ -291,6 +316,8 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, inferred_map: NodeMap(), inferred_infos: Vec::new(), + lang_items: lang_items(tcx), + // cache and share the variance struct used for items with // no type/region parameters empty_variances: Rc::new(ty::ItemVariances { @@ -304,7 +331,78 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, terms_cx } +fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec)> { + let all = vec![ + (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]), + (tcx.lang_items.phantom_data(), vec![ty::Covariant]), + (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]), + + // Deprecated: + (tcx.lang_items.covariant_type(), vec![ty::Covariant]), + (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]), + (tcx.lang_items.invariant_type(), vec![ty::Invariant]), + (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]), + (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]), + (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]), + + ]; + + all.into_iter() + .filter(|&(ref d,_)| d.is_some()) + .filter(|&(ref d,_)| d.as_ref().unwrap().krate == ast::LOCAL_CRATE) + .map(|(d, v)| (d.unwrap().node, v)) + .collect() +} + impl<'a, 'tcx> TermsContext<'a, 'tcx> { + fn add_inferreds_for_item(&mut self, + item_id: ast::NodeId, + has_self: bool, + generics: &ast::Generics) + { + /*! + * Add "inferreds" for the generic parameters declared on this + * item. This has a lot of annoying parameters because we are + * trying to drive this from the AST, rather than the + * ty::Generics, so that we can get span info -- but this + * means we must accommodate syntactic distinctions. + */ + + // NB: In the code below for writing the results back into the + // tcx, we rely on the fact that all inferreds for a particular + // item are assigned continuous indices. + + let inferreds_on_entry = self.num_inferred(); + + if has_self { + self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id); + } + + for (i, p) in generics.lifetimes.iter().enumerate() { + let id = p.lifetime.id; + self.add_inferred(item_id, RegionParam, TypeSpace, i, id); + } + + for (i, p) in generics.ty_params.iter().enumerate() { + self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id); + } + + // If this item has no type or lifetime parameters, + // then there are no variances to infer, so just + // insert an empty entry into the variance map. + // Arguably we could just leave the map empty in this + // case but it seems cleaner to be able to distinguish + // "invalid item id" from "item id with no + // parameters". + if self.num_inferred() == inferreds_on_entry { + let newly_added = + self.tcx.item_variance_map.borrow_mut().insert( + ast_util::local_def(item_id), + self.empty_variances.clone()).is_none(); + assert!(newly_added); + } + } + fn add_inferred(&mut self, item_id: ast::NodeId, kind: ParamKind, @@ -313,21 +411,48 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { param_id: ast::NodeId) { let inf_index = InferredIndex(self.inferred_infos.len()); let term = self.arena.alloc(InferredTerm(inf_index)); + let initial_variance = self.pick_initial_variance(item_id, space, index); self.inferred_infos.push(InferredInfo { item_id: item_id, kind: kind, space: space, index: index, param_id: param_id, - term: term }); + term: term, + initial_variance: initial_variance }); let newly_added = self.inferred_map.insert(param_id, inf_index).is_none(); assert!(newly_added); - debug!("add_inferred(item_id={}, \ + debug!("add_inferred(item_path={}, \ + item_id={}, \ kind={:?}, \ + space={:?}, \ index={}, \ - param_id={}, - inf_index={:?})", - item_id, kind, index, param_id, inf_index); + param_id={}, \ + inf_index={:?}, \ + initial_variance={:?})", + ty::item_path_str(self.tcx, ast_util::local_def(item_id)), + item_id, kind, space, index, param_id, inf_index, + initial_variance); + } + + fn pick_initial_variance(&self, + item_id: ast::NodeId, + space: ParamSpace, + index: uint) + -> ty::Variance + { + match space { + SelfSpace | FnSpace => { + ty::Bivariant + } + + TypeSpace => { + match self.lang_items.iter().find(|&&(n, _)| n == item_id) { + Some(&(_, ref variances)) => variances[index], + None => ty::Bivariant + } + } + } } fn num_inferred(&self) -> uint { @@ -339,44 +464,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { fn visit_item(&mut self, item: &ast::Item) { debug!("add_inferreds for item {}", item.repr(self.tcx)); - let inferreds_on_entry = self.num_inferred(); - - // NB: In the code below for writing the results back into the - // tcx, we rely on the fact that all inferreds for a particular - // item are assigned continuous indices. - match item.node { - ast::ItemTrait(..) => { - self.add_inferred(item.id, TypeParam, SelfSpace, 0, item.id); - } - _ => { } - } - match item.node { ast::ItemEnum(_, ref generics) | - ast::ItemStruct(_, ref generics) | + ast::ItemStruct(_, ref generics) => { + self.add_inferreds_for_item(item.id, false, generics); + } ast::ItemTrait(_, ref generics, _, _) => { - for (i, p) in generics.lifetimes.iter().enumerate() { - let id = p.lifetime.id; - self.add_inferred(item.id, RegionParam, TypeSpace, i, id); - } - for (i, p) in generics.ty_params.iter().enumerate() { - self.add_inferred(item.id, TypeParam, TypeSpace, i, p.id); - } - - // If this item has no type or lifetime parameters, - // then there are no variances to infer, so just - // insert an empty entry into the variance map. - // Arguably we could just leave the map empty in this - // case but it seems cleaner to be able to distinguish - // "invalid item id" from "item id with no - // parameters". - if self.num_inferred() == inferreds_on_entry { - let newly_added = self.tcx.item_variance_map.borrow_mut().insert( - ast_util::local_def(item.id), - self.empty_variances.clone()).is_none(); - assert!(newly_added); - } - + self.add_inferreds_for_item(item.id, true, generics); visit::walk_item(self, item); } @@ -404,16 +498,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { struct ConstraintContext<'a, 'tcx: 'a> { terms_cx: TermsContext<'a, 'tcx>, - // These are the def-id of the std::marker::InvariantType, - // std::marker::InvariantLifetime, and so on. The arrays - // are indexed by the `ParamKind` (type, lifetime, self). Note - // that there are no marker types for self, so the entries for - // self are always None. - invariant_lang_items: [Option; 2], - covariant_lang_items: [Option; 2], - contravariant_lang_items: [Option; 2], - unsafe_cell_lang_item: Option, - // These are pointers to common `ConstantTerm` instances covariant: VarianceTermPtr<'a>, contravariant: VarianceTermPtr<'a>, @@ -433,40 +517,14 @@ struct Constraint<'a> { fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>, krate: &ast::Crate) - -> ConstraintContext<'a, 'tcx> { - let mut invariant_lang_items = [None; 2]; - let mut covariant_lang_items = [None; 2]; - let mut contravariant_lang_items = [None; 2]; - - covariant_lang_items[TypeParam as uint] = - terms_cx.tcx.lang_items.covariant_type(); - covariant_lang_items[RegionParam as uint] = - terms_cx.tcx.lang_items.covariant_lifetime(); - - contravariant_lang_items[TypeParam as uint] = - terms_cx.tcx.lang_items.contravariant_type(); - contravariant_lang_items[RegionParam as uint] = - terms_cx.tcx.lang_items.contravariant_lifetime(); - - invariant_lang_items[TypeParam as uint] = - terms_cx.tcx.lang_items.invariant_type(); - invariant_lang_items[RegionParam as uint] = - terms_cx.tcx.lang_items.invariant_lifetime(); - - let unsafe_cell_lang_item = terms_cx.tcx.lang_items.unsafe_cell_type(); - + -> ConstraintContext<'a, 'tcx> +{ let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant)); let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant)); let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant)); let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant)); let mut constraint_cx = ConstraintContext { terms_cx: terms_cx, - - invariant_lang_items: invariant_lang_items, - covariant_lang_items: covariant_lang_items, - contravariant_lang_items: contravariant_lang_items, - unsafe_cell_lang_item: unsafe_cell_lang_item, - covariant: covariant, contravariant: contravariant, invariant: invariant, @@ -487,7 +545,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { match item.node { ast::ItemEnum(ref enum_definition, _) => { - let generics = &ty::lookup_item_type(tcx, did).generics; + let scheme = ty::lookup_item_type(tcx, did); + + // Not entirely obvious: constraints on structs/enums do not + // affect the variance of their type parameters. See discussion + // in comment at top of module. + // + // self.add_constraints_from_generics(&scheme.generics); // Hack: If we directly call `ty::enum_variants`, it // annoyingly takes it upon itself to run off and @@ -505,29 +569,48 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { &**ast_variant, /*discriminant*/ 0); for arg_ty in &variant.args { - self.add_constraints_from_ty(generics, *arg_ty, self.covariant); + self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.covariant); } } } ast::ItemStruct(..) => { - let generics = &ty::lookup_item_type(tcx, did).generics; + let scheme = ty::lookup_item_type(tcx, did); + + // Not entirely obvious: constraints on structs/enums do not + // affect the variance of their type parameters. See discussion + // in comment at top of module. + // + // self.add_constraints_from_generics(&scheme.generics); + let struct_fields = ty::lookup_struct_fields(tcx, did); for field_info in &struct_fields { assert_eq!(field_info.id.krate, ast::LOCAL_CRATE); let field_ty = ty::node_id_to_type(tcx, field_info.id.node); - self.add_constraints_from_ty(generics, field_ty, self.covariant); + self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant); } } ast::ItemTrait(..) => { + let trait_def = ty::lookup_trait_def(tcx, did); + let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds); + self.add_constraints_from_predicates(&trait_def.generics, + &predicates[], + self.covariant); + let trait_items = ty::trait_items(tcx, did); for trait_item in &*trait_items { match *trait_item { ty::MethodTraitItem(ref method) => { - self.add_constraints_from_sig(&method.generics, - &method.fty.sig, - self.covariant); + self.add_constraints_from_predicates( + &method.generics, + method.predicates.predicates.get_slice(FnSpace), + self.contravariant); + + self.add_constraints_from_sig( + &method.generics, + &method.fty.sig, + self.covariant); } ty::TypeTraitItem(_) => {} } @@ -544,9 +627,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { ast::ItemTy(..) | ast::ItemImpl(..) | ast::ItemMac(..) => { - visit::walk_item(self, item); } } + + visit::walk_item(self, item); } } @@ -648,15 +732,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { -> VarianceTermPtr<'a> { assert_eq!(param_def_id.krate, item_def_id.krate); - if self.invariant_lang_items[kind as uint] == Some(item_def_id) { - self.invariant - } else if self.covariant_lang_items[kind as uint] == Some(item_def_id) { - self.covariant - } else if self.contravariant_lang_items[kind as uint] == Some(item_def_id) { - self.contravariant - } else if kind == TypeParam && Some(item_def_id) == self.unsafe_cell_lang_item { - self.invariant - } else if param_def_id.krate == ast::LOCAL_CRATE { + if param_def_id.krate == ast::LOCAL_CRATE { // Parameter on an item defined within current crate: // variance not yet inferred, so return a symbolic // variance. @@ -724,6 +800,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } } + fn add_constraints_from_trait_ref(&mut self, + generics: &ty::Generics<'tcx>, + trait_ref: &ty::TraitRef<'tcx>, + variance: VarianceTermPtr<'a>) { + debug!("add_constraints_from_trait_ref: trait_ref={} variance={:?}", + trait_ref.repr(self.tcx()), + variance); + + let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id); + + self.add_constraints_from_substs( + generics, + trait_ref.def_id, + trait_def.generics.types.as_slice(), + trait_def.generics.regions.as_slice(), + trait_ref.substs, + variance); + } + /// Adds constraints appropriate for an instance of `ty` appearing /// in a context with the generics defined in `generics` and /// ambient variance `variance` @@ -731,7 +826,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { generics: &ty::Generics<'tcx>, ty: Ty<'tcx>, variance: VarianceTermPtr<'a>) { - debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx())); + debug!("add_constraints_from_ty(ty={}, variance={:?})", + ty.repr(self.tcx()), + variance); match ty.sty { ty::ty_bool | @@ -754,6 +851,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_ty(generics, typ, variance); } + ty::ty_ptr(ref mt) => { self.add_constraints_from_mt(generics, mt, variance); } @@ -797,27 +895,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::ty_trait(ref data) => { - let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(), - self.tcx().types.err); - let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id()); - - // Traits never declare region parameters in the self - // space nor anything in the fn space. - assert!(trait_def.generics.regions.is_empty_in(subst::SelfSpace)); - assert!(trait_def.generics.types.is_empty_in(subst::FnSpace)); - assert!(trait_def.generics.regions.is_empty_in(subst::FnSpace)); + let poly_trait_ref = + data.principal_trait_ref_with_self_ty(self.tcx(), + self.tcx().types.err); // The type `Foo` is contravariant w/r/t `'a`: let contra = self.contravariant(variance); self.add_constraints_from_region(generics, data.bounds.region_bound, contra); - self.add_constraints_from_substs( - generics, - trait_ref.def_id(), - trait_def.generics.types.get_slice(subst::TypeSpace), - trait_def.generics.regions.get_slice(subst::TypeSpace), - trait_ref.substs(), - variance); + // Ignore the SelfSpace, it is erased. + self.add_constraints_from_trait_ref(generics, &*poly_trait_ref.0, variance); let projections = data.projection_bounds_with_self_ty(self.tcx(), self.tcx().types.err); @@ -845,7 +932,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_sig(generics, sig, variance); } - ty::ty_infer(..) | ty::ty_err => { + ty::ty_err => { + // we encounter this when walking the trait references for object + // types, where we use ty_err as the Self type + } + + ty::ty_infer(..) => { self.tcx().sess.bug( &format!("unexpected type encountered in \ variance inference: {}", @@ -864,7 +956,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { region_param_defs: &[ty::RegionParameterDef], substs: &subst::Substs<'tcx>, variance: VarianceTermPtr<'a>) { - debug!("add_constraints_from_substs(def_id={:?})", def_id); + debug!("add_constraints_from_substs(def_id={}, substs={}, variance={:?})", + def_id.repr(self.tcx()), + substs.repr(self.tcx()), + variance); for p in type_param_defs { let variance_decl = @@ -872,6 +967,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { p.space, p.index as uint); let variance_i = self.xform(variance, variance_decl); let substs_ty = *substs.types.get(p.space, p.index as uint); + debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}", + variance_decl, variance_i); self.add_constraints_from_ty(generics, substs_ty, variance_i); } @@ -885,6 +982,51 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } } + fn add_constraints_from_predicates(&mut self, + generics: &ty::Generics<'tcx>, + predicates: &[ty::Predicate<'tcx>], + variance: VarianceTermPtr<'a>) { + debug!("add_constraints_from_generics({})", + generics.repr(self.tcx())); + + for predicate in predicates.iter() { + match *predicate { + ty::Predicate::Trait(ty::Binder(ref data)) => { + self.add_constraints_from_trait_ref(generics, &*data.trait_ref, variance); + } + + ty::Predicate::Equate(ty::Binder(ref data)) => { + self.add_constraints_from_ty(generics, data.0, variance); + self.add_constraints_from_ty(generics, data.1, variance); + } + + ty::Predicate::TypeOutlives(ty::Binder(ref data)) => { + self.add_constraints_from_ty(generics, data.0, variance); + + let variance_r = self.xform(variance, self.contravariant); + self.add_constraints_from_region(generics, data.1, variance_r); + } + + ty::Predicate::RegionOutlives(ty::Binder(ref data)) => { + // `'a : 'b` is still true if 'a gets bigger + self.add_constraints_from_region(generics, data.0, variance); + + // `'a : 'b` is still true if 'b gets smaller + let variance_r = self.xform(variance, self.contravariant); + self.add_constraints_from_region(generics, data.1, variance_r); + } + + ty::Predicate::Projection(ty::Binder(ref data)) => { + self.add_constraints_from_trait_ref(generics, + &*data.projection_ty.trait_ref, + variance); + + self.add_constraints_from_ty(generics, data.ty, self.invariant); + } + } + } + } + /// Adds constraints appropriate for a function with signature /// `sig` appearing in a context with ambient variance `variance` fn add_constraints_from_sig(&mut self, @@ -969,7 +1111,12 @@ struct SolveContext<'a, 'tcx: 'a> { fn solve_constraints(constraints_cx: ConstraintContext) { let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; - let solutions: Vec<_> = repeat(ty::Bivariant).take(terms_cx.num_inferred()).collect(); + + let solutions = + terms_cx.inferred_infos.iter() + .map(|ii| ii.initial_variance) + .collect(); + let mut solutions_cx = SolveContext { terms_cx: terms_cx, constraints: constraints, @@ -1034,20 +1181,16 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { let mut types = VecPerParamSpace::empty(); let mut regions = VecPerParamSpace::empty(); - while index < num_inferred && - inferred_infos[index].item_id == item_id { + while index < num_inferred && inferred_infos[index].item_id == item_id { let info = &inferred_infos[index]; let variance = solutions[index]; debug!("Index {} Info {} / {:?} / {:?} Variance {:?}", index, info.index, info.kind, info.space, variance); match info.kind { - TypeParam => { - types.push(info.space, variance); - } - RegionParam => { - regions.push(info.space, variance); - } + TypeParam => { types.push(info.space, variance); } + RegionParam => { regions.push(info.space, variance); } } + index += 1; } @@ -1065,7 +1208,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { // attribute and report an error with various results if found. if ty::has_attr(tcx, item_def_id, "rustc_variance") { let found = item_variances.repr(tcx); - span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[]); + span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[..]); } let newly_added = tcx.item_variance_map.borrow_mut() @@ -1144,3 +1287,4 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance { (x, ty::Bivariant) | (ty::Bivariant, x) => x, } } + diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index a7cf5eb89187f..ad91c3cb2c35b 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -112,7 +112,7 @@ mod imp { impl Lock { pub fn new(p: &Path) -> Lock { - let buf = CString::from_slice(p.as_vec()); + let buf = CString::new(p.as_vec()).unwrap(); let fd = unsafe { libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT, libc::S_IRWXU) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 6acd15379461c..44c0acda66fba 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -34,7 +34,7 @@ pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String { class, id, &mut out).unwrap(); - String::from_utf8_lossy(&out[]).into_owned() + String::from_utf8_lossy(&out[..]).into_owned() } /// Exhausts the `lexer` writing the output into `out`. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c513fe2e8eb3c..7ea5bd569e199 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -236,7 +236,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { s.push_str(&highlight::highlight(&text, None, Some("rust-example-rendered"))); - let output = CString::from_vec(s.into_bytes()); + let output = CString::new(s).unwrap(); hoedown_buffer_puts(ob, output.as_ptr()); }) } @@ -293,7 +293,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { format!("{} ", sec) }); - let text = CString::from_vec(text.into_bytes()); + let text = CString::new(text).unwrap(); unsafe { hoedown_buffer_puts(ob, text.as_ptr()) } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 95994af7dc8de..fc3c87389917a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1404,8 +1404,7 @@ impl<'a> fmt::Display for Item<'a> { try!(write!(fmt, r##" - [-] -  [+] + [-] [+] "##)); // Write `src` tag diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index a4263badb0136..2f0755ecb898a 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -374,8 +374,8 @@ a { color: #000; background: transparent; } -p a { color: #4e8bca; } -p a:hover { text-decoration: underline; } +.docblock a { color: #4e8bca; } +.docblock a:hover { text-decoration: underline; } .content span.trait, .content a.trait, .block a.current.trait { color: #ed9603; } .content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bab734db12650..f9e0948d7bc8a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -23,7 +23,6 @@ #![feature(collections)] #![feature(core)] #![feature(env)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index abd73fcfb7028..722f14fa6d4c7 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -293,7 +293,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult { let mut a: Vec = i.attrs.iter().filter(|&a| match a { &clean::NameValue(ref x, _) if "doc" == *x => false, _ => true - }).map(|x| x.clone()).collect(); + }).cloned().collect(); if docstr.len() > 0 { a.push(clean::NameValue("doc".to_string(), docstr)); } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ac1a02854124a..c52b0bab1fa8b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -333,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { name: name, items: items.clone(), generics: gen.clone(), - bounds: b.iter().map(|x| (*x).clone()).collect(), + bounds: b.iter().cloned().collect(), id: item.id, attrs: item.attrs.clone(), whence: item.span, diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index f81edca837198..10cf02f85e818 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -12,16 +12,17 @@ use std::usize; use std::default::Default; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; +#[cfg(stage0)] use std::hash::Hasher; use std::collections::hash_state::HashState; use {Decodable, Encodable, Decoder, Encoder}; -use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; +use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; use collections::enum_set::{EnumSet, CLike}; impl< T: Encodable -> Encodable for DList { +> Encodable for LinkedList { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { @@ -32,10 +33,10 @@ impl< } } -impl Decodable for DList { - fn decode(d: &mut D) -> Result, D::Error> { +impl Decodable for LinkedList { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { - let mut list = DList::new(); + let mut list = LinkedList::new(); for i in 0..len { list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } @@ -44,7 +45,7 @@ impl Decodable for DList { } } -impl Encodable for RingBuf { +impl Encodable for VecDeque { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { @@ -55,10 +56,10 @@ impl Encodable for RingBuf { } } -impl Decodable for RingBuf { - fn decode(d: &mut D) -> Result, D::Error> { +impl Decodable for VecDeque { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { - let mut deque: RingBuf = RingBuf::new(); + let mut deque: VecDeque = VecDeque::new(); for i in 0..len { deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } @@ -157,6 +158,7 @@ impl< } } +#[cfg(stage0)] impl Encodable for HashMap where K: Encodable + Hash< ::Hasher> + Eq, V: Encodable, @@ -175,7 +177,26 @@ impl Encodable for HashMap }) } } +#[cfg(not(stage0))] +impl Encodable for HashMap + where K: Encodable + Hash + Eq, + V: Encodable, + S: HashState, +{ + fn encode(&self, e: &mut E) -> Result<(), E::Error> { + e.emit_map(self.len(), |e| { + let mut i = 0; + for (key, val) in self { + try!(e.emit_map_elt_key(i, |e| key.encode(e))); + try!(e.emit_map_elt_val(i, |e| val.encode(e))); + i += 1; + } + Ok(()) + }) + } +} +#[cfg(stage0)] impl Decodable for HashMap where K: Decodable + Hash< ::Hasher> + Eq, V: Decodable, @@ -195,7 +216,27 @@ impl Decodable for HashMap }) } } +#[cfg(not(stage0))] +impl Decodable for HashMap + where K: Decodable + Hash + Eq, + V: Decodable, + S: HashState + Default, +{ + fn decode(d: &mut D) -> Result, D::Error> { + d.read_map(|d, len| { + let state = Default::default(); + let mut map = HashMap::with_capacity_and_hash_state(len, state); + for i in 0..len { + let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); + let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); + map.insert(key, val); + } + Ok(map) + }) + } +} +#[cfg(stage0)] impl Encodable for HashSet where T: Encodable + Hash< ::Hasher> + Eq, S: HashState, @@ -212,7 +253,24 @@ impl Encodable for HashSet }) } } +#[cfg(not(stage0))] +impl Encodable for HashSet + where T: Encodable + Hash + Eq, + S: HashState, +{ + fn encode(&self, s: &mut E) -> Result<(), E::Error> { + s.emit_seq(self.len(), |s| { + let mut i = 0; + for e in self { + try!(s.emit_seq_elt(i, |s| e.encode(s))); + i += 1; + } + Ok(()) + }) + } +} +#[cfg(stage0)] impl Decodable for HashSet where T: Decodable + Hash< ::Hasher> + Eq, S: HashState + Default, @@ -229,6 +287,22 @@ impl Decodable for HashSet }) } } +#[cfg(not(stage0))] +impl Decodable for HashSet + where T: Decodable + Hash + Eq, + S: HashState + Default, +{ + fn decode(d: &mut D) -> Result, D::Error> { + d.read_seq(|d, len| { + let state = Default::default(); + let mut set = HashSet::with_capacity_and_hash_state(len, state); + for i in 0..len { + set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(set) + }) + } +} impl Encodable for VecMap { fn encode(&self, e: &mut S) -> Result<(), S::Error> { diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 68b28784b4254..a0f42815b4396 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1120,7 +1120,7 @@ impl Json { /// Returns None otherwise. pub fn as_string<'a>(&'a self) -> Option<&'a str> { match *self { - Json::String(ref s) => Some(&s[]), + Json::String(ref s) => Some(&s[..]), _ => None } } @@ -2237,7 +2237,7 @@ impl ::Decoder for Decoder { return Err(ExpectedError("String or Object".to_string(), format!("{}", json))) } }; - let idx = match names.iter().position(|n| *n == &name[]) { + let idx = match names.iter().position(|n| *n == &name[..]) { Some(idx) => idx, None => return Err(UnknownVariantError(name)) }; @@ -3461,7 +3461,7 @@ mod tests { hm.insert(1, true); let mut mem_buf = Vec::new(); write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); - let json_str = from_utf8(&mem_buf[]).unwrap(); + let json_str = from_utf8(&mem_buf[..]).unwrap(); match from_str(json_str) { Err(_) => panic!("Unable to parse json_str: {:?}", json_str), _ => {} // it parsed and we are good to go @@ -3477,7 +3477,7 @@ mod tests { hm.insert(1, true); let mut mem_buf = Vec::new(); write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); - let json_str = from_utf8(&mem_buf[]).unwrap(); + let json_str = from_utf8(&mem_buf[..]).unwrap(); match from_str(json_str) { Err(_) => panic!("Unable to parse json_str: {:?}", json_str), _ => {} // it parsed and we are good to go @@ -3517,7 +3517,7 @@ mod tests { write!(&mut writer, "{}", super::as_pretty_json(&json).indent(i)).unwrap(); - let printed = from_utf8(&writer[]).unwrap(); + let printed = from_utf8(&writer[..]).unwrap(); // Check for indents at each line let lines: Vec<&str> = printed.lines().collect(); @@ -3549,7 +3549,7 @@ mod tests { let mut map = HashMap::new(); map.insert(Enum::Foo, 0); let result = json::encode(&map).unwrap(); - assert_eq!(&result[], r#"{"Foo":0}"#); + assert_eq!(&result[..], r#"{"Foo":0}"#); let decoded: HashMap = json::decode(&result).unwrap(); assert_eq!(map, decoded); } diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 853da598ab5be..d476fd72abc3b 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -31,7 +31,6 @@ Core encoding and decoding interfaces. #![feature(int_uint)] #![feature(old_io)] #![feature(old_path)] -#![feature(hash)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 517907bcf58e3..70f0ba4bb23af 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -326,7 +326,7 @@ impl Encodable for str { impl Encodable for String { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(&self[]) + s.emit_str(&self[..]) } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 1b9f8b9901723..ade4f1f0533ee 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -14,12 +14,12 @@ use self::Entry::*; use self::SearchResult::*; use self::VacantEntryState::*; -use borrow::BorrowFrom; +use borrow::Borrow; use clone::Clone; use cmp::{max, Eq, PartialEq}; use default::Default; use fmt::{self, Debug}; -use hash::{self, Hash, SipHasher}; +use hash::{Hash, SipHasher}; use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map}; use marker::Sized; use mem::{self, replace}; @@ -440,12 +440,10 @@ impl SearchResult { } } -impl HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl HashMap + where K: Eq + Hash, S: HashState { - fn make_hash(&self, x: &X) -> SafeHash where X: Hash { + fn make_hash(&self, x: &X) -> SafeHash where X: Hash { table::make_hash(&self.hash_state, x) } @@ -453,18 +451,18 @@ impl HashMap /// If you already have the hash for the key lying around, use /// search_hashed. fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where K: Borrow, Q: Eq + Hash { let hash = self.make_hash(q); - search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + search_hashed(&self.table, hash, |k| q.eq(k.borrow())) .into_option() } fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where K: Borrow, Q: Eq + Hash { let hash = self.make_hash(q); - search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + search_hashed(&mut self.table, hash, |k| q.eq(k.borrow())) .into_option() } @@ -490,7 +488,7 @@ impl HashMap } } -impl + Eq, V> HashMap { +impl HashMap { /// Create an empty HashMap. /// /// # Example @@ -520,10 +518,8 @@ impl + Eq, V> HashMap { } } -impl HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl HashMap + where K: Eq + Hash, S: HashState { /// Creates an empty hashmap which will use the given hasher to hash keys. /// @@ -1037,7 +1033,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, k: &Q) -> Option<&V> - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search(k).map(|bucket| bucket.into_refs().1) } @@ -1060,7 +1056,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains_key(&self, k: &Q) -> bool - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search(k).is_some() } @@ -1086,7 +1082,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) } @@ -1138,7 +1134,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, k: &Q) -> Option - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { if self.table.size() == 0 { return None @@ -1195,10 +1191,8 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable, hash: SafeHas } } -impl PartialEq for HashMap - where K: Eq + Hash, V: PartialEq, - S: HashState, - H: hash::Hasher +impl PartialEq for HashMap + where K: Eq + Hash, V: PartialEq, S: HashState { fn eq(&self, other: &HashMap) -> bool { if self.len() != other.len() { return false; } @@ -1210,17 +1204,13 @@ impl PartialEq for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashMap - where K: Eq + Hash, V: Eq, - S: HashState, - H: hash::Hasher +impl Eq for HashMap + where K: Eq + Hash, V: Eq, S: HashState {} #[stable(feature = "rust1", since = "1.0.0")] -impl Debug for HashMap - where K: Eq + Hash + Debug, V: Debug, - S: HashState, - H: hash::Hasher +impl Debug for HashMap + where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "HashMap {{")); @@ -1235,10 +1225,9 @@ impl Debug for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for HashMap - where K: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl Default for HashMap + where K: Eq + Hash, + S: HashState + Default, { fn default() -> HashMap { HashMap::with_hash_state(Default::default()) @@ -1246,11 +1235,10 @@ impl Default for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Index for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, - S: HashState, - H: hash::Hasher +impl Index for HashMap + where K: Eq + Hash + Borrow, + Q: Eq + Hash, + S: HashState, { type Output = V; @@ -1261,11 +1249,10 @@ impl Index for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, - S: HashState, - H: hash::Hasher +impl IndexMut for HashMap + where K: Eq + Hash + Borrow, + Q: Eq + Hash, + S: HashState, { #[inline] fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V { @@ -1373,10 +1360,8 @@ enum VacantEntryState { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V, S, H> IntoIterator for &'a HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, K, V, S> IntoIterator for &'a HashMap + where K: Eq + Hash, S: HashState { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; @@ -1387,10 +1372,8 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, K, V, S> IntoIterator for &'a mut HashMap + where K: Eq + Hash, S: HashState { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; @@ -1401,10 +1384,8 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl IntoIterator for HashMap + where K: Eq + Hash, S: HashState { type Item = (K, V); type IntoIter = IntoIter; @@ -1550,12 +1531,11 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator<(K, V)> for HashMap - where K: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl FromIterator<(K, V)> for HashMap + where K: Eq + Hash, S: HashState + Default { - fn from_iter>(iter: T) -> HashMap { + fn from_iter>(iterable: T) -> HashMap { + let iter = iterable.into_iter(); let lower = iter.size_hint().0; let mut map = HashMap::with_capacity_and_hash_state(lower, Default::default()); @@ -1565,12 +1545,10 @@ impl FromIterator<(K, V)> for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend<(K, V)> for HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl Extend<(K, V)> for HashMap + where K: Eq + Hash, S: HashState { - fn extend>(&mut self, iter: T) { + fn extend>(&mut self, iter: T) { for (k, v) in iter { self.insert(k, v); } @@ -1606,9 +1584,9 @@ impl RandomState { #[unstable(feature = "std_misc", reason = "hashing an hash maps may be altered")] impl HashState for RandomState { - type Hasher = Hasher; - fn hasher(&self) -> Hasher { - Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) } + type Hasher = SipHasher; + fn hasher(&self) -> SipHasher { + SipHasher::new_with_keys(self.k0, self.k1) } } @@ -1621,25 +1599,6 @@ impl Default for RandomState { } } -/// A hasher implementation which is generated from `RandomState` instances. -/// -/// This is the default hasher used in a `HashMap` to hash keys. Types do not -/// typically declare an ability to explicitly hash into this particular type, -/// but rather in a `H: hash::Writer` type parameter. -#[unstable(feature = "std_misc", - reason = "hashing an hash maps may be altered")] -pub struct Hasher { inner: SipHasher } - -impl hash::Writer for Hasher { - fn write(&mut self, data: &[u8]) { self.inner.write(data) } -} - -impl hash::Hasher for Hasher { - type Output = u64; - fn reset(&mut self) { self.inner.reset() } - fn finish(&self) -> u64 { self.inner.finish() } -} - #[cfg(test)] mod test_map { use prelude::v1::*; diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs new file mode 100644 index 0000000000000..f9e5044c59761 --- /dev/null +++ b/src/libstd/collections/hash/map_stage0.rs @@ -0,0 +1,2330 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// ignore-lexer-test FIXME #15883 + +use self::Entry::*; +use self::SearchResult::*; +use self::VacantEntryState::*; + +use borrow::Borrow; +use clone::Clone; +use cmp::{max, Eq, PartialEq}; +use default::Default; +use fmt::{self, Debug}; +use hash::{self, Hash, SipHasher}; +use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map}; +use marker::Sized; +use mem::{self, replace}; +use num::{Int, UnsignedInt}; +use ops::{Deref, FnMut, Index, IndexMut}; +use option::Option::{self, Some, None}; +use rand::{self, Rng}; +use result::Result::{self, Ok, Err}; + +use super::table::{ + self, + Bucket, + EmptyBucket, + FullBucket, + FullBucketImm, + FullBucketMut, + RawTable, + SafeHash +}; +use super::table::BucketState::{ + Empty, + Full, +}; +use super::state::HashState; + +const INITIAL_LOG2_CAP: usize = 5; +#[unstable(feature = "std_misc")] +pub const INITIAL_CAPACITY: usize = 1 << INITIAL_LOG2_CAP; // 2^5 + +/// The default behavior of HashMap implements a load factor of 90.9%. +/// This behavior is characterized by the following condition: +/// +/// - if size > 0.909 * capacity: grow the map +#[derive(Clone)] +struct DefaultResizePolicy; + +impl DefaultResizePolicy { + fn new() -> DefaultResizePolicy { + DefaultResizePolicy + } + + #[inline] + fn min_capacity(&self, usable_size: usize) -> usize { + // Here, we are rephrasing the logic by specifying the lower limit + // on capacity: + // + // - if `cap < size * 1.1`: grow the map + usable_size * 11 / 10 + } + + /// An inverse of `min_capacity`, approximately. + #[inline] + fn usable_capacity(&self, cap: usize) -> usize { + // As the number of entries approaches usable capacity, + // min_capacity(size) must be smaller than the internal capacity, + // so that the map is not resized: + // `min_capacity(usable_capacity(x)) <= x`. + // The left-hand side can only be smaller due to flooring by integer + // division. + // + // This doesn't have to be checked for overflow since allocation size + // in bytes will overflow earlier than multiplication by 10. + cap * 10 / 11 + } +} + +#[test] +fn test_resize_policy() { + use prelude::v1::*; + let rp = DefaultResizePolicy; + for n in 0..1000 { + assert!(rp.min_capacity(rp.usable_capacity(n)) <= n); + assert!(rp.usable_capacity(rp.min_capacity(n)) <= n); + } +} + +// The main performance trick in this hashmap is called Robin Hood Hashing. +// It gains its excellent performance from one essential operation: +// +// If an insertion collides with an existing element, and that element's +// "probe distance" (how far away the element is from its ideal location) +// is higher than how far we've already probed, swap the elements. +// +// This massively lowers variance in probe distance, and allows us to get very +// high load factors with good performance. The 90% load factor I use is rather +// conservative. +// +// > Why a load factor of approximately 90%? +// +// In general, all the distances to initial buckets will converge on the mean. +// At a load factor of α, the odds of finding the target bucket after k +// probes is approximately 1-α^k. If we set this equal to 50% (since we converge +// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round +// this down to make the math easier on the CPU and avoid its FPU. +// Since on average we start the probing in the middle of a cache line, this +// strategy pulls in two cache lines of hashes on every lookup. I think that's +// pretty good, but if you want to trade off some space, it could go down to one +// cache line on average with an α of 0.84. +// +// > Wait, what? Where did you get 1-α^k from? +// +// On the first probe, your odds of a collision with an existing element is α. +// The odds of doing this twice in a row is approximately α^2. For three times, +// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT +// colliding after k tries is 1-α^k. +// +// The paper from 1986 cited below mentions an implementation which keeps track +// of the distance-to-initial-bucket histogram. This approach is not suitable +// for modern architectures because it requires maintaining an internal data +// structure. This allows very good first guesses, but we are most concerned +// with guessing entire cache lines, not individual indexes. Furthermore, array +// accesses are no longer linear and in one direction, as we have now. There +// is also memory and cache pressure that this would entail that would be very +// difficult to properly see in a microbenchmark. +// +// ## Future Improvements (FIXME!) +// +// Allow the load factor to be changed dynamically and/or at initialization. +// +// Also, would it be possible for us to reuse storage when growing the +// underlying table? This is exactly the use case for 'realloc', and may +// be worth exploring. +// +// ## Future Optimizations (FIXME!) +// +// Another possible design choice that I made without any real reason is +// parameterizing the raw table over keys and values. Technically, all we need +// is the size and alignment of keys and values, and the code should be just as +// efficient (well, we might need one for power-of-two size and one for not...). +// This has the potential to reduce code bloat in rust executables, without +// really losing anything except 4 words (key size, key alignment, val size, +// val alignment) which can be passed in to every call of a `RawTable` function. +// This would definitely be an avenue worth exploring if people start complaining +// about the size of rust executables. +// +// Annotate exceedingly likely branches in `table::make_hash` +// and `search_hashed` to reduce instruction cache pressure +// and mispredictions once it becomes possible (blocked on issue #11092). +// +// Shrinking the table could simply reallocate in place after moving buckets +// to the first half. +// +// The growth algorithm (fragment of the Proof of Correctness) +// -------------------- +// +// The growth algorithm is basically a fast path of the naive reinsertion- +// during-resize algorithm. Other paths should never be taken. +// +// Consider growing a robin hood hashtable of capacity n. Normally, we do this +// by allocating a new table of capacity `2n`, and then individually reinsert +// each element in the old table into the new one. This guarantees that the +// new table is a valid robin hood hashtable with all the desired statistical +// properties. Remark that the order we reinsert the elements in should not +// matter. For simplicity and efficiency, we will consider only linear +// reinsertions, which consist of reinserting all elements in the old table +// into the new one by increasing order of index. However we will not be +// starting our reinsertions from index 0 in general. If we start from index +// i, for the purpose of reinsertion we will consider all elements with real +// index j < i to have virtual index n + j. +// +// Our hash generation scheme consists of generating a 64-bit hash and +// truncating the most significant bits. When moving to the new table, we +// simply introduce a new bit to the front of the hash. Therefore, if an +// elements has ideal index i in the old table, it can have one of two ideal +// locations in the new table. If the new bit is 0, then the new ideal index +// is i. If the new bit is 1, then the new ideal index is n + i. Intuitively, +// we are producing two independent tables of size n, and for each element we +// independently choose which table to insert it into with equal probability. +// However the rather than wrapping around themselves on overflowing their +// indexes, the first table overflows into the first, and the first into the +// second. Visually, our new table will look something like: +// +// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy] +// +// Where x's are elements inserted into the first table, y's are elements +// inserted into the second, and _'s are empty sections. We now define a few +// key concepts that we will use later. Note that this is a very abstract +// perspective of the table. A real resized table would be at least half +// empty. +// +// Theorem: A linear robin hood reinsertion from the first ideal element +// produces identical results to a linear naive reinsertion from the same +// element. +// +// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs + +/// A hash map implementation which uses linear probing with Robin +/// Hood bucket stealing. +/// +/// The hashes are all keyed by the task-local random number generator +/// on creation by default. This means that the ordering of the keys is +/// randomized, but makes the tables more resistant to +/// denial-of-service attacks (Hash DoS). This behaviour can be +/// overridden with one of the constructors. +/// +/// It is required that the keys implement the `Eq` and `Hash` traits, although +/// this can frequently be achieved by using `#[derive(Eq, Hash)]`. +/// +/// Relevant papers/articles: +/// +/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf) +/// 2. Emmanuel Goossaert. ["Robin Hood +/// hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/) +/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift +/// deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/) +/// +/// # Example +/// +/// ``` +/// use std::collections::HashMap; +/// +/// // type inference lets us omit an explicit type signature (which +/// // would be `HashMap<&str, &str>` in this example). +/// let mut book_reviews = HashMap::new(); +/// +/// // review some books. +/// book_reviews.insert("Adventures of Huckleberry Finn", "My favorite book."); +/// book_reviews.insert("Grimms' Fairy Tales", "Masterpiece."); +/// book_reviews.insert("Pride and Prejudice", "Very enjoyable."); +/// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot."); +/// +/// // check for a specific one. +/// if !book_reviews.contains_key(&("Les Misérables")) { +/// println!("We've got {} reviews, but Les Misérables ain't one.", +/// book_reviews.len()); +/// } +/// +/// // oops, this review has a lot of spelling mistakes, let's delete it. +/// book_reviews.remove(&("The Adventures of Sherlock Holmes")); +/// +/// // look up the values associated with some keys. +/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; +/// for book in to_find.iter() { +/// match book_reviews.get(book) { +/// Some(review) => println!("{}: {}", *book, *review), +/// None => println!("{} is unreviewed.", *book) +/// } +/// } +/// +/// // iterate over everything. +/// for (book, review) in book_reviews.iter() { +/// println!("{}: \"{}\"", *book, *review); +/// } +/// ``` +/// +/// The easiest way to use `HashMap` with a custom type as key is to derive `Eq` and `Hash`. +/// We must also derive `PartialEq`. +/// +/// ``` +/// use std::collections::HashMap; +/// +/// #[derive(Hash, Eq, PartialEq, Debug)] +/// struct Viking { +/// name: String, +/// country: String, +/// } +/// +/// impl Viking { +/// /// Create a new Viking. +/// fn new(name: &str, country: &str) -> Viking { +/// Viking { name: name.to_string(), country: country.to_string() } +/// } +/// } +/// +/// // Use a HashMap to store the vikings' health points. +/// let mut vikings = HashMap::new(); +/// +/// vikings.insert(Viking::new("Einar", "Norway"), 25); +/// vikings.insert(Viking::new("Olaf", "Denmark"), 24); +/// vikings.insert(Viking::new("Harald", "Iceland"), 12); +/// +/// // Use derived implementation to print the status of the vikings. +/// for (viking, health) in vikings.iter() { +/// println!("{:?} has {} hp", viking, health); +/// } +/// ``` +#[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct HashMap { + // All hashes are keyed on these values, to prevent hash collision attacks. + hash_state: S, + + table: RawTable, + + resize_policy: DefaultResizePolicy, +} + +/// Search for a pre-hashed key. +fn search_hashed(table: M, + hash: SafeHash, + mut is_match: F) + -> SearchResult where + M: Deref>, + F: FnMut(&K) -> bool, +{ + let size = table.size(); + let mut probe = Bucket::new(table, hash); + let ib = probe.index(); + + while probe.index() != ib + size { + let full = match probe.peek() { + Empty(b) => return TableRef(b.into_table()), // hit an empty bucket + Full(b) => b + }; + + if full.distance() + ib < full.index() { + // We can finish the search early if we hit any bucket + // with a lower distance to initial bucket than we've probed. + return TableRef(full.into_table()); + } + + // If the hash doesn't match, it can't be this one.. + if hash == full.hash() { + // If the key doesn't match, it can't be this one.. + if is_match(full.read().0) { + return FoundExisting(full); + } + } + + probe = full.next(); + } + + TableRef(probe.into_table()) +} + +fn pop_internal(starting_bucket: FullBucketMut) -> (K, V) { + let (empty, retkey, retval) = starting_bucket.take(); + let mut gap = match empty.gap_peek() { + Some(b) => b, + None => return (retkey, retval) + }; + + while gap.full().distance() != 0 { + gap = match gap.shift() { + Some(b) => b, + None => break + }; + } + + // Now we've done all our shifting. Return the value we grabbed earlier. + (retkey, retval) +} + +/// Perform robin hood bucket stealing at the given `bucket`. You must +/// also pass the position of that bucket's initial bucket so we don't have +/// to recalculate it. +/// +/// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable. +fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>, + mut ib: usize, + mut hash: SafeHash, + mut k: K, + mut v: V) + -> &'a mut V { + let starting_index = bucket.index(); + let size = { + let table = bucket.table(); // FIXME "lifetime too short". + table.size() + }; + // There can be at most `size - dib` buckets to displace, because + // in the worst case, there are `size` elements and we already are + // `distance` buckets away from the initial one. + let idx_end = starting_index + size - bucket.distance(); + + loop { + let (old_hash, old_key, old_val) = bucket.replace(hash, k, v); + loop { + let probe = bucket.next(); + assert!(probe.index() != idx_end); + + let full_bucket = match probe.peek() { + Empty(bucket) => { + // Found a hole! + let b = bucket.put(old_hash, old_key, old_val); + // Now that it's stolen, just read the value's pointer + // right out of the table! + return Bucket::at_index(b.into_table(), starting_index) + .peek() + .expect_full() + .into_mut_refs() + .1; + }, + Full(bucket) => bucket + }; + + let probe_ib = full_bucket.index() - full_bucket.distance(); + + bucket = full_bucket; + + // Robin hood! Steal the spot. + if ib < probe_ib { + ib = probe_ib; + hash = old_hash; + k = old_key; + v = old_val; + break; + } + } + } +} + +/// A result that works like Option> but preserves +/// the reference that grants us access to the table in any case. +enum SearchResult { + // This is an entry that holds the given key: + FoundExisting(FullBucket), + + // There was no such entry. The reference is given back: + TableRef(M) +} + +impl SearchResult { + fn into_option(self) -> Option> { + match self { + FoundExisting(bucket) => Some(bucket), + TableRef(_) => None + } + } +} + +impl HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn make_hash(&self, x: &X) -> SafeHash where X: Hash { + table::make_hash(&self.hash_state, x) + } + + /// Search for a key, yielding the index if it's found in the hashtable. + /// If you already have the hash for the key lying around, use + /// search_hashed. + fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option> + where K: Borrow, Q: Eq + Hash + { + let hash = self.make_hash(q); + search_hashed(&self.table, hash, |k| q.eq(k.borrow())) + .into_option() + } + + fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option> + where K: Borrow, Q: Eq + Hash + { + let hash = self.make_hash(q); + search_hashed(&mut self.table, hash, |k| q.eq(k.borrow())) + .into_option() + } + + // The caller should ensure that invariants by Robin Hood Hashing hold. + fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) { + let cap = self.table.capacity(); + let mut buckets = Bucket::new(&mut self.table, hash); + let ib = buckets.index(); + + while buckets.index() != ib + cap { + // We don't need to compare hashes for value swap. + // Not even DIBs for Robin Hood. + buckets = match buckets.peek() { + Empty(empty) => { + empty.put(hash, k, v); + return; + } + Full(b) => b.into_bucket() + }; + buckets.next(); + } + panic!("Internal HashMap error: Out of space."); + } +} + +impl + Eq, V> HashMap { + /// Create an empty HashMap. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, int> = HashMap::new(); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new() -> HashMap { + Default::default() + } + + /// Creates an empty hash map with the given initial capacity. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn with_capacity(capacity: usize) -> HashMap { + HashMap::with_capacity_and_hash_state(capacity, Default::default()) + } +} + +impl HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + /// Creates an empty hashmap which will use the given hasher to hash keys. + /// + /// The creates map has the default initial capacity. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_hash_state(s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_hash_state(hash_state: S) -> HashMap { + HashMap { + hash_state: hash_state, + resize_policy: DefaultResizePolicy::new(), + table: RawTable::new(0), + } + } + + /// Create an empty HashMap with space for at least `capacity` + /// elements, using `hasher` to hash the keys. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_capacity_and_hash_state(10, s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S) + -> HashMap { + let resize_policy = DefaultResizePolicy::new(); + let min_cap = max(INITIAL_CAPACITY, resize_policy.min_capacity(capacity)); + let internal_cap = min_cap.checked_next_power_of_two().expect("capacity overflow"); + assert!(internal_cap >= capacity, "capacity overflow"); + HashMap { + hash_state: hash_state, + resize_policy: resize_policy, + table: RawTable::new(internal_cap), + } + } + + /// Returns the number of elements the map can hold without reallocating. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let map: HashMap = HashMap::with_capacity(100); + /// assert!(map.capacity() >= 100); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn capacity(&self) -> usize { + self.resize_policy.usable_capacity(self.table.capacity()) + } + + /// Reserves capacity for at least `additional` more elements to be inserted + /// in the `HashMap`. The collection may reserve more space to avoid + /// frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new allocation size overflows `usize`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, int> = HashMap::new(); + /// map.reserve(10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reserve(&mut self, additional: usize) { + let new_size = self.len().checked_add(additional).expect("capacity overflow"); + let min_cap = self.resize_policy.min_capacity(new_size); + + // An invalid value shouldn't make us run out of space. This includes + // an overflow check. + assert!(new_size <= min_cap); + + if self.table.capacity() < min_cap { + let new_capacity = max(min_cap.next_power_of_two(), INITIAL_CAPACITY); + self.resize(new_capacity); + } + } + + /// Resizes the internal vectors to a new capacity. It's your responsibility to: + /// 1) Make sure the new capacity is enough for all the elements, accounting + /// for the load factor. + /// 2) Ensure new_capacity is a power of two or zero. + fn resize(&mut self, new_capacity: usize) { + assert!(self.table.size() <= new_capacity); + assert!(new_capacity.is_power_of_two() || new_capacity == 0); + + let mut old_table = replace(&mut self.table, RawTable::new(new_capacity)); + let old_size = old_table.size(); + + if old_table.capacity() == 0 || old_table.size() == 0 { + return; + } + + // Grow the table. + // Specialization of the other branch. + let mut bucket = Bucket::first(&mut old_table); + + // "So a few of the first shall be last: for many be called, + // but few chosen." + // + // We'll most likely encounter a few buckets at the beginning that + // have their initial buckets near the end of the table. They were + // placed at the beginning as the probe wrapped around the table + // during insertion. We must skip forward to a bucket that won't + // get reinserted too early and won't unfairly steal others spot. + // This eliminates the need for robin hood. + loop { + bucket = match bucket.peek() { + Full(full) => { + if full.distance() == 0 { + // This bucket occupies its ideal spot. + // It indicates the start of another "cluster". + bucket = full.into_bucket(); + break; + } + // Leaving this bucket in the last cluster for later. + full.into_bucket() + } + Empty(b) => { + // Encountered a hole between clusters. + b.into_bucket() + } + }; + bucket.next(); + } + + // This is how the buckets might be laid out in memory: + // ($ marks an initialized bucket) + // ________________ + // |$$$_$$$$$$_$$$$$| + // + // But we've skipped the entire initial cluster of buckets + // and will continue iteration in this order: + // ________________ + // |$$$$$$_$$$$$ + // ^ wrap around once end is reached + // ________________ + // $$$_____________| + // ^ exit once table.size == 0 + loop { + bucket = match bucket.peek() { + Full(bucket) => { + let h = bucket.hash(); + let (b, k, v) = bucket.take(); + self.insert_hashed_ordered(h, k, v); + { + let t = b.table(); // FIXME "lifetime too short". + if t.size() == 0 { break } + }; + b.into_bucket() + } + Empty(b) => b.into_bucket() + }; + bucket.next(); + } + + assert_eq!(self.table.size(), old_size); + } + + /// Shrinks the capacity of the map as much as possible. It will drop + /// down as much as possible while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap = HashMap::with_capacity(100); + /// map.insert(1, 2); + /// map.insert(3, 4); + /// assert!(map.capacity() >= 100); + /// map.shrink_to_fit(); + /// assert!(map.capacity() >= 2); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn shrink_to_fit(&mut self) { + let min_capacity = self.resize_policy.min_capacity(self.len()); + let min_capacity = max(min_capacity.next_power_of_two(), INITIAL_CAPACITY); + + // An invalid value shouldn't make us run out of space. + debug_assert!(self.len() <= min_capacity); + + if self.table.capacity() != min_capacity { + let old_table = replace(&mut self.table, RawTable::new(min_capacity)); + let old_size = old_table.size(); + + // Shrink the table. Naive algorithm for resizing: + for (h, k, v) in old_table.into_iter() { + self.insert_hashed_nocheck(h, k, v); + } + + debug_assert_eq!(self.table.size(), old_size); + } + } + + /// Insert a pre-hashed key-value pair, without first checking + /// that there's enough room in the buckets. Returns a reference to the + /// newly insert value. + /// + /// If the key already exists, the hashtable will be returned untouched + /// and a reference to the existing element will be returned. + fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V { + self.insert_or_replace_with(hash, k, v, |_, _, _| ()) + } + + fn insert_or_replace_with<'a, F>(&'a mut self, + hash: SafeHash, + k: K, + v: V, + mut found_existing: F) + -> &'a mut V where + F: FnMut(&mut K, &mut V, V), + { + // Worst case, we'll find one empty bucket among `size + 1` buckets. + let size = self.table.size(); + let mut probe = Bucket::new(&mut self.table, hash); + let ib = probe.index(); + + loop { + let mut bucket = match probe.peek() { + Empty(bucket) => { + // Found a hole! + return bucket.put(hash, k, v).into_mut_refs().1; + } + Full(bucket) => bucket + }; + + // hash matches? + if bucket.hash() == hash { + // key matches? + if k == *bucket.read_mut().0 { + let (bucket_k, bucket_v) = bucket.into_mut_refs(); + debug_assert!(k == *bucket_k); + // Key already exists. Get its reference. + found_existing(bucket_k, bucket_v, v); + return bucket_v; + } + } + + let robin_ib = bucket.index() as int - bucket.distance() as int; + + if (ib as int) < robin_ib { + // Found a luckier bucket than me. Better steal his spot. + return robin_hood(bucket, robin_ib as usize, hash, k, v); + } + + probe = bucket.next(); + assert!(probe.index() != ib + size + 1); + } + } + + /// An iterator visiting all keys in arbitrary order. + /// Iterator element type is `&'a K`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// for key in map.keys() { + /// println!("{}", key); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { + fn first((a, _): (A, B)) -> A { a } + let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr + + Keys { inner: self.iter().map(first) } + } + + /// An iterator visiting all values in arbitrary order. + /// Iterator element type is `&'a V`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// for val in map.values() { + /// println!("{}", val); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn values<'a>(&'a self) -> Values<'a, K, V> { + fn second((_, b): (A, B)) -> B { b } + let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr + + Values { inner: self.iter().map(second) } + } + + /// An iterator visiting all key-value pairs in arbitrary order. + /// Iterator element type is `(&'a K, &'a V)`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// for (key, val) in map.iter() { + /// println!("key: {} val: {}", key, val); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter { + Iter { inner: self.table.iter() } + } + + /// An iterator visiting all key-value pairs in arbitrary order, + /// with mutable references to the values. + /// Iterator element type is `(&'a K, &'a mut V)`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// // Update all values + /// for (_, val) in map.iter_mut() { + /// *val *= 2; + /// } + /// + /// for (key, val) in map.iter() { + /// println!("key: {} val: {}", key, val); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter_mut(&mut self) -> IterMut { + IterMut { inner: self.table.iter_mut() } + } + + /// Creates a consuming iterator, that is, one that moves each key-value + /// pair out of the map in arbitrary order. The map cannot be used after + /// calling this. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// // Not possible with .iter() + /// let vec: Vec<(&str, int)> = map.into_iter().collect(); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_iter(self) -> IntoIter { + fn last_two((_, b, c): (A, B, C)) -> (B, C) { (b, c) } + let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; + + IntoIter { + inner: self.table.into_iter().map(last_two) + } + } + + /// Gets the given key's corresponding entry in the map for in-place manipulation. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn entry(&mut self, key: K) -> Entry { + // Gotta resize now. + self.reserve(1); + + let hash = self.make_hash(&key); + search_entry_hashed(&mut self.table, hash, key) + } + + /// Returns the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn len(&self) -> usize { self.table.size() } + + /// Returns true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1, "a"); + /// assert!(!a.is_empty()); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears the map, returning all key-value pairs as an iterator. Keeps the + /// allocated memory for reuse. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// a.insert(1, "a"); + /// a.insert(2, "b"); + /// + /// for (k, v) in a.drain().take(1) { + /// assert!(k == 1 || k == 2); + /// assert!(v == "a" || v == "b"); + /// } + /// + /// assert!(a.is_empty()); + /// ``` + #[inline] + #[unstable(feature = "std_misc", + reason = "matches collection reform specification, waiting for dust to settle")] + pub fn drain(&mut self) -> Drain { + fn last_two((_, b, c): (A, B, C)) -> (B, C) { (b, c) } + let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer + + Drain { + inner: self.table.drain().map(last_two), + } + } + + /// Clears the map, removing all key-value pairs. Keeps the allocated memory + /// for reuse. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// a.insert(1, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn clear(&mut self) { + self.drain(); + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self, k: &Q) -> Option<&V> + where K: Borrow, Q: Hash + Eq + { + self.search(k).map(|bucket| bucket.into_refs().1) + } + + /// Returns true if the map contains a value for the specified key. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn contains_key(&self, k: &Q) -> bool + where K: Borrow, Q: Hash + Eq + { + self.search(k).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// match map.get_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> + where K: Borrow, Q: Hash + Eq + { + self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) + } + + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// assert_eq!(map.insert(37, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.insert(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, k: K, v: V) -> Option { + let hash = self.make_hash(&k); + self.reserve(1); + + let mut retval = None; + self.insert_or_replace_with(hash, k, v, |_, val_ref, val| { + retval = Some(replace(val_ref, val)); + }); + retval + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(&mut self, k: &Q) -> Option + where K: Borrow, Q: Hash + Eq + { + if self.table.size() == 0 { + return None + } + + self.search_mut(k).map(|bucket| pop_internal(bucket).1) + } +} + +fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable, hash: SafeHash, k: K) + -> Entry<'a, K, V> +{ + // Worst case, we'll find one empty bucket among `size + 1` buckets. + let size = table.size(); + let mut probe = Bucket::new(table, hash); + let ib = probe.index(); + + loop { + let bucket = match probe.peek() { + Empty(bucket) => { + // Found a hole! + return Vacant(VacantEntry { + hash: hash, + key: k, + elem: NoElem(bucket), + }); + }, + Full(bucket) => bucket + }; + + // hash matches? + if bucket.hash() == hash { + // key matches? + if k == *bucket.read().0 { + return Occupied(OccupiedEntry{ + elem: bucket, + }); + } + } + + let robin_ib = bucket.index() as int - bucket.distance() as int; + + if (ib as int) < robin_ib { + // Found a luckier bucket than me. Better steal his spot. + return Vacant(VacantEntry { + hash: hash, + key: k, + elem: NeqElem(bucket, robin_ib as usize), + }); + } + + probe = bucket.next(); + assert!(probe.index() != ib + size + 1); + } +} + +impl PartialEq for HashMap + where K: Eq + Hash, V: PartialEq, + S: HashState, + H: hash::Hasher +{ + fn eq(&self, other: &HashMap) -> bool { + if self.len() != other.len() { return false; } + + self.iter().all(|(key, value)| + other.get(key).map_or(false, |v| *value == *v) + ) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for HashMap + where K: Eq + Hash, V: Eq, + S: HashState, + H: hash::Hasher +{} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Debug for HashMap + where K: Eq + Hash + Debug, V: Debug, + S: HashState, + H: hash::Hasher +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "HashMap {{")); + + for (i, (k, v)) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{:?}: {:?}", *k, *v)); + } + + write!(f, "}}") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for HashMap + where K: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + fn default() -> HashMap { + HashMap::with_hash_state(Default::default()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Index for HashMap + where K: Eq + Hash + Borrow, + Q: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Output = V; + + #[inline] + fn index<'a>(&'a self, index: &Q) -> &'a V { + self.get(index).expect("no entry found for key") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl IndexMut for HashMap + where K: Eq + Hash + Borrow, + Q: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + #[inline] + fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V { + self.get_mut(index).expect("no entry found for key") + } +} + +/// HashMap iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Iter<'a, K: 'a, V: 'a> { + inner: table::Iter<'a, K, V> +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +impl<'a, K, V> Clone for Iter<'a, K, V> { + fn clone(&self) -> Iter<'a, K, V> { + Iter { + inner: self.inner.clone() + } + } +} + +/// HashMap mutable values iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IterMut<'a, K: 'a, V: 'a> { + inner: table::IterMut<'a, K, V> +} + +/// HashMap move iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IntoIter { + inner: iter::Map, fn((SafeHash, K, V)) -> (K, V)> +} + +/// HashMap keys iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Keys<'a, K: 'a, V: 'a> { + inner: Map, fn((&'a K, &'a V)) -> &'a K> +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +impl<'a, K, V> Clone for Keys<'a, K, V> { + fn clone(&self) -> Keys<'a, K, V> { + Keys { + inner: self.inner.clone() + } + } +} + +/// HashMap values iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Values<'a, K: 'a, V: 'a> { + inner: Map, fn((&'a K, &'a V)) -> &'a V> +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +impl<'a, K, V> Clone for Values<'a, K, V> { + fn clone(&self) -> Values<'a, K, V> { + Values { + inner: self.inner.clone() + } + } +} + +/// HashMap drain iterator. +#[unstable(feature = "std_misc", + reason = "matches collection reform specification, waiting for dust to settle")] +pub struct Drain<'a, K: 'a, V: 'a> { + inner: iter::Map, fn((SafeHash, K, V)) -> (K, V)> +} + +/// A view into a single occupied location in a HashMap. +#[unstable(feature = "std_misc", + reason = "precise API still being fleshed out")] +pub struct OccupiedEntry<'a, K: 'a, V: 'a> { + elem: FullBucket>, +} + +/// A view into a single empty location in a HashMap. +#[unstable(feature = "std_misc", + reason = "precise API still being fleshed out")] +pub struct VacantEntry<'a, K: 'a, V: 'a> { + hash: SafeHash, + key: K, + elem: VacantEntryState>, +} + +/// A view into a single location in a map, which may be vacant or occupied. +#[unstable(feature = "std_misc", + reason = "precise API still being fleshed out")] +pub enum Entry<'a, K: 'a, V: 'a> { + /// An occupied Entry. + Occupied(OccupiedEntry<'a, K, V>), + /// A vacant Entry. + Vacant(VacantEntry<'a, K, V>), +} + +/// Possible states of a VacantEntry. +enum VacantEntryState { + /// The index is occupied, but the key to insert has precedence, + /// and will kick the current one out on insertion. + NeqElem(FullBucket, usize), + /// The index is genuinely vacant. + NoElem(EmptyBucket), +} + +impl<'a, K, V, S, H> IntoIterator for &'a HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = (&'a K, &'a V); + type IntoIter = Iter<'a, K, V>; + + fn into_iter(self) -> Iter<'a, K, V> { + self.iter() + } +} + +impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = (&'a K, &'a mut V); + type IntoIter = IterMut<'a, K, V>; + + fn into_iter(mut self) -> IterMut<'a, K, V> { + self.iter_mut() + } +} + +impl IntoIterator for HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = (K, V); + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + self.into_iter() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Iter<'a, K, V> { + type Item = (&'a K, &'a V); + + #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for IterMut<'a, K, V> { + type Item = (&'a K, &'a mut V); + + #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for IntoIter { + type Item = (K, V); + + #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for IntoIter { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Keys<'a, K, V> { + type Item = &'a K; + + #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Values<'a, K, V> { + type Item = &'a V; + + #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Drain<'a, K, V> { + type Item = (K, V); + + #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[unstable(feature = "std_misc", + reason = "matches collection reform v2 specification, waiting for dust to settle")] +impl<'a, K, V> Entry<'a, K, V> { + /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant. + pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> { + match self { + Occupied(entry) => Ok(entry.into_mut()), + Vacant(entry) => Err(entry), + } + } +} + +impl<'a, K, V> OccupiedEntry<'a, K, V> { + /// Gets a reference to the value in the entry. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> &V { + self.elem.read().1 + } + + /// Gets a mutable reference to the value in the entry. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get_mut(&mut self) -> &mut V { + self.elem.read_mut().1 + } + + /// Converts the OccupiedEntry into a mutable reference to the value in the entry + /// with a lifetime bound to the map itself + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_mut(self) -> &'a mut V { + self.elem.into_mut_refs().1 + } + + /// Sets the value of the entry, and returns the entry's old value + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, mut value: V) -> V { + let old_value = self.get_mut(); + mem::swap(&mut value, old_value); + value + } + + /// Takes the value out of the entry, and returns it + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(self) -> V { + pop_internal(self.elem).1 + } +} + +impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { + /// Sets the value of the entry with the VacantEntry's key, + /// and returns a mutable reference to it + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(self, value: V) -> &'a mut V { + match self.elem { + NeqElem(bucket, ib) => { + robin_hood(bucket, ib, self.hash, self.key, value) + } + NoElem(bucket) => { + bucket.put(self.hash, self.key, value).into_mut_refs().1 + } + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl FromIterator<(K, V)> for HashMap + where K: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + fn from_iter>(iter: T) -> HashMap { + let iter = iter.into_iter(); + let lower = iter.size_hint().0; + let mut map = HashMap::with_capacity_and_hash_state(lower, + Default::default()); + map.extend(iter); + map + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Extend<(K, V)> for HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn extend>(&mut self, iter: T) { + for (k, v) in iter { + self.insert(k, v); + } + } +} + + +/// `RandomState` is the default state for `HashMap` types. +/// +/// A particular instance `RandomState` will create the same instances of +/// `Hasher`, but the hashers created by two different `RandomState` +/// instances are unlikely to produce the same result for the same values. +#[derive(Clone)] +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +pub struct RandomState { + k0: u64, + k1: u64, +} + +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +impl RandomState { + /// Construct a new `RandomState` that is initialized with random keys. + #[inline] + #[allow(deprecated)] + pub fn new() -> RandomState { + let mut r = rand::thread_rng(); + RandomState { k0: r.gen(), k1: r.gen() } + } +} + +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +impl HashState for RandomState { + type Hasher = Hasher; + fn hasher(&self) -> Hasher { + Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) } + } +} + +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +impl Default for RandomState { + #[inline] + fn default() -> RandomState { + RandomState::new() + } +} + +/// A hasher implementation which is generated from `RandomState` instances. +/// +/// This is the default hasher used in a `HashMap` to hash keys. Types do not +/// typically declare an ability to explicitly hash into this particular type, +/// but rather in a `H: hash::Writer` type parameter. +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +pub struct Hasher { inner: SipHasher } + +impl hash::Writer for Hasher { + fn write(&mut self, data: &[u8]) { + hash::Writer::write(&mut self.inner, data) + } +} + +impl hash::Hasher for Hasher { + type Output = u64; + fn reset(&mut self) { hash::Hasher::reset(&mut self.inner) } + fn finish(&self) -> u64 { self.inner.finish() } +} + +#[cfg(test)] +mod test_map { + use prelude::v1::*; + + use super::HashMap; + use super::Entry::{Occupied, Vacant}; + use iter::{range_inclusive, range_step_inclusive, repeat}; + use cell::RefCell; + use rand::{weak_rng, Rng}; + + #[test] + fn test_create_capacity_zero() { + let mut m = HashMap::with_capacity(0); + + assert!(m.insert(1, 1).is_none()); + + assert!(m.contains_key(&1)); + assert!(!m.contains_key(&0)); + } + + #[test] + fn test_insert() { + let mut m = HashMap::new(); + assert_eq!(m.len(), 0); + assert!(m.insert(1, 2).is_none()); + assert_eq!(m.len(), 1); + assert!(m.insert(2, 4).is_none()); + assert_eq!(m.len(), 2); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&2).unwrap(), 4); + } + + thread_local! { static DROP_VECTOR: RefCell> = RefCell::new(Vec::new()) } + + #[derive(Hash, PartialEq, Eq)] + struct Dropable { + k: usize + } + + impl Dropable { + fn new(k: usize) -> Dropable { + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[k] += 1; + }); + + Dropable { k: k } + } + } + + impl Drop for Dropable { + fn drop(&mut self) { + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[self.k] -= 1; + }); + } + } + + impl Clone for Dropable { + fn clone(&self) -> Dropable { + Dropable::new(self.k) + } + } + + #[test] + fn test_drops() { + DROP_VECTOR.with(|slot| { + *slot.borrow_mut() = repeat(0).take(200).collect(); + }); + + { + let mut m = HashMap::new(); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + + for i in 0..100 { + let d1 = Dropable::new(i); + let d2 = Dropable::new(i+100); + m.insert(d1, d2); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + for i in 0..50 { + let k = Dropable::new(i); + let v = m.remove(&k); + + assert!(v.is_some()); + + DROP_VECTOR.with(|v| { + assert_eq!(v.borrow()[i], 1); + assert_eq!(v.borrow()[i+100], 1); + }); + } + + DROP_VECTOR.with(|v| { + for i in 0..50 { + assert_eq!(v.borrow()[i], 0); + assert_eq!(v.borrow()[i+100], 0); + } + + for i in 50..100 { + assert_eq!(v.borrow()[i], 1); + assert_eq!(v.borrow()[i+100], 1); + } + }); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + } + + #[test] + fn test_move_iter_drops() { + DROP_VECTOR.with(|v| { + *v.borrow_mut() = repeat(0).take(200).collect(); + }); + + let hm = { + let mut hm = HashMap::new(); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + + for i in 0..100 { + let d1 = Dropable::new(i); + let d2 = Dropable::new(i+100); + hm.insert(d1, d2); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + hm + }; + + // By the way, ensure that cloning doesn't screw up the dropping. + drop(hm.clone()); + + { + let mut half = hm.into_iter().take(50); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + for _ in half.by_ref() {} + + DROP_VECTOR.with(|v| { + let nk = (0..100).filter(|&i| { + v.borrow()[i] == 1 + }).count(); + + let nv = (0..100).filter(|&i| { + v.borrow()[i+100] == 1 + }).count(); + + assert_eq!(nk, 50); + assert_eq!(nv, 50); + }); + }; + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + } + + #[test] + fn test_empty_pop() { + let mut m: HashMap = HashMap::new(); + assert_eq!(m.remove(&0), None); + } + + #[test] + fn test_lots_of_insertions() { + let mut m = HashMap::new(); + + // Try this a few times to make sure we never screw up the hashmap's + // internal state. + for _ in 0..10 { + assert!(m.is_empty()); + + for i in range_inclusive(1, 1000) { + assert!(m.insert(i, i).is_none()); + + for j in range_inclusive(1, i) { + let r = m.get(&j); + assert_eq!(r, Some(&j)); + } + + for j in range_inclusive(i+1, 1000) { + let r = m.get(&j); + assert_eq!(r, None); + } + } + + for i in range_inclusive(1001, 2000) { + assert!(!m.contains_key(&i)); + } + + // remove forwards + for i in range_inclusive(1, 1000) { + assert!(m.remove(&i).is_some()); + + for j in range_inclusive(1, i) { + assert!(!m.contains_key(&j)); + } + + for j in range_inclusive(i+1, 1000) { + assert!(m.contains_key(&j)); + } + } + + for i in range_inclusive(1, 1000) { + assert!(!m.contains_key(&i)); + } + + for i in range_inclusive(1, 1000) { + assert!(m.insert(i, i).is_none()); + } + + // remove backwards + for i in range_step_inclusive(1000, 1, -1) { + assert!(m.remove(&i).is_some()); + + for j in range_inclusive(i, 1000) { + assert!(!m.contains_key(&j)); + } + + for j in range_inclusive(1, i-1) { + assert!(m.contains_key(&j)); + } + } + } + } + + #[test] + fn test_find_mut() { + let mut m = HashMap::new(); + assert!(m.insert(1, 12).is_none()); + assert!(m.insert(2, 8).is_none()); + assert!(m.insert(5, 14).is_none()); + let new = 100; + match m.get_mut(&5) { + None => panic!(), Some(x) => *x = new + } + assert_eq!(m.get(&5), Some(&new)); + } + + #[test] + fn test_insert_overwrite() { + let mut m = HashMap::new(); + assert!(m.insert(1, 2).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(!m.insert(1, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 3); + } + + #[test] + fn test_insert_conflicts() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(5, 3).is_none()); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&1).unwrap(), 2); + } + + #[test] + fn test_conflict_remove() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(m.insert(5, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&9).unwrap(), 4); + assert!(m.remove(&1).is_some()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); + } + + #[test] + fn test_is_empty() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert!(!m.is_empty()); + assert!(m.remove(&1).is_some()); + assert!(m.is_empty()); + } + + #[test] + fn test_pop() { + let mut m = HashMap::new(); + m.insert(1, 2); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); + } + + #[test] + fn test_iterate() { + let mut m = HashMap::with_capacity(4); + for i in 0..32 { + assert!(m.insert(i, i*2).is_none()); + } + assert_eq!(m.len(), 32); + + let mut observed: u32 = 0; + + for (k, v) in &m { + assert_eq!(*v, *k * 2); + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); + } + + #[test] + fn test_keys() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let keys: Vec<_> = map.keys().cloned().collect(); + assert_eq!(keys.len(), 3); + assert!(keys.contains(&1)); + assert!(keys.contains(&2)); + assert!(keys.contains(&3)); + } + + #[test] + fn test_values() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let values: Vec<_> = map.values().cloned().collect(); + assert_eq!(values.len(), 3); + assert!(values.contains(&'a')); + assert!(values.contains(&'b')); + assert!(values.contains(&'c')); + } + + #[test] + fn test_find() { + let mut m = HashMap::new(); + assert!(m.get(&1).is_none()); + m.insert(1, 2); + match m.get(&1) { + None => panic!(), + Some(v) => assert_eq!(*v, 2) + } + } + + #[test] + fn test_eq() { + let mut m1 = HashMap::new(); + m1.insert(1, 2); + m1.insert(2, 3); + m1.insert(3, 4); + + let mut m2 = HashMap::new(); + m2.insert(1, 2); + m2.insert(2, 3); + + assert!(m1 != m2); + + m2.insert(3, 4); + + assert_eq!(m1, m2); + } + + #[test] + fn test_show() { + let mut map = HashMap::new(); + let empty: HashMap = HashMap::new(); + + map.insert(1, 2); + map.insert(3, 4); + + let map_str = format!("{:?}", map); + + assert!(map_str == "HashMap {1: 2, 3: 4}" || + map_str == "HashMap {3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "HashMap {}"); + } + + #[test] + fn test_expand() { + let mut m = HashMap::new(); + + assert_eq!(m.len(), 0); + assert!(m.is_empty()); + + let mut i = 0; + let old_cap = m.table.capacity(); + while old_cap == m.table.capacity() { + m.insert(i, i); + i += 1; + } + + assert_eq!(m.len(), i); + assert!(!m.is_empty()); + } + + #[test] + fn test_behavior_resize_policy() { + let mut m = HashMap::new(); + + assert_eq!(m.len(), 0); + assert_eq!(m.table.capacity(), 0); + assert!(m.is_empty()); + + m.insert(0, 0); + m.remove(&0); + assert!(m.is_empty()); + let initial_cap = m.table.capacity(); + m.reserve(initial_cap); + let cap = m.table.capacity(); + + assert_eq!(cap, initial_cap * 2); + + let mut i = 0; + for _ in 0..cap * 3 / 4 { + m.insert(i, i); + i += 1; + } + // three quarters full + + assert_eq!(m.len(), i); + assert_eq!(m.table.capacity(), cap); + + for _ in 0..cap / 4 { + m.insert(i, i); + i += 1; + } + // half full + + let new_cap = m.table.capacity(); + assert_eq!(new_cap, cap * 2); + + for _ in 0..cap / 2 - 1 { + i -= 1; + m.remove(&i); + assert_eq!(m.table.capacity(), new_cap); + } + // A little more than one quarter full. + m.shrink_to_fit(); + assert_eq!(m.table.capacity(), cap); + // again, a little more than half full + for _ in 0..cap / 2 - 1 { + i -= 1; + m.remove(&i); + } + m.shrink_to_fit(); + + assert_eq!(m.len(), i); + assert!(!m.is_empty()); + assert_eq!(m.table.capacity(), initial_cap); + } + + #[test] + fn test_reserve_shrink_to_fit() { + let mut m = HashMap::new(); + m.insert(0, 0); + m.remove(&0); + assert!(m.capacity() >= m.len()); + for i in 0..128 { + m.insert(i, i); + } + m.reserve(256); + + let usable_cap = m.capacity(); + for i in 128..(128 + 256) { + m.insert(i, i); + assert_eq!(m.capacity(), usable_cap); + } + + for i in 100..(128 + 256) { + assert_eq!(m.remove(&i), Some(i)); + } + m.shrink_to_fit(); + + assert_eq!(m.len(), 100); + assert!(!m.is_empty()); + assert!(m.capacity() >= m.len()); + + for i in 0..100 { + assert_eq!(m.remove(&i), Some(i)); + } + m.shrink_to_fit(); + m.insert(0, 0); + + assert_eq!(m.len(), 1); + assert!(m.capacity() >= m.len()); + assert_eq!(m.remove(&0), Some(0)); + } + + #[test] + fn test_from_iter() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + for &(k, v) in &xs { + assert_eq!(map.get(&k), Some(&v)); + } + } + + #[test] + fn test_size_hint() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.size_hint(), (3, Some(3))); + } + + #[test] + fn test_iter_len() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); + } + + #[test] + fn test_mut_size_hint() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.size_hint(), (3, Some(3))); + } + + #[test] + fn test_iter_mut_len() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); + } + + #[test] + fn test_index() { + let mut map = HashMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + assert_eq!(map[2], 1); + } + + #[test] + #[should_fail] + fn test_index_nonexistent() { + let mut map = HashMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + map[4]; + } + + #[test] + fn test_entry(){ + let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + // Existing key (insert) + match map.entry(1) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + assert_eq!(view.get(), &10); + assert_eq!(view.insert(100), 10); + } + } + assert_eq!(map.get(&1).unwrap(), &100); + assert_eq!(map.len(), 6); + + + // Existing key (update) + match map.entry(2) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + let v = view.get_mut(); + let new_v = (*v) * 10; + *v = new_v; + } + } + assert_eq!(map.get(&2).unwrap(), &200); + assert_eq!(map.len(), 6); + + // Existing key (take) + match map.entry(3) { + Vacant(_) => unreachable!(), + Occupied(view) => { + assert_eq!(view.remove(), 30); + } + } + assert_eq!(map.get(&3), None); + assert_eq!(map.len(), 5); + + + // Inexistent key (insert) + match map.entry(10) { + Occupied(_) => unreachable!(), + Vacant(view) => { + assert_eq!(*view.insert(1000), 1000); + } + } + assert_eq!(map.get(&10).unwrap(), &1000); + assert_eq!(map.len(), 6); + } + + #[test] + fn test_entry_take_doesnt_corrupt() { + // Test for #19292 + fn check(m: &HashMap) { + for k in m.keys() { + assert!(m.contains_key(k), + "{} is in keys() but not in the map?", k); + } + } + + let mut m = HashMap::new(); + let mut rng = weak_rng(); + + // Populate the map with some items. + for _ in 0..50 { + let x = rng.gen_range(-10, 10); + m.insert(x, ()); + } + + for i in 0..1000 { + let x = rng.gen_range(-10, 10); + match m.entry(x) { + Vacant(_) => {}, + Occupied(e) => { + println!("{}: remove {}", i, x); + e.remove(); + }, + } + + check(&m); + } + } +} diff --git a/src/libstd/collections/hash/mod.rs b/src/libstd/collections/hash/mod.rs index 47e300af26981..39c1458b72001 100644 --- a/src/libstd/collections/hash/mod.rs +++ b/src/libstd/collections/hash/mod.rs @@ -12,6 +12,14 @@ mod bench; mod table; +#[cfg(stage0)] +#[path = "map_stage0.rs"] pub mod map; +#[cfg(not(stage0))] +pub mod map; +#[cfg(stage0)] +#[path = "set_stage0.rs"] +pub mod set; +#[cfg(not(stage0))] pub mod set; pub mod state; diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 5fbbcb3b347af..e0631a64d44b1 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -10,21 +10,21 @@ // // ignore-lexer-test FIXME #15883 -use borrow::BorrowFrom; +use borrow::Borrow; use clone::Clone; use cmp::{Eq, PartialEq}; use core::marker::Sized; use default::Default; use fmt::Debug; use fmt; -use hash::{self, Hash}; +use hash::Hash; use iter::{ Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend, }; use ops::{BitOr, BitAnd, BitXor, Sub}; use option::Option::{Some, None, self}; -use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher}; +use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState}; use super::state::HashState; // Future Optimization (FIXME!) @@ -97,7 +97,7 @@ pub struct HashSet { map: HashMap } -impl + Eq> HashSet { +impl HashSet { /// Create an empty HashSet. /// /// # Example @@ -128,10 +128,8 @@ impl + Eq> HashSet { } } -impl HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl HashSet + where T: Eq + Hash, S: HashState { /// Creates a new empty hash set which will use the given hasher to hash /// keys. @@ -462,7 +460,7 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where T: Borrow, Q: Hash + Eq { self.map.contains_key(value) } @@ -572,17 +570,15 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where T: Borrow, Q: Hash + Eq { self.map.remove(value).is_some() } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl PartialEq for HashSet + where T: Eq + Hash, S: HashState { fn eq(&self, other: &HashSet) -> bool { if self.len() != other.len() { return false; } @@ -592,17 +588,14 @@ impl PartialEq for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl Eq for HashSet + where T: Eq + Hash, S: HashState {} #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for HashSet - where T: Eq + Hash + fmt::Debug, - S: HashState, - H: hash::Hasher +impl fmt::Debug for HashSet + where T: Eq + Hash + fmt::Debug, + S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "HashSet {{")); @@ -617,12 +610,12 @@ impl fmt::Debug for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for HashSet - where T: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl FromIterator for HashSet + where T: Eq + Hash, + S: HashState + Default, { - fn from_iter>(iter: I) -> HashSet { + fn from_iter>(iterable: I) -> HashSet { + let iter = iterable.into_iter(); let lower = iter.size_hint().0; let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default()); set.extend(iter); @@ -631,12 +624,11 @@ impl FromIterator for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl Extend for HashSet + where T: Eq + Hash, + S: HashState, { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for k in iter { self.insert(k); } @@ -644,10 +636,9 @@ impl Extend for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for HashSet - where T: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl Default for HashSet + where T: Eq + Hash, + S: HashState + Default, { #[stable(feature = "rust1", since = "1.0.0")] fn default() -> HashSet { @@ -656,10 +647,9 @@ impl Default for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> BitOr<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> BitOr<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -689,10 +679,9 @@ impl<'a, 'b, T, S, H> BitOr<&'b HashSet> for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> BitAnd<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> BitAnd<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -722,10 +711,9 @@ impl<'a, 'b, T, S, H> BitAnd<&'b HashSet> for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> BitXor<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> BitXor<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -755,10 +743,9 @@ impl<'a, 'b, T, S, H> BitXor<&'b HashSet> for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> Sub<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> Sub<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -836,10 +823,8 @@ pub struct Union<'a, T: 'a, S: 'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> IntoIterator for &'a HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> IntoIterator for &'a HashSet + where T: Eq + Hash, S: HashState { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -850,10 +835,9 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl IntoIterator for HashSet + where T: Eq + Hash, + S: HashState { type Item = T; type IntoIter = IntoIter; @@ -900,10 +884,8 @@ impl<'a, K> ExactSizeIterator for Drain<'a, K> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for Intersection<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for Intersection<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; @@ -925,10 +907,8 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, S> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for Difference<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for Difference<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; @@ -950,10 +930,8 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, S> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; @@ -962,10 +940,8 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for Union<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for Union<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs new file mode 100644 index 0000000000000..68c9e02d8ad72 --- /dev/null +++ b/src/libstd/collections/hash/set_stage0.rs @@ -0,0 +1,1252 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// ignore-lexer-test FIXME #15883 + +use borrow::Borrow; +use clone::Clone; +use cmp::{Eq, PartialEq}; +use core::marker::Sized; +use default::Default; +use fmt::Debug; +use fmt; +use hash::{self, Hash}; +use iter::{ + Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend, +}; +use ops::{BitOr, BitAnd, BitXor, Sub}; +use option::Option::{Some, None, self}; + +use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher}; +use super::state::HashState; + +// Future Optimization (FIXME!) +// ============================= +// +// Iteration over zero sized values is a noop. There is no need +// for `bucket.val` in the case of HashSet. I suppose we would need HKT +// to get rid of it properly. + +/// An implementation of a hash set using the underlying representation of a +/// HashMap where the value is (). As with the `HashMap` type, a `HashSet` +/// requires that the elements implement the `Eq` and `Hash` traits. +/// +/// # Example +/// +/// ``` +/// use std::collections::HashSet; +/// // Type inference lets us omit an explicit type signature (which +/// // would be `HashSet<&str>` in this example). +/// let mut books = HashSet::new(); +/// +/// // Add some books. +/// books.insert("A Dance With Dragons"); +/// books.insert("To Kill a Mockingbird"); +/// books.insert("The Odyssey"); +/// books.insert("The Great Gatsby"); +/// +/// // Check for a specific one. +/// if !books.contains(&("The Winds of Winter")) { +/// println!("We have {} books, but The Winds of Winter ain't one.", +/// books.len()); +/// } +/// +/// // Remove a book. +/// books.remove(&"The Odyssey"); +/// +/// // Iterate over everything. +/// for book in books.iter() { +/// println!("{}", *book); +/// } +/// ``` +/// +/// The easiest way to use `HashSet` with a custom type is to derive +/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the +/// future be implied by `Eq`. +/// +/// ``` +/// use std::collections::HashSet; +/// #[derive(Hash, Eq, PartialEq, Debug)] +/// struct Viking<'a> { +/// name: &'a str, +/// power: usize, +/// } +/// +/// let mut vikings = HashSet::new(); +/// +/// vikings.insert(Viking { name: "Einar", power: 9 }); +/// vikings.insert(Viking { name: "Einar", power: 9 }); +/// vikings.insert(Viking { name: "Olaf", power: 4 }); +/// vikings.insert(Viking { name: "Harald", power: 8 }); +/// +/// // Use derived implementation to print the vikings. +/// for x in vikings.iter() { +/// println!("{:?}", x); +/// } +/// ``` +#[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct HashSet { + map: HashMap +} + +impl + Eq> HashSet { + /// Create an empty HashSet. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set: HashSet = HashSet::new(); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new() -> HashSet { + HashSet::with_capacity(INITIAL_CAPACITY) + } + + /// Create an empty HashSet with space for at least `n` elements in + /// the hash table. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set: HashSet = HashSet::with_capacity(10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn with_capacity(capacity: usize) -> HashSet { + HashSet { map: HashMap::with_capacity(capacity) } + } +} + +impl HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + /// Creates a new empty hash set which will use the given hasher to hash + /// keys. + /// + /// The hash set is also created with the default initial capacity. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_hash_state(s); + /// set.insert(2); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_hash_state(hash_state: S) -> HashSet { + HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state) + } + + /// Create an empty HashSet with space for at least `capacity` + /// elements in the hash table, using `hasher` to hash the keys. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_capacity_and_hash_state(10, s); + /// set.insert(1); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S) + -> HashSet { + HashSet { + map: HashMap::with_capacity_and_hash_state(capacity, hash_state), + } + } + + /// Returns the number of elements the set can hold without reallocating. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let set: HashSet = HashSet::with_capacity(100); + /// assert!(set.capacity() >= 100); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn capacity(&self) -> usize { + self.map.capacity() + } + + /// Reserves capacity for at least `additional` more elements to be inserted + /// in the `HashSet`. The collection may reserve more space to avoid + /// frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new allocation size overflows `usize`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set: HashSet = HashSet::new(); + /// set.reserve(10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reserve(&mut self, additional: usize) { + self.map.reserve(additional) + } + + /// Shrinks the capacity of the set as much as possible. It will drop + /// down as much as possible while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set: HashSet = HashSet::with_capacity(100); + /// set.insert(1); + /// set.insert(2); + /// assert!(set.capacity() >= 100); + /// set.shrink_to_fit(); + /// assert!(set.capacity() >= 2); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn shrink_to_fit(&mut self) { + self.map.shrink_to_fit() + } + + /// An iterator visiting all elements in arbitrary order. + /// Iterator element type is &'a T. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set = HashSet::new(); + /// set.insert("a"); + /// set.insert("b"); + /// + /// // Will print in an arbitrary order. + /// for x in set.iter() { + /// println!("{}", x); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter { + Iter { iter: self.map.keys() } + } + + /// Creates a consuming iterator, that is, one that moves each value out + /// of the set in arbitrary order. The set cannot be used after calling + /// this. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set = HashSet::new(); + /// set.insert("a".to_string()); + /// set.insert("b".to_string()); + /// + /// // Not possible to collect to a Vec with a regular `.iter()`. + /// let v: Vec = set.into_iter().collect(); + /// + /// // Will print in an arbitrary order. + /// for x in v.iter() { + /// println!("{}", x); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_iter(self) -> IntoIter { + fn first((a, _): (A, B)) -> A { a } + let first: fn((T, ())) -> T = first; + + IntoIter { iter: self.map.into_iter().map(first) } + } + + /// Visit the values representing the difference. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Can be seen as `a - b`. + /// for x in a.difference(&b) { + /// println!("{}", x); // Print 1 + /// } + /// + /// let diff: HashSet = a.difference(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1].iter().map(|&x| x).collect()); + /// + /// // Note that difference is not symmetric, + /// // and `b - a` means something else: + /// let diff: HashSet = b.difference(&a).map(|&x| x).collect(); + /// assert_eq!(diff, [4].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { + Difference { + iter: self.iter(), + other: other, + } + } + + /// Visit the values representing the symmetric difference. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 1, 4 in arbitrary order. + /// for x in a.symmetric_difference(&b) { + /// println!("{}", x); + /// } + /// + /// let diff1: HashSet = a.symmetric_difference(&b).map(|&x| x).collect(); + /// let diff2: HashSet = b.symmetric_difference(&a).map(|&x| x).collect(); + /// + /// assert_eq!(diff1, diff2); + /// assert_eq!(diff1, [1, 4].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) + -> SymmetricDifference<'a, T, S> { + SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } + } + + /// Visit the values representing the intersection. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 2, 3 in arbitrary order. + /// for x in a.intersection(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: HashSet = a.intersection(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { + Intersection { + iter: self.iter(), + other: other, + } + } + + /// Visit the values representing the union. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 1, 2, 3, 4 in arbitrary order. + /// for x in a.union(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: HashSet = a.union(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1, 2, 3, 4].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { + Union { iter: self.iter().chain(other.difference(self)) } + } + + /// Return the number of elements in the set + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// assert_eq!(v.len(), 0); + /// v.insert(1); + /// assert_eq!(v.len(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn len(&self) -> usize { self.map.len() } + + /// Returns true if the set contains no elements + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// assert!(v.is_empty()); + /// v.insert(1); + /// assert!(!v.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_empty(&self) -> bool { self.map.len() == 0 } + + /// Clears the set, returning all elements in an iterator. + #[inline] + #[unstable(feature = "std_misc", + reason = "matches collection reform specification, waiting for dust to settle")] + pub fn drain(&mut self) -> Drain { + fn first((a, _): (A, B)) -> A { a } + let first: fn((T, ())) -> T = first; // coerce to fn pointer + + Drain { iter: self.map.drain().map(first) } + } + + /// Clears the set, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// v.insert(1); + /// v.clear(); + /// assert!(v.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn clear(&mut self) { self.map.clear() } + + /// Returns `true` if the set contains a value. + /// + /// The value may be any borrowed form of the set's value type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the value type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); + /// assert_eq!(set.contains(&1), true); + /// assert_eq!(set.contains(&4), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn contains(&self, value: &Q) -> bool + where T: Borrow, Q: Hash + Eq + { + self.map.contains_key(value) + } + + /// Returns `true` if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); + /// let mut b = HashSet::new(); + /// + /// assert_eq!(a.is_disjoint(&b), true); + /// b.insert(4); + /// assert_eq!(a.is_disjoint(&b), true); + /// b.insert(1); + /// assert_eq!(a.is_disjoint(&b), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_disjoint(&self, other: &HashSet) -> bool { + self.iter().all(|v| !other.contains(v)) + } + + /// Returns `true` if the set is a subset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect(); + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.is_subset(&sup), true); + /// set.insert(2); + /// assert_eq!(set.is_subset(&sup), true); + /// set.insert(4); + /// assert_eq!(set.is_subset(&sup), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_subset(&self, other: &HashSet) -> bool { + self.iter().all(|v| other.contains(v)) + } + + /// Returns `true` if the set is a superset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let sub: HashSet<_> = [1, 2].iter().cloned().collect(); + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.is_superset(&sub), false); + /// + /// set.insert(0); + /// set.insert(1); + /// assert_eq!(set.is_superset(&sub), false); + /// + /// set.insert(2); + /// assert_eq!(set.is_superset(&sub), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_superset(&self, other: &HashSet) -> bool { + other.is_subset(self) + } + + /// Adds a value to the set. Returns `true` if the value was not already + /// present in the set. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.insert(2), true); + /// assert_eq!(set.insert(2), false); + /// assert_eq!(set.len(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } + + /// Removes a value from the set. Returns `true` if the value was + /// present in the set. + /// + /// The value may be any borrowed form of the set's value type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the value type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::new(); + /// + /// set.insert(2); + /// assert_eq!(set.remove(&2), true); + /// assert_eq!(set.remove(&2), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(&mut self, value: &Q) -> bool + where T: Borrow, Q: Hash + Eq + { + self.map.remove(value).is_some() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn eq(&self, other: &HashSet) -> bool { + if self.len() != other.len() { return false; } + + self.iter().all(|key| other.contains(key)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for HashSet + where T: Eq + Hash + fmt::Debug, + S: HashState, + H: hash::Hasher +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "HashSet {{")); + + for (i, x) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{:?}", *x)); + } + + write!(f, "}}") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl FromIterator for HashSet + where T: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + fn from_iter>(iter: I) -> HashSet { + let iter = iter.into_iter(); + let lower = iter.size_hint().0; + let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default()); + set.extend(iter); + set + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Extend for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn extend>(&mut self, iter: I) { + for k in iter { + self.insert(k); + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for HashSet + where T: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + #[stable(feature = "rust1", since = "1.0.0")] + fn default() -> HashSet { + HashSet::with_hash_state(Default::default()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> BitOr<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the union of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a | &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 3, 4, 5]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitor(self, rhs: &HashSet) -> HashSet { + self.union(rhs).cloned().collect() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> BitAnd<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the intersection of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect(); + /// + /// let set = &a & &b; + /// + /// let mut i = 0; + /// let expected = [2, 3]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitand(self, rhs: &HashSet) -> HashSet { + self.intersection(rhs).cloned().collect() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> BitXor<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a ^ &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 4, 5]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitxor(self, rhs: &HashSet) -> HashSet { + self.symmetric_difference(rhs).cloned().collect() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> Sub<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the difference of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a - &b; + /// + /// let mut i = 0; + /// let expected = [1, 2]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn sub(self, rhs: &HashSet) -> HashSet { + self.difference(rhs).cloned().collect() + } +} + +/// HashSet iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Iter<'a, K: 'a> { + iter: Keys<'a, K, ()> +} + +/// HashSet move iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IntoIter { + iter: Map, fn((K, ())) -> K> +} + +/// HashSet drain iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Drain<'a, K: 'a> { + iter: Map, fn((K, ())) -> K>, +} + +/// Intersection iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Intersection<'a, T: 'a, S: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, +} + +/// Difference iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Difference<'a, T: 'a, S: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, +} + +/// Symmetric difference iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct SymmetricDifference<'a, T: 'a, S: 'a> { + iter: Chain, Difference<'a, T, S>> +} + +/// Set union iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Union<'a, T: 'a, S: 'a> { + iter: Chain, Difference<'a, T, S>> +} + +impl<'a, T, S, H> IntoIterator for &'a HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl IntoIterator for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = T; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + self.into_iter() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> Iterator for Iter<'a, K> { + type Item = &'a K; + + fn next(&mut self) -> Option<&'a K> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> ExactSizeIterator for Iter<'a, K> { + fn len(&self) -> usize { self.iter.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for IntoIter { + type Item = K; + + fn next(&mut self) -> Option { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for IntoIter { + fn len(&self) -> usize { self.iter.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> Iterator for Drain<'a, K> { + type Item = K; + + fn next(&mut self) -> Option { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> ExactSizeIterator for Drain<'a, K> { + fn len(&self) -> usize { self.iter.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for Intersection<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for Difference<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if !self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for Union<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} + +#[cfg(test)] +mod test_set { + use prelude::v1::*; + + use super::HashSet; + + #[test] + fn test_disjoint() { + let mut xs = HashSet::new(); + let mut ys = HashSet::new(); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(5)); + assert!(ys.insert(11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(7)); + assert!(xs.insert(19)); + assert!(xs.insert(4)); + assert!(ys.insert(2)); + assert!(ys.insert(-11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(ys.insert(7)); + assert!(!xs.is_disjoint(&ys)); + assert!(!ys.is_disjoint(&xs)); + } + + #[test] + fn test_subset_and_superset() { + let mut a = HashSet::new(); + assert!(a.insert(0)); + assert!(a.insert(5)); + assert!(a.insert(11)); + assert!(a.insert(7)); + + let mut b = HashSet::new(); + assert!(b.insert(0)); + assert!(b.insert(7)); + assert!(b.insert(19)); + assert!(b.insert(250)); + assert!(b.insert(11)); + assert!(b.insert(200)); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(!b.is_superset(&a)); + + assert!(b.insert(5)); + + assert!(a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(b.is_superset(&a)); + } + + #[test] + fn test_iterate() { + let mut a = HashSet::new(); + for i in 0..32 { + assert!(a.insert(i)); + } + let mut observed: u32 = 0; + for k in &a { + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); + } + + #[test] + fn test_intersection() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(11)); + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(77)); + assert!(a.insert(103)); + assert!(a.insert(5)); + assert!(a.insert(-5)); + + assert!(b.insert(2)); + assert!(b.insert(11)); + assert!(b.insert(77)); + assert!(b.insert(-9)); + assert!(b.insert(-42)); + assert!(b.insert(5)); + assert!(b.insert(3)); + + let mut i = 0; + let expected = [3, 5, 11, 77]; + for x in a.intersection(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_difference() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(3)); + assert!(b.insert(9)); + + let mut i = 0; + let expected = [1, 5, 11]; + for x in a.difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_symmetric_difference() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(-2)); + assert!(b.insert(3)); + assert!(b.insert(9)); + assert!(b.insert(14)); + assert!(b.insert(22)); + + let mut i = 0; + let expected = [-2, 1, 5, 11, 14, 22]; + for x in a.symmetric_difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_union() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + assert!(a.insert(16)); + assert!(a.insert(19)); + assert!(a.insert(24)); + + assert!(b.insert(-2)); + assert!(b.insert(1)); + assert!(b.insert(5)); + assert!(b.insert(9)); + assert!(b.insert(13)); + assert!(b.insert(19)); + + let mut i = 0; + let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; + for x in a.union(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_from_iter() { + let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + + let set: HashSet<_> = xs.iter().cloned().collect(); + + for x in &xs { + assert!(set.contains(x)); + } + } + + #[test] + fn test_move_iter() { + let hs = { + let mut hs = HashSet::new(); + + hs.insert('a'); + hs.insert('b'); + + hs + }; + + let v = hs.into_iter().collect::>(); + assert!(['a', 'b'] == v || ['b', 'a'] == v); + } + + #[test] + fn test_eq() { + // These constants once happened to expose a bug in insert(). + // I'm keeping them around to prevent a regression. + let mut s1 = HashSet::new(); + + s1.insert(1); + s1.insert(2); + s1.insert(3); + + let mut s2 = HashSet::new(); + + s2.insert(1); + s2.insert(2); + + assert!(s1 != s2); + + s2.insert(3); + + assert_eq!(s1, s2); + } + + #[test] + fn test_show() { + let mut set = HashSet::new(); + let empty = HashSet::::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{:?}", set); + + assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}"); + assert_eq!(format!("{:?}", empty), "HashSet {}"); + } + + #[test] + fn test_trivial_drain() { + let mut s = HashSet::::new(); + for _ in s.drain() {} + assert!(s.is_empty()); + drop(s); + + let mut s = HashSet::::new(); + drop(s.drain()); + assert!(s.is_empty()); + } + + #[test] + fn test_drain() { + let mut s: HashSet<_> = (1..100).collect(); + + // try this a bunch of times to make sure we don't screw up internal state. + for _ in 0..20 { + assert_eq!(s.len(), 99); + + { + let mut last_i = 0; + let mut d = s.drain(); + for (i, x) in d.by_ref().take(50).enumerate() { + last_i = i; + assert!(x != 0); + } + assert_eq!(last_i, 49); + } + + for _ in &s { panic!("s should be empty!"); } + + // reset to try again. + s.extend(1..100); + } + } +} diff --git a/src/libstd/collections/hash/state.rs b/src/libstd/collections/hash/state.rs index 79e01304fb8c0..7e6dd45b51e48 100644 --- a/src/libstd/collections/hash/state.rs +++ b/src/libstd/collections/hash/state.rs @@ -11,6 +11,7 @@ use clone::Clone; use default::Default; use hash; +use marker; /// A trait representing stateful hashes which can be used to hash keys in a /// `HashMap`. @@ -37,7 +38,7 @@ pub trait HashState { /// /// This struct has is 0-sized and does not need construction. #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] -pub struct DefaultState; +pub struct DefaultState(marker::PhantomData); impl HashState for DefaultState { type Hasher = H; @@ -45,9 +46,9 @@ impl HashState for DefaultState { } impl Clone for DefaultState { - fn clone(&self) -> DefaultState { DefaultState } + fn clone(&self) -> DefaultState { DefaultState(marker::PhantomData) } } impl Default for DefaultState { - fn default() -> DefaultState { DefaultState } + fn default() -> DefaultState { DefaultState(marker::PhantomData) } } diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 0bb6bd4cf356a..f301f6db92f96 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,8 +23,8 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory}; -use rt::heap::{allocate, deallocate}; +use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory}; +use rt::heap::{allocate, deallocate, EMPTY}; use collections::hash_state::HashState; const EMPTY_BUCKET: u64 = 0u64; @@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64; pub struct RawTable { capacity: usize, size: usize, - hashes: *mut u64, + hashes: Unique, + // Because K/V do not appear directly in any of the types in the struct, // inform rustc that in fact instances of K and V are reachable from here. - marker: marker::CovariantType<(K,V)>, + marker: marker::PhantomData<(K,V)>, } unsafe impl Send for RawTable {} @@ -81,7 +82,8 @@ unsafe impl Sync for RawTable {} struct RawBucket { hash: *mut u64, key: *mut K, - val: *mut V + val: *mut V, + _marker: marker::PhantomData<(K,V)>, } impl Copy for RawBucket {} @@ -141,6 +143,7 @@ impl SafeHash { /// We need to remove hashes of 0. That's reserved for empty buckets. /// This function wraps up `hash_keyed` to be the only way outside this /// module to generate a SafeHash. +#[cfg(stage0)] pub fn make_hash(hash_state: &S, t: &T) -> SafeHash where T: Hash, S: HashState, @@ -155,6 +158,22 @@ pub fn make_hash(hash_state: &S, t: &T) -> SafeHash SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() } } +/// We need to remove hashes of 0. That's reserved for empty buckets. +/// This function wraps up `hash_keyed` to be the only way outside this +/// module to generate a SafeHash. +#[cfg(not(stage0))] +pub fn make_hash(hash_state: &S, t: &T) -> SafeHash + where T: Hash, S: HashState +{ + let mut state = hash_state.hasher(); + t.hash(&mut state); + // We need to avoid 0u64 in order to prevent collisions with + // EMPTY_HASH. We can maintain our precious uniform distribution + // of initial indexes by unconditionally setting the MSB, + // effectively reducing 64-bits hashes to 63 bits. + SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() } +} + // `replace` casts a `*u64` to a `*SafeHash`. Since we statically // ensure that a `FullBucket` points to an index with a non-zero hash, // and a `SafeHash` is just a `u64` with a different name, this is @@ -170,11 +189,12 @@ fn can_alias_safehash_as_u64() { } impl RawBucket { - unsafe fn offset(self, count: int) -> RawBucket { + unsafe fn offset(self, count: isize) -> RawBucket { RawBucket { hash: self.hash.offset(count), key: self.key.offset(count), val: self.val.offset(count), + _marker: marker::PhantomData, } } } @@ -567,10 +587,11 @@ impl RawTable { return RawTable { size: 0, capacity: 0, - hashes: ptr::null_mut(), - marker: marker::CovariantType, + hashes: Unique::new(EMPTY as *mut u64), + marker: marker::PhantomData, }; } + // No need for `checked_mul` before a more restrictive check performed // later in this method. let hashes_size = capacity * size_of::(); @@ -606,8 +627,8 @@ impl RawTable { RawTable { capacity: capacity, size: 0, - hashes: hashes, - marker: marker::CovariantType, + hashes: Unique::new(hashes), + marker: marker::PhantomData, } } @@ -615,16 +636,17 @@ impl RawTable { let hashes_size = self.capacity * size_of::(); let keys_size = self.capacity * size_of::(); - let buffer = self.hashes as *mut u8; + let buffer = *self.hashes as *mut u8; let (keys_offset, vals_offset) = calculate_offsets(hashes_size, keys_size, min_align_of::(), min_align_of::()); unsafe { RawBucket { - hash: self.hashes, + hash: *self.hashes, key: buffer.offset(keys_offset as isize) as *mut K, - val: buffer.offset(vals_offset as isize) as *mut V + val: buffer.offset(vals_offset as isize) as *mut V, + _marker: marker::PhantomData, } } } @@ -634,7 +656,7 @@ impl RawTable { pub fn new(capacity: usize) -> RawTable { unsafe { let ret = RawTable::new_uninitialized(capacity); - zero_memory(ret.hashes, capacity); + zero_memory(*ret.hashes, capacity); ret } } @@ -656,7 +678,7 @@ impl RawTable { hashes_end: unsafe { self.hashes.offset(self.capacity as isize) }, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, } } @@ -681,7 +703,7 @@ impl RawTable { iter: RawBuckets { raw: raw, hashes_end: hashes_end, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, }, table: self, } @@ -694,7 +716,7 @@ impl RawTable { iter: RawBuckets { raw: raw, hashes_end: hashes_end, - marker: marker::ContravariantLifetime::<'static>, + marker: marker::PhantomData, }, table: self, } @@ -708,7 +730,7 @@ impl RawTable { raw: raw_bucket.offset(self.capacity as isize), hashes_end: raw_bucket.hash, elems_left: self.size, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, } } } @@ -718,7 +740,13 @@ impl RawTable { struct RawBuckets<'a, K, V> { raw: RawBucket, hashes_end: *mut u64, - marker: marker::ContravariantLifetime<'a>, + + // Strictly speaking, this should be &'a (K,V), but that would + // require that K:'a, and we often use RawBuckets<'static...> for + // move iterations, so that messes up a lot of other things. So + // just use `&'a (K,V)` as this is not a publicly exposed type + // anyway. + marker: marker::PhantomData<&'a ()>, } // FIXME(#19839) Remove in favor of `#[derive(Clone)]` @@ -727,7 +755,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> { RawBuckets { raw: self.raw, hashes_end: self.hashes_end, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, } } } @@ -759,7 +787,11 @@ struct RevMoveBuckets<'a, K, V> { raw: RawBucket, hashes_end: *mut u64, elems_left: usize, - marker: marker::ContravariantLifetime<'a>, + + // As above, `&'a (K,V)` would seem better, but we often use + // 'static for the lifetime, and this is not a publicly exposed + // type. + marker: marker::PhantomData<&'a ()>, } impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> { @@ -966,9 +998,10 @@ impl Clone for RawTable { #[unsafe_destructor] impl Drop for RawTable { fn drop(&mut self) { - if self.hashes.is_null() { + if self.capacity == 0 { return; } + // This is done in reverse because we've likely partially taken // some elements out with `.into_iter()` from the front. // Check if the size is 0, so we don't do a useless scan when @@ -986,7 +1019,7 @@ impl Drop for RawTable { vals_size, min_align_of::()); unsafe { - deallocate(self.hashes as *mut u8, size, align); + deallocate(*self.hashes as *mut u8, size, align); // Remember how everything was allocated out of one buffer // during initialization? We only need one call to free here. } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index be441bfec8865..0e64370df60ec 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -23,7 +23,7 @@ //! //! Rust's collections can be grouped into four major categories: //! -//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV` +//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitV` //! * Maps: `HashMap`, `BTreeMap`, `VecMap` //! * Sets: `HashSet`, `BTreeSet`, `BitVSet` //! * Misc: `BinaryHeap` @@ -43,13 +43,13 @@ //! * You want a resizable array. //! * You want a heap-allocated array. //! -//! ### Use a `RingBuf` when: +//! ### Use a `VecDeque` when: //! * You want a `Vec` that supports efficient insertion at both ends of the sequence. //! * You want a queue. //! * You want a double-ended queue (deque). //! -//! ### Use a `DList` when: -//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization. +//! ### Use a `LinkedList` when: +//! * You want a `Vec` or `VecDeque` of unknown size, and can't tolerate amortization. //! * You want to efficiently split and append lists. //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list. //! @@ -75,7 +75,7 @@ //! //! ### Use a `BitV` when: //! * You want to store an unbounded number of booleans in a small space. -//! * You want a bitvector. +//! * You want a bit vector. //! //! ### Use a `BitVSet` when: //! * You want a `VecSet`. @@ -106,20 +106,20 @@ //! //! ## Sequences //! -//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | -//! |---------|----------------|-----------------|----------------|--------|----------------| -//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | -//! | RingBuf | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | -//! | DList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | -//! | Bitv | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | +//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | +//! |--------------|----------------|-----------------|----------------|--------|----------------| +//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | +//! | VecDeque | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | +//! | LinkedList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | +//! | BitVec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | //! -//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf -//! is generally going to be faster than DList. Bitv is not a general purpose collection, and +//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque +//! is generally going to be faster than LinkedList. BitVec is not a general purpose collection, and //! therefore cannot reasonably be compared. //! //! ## Maps //! -//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet, +//! For Sets, all operations have the cost of the equivalent Map operation. For BitSet, //! refer to VecMap. //! //! | | get | insert | remove | predecessor | @@ -166,7 +166,7 @@ //! //! Any `with_capacity` constructor will instruct the collection to allocate enough space //! for the specified number of elements. Ideally this will be for exactly that many -//! elements, but some implementation details may prevent this. `Vec` and `RingBuf` can +//! elements, but some implementation details may prevent this. `Vec` and `VecDeque` can //! be relied on to allocate exactly the requested amount, though. Use `with_capacity` //! when you know exactly how many elements will be inserted, or at least have a //! reasonable upper-bound on that number. @@ -240,10 +240,10 @@ //! ``` //! //! ``` -//! use std::collections::RingBuf; +//! use std::collections::VecDeque; //! //! let vec = vec![1, 2, 3, 4]; -//! let buf: RingBuf<_> = vec.into_iter().collect(); +//! let buf: VecDeque<_> = vec.into_iter().collect(); //! ``` //! //! Iterators also provide a series of *adapter* methods for performing common tasks to @@ -362,11 +362,11 @@ #![stable(feature = "rust1", since = "1.0.0")] pub use core_collections::Bound; -pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet}; -pub use core_collections::{DList, RingBuf, VecMap}; +pub use core_collections::{BinaryHeap, BitVec, BitSet, BTreeMap, BTreeSet}; +pub use core_collections::{LinkedList, VecDeque, VecMap}; -pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set}; -pub use core_collections::{dlist, ring_buf, vec_map}; +pub use core_collections::{binary_heap, bit_vec, bit_set, btree_map, btree_set}; +pub use core_collections::{linked_list, vec_deque, vec_map}; pub use self::hash_map::HashMap; pub use self::hash_set::HashSet; diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index c5dd66630b420..b0fb9c2940351 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -112,7 +112,7 @@ impl DynamicLibrary { // This function should have a lifetime constraint of 'a on // T but that feature is still unimplemented - let raw_string = CString::from_slice(symbol.as_bytes()); + let raw_string = CString::new(symbol).unwrap(); let maybe_symbol_value = dl::check_for_errors_in(|| { dl::symbol(self.handle, raw_string.as_ptr()) }); @@ -187,7 +187,7 @@ mod test { mod dl { use prelude::v1::*; - use ffi::{self, CString}; + use ffi::{CString, CStr}; use str; use libc; use ptr; @@ -206,7 +206,7 @@ mod dl { const LAZY: libc::c_int = 1; unsafe fn open_external(filename: &[u8]) -> *mut u8 { - let s = CString::from_slice(filename); + let s = CString::new(filename).unwrap(); dlopen(s.as_ptr(), LAZY) as *mut u8 } @@ -231,7 +231,7 @@ mod dl { let ret = if ptr::null() == last_error { Ok(result) } else { - let s = ffi::c_str_to_bytes(&last_error); + let s = CStr::from_ptr(last_error).to_bytes(); Err(str::from_utf8(s).unwrap().to_string()) }; diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 93dc3efe2c4fc..8676586e7dc2a 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -926,7 +926,7 @@ mod tests { #[cfg(unix)] fn join_paths_unix() { fn test_eq(input: &[&str], output: &str) -> bool { - &*join_paths(input.iter().map(|s| *s)).unwrap() == + &*join_paths(input.iter().cloned()).unwrap() == OsStr::from_str(output) } @@ -935,14 +935,14 @@ mod tests { "/bin:/usr/bin:/usr/local/bin")); assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:")); - assert!(join_paths(["/te:st"].iter().map(|s| *s)).is_err()); + assert!(join_paths(["/te:st"].iter().cloned()).is_err()); } #[test] #[cfg(windows)] fn join_paths_windows() { fn test_eq(input: &[&str], output: &str) -> bool { - &*join_paths(input.iter().map(|s| *s)).unwrap() == + &*join_paths(input.iter().cloned()).unwrap() == OsStr::from_str(output) } @@ -953,6 +953,6 @@ mod tests { r";c:\windows;;;c:\;")); assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#)); - assert!(join_paths([r#"c:\te"st"#].iter().map(|s| *s)).is_err()); + assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err()); } } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 45089176cba96..8976813d3f91e 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -8,18 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; +use error::{Error, FromError}; use fmt; +use io; use iter::IteratorExt; use libc; use mem; +use old_io; use ops::Deref; +use option::Option::{self, Some, None}; +use result::Result::{self, Ok, Err}; use slice::{self, SliceExt}; +use str::StrExt; use string::String; use vec::Vec; -/// A type representing a C-compatible string +/// A type representing an owned C-compatible string /// -/// This type serves the primary purpose of being able to generate a +/// This type serves the primary purpose of being able to safely generate a /// C-compatible string from a Rust byte slice or vector. An instance of this /// type is a static guarantee that the underlying bytes contain no interior 0 /// bytes and the final byte is 0. @@ -44,8 +51,8 @@ use vec::Vec; /// fn my_printer(s: *const libc::c_char); /// } /// -/// let to_print = "Hello, world!"; -/// let c_to_print = CString::from_slice(to_print.as_bytes()); +/// let to_print = b"Hello, world!"; +/// let c_to_print = CString::new(to_print).unwrap(); /// unsafe { /// my_printer(c_to_print.as_ptr()); /// } @@ -53,19 +60,135 @@ use vec::Vec; /// ``` #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct CString { - inner: Vec, + inner: Vec, +} + +/// Representation of a borrowed C string. +/// +/// This dynamically sized type is only safely constructed via a borrowed +/// version of an instance of `CString`. This type can be constructed from a raw +/// C string as well and represents a C string borrowed from another location. +/// +/// Note that this structure is **not** `repr(C)` and is not recommended to be +/// placed in the signatures of FFI functions. Instead safe wrappers of FFI +/// functions may leverage the unsafe `from_ptr` constructor to provide a safe +/// interface to other consumers. +/// +/// # Examples +/// +/// Inspecting a foreign C string +/// +/// ```no_run +/// extern crate libc; +/// use std::ffi::CStr; +/// +/// extern { fn my_string() -> *const libc::c_char; } +/// +/// fn main() { +/// unsafe { +/// let slice = CStr::from_ptr(my_string()); +/// println!("string length: {}", slice.to_bytes().len()); +/// } +/// } +/// ``` +/// +/// Passing a Rust-originating C string +/// +/// ```no_run +/// extern crate libc; +/// use std::ffi::{CString, CStr}; +/// +/// fn work(data: &CStr) { +/// extern { fn work_with(data: *const libc::c_char); } +/// +/// unsafe { work_with(data.as_ptr()) } +/// } +/// +/// fn main() { +/// let s = CString::new("data data data data").unwrap(); +/// work(&s); +/// } +/// ``` +#[derive(Hash)] +pub struct CStr { + inner: [libc::c_char] +} + +/// An error returned from `CString::new` to indicate that a nul byte was found +/// in the vector provided. +#[derive(Clone, PartialEq, Debug)] +pub struct NulError(usize, Vec); + +/// A conversion trait used by the constructor of `CString` for types that can +/// be converted to a vector of bytes. +pub trait IntoBytes { + /// Consumes this container, returning a vector of bytes. + fn into_bytes(self) -> Vec; } impl CString { + /// Create a new C-compatible string from a container of bytes. + /// + /// This method will consume the provided data and use the underlying bytes + /// to construct a new string, ensuring that there is a trailing 0 byte. + /// + /// # Examples + /// + /// ```no_run + /// extern crate libc; + /// use std::ffi::CString; + /// + /// extern { fn puts(s: *const libc::c_char); } + /// + /// fn main() { + /// let to_print = CString::new("Hello!").unwrap(); + /// unsafe { + /// puts(to_print.as_ptr()); + /// } + /// } + /// ``` + /// + /// # Errors + /// + /// This function will return an error if the bytes yielded contain an + /// internal 0 byte. The error returned will contain the bytes as well as + /// the position of the nul byte. + pub fn new(t: T) -> Result { + let bytes = t.into_bytes(); + match bytes.iter().position(|x| *x == 0) { + Some(i) => Err(NulError(i, bytes)), + None => Ok(unsafe { CString::from_vec_unchecked(bytes) }), + } + } + /// Create a new C-compatible string from a byte slice. /// /// This method will copy the data of the slice provided into a new /// allocation, ensuring that there is a trailing 0 byte. /// + /// # Examples + /// + /// ```no_run + /// extern crate libc; + /// use std::ffi::CString; + /// + /// extern { fn puts(s: *const libc::c_char); } + /// + /// fn main() { + /// let to_print = CString::new("Hello!").unwrap(); + /// unsafe { + /// puts(to_print.as_ptr()); + /// } + /// } + /// ``` + /// /// # Panics /// - /// This function will panic if there are any 0 bytes already in the slice - /// provided. + /// This function will panic if the provided slice contains any + /// interior nul bytes. + #[unstable(feature = "std_misc")] + #[deprecated(since = "1.0.0", reason = "use CString::new instead")] + #[allow(deprecated)] pub fn from_slice(v: &[u8]) -> CString { CString::from_vec(v.to_vec()) } @@ -77,11 +200,15 @@ impl CString { /// /// # Panics /// - /// This function will panic if there are any 0 bytes already in the vector - /// provided. + /// This function will panic if the provided slice contains any + /// interior nul bytes. + #[unstable(feature = "std_misc")] + #[deprecated(since = "1.0.0", reason = "use CString::new instead")] pub fn from_vec(v: Vec) -> CString { - assert!(!v.iter().any(|&x| x == 0)); - unsafe { CString::from_vec_unchecked(v) } + match v.iter().position(|x| *x == 0) { + Some(i) => panic!("null byte found in slice at: {}", i), + None => unsafe { CString::from_vec_unchecked(v) }, + } } /// Create a C-compatible string from a byte vector without checking for @@ -91,31 +218,29 @@ impl CString { /// is made that `v` contains no 0 bytes. pub unsafe fn from_vec_unchecked(mut v: Vec) -> CString { v.push(0); - CString { inner: mem::transmute(v) } + CString { inner: v } } - /// Create a view into this C string which includes the trailing nul - /// terminator at the end of the string. - pub fn as_slice_with_nul(&self) -> &[libc::c_char] { &self.inner } - - /// Similar to the `as_slice` method, but returns a `u8` slice instead of a - /// `libc::c_char` slice. + /// Returns the contents of this `CString` as a slice of bytes. + /// + /// The returned slice does **not** contain the trailing nul separator and + /// it is guaranteet to not have any interior nul bytes. pub fn as_bytes(&self) -> &[u8] { - unsafe { mem::transmute(&**self) } + &self.inner[..self.inner.len() - 1] } - /// Equivalent to `as_slice_with_nul` except that the type returned is a - /// `u8` slice instead of a `libc::c_char` slice. + /// Equivalent to the `as_bytes` function except that the returned slice + /// includes the trailing nul byte. pub fn as_bytes_with_nul(&self) -> &[u8] { - unsafe { mem::transmute(self.as_slice_with_nul()) } + &self.inner } } impl Deref for CString { - type Target = [libc::c_char]; + type Target = CStr; - fn deref(&self) -> &[libc::c_char] { - &self.inner[..(self.inner.len() - 1)] + fn deref(&self) -> &CStr { + unsafe { mem::transmute(self.as_bytes_with_nul()) } } } @@ -126,54 +251,172 @@ impl fmt::Debug for CString { } } -/// Interpret a C string as a byte slice. -/// -/// This function will calculate the length of the C string provided, and it -/// will then return a corresponding slice for the contents of the C string not -/// including the nul terminator. -/// -/// This function will tie the lifetime of the returned slice to the lifetime of -/// the pointer provided. This is done to help prevent the slice from escaping -/// the lifetime of the pointer itself. If a longer lifetime is needed, then -/// `mem::copy_lifetime` should be used. -/// -/// This function is unsafe because there is no guarantee of the validity of the -/// pointer `raw` or a guarantee that a nul terminator will be found. -/// -/// # Example -/// -/// ```no_run -/// # extern crate libc; -/// # fn main() { -/// use std::ffi; -/// use std::str; -/// use libc; -/// -/// extern { -/// fn my_string() -> *const libc::c_char; -/// } -/// -/// unsafe { -/// let to_print = my_string(); -/// let slice = ffi::c_str_to_bytes(&to_print); -/// println!("string returned: {}", str::from_utf8(slice).unwrap()); -/// } -/// # } -/// ``` +impl NulError { + /// Returns the position of the nul byte in the slice that was provided to + /// `CString::from_vec`. + pub fn nul_position(&self) -> usize { self.0 } + + /// Consumes this error, returning the underlying vector of bytes which + /// generated the error in the first place. + pub fn into_vec(self) -> Vec { self.1 } +} + +impl Error for NulError { + fn description(&self) -> &str { "nul byte found in data" } +} + +impl fmt::Display for NulError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "nul byte found in provided data at position: {}", self.0) + } +} + +impl FromError for io::Error { + fn from_error(_: NulError) -> io::Error { + io::Error::new(io::ErrorKind::InvalidInput, + "data provided contains a nul byte", None) + } +} + +impl FromError for old_io::IoError { + fn from_error(_: NulError) -> old_io::IoError { + old_io::IoError { + kind: old_io::IoErrorKind::InvalidInput, + desc: "data provided contains a nul byte", + detail: None + } + } +} + +impl CStr { + /// Cast a raw C string to a safe C string wrapper. + /// + /// This function will cast the provided `ptr` to the `CStr` wrapper which + /// allows inspection and interoperation of non-owned C strings. This method + /// is unsafe for a number of reasons: + /// + /// * There is no guarantee to the validity of `ptr` + /// * The returned lifetime is not guaranteed to be the actual lifetime of + /// `ptr` + /// * There is no guarantee that the memory pointed to by `ptr` contains a + /// valid nul terminator byte at the end of the string. + /// + /// > **Note**: This operation is intended to be a 0-cost cast but it is + /// > currently implemented with an up-front calculation of the length of + /// > the string. This is not guaranteed to always be the case. + /// + /// # Example + /// + /// ```no_run + /// # extern crate libc; + /// # fn main() { + /// use std::ffi::CStr; + /// use std::str; + /// use libc; + /// + /// extern { + /// fn my_string() -> *const libc::c_char; + /// } + /// + /// unsafe { + /// let slice = CStr::from_ptr(my_string()); + /// println!("string returned: {}", + /// str::from_utf8(slice.to_bytes()).unwrap()); + /// } + /// # } + /// ``` + pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr { + let len = libc::strlen(ptr); + mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) + } + + /// Return the inner pointer to this C string. + /// + /// The returned pointer will be valid for as long as `self` is and points + /// to a continguous region of memory terminated with a 0 byte to represent + /// the end of the string. + pub fn as_ptr(&self) -> *const libc::c_char { + self.inner.as_ptr() + } + + /// Convert this C string to a byte slice. + /// + /// This function will calculate the length of this string (which normally + /// requires a linear amount of work to be done) and then return the + /// resulting slice of `u8` elements. + /// + /// The returned slice will **not** contain the trailing nul that this C + /// string has. + /// + /// > **Note**: This method is currently implemented as a 0-cost cast, but + /// > it is planned to alter its definition in the future to perform the + /// > length calculation whenever this method is called. + pub fn to_bytes(&self) -> &[u8] { + let bytes = self.to_bytes_with_nul(); + &bytes[..bytes.len() - 1] + } + + /// Convert this C string to a byte slice containing the trailing 0 byte. + /// + /// This function is the equivalent of `to_bytes` except that it will retain + /// the trailing nul instead of chopping it off. + /// + /// > **Note**: This method is currently implemented as a 0-cost cast, but + /// > it is planned to alter its definition in the future to perform the + /// > length calculation whenever this method is called. + pub fn to_bytes_with_nul(&self) -> &[u8] { + unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } + } +} + +impl PartialEq for CStr { + fn eq(&self, other: &CStr) -> bool { + self.to_bytes().eq(&other.to_bytes()) + } +} +impl Eq for CStr {} +impl PartialOrd for CStr { + fn partial_cmp(&self, other: &CStr) -> Option { + self.to_bytes().partial_cmp(&other.to_bytes()) + } +} +impl Ord for CStr { + fn cmp(&self, other: &CStr) -> Ordering { + self.to_bytes().cmp(&other.to_bytes()) + } +} + +/// Deprecated in favor of `CStr` +#[unstable(feature = "std_misc")] +#[deprecated(since = "1.0.0", reason = "use CStr::from_ptr(p).to_bytes() instead")] pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] { let len = libc::strlen(*raw); slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize) } -/// Interpret a C string as a byte slice with the nul terminator. -/// -/// This function is identical to `from_raw_buf` except that the returned slice -/// will include the nul terminator of the string. -pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] { +/// Deprecated in favor of `CStr` +#[unstable(feature = "std_misc")] +#[deprecated(since = "1.0.0", + reason = "use CStr::from_ptr(p).to_bytes_with_nul() instead")] +pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) + -> &'a [u8] { let len = libc::strlen(*raw) + 1; slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize) } +impl<'a> IntoBytes for &'a str { + fn into_bytes(self) -> Vec { self.as_bytes().to_vec() } +} +impl<'a> IntoBytes for &'a [u8] { + fn into_bytes(self) -> Vec { self.to_vec() } +} +impl IntoBytes for String { + fn into_bytes(self) -> Vec { self.into_bytes() } +} +impl IntoBytes for Vec { + fn into_bytes(self) -> Vec { self } +} + #[cfg(test)] mod tests { use prelude::v1::*; @@ -193,21 +436,19 @@ mod tests { #[test] fn simple() { - let s = CString::from_slice(b"1234"); + let s = CString::new(b"1234").unwrap(); assert_eq!(s.as_bytes(), b"1234"); assert_eq!(s.as_bytes_with_nul(), b"1234\0"); - unsafe { - assert_eq!(&*s, - mem::transmute::<_, &[libc::c_char]>(b"1234")); - assert_eq!(s.as_slice_with_nul(), - mem::transmute::<_, &[libc::c_char]>(b"1234\0")); - } } - #[should_fail] #[test] - fn build_with_zero1() { CString::from_slice(b"\0"); } - #[should_fail] #[test] - fn build_with_zero2() { CString::from_vec(vec![0]); } + #[test] + fn build_with_zero1() { + assert!(CString::new(b"\0").is_err()); + } + #[test] + fn build_with_zero2() { + assert!(CString::new(vec![0]).is_err()); + } #[test] fn build_with_zero3() { @@ -219,7 +460,16 @@ mod tests { #[test] fn formatted() { - let s = CString::from_slice(b"12"); + let s = CString::new(b"12").unwrap(); assert_eq!(format!("{:?}", s), "\"12\""); } + + #[test] + fn borrowed() { + unsafe { + let s = CStr::from_ptr(b"12\0".as_ptr() as *const _); + assert_eq!(s.to_bytes(), b"12"); + assert_eq!(s.to_bytes_with_nul(), b"12\0"); + } + } } diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 07a4f17796c49..1bff6afb77607 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -14,8 +14,10 @@ reason = "module just underwent fairly large reorganization and the dust \ still needs to settle")] -pub use self::c_str::CString; +pub use self::c_str::{CString, CStr, NulError, IntoBytes}; +#[allow(deprecated)] pub use self::c_str::c_str_to_bytes; +#[allow(deprecated)] pub use self::c_str::c_str_to_bytes_with_nul; pub use self::os_str::OsString; diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 1d14b141778f0..84149a2eb8e43 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -34,13 +34,14 @@ use core::prelude::*; -use core::borrow::{BorrowFrom, ToOwned}; +use borrow::{Borrow, ToOwned}; use fmt::{self, Debug}; use mem; use string::{String, CowString}; use ops; use cmp; -use hash::{Hash, Hasher, Writer}; +use hash::{Hash, Hasher}; +#[cfg(stage0)] use hash::Writer; use old_path::{Path, GenericPath}; use sys::os_str::{Buf, Slice}; @@ -103,7 +104,7 @@ impl ops::Deref for OsString { #[inline] fn deref(&self) -> &OsStr { - &self[] + &self[..] } } @@ -162,12 +163,21 @@ impl Ord for OsString { } } +#[cfg(stage0)] impl<'a, S: Hasher + Writer> Hash for OsString { #[inline] fn hash(&self, state: &mut S) { (&**self).hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for OsString { + #[inline] + fn hash(&self, state: &mut H) { + (&**self).hash(state) + } +} impl OsStr { /// Coerce directly from a `&str` slice to a `&OsStr` slice. @@ -253,12 +263,21 @@ impl Ord for OsStr { fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } } +#[cfg(stage0)] impl<'a, S: Hasher + Writer> Hash for OsStr { #[inline] fn hash(&self, state: &mut S) { self.bytes().hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for OsStr { + #[inline] + fn hash(&self, state: &mut H) { + self.bytes().hash(state) + } +} impl Debug for OsStr { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { @@ -266,11 +285,12 @@ impl Debug for OsStr { } } -impl BorrowFrom for OsStr { - fn borrow_from(owned: &OsString) -> &OsStr { &owned[] } +impl Borrow for OsString { + fn borrow(&self) -> &OsStr { &self[..] } } -impl ToOwned for OsStr { +impl ToOwned for OsStr { + type Owned = OsString; fn to_owned(&self) -> OsString { self.to_os_string() } } @@ -288,7 +308,7 @@ impl AsOsStr for OsStr { impl AsOsStr for OsString { fn as_os_str(&self) -> &OsStr { - &self[] + &self[..] } } @@ -300,7 +320,7 @@ impl AsOsStr for str { impl AsOsStr for String { fn as_os_str(&self) -> &OsStr { - OsStr::from_str(&self[]) + OsStr::from_str(&self[..]) } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 2fd6631ecc437..e9a8dbb4098af 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -618,14 +618,14 @@ mod tests { #[test] fn read_char_buffered() { let buf = [195u8, 159u8]; - let mut reader = BufReader::with_capacity(1, &buf[]); + let mut reader = BufReader::with_capacity(1, &buf[..]); assert_eq!(reader.chars().next(), Some(Ok('ß'))); } #[test] fn test_chars() { let buf = [195u8, 159u8, b'a']; - let mut reader = BufReader::with_capacity(1, &buf[]); + let mut reader = BufReader::with_capacity(1, &buf[..]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); assert_eq!(it.next(), Some(Ok('a'))); diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 9f3655de20fc2..f6cb4a8c9f369 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -180,7 +180,7 @@ mod tests { fn test_buf_writer() { let mut buf = [0 as u8; 9]; { - let mut writer = Cursor::new(&mut buf[]); + let mut writer = Cursor::new(&mut buf[..]); assert_eq!(writer.position(), 0); assert_eq!(writer.write(&[0]), Ok(1)); assert_eq!(writer.position(), 1); @@ -201,7 +201,7 @@ mod tests { fn test_buf_writer_seek() { let mut buf = [0 as u8; 8]; { - let mut writer = Cursor::new(&mut buf[]); + let mut writer = Cursor::new(&mut buf[..]); assert_eq!(writer.position(), 0); assert_eq!(writer.write(&[1]), Ok(1)); assert_eq!(writer.position(), 1); @@ -229,7 +229,7 @@ mod tests { #[test] fn test_buf_writer_error() { let mut buf = [0 as u8; 2]; - let mut writer = Cursor::new(&mut buf[]); + let mut writer = Cursor::new(&mut buf[..]); assert_eq!(writer.write(&[0]), Ok(1)); assert_eq!(writer.write(&[0, 0]), Ok(1)); assert_eq!(writer.write(&[0, 0]), Ok(0)); @@ -331,7 +331,7 @@ mod tests { #[test] fn seek_past_end() { let buf = [0xff]; - let mut r = Cursor::new(&buf[]); + let mut r = Cursor::new(&buf[..]); assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10)); assert_eq!(r.read(&mut [0]), Ok(0)); @@ -340,7 +340,7 @@ mod tests { assert_eq!(r.read(&mut [0]), Ok(0)); let mut buf = [0]; - let mut r = Cursor::new(&mut buf[]); + let mut r = Cursor::new(&mut buf[..]); assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10)); assert_eq!(r.write(&[3]), Ok(0)); } @@ -348,14 +348,14 @@ mod tests { #[test] fn seek_before_0() { let buf = [0xff_u8]; - let mut r = Cursor::new(&buf[]); + let mut r = Cursor::new(&buf[..]); assert!(r.seek(SeekFrom::End(-2)).is_err()); let mut r = Cursor::new(vec!(10u8)); assert!(r.seek(SeekFrom::End(-2)).is_err()); let mut buf = [0]; - let mut r = Cursor::new(&mut buf[]); + let mut r = Cursor::new(&mut buf[..]); assert!(r.seek(SeekFrom::End(-2)).is_err()); } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7c9a8a7b4b5ad..fbd403ea593b8 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -161,7 +161,6 @@ extern crate libc; // NB: These reexports are in the order they should be listed in rustdoc pub use core::any; -pub use core::borrow; pub use core::cell; pub use core::clone; #[cfg(not(test))] pub use core::cmp; @@ -184,6 +183,7 @@ pub use core::error; #[cfg(not(test))] pub use alloc::boxed; pub use alloc::rc; +pub use core_collections::borrow; pub use core_collections::fmt; pub use core_collections::slice; pub use core_collections::str; diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 66d4d34f8eb54..51944adf3b403 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -147,6 +147,7 @@ impl PartialEq for Repr { } impl Eq for Repr {} +#[cfg(stage0)] impl hash::Hash for Repr { fn hash(&self, s: &mut S) { match *self { @@ -160,6 +161,21 @@ impl hash::Hash for Repr { } } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Repr { + fn hash(&self, s: &mut H) { + match *self { + Repr::V4(ref a) => { + (a.sin_family, a.sin_port, a.sin_addr.s_addr).hash(s) + } + Repr::V6(ref a) => { + (a.sin6_family, a.sin6_port, &a.sin6_addr.s6_addr, + a.sin6_flowinfo, a.sin6_scope_id).hash(s) + } + } + } +} /// A trait for objects which can be converted or resolved to one or more /// `SocketAddr` values. diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 08f7a6e2e9636..571a1b03ef07f 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -189,11 +189,19 @@ impl PartialEq for Ipv4Addr { } impl Eq for Ipv4Addr {} +#[cfg(stage0)] impl hash::Hash for Ipv4Addr { fn hash(&self, s: &mut S) { self.inner.s_addr.hash(s) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Ipv4Addr { + fn hash(&self, s: &mut H) { + self.inner.s_addr.hash(s) + } +} impl PartialOrd for Ipv4Addr { fn partial_cmp(&self, other: &Ipv4Addr) -> Option { @@ -421,11 +429,19 @@ impl PartialEq for Ipv6Addr { } impl Eq for Ipv6Addr {} +#[cfg(stage0)] impl hash::Hash for Ipv6Addr { fn hash(&self, s: &mut S) { self.inner.s6_addr.hash(s) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Ipv6Addr { + fn hash(&self, s: &mut H) { + self.inner.s6_addr.hash(s) + } +} impl PartialOrd for Ipv6Addr { fn partial_cmp(&self, other: &Ipv6Addr) -> Option { diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs index 59a437ad91653..2d2d0d8b33a4c 100644 --- a/src/libstd/old_io/buffered.rs +++ b/src/libstd/old_io/buffered.rs @@ -546,7 +546,7 @@ mod test { assert_eq!(a, &w.get_ref()[]); let w = w.into_inner(); let a: &[_] = &[0, 1]; - assert_eq!(a, &w[]); + assert_eq!(a, &w[..]); } // This is just here to make sure that we don't infinite loop in the @@ -643,14 +643,14 @@ mod test { #[test] fn read_char_buffered() { let buf = [195u8, 159u8]; - let mut reader = BufferedReader::with_capacity(1, &buf[]); + let mut reader = BufferedReader::with_capacity(1, &buf[..]); assert_eq!(reader.read_char(), Ok('ß')); } #[test] fn test_chars() { let buf = [195u8, 159u8, b'a']; - let mut reader = BufferedReader::with_capacity(1, &buf[]); + let mut reader = BufferedReader::with_capacity(1, &buf[..]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); assert_eq!(it.next(), Some(Ok('a'))); diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs index 21282a0c28abb..fc3deb67f41ec 100644 --- a/src/libstd/old_io/mod.rs +++ b/src/libstd/old_io/mod.rs @@ -252,7 +252,7 @@ use error::Error; use fmt; use isize; use iter::{Iterator, IteratorExt}; -use marker::Sized; +use marker::{PhantomFn, Sized}; use mem::transmute; use ops::FnOnce; use option::Option; @@ -433,7 +433,7 @@ pub enum IoErrorKind { } /// A trait that lets you add a `detail` to an IoError easily -trait UpdateIoError { +trait UpdateIoError { /// Returns an IoError with updated description and detail fn update_err(self, desc: &'static str, detail: D) -> Self where D: FnOnce(&IoError) -> String; @@ -446,7 +446,7 @@ trait UpdateIoError { fn update_desc(self, desc: &'static str) -> Self; } -impl UpdateIoError for IoResult { +impl UpdateIoError for IoResult { fn update_err(self, desc: &'static str, detail: D) -> IoResult where D: FnOnce(&IoError) -> String, { @@ -1572,7 +1572,9 @@ pub trait Seek { /// connections. /// /// Doing so produces some sort of Acceptor. -pub trait Listener> { +pub trait Listener> + : PhantomFn // FIXME should be an assoc type anyhow +{ /// Spin up the listener and start queuing incoming connections /// /// # Error diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index 8a4e8668b1092..d05669d32b8cf 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -55,7 +55,7 @@ impl UnixStream { /// stream.write(&[1, 2, 3]); /// ``` pub fn connect(path: P) -> IoResult { - let path = CString::from_slice(path.container_as_bytes()); + let path = try!(CString::new(path.container_as_bytes())); UnixStreamImp::connect(&path, None) .map(|inner| UnixStream { inner: inner }) } @@ -77,7 +77,7 @@ impl UnixStream { return Err(standard_error(TimedOut)); } - let path = CString::from_slice(path.container_as_bytes()); + let path = try!(CString::new(path.container_as_bytes())); UnixStreamImp::connect(&path, Some(timeout.num_milliseconds() as u64)) .map(|inner| UnixStream { inner: inner }) } @@ -184,7 +184,7 @@ impl UnixListener { /// # } /// ``` pub fn bind(path: P) -> IoResult { - let path = CString::from_slice(path.container_as_bytes()); + let path = try!(CString::new(path.container_as_bytes())); UnixListenerImp::bind(&path) .map(|inner| UnixListener { inner: inner }) } diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index ea6510c61b76b..c803cfbcb7d85 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -104,7 +104,7 @@ struct EnvKey(CString); #[derive(Eq, Clone, Debug)] struct EnvKey(CString); -#[cfg(windows)] +#[cfg(all(windows, stage0))] impl hash::Hash for EnvKey { fn hash(&self, state: &mut H) { let &EnvKey(ref x) = self; @@ -116,6 +116,18 @@ impl hash::Hash for EnvKey { } } } +#[cfg(all(windows, not(stage0)))] +impl hash::Hash for EnvKey { + fn hash(&self, state: &mut H) { + let &EnvKey(ref x) = self; + match str::from_utf8(x.as_bytes()) { + Ok(s) => for ch in s.chars() { + (ch as u8 as char).to_lowercase().hash(state); + }, + Err(..) => x.hash(state) + } + } +} #[cfg(windows)] impl PartialEq for EnvKey { @@ -204,7 +216,7 @@ impl Command { /// otherwise configure the process. pub fn new(program: T) -> Command { Command { - program: CString::from_slice(program.container_as_bytes()), + program: CString::new(program.container_as_bytes()).unwrap(), args: Vec::new(), env: None, cwd: None, @@ -219,14 +231,14 @@ impl Command { /// Add an argument to pass to the program. pub fn arg<'a, T: BytesContainer>(&'a mut self, arg: T) -> &'a mut Command { - self.args.push(CString::from_slice(arg.container_as_bytes())); + self.args.push(CString::new(arg.container_as_bytes()).unwrap()); self } /// Add multiple arguments to pass to the program. pub fn args<'a, T: BytesContainer>(&'a mut self, args: &[T]) -> &'a mut Command { self.args.extend(args.iter().map(|arg| { - CString::from_slice(arg.container_as_bytes()) + CString::new(arg.container_as_bytes()).unwrap() })); self } @@ -239,8 +251,8 @@ impl Command { // if the env is currently just inheriting from the parent's, // materialize the parent's env into a hashtable. self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| { - (EnvKey(CString::from_slice(&k)), - CString::from_slice(&v)) + (EnvKey(CString::new(k).unwrap()), + CString::new(v).unwrap()) }).collect()); self.env.as_mut().unwrap() } @@ -254,8 +266,8 @@ impl Command { pub fn env<'a, T, U>(&'a mut self, key: T, val: U) -> &'a mut Command where T: BytesContainer, U: BytesContainer { - let key = EnvKey(CString::from_slice(key.container_as_bytes())); - let val = CString::from_slice(val.container_as_bytes()); + let key = EnvKey(CString::new(key.container_as_bytes()).unwrap()); + let val = CString::new(val.container_as_bytes()).unwrap(); self.get_env_map().insert(key, val); self } @@ -263,7 +275,7 @@ impl Command { /// Removes an environment variable mapping. pub fn env_remove<'a, T>(&'a mut self, key: T) -> &'a mut Command where T: BytesContainer { - let key = EnvKey(CString::from_slice(key.container_as_bytes())); + let key = EnvKey(CString::new(key.container_as_bytes()).unwrap()); self.get_env_map().remove(&key); self } @@ -276,15 +288,15 @@ impl Command { -> &'a mut Command where T: BytesContainer, U: BytesContainer { self.env = Some(env.iter().map(|&(ref k, ref v)| { - (EnvKey(CString::from_slice(k.container_as_bytes())), - CString::from_slice(v.container_as_bytes())) + (EnvKey(CString::new(k.container_as_bytes()).unwrap()), + CString::new(v.container_as_bytes()).unwrap()) }).collect()); self } /// Set the working directory for the child process. pub fn cwd<'a>(&'a mut self, dir: &Path) -> &'a mut Command { - self.cwd = Some(CString::from_slice(dir.as_vec())); + self.cwd = Some(CString::new(dir.as_vec()).unwrap()); self } @@ -1226,7 +1238,7 @@ mod tests { cmd.env("path", "foo"); cmd.env("Path", "bar"); let env = &cmd.env.unwrap(); - let val = env.get(&EnvKey(CString::from_slice(b"PATH"))); - assert!(val.unwrap() == &CString::from_slice(b"bar")); + let val = env.get(&EnvKey(CString::new(b"PATH").unwrap())); + assert!(val.unwrap() == &CString::new(b"bar").unwrap()); } } diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs index 37de2993c4d0f..e9005aa22bcfb 100644 --- a/src/libstd/old_path/mod.rs +++ b/src/libstd/old_path/mod.rs @@ -877,7 +877,7 @@ impl BytesContainer for String { } #[inline] fn container_as_str(&self) -> Option<&str> { - Some(&self[]) + Some(&self[..]) } #[inline] fn is_str(_: Option<&String>) -> bool { true } @@ -893,7 +893,7 @@ impl BytesContainer for [u8] { impl BytesContainer for Vec { #[inline] fn container_as_bytes(&self) -> &[u8] { - &self[] + &self[..] } } diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs index 0a184a01a1d03..15eee9e4a0c02 100644 --- a/src/libstd/old_path/posix.rs +++ b/src/libstd/old_path/posix.rs @@ -100,12 +100,21 @@ impl FromStr for Path { #[derive(Debug, Clone, PartialEq, Copy)] pub struct ParsePathError; +#[cfg(stage0)] impl hash::Hash for Path { #[inline] fn hash(&self, state: &mut S) { self.repr.hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Path { + #[inline] + fn hash(&self, state: &mut H) { + self.repr.hash(state) + } +} impl BytesContainer for Path { #[inline] @@ -1172,7 +1181,7 @@ mod tests { let exp: &[&[u8]] = &[$($exp),*]; assert_eq!(comps, exp); let comps = path.components().rev().collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); + let exp = exp.iter().rev().cloned().collect::>(); assert_eq!(comps, exp) } ) @@ -1204,7 +1213,7 @@ mod tests { let exp: &[Option<&str>] = &$exp; assert_eq!(comps, exp); let comps = path.str_components().rev().collect::>>(); - let exp = exp.iter().rev().map(|&x|x).collect::>>(); + let exp = exp.iter().rev().cloned().collect::>>(); assert_eq!(comps, exp); } ) diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs index 02a21321c4cb9..887dc804c7af3 100644 --- a/src/libstd/old_path/windows.rs +++ b/src/libstd/old_path/windows.rs @@ -127,6 +127,7 @@ impl FromStr for Path { #[derive(Debug, Clone, PartialEq, Copy)] pub struct ParsePathError; +#[cfg(stage0)] impl hash::Hash for Path { #[cfg(not(test))] #[inline] @@ -140,6 +141,21 @@ impl hash::Hash for Path { // No-op because the `hash` implementation will be wrong. } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Path { + #[cfg(not(test))] + #[inline] + fn hash(&self, state: &mut H) { + self.repr.hash(state) + } + + #[cfg(test)] + #[inline] + fn hash(&self, _: &mut H) { + // No-op because the `hash` implementation will be wrong. + } +} impl BytesContainer for Path { #[inline] @@ -182,7 +198,7 @@ impl GenericPathUnsafe for Path { s.push_str(".."); s.push(SEP); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } None => { self.update_normalized(filename); @@ -192,20 +208,20 @@ impl GenericPathUnsafe for Path { s.push_str(&self.repr[..end]); s.push(SEP); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => { let mut s = String::with_capacity(idxb + filename.len()); s.push_str(&self.repr[..idxb]); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } Some((idxb,_,_)) => { let mut s = String::with_capacity(idxb + 1 + filename.len()); s.push_str(&self.repr[..idxb]); s.push(SEP); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } } } @@ -229,7 +245,7 @@ impl GenericPathUnsafe for Path { } fn shares_volume(me: &Path, path: &str) -> bool { // path is assumed to have a prefix of Some(DiskPrefix) - let repr = &me.repr[]; + let repr = &me.repr[..]; match me.prefix { Some(DiskPrefix) => { repr.as_bytes()[0] == path.as_bytes()[0].to_ascii_uppercase() @@ -261,7 +277,7 @@ impl GenericPathUnsafe for Path { else { None }; let pathlen = path_.as_ref().map_or(path.len(), |p| p.len()); let mut s = String::with_capacity(me.repr.len() + 1 + pathlen); - s.push_str(&me.repr[]); + s.push_str(&me.repr[..]); let plen = me.prefix_len(); // if me is "C:" we don't want to add a path separator match me.prefix { @@ -273,9 +289,9 @@ impl GenericPathUnsafe for Path { } match path_ { None => s.push_str(path), - Some(p) => s.push_str(&p[]), + Some(p) => s.push_str(&p[..]), }; - me.update_normalized(&s[]) + me.update_normalized(&s[..]) } if !path.is_empty() { @@ -329,7 +345,7 @@ impl GenericPath for Path { /// Always returns a `Some` value. #[inline] fn as_str<'a>(&'a self) -> Option<&'a str> { - Some(&self.repr[]) + Some(&self.repr[..]) } #[inline] @@ -351,13 +367,13 @@ impl GenericPath for Path { /// Always returns a `Some` value. fn dirname_str<'a>(&'a self) -> Option<&'a str> { Some(match self.sepidx_or_prefix_len() { - None if ".." == self.repr => &self.repr[], + None if ".." == self.repr => &self.repr[..], None => ".", Some((_,idxa,end)) if &self.repr[idxa..end] == ".." => { - &self.repr[] + &self.repr[..] } Some((idxb,_,end)) if &self.repr[idxb..end] == "\\" => { - &self.repr[] + &self.repr[..] } Some((0,idxa,_)) => &self.repr[..idxa], Some((idxb,idxa,_)) => { @@ -379,7 +395,7 @@ impl GenericPath for Path { /// See `GenericPath::filename_str` for info. /// Always returns a `Some` value if `filename` returns a `Some` value. fn filename_str<'a>(&'a self) -> Option<&'a str> { - let repr = &self.repr[]; + let repr = &self.repr[..]; match self.sepidx_or_prefix_len() { None if "." == repr || ".." == repr => None, None => Some(repr), @@ -639,7 +655,7 @@ impl Path { /// Does not distinguish between absolute and cwd-relative paths, e.g. /// C:\foo and C:foo. pub fn str_components<'a>(&'a self) -> StrComponents<'a> { - let repr = &self.repr[]; + let repr = &self.repr[..]; let s = match self.prefix { Some(_) => { let plen = self.prefix_len(); @@ -667,8 +683,8 @@ impl Path { } fn equiv_prefix(&self, other: &Path) -> bool { - let s_repr = &self.repr[]; - let o_repr = &other.repr[]; + let s_repr = &self.repr[..]; + let o_repr = &other.repr[..]; match (self.prefix, other.prefix) { (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => { self.is_absolute() && @@ -823,7 +839,7 @@ impl Path { fn update_sepidx(&mut self) { let s = if self.has_nonsemantic_trailing_slash() { &self.repr[..self.repr.len()-1] - } else { &self.repr[] }; + } else { &self.repr[..] }; let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) { is_sep } else { @@ -902,7 +918,7 @@ pub fn is_verbatim(path: &Path) -> bool { /// non-verbatim, the non-verbatim version is returned. /// Otherwise, None is returned. pub fn make_non_verbatim(path: &Path) -> Option { - let repr = &path.repr[]; + let repr = &path.repr[..]; let new_path = match path.prefix { Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None, Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()), @@ -2226,7 +2242,7 @@ mod tests { assert_eq!(comps, exp); let comps = path.str_components().rev().map(|x|x.unwrap()) .collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); + let exp = exp.iter().rev().cloned().collect::>(); assert_eq!(comps, exp); } ); @@ -2282,7 +2298,7 @@ mod tests { let exp: &[&[u8]] = &$exp; assert_eq!(comps, exp); let comps = path.components().rev().collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); + let exp = exp.iter().rev().cloned().collect::>(); assert_eq!(comps, exp); } ) diff --git a/src/libstd/os.rs b/src/libstd/os.rs index a4213e7373b1e..f181fc5df5759 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -561,10 +561,11 @@ pub fn get_exit_status() -> int { #[cfg(target_os = "macos")] unsafe fn load_argc_and_argv(argc: int, argv: *const *const c_char) -> Vec> { + use ffi::CStr; use iter::range; - (0..argc as uint).map(|i| { - ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec() + (0..argc).map(|i| { + CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec() }).collect() } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 35221a7e647cc..2e05f6d974e3e 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -37,7 +37,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) { let msg = match obj.downcast_ref::<&'static str>() { Some(s) => *s, None => match obj.downcast_ref::() { - Some(s) => &s[], + Some(s) => &s[..], None => "Box", } }; diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1d992668900f0..49a5efec7c2e4 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -108,12 +108,11 @@ use core::prelude::*; use ascii::*; -use borrow::BorrowFrom; +use borrow::{Borrow, ToOwned, Cow}; use cmp; -use iter; +use iter::{self, IntoIterator}; use mem; use ops::{self, Deref}; -use string::CowString; use vec::Vec; use fmt; @@ -953,7 +952,7 @@ impl PathBuf { } impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath { - fn from_iter>(iter: I) -> PathBuf { + fn from_iter>(iter: I) -> PathBuf { let mut buf = PathBuf::new(""); buf.extend(iter); buf @@ -961,7 +960,7 @@ impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath { } impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for p in iter { self.push(p) } @@ -978,16 +977,21 @@ impl ops::Deref for PathBuf { type Target = Path; fn deref(&self) -> &Path { - unsafe { mem::transmute(&self.inner[]) } + unsafe { mem::transmute(&self.inner[..]) } } } -impl BorrowFrom for Path { - fn borrow_from(owned: &PathBuf) -> &Path { - owned.deref() +impl Borrow for PathBuf { + fn borrow(&self) -> &Path { + self.deref() } } +impl ToOwned for Path { + type Owned = PathBuf; + fn to_owned(&self) -> PathBuf { self.to_path_buf() } +} + impl cmp::PartialEq for PathBuf { fn eq(&self, other: &PathBuf) -> bool { self.components() == other.components() @@ -1010,7 +1014,7 @@ impl cmp::Ord for PathBuf { impl AsOsStr for PathBuf { fn as_os_str(&self) -> &OsStr { - &self.inner[] + &self.inner[..] } } @@ -1066,10 +1070,10 @@ impl Path { self.inner.to_str() } - /// Convert a `Path` to a `CowString`. + /// Convert a `Path` to a `Cow`. /// /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. - pub fn to_string_lossy(&self) -> CowString { + pub fn to_string_lossy(&self) -> Cow { self.inner.to_string_lossy() } diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index 25d372b406f76..5c89144119803 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -547,7 +547,7 @@ mod test { #[test] fn test_choose() { let mut r = thread_rng(); - assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1)); + assert_eq!(r.choose(&[1, 1, 1]).cloned(), Some(1)); let v: &[int] = &[]; assert_eq!(r.choose(v), None); diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index c2f5133eaf3fe..61f5bd0f01360 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -49,7 +49,7 @@ mod imp { use libc; use mem; - use ffi; + use ffi::CStr; use sync::{StaticMutex, MUTEX_INIT}; @@ -96,10 +96,11 @@ mod imp { unsafe { mem::transmute(&GLOBAL_ARGS_PTR) } } - unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec> { + unsafe fn load_argc_and_argv(argc: isize, + argv: *const *const u8) -> Vec> { let argv = argv as *const *const libc::c_char; - (0..argc as uint).map(|i| { - ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec() + (0..argc).map(|i| { + CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec() }).collect() } diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 7325e0a5ac8dd..e2ac5ac24f89e 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -12,8 +12,7 @@ use prelude::v1::*; use self::SocketStatus::*; use self::InAddr::*; -use ffi::CString; -use ffi; +use ffi::{CString, CStr}; use old_io::net::addrinfo; use old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr}; use old_io::{IoResult, IoError}; @@ -235,9 +234,15 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>, assert!(host.is_some() || servname.is_some()); - let c_host = host.map(|x| CString::from_slice(x.as_bytes())); + let c_host = match host { + Some(x) => Some(try!(CString::new(x))), + None => None, + }; let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null()); - let c_serv = servname.map(|x| CString::from_slice(x.as_bytes())); + let c_serv = match servname { + Some(x) => Some(try!(CString::new(x))), + None => None, + }; let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null()); let hint = hint.map(|hint| { @@ -325,8 +330,8 @@ pub fn get_address_name(addr: IpAddr) -> Result { } unsafe { - Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr())) - .unwrap().to_string()) + let data = CStr::from_ptr(hostbuf.as_ptr()); + Ok(str::from_utf8(data.to_bytes()).unwrap().to_string()) } } diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net2.rs index 5af59ec6d2b14..713f79c5d0814 100644 --- a/src/libstd/sys/common/net2.rs +++ b/src/libstd/sys/common/net2.rs @@ -121,7 +121,7 @@ impl Drop for LookupHost { pub fn lookup_host(host: &str) -> io::Result { init(); - let c_host = CString::from_slice(host.as_bytes()); + let c_host = try!(CString::new(host)); let mut res = 0 as *mut _; unsafe { try!(cvt_gai(getaddrinfo(c_host.as_ptr(), 0 as *const _, 0 as *const _, diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index b610f6c370bb3..ca3ae1a7a3436 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -31,8 +31,9 @@ use ascii::*; use borrow::Cow; use cmp; use fmt; -use hash::{Hash, Writer, Hasher}; -use iter::FromIterator; +use hash::{Hash, Hasher}; +#[cfg(stage0)] use hash::Writer; +use iter::{FromIterator, IntoIterator}; use mem; use num::Int; use ops; @@ -356,9 +357,9 @@ impl Wtf8Buf { /// This replaces surrogate code point pairs with supplementary code points, /// like concatenating ill-formed UTF-16 strings effectively would. impl FromIterator for Wtf8Buf { - fn from_iter>(iterator: T) -> Wtf8Buf { + fn from_iter>(iter: T) -> Wtf8Buf { let mut string = Wtf8Buf::new(); - string.extend(iterator); + string.extend(iter); string } } @@ -368,7 +369,8 @@ impl FromIterator for Wtf8Buf { /// This replaces surrogate code point pairs with supplementary code points, /// like concatenating ill-formed UTF-16 strings effectively would. impl Extend for Wtf8Buf { - fn extend>(&mut self, iterator: T) { + fn extend>(&mut self, iterable: T) { + let iterator = iterable.into_iter(); let (low, _high) = iterator.size_hint(); // Lower bound of one byte per code point (ASCII only) self.bytes.reserve(low); @@ -794,13 +796,22 @@ impl<'a> Iterator for EncodeWide<'a> { } } +#[cfg(stage0)] impl Hash for CodePoint { #[inline] fn hash(&self, state: &mut S) { self.value.hash(state) } } +#[cfg(not(stage0))] +impl Hash for CodePoint { + #[inline] + fn hash(&self, state: &mut H) { + self.value.hash(state) + } +} +#[cfg(stage0)] impl Hash for Wtf8Buf { #[inline] fn hash(&self, state: &mut S) { @@ -808,7 +819,16 @@ impl Hash for Wtf8Buf { 0xfeu8.hash(state) } } +#[cfg(not(stage0))] +impl Hash for Wtf8Buf { + #[inline] + fn hash(&self, state: &mut H) { + state.write(&self.bytes); + 0xfeu8.hash(state) + } +} +#[cfg(stage0)] impl<'a, S: Writer + Hasher> Hash for Wtf8 { #[inline] fn hash(&self, state: &mut S) { @@ -816,6 +836,14 @@ impl<'a, S: Writer + Hasher> Hash for Wtf8 { 0xfeu8.hash(state) } } +#[cfg(not(stage0))] +impl Hash for Wtf8 { + #[inline] + fn hash(&self, state: &mut H) { + state.write(&self.bytes); + 0xfeu8.hash(state) + } +} impl AsciiExt for Wtf8 { type Owned = Wtf8Buf; diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index 5e512e9261b1d..8b560339f3044 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -85,7 +85,7 @@ use prelude::v1::*; -use ffi; +use ffi::CStr; use old_io::IoResult; use libc; use mem; @@ -233,7 +233,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { output(w, idx,addr, None) } else { output(w, idx, addr, Some(unsafe { - ffi::c_str_to_bytes(&info.dli_sname) + CStr::from_ptr(info.dli_sname).to_bytes() })) } } @@ -364,7 +364,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { if ret == 0 || data.is_null() { output(w, idx, addr, None) } else { - output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) })) + output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() })) } } diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index bbbe022fbaf61..b8b9dcfb3c689 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -33,7 +33,7 @@ use prelude::v1::*; -use ffi::{CString, OsStr, OsString}; +use ffi::{CString, NulError, OsStr, OsString}; use fs::{self, Permissions, OpenOptions}; use net; use mem; @@ -155,7 +155,7 @@ pub trait OsStrExt { fn as_bytes(&self) -> &[u8]; /// Convert the `OsStr` slice into a `CString`. - fn to_cstring(&self) -> CString; + fn to_cstring(&self) -> Result; } impl OsStrExt for OsStr { @@ -166,8 +166,8 @@ impl OsStrExt for OsStr { &self.as_inner().inner } - fn to_cstring(&self) -> CString { - CString::from_slice(self.as_bytes()) + fn to_cstring(&self) -> Result { + CString::new(self.as_bytes()) } } @@ -249,5 +249,7 @@ impl ExitStatusExt for process::ExitStatus { /// Includes all extension traits, and some important type definitions. pub mod prelude { #[doc(no_inline)] - pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt, CommandExt, ExitStatusExt}; + pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt}; + #[doc(no_inline)] + pub use super::{CommandExt, ExitStatusExt}; } diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 0ee2b5b68090e..5c847002d2394 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -12,7 +12,7 @@ use prelude::v1::*; -use ffi::{self, CString}; +use ffi::{CString, CStr}; use old_io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode}; use old_io::{IoResult, FileStat, SeekStyle}; use old_io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append}; @@ -151,8 +151,8 @@ impl Drop for FileDesc { } } -fn cstr(path: &Path) -> CString { - CString::from_slice(path.as_vec()) +fn cstr(path: &Path) -> IoResult { + Ok(try!(CString::new(path.as_vec()))) } pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult { @@ -170,7 +170,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult { libc::S_IRUSR | libc::S_IWUSR), }; - let path = cstr(path); + let path = try!(cstr(path)); match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) { -1 => Err(super::last_error()), fd => Ok(FileDesc::new(fd, true)), @@ -178,7 +178,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult { } pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) }) } @@ -203,7 +203,7 @@ pub fn readdir(p: &Path) -> IoResult> { let mut buf = Vec::::with_capacity(size as uint); let ptr = buf.as_mut_ptr() as *mut dirent_t; - let p = CString::from_slice(p.as_vec()); + let p = try!(CString::new(p.as_vec())); let dir_ptr = unsafe {opendir(p.as_ptr())}; if dir_ptr as uint != 0 { @@ -212,7 +212,7 @@ pub fn readdir(p: &Path) -> IoResult> { while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } { if entry_ptr.is_null() { break } paths.push(unsafe { - Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr))) + Path::new(CStr::from_ptr(rust_list_dir_val(entry_ptr)).to_bytes()) }); } assert_eq!(unsafe { closedir(dir_ptr) }, 0); @@ -223,39 +223,39 @@ pub fn readdir(p: &Path) -> IoResult> { } pub fn unlink(p: &Path) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(unsafe { libc::unlink(p.as_ptr()) }) } pub fn rename(old: &Path, new: &Path) -> IoResult<()> { - let old = cstr(old); - let new = cstr(new); + let old = try!(cstr(old)); + let new = try!(cstr(new)); mkerr_libc(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }) } pub fn chmod(p: &Path, mode: uint) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(retry(|| unsafe { libc::chmod(p.as_ptr(), mode as libc::mode_t) })) } pub fn rmdir(p: &Path) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) }) } pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(retry(|| unsafe { libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })) } pub fn readlink(p: &Path) -> IoResult { - let c_path = cstr(p); + let c_path = try!(cstr(p)); let p = c_path.as_ptr(); let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) }; if len == -1 { @@ -276,14 +276,14 @@ pub fn readlink(p: &Path) -> IoResult { } pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) }) } pub fn link(src: &Path, dst: &Path) -> IoResult<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) }) } @@ -331,7 +331,7 @@ fn mkstat(stat: &libc::stat) -> FileStat { } pub fn stat(p: &Path) -> IoResult { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; match unsafe { libc::stat(p.as_ptr(), &mut stat) } { 0 => Ok(mkstat(&stat)), @@ -340,7 +340,7 @@ pub fn stat(p: &Path) -> IoResult { } pub fn lstat(p: &Path) -> IoResult { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; match unsafe { libc::lstat(p.as_ptr(), &mut stat) } { 0 => Ok(mkstat(&stat)), @@ -349,7 +349,7 @@ pub fn lstat(p: &Path) -> IoResult { } pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); let buf = libc::utimbuf { actime: (atime / 1000) as libc::time_t, modtime: (mtime / 1000) as libc::time_t, diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs index e5904b074bcb9..92a47c6c3850d 100644 --- a/src/libstd/sys/unix/fs2.rs +++ b/src/libstd/sys/unix/fs2.rs @@ -12,7 +12,7 @@ use core::prelude::*; use io::prelude::*; use os::unix::prelude::*; -use ffi::{self, CString, OsString, AsOsStr, OsStr}; +use ffi::{CString, CStr, OsString, AsOsStr, OsStr}; use io::{self, Error, Seek, SeekFrom}; use libc::{self, c_int, c_void, size_t, off_t, c_char, mode_t}; use mem; @@ -147,8 +147,7 @@ impl DirEntry { fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char; } unsafe { - let ptr = rust_list_dir_val(self.dirent); - ffi::c_str_to_bytes(mem::copy_lifetime(self, &ptr)) + CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes() } } } @@ -204,7 +203,7 @@ impl File { (true, false) | (false, false) => libc::O_RDONLY, }; - let path = cstr(path); + let path = try!(cstr(path)); let fd = try!(cvt_r(|| unsafe { libc::open(path.as_ptr(), flags, opts.mode) })); @@ -268,19 +267,20 @@ impl File { pub fn fd(&self) -> &FileDesc { &self.0 } } -fn cstr(path: &Path) -> CString { - CString::from_slice(path.as_os_str().as_bytes()) +fn cstr(path: &Path) -> io::Result { + let cstring = try!(path.as_os_str().to_cstring()); + Ok(cstring) } pub fn mkdir(p: &Path) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) })); Ok(()) } pub fn readdir(p: &Path) -> io::Result { let root = Rc::new(p.to_path_buf()); - let p = cstr(p); + let p = try!(cstr(p)); unsafe { let ptr = libc::opendir(p.as_ptr()); if ptr.is_null() { @@ -292,32 +292,32 @@ pub fn readdir(p: &Path) -> io::Result { } pub fn unlink(p: &Path) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt(unsafe { libc::unlink(p.as_ptr()) })); Ok(()) } pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let old = cstr(old); - let new = cstr(new); + let old = try!(cstr(old)); + let new = try!(cstr(new)); try!(cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })); Ok(()) } pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })); Ok(()) } pub fn rmdir(p: &Path) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt(unsafe { libc::rmdir(p.as_ptr()) })); Ok(()) } pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt_r(|| unsafe { libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })); @@ -325,7 +325,7 @@ pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> { } pub fn readlink(p: &Path) -> io::Result { - let c_path = cstr(p); + let c_path = try!(cstr(p)); let p = c_path.as_ptr(); let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) }; if len < 0 { @@ -343,35 +343,35 @@ pub fn readlink(p: &Path) -> io::Result { } pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); try!(cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })); Ok(()) } pub fn link(src: &Path, dst: &Path) -> io::Result<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); try!(cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })); Ok(()) } pub fn stat(p: &Path) -> io::Result { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; try!(cvt(unsafe { libc::stat(p.as_ptr(), &mut stat) })); Ok(FileAttr { stat: stat }) } pub fn lstat(p: &Path) -> io::Result { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; try!(cvt(unsafe { libc::lstat(p.as_ptr(), &mut stat) })); Ok(FileAttr { stat: stat }) } pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); let buf = [super::ms_to_timeval(atime), super::ms_to_timeval(mtime)]; try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) })); Ok(()) diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 850189140d1eb..b79ad7031fa48 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -17,7 +17,7 @@ use prelude::v1::*; -use ffi; +use ffi::CStr; use io::{self, ErrorKind}; use libc; use num::{Int, SignedInt}; @@ -91,7 +91,8 @@ pub fn last_gai_error(s: libc::c_int) -> IoError { let mut err = decode_error(s); err.detail = Some(unsafe { - str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string() + let data = CStr::from_ptr(gai_strerror(s)); + str::from_utf8(data.to_bytes()).unwrap().to_string() }); err } diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 54aec7cf4b193..83b6a14b78d95 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -10,7 +10,7 @@ use prelude::v1::*; -use ffi; +use ffi::CStr; use io; use libc::{self, c_int, size_t}; use str; @@ -31,7 +31,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } let detail = unsafe { - str::from_utf8(ffi::c_str_to_bytes(&c::gai_strerror(err))).unwrap() + str::from_utf8(CStr::from_ptr(c::gai_strerror(err)).to_bytes()).unwrap() .to_string() }; Err(io::Error::new(io::ErrorKind::Other, diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 5fe84cafb71e2..3d1ef3a2c37f7 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -14,7 +14,7 @@ use prelude::v1::*; use os::unix::*; use error::Error as StdError; -use ffi::{self, CString, OsString, OsStr, AsOsStr}; +use ffi::{CString, CStr, OsString, OsStr, AsOsStr}; use fmt; use iter; use libc::{self, c_int, c_char, c_void}; @@ -88,7 +88,7 @@ pub fn error_string(errno: i32) -> String { } let p = p as *const _; - str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string() + str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string() } } @@ -98,13 +98,13 @@ pub fn getcwd() -> IoResult { if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { Err(IoError::last_error()) } else { - Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr()))) + Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes())) } } } pub fn chdir(p: &Path) -> IoResult<()> { - let p = CString::from_slice(p.as_vec()); + let p = CString::new(p.as_vec()).unwrap(); unsafe { match libc::chdir(p.as_ptr()) == (0 as c_int) { true => Ok(()), @@ -211,7 +211,7 @@ pub fn current_exe() -> IoResult { if v.is_null() { Err(IoError::last_error()) } else { - Ok(Path::new(ffi::c_str_to_bytes(&v).to_vec())) + Ok(Path::new(CStr::from_ptr(&v).to_bytes().to_vec())) } } } @@ -266,7 +266,7 @@ pub fn args() -> Args { let (argc, argv) = (*_NSGetArgc() as isize, *_NSGetArgv() as *const *const c_char); range(0, argc as isize).map(|i| { - let bytes = ffi::c_str_to_bytes(&*argv.offset(i)).to_vec(); + let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec(); OsStringExt::from_vec(bytes) }).collect::>() }; @@ -324,7 +324,7 @@ pub fn args() -> Args { let tmp = objc_msgSend(args, object_at_sel, i); let utf_c_str: *const libc::c_char = mem::transmute(objc_msgSend(tmp, utf8_sel)); - let bytes = ffi::c_str_to_bytes(&utf_c_str); + let bytes = CStr::from_ptr(utf_c_str).to_bytes(); res.push(OsString::from_str(str::from_utf8(bytes).unwrap())) } } @@ -380,7 +380,7 @@ pub fn env() -> Env { } let mut result = Vec::new(); while *environ != ptr::null() { - result.push(parse(ffi::c_str_to_bytes(&*environ))); + result.push(parse(CStr::from_ptr(*environ).to_bytes())); environ = environ.offset(1); } Env { iter: result.into_iter(), _dont_send_or_sync_me: 0 as *mut _ } @@ -397,20 +397,20 @@ pub fn env() -> Env { pub fn getenv(k: &OsStr) -> Option { unsafe { - let s = CString::from_slice(k.as_bytes()); + let s = k.to_cstring().unwrap(); let s = libc::getenv(s.as_ptr()) as *const _; if s.is_null() { None } else { - Some(OsStringExt::from_vec(ffi::c_str_to_bytes(&s).to_vec())) + Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec())) } } } pub fn setenv(k: &OsStr, v: &OsStr) { unsafe { - let k = CString::from_slice(k.as_bytes()); - let v = CString::from_slice(v.as_bytes()); + let k = k.to_cstring().unwrap(); + let v = v.to_cstring().unwrap(); if libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1) != 0 { panic!("failed setenv: {}", IoError::last_error()); } @@ -419,7 +419,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) { pub fn unsetenv(n: &OsStr) { unsafe { - let nbuf = CString::from_slice(n.as_bytes()); + let nbuf = n.to_cstring().unwrap(); if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 { panic!("failed unsetenv: {}", IoError::last_error()); } @@ -480,7 +480,7 @@ pub fn home_dir() -> Option { _ => return None } let ptr = passwd.pw_dir as *const _; - let bytes = ffi::c_str_to_bytes(&ptr).to_vec(); + let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); return Some(OsStringExt::from_vec(bytes)) } } diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 45d5b1506c3aa..3c9cdc65975f6 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -38,7 +38,7 @@ fn addr_to_sockaddr_un(addr: &CString, mem::size_of::()); let s = unsafe { &mut *(storage as *mut _ as *mut libc::sockaddr_un) }; - let len = addr.len(); + let len = addr.as_bytes().len(); if len > s.sun_path.len() - 1 { return Err(IoError { kind: old_io::InvalidInput, @@ -47,8 +47,8 @@ fn addr_to_sockaddr_un(addr: &CString, }) } s.sun_family = libc::AF_UNIX as libc::sa_family_t; - for (slot, value) in s.sun_path.iter_mut().zip(addr.iter()) { - *slot = *value; + for (slot, value) in s.sun_path.iter_mut().zip(addr.as_bytes().iter()) { + *slot = *value as libc::c_char; } // count the null terminator diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index f954024b0e9e3..b30ac889120c2 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -12,6 +12,7 @@ use prelude::v1::*; use self::Req::*; use collections::HashMap; +#[cfg(stage0)] use collections::hash_map::Hasher; use ffi::CString; use hash::Hash; @@ -63,6 +64,7 @@ impl Process { mkerr_libc(r) } + #[cfg(stage0)] pub fn spawn(cfg: &C, in_fd: Option

, out_fd: Option

, err_fd: Option

) -> IoResult @@ -278,6 +280,214 @@ impl Process { }) }) } + #[cfg(not(stage0))] + pub fn spawn(cfg: &C, in_fd: Option

, + out_fd: Option

, err_fd: Option

) + -> IoResult + where C: ProcessConfig, P: AsInner, + K: BytesContainer + Eq + Hash, V: BytesContainer + { + use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; + use libc::funcs::bsd44::getdtablesize; + + mod rustrt { + extern { + pub fn rust_unset_sigprocmask(); + } + } + + unsafe fn set_cloexec(fd: c_int) { + let ret = c::ioctl(fd, c::FIOCLEX); + assert_eq!(ret, 0); + } + + let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null()); + + // temporary until unboxed closures land + let cfg = unsafe { + mem::transmute::<&ProcessConfig,&'static ProcessConfig>(cfg) + }; + + with_envp(cfg.env(), move|envp: *const c_void| { + with_argv(cfg.program(), cfg.args(), move|argv: *const *const libc::c_char| unsafe { + let (input, mut output) = try!(sys::os::pipe()); + + // We may use this in the child, so perform allocations before the + // fork + let devnull = b"/dev/null\0"; + + set_cloexec(output.fd()); + + let pid = fork(); + if pid < 0 { + return Err(super::last_error()) + } else if pid > 0 { + #[inline] + fn combine(arr: &[u8]) -> i32 { + let a = arr[0] as u32; + let b = arr[1] as u32; + let c = arr[2] as u32; + let d = arr[3] as u32; + + ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32 + } + + let p = Process{ pid: pid }; + drop(output); + let mut bytes = [0; 8]; + return match input.read(&mut bytes) { + Ok(8) => { + assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]), + "Validation on the CLOEXEC pipe failed: {:?}", bytes); + let errno = combine(&bytes[0.. 4]); + assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); + Err(super::decode_error(errno)) + } + Err(ref e) if e.kind == EndOfFile => Ok(p), + Err(e) => { + assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); + panic!("the CLOEXEC pipe failed: {:?}", e) + }, + Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic + assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); + panic!("short read on the CLOEXEC pipe") + } + }; + } + + // And at this point we've reached a special time in the life of the + // child. The child must now be considered hamstrung and unable to + // do anything other than syscalls really. Consider the following + // scenario: + // + // 1. Thread A of process 1 grabs the malloc() mutex + // 2. Thread B of process 1 forks(), creating thread C + // 3. Thread C of process 2 then attempts to malloc() + // 4. The memory of process 2 is the same as the memory of + // process 1, so the mutex is locked. + // + // This situation looks a lot like deadlock, right? It turns out + // that this is what pthread_atfork() takes care of, which is + // presumably implemented across platforms. The first thing that + // threads to *before* forking is to do things like grab the malloc + // mutex, and then after the fork they unlock it. + // + // Despite this information, libnative's spawn has been witnessed to + // deadlock on both OSX and FreeBSD. I'm not entirely sure why, but + // all collected backtraces point at malloc/free traffic in the + // child spawned process. + // + // For this reason, the block of code below should contain 0 + // invocations of either malloc of free (or their related friends). + // + // As an example of not having malloc/free traffic, we don't close + // this file descriptor by dropping the FileDesc (which contains an + // allocation). Instead we just close it manually. This will never + // have the drop glue anyway because this code never returns (the + // child will either exec() or invoke libc::exit) + let _ = libc::close(input.fd()); + + fn fail(output: &mut FileDesc) -> ! { + let errno = sys::os::errno() as u32; + let bytes = [ + (errno >> 24) as u8, + (errno >> 16) as u8, + (errno >> 8) as u8, + (errno >> 0) as u8, + CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1], + CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3] + ]; + // pipe I/O up to PIPE_BUF bytes should be atomic + assert!(output.write(&bytes).is_ok()); + unsafe { libc::_exit(1) } + } + + rustrt::rust_unset_sigprocmask(); + + // If a stdio file descriptor is set to be ignored (via a -1 file + // descriptor), then we don't actually close it, but rather open + // up /dev/null into that file descriptor. Otherwise, the first file + // descriptor opened up in the child would be numbered as one of the + // stdio file descriptors, which is likely to wreak havoc. + let setup = |src: Option

, dst: c_int| { + let src = match src { + None => { + let flags = if dst == libc::STDIN_FILENO { + libc::O_RDONLY + } else { + libc::O_RDWR + }; + libc::open(devnull.as_ptr() as *const _, flags, 0) + } + Some(obj) => { + let fd = obj.as_inner().fd(); + // Leak the memory and the file descriptor. We're in the + // child now an all our resources are going to be + // cleaned up very soon + mem::forget(obj); + fd + } + }; + src != -1 && retry(|| dup2(src, dst)) != -1 + }; + + if !setup(in_fd, libc::STDIN_FILENO) { fail(&mut output) } + if !setup(out_fd, libc::STDOUT_FILENO) { fail(&mut output) } + if !setup(err_fd, libc::STDERR_FILENO) { fail(&mut output) } + + // close all other fds + for fd in (3..getdtablesize()).rev() { + if fd != output.fd() { + let _ = close(fd as c_int); + } + } + + match cfg.gid() { + Some(u) => { + if libc::setgid(u as libc::gid_t) != 0 { + fail(&mut output); + } + } + None => {} + } + match cfg.uid() { + Some(u) => { + // When dropping privileges from root, the `setgroups` call + // will remove any extraneous groups. If we don't call this, + // then even though our uid has dropped, we may still have + // groups that enable us to do super-user things. This will + // fail if we aren't root, so don't bother checking the + // return value, this is just done as an optimistic + // privilege dropping function. + extern { + fn setgroups(ngroups: libc::c_int, + ptr: *const libc::c_void) -> libc::c_int; + } + let _ = setgroups(0, ptr::null()); + + if libc::setuid(u as libc::uid_t) != 0 { + fail(&mut output); + } + } + None => {} + } + if cfg.detach() { + // Don't check the error of setsid because it fails if we're the + // process leader already. We just forked so it shouldn't return + // error, but ignore it anyway. + let _ = libc::setsid(); + } + if !dirp.is_null() && chdir(dirp) == -1 { + fail(&mut output); + } + if !envp.is_null() { + *sys::os::environ() = envp as *const _; + } + let _ = execvp(*argv, argv as *mut _); + fail(&mut output); + }) + }) + } pub fn wait(&self, deadline: u64) -> IoResult { use cmp; @@ -556,6 +766,7 @@ fn with_argv(prog: &CString, args: &[CString], cb(ptrs.as_ptr()) } +#[cfg(stage0)] fn with_envp(env: Option<&HashMap>, cb: F) -> T @@ -593,6 +804,44 @@ fn with_envp(env: Option<&HashMap>, _ => cb(ptr::null()) } } +#[cfg(not(stage0))] +fn with_envp(env: Option<&HashMap>, + cb: F) + -> T + where F : FnOnce(*const c_void) -> T, + K : BytesContainer + Eq + Hash, + V : BytesContainer +{ + // On posixy systems we can pass a char** for envp, which is a + // null-terminated array of "k=v\0" strings. Since we must create + // these strings locally, yet expose a raw pointer to them, we + // create a temporary vector to own the CStrings that outlives the + // call to cb. + match env { + Some(env) => { + let mut tmps = Vec::with_capacity(env.len()); + + for pair in env { + let mut kv = Vec::new(); + kv.push_all(pair.0.container_as_bytes()); + kv.push('=' as u8); + kv.push_all(pair.1.container_as_bytes()); + kv.push(0); // terminating null + tmps.push(kv); + } + + // As with `with_argv`, this is unsafe, since cb could leak the pointers. + let mut ptrs: Vec<*const libc::c_char> = + tmps.iter() + .map(|tmp| tmp.as_ptr() as *const libc::c_char) + .collect(); + ptrs.push(ptr::null()); + + cb(ptrs.as_ptr() as *const c_void) + } + _ => cb(ptr::null()) + } +} fn translate_status(status: c_int) -> ProcessExit { #![allow(non_snake_case)] diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs index 5e2c207f3756a..06fa5c4bba725 100644 --- a/src/libstd/sys/unix/process2.rs +++ b/src/libstd/sys/unix/process2.rs @@ -11,7 +11,6 @@ use prelude::v1::*; use collections::HashMap; -use collections::hash_map::Hasher; use env; use ffi::{OsString, OsStr, CString}; use fmt; @@ -46,7 +45,7 @@ pub struct Command { impl Command { pub fn new(program: &OsStr) -> Command { Command { - program: program.to_cstring(), + program: program.to_cstring().unwrap(), args: Vec::new(), env: None, cwd: None, @@ -57,10 +56,10 @@ impl Command { } pub fn arg(&mut self, arg: &OsStr) { - self.args.push(arg.to_cstring()) + self.args.push(arg.to_cstring().unwrap()) } pub fn args<'a, I: Iterator>(&mut self, args: I) { - self.args.extend(args.map(OsStrExt::to_cstring)) + self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap())) } fn init_env_map(&mut self) { if self.env.is_none() { @@ -79,7 +78,7 @@ impl Command { self.env = Some(HashMap::new()) } pub fn cwd(&mut self, dir: &OsStr) { - self.cwd = Some(dir.to_cstring()) + self.cwd = Some(dir.to_cstring().unwrap()) } } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 82c52471d1097..c90ba7645feb4 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -237,7 +237,7 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result { pub unsafe fn set_name(name: &str) { // pthread_setname_np() since glibc 2.12 // availability autodetected via weak linkage - let cname = CString::from_slice(name.as_bytes()); + let cname = CString::new(name).unwrap(); type F = unsafe extern "C" fn(libc::pthread_t, *const libc::c_char) -> libc::c_int; extern { #[linkage = "extern_weak"] @@ -255,14 +255,14 @@ pub unsafe fn set_name(name: &str) { target_os = "openbsd"))] pub unsafe fn set_name(name: &str) { // pthread_set_name_np() since almost forever on all BSDs - let cname = CString::from_slice(name.as_bytes()); + let cname = CString::new(name).unwrap(); pthread_set_name_np(pthread_self(), cname.as_ptr()); } #[cfg(any(target_os = "macos", target_os = "ios"))] pub unsafe fn set_name(name: &str) { // pthread_setname_np() since OS X 10.6 and iOS 3.2 - let cname = CString::from_slice(name.as_bytes()); + let cname = CString::new(name).unwrap(); pthread_setname_np(cname.as_ptr()); } diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index 92e309da34bef..51cf30324233c 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -25,7 +25,7 @@ #![allow(dead_code)] use dynamic_lib::DynamicLibrary; -use ffi; +use ffi::CStr; use intrinsics; use old_io::{IoResult, Writer}; use libc; @@ -362,7 +362,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> { if ret == libc::TRUE { try!(write!(w, " - ")); let ptr = info.Name.as_ptr() as *const libc::c_char; - let bytes = unsafe { ffi::c_str_to_bytes(&ptr) }; + let bytes = unsafe { CStr::from_ptr(ptr).to_bytes() }; match str::from_utf8(bytes) { Ok(s) => try!(demangle(w, s)), Err(..) => try!(w.write_all(&bytes[..bytes.len()-1])), diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index f861255a00a14..2d1a5e10bd63f 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -283,7 +283,7 @@ pub mod compat { fallback: usize) -> usize { let mut module: Vec = module.utf16_units().collect(); module.push(0); - let symbol = CString::from_slice(symbol.as_bytes()); + let symbol = CString::new(symbol).unwrap(); let func = unsafe { let handle = GetModuleHandleW(module.as_ptr()); GetProcAddress(handle, symbol.as_ptr()) as usize diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 4d6d033deee14..a756fb29f81ae 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -265,12 +265,12 @@ fn fill_utf16_buf_base(mut f1: F1, f2: F2) -> Result let mut n = stack_buf.len(); loop { let buf = if n <= stack_buf.len() { - &mut stack_buf[] + &mut stack_buf[..] } else { let extra = n - heap_buf.len(); heap_buf.reserve(extra); heap_buf.set_len(n); - &mut heap_buf[] + &mut heap_buf[..] }; // This function is typically called on windows API functions which diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 502d70d4e1a16..6520d30487c76 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -114,7 +114,7 @@ impl Iterator for Env { let (k, v) = match s.iter().position(|&b| b == '=' as u16) { Some(n) => (&s[..n], &s[n+1..]), - None => (s, &[][]), + None => (s, &[][..]), }; Some((OsStringExt::from_wide(k), OsStringExt::from_wide(v))) } @@ -186,7 +186,7 @@ impl<'a> Iterator for SplitPaths<'a> { if !must_yield && in_progress.is_empty() { None } else { - Some(super::os2path(&in_progress[])) + Some(super::os2path(&in_progress[..])) } } } @@ -208,14 +208,14 @@ pub fn join_paths(paths: I) -> Result return Err(JoinPathsError) } else if v.contains(&sep) { joined.push(b'"' as u16); - joined.push_all(&v[]); + joined.push_all(&v[..]); joined.push(b'"' as u16); } else { - joined.push_all(&v[]); + joined.push_all(&v[..]); } } - Ok(OsStringExt::from_wide(&joined[])) + Ok(OsStringExt::from_wide(&joined[..])) } impl fmt::Display for JoinPathsError { diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 96ffc4daddd4e..60d24e6174fd7 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -10,7 +10,7 @@ use prelude::v1::*; -use collections::hash_map::Hasher; +#[cfg(stage0)] use collections::hash_map::Hasher; use collections; use env; use ffi::CString; @@ -106,6 +106,7 @@ impl Process { } #[allow(deprecated)] + #[cfg(stage0)] pub fn spawn(cfg: &C, in_fd: Option

, out_fd: Option

, err_fd: Option

) -> IoResult @@ -267,6 +268,169 @@ impl Process { }) } } + #[allow(deprecated)] + #[cfg(not(stage0))] + pub fn spawn(cfg: &C, in_fd: Option

, + out_fd: Option

, err_fd: Option

) + -> IoResult + where C: ProcessConfig, P: AsInner, + K: BytesContainer + Eq + Hash, V: BytesContainer + { + use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO}; + use libc::consts::os::extra::{ + TRUE, FALSE, + STARTF_USESTDHANDLES, + INVALID_HANDLE_VALUE, + DUPLICATE_SAME_ACCESS + }; + use libc::funcs::extra::kernel32::{ + GetCurrentProcess, + DuplicateHandle, + CloseHandle, + CreateProcessW + }; + use libc::funcs::extra::msvcrt::get_osfhandle; + + use mem; + use iter::IteratorExt; + use str::StrExt; + + if cfg.gid().is_some() || cfg.uid().is_some() { + return Err(IoError { + kind: old_io::IoUnavailable, + desc: "unsupported gid/uid requested on windows", + detail: None, + }) + } + + // To have the spawning semantics of unix/windows stay the same, we need to + // read the *child's* PATH if one is provided. See #15149 for more details. + let program = cfg.env().and_then(|env| { + for (key, v) in env { + if b"PATH" != key.container_as_bytes() { continue } + + // Split the value and test each path to see if the + // program exists. + for path in os::split_paths(v.container_as_bytes()) { + let path = path.join(cfg.program().as_bytes()) + .with_extension(env::consts::EXE_EXTENSION); + if path.exists() { + return Some(CString::from_slice(path.as_vec())) + } + } + break + } + None + }); + + unsafe { + let mut si = zeroed_startupinfo(); + si.cb = mem::size_of::() as DWORD; + si.dwFlags = STARTF_USESTDHANDLES; + + let cur_proc = GetCurrentProcess(); + + // Similarly to unix, we don't actually leave holes for the stdio file + // descriptors, but rather open up /dev/null equivalents. These + // equivalents are drawn from libuv's windows process spawning. + let set_fd = |fd: &Option

, slot: &mut HANDLE, + is_stdin: bool| { + match *fd { + None => { + let access = if is_stdin { + libc::FILE_GENERIC_READ + } else { + libc::FILE_GENERIC_WRITE | libc::FILE_READ_ATTRIBUTES + }; + let size = mem::size_of::(); + let mut sa = libc::SECURITY_ATTRIBUTES { + nLength: size as libc::DWORD, + lpSecurityDescriptor: ptr::null_mut(), + bInheritHandle: 1, + }; + let mut filename: Vec = "NUL".utf16_units().collect(); + filename.push(0); + *slot = libc::CreateFileW(filename.as_ptr(), + access, + libc::FILE_SHARE_READ | + libc::FILE_SHARE_WRITE, + &mut sa, + libc::OPEN_EXISTING, + 0, + ptr::null_mut()); + if *slot == INVALID_HANDLE_VALUE { + return Err(super::last_error()) + } + } + Some(ref fd) => { + let orig = get_osfhandle(fd.as_inner().fd()) as HANDLE; + if orig == INVALID_HANDLE_VALUE { + return Err(super::last_error()) + } + if DuplicateHandle(cur_proc, orig, cur_proc, slot, + 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { + return Err(super::last_error()) + } + } + } + Ok(()) + }; + + try!(set_fd(&in_fd, &mut si.hStdInput, true)); + try!(set_fd(&out_fd, &mut si.hStdOutput, false)); + try!(set_fd(&err_fd, &mut si.hStdError, false)); + + let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program()), + cfg.args()); + let mut pi = zeroed_process_information(); + let mut create_err = None; + + // stolen from the libuv code. + let mut flags = libc::CREATE_UNICODE_ENVIRONMENT; + if cfg.detach() { + flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP; + } + + with_envp(cfg.env(), |envp| { + with_dirp(cfg.cwd(), |dirp| { + let mut cmd_str: Vec = cmd_str.utf16_units().collect(); + cmd_str.push(0); + let _lock = CREATE_PROCESS_LOCK.lock().unwrap(); + let created = CreateProcessW(ptr::null(), + cmd_str.as_mut_ptr(), + ptr::null_mut(), + ptr::null_mut(), + TRUE, + flags, envp, dirp, + &mut si, &mut pi); + if created == FALSE { + create_err = Some(super::last_error()); + } + }) + }); + + assert!(CloseHandle(si.hStdInput) != 0); + assert!(CloseHandle(si.hStdOutput) != 0); + assert!(CloseHandle(si.hStdError) != 0); + + match create_err { + Some(err) => return Err(err), + None => {} + } + + // We close the thread handle because we don't care about keeping the + // thread id valid, and we aren't keeping the thread handle around to be + // able to close it later. We don't close the process handle however + // because std::we want the process id to stay valid at least until the + // calling code closes the process handle. + assert!(CloseHandle(pi.hThread) != 0); + + Ok(Process { + pid: pi.dwProcessId as pid_t, + handle: pi.hProcess as *mut () + }) + } + } /// Waits for a process to exit and returns the exit code, failing /// if there is no process with the specified id. @@ -425,6 +589,7 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String { } } +#[cfg(stage0)] fn with_envp(env: Option<&collections::HashMap>, cb: F) -> T where K: BytesContainer + Eq + Hash, V: BytesContainer, @@ -452,6 +617,34 @@ fn with_envp(env: Option<&collections::HashMap>, cb: F) -> T _ => cb(ptr::null_mut()) } } +#[cfg(not(stage0))] +fn with_envp(env: Option<&collections::HashMap>, cb: F) -> T + where K: BytesContainer + Eq + Hash, + V: BytesContainer, + F: FnOnce(*mut c_void) -> T, +{ + // On Windows we pass an "environment block" which is not a char**, but + // rather a concatenation of null-terminated k=v\0 sequences, with a final + // \0 to terminate. + match env { + Some(env) => { + let mut blk = Vec::new(); + + for pair in env { + let kv = format!("{}={}", + pair.0.container_as_str().unwrap(), + pair.1.container_as_str().unwrap()); + blk.extend(kv.utf16_units()); + blk.push(0); + } + + blk.push(0); + + cb(blk.as_mut_ptr() as *mut c_void) + } + _ => cb(ptr::null_mut()) + } +} fn with_dirp(d: Option<&CString>, cb: F) -> T where F: FnOnce(*const u16) -> T, diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 3137d779c4071..3653e7e31d5c6 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -153,7 +153,7 @@ use any::Any; use cell::UnsafeCell; use fmt; use io; -use marker; +use marker::PhantomData; use old_io::stdio; use rt::{self, unwind}; use sync::{Mutex, Condvar, Arc}; @@ -260,7 +260,7 @@ impl Builder { T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { self.spawn_inner(Thunk::new(f)).map(|inner| { - JoinGuard { inner: inner, _marker: marker::CovariantType } + JoinGuard { inner: inner, _marker: PhantomData } }) } @@ -642,7 +642,7 @@ impl Drop for JoinHandle { #[stable(feature = "rust1", since = "1.0.0")] pub struct JoinGuard<'a, T: 'a> { inner: JoinInner, - _marker: marker::CovariantType<&'a T>, + _marker: PhantomData<&'a T>, } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d6778be553e8b..140e21b5d04b7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -198,7 +198,7 @@ impl Encodable for Ident { impl Decodable for Ident { fn decode(d: &mut D) -> Result { - Ok(str_to_ident(&try!(d.read_str())[])) + Ok(str_to_ident(&try!(d.read_str())[..])) } } diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 5535e5911e0c2..ba08f61b5575c 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -86,7 +86,7 @@ pub fn path_to_string>(path: PI) -> String { if !s.is_empty() { s.push_str("::"); } - s.push_str(&e[]); + s.push_str(&e[..]); s }) } @@ -251,7 +251,7 @@ impl<'ast> Map<'ast> { } fn find_entry(&self, id: NodeId) -> Option> { - self.map.borrow().get(id as usize).map(|e| *e) + self.map.borrow().get(id as usize).cloned() } pub fn krate(&self) -> &'ast Crate { @@ -463,20 +463,20 @@ impl<'ast> Map<'ast> { F: FnOnce(Option<&[Attribute]>) -> T, { let attrs = match self.get(id) { - NodeItem(i) => Some(&i.attrs[]), - NodeForeignItem(fi) => Some(&fi.attrs[]), + NodeItem(i) => Some(&i.attrs[..]), + NodeForeignItem(fi) => Some(&fi.attrs[..]), NodeTraitItem(ref tm) => match **tm { - RequiredMethod(ref type_m) => Some(&type_m.attrs[]), - ProvidedMethod(ref m) => Some(&m.attrs[]), - TypeTraitItem(ref typ) => Some(&typ.attrs[]), + RequiredMethod(ref type_m) => Some(&type_m.attrs[..]), + ProvidedMethod(ref m) => Some(&m.attrs[..]), + TypeTraitItem(ref typ) => Some(&typ.attrs[..]), }, NodeImplItem(ref ii) => { match **ii { - MethodImplItem(ref m) => Some(&m.attrs[]), - TypeImplItem(ref t) => Some(&t.attrs[]), + MethodImplItem(ref m) => Some(&m.attrs[..]), + TypeImplItem(ref t) => Some(&t.attrs[..]), } } - NodeVariant(ref v) => Some(&v.node.attrs[]), + NodeVariant(ref v) => Some(&v.node.attrs[..]), // unit/tuple structs take the attributes straight from // the struct definition. // FIXME(eddyb) make this work again (requires access to the map). @@ -577,7 +577,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { None => return false, Some((node_id, name)) => (node_id, name), }; - if &part[] != mod_name.as_str() { + if &part[..] != mod_name.as_str() { return false; } cursor = self.map.get_parent(mod_id); @@ -615,7 +615,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { // We are looking at some node `n` with a given name and parent // id; do their names match what I am seeking? fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool { - name.as_str() == &self.item_name[] && + name.as_str() == &self.item_name[..] && self.suffix_matches(parent_of_n) } } @@ -1026,7 +1026,7 @@ impl<'a> NodePrinter for pprust::State<'a> { fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { let id_str = format!(" (id={})", id); - let id_str = if include_id { &id_str[] } else { "" }; + let id_str = if include_id { &id_str[..] } else { "" }; match map.find(id) { Some(NodeItem(item)) => { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 117507ad8b7e8..f660296fcd7b6 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -257,11 +257,11 @@ pub fn impl_pretty_name(trait_ref: &Option, ty: &Ty) -> Ident { match *trait_ref { Some(ref trait_ref) => { pretty.push('.'); - pretty.push_str(&pprust::path_to_string(&trait_ref.path)[]); + pretty.push_str(&pprust::path_to_string(&trait_ref.path)); } None => {} } - token::gensym_ident(&pretty[]) + token::gensym_ident(&pretty[..]) } pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod { @@ -673,7 +673,7 @@ pub fn pat_is_ident(pat: P) -> bool { pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool { (a.span == b.span) && (a.global == b.global) - && (segments_name_eq(&a.segments[], &b.segments[])) + && (segments_name_eq(&a.segments[..], &b.segments[..])) } // are two arrays of segments equal when compared unhygienically? diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a3afe5780d0d5..62e676891a0e6 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -26,11 +26,11 @@ use parse::token; use ptr::P; use std::cell::{RefCell, Cell}; -use std::collections::BitvSet; +use std::collections::BitSet; use std::collections::HashSet; use std::fmt; -thread_local! { static USED_ATTRS: RefCell = RefCell::new(BitvSet::new()) } +thread_local! { static USED_ATTRS: RefCell = RefCell::new(BitSet::new()) } pub fn mark_used(attr: &Attribute) { let AttrId(id) = attr.node.id; @@ -44,7 +44,7 @@ pub fn is_used(attr: &Attribute) -> bool { pub trait AttrMetaMethods { fn check_name(&self, name: &str) -> bool { - name == &self.name()[] + name == &self.name()[..] } /// Retrieve the name of the meta item, e.g. `foo` in `#[foo]`, @@ -62,7 +62,7 @@ pub trait AttrMetaMethods { impl AttrMetaMethods for Attribute { fn check_name(&self, name: &str) -> bool { - let matches = name == &self.name()[]; + let matches = name == &self.name()[..]; if matches { mark_used(self); } @@ -101,7 +101,7 @@ impl AttrMetaMethods for MetaItem { fn meta_item_list<'a>(&'a self) -> Option<&'a [P]> { match self.node { - MetaList(_, ref l) => Some(&l[]), + MetaList(_, ref l) => Some(&l[..]), _ => None } } @@ -142,7 +142,7 @@ impl AttributeMethods for Attribute { let meta = mk_name_value_item_str( InternedString::new("doc"), token::intern_and_get_ident(&strip_doc_comment_decoration( - &comment)[])); + &comment))); if self.node.style == ast::AttrOuter { f(&mk_attr_outer(self.node.id, meta)) } else { @@ -302,9 +302,9 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr { } MetaList(ref n, ref items) if *n == "inline" => { mark_used(attr); - if contains_name(&items[], "always") { + if contains_name(&items[..], "always") { InlineAlways - } else if contains_name(&items[], "never") { + } else if contains_name(&items[..], "never") { InlineNever } else { InlineHint @@ -326,11 +326,11 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool { /// Tests if a cfg-pattern matches the cfg set pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P], cfg: &ast::MetaItem) -> bool { match cfg.node { - ast::MetaList(ref pred, ref mis) if &pred[] == "any" => + ast::MetaList(ref pred, ref mis) if &pred[..] == "any" => mis.iter().any(|mi| cfg_matches(diagnostic, cfgs, &**mi)), - ast::MetaList(ref pred, ref mis) if &pred[] == "all" => + ast::MetaList(ref pred, ref mis) if &pred[..] == "all" => mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)), - ast::MetaList(ref pred, ref mis) if &pred[] == "not" => { + ast::MetaList(ref pred, ref mis) if &pred[..] == "not" => { if mis.len() != 1 { diagnostic.span_err(cfg.span, "expected 1 cfg-pattern"); return false; @@ -382,7 +382,7 @@ fn find_stability_generic<'a, 'outer: for attr in attrs { let tag = attr.name(); - let tag = &tag[]; + let tag = &tag[..]; if tag != "deprecated" && tag != "unstable" && tag != "stable" { continue // not a stability level } @@ -404,7 +404,7 @@ fn find_stability_generic<'a, } } } - if &meta.name()[] == "since" { + if &meta.name()[..] == "since" { match meta.value_str() { Some(v) => since = Some(v), None => { @@ -413,7 +413,7 @@ fn find_stability_generic<'a, } } } - if &meta.name()[] == "reason" { + if &meta.name()[..] == "reason" { match meta.value_str() { Some(v) => reason = Some(v), None => { @@ -501,7 +501,7 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P]) { if !set.insert(name.clone()) { diagnostic.span_fatal(meta.span, - &format!("duplicate meta item `{}`", name)[]); + &format!("duplicate meta item `{}`", name)); } } } @@ -521,7 +521,7 @@ pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec { - let hint = match &word[] { + let hint = match &word[..] { // Can't use "extern" because it's not a lexical identifier. "C" => Some(ReprExtern), "packed" => Some(ReprPacked), diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3231342cb50c8..099f646294235 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -360,7 +360,7 @@ impl CodeMap { let mut src = if src.starts_with("\u{feff}") { String::from_str(&src[3..]) } else { - String::from_str(&src[]) + String::from_str(&src[..]) }; // Append '\n' in case it's not already there. diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 7ca0591be5064..dfe3477bddc3b 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -311,7 +311,7 @@ impl<'a> fold::Folder for CfgAttrFolder<'a> { } }; - if attr::cfg_matches(self.diag, &self.config[], &cfg) { + if attr::cfg_matches(self.diag, &self.config[..], &cfg) { Some(respan(mi.span, ast::Attribute_ { id: attr::mk_attr_id(), style: attr.node.style, diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 83a4d938bb5d5..27219774cf148 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -129,7 +129,7 @@ impl SpanHandler { panic!(ExplicitBug); } pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { - self.span_bug(sp, &format!("unimplemented {}", msg)[]); + self.span_bug(sp, &format!("unimplemented {}", msg)); } pub fn handler<'a>(&'a self) -> &'a Handler { &self.handler @@ -173,7 +173,7 @@ impl Handler { self.err_count.get()); } } - self.fatal(&s[]); + self.fatal(&s[..]); } pub fn warn(&self, msg: &str) { self.emit.borrow_mut().emit(None, msg, None, Warning); @@ -189,7 +189,7 @@ impl Handler { panic!(ExplicitBug); } pub fn unimpl(&self, msg: &str) -> ! { - self.bug(&format!("unimplemented {}", msg)[]); + self.bug(&format!("unimplemented {}", msg)); } pub fn emit(&self, cmsp: Option<(&codemap::CodeMap, Span)>, @@ -311,16 +311,16 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level, } try!(print_maybe_styled(dst, - &format!("{}: ", lvl.to_string())[], + &format!("{}: ", lvl.to_string()), term::attr::ForegroundColor(lvl.color()))); try!(print_maybe_styled(dst, - &format!("{}", msg)[], + &format!("{}", msg), term::attr::Bold)); match code { Some(code) => { let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA); - try!(print_maybe_styled(dst, &format!(" [{}]", code.clone())[], style)); + try!(print_maybe_styled(dst, &format!(" [{}]", code.clone()), style)); } None => () } @@ -419,12 +419,12 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, // the span) let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id}; let ses = cm.span_to_string(span_end); - try!(print_diagnostic(dst, &ses[], lvl, msg, code)); + try!(print_diagnostic(dst, &ses[..], lvl, msg, code)); if rsp.is_full_span() { try!(custom_highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp))); } } else { - try!(print_diagnostic(dst, &ss[], lvl, msg, code)); + try!(print_diagnostic(dst, &ss[..], lvl, msg, code)); if rsp.is_full_span() { try!(highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp))); } @@ -436,9 +436,9 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, Some(code) => match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) { Some(_) => { - try!(print_diagnostic(dst, &ss[], Help, + try!(print_diagnostic(dst, &ss[..], Help, &format!("pass `--explain {}` to see a detailed \ - explanation", code)[], None)); + explanation", code), None)); } None => () }, @@ -455,7 +455,7 @@ fn highlight_lines(err: &mut EmitterWriter, let fm = &*lines.file; let mut elided = false; - let mut display_lines = &lines.lines[]; + let mut display_lines = &lines.lines[..]; if display_lines.len() > MAX_LINES { display_lines = &display_lines[0..MAX_LINES]; elided = true; @@ -542,7 +542,7 @@ fn highlight_lines(err: &mut EmitterWriter, } try!(print_maybe_styled(err, - &format!("{}\n", s)[], + &format!("{}\n", s), term::attr::ForegroundColor(lvl.color()))); } } @@ -563,7 +563,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter, -> old_io::IoResult<()> { let fm = &*lines.file; - let lines = &lines.lines[]; + let lines = &lines.lines[..]; if lines.len() > MAX_LINES { if let Some(line) = fm.get_line(lines[0]) { try!(write!(&mut w.dst, "{}:{} {}\n", fm.name, @@ -610,7 +610,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter, s.push('^'); s.push('\n'); print_maybe_styled(w, - &s[], + &s[..], term::attr::ForegroundColor(lvl.color())) } @@ -618,22 +618,25 @@ fn print_macro_backtrace(w: &mut EmitterWriter, cm: &codemap::CodeMap, sp: Span) -> old_io::IoResult<()> { - let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info { - Some(ei) => { - let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span)); - let (pre, post) = match ei.callee.format { - codemap::MacroAttribute => ("#[", "]"), - codemap::MacroBang => ("", "!") - }; - try!(print_diagnostic(w, &ss[], Note, - &format!("in expansion of {}{}{}", pre, - ei.callee.name, - post)[], None)); - let ss = cm.span_to_string(ei.call_site); - try!(print_diagnostic(w, &ss[], Note, "expansion site", None)); - Ok(Some(ei.call_site)) - } - None => Ok(None) + let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> { + match expn_info { + Some(ei) => { + let ss = ei.callee.span.map_or(String::new(), + |span| cm.span_to_string(span)); + let (pre, post) = match ei.callee.format { + codemap::MacroAttribute => ("#[", "]"), + codemap::MacroBang => ("", "!") + }; + try!(print_diagnostic(w, &ss, Note, + &format!("in expansion of {}{}{}", pre, + ei.callee.name, + post), None)); + let ss = cm.span_to_string(ei.call_site); + try!(print_diagnostic(w, &ss, Note, "expansion site", None)); + Ok(Some(ei.call_site)) + } + None => Ok(None) + } })); cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site)) } @@ -643,6 +646,6 @@ pub fn expect(diag: &SpanHandler, opt: Option, msg: M) -> T where { match opt { Some(t) => t, - None => diag.handler().bug(&msg()[]), + None => diag.handler().bug(&msg()), } } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 833a6d52acb97..b3afc3fc4dd13 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -59,7 +59,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, Some(previous_span) => { ecx.span_warn(span, &format!( "diagnostic code {} already used", &token::get_ident(code) - )[]); + )); ecx.span_note(previous_span, "previous invocation"); }, None => () @@ -70,7 +70,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, if !diagnostics.contains_key(&code.name) { ecx.span_err(span, &format!( "used diagnostic code {} not registered", &token::get_ident(code) - )[]); + )); } }); MacExpr::new(quote_expr!(ecx, ())) @@ -95,12 +95,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, if diagnostics.insert(code.name, description).is_some() { ecx.span_err(span, &format!( "diagnostic code {} already registered", &token::get_ident(*code) - )[]); + )); } }); let sym = Ident::new(token::gensym(&( "__register_diagnostic_".to_string() + &token::get_ident(*code) - )[])); + ))); MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter()) } diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs index 62d48189c4347..a6cfd1a5a9ac3 100644 --- a/src/libsyntax/diagnostics/registry.rs +++ b/src/libsyntax/diagnostics/registry.rs @@ -17,10 +17,10 @@ pub struct Registry { impl Registry { pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry { - Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() } + Registry { descriptions: descriptions.iter().cloned().collect() } } pub fn find_description(&self, code: &str) -> Option<&'static str> { - self.descriptions.get(code).map(|desc| *desc) + self.descriptions.get(code).cloned() } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8800ffd1e9b5f..d4ccabbd63b4a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -640,7 +640,7 @@ impl<'a> ExtCtxt<'a> { pub fn mod_path(&self) -> Vec { let mut v = Vec::new(); v.push(token::str_to_ident(&self.ecfg.crate_name[])); - v.extend(self.mod_path.iter().map(|a| *a)); + v.extend(self.mod_path.iter().cloned()); return v; } pub fn bt_push(&mut self, ei: ExpnInfo) { diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs index 80d128959eaf3..38098e50dee83 100644 --- a/src/libsyntax/ext/concat.rs +++ b/src/libsyntax/ext/concat.rs @@ -62,5 +62,5 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, } base::MacExpr::new(cx.expr_str( sp, - token::intern_and_get_ident(&accumulator[]))) + token::intern_and_get_ident(&accumulator[..]))) } diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 63a8bd9ddf1b3..9410a51e7a5f6 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -49,7 +49,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree] } } } - let res = str_to_ident(&res_str[]); + let res = str_to_ident(&res_str[..]); let e = P(ast::Expr { id: ast::DUMMY_NODE_ID, diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index 879718a6399f5..93098484ae013 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -24,7 +24,7 @@ pub fn expand_deriving_bound(cx: &mut ExtCtxt, { let name = match mitem.node { MetaWord(ref tname) => { - match &tname[] { + match &tname[..] { "Copy" => "Copy", "Send" | "Sync" => { return cx.span_err(span, diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index f878cb5ca8b78..b912ed34ae0ad 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -367,7 +367,7 @@ impl<'a> TraitDef<'a> { "allow" | "warn" | "deny" | "forbid" => true, _ => false, } - }).map(|a| a.clone())); + }).cloned()); push(P(ast::Item { attrs: attrs, ..(*newitem).clone() @@ -410,7 +410,7 @@ impl<'a> TraitDef<'a> { let mut ty_params = ty_params.into_vec(); // Copy the lifetimes - lifetimes.extend(generics.lifetimes.iter().map(|l| (*l).clone())); + lifetimes.extend(generics.lifetimes.iter().cloned()); // Create the type parameters. ty_params.extend(generics.ty_params.iter().map(|ty_param| { @@ -445,14 +445,14 @@ impl<'a> TraitDef<'a> { span: self.span, bound_lifetimes: wb.bound_lifetimes.clone(), bounded_ty: wb.bounded_ty.clone(), - bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect()) + bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect()) }) } ast::WherePredicate::RegionPredicate(ref rb) => { ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { span: self.span, lifetime: rb.lifetime, - bounds: rb.bounds.iter().map(|b| b.clone()).collect() + bounds: rb.bounds.iter().cloned().collect() }) } ast::WherePredicate::EqPredicate(ref we) => { @@ -500,7 +500,7 @@ impl<'a> TraitDef<'a> { let opt_trait_ref = Some(trait_ref); let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type); let mut a = vec![attr]; - a.extend(self.attributes.iter().map(|a| a.clone())); + a.extend(self.attributes.iter().cloned()); cx.item( self.span, ident, @@ -536,15 +536,15 @@ impl<'a> TraitDef<'a> { self, struct_def, type_ident, - &self_args[], - &nonself_args[]) + &self_args[..], + &nonself_args[..]) } else { method_def.expand_struct_method_body(cx, self, struct_def, type_ident, - &self_args[], - &nonself_args[]) + &self_args[..], + &nonself_args[..]) }; method_def.create_method(cx, @@ -576,15 +576,15 @@ impl<'a> TraitDef<'a> { self, enum_def, type_ident, - &self_args[], - &nonself_args[]) + &self_args[..], + &nonself_args[..]) } else { method_def.expand_enum_method_body(cx, self, enum_def, type_ident, self_args, - &nonself_args[]) + &nonself_args[..]) }; method_def.create_method(cx, @@ -934,22 +934,22 @@ impl<'a> MethodDef<'a> { .collect::>(); let self_arg_idents = self_arg_names.iter() - .map(|name|cx.ident_of(&name[])) + .map(|name|cx.ident_of(&name[..])) .collect::>(); // The `vi_idents` will be bound, solely in the catch-all, to // a series of let statements mapping each self_arg to a usize // corresponding to its variant index. let vi_idents: Vec = self_arg_names.iter() - .map(|name| { let vi_suffix = format!("{}_vi", &name[]); - cx.ident_of(&vi_suffix[]) }) + .map(|name| { let vi_suffix = format!("{}_vi", &name[..]); + cx.ident_of(&vi_suffix[..]) }) .collect::>(); // Builds, via callback to call_substructure_method, the // delegated expression that handles the catch-all case, // using `__variants_tuple` to drive logic if necessary. let catch_all_substructure = EnumNonMatchingCollapsed( - self_arg_idents, &variants[], &vi_idents[]); + self_arg_idents, &variants[..], &vi_idents[..]); // These arms are of the form: // (Variant1, Variant1, ...) => Body1 @@ -976,7 +976,7 @@ impl<'a> MethodDef<'a> { idents }; for self_arg_name in self_arg_names.tail() { - let (p, idents) = mk_self_pat(cx, &self_arg_name[]); + let (p, idents) = mk_self_pat(cx, &self_arg_name[..]); subpats.push(p); self_pats_idents.push(idents); } @@ -1032,7 +1032,7 @@ impl<'a> MethodDef<'a> { &**variant, field_tuples); let arm_expr = self.call_substructure_method( - cx, trait_, type_ident, &self_args[], nonself_args, + cx, trait_, type_ident, &self_args[..], nonself_args, &substructure); cx.arm(sp, vec![single_pat], arm_expr) @@ -1085,7 +1085,7 @@ impl<'a> MethodDef<'a> { } let arm_expr = self.call_substructure_method( - cx, trait_, type_ident, &self_args[], nonself_args, + cx, trait_, type_ident, &self_args[..], nonself_args, &catch_all_substructure); // Builds the expression: @@ -1391,7 +1391,7 @@ pub fn cs_fold(use_foldl: bool, } }, EnumNonMatchingCollapsed(ref all_args, _, tuple) => - enum_nonmatch_f(cx, trait_span, (&all_args[], tuple), + enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple), substructure.nonself_args), StaticEnum(..) | StaticStruct(..) => { cx.span_bug(trait_span, "static function in `derive`") @@ -1431,7 +1431,7 @@ pub fn cs_same_method(f: F, f(cx, trait_span, called) }, EnumNonMatchingCollapsed(ref all_self_args, _, tuple) => - enum_nonmatch_f(cx, trait_span, (&all_self_args[], tuple), + enum_nonmatch_f(cx, trait_span, (&all_self_args[..], tuple), substructure.nonself_args), StaticEnum(..) | StaticStruct(..) => { cx.span_bug(trait_span, "static function in `derive`") diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 5aa9f9a0c3e76..2149c7a7f77a7 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -14,7 +14,6 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; use ext::deriving::generic::ty::*; -use parse::token::InternedString; use ptr::P; pub fn expand_deriving_hash(cx: &mut ExtCtxt, @@ -26,30 +25,26 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, { let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None, - vec!(box Literal(Path::new_local("__S"))), true); - let generics = LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec!(("__S", - vec!(path_std!(cx, core::hash::Writer), - path_std!(cx, core::hash::Hasher)))), - }; - let args = Path::new_local("__S"); - let inline = cx.meta_word(span, InternedString::new("inline")); - let attrs = vec!(cx.attribute(span, inline)); + vec!(), true); + let arg = Path::new_local("__H"); let hash_trait_def = TraitDef { span: span, attributes: Vec::new(), path: path, additional_bounds: Vec::new(), - generics: generics, + generics: LifetimeBounds::empty(), methods: vec!( MethodDef { name: "hash", - generics: LifetimeBounds::empty(), + generics: LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec![("__H", + vec![path_std!(cx, core::hash::Hasher)])], + }, explicit_self: borrowed_explicit_self(), - args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))), + args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))), ret_ty: nil_ty(), - attributes: attrs, + attributes: vec![], combine_substructure: combine_substructure(box |a, b, c| { hash_substructure(a, b, c) }) diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 0ed9e85e57677..f8bc331bfcfe7 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -102,7 +102,7 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt, |i| push(i))) } - match &tname[] { + match &tname[..] { "Clone" => expand!(clone::expand_deriving_clone), "Hash" => expand!(hash::expand_deriving_hash), diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 3f5947672e022..281f23f9e61e8 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -128,7 +128,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, let formatter = substr.nonself_args[0].clone(); let meth = cx.ident_of("write_fmt"); - let s = token::intern_and_get_ident(&format_string[]); + let s = token::intern_and_get_ident(&format_string[..]); let format_string = cx.expr_str(span, s); // phew, not our responsibility any more! diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index 5d56707c87a47..9c04d1e928295 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -30,7 +30,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT Some(v) => v }; - let e = match env::var(&var[]) { + let e = match env::var(&var[..]) { Err(..) => { cx.expr_path(cx.path_all(sp, true, @@ -56,7 +56,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT cx.ident_of("Some")), vec!(cx.expr_str(sp, token::intern_and_get_ident( - &s[])))) + &s[..])))) } }; MacExpr::new(e) @@ -101,7 +101,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } - let e = match env::var(&var[]) { + let e = match env::var(&var[..]) { Err(_) => { cx.span_err(sp, &msg); cx.expr_usize(sp, 0) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6b7cecee81576..d4dda7390a52f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -405,7 +405,7 @@ fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, }, }); let fm = fresh_mark(); - let marked_before = mark_tts(&tts[], fm); + let marked_before = mark_tts(&tts[..], fm); // The span that we pass to the expanders we want to // be the root of the call stack. That's the most @@ -416,7 +416,7 @@ fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, let opt_parsed = { let expanded = expandfun.expand(fld.cx, mac_span, - &marked_before[]); + &marked_before[..]); parse_thunk(expanded) }; let parsed = match opt_parsed { @@ -425,7 +425,7 @@ fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, fld.cx.span_err( pth.span, &format!("non-expression macro in expression position: {}", - &extnamestr[] + &extnamestr[..] )[]); return None; } @@ -633,8 +633,8 @@ pub fn expand_item_mac(it: P, } }); // mark before expansion: - let marked_before = mark_tts(&tts[], fm); - expander.expand(fld.cx, it.span, &marked_before[]) + let marked_before = mark_tts(&tts[..], fm); + expander.expand(fld.cx, it.span, &marked_before[..]) } IdentTT(ref expander, span) => { if it.ident.name == parse::token::special_idents::invalid.name { @@ -652,7 +652,7 @@ pub fn expand_item_mac(it: P, } }); // mark before expansion: - let marked_tts = mark_tts(&tts[], fm); + let marked_tts = mark_tts(&tts[..], fm); expander.expand(fld.cx, it.span, it.ident, marked_tts) } MacroRulesTT => { @@ -971,11 +971,11 @@ fn expand_pat(p: P, fld: &mut MacroExpander) -> P { }); let fm = fresh_mark(); - let marked_before = mark_tts(&tts[], fm); + let marked_before = mark_tts(&tts[..], fm); let mac_span = fld.cx.original_span(); let expanded = match expander.expand(fld.cx, mac_span, - &marked_before[]).make_pat() { + &marked_before[..]).make_pat() { Some(e) => e, None => { fld.cx.span_err( @@ -1128,7 +1128,7 @@ fn expand_annotatable(a: Annotatable, if valid_ident { fld.cx.mod_push(it.ident); } - let macro_use = contains_macro_use(fld, &new_attrs[]); + let macro_use = contains_macro_use(fld, &new_attrs[..]); let result = with_exts_frame!(fld.cx.syntax_env, macro_use, noop_fold_item(it, fld)); @@ -1508,7 +1508,7 @@ impl Folder for Marker { node: match node { MacInvocTT(path, tts, ctxt) => { MacInvocTT(self.fold_path(path), - self.fold_tts(&tts[]), + self.fold_tts(&tts[..]), mtwt::apply_mark(self.mark, ctxt)) } }, @@ -1914,7 +1914,7 @@ mod test { .collect(); println!("varref #{}: {:?}, resolves to {}",idx, varref_idents, varref_name); let string = token::get_ident(final_varref_ident); - println!("varref's first segment's string: \"{}\"", &string[]); + println!("varref's first segment's string: \"{}\"", &string[..]); println!("binding #{}: {}, resolves to {}", binding_idx, bindings[binding_idx], binding_name); mtwt::with_sctable(|x| mtwt::display_sctable(x)); @@ -1967,10 +1967,10 @@ foo_module!(); let cxbinds: Vec<&ast::Ident> = bindings.iter().filter(|b| { let ident = token::get_ident(**b); - let string = &ident[]; + let string = &ident[..]; "xx" == string }).collect(); - let cxbinds: &[&ast::Ident] = &cxbinds[]; + let cxbinds: &[&ast::Ident] = &cxbinds[..]; let cxbind = match cxbinds { [b] => b, _ => panic!("expected just one binding for ext_cx") diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 170a455a91326..e17329d7d3300 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -118,7 +118,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } }; let interned_name = token::get_ident(ident); - let name = &interned_name[]; + let name = &interned_name[..]; p.expect(&token::Eq); let e = p.parse_expr(); @@ -218,7 +218,7 @@ impl<'a, 'b> Context<'a, 'b> { let msg = format!("invalid reference to argument `{}` ({})", arg, self.describe_num_args()); - self.ecx.span_err(self.fmtsp, &msg[]); + self.ecx.span_err(self.fmtsp, &msg[..]); return; } { @@ -238,7 +238,7 @@ impl<'a, 'b> Context<'a, 'b> { Some(e) => e.span, None => { let msg = format!("there is no argument named `{}`", name); - self.ecx.span_err(self.fmtsp, &msg[]); + self.ecx.span_err(self.fmtsp, &msg[..]); return; } }; @@ -587,7 +587,7 @@ impl<'a, 'b> Context<'a, 'b> { -> P { let trait_ = match *ty { Known(ref tyname) => { - match &tyname[] { + match &tyname[..] { "" => "Display", "?" => "Debug", "e" => "LowerExp", diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 67990895d071a..2c7bf713aad85 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -668,7 +668,7 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec> { for i in 0..tt.len() { seq.push(tt.get_tt(i)); } - mk_tts(cx, &seq[]) + mk_tts(cx, &seq[..]) } ast::TtToken(sp, ref tok) => { let e_sp = cx.expr_ident(sp, id_ext("_sp")); @@ -757,7 +757,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp)); let mut vector = vec!(stmt_let_sp, stmt_let_tt); - vector.extend(mk_tts(cx, &tts[]).into_iter()); + vector.extend(mk_tts(cx, &tts[..]).into_iter()); let block = cx.expr_block( cx.block_all(sp, vector, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 7a3a3562bdfdc..c8d48750c7509 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -65,7 +65,7 @@ pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box { let s = pprust::tts_to_string(tts); base::MacExpr::new(cx.expr_str(sp, - token::intern_and_get_ident(&s[]))) + token::intern_and_get_ident(&s[..]))) } pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) @@ -78,7 +78,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) .connect("::"); base::MacExpr::new(cx.expr_str( sp, - token::intern_and_get_ident(&string[]))) + token::intern_and_get_ident(&string[..]))) } /// include! : parse the given file as an expr @@ -117,7 +117,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree None => self.p.span_fatal( self.p.span, &format!("expected item, found `{}`", - self.p.this_token_to_string())[] + self.p.this_token_to_string()) ) } } @@ -141,7 +141,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), - e)[]); + e)); return DummyResult::expr(sp); } Ok(bytes) => bytes, @@ -151,7 +151,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // Add this input file to the code map to make it available as // dependency information let filename = format!("{}", file.display()); - let interned = token::intern_and_get_ident(&src[]); + let interned = token::intern_and_get_ident(&src[..]); cx.codemap().new_filemap(filename, src); base::MacExpr::new(cx.expr_str(sp, interned)) @@ -159,7 +159,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) Err(_) => { cx.span_err(sp, &format!("{} wasn't a utf-8 file", - file.display())[]); + file.display())); return DummyResult::expr(sp); } } @@ -175,11 +175,11 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) match File::open(&file).read_to_end() { Err(e) => { cx.span_err(sp, - &format!("couldn't read {}: {}", file.display(), e)[]); + &format!("couldn't read {}: {}", file.display(), e)); return DummyResult::expr(sp); } Ok(bytes) => { - let bytes = bytes.iter().map(|x| *x).collect(); + let bytes = bytes.iter().cloned().collect(); base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes)))) } } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d649e497ef71a..664f7b3e08848 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -165,7 +165,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize { pub fn initial_matcher_pos(ms: Rc>, sep: Option, lo: BytePos) -> Box { - let match_idx_hi = count_names(&ms[]); + let match_idx_hi = count_names(&ms[..]); let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect(); box MatcherPos { stack: vec![], @@ -229,7 +229,7 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc]) p_s.span_diagnostic .span_fatal(sp, &format!("duplicated bind name: {}", - &string)[]) + &string)) } } } @@ -254,13 +254,13 @@ pub fn parse_or_else(sess: &ParseSess, rdr: TtReader, ms: Vec ) -> HashMap> { - match parse(sess, cfg, rdr, &ms[]) { + match parse(sess, cfg, rdr, &ms[..]) { Success(m) => m, Failure(sp, str) => { - sess.span_diagnostic.span_fatal(sp, &str[]) + sess.span_diagnostic.span_fatal(sp, &str[..]) } Error(sp, str) => { - sess.span_diagnostic.span_fatal(sp, &str[]) + sess.span_diagnostic.span_fatal(sp, &str[..]) } } } @@ -283,7 +283,7 @@ pub fn parse(sess: &ParseSess, -> ParseResult { let mut cur_eis = Vec::new(); cur_eis.push(initial_matcher_pos(Rc::new(ms.iter() - .map(|x| (*x).clone()) + .cloned() .collect()), None, rdr.peek().sp.lo)); @@ -447,7 +447,7 @@ pub fn parse(sess: &ParseSess, for dv in &mut (&mut eof_eis[0]).matches { v.push(dv.pop().unwrap()); } - return Success(nameize(sess, ms, &v[])); + return Success(nameize(sess, ms, &v[..])); } else if eof_eis.len() > 1 { return Error(sp, "ambiguity: multiple successful parses".to_string()); } else { @@ -533,7 +533,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { _ => { let token_str = pprust::token_to_string(&p.token); p.fatal(&format!("expected ident, found {}", - &token_str[])[]) + &token_str[..])) } }, "path" => { @@ -542,7 +542,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { "meta" => token::NtMeta(p.parse_meta_item()), _ => { p.span_fatal_help(sp, - &format!("invalid fragment specifier `{}`", name)[], + &format!("invalid fragment specifier `{}`", name), "valid fragment specifiers are `ident`, `block`, \ `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ and `item`") diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index f322cf8bad09c..fa6d934a45755 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -50,7 +50,7 @@ impl<'a> ParserAnyMacro<'a> { following", token_str); let span = parser.span; - parser.span_err(span, &msg[]); + parser.span_err(span, &msg[..]); } } } @@ -123,8 +123,8 @@ impl TTMacroExpander for MacroRulesMacroExpander { self.name, self.imported_from, arg, - &self.lhses[], - &self.rhses[]) + &self.lhses, + &self.rhses) } } @@ -151,7 +151,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, match **lhs { MatchedNonterminal(NtTT(ref lhs_tt)) => { let lhs_tt = match **lhs_tt { - TtDelimited(_, ref delim) => &delim.tts[], + TtDelimited(_, ref delim) => &delim.tts[..], _ => cx.span_fatal(sp, "malformed macro lhs") }; // `None` is because we're not interpolating @@ -159,7 +159,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, None, None, arg.iter() - .map(|x| (*x).clone()) + .cloned() .collect(), true); match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) { @@ -192,13 +192,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, best_fail_spot = sp; best_fail_msg = (*msg).clone(); }, - Error(sp, ref msg) => cx.span_fatal(sp, &msg[]) + Error(sp, ref msg) => cx.span_fatal(sp, &msg[..]) } } _ => cx.bug("non-matcher found in parsed lhses") } } - cx.span_fatal(best_fail_spot, &best_fail_msg[]); + cx.span_fatal(best_fail_spot, &best_fail_msg[..]); } // Note that macro-by-example's input is also matched against a token tree: diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 83234e3b7a5d8..0d92bd761b418 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -255,7 +255,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { } LisContradiction(ref msg) => { // FIXME #2887 blame macro invoker instead - r.sp_diag.span_fatal(sp.clone(), &msg[]); + r.sp_diag.span_fatal(sp.clone(), &msg[..]); } LisConstraint(len, _) => { if len == 0 { @@ -309,7 +309,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { r.sp_diag.span_fatal( r.cur_span, /* blame the macro writer */ &format!("variable '{:?}' is still repeating at this depth", - token::get_ident(ident))[]); + token::get_ident(ident))); } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 0110823ae98c1..071158fcebb5c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -356,7 +356,7 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: diag.span_err(span, explain); diag.span_help(span, &format!("add #![feature({})] to the \ crate attributes to enable", - feature)[]); + feature)); } pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) { @@ -364,7 +364,7 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: if diag.handler.can_emit_warnings { diag.span_help(span, &format!("add #![feature({})] to the \ crate attributes to silence this warning", - feature)[]); + feature)); } } @@ -438,7 +438,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { fn visit_item(&mut self, i: &ast::Item) { match i.node { ast::ItemExternCrate(_) => { - if attr::contains_name(&i.attrs[], "macro_reexport") { + if attr::contains_name(&i.attrs[..], "macro_reexport") { self.gate_feature("macro_reexport", i.span, "macros reexports are experimental \ and possibly buggy"); @@ -446,7 +446,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } ast::ItemForeignMod(ref foreign_module) => { - if attr::contains_name(&i.attrs[], "link_args") { + if attr::contains_name(&i.attrs[..], "link_args") { self.gate_feature("link_args", i.span, "the `link_args` attribute is not portable \ across platforms, it is recommended to \ @@ -460,17 +460,17 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } ast::ItemFn(..) => { - if attr::contains_name(&i.attrs[], "plugin_registrar") { + if attr::contains_name(&i.attrs[..], "plugin_registrar") { self.gate_feature("plugin_registrar", i.span, "compiler plugins are experimental and possibly buggy"); } - if attr::contains_name(&i.attrs[], "start") { + if attr::contains_name(&i.attrs[..], "start") { self.gate_feature("start", i.span, "a #[start] function is an experimental \ feature whose signature may change \ over time"); } - if attr::contains_name(&i.attrs[], "main") { + if attr::contains_name(&i.attrs[..], "main") { self.gate_feature("main", i.span, "declaration of a nonstandard #[main] \ function may change over time, for now \ @@ -479,7 +479,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } ast::ItemStruct(..) => { - if attr::contains_name(&i.attrs[], "simd") { + if attr::contains_name(&i.attrs[..], "simd") { self.gate_feature("simd", i.span, "SIMD types are experimental and possibly buggy"); } @@ -505,7 +505,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { removed in the future"); } - if attr::contains_name(&i.attrs[], + if attr::contains_name(&i.attrs[..], "old_orphan_check") { self.gate_feature( "old_orphan_check", @@ -513,7 +513,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { "the new orphan check rules will eventually be strictly enforced"); } - if attr::contains_name(&i.attrs[], + if attr::contains_name(&i.attrs[..], "old_impl_check") { self.gate_feature("old_impl_check", i.span, @@ -528,7 +528,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { - if attr::contains_name(&i.attrs[], "linkage") { + if attr::contains_name(&i.attrs, "linkage") { self.gate_feature("linkage", i.span, "the `linkage` attribute is experimental \ and not portable across platforms") diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index e8bdcd62b588b..3a7fa54edbdd7 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -28,7 +28,6 @@ #![feature(collections)] #![feature(core)] #![feature(env)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 0f9a56baa170b..f5201d4a8bc68 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -10,7 +10,7 @@ use std::default::Default; use std::fmt; -use std::iter::FromIterator; +use std::iter::{IntoIterator, FromIterator}; use std::ops::Deref; use std::vec; use serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -77,8 +77,8 @@ impl Clone for OwnedSlice { } impl FromIterator for OwnedSlice { - fn from_iter>(iter: I) -> OwnedSlice { - OwnedSlice::from_vec(iter.collect()) + fn from_iter>(iter: I) -> OwnedSlice { + OwnedSlice::from_vec(iter.into_iter().collect()) } } diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index b17fc7fe82e6c..1f06db600278b 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -61,7 +61,7 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle { pub fn strip_doc_comment_decoration(comment: &str) -> String { /// remove whitespace-only lines from the start/end of lines - fn vertical_trim(lines: Vec ) -> Vec { + fn vertical_trim(lines: Vec) -> Vec { let mut i = 0; let mut j = lines.len(); // first line of all-stars should be omitted @@ -82,7 +82,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String { while j > i && lines[j - 1].trim().is_empty() { j -= 1; } - return lines[i..j].iter().map(|x| (*x).clone()).collect(); + lines[i..j].iter().cloned().collect() } /// remove a "[ \t]*\*" block from each line, if possible @@ -187,7 +187,7 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool, let line = rdr.read_one_line_comment(); debug!("{}", line); // Doc comments are not put in comments. - if is_doc_comment(&line[]) { + if is_doc_comment(&line[..]) { break; } lines.push(line); @@ -224,7 +224,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option { fn trim_whitespace_prefix_and_push_line(lines: &mut Vec , s: String, col: CharPos) { let len = s.len(); - let s1 = match all_whitespace(&s[], col) { + let s1 = match all_whitespace(&s[..], col) { Some(col) => { if col < len { (&s[col..len]).to_string() @@ -261,7 +261,7 @@ fn read_block_comment(rdr: &mut StringReader, rdr.bump(); rdr.bump(); } - if is_block_doc_comment(&curr_line[]) { + if is_block_doc_comment(&curr_line[..]) { return } assert!(!curr_line.contains_char('\n')); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 38ba0b38df5a7..fd08cbd161bfe 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -16,14 +16,13 @@ use ext::tt::transcribe::tt_next_token; use parse::token; use parse::token::{str_to_ident}; -use std::borrow::IntoCow; +use std::borrow::{IntoCow, Cow}; use std::char; use std::fmt; use std::mem::replace; use std::num; use std::rc::Rc; use std::str; -use std::string::CowString; pub use ext::tt::transcribe::{TtReader, new_tt_reader, new_tt_reader_with_doc_flag}; @@ -196,7 +195,7 @@ impl<'a> StringReader<'a> { let mut m = m.to_string(); m.push_str(": "); for c in c.escape_default() { m.push(c) } - self.fatal_span_(from_pos, to_pos, &m[]); + self.fatal_span_(from_pos, to_pos, &m[..]); } /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an @@ -205,7 +204,7 @@ impl<'a> StringReader<'a> { let mut m = m.to_string(); m.push_str(": "); for c in c.escape_default() { m.push(c) } - self.err_span_(from_pos, to_pos, &m[]); + self.err_span_(from_pos, to_pos, &m[..]); } /// Report a lexical error spanning [`from_pos`, `to_pos`), appending the @@ -215,7 +214,7 @@ impl<'a> StringReader<'a> { let from = self.byte_offset(from_pos).to_usize(); let to = self.byte_offset(to_pos).to_usize(); m.push_str(&self.filemap.src[from..to]); - self.fatal_span_(from_pos, to_pos, &m[]); + self.fatal_span_(from_pos, to_pos, &m[..]); } /// Advance peek_tok and peek_span to refer to the next token, and @@ -278,7 +277,7 @@ impl<'a> StringReader<'a> { /// Converts CRLF to LF in the given string, raising an error on bare CR. fn translate_crlf<'b>(&self, start: BytePos, - s: &'b str, errmsg: &'b str) -> CowString<'b> { + s: &'b str, errmsg: &'b str) -> Cow<'b, str> { let mut i = 0; while i < s.len() { let str::CharRange { ch, next } = s.char_range_at(i); @@ -556,7 +555,7 @@ impl<'a> StringReader<'a> { self.translate_crlf(start_bpos, string, "bare CR not allowed in block doc-comment") } else { string.into_cow() }; - token::DocComment(token::intern(&string[])) + token::DocComment(token::intern(&string[..])) } else { token::Comment }; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6ea23cf3f04a5..7ed48bdbb928d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -258,7 +258,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) unreachable!() } }; - match str::from_utf8(&bytes[]).ok() { + match str::from_utf8(&bytes[..]).ok() { Some(s) => { return string_to_filemap(sess, s.to_string(), path.as_str().unwrap().to_string()) @@ -398,7 +398,7 @@ pub fn char_lit(lit: &str) -> (char, isize) { } let msg = format!("lexer should have rejected a bad character escape {}", lit); - let msg2 = &msg[]; + let msg2 = &msg[..]; fn esc(len: usize, lit: &str) -> Option<(char, isize)> { num::from_str_radix(&lit[2..len], 16).ok() @@ -662,7 +662,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> // s can only be ascii, byte indexing is fine let s2 = s.chars().filter(|&c| c != '_').collect::(); - let mut s = &s2[]; + let mut s = &s2[..]; debug!("integer_lit: {}, {:?}", s, suffix); @@ -819,7 +819,7 @@ mod test { #[test] fn string_to_tts_macro () { let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string()); - let tts: &[ast::TokenTree] = &tts[]; + let tts: &[ast::TokenTree] = &tts[..]; match tts { [ast::TtToken(_, token::Ident(name_macro_rules, token::Plain)), ast::TtToken(_, token::Not), @@ -1114,24 +1114,24 @@ mod test { let use_s = "use foo::bar::baz;"; let vitem = string_to_item(use_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], use_s); + assert_eq!(&vitem_s[..], use_s); let use_s = "use foo::bar as baz;"; let vitem = string_to_item(use_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], use_s); + assert_eq!(&vitem_s[..], use_s); } #[test] fn parse_extern_crate() { let ex_s = "extern crate foo;"; let vitem = string_to_item(ex_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], ex_s); + assert_eq!(&vitem_s[..], ex_s); let ex_s = "extern crate \"foo\" as bar;"; let vitem = string_to_item(ex_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], ex_s); + assert_eq!(&vitem_s[..], ex_s); } fn get_spans_of_pat_idents(src: &str) -> Vec { @@ -1203,19 +1203,19 @@ mod test { let source = "/// doc comment\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); - assert_eq!(&doc[], "/// doc comment"); + assert_eq!(&doc[..], "/// doc comment"); let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap(); let docs = item.attrs.iter().filter(|a| &a.name()[] == "doc") .map(|a| a.value_str().unwrap().to_string()).collect::>(); let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; - assert_eq!(&docs[], b); + assert_eq!(&docs[..], b); let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); - assert_eq!(&doc[], "/** doc comment\n * with CRLF */"); + assert_eq!(&doc[..], "/** doc comment\n * with CRLF */"); } #[test] @@ -1235,7 +1235,7 @@ mod test { let span = tts.iter().rev().next().unwrap().get_span(); match sess.span_diagnostic.cm.span_to_snippet(span) { - Ok(s) => assert_eq!(&s[], "{ body }"), + Ok(s) => assert_eq!(&s[..], "{ body }"), Err(_) => panic!("could not get snippet"), } } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 1df2e762ee748..8480772ce6c1a 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -28,6 +28,7 @@ pub enum ObsoleteSyntax { ProcExpr, ClosureType, ClosureKind, + EmptyIndex, } pub trait ParserObsoleteMethods { @@ -40,7 +41,8 @@ pub trait ParserObsoleteMethods { sp: Span, kind: ObsoleteSyntax, kind_str: &str, - desc: &str); + desc: &str, + error: bool); fn is_obsolete_ident(&mut self, ident: &str) -> bool; fn eat_obsolete_ident(&mut self, ident: &str) -> bool; } @@ -48,35 +50,46 @@ pub trait ParserObsoleteMethods { 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 { + let (kind_str, desc, error) = match kind { ObsoleteSyntax::ForSized => ( "for Sized?", "no longer required. Traits (and their `Self` type) do not have the `Sized` bound \ by default", + true, ), ObsoleteSyntax::ProcType => ( "the `proc` type", "use unboxed closures instead", + true, ), ObsoleteSyntax::ProcExpr => ( "`proc` expression", "use a `move ||` expression instead", + true, ), ObsoleteSyntax::ClosureType => ( "`|usize| -> bool` closure type", - "use unboxed closures instead, no type annotation needed" + "use unboxed closures instead, no type annotation needed", + true, ), ObsoleteSyntax::ClosureKind => ( "`:`, `&mut:`, or `&:`", - "rely on inference instead" + "rely on inference instead", + true, ), ObsoleteSyntax::Sized => ( "`Sized? T` for removing the `Sized` bound", - "write `T: ?Sized` instead" + "write `T: ?Sized` instead", + true, + ), + ObsoleteSyntax::EmptyIndex => ( + "[]", + "write `[..]` instead", + false, // warning for now ), }; - self.report(sp, kind, kind_str, desc); + self.report(sp, kind, kind_str, desc, error); } /// Reports an obsolete syntax non-fatal error, and returns @@ -90,9 +103,13 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { sp: Span, kind: ObsoleteSyntax, kind_str: &str, - desc: &str) { - self.span_err(sp, - &format!("obsolete syntax: {}", kind_str)[]); + desc: &str, + error: bool) { + if error { + self.span_err(sp, &format!("obsolete syntax: {}", kind_str)[]); + } else { + self.span_warn(sp, &format!("obsolete syntax: {}", kind_str)[]); + } if !self.obsolete_set.contains(&kind) { self.sess diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 407740e580d2e..370201e53825e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -240,9 +240,8 @@ macro_rules! maybe_whole { fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { - match rhs { - Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())), - None => {} + if let Some(ref attrs) = rhs { + lhs.extend(attrs.iter().cloned()) } lhs } @@ -362,7 +361,7 @@ impl<'a> Parser<'a> { let token_str = Parser::token_to_string(t); let last_span = self.last_span; self.span_fatal(last_span, &format!("unexpected token: `{}`", - token_str)[]); + token_str)); } pub fn unexpected(&mut self) -> ! { @@ -381,7 +380,7 @@ impl<'a> Parser<'a> { let this_token_str = self.this_token_to_string(); self.fatal(&format!("expected `{}`, found `{}`", token_str, - this_token_str)[]) + this_token_str)) } } else { self.expect_one_of(slice::ref_slice(t), &[]); @@ -422,7 +421,7 @@ impl<'a> Parser<'a> { expected.push_all(&*self.expected_tokens); expected.sort_by(|a, b| a.to_string().cmp(&b.to_string())); expected.dedup(); - let expect = tokens_to_string(&expected[]); + let expect = tokens_to_string(&expected[..]); let actual = self.this_token_to_string(); self.fatal( &(if expected.len() > 1 { @@ -436,7 +435,7 @@ impl<'a> Parser<'a> { (format!("expected {}, found `{}`", expect, actual)) - }[]) + })[..] ) } } @@ -467,9 +466,9 @@ impl<'a> Parser<'a> { debug!("commit_expr {:?}", e); if let ExprPath(..) = e.node { // might be unit-struct construction; check for recoverableinput error. - let mut expected = edible.iter().map(|x| x.clone()).collect::>(); + let mut expected = edible.iter().cloned().collect::>(); expected.push_all(inedible); - self.check_for_erroneous_unit_struct_expecting(&expected[]); + self.check_for_erroneous_unit_struct_expecting(&expected[..]); } self.expect_one_of(edible, inedible) } @@ -485,10 +484,9 @@ impl<'a> Parser<'a> { if self.last_token .as_ref() .map_or(false, |t| t.is_ident() || t.is_path()) { - let mut expected = edible.iter().map(|x| x.clone()).collect::>(); - expected.push_all(&inedible[]); - self.check_for_erroneous_unit_struct_expecting( - &expected[]); + let mut expected = edible.iter().cloned().collect::>(); + expected.push_all(&inedible); + self.check_for_erroneous_unit_struct_expecting(&expected); } self.expect_one_of(edible, inedible) } @@ -511,7 +509,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected ident, found `{}`", - token_str)[]) + token_str)) } } } @@ -599,7 +597,7 @@ impl<'a> Parser<'a> { let span = self.span; self.span_err(span, &format!("expected identifier, found keyword `{}`", - token_str)[]); + token_str)); } } @@ -608,7 +606,7 @@ impl<'a> Parser<'a> { if self.token.is_reserved_keyword() { let token_str = self.this_token_to_string(); self.fatal(&format!("`{}` is a reserved keyword", - token_str)[]) + token_str)) } } @@ -734,7 +732,7 @@ impl<'a> Parser<'a> { let this_token_str = self.this_token_to_string(); self.fatal(&format!("expected `{}`, found `{}`", gt_str, - this_token_str)[]) + this_token_str)) } } } @@ -1364,7 +1362,7 @@ impl<'a> Parser<'a> { let (inner_attrs, body) = p.parse_inner_attrs_and_block(); let mut attrs = attrs; - attrs.push_all(&inner_attrs[]); + attrs.push_all(&inner_attrs[..]); ProvidedMethod(P(ast::Method { attrs: attrs, id: ast::DUMMY_NODE_ID, @@ -1383,7 +1381,7 @@ impl<'a> Parser<'a> { _ => { let token_str = p.this_token_to_string(); p.fatal(&format!("expected `;` or `{{`, found `{}`", - token_str)[]) + token_str)[..]) } } } @@ -1551,7 +1549,7 @@ impl<'a> Parser<'a> { } else { let this_token_str = self.this_token_to_string(); let msg = format!("expected type, found `{}`", this_token_str); - self.fatal(&msg[]); + self.fatal(&msg[..]); }; let sp = mk_sp(lo, self.last_span.hi); @@ -1699,14 +1697,14 @@ impl<'a> Parser<'a> { token::StrRaw(s, n) => { (true, LitStr( - token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())[]), + token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())), ast::RawStr(n))) } token::Binary(i) => (true, LitBinary(parse::binary_lit(i.as_str()))), token::BinaryRaw(i, _) => (true, - LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect()))), + LitBinary(Rc::new(i.as_str().as_bytes().iter().cloned().collect()))), }; if suffix_illegal { @@ -1944,7 +1942,7 @@ impl<'a> Parser<'a> { }; } _ => { - self.fatal(&format!("expected a lifetime name")[]); + self.fatal(&format!("expected a lifetime name")); } } } @@ -1982,7 +1980,7 @@ impl<'a> Parser<'a> { let msg = format!("expected `,` or `>` after lifetime \ name, found `{}`", this_token_str); - self.fatal(&msg[]); + self.fatal(&msg[..]); } } } @@ -2497,7 +2495,7 @@ impl<'a> Parser<'a> { let last_span = self.last_span; let fstr = n.as_str(); self.span_err(last_span, - &format!("unexpected token: `{}`", n.as_str())[]); + &format!("unexpected token: `{}`", n.as_str())); if fstr.chars().all(|x| "0123456789.".contains_char(x)) { let float = match fstr.parse::().ok() { Some(f) => f, @@ -2506,7 +2504,7 @@ impl<'a> Parser<'a> { self.span_help(last_span, &format!("try parenthesizing the first index; e.g., `(foo.{}){}`", float.trunc() as usize, - &float.fract().to_string()[1..])[]); + &float.fract().to_string()[1..])); } self.abort_if_errors(); @@ -2552,8 +2550,9 @@ impl<'a> Parser<'a> { parameters: ast::PathParameters::none(), } }).collect(); + let span = mk_sp(lo, hi); let path = ast::Path { - span: mk_sp(lo, hi), + span: span, global: true, segments: segments, }; @@ -2562,10 +2561,8 @@ impl<'a> Parser<'a> { let ix = self.mk_expr(bracket_pos, hi, range); let index = self.mk_index(e, ix); e = self.mk_expr(lo, hi, index); - // Enable after snapshot. - // self.span_warn(e.span, "deprecated slicing syntax: `[]`"); - // self.span_note(e.span, - // "use `&expr[..]` to construct a slice of the whole of expr"); + + self.obsolete(span, ObsoleteSyntax::EmptyIndex); } else { let ix = self.parse_expr(); hi = self.span.hi; @@ -2639,7 +2636,7 @@ impl<'a> Parser<'a> { match self.token { token::SubstNt(name, _) => self.fatal(&format!("unknown macro variable `{}`", - token::get_ident(name))[]), + token::get_ident(name))), _ => {} } } @@ -2701,7 +2698,7 @@ impl<'a> Parser<'a> { }; let token_str = p.this_token_to_string(); p.fatal(&format!("incorrect close delimiter: `{}`", - token_str)[]) + token_str)) }, /* we ought to allow different depths of unquotation */ token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => { @@ -2822,7 +2819,7 @@ impl<'a> Parser<'a> { let this_token_to_string = self.this_token_to_string(); self.span_err(span, &format!("expected expression, found `{}`", - this_token_to_string)[]); + this_token_to_string)); let box_span = mk_sp(lo, self.last_span.hi); self.span_help(box_span, "perhaps you meant `box() (foo)` instead?"); @@ -3275,7 +3272,7 @@ impl<'a> Parser<'a> { if self.token != token::CloseDelim(token::Brace) { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `{}`, found `{}`", "}", - token_str)[]) + token_str)) } etc = true; break; @@ -3576,7 +3573,7 @@ impl<'a> Parser<'a> { let span = self.span; let tok_str = self.this_token_to_string(); self.span_fatal(span, - &format!("expected identifier, found `{}`", tok_str)[]); + &format!("expected identifier, found `{}`", tok_str)); } let ident = self.parse_ident(); let last_span = self.last_span; @@ -3673,7 +3670,7 @@ impl<'a> Parser<'a> { let lo = self.span.lo; if self.check_keyword(keywords::Let) { - check_expected_item(self, &item_attrs[]); + check_expected_item(self, &item_attrs[..]); self.expect_keyword(keywords::Let); let decl = self.parse_let(); P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))) @@ -3682,7 +3679,7 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| *t == token::Not) { // it's a macro invocation: - check_expected_item(self, &item_attrs[]); + check_expected_item(self, &item_attrs[..]); // Potential trouble: if we allow macros with paths instead of // idents, we'd need to look ahead past the whole path here... @@ -3710,7 +3707,7 @@ impl<'a> Parser<'a> { let tok_str = self.this_token_to_string(); self.fatal(&format!("expected {}`(` or `{{`, found `{}`", ident_str, - tok_str)[]) + tok_str)) }, }; @@ -3758,7 +3755,7 @@ impl<'a> Parser<'a> { } } else { let found_attrs = !item_attrs.is_empty(); - let item_err = Parser::expected_item_err(&item_attrs[]); + let item_err = Parser::expected_item_err(&item_attrs[..]); match self.parse_item_(item_attrs, false) { Ok(i) => { let hi = i.span.hi; @@ -3795,7 +3792,7 @@ impl<'a> Parser<'a> { let sp = self.span; let tok = self.this_token_to_string(); self.span_fatal_help(sp, - &format!("expected `{{`, found `{}`", tok)[], + &format!("expected `{{`, found `{}`", tok), "place this code inside a block"); } @@ -3830,13 +3827,13 @@ impl<'a> Parser<'a> { while self.token != token::CloseDelim(token::Brace) { // parsing items even when they're not allowed lets us give // better error messages and recover more gracefully. - attributes_box.push_all(&self.parse_outer_attributes()[]); + attributes_box.push_all(&self.parse_outer_attributes()); match self.token { token::Semi => { if !attributes_box.is_empty() { let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attributes_box[])); + Parser::expected_item_err(&attributes_box[..])); attributes_box = Vec::new(); } self.bump(); // empty @@ -3928,7 +3925,7 @@ impl<'a> Parser<'a> { if !attributes_box.is_empty() { let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attributes_box[])); + Parser::expected_item_err(&attributes_box[..])); } let hi = self.span.hi; @@ -4383,7 +4380,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `self`, found `{}`", - token_str)[]) + token_str)) } } } @@ -4404,7 +4401,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `Self`, found `{}`", - token_str)[]) + token_str)) } } } @@ -4539,7 +4536,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `,` or `)`, found `{}`", - token_str)[]) + token_str)) } } } @@ -4712,7 +4709,7 @@ impl<'a> Parser<'a> { let (inner_attrs, body) = self.parse_inner_attrs_and_block(); let body_span = body.span; let mut new_attrs = attrs; - new_attrs.push_all(&inner_attrs[]); + new_attrs.push_all(&inner_attrs[..]); (ast::MethDecl(ident, generics, abi, @@ -4942,7 +4939,7 @@ impl<'a> Parser<'a> { if fields.len() == 0 { self.fatal(&format!("unit-like struct definition should be \ written as `struct {};`", - token::get_ident(class_name.clone()))[]); + token::get_ident(class_name.clone()))); } self.bump(); @@ -4950,7 +4947,7 @@ impl<'a> Parser<'a> { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `where`, or `{}` after struct \ name, found `{}`", "{", - token_str)[]); + token_str)); } fields @@ -4981,7 +4978,7 @@ impl<'a> Parser<'a> { if fields.len() == 0 { self.fatal(&format!("unit-like struct definition should be \ written as `struct {};`", - token::get_ident(class_name.clone()))[]); + token::get_ident(class_name.clone()))); } self.parse_where_clause(generics); @@ -4996,7 +4993,7 @@ impl<'a> Parser<'a> { } else { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `where`, `{}`, `(`, or `;` after struct \ - name, found `{}`", "{", token_str)[]); + name, found `{}`", "{", token_str)); } } @@ -5016,7 +5013,7 @@ impl<'a> Parser<'a> { let token_str = self.this_token_to_string(); self.span_fatal_help(span, &format!("expected `,`, or `}}`, found `{}`", - token_str)[], + token_str), "struct fields should be separated by commas") } } @@ -5088,7 +5085,7 @@ impl<'a> Parser<'a> { // Parse all of the items up to closing or an attribute. let mut attrs = first_item_attrs; - attrs.push_all(&self.parse_outer_attributes()[]); + attrs.push_all(&self.parse_outer_attributes()); let mut items = vec![]; loop { @@ -5108,14 +5105,14 @@ impl<'a> Parser<'a> { while self.token != term { let mut attrs = mem::replace(&mut attrs, vec![]); - attrs.push_all(&self.parse_outer_attributes()[]); + attrs.push_all(&self.parse_outer_attributes()); debug!("parse_mod_items: parse_item_(attrs={:?})", attrs); match self.parse_item_(attrs, true /* macros allowed */) { Ok(item) => items.push(item), Err(_) => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected item, found `{}`", - token_str)[]) + token_str)) } } } @@ -5124,7 +5121,7 @@ impl<'a> Parser<'a> { // We parsed attributes for the first item but didn't find it let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attrs[])); + Parser::expected_item_err(&attrs[..])); } ast::Mod { @@ -5203,8 +5200,8 @@ impl<'a> Parser<'a> { let mod_name = mod_string.to_string(); let default_path_str = format!("{}.rs", mod_name); let secondary_path_str = format!("{}/mod.rs", mod_name); - let default_path = dir_path.join(&default_path_str[]); - let secondary_path = dir_path.join(&secondary_path_str[]); + let default_path = dir_path.join(&default_path_str[..]); + let secondary_path = dir_path.join(&secondary_path_str[..]); let default_exists = default_path.exists(); let secondary_exists = secondary_path.exists(); @@ -5219,13 +5216,13 @@ impl<'a> Parser<'a> { &format!("maybe move this module `{0}` \ to its own directory via \ `{0}/mod.rs`", - this_module)[]); + this_module)); if default_exists || secondary_exists { self.span_note(id_sp, &format!("... or maybe `use` the module \ `{}` instead of possibly \ redeclaring it", - mod_name)[]); + mod_name)); } self.abort_if_errors(); } @@ -5236,12 +5233,12 @@ impl<'a> Parser<'a> { (false, false) => { self.span_fatal_help(id_sp, &format!("file not found for module `{}`", - mod_name)[], + mod_name), &format!("name the file either {} or {} inside \ the directory {:?}", default_path_str, secondary_path_str, - dir_path.display())[]); + dir_path.display())); } (true, true) => { self.span_fatal_help( @@ -5250,7 +5247,7 @@ impl<'a> Parser<'a> { and {}", mod_name, default_path_str, - secondary_path_str)[], + secondary_path_str), "delete or rename one of them to remove the ambiguity"); } } @@ -5272,11 +5269,11 @@ impl<'a> Parser<'a> { let mut err = String::from_str("circular modules: "); let len = included_mod_stack.len(); for p in &included_mod_stack[i.. len] { - err.push_str(&p.display().as_cow()[]); + err.push_str(&p.display().as_cow()); err.push_str(" -> "); } - err.push_str(&path.display().as_cow()[]); - self.span_fatal(id_sp, &err[]); + err.push_str(&path.display().as_cow()); + self.span_fatal(id_sp, &err[..]); } None => () } @@ -5381,7 +5378,7 @@ impl<'a> Parser<'a> { self.span_help(span, &format!("perhaps you meant to enclose the crate name `{}` in \ a string?", - the_ident.as_str())[]); + the_ident.as_str())); None } else { None @@ -5407,7 +5404,7 @@ impl<'a> Parser<'a> { self.span_fatal(span, &format!("expected extern crate name but \ found `{}`", - token_str)[]); + token_str)); } }; @@ -5505,7 +5502,7 @@ impl<'a> Parser<'a> { self.span_err(start_span, &format!("unit-like struct variant should be written \ without braces, as `{},`", - token::get_ident(ident))[]); + token::get_ident(ident))); } kind = StructVariantKind(struct_def); } else if self.check(&token::OpenDelim(token::Paren)) { @@ -5583,7 +5580,7 @@ impl<'a> Parser<'a> { &format!("illegal ABI: expected one of [{}], \ found `{}`", abi::all_names().connect(", "), - the_string)[]); + the_string)); None } } @@ -5663,7 +5660,7 @@ impl<'a> Parser<'a> { let token_str = self.this_token_to_string(); self.span_fatal(span, &format!("expected `{}` or `fn`, found `{}`", "{", - token_str)[]); + token_str)); } if self.eat_keyword_noexpect(keywords::Virtual) { @@ -5772,7 +5769,7 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Mod) { // MODULE ITEM let (ident, item_, extra_attrs) = - self.parse_item_mod(&attrs[]); + self.parse_item_mod(&attrs[..]); let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -6057,7 +6054,7 @@ impl<'a> Parser<'a> { fn parse_foreign_items(&mut self, first_item_attrs: Vec) -> Vec> { let mut attrs = first_item_attrs; - attrs.push_all(&self.parse_outer_attributes()[]); + attrs.push_all(&self.parse_outer_attributes()); let mut foreign_items = Vec::new(); loop { match self.parse_foreign_item(attrs) { @@ -6078,7 +6075,7 @@ impl<'a> Parser<'a> { if !attrs.is_empty() { let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attrs[])); + Parser::expected_item_err(&attrs[..])); } foreign_items diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 0747a97fa37cc..433c013591c2d 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -482,7 +482,7 @@ macro_rules! declare_special_idents_and_keywords {( $(init_vec.push($si_str);)* $(init_vec.push($sk_str);)* $(init_vec.push($rk_str);)* - interner::StrInterner::prefill(&init_vec[]) + interner::StrInterner::prefill(&init_vec[..]) } }} @@ -644,7 +644,7 @@ impl BytesContainer for InternedString { // of `BytesContainer`, which is itself a workaround for the lack of // DST. unsafe { - let this = &self[]; + let this = &self[..]; mem::transmute::<&[u8],&[u8]>(this.container_as_bytes()) } } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 6c6cf186e70ae..1593bfb97fe1d 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -539,8 +539,8 @@ impl Printer { pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> { debug!("print {} {} (remaining line space={})", tok_str(&token), l, self.space); - debug!("{}", buf_str(&self.token[], - &self.size[], + debug!("{}", buf_str(&self.token, + &self.size, self.left, self.right, 6)); @@ -607,7 +607,7 @@ impl Printer { assert_eq!(l, len); // assert!(l <= space); self.space -= len; - self.print_str(&s[]) + self.print_str(&s[..]) } Token::Eof => { // Eof should never get here. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 4b021f2434f05..f26578e740120 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -134,7 +134,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap, try!(s.print_attribute(&fake_attr)); } - try!(s.print_mod(&krate.module, &krate.attrs[])); + try!(s.print_mod(&krate.module, &krate.attrs)); try!(s.print_remaining_comments()); eof(&mut s.s) } @@ -602,7 +602,7 @@ impl<'a> State<'a> { pub fn synth_comment(&mut self, text: String) -> IoResult<()> { try!(word(&mut self.s, "/*")); try!(space(&mut self.s)); - try!(word(&mut self.s, &text[])); + try!(word(&mut self.s, &text[..])); try!(space(&mut self.s)); word(&mut self.s, "*/") } @@ -701,7 +701,7 @@ impl<'a> State<'a> { } ast::TyTup(ref elts) => { try!(self.popen()); - try!(self.commasep(Inconsistent, &elts[], + try!(self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&**ty))); if elts.len() == 1 { try!(word(&mut self.s, ",")); @@ -734,10 +734,10 @@ impl<'a> State<'a> { } ast::TyObjectSum(ref ty, ref bounds) => { try!(self.print_type(&**ty)); - try!(self.print_bounds("+", &bounds[])); + try!(self.print_bounds("+", &bounds[..])); } ast::TyPolyTraitRef(ref bounds) => { - try!(self.print_bounds("", &bounds[])); + try!(self.print_bounds("", &bounds[..])); } ast::TyQPath(ref qpath) => { try!(self.print_qpath(&**qpath, false)) @@ -765,7 +765,7 @@ impl<'a> State<'a> { item: &ast::ForeignItem) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); - try!(self.print_outer_attributes(&item.attrs[])); + try!(self.print_outer_attributes(&item.attrs)); match item.node { ast::ForeignItemFn(ref decl, ref generics) => { try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics, @@ -776,7 +776,7 @@ impl<'a> State<'a> { } ast::ForeignItemStatic(ref t, m) => { try!(self.head(&visibility_qualified(item.vis, - "static")[])); + "static"))); if m { try!(self.word_space("mut")); } @@ -793,7 +793,7 @@ impl<'a> State<'a> { fn print_associated_type(&mut self, typedef: &ast::AssociatedType) -> IoResult<()> { - try!(self.print_outer_attributes(&typedef.attrs[])); + try!(self.print_outer_attributes(&typedef.attrs)); try!(self.word_space("type")); try!(self.print_ty_param(&typedef.ty_param)); word(&mut self.s, ";") @@ -812,12 +812,12 @@ impl<'a> State<'a> { pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); - try!(self.print_outer_attributes(&item.attrs[])); + try!(self.print_outer_attributes(&item.attrs)); try!(self.ann.pre(self, NodeItem(item))); match item.node { ast::ItemExternCrate(ref optional_path) => { try!(self.head(&visibility_qualified(item.vis, - "extern crate")[])); + "extern crate"))); if let Some((ref p, style)) = *optional_path { try!(self.print_string(p, style)); try!(space(&mut self.s)); @@ -831,7 +831,7 @@ impl<'a> State<'a> { } ast::ItemUse(ref vp) => { try!(self.head(&visibility_qualified(item.vis, - "use")[])); + "use"))); try!(self.print_view_path(&**vp)); try!(word(&mut self.s, ";")); try!(self.end()); // end inner head-block @@ -839,7 +839,7 @@ impl<'a> State<'a> { } ast::ItemStatic(ref ty, m, ref expr) => { try!(self.head(&visibility_qualified(item.vis, - "static")[])); + "static"))); if m == ast::MutMutable { try!(self.word_space("mut")); } @@ -856,7 +856,7 @@ impl<'a> State<'a> { } ast::ItemConst(ref ty, ref expr) => { try!(self.head(&visibility_qualified(item.vis, - "const")[])); + "const"))); try!(self.print_ident(item.ident)); try!(self.word_space(":")); try!(self.print_type(&**ty)); @@ -879,28 +879,28 @@ impl<'a> State<'a> { item.vis )); try!(word(&mut self.s, " ")); - try!(self.print_block_with_attrs(&**body, &item.attrs[])); + try!(self.print_block_with_attrs(&**body, &item.attrs)); } ast::ItemMod(ref _mod) => { try!(self.head(&visibility_qualified(item.vis, - "mod")[])); + "mod"))); try!(self.print_ident(item.ident)); try!(self.nbsp()); try!(self.bopen()); - try!(self.print_mod(_mod, &item.attrs[])); + try!(self.print_mod(_mod, &item.attrs)); try!(self.bclose(item.span)); } ast::ItemForeignMod(ref nmod) => { try!(self.head("extern")); - try!(self.word_nbsp(&nmod.abi.to_string()[])); + try!(self.word_nbsp(&nmod.abi.to_string())); try!(self.bopen()); - try!(self.print_foreign_mod(nmod, &item.attrs[])); + try!(self.print_foreign_mod(nmod, &item.attrs)); try!(self.bclose(item.span)); } ast::ItemTy(ref ty, ref params) => { try!(self.ibox(indent_unit)); try!(self.ibox(0)); - try!(self.word_nbsp(&visibility_qualified(item.vis, "type")[])); + try!(self.word_nbsp(&visibility_qualified(item.vis, "type"))); try!(self.print_ident(item.ident)); try!(self.print_generics(params)); try!(self.end()); // end the inner ibox @@ -922,7 +922,7 @@ impl<'a> State<'a> { )); } ast::ItemStruct(ref struct_def, ref generics) => { - try!(self.head(&visibility_qualified(item.vis,"struct")[])); + try!(self.head(&visibility_qualified(item.vis,"struct"))); try!(self.print_struct(&**struct_def, generics, item.ident, item.span)); } @@ -963,7 +963,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.bopen()); - try!(self.print_inner_attributes(&item.attrs[])); + try!(self.print_inner_attributes(&item.attrs)); for impl_item in impl_items { match *impl_item { ast::MethodImplItem(ref meth) => { @@ -983,18 +983,17 @@ impl<'a> State<'a> { try!(self.word_nbsp("trait")); try!(self.print_ident(item.ident)); try!(self.print_generics(generics)); - let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect(); let mut real_bounds = Vec::with_capacity(bounds.len()); - for b in bounds { - if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b { + for b in bounds.iter() { + if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b { try!(space(&mut self.s)); try!(self.word_space("for ?")); try!(self.print_trait_ref(&ptr.trait_ref)); } else { - real_bounds.push(b); + real_bounds.push(b.clone()); } } - try!(self.print_bounds(":", &real_bounds[])); + try!(self.print_bounds(":", &real_bounds[..])); try!(self.print_where_clause(generics)); try!(word(&mut self.s, " ")); try!(self.bopen()); @@ -1012,7 +1011,7 @@ impl<'a> State<'a> { try!(self.print_ident(item.ident)); try!(self.cbox(indent_unit)); try!(self.popen()); - try!(self.print_tts(&tts[])); + try!(self.print_tts(&tts[..])); try!(self.pclose()); try!(word(&mut self.s, ";")); try!(self.end()); @@ -1050,12 +1049,12 @@ impl<'a> State<'a> { generics: &ast::Generics, ident: ast::Ident, span: codemap::Span, visibility: ast::Visibility) -> IoResult<()> { - try!(self.head(&visibility_qualified(visibility, "enum")[])); + try!(self.head(&visibility_qualified(visibility, "enum"))); try!(self.print_ident(ident)); try!(self.print_generics(generics)); try!(self.print_where_clause(generics)); try!(space(&mut self.s)); - self.print_variants(&enum_definition.variants[], span) + self.print_variants(&enum_definition.variants, span) } pub fn print_variants(&mut self, @@ -1065,7 +1064,7 @@ impl<'a> State<'a> { for v in variants { try!(self.space_if_not_bol()); try!(self.maybe_print_comment(v.span.lo)); - try!(self.print_outer_attributes(&v.node.attrs[])); + try!(self.print_outer_attributes(&v.node.attrs)); try!(self.ibox(indent_unit)); try!(self.print_variant(&**v)); try!(word(&mut self.s, ",")); @@ -1093,7 +1092,7 @@ impl<'a> State<'a> { if !struct_def.fields.is_empty() { try!(self.popen()); try!(self.commasep( - Inconsistent, &struct_def.fields[], + Inconsistent, &struct_def.fields, |s, field| { match field.node.kind { ast::NamedField(..) => panic!("unexpected named field"), @@ -1123,7 +1122,7 @@ impl<'a> State<'a> { ast::NamedField(ident, visibility) => { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(field.span.lo)); - try!(self.print_outer_attributes(&field.node.attrs[])); + try!(self.print_outer_attributes(&field.node.attrs)); try!(self.print_visibility(visibility)); try!(self.print_ident(ident)); try!(self.word_nbsp(":")); @@ -1147,7 +1146,7 @@ impl<'a> State<'a> { pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> { match *tt { ast::TtToken(_, ref tk) => { - try!(word(&mut self.s, &token_to_string(tk)[])); + try!(word(&mut self.s, &token_to_string(tk))); match *tk { parse::token::DocComment(..) => { hardbreak(&mut self.s) @@ -1156,11 +1155,11 @@ impl<'a> State<'a> { } } ast::TtDelimited(_, ref delimed) => { - try!(word(&mut self.s, &token_to_string(&delimed.open_token())[])); + try!(word(&mut self.s, &token_to_string(&delimed.open_token()))); try!(space(&mut self.s)); - try!(self.print_tts(&delimed.tts[])); + try!(self.print_tts(&delimed.tts)); try!(space(&mut self.s)); - word(&mut self.s, &token_to_string(&delimed.close_token())[]) + word(&mut self.s, &token_to_string(&delimed.close_token())) }, ast::TtSequence(_, ref seq) => { try!(word(&mut self.s, "$(")); @@ -1170,7 +1169,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, ")")); match seq.separator { Some(ref tk) => { - try!(word(&mut self.s, &token_to_string(tk)[])); + try!(word(&mut self.s, &token_to_string(tk))); } None => {}, } @@ -1210,7 +1209,7 @@ impl<'a> State<'a> { if !args.is_empty() { try!(self.popen()); try!(self.commasep(Consistent, - &args[], + &args[..], |s, arg| s.print_type(&*arg.ty))); try!(self.pclose()); } @@ -1234,7 +1233,7 @@ impl<'a> State<'a> { pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(m.span.lo)); - try!(self.print_outer_attributes(&m.attrs[])); + try!(self.print_outer_attributes(&m.attrs)); try!(self.print_ty_fn(m.abi, m.unsafety, &*m.decl, @@ -1263,7 +1262,7 @@ impl<'a> State<'a> { pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(meth.span.lo)); - try!(self.print_outer_attributes(&meth.attrs[])); + try!(self.print_outer_attributes(&meth.attrs)); match meth.node { ast::MethDecl(ident, ref generics, @@ -1281,7 +1280,7 @@ impl<'a> State<'a> { Some(&explicit_self.node), vis)); try!(word(&mut self.s, " ")); - self.print_block_with_attrs(&**body, &meth.attrs[]) + self.print_block_with_attrs(&**body, &meth.attrs) }, ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), ..}) => { @@ -1290,7 +1289,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, "! ")); try!(self.cbox(indent_unit)); try!(self.popen()); - try!(self.print_tts(&tts[])); + try!(self.print_tts(&tts[..])); try!(self.pclose()); try!(word(&mut self.s, ";")); self.end() @@ -1552,7 +1551,7 @@ impl<'a> State<'a> { fn print_expr_vec(&mut self, exprs: &[P]) -> IoResult<()> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); - try!(self.commasep_exprs(Inconsistent, &exprs[])); + try!(self.commasep_exprs(Inconsistent, &exprs[..])); try!(word(&mut self.s, "]")); self.end() } @@ -1578,7 +1577,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, "{")); try!(self.commasep_cmnt( Consistent, - &fields[], + &fields[..], |s, field| { try!(s.ibox(indent_unit)); try!(s.print_ident(field.ident.node)); @@ -1607,7 +1606,7 @@ impl<'a> State<'a> { fn print_expr_tup(&mut self, exprs: &[P]) -> IoResult<()> { try!(self.popen()); - try!(self.commasep_exprs(Inconsistent, &exprs[])); + try!(self.commasep_exprs(Inconsistent, &exprs[..])); if exprs.len() == 1 { try!(word(&mut self.s, ",")); } @@ -1672,22 +1671,22 @@ impl<'a> State<'a> { try!(self.print_expr_box(place, &**expr)); } ast::ExprVec(ref exprs) => { - try!(self.print_expr_vec(&exprs[])); + try!(self.print_expr_vec(&exprs[..])); } ast::ExprRepeat(ref element, ref count) => { try!(self.print_expr_repeat(&**element, &**count)); } ast::ExprStruct(ref path, ref fields, ref wth) => { - try!(self.print_expr_struct(path, &fields[], wth)); + try!(self.print_expr_struct(path, &fields[..], wth)); } ast::ExprTup(ref exprs) => { - try!(self.print_expr_tup(&exprs[])); + try!(self.print_expr_tup(&exprs[..])); } ast::ExprCall(ref func, ref args) => { - try!(self.print_expr_call(&**func, &args[])); + try!(self.print_expr_call(&**func, &args[..])); } ast::ExprMethodCall(ident, ref tys, ref args) => { - try!(self.print_expr_method_call(ident, &tys[], &args[])); + try!(self.print_expr_method_call(ident, &tys[..], &args[..])); } ast::ExprBinary(op, ref lhs, ref rhs) => { try!(self.print_expr_binary(op, &**lhs, &**rhs)); @@ -1875,11 +1874,11 @@ impl<'a> State<'a> { try!(self.print_string(&a.asm, a.asm_str_style)); try!(self.word_space(":")); - try!(self.commasep(Inconsistent, &a.outputs[], + try!(self.commasep(Inconsistent, &a.outputs, |s, &(ref co, ref o, is_rw)| { match co.slice_shift_char() { Some(('=', operand)) if is_rw => { - try!(s.print_string(&format!("+{}", operand)[], + try!(s.print_string(&format!("+{}", operand), ast::CookedStr)) } _ => try!(s.print_string(&co, ast::CookedStr)) @@ -1892,7 +1891,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.word_space(":")); - try!(self.commasep(Inconsistent, &a.inputs[], + try!(self.commasep(Inconsistent, &a.inputs, |s, &(ref co, ref o)| { try!(s.print_string(&co, ast::CookedStr)); try!(s.popen()); @@ -1903,7 +1902,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.word_space(":")); - try!(self.commasep(Inconsistent, &a.clobbers[], + try!(self.commasep(Inconsistent, &a.clobbers, |s, co| { try!(s.print_string(&co, ast::CookedStr)); Ok(()) @@ -1977,7 +1976,7 @@ impl<'a> State<'a> { pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> { if self.encode_idents_with_hygiene { let encoded = ident.encode_with_hygiene(); - try!(word(&mut self.s, &encoded[])) + try!(word(&mut self.s, &encoded[..])) } else { try!(word(&mut self.s, &token::get_ident(ident))) } @@ -1985,7 +1984,7 @@ impl<'a> State<'a> { } pub fn print_usize(&mut self, i: usize) -> IoResult<()> { - word(&mut self.s, &i.to_string()[]) + word(&mut self.s, &i.to_string()) } pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> { @@ -2075,7 +2074,7 @@ impl<'a> State<'a> { } try!(self.commasep( Inconsistent, - &data.types[], + &data.types, |s, ty| s.print_type(&**ty))); comma = true; } @@ -2098,7 +2097,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, "(")); try!(self.commasep( Inconsistent, - &data.inputs[], + &data.inputs, |s, ty| s.print_type(&**ty))); try!(word(&mut self.s, ")")); @@ -2151,7 +2150,7 @@ impl<'a> State<'a> { Some(ref args) => { if !args.is_empty() { try!(self.popen()); - try!(self.commasep(Inconsistent, &args[], + try!(self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&**p))); try!(self.pclose()); } @@ -2163,7 +2162,7 @@ impl<'a> State<'a> { try!(self.nbsp()); try!(self.word_space("{")); try!(self.commasep_cmnt( - Consistent, &fields[], + Consistent, &fields[..], |s, f| { try!(s.cbox(indent_unit)); if !f.node.is_shorthand { @@ -2184,7 +2183,7 @@ impl<'a> State<'a> { ast::PatTup(ref elts) => { try!(self.popen()); try!(self.commasep(Inconsistent, - &elts[], + &elts[..], |s, p| s.print_pat(&**p))); if elts.len() == 1 { try!(word(&mut self.s, ",")); @@ -2212,7 +2211,7 @@ impl<'a> State<'a> { ast::PatVec(ref before, ref slice, ref after) => { try!(word(&mut self.s, "[")); try!(self.commasep(Inconsistent, - &before[], + &before[..], |s, p| s.print_pat(&**p))); if let Some(ref p) = *slice { if !before.is_empty() { try!(self.word_space(",")); } @@ -2226,7 +2225,7 @@ impl<'a> State<'a> { if !after.is_empty() { try!(self.word_space(",")); } } try!(self.commasep(Inconsistent, - &after[], + &after[..], |s, p| s.print_pat(&**p))); try!(word(&mut self.s, "]")); } @@ -2243,7 +2242,7 @@ impl<'a> State<'a> { } try!(self.cbox(indent_unit)); try!(self.ibox(0)); - try!(self.print_outer_attributes(&arm.attrs[])); + try!(self.print_outer_attributes(&arm.attrs)); let mut first = true; for p in &arm.pats { if first { @@ -2475,7 +2474,7 @@ impl<'a> State<'a> { ints.push(i); } - try!(self.commasep(Inconsistent, &ints[], |s, &idx| { + try!(self.commasep(Inconsistent, &ints[..], |s, &idx| { if idx < generics.lifetimes.len() { let lifetime = &generics.lifetimes[idx]; s.print_lifetime_def(lifetime) @@ -2492,7 +2491,7 @@ impl<'a> State<'a> { pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> { try!(self.print_ident(param.ident)); - try!(self.print_bounds(":", ¶m.bounds[])); + try!(self.print_bounds(":", ¶m.bounds)); match param.default { Some(ref default) => { try!(space(&mut self.s)); @@ -2562,7 +2561,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, &name)); } ast::MetaNameValue(ref name, ref value) => { - try!(self.word_space(&name[])); + try!(self.word_space(&name[..])); try!(self.word_space("=")); try!(self.print_literal(value)); } @@ -2570,7 +2569,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, &name)); try!(self.popen()); try!(self.commasep(Consistent, - &items[], + &items[..], |s, i| s.print_meta_item(&**i))); try!(self.pclose()); } @@ -2606,7 +2605,7 @@ impl<'a> State<'a> { try!(self.print_path(path, false)); try!(word(&mut self.s, "::{")); } - try!(self.commasep(Inconsistent, &idents[], |s, w| { + try!(self.commasep(Inconsistent, &idents[..], |s, w| { match w.node { ast::PathListIdent { name, .. } => { s.print_ident(name) @@ -2753,7 +2752,7 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(lit.span.lo)); match self.next_lit(lit.span.lo) { Some(ref ltrl) => { - return word(&mut self.s, &(*ltrl).lit[]); + return word(&mut self.s, &(*ltrl).lit); } _ => () } @@ -2763,33 +2762,33 @@ impl<'a> State<'a> { let mut res = String::from_str("b'"); res.extend(ascii::escape_default(byte).map(|c| c as char)); res.push('\''); - word(&mut self.s, &res[]) + word(&mut self.s, &res[..]) } ast::LitChar(ch) => { let mut res = String::from_str("'"); res.extend(ch.escape_default()); res.push('\''); - word(&mut self.s, &res[]) + word(&mut self.s, &res[..]) } ast::LitInt(i, t) => { match t { ast::SignedIntLit(st, ast::Plus) => { word(&mut self.s, - &ast_util::int_ty_to_string(st, Some(i as i64))[]) + &ast_util::int_ty_to_string(st, Some(i as i64))) } ast::SignedIntLit(st, ast::Minus) => { let istr = ast_util::int_ty_to_string(st, Some(-(i as i64))); word(&mut self.s, - &format!("-{}", istr)[]) + &format!("-{}", istr)) } ast::UnsignedIntLit(ut) => { word(&mut self.s, &ast_util::uint_ty_to_string(ut, Some(i))) } ast::UnsuffixedIntLit(ast::Plus) => { - word(&mut self.s, &format!("{}", i)[]) + word(&mut self.s, &format!("{}", i)) } ast::UnsuffixedIntLit(ast::Minus) => { - word(&mut self.s, &format!("-{}", i)[]) + word(&mut self.s, &format!("-{}", i)) } } } @@ -2798,9 +2797,9 @@ impl<'a> State<'a> { &format!( "{}{}", &f, - &ast_util::float_ty_to_string(t)[])[]) + &ast_util::float_ty_to_string(t))) } - ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[]), + ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]), ast::LitBool(val) => { if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") } } @@ -2810,7 +2809,7 @@ impl<'a> State<'a> { escaped.extend(ascii::escape_default(ch as u8) .map(|c| c as char)); } - word(&mut self.s, &format!("b\"{}\"", escaped)[]) + word(&mut self.s, &format!("b\"{}\"", escaped)) } } } @@ -2851,7 +2850,7 @@ impl<'a> State<'a> { comments::Mixed => { assert_eq!(cmnt.lines.len(), 1); try!(zerobreak(&mut self.s)); - try!(word(&mut self.s, &cmnt.lines[0][])); + try!(word(&mut self.s, &cmnt.lines[0])); zerobreak(&mut self.s) } comments::Isolated => { @@ -2860,7 +2859,7 @@ impl<'a> State<'a> { // Don't print empty lines because they will end up as trailing // whitespace if !line.is_empty() { - try!(word(&mut self.s, &line[])); + try!(word(&mut self.s, &line[..])); } try!(hardbreak(&mut self.s)); } @@ -2869,13 +2868,13 @@ impl<'a> State<'a> { comments::Trailing => { try!(word(&mut self.s, " ")); if cmnt.lines.len() == 1 { - try!(word(&mut self.s, &cmnt.lines[0][])); + try!(word(&mut self.s, &cmnt.lines[0])); hardbreak(&mut self.s) } else { try!(self.ibox(0)); for line in &cmnt.lines { if !line.is_empty() { - try!(word(&mut self.s, &line[])); + try!(word(&mut self.s, &line[..])); } try!(hardbreak(&mut self.s)); } @@ -2908,7 +2907,7 @@ impl<'a> State<'a> { string=st)) } }; - word(&mut self.s, &st[]) + word(&mut self.s, &st[..]) } pub fn next_comment(&mut self) -> Option { @@ -2939,7 +2938,7 @@ impl<'a> State<'a> { Some(abi::Rust) => Ok(()), Some(abi) => { try!(self.word_nbsp("extern")); - self.word_nbsp(&abi.to_string()[]) + self.word_nbsp(&abi.to_string()) } None => Ok(()) } @@ -2950,7 +2949,7 @@ impl<'a> State<'a> { match opt_abi { Some(abi) => { try!(self.word_nbsp("extern")); - self.word_nbsp(&abi.to_string()[]) + self.word_nbsp(&abi.to_string()) } None => Ok(()) } @@ -2965,7 +2964,7 @@ impl<'a> State<'a> { if abi != abi::Rust { try!(self.word_nbsp("extern")); - try!(self.word_nbsp(&abi.to_string()[])); + try!(self.word_nbsp(&abi.to_string())); } word(&mut self.s, "fn") diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 01f3839b0390e..adb5383a8fd54 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -111,11 +111,18 @@ impl Display for P { } } +#[cfg(stage0)] impl> Hash for P { fn hash(&self, state: &mut S) { (**self).hash(state); } } +#[cfg(not(stage0))] +impl Hash for P { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} impl Decodable for P { fn decode(d: &mut D) -> Result, D::Error> { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 98c193c7e6b85..4e4a571ede7b8 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -45,16 +45,16 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool { attr::contains_name(attrs, "no_implicit_prelude") } -struct StandardLibraryInjector<'a> { - alt_std_name: Option +struct StandardLibraryInjector { + alt_std_name: Option, } -impl<'a> fold::Folder for StandardLibraryInjector<'a> { +impl fold::Folder for StandardLibraryInjector { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { // The name to use in `extern crate "name" as std;` let actual_crate_name = match self.alt_std_name { - Some(ref s) => token::intern_and_get_ident(&s[]), + Some(ref s) => token::intern_and_get_ident(&s[..]), None => token::intern_and_get_ident("std"), }; @@ -80,9 +80,10 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option) -> ast::Cr fold.fold_crate(krate) } -struct PreludeInjector<'a>; +struct PreludeInjector; -impl<'a> fold::Folder for PreludeInjector<'a> { + +impl fold::Folder for PreludeInjector { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { // only add `use std::prelude::*;` if there wasn't a // `#![no_implicit_prelude]` at the crate level. diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 6511dffa6bf8b..7b1fc91e45b5b 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -119,7 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { self.cx.path.push(ident); } debug!("current path: {}", - ast_util::path_name_i(&self.cx.path[])); + ast_util::path_name_i(&self.cx.path)); if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) { match i.node { @@ -274,8 +274,8 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate { // When not compiling with --test we should not compile the // #[test] functions config::strip_items(krate, |attrs| { - !attr::contains_name(&attrs[], "test") && - !attr::contains_name(&attrs[], "bench") + !attr::contains_name(&attrs[..], "test") && + !attr::contains_name(&attrs[..], "bench") }) } @@ -563,7 +563,7 @@ fn mk_tests(cx: &TestCtxt) -> P { fn is_test_crate(krate: &ast::Crate) -> bool { match attr::find_crate_name(&krate.attrs[]) { - Some(ref s) if "test" == &s[] => true, + Some(ref s) if "test" == &s[..] => true, _ => false } } @@ -603,11 +603,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // creates $name: $expr let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr); - debug!("encoding {}", ast_util::path_name_i(&path[])); + debug!("encoding {}", ast_util::path_name_i(&path[..])); // path to the #[test] function: "foo::bar::baz" - let path_string = ast_util::path_name_i(&path[]); - let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[])); + let path_string = ast_util::path_name_i(&path[..]); + let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..])); // self::test::StaticTestName($name_expr) let name_expr = ecx.expr_call(span, diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 511442675194e..dffeac6f3f793 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -14,13 +14,13 @@ use ast::Name; -use std::borrow::BorrowFrom; +use std::borrow::Borrow; use std::cell::RefCell; use std::cmp::Ordering; use std::collections::HashMap; +#[cfg(stage0)] use std::collections::hash_map::Hasher; use std::fmt; use std::hash::Hash; -use std::collections::hash_map::Hasher; use std::ops::Deref; use std::rc::Rc; @@ -30,6 +30,7 @@ pub struct Interner { } // when traits can extend traits, we should extend index to get [] +#[cfg(stage0)] impl + Clone + 'static> Interner { pub fn new() -> Interner { Interner { @@ -79,7 +80,71 @@ impl + Clone + 'static> Interner { } pub fn find(&self, val: &Q) -> Option - where Q: BorrowFrom + Eq + Hash { + where T: Borrow, Q: Eq + Hash { + let map = self.map.borrow(); + match (*map).get(val) { + Some(v) => Some(*v), + None => None, + } + } + + pub fn clear(&self) { + *self.map.borrow_mut() = HashMap::new(); + *self.vect.borrow_mut() = Vec::new(); + } +} +// when traits can extend traits, we should extend index to get [] +#[cfg(not(stage0))] +impl Interner { + pub fn new() -> Interner { + Interner { + map: RefCell::new(HashMap::new()), + vect: RefCell::new(Vec::new()), + } + } + + pub fn prefill(init: &[T]) -> Interner { + let rv = Interner::new(); + for v in init { + rv.intern((*v).clone()); + } + rv + } + + pub fn intern(&self, val: T) -> Name { + let mut map = self.map.borrow_mut(); + match (*map).get(&val) { + Some(&idx) => return idx, + None => (), + } + + let mut vect = self.vect.borrow_mut(); + let new_idx = Name((*vect).len() as u32); + (*map).insert(val.clone(), new_idx); + (*vect).push(val); + new_idx + } + + pub fn gensym(&self, val: T) -> Name { + let mut vect = self.vect.borrow_mut(); + let new_idx = Name((*vect).len() as u32); + // leave out of .map to avoid colliding + (*vect).push(val); + new_idx + } + + pub fn get(&self, idx: Name) -> T { + let vect = self.vect.borrow(); + (*vect)[idx.usize()].clone() + } + + pub fn len(&self) -> usize { + let vect = self.vect.borrow(); + (*vect).len() + } + + pub fn find(&self, val: &Q) -> Option + where T: Borrow, Q: Eq + Hash { let map = self.map.borrow(); match (*map).get(val) { Some(v) => Some(*v), @@ -110,34 +175,34 @@ impl Eq for RcStr {} impl Ord for RcStr { fn cmp(&self, other: &RcStr) -> Ordering { - self[].cmp(&other[]) + self[..].cmp(&other[..]) } } impl fmt::Debug for RcStr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use std::fmt::Debug; - self[].fmt(f) + self[..].fmt(f) } } impl fmt::Display for RcStr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use std::fmt::Display; - self[].fmt(f) + self[..].fmt(f) } } -impl BorrowFrom for str { - fn borrow_from(owned: &RcStr) -> &str { - &owned.string[] +impl Borrow for RcStr { + fn borrow(&self) -> &str { + &self.string[..] } } impl Deref for RcStr { type Target = str; - fn deref(&self) -> &str { &self.string[] } + fn deref(&self) -> &str { &self.string[..] } } /// A StrInterner differs from Interner in that it accepts @@ -210,8 +275,17 @@ impl StrInterner { self.vect.borrow().len() } + #[cfg(stage0)] + pub fn find(&self, val: &Q) -> Option + where RcStr: Borrow, Q: Eq + Hash { + match (*self.map.borrow()).get(val) { + Some(v) => Some(*v), + None => None, + } + } + #[cfg(not(stage0))] pub fn find(&self, val: &Q) -> Option - where Q: BorrowFrom + Eq + Hash { + where RcStr: Borrow, Q: Eq + Hash { match (*self.map.borrow()).get(val) { Some(v) => Some(*v), None => None, diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index b2009a7e84854..0a39d3809045a 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -11,7 +11,7 @@ use self::SmallVectorRepr::*; use self::IntoIterRepr::*; -use std::iter::FromIterator; +use std::iter::{IntoIterator, FromIterator}; use std::mem; use std::slice; use std::vec; @@ -30,7 +30,7 @@ enum SmallVectorRepr { } impl FromIterator for SmallVector { - fn from_iter>(iter: I) -> SmallVector { + fn from_iter>(iter: I) -> SmallVector { let mut v = SmallVector::zero(); v.extend(iter); v @@ -38,7 +38,7 @@ impl FromIterator for SmallVector { } impl Extend for SmallVector { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for val in iter { self.push(val); } diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 304f370a1993e..5418533aff1d9 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -50,7 +50,6 @@ html_playground_url = "http://play.rust-lang.org/")] #![deny(missing_docs)] -#![feature(core)] #![feature(box_syntax)] #![feature(collections)] #![feature(int_uint)] diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index b978d2d8054e5..be1c623c85905 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -180,7 +180,7 @@ impl TerminfoTerminal { } }; - let entry = open(&term[]); + let entry = open(&term[..]); if entry.is_err() { if env::var("MSYSCON").ok().map_or(false, |s| { "mintty.exe" == s diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index 82b5ec11d95d1..0b577f8de74c2 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -608,7 +608,7 @@ mod test { Result, String> { let mut u8v: Vec<_> = fmt.bytes().collect(); - u8v.extend(cap.as_bytes().iter().map(|&b| b)); + u8v.extend(cap.bytes()); expand(&u8v, params, vars) } diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index fd6e6a843e1f3..c40a5534efbbb 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -60,13 +60,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { for p in &dirs_to_search { if p.exists() { let f = first_char.to_string(); - let newp = p.join_many(&[&f[], term]); + let newp = p.join_many(&[&f[..], term]); if newp.exists() { return Some(box newp); } // on some installations the dir is named after the hex of the char (e.g. OS X) let f = format!("{:x}", first_char as uint); - let newp = p.join_many(&[&f[], term]); + let newp = p.join_many(&[&f[..], term]); if newp.exists() { return Some(box newp); } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 2cb30ad9804c6..82c1a4b1195ce 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -37,7 +37,6 @@ #![feature(collections)] #![feature(core)] #![feature(env)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(old_path)] @@ -721,7 +720,7 @@ fn should_sort_failures_before_printing_them() { st.write_failures().unwrap(); let s = match st.out { - Raw(ref m) => String::from_utf8_lossy(&m[]), + Raw(ref m) => String::from_utf8_lossy(&m[..]), Pretty(_) => unreachable!() }; @@ -834,7 +833,7 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec filtered, Some(ref filter) => { filtered.into_iter().filter(|test| { - test.desc.name.as_slice().contains(&filter[]) + test.desc.name.as_slice().contains(&filter[..]) }).collect() } }; diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 31ce3e91a7717..4e94be59ade0d 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -12,7 +12,7 @@ use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::collections::hash_map::{self, Hasher}; +use std::collections::hash_map; use std::hash::Hash; use std::mem; use std::num::{Float, FromPrimitive}; @@ -333,7 +333,7 @@ pub fn winsorize(samples: &mut [T], pct: T) { /// Returns a HashMap with the number of occurrences of every element in the /// sequence that the iterator exposes. pub fn freq_count(iter: T) -> hash_map::HashMap - where T: Iterator, U: Eq + Clone + Hash + where T: Iterator, U: Eq + Clone + Hash { let mut map: hash_map::HashMap = hash_map::HashMap::new(); for elem in iter { diff --git a/src/llvm b/src/llvm index 2089cab13e7f9..4891e6382e3e8 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 2089cab13e7f92b487ba0dc1df9f6c05116b004a +Subproject commit 4891e6382e3e8aa89d530aa18427836428c47157 diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index 6f5fc5c1969f0..224f1ef1a8b9b 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -92,7 +92,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { { let urls = markdown_data.replace(".md)", ".html)"); try!(File::create(&preprocessed_path) - .write_str(&urls[])); + .write_str(&urls[..])); } // write the prelude to a temporary HTML file for rustdoc inclusion diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs index 1c10a270acc6c..43c882c7d5b8a 100644 --- a/src/rustbook/error.rs +++ b/src/rustbook/error.rs @@ -52,7 +52,7 @@ impl<'a> Error for &'a str { impl Error for String { fn description<'a>(&'a self) -> &'a str { - &self[] + &self[..] } } @@ -75,7 +75,7 @@ impl Error for IoError { self.desc } fn detail(&self) -> Option<&str> { - self.detail.as_ref().map(|s| &s[]) + self.detail.as_ref().map(|s| &s[..]) } } diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs index d3cb8a7316e86..c5d4875423ae1 100644 --- a/src/rustbook/test.rs +++ b/src/rustbook/test.rs @@ -65,7 +65,7 @@ impl Subcommand for Test { } Err(errors) => { for err in errors { - term.err(&err[]); + term.err(&err[..]); } return Err(box "There was an error." as Box); } diff --git a/src/test/auxiliary/coherence-orphan-lib.rs b/src/test/auxiliary/coherence-orphan-lib.rs index 2e5d18b58f22f..cc42b288e6638 100644 --- a/src/test/auxiliary/coherence-orphan-lib.rs +++ b/src/test/auxiliary/coherence-orphan-lib.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait TheTrait { +pub trait TheTrait : ::std::marker::PhantomFn { fn the_fn(&self); } diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/auxiliary/default_type_params_xc.rs index d12f716decf99..0a65174911ec7 100644 --- a/src/test/auxiliary/default_type_params_xc.rs +++ b/src/test/auxiliary/default_type_params_xc.rs @@ -12,4 +12,5 @@ pub struct Heap; pub struct FakeHeap; -pub struct FakeVec; +pub struct FakeVec { pub f: Option<(T,A)> } + diff --git a/src/test/auxiliary/inner_static.rs b/src/test/auxiliary/inner_static.rs index 94acea0661838..ca5c6072cb371 100644 --- a/src/test/auxiliary/inner_static.rs +++ b/src/test/auxiliary/inner_static.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct A; -pub struct B; +pub struct A { pub v: T } +pub struct B { pub v: T } pub mod test { - pub struct A; + pub struct A { pub v: T } impl A { pub fn foo(&self) -> int { @@ -52,9 +52,9 @@ impl B { } pub fn foo() -> int { - let a = A::<()>; - let b = B::<()>; - let c = test::A::<()>; + let a = A { v: () }; + let b = B { v: () }; + let c = test::A { v: () }; return a.foo() + a.bar() + b.foo() + b.bar() + c.foo() + c.bar(); diff --git a/src/test/auxiliary/issue-14421.rs b/src/test/auxiliary/issue-14421.rs index 7c69cba179ca1..a48088609f982 100644 --- a/src/test/auxiliary/issue-14421.rs +++ b/src/test/auxiliary/issue-14421.rs @@ -10,6 +10,7 @@ #![crate_type="lib"] #![deny(warnings)] +#![allow(dead_code)] pub use src::aliases::B; pub use src::hidden_core::make; @@ -23,9 +24,9 @@ mod src { pub mod hidden_core { use super::aliases::B; - pub struct A; + pub struct A { t: T } - pub fn make() -> B { A } + pub fn make() -> B { A { t: 1.0 } } impl A { pub fn foo(&mut self) { println!("called foo"); } diff --git a/src/test/auxiliary/issue-16643.rs b/src/test/auxiliary/issue-16643.rs index c5b3fceaf4a5f..b590160a0c2ab 100644 --- a/src/test/auxiliary/issue-16643.rs +++ b/src/test/auxiliary/issue-16643.rs @@ -10,7 +10,7 @@ #![crate_type = "lib"] -pub struct TreeBuilder; +pub struct TreeBuilder { pub h: H } impl TreeBuilder { pub fn process_token(&mut self) { diff --git a/src/test/auxiliary/issue-17662.rs b/src/test/auxiliary/issue-17662.rs index be10ca1dd8fd8..fb55a077005eb 100644 --- a/src/test/auxiliary/issue-17662.rs +++ b/src/test/auxiliary/issue-17662.rs @@ -11,7 +11,7 @@ #![crate_type = "lib"] pub trait Foo<'a, T> { - fn foo(&self) -> T; + fn foo(&'a self) -> T; } pub fn foo<'a, T>(x: &'a Foo<'a, T>) -> T { diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs index 8eb6cd6e26318..96f33f97a6969 100644 --- a/src/test/auxiliary/issue-2380.rs +++ b/src/test/auxiliary/issue-2380.rs @@ -14,7 +14,10 @@ #![allow(unknown_features)] #![feature(box_syntax)] -pub trait i { } +pub trait i +{ + fn dummy(&self, t: T) -> T { panic!() } +} pub fn f() -> Box+'static> { impl i for () { } diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index e3ce4e8f6565a..89b3b56121a16 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -13,8 +13,11 @@ #![feature(unsafe_destructor)] +use std::marker; + struct arc_destruct { - _data: int, + _data: int, + _marker: marker::PhantomData } #[unsafe_destructor] @@ -24,7 +27,8 @@ impl Drop for arc_destruct { fn arc_destruct(data: int) -> arc_destruct { arc_destruct { - _data: data + _data: data, + _marker: marker::PhantomData } } diff --git a/src/test/auxiliary/issue_20389.rs b/src/test/auxiliary/issue_20389.rs index 7a378b06df9e1..4ce7e3079e330 100644 --- a/src/test/auxiliary/issue_20389.rs +++ b/src/test/auxiliary/issue_20389.rs @@ -10,4 +10,5 @@ pub trait T { type C; + fn dummy(&self) { } } diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs index 2e254e5431d53..545e15fe1664d 100644 --- a/src/test/auxiliary/issue_3907.rs +++ b/src/test/auxiliary/issue_3907.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Foo { +use std::marker::MarkerTrait; + +pub trait Foo : MarkerTrait { fn bar(); } diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs index 0831993119ae8..9006a5d1775f7 100644 --- a/src/test/auxiliary/issue_8401.rs +++ b/src/test/auxiliary/issue_8401.rs @@ -12,7 +12,9 @@ use std::mem; -trait A {} +trait A { + fn dummy(&self) { } +} struct B; impl A for B {} diff --git a/src/test/auxiliary/issue_9123.rs b/src/test/auxiliary/issue_9123.rs index 000cc100a12f3..4f2792aebcd24 100644 --- a/src/test/auxiliary/issue_9123.rs +++ b/src/test/auxiliary/issue_9123.rs @@ -15,5 +15,6 @@ pub trait X { fn f() { } f(); } + fn dummy(&self) { } } diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index 834667968c85b..b9cc20b63cc56 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -12,8 +12,12 @@ #![no_std] #![feature(lang_items)] +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + #[lang="sized"] -pub trait Sized {} +pub trait Sized : PhantomFn {} #[lang="panic"] fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} } @@ -25,6 +29,8 @@ extern fn stack_exhausted() {} extern fn eh_personality() {} #[lang="copy"] -pub trait Copy {} +pub trait Copy : PhantomFn { + // Empty. +} diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs index 36b3091852bce..e9d98889ff854 100644 --- a/src/test/auxiliary/lint_group_plugin_test.rs +++ b/src/test/auxiliary/lint_group_plugin_test.rs @@ -37,9 +37,9 @@ impl LintPass for Pass { fn check_item(&mut self, cx: &Context, it: &ast::Item) { let name = token::get_ident(it.ident); - if &name[] == "lintme" { + if &name[..] == "lintme" { cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); - } else if &name[] == "pleaselintme" { + } else if &name[..] == "pleaselintme" { cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"); } } diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs index 9020bb7b0fb2e..ffb234f70c8e7 100644 --- a/src/test/auxiliary/lint_plugin_test.rs +++ b/src/test/auxiliary/lint_plugin_test.rs @@ -35,7 +35,7 @@ impl LintPass for Pass { fn check_item(&mut self, cx: &Context, it: &ast::Item) { let name = token::get_ident(it.ident); - if &name[] == "lintme" { + if &name[..] == "lintme" { cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); } } diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs index 01b2b748ba9d8..fb535eb8336f9 100644 --- a/src/test/auxiliary/lint_stability.rs +++ b/src/test/auxiliary/lint_stability.rs @@ -96,7 +96,7 @@ pub trait Trait { impl Trait for MethodTester {} #[unstable(feature = "test_feature")] -pub trait UnstableTrait {} +pub trait UnstableTrait { fn dummy(&self) { } } #[stable(feature = "test_feature", since = "1.0.0")] #[deprecated(since = "1.0.0")] diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs index 21784bda27a8f..fc1bea5a9fd41 100644 --- a/src/test/auxiliary/nested_item.rs +++ b/src/test/auxiliary/nested_item.rs @@ -25,7 +25,7 @@ impl Foo { } // issue 8134 -pub struct Parser; +pub struct Parser(T); impl> Parser { fn in_doctype(&mut self) { static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E']; diff --git a/src/test/auxiliary/orphan_check_diagnostics.rs b/src/test/auxiliary/orphan_check_diagnostics.rs index 7647f159401a7..cf3e9903b5ad0 100644 --- a/src/test/auxiliary/orphan_check_diagnostics.rs +++ b/src/test/auxiliary/orphan_check_diagnostics.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait RemoteTrait {} +pub trait RemoteTrait { fn dummy(&self) { } } diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs index caa9bbe5736e4..3c8cba13ae73d 100644 --- a/src/test/auxiliary/overloaded_autoderef_xc.rs +++ b/src/test/auxiliary/overloaded_autoderef_xc.rs @@ -11,7 +11,8 @@ use std::ops::Deref; struct DerefWithHelper { - pub helper: H + pub helper: H, + pub value: Option } trait Helper { @@ -34,6 +35,6 @@ impl> Deref for DerefWithHelper { // Test cross-crate autoderef + vtable. pub fn check(x: T, y: T) -> bool { - let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x) }; + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), value: None }; d.eq(&y) } diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs index 907d80b50db82..d0ab944813a0a 100644 --- a/src/test/auxiliary/plugin_args.rs +++ b/src/test/auxiliary/plugin_args.rs @@ -37,7 +37,7 @@ impl TTMacroExpander for Expander { _: &[ast::TokenTree]) -> Box { let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i)) .collect::>().connect(", "); - let interned = token::intern_and_get_ident(&args[]); + let interned = token::intern_and_get_ident(&args[..]); MacExpr::new(ecx.expr_str(sp, interned)) } } diff --git a/src/test/auxiliary/private_trait_xc.rs b/src/test/auxiliary/private_trait_xc.rs index 37ee10c8d3733..42691579491bb 100644 --- a/src/test/auxiliary/private_trait_xc.rs +++ b/src/test/auxiliary/private_trait_xc.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo : ::std::marker::MarkerTrait {} diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/auxiliary/svh-a-base.rs index 12833daf60458..04f1062c16f02 100644 --- a/src/test/auxiliary/svh-a-base.rs +++ b/src/test/auxiliary/svh-a-base.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/auxiliary/svh-a-change-lit.rs index 9e74bf281358f..fabd2289e9a44 100644 --- a/src/test/auxiliary/svh-a-change-lit.rs +++ b/src/test/auxiliary/svh-a-change-lit.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/auxiliary/svh-a-change-significant-cfg.rs index c900550041b5c..3fdb861bd40c1 100644 --- a/src/test/auxiliary/svh-a-change-significant-cfg.rs +++ b/src/test/auxiliary/svh-a-change-significant-cfg.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/auxiliary/svh-a-change-trait-bound.rs index 04f8eb3cf9bc0..3116d24673d48 100644 --- a/src/test/auxiliary/svh-a-change-trait-bound.rs +++ b/src/test/auxiliary/svh-a-change-trait-bound.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/auxiliary/svh-a-change-type-arg.rs index c7e0a18768a3d..b49a1533628f6 100644 --- a/src/test/auxiliary/svh-a-change-type-arg.rs +++ b/src/test/auxiliary/svh-a-change-type-arg.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/auxiliary/svh-a-change-type-ret.rs index 5100af323183b..6562a93135f39 100644 --- a/src/test/auxiliary/svh-a-change-type-ret.rs +++ b/src/test/auxiliary/svh-a-change-type-ret.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/auxiliary/svh-a-change-type-static.rs index 077c33cb90d75..c7b392c6ee82b 100644 --- a/src/test/auxiliary/svh-a-change-type-static.rs +++ b/src/test/auxiliary/svh-a-change-type-static.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/auxiliary/svh-a-comment.rs index d481fa5a1fa3b..450f61020260d 100644 --- a/src/test/auxiliary/svh-a-comment.rs +++ b/src/test/auxiliary/svh-a-comment.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/auxiliary/svh-a-doc.rs index 9e99a355ac1ee..c000737c854c6 100644 --- a/src/test/auxiliary/svh-a-doc.rs +++ b/src/test/auxiliary/svh-a-doc.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/auxiliary/svh-a-macro.rs index b8dd497ac99c8..1e12659dc4b92 100644 --- a/src/test/auxiliary/svh-a-macro.rs +++ b/src/test/auxiliary/svh-a-macro.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/auxiliary/svh-a-no-change.rs index 12833daf60458..04f1062c16f02 100644 --- a/src/test/auxiliary/svh-a-no-change.rs +++ b/src/test/auxiliary/svh-a-no-change.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/auxiliary/svh-a-redundant-cfg.rs index 690ddc670f5fa..1e82b74f1ef2e 100644 --- a/src/test/auxiliary/svh-a-redundant-cfg.rs +++ b/src/test/auxiliary/svh-a-redundant-cfg.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/auxiliary/svh-a-whitespace.rs index 216e8e997f22d..3c3dac9cdab96 100644 --- a/src/test/auxiliary/svh-a-whitespace.rs +++ b/src/test/auxiliary/svh-a-whitespace.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs index 1695e474de999..a7c469fccaa5a 100644 --- a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs +++ b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Trait {} +pub trait Trait { + fn dummy(&self) { } +} pub struct Foo { pub x: T, diff --git a/src/test/auxiliary/trait_impl_conflict.rs b/src/test/auxiliary/trait_impl_conflict.rs index 990bc21604959..0982efbdbf47e 100644 --- a/src/test/auxiliary/trait_impl_conflict.rs +++ b/src/test/auxiliary/trait_impl_conflict.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Foo { +pub trait Foo : ::std::marker::MarkerTrait { } impl Foo for int { diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs index 22e0d3168cadc..56fb40bc0a469 100644 --- a/src/test/auxiliary/use_from_trait_xc.rs +++ b/src/test/auxiliary/use_from_trait_xc.rs @@ -11,7 +11,7 @@ pub use self::sub::{Bar, Baz}; pub trait Trait { - fn foo(); + fn foo(&self); } struct Foo; diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 1d440c4540ca3..994c9605fc375 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -16,9 +16,8 @@ extern crate collections; extern crate rand; use std::collections::BTreeSet; -use std::collections::BitvSet; +use std::collections::BitSet; use std::collections::HashSet; -use std::collections::hash_map::Hasher; use std::hash::Hash; use std::env; use std::time::Duration; @@ -43,7 +42,7 @@ trait MutableSet { fn contains(&self, k: &T) -> bool; } -impl + Eq> MutableSet for HashSet { +impl MutableSet for HashSet { fn insert(&mut self, k: T) { self.insert(k); } fn remove(&mut self, k: &T) -> bool { self.remove(k) } fn contains(&self, k: &T) -> bool { self.contains(k) } @@ -53,7 +52,7 @@ impl MutableSet for BTreeSet { fn remove(&mut self, k: &T) -> bool { self.remove(k) } fn contains(&self, k: &T) -> bool { self.contains(k) } } -impl MutableSet for BitvSet { +impl MutableSet for BitSet { fn insert(&mut self, k: usize) { self.insert(k); } fn remove(&mut self, k: &usize) -> bool { self.remove(k) } fn contains(&self, k: &usize) -> bool { self.contains(k) } @@ -222,7 +221,7 @@ fn main() { { let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed); let mut results = empty_results(); - results.bench_int(&mut rng, num_keys, max, || BitvSet::new()); - write_results("collections::bitv::BitvSet", &results); + results.bench_int(&mut rng, num_keys, max, || BitSet::new()); + write_results("collections::bit_vec::BitSet", &results); } } diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index fd559608011af..2c640c4b09255 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -132,7 +132,7 @@ fn run(writer: &mut W) -> std::old_io::IoResult<()> { ('t', 0.3015094502008)]; try!(make_fasta(writer, ">ONE Homo sapiens alu\n", - alu.as_bytes().iter().cycle().map(|c| *c), n * 2)); + alu.as_bytes().iter().cycle().cloned(), n * 2)); try!(make_fasta(writer, ">TWO IUB ambiguity codes\n", AAGen::new(rng, iub), n * 3)); try!(make_fasta(writer, ">THREE Homo sapiens frequency\n", diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index 73dce2910c9b4..a94fe0ccd9598 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -202,7 +202,7 @@ fn filter_masks(masks: &mut Vec>>) { for i in 0..masks.len() { for j in 0..(*masks)[i].len() { masks[i][j] = - (*masks)[i][j].iter().map(|&m| m) + (*masks)[i][j].iter().cloned() .filter(|&m| !is_board_unfeasible(m, masks)) .collect(); } @@ -270,7 +270,7 @@ fn handle_sol(raw_sol: &List, data: &mut Data) { // reverse order, i.e. the board rotated by half a turn. data.nb += 2; let sol1 = to_vec(raw_sol); - let sol2: Vec = sol1.iter().rev().map(|x| *x).collect(); + let sol2: Vec = sol1.iter().rev().cloned().collect(); if data.nb == 2 { data.min = sol1.clone(); diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs index 621f5ec9660fc..edd1b8255ccdc 100644 --- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs @@ -16,8 +16,12 @@ #![feature(no_std)] #![no_std] +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + #[lang="sized"] -pub trait Sized { +pub trait Sized : PhantomFn { // Empty. } diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs index 95a68dd669836..b7a16c68a34e1 100644 --- a/src/test/compile-fail/associated-types-coherence-failure.rs +++ b/src/test/compile-fail/associated-types-coherence-failure.rs @@ -11,9 +11,10 @@ // Test that coherence detects overlap when some of the types in the // impls are projections of associated type. Issue #20624. +use std::marker::PhantomData; use std::ops::Deref; -pub struct Cow<'a, B: ?Sized>; +pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>); /// Trait for moving into a `Cow` pub trait IntoCow<'a, B: ?Sized> { diff --git a/src/test/compile-fail/associated-types-eq-expr-path.rs b/src/test/compile-fail/associated-types-eq-expr-path.rs index 9baa7f1ad5a69..c48f9972ebc18 100644 --- a/src/test/compile-fail/associated-types-eq-expr-path.rs +++ b/src/test/compile-fail/associated-types-eq-expr-path.rs @@ -10,7 +10,7 @@ // Check that an associated type cannot be bound in an expression path. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { type A; fn bar() -> isize; } diff --git a/src/test/compile-fail/associated-types-issue-17359.rs b/src/test/compile-fail/associated-types-issue-17359.rs index fa09ae793bf63..625f4cdb8ef3d 100644 --- a/src/test/compile-fail/associated-types-issue-17359.rs +++ b/src/test/compile-fail/associated-types-issue-17359.rs @@ -11,7 +11,7 @@ // Test that we do not ICE when an impl is missing an associated type (and that we report // a useful error, of course). -trait Trait { +trait Trait : ::std::marker::MarkerTrait { type Type; } diff --git a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs index 9436f825de89d..5632f148da67c 100644 --- a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs +++ b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { type X; type Y; } diff --git a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs index a3f2850b29464..2b84c38f80b54 100644 --- a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs +++ b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs @@ -11,7 +11,7 @@ // Check that we get an error when you use `::Value` in // the trait definition but `Self` does not, in fact, implement `Get`. -trait Get { +trait Get : ::std::marker::MarkerTrait { type Value; } diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs index 51a37b517ddeb..b9a62ff4e417a 100644 --- a/src/test/compile-fail/associated-types-path-2.rs +++ b/src/test/compile-fail/associated-types-path-2.rs @@ -12,6 +12,8 @@ pub trait Foo { type A; + + fn dummy(&self) { } } impl Foo for i32 { diff --git a/src/test/compile-fail/associated-types-unconstrained.rs b/src/test/compile-fail/associated-types-unconstrained.rs index aecbf217a5b25..8832028f9aba1 100644 --- a/src/test/compile-fail/associated-types-unconstrained.rs +++ b/src/test/compile-fail/associated-types-unconstrained.rs @@ -10,7 +10,7 @@ // Check that an associated type cannot be bound in an expression path. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { type A; fn bar() -> isize; } diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs index c91849ca53e1a..3e02a11c378bd 100644 --- a/src/test/compile-fail/bad-mid-path-type-params.rs +++ b/src/test/compile-fail/bad-mid-path-type-params.rs @@ -10,13 +10,6 @@ // ignore-tidy-linelength -#![feature(no_std)] -#![no_std] -#![feature(lang_items)] - -#[lang="sized"] -pub trait Sized {} - struct S { contents: T, } diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs index 69be6414e4c90..1944acbe1f345 100644 --- a/src/test/compile-fail/bad-sized.rs +++ b/src/test/compile-fail/bad-sized.rs @@ -12,7 +12,7 @@ use std::cell::RefCell; -trait Trait {} +trait Trait : ::std::marker::MarkerTrait {} pub fn main() { let x: Vec = Vec::new(); diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs index 27d97d18c949f..d4decb713498d 100644 --- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs +++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs @@ -10,6 +10,7 @@ use std::fmt::Show; use std::default::Default; +use std::marker::MarkerTrait; // Test that two blanket impls conflict (at least without negative // bounds). After all, some other crate could implement Even or Odd @@ -19,9 +20,9 @@ trait MyTrait { fn get(&self) -> usize; } -trait Even { } +trait Even : MarkerTrait { } -trait Odd { } +trait Odd : MarkerTrait { } impl Even for isize { } diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs index 0f233b78c7216..b1ee1762b6e71 100644 --- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs +++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs @@ -19,9 +19,9 @@ trait MyTrait { fn get(&self) -> usize; } -trait Even { } +trait Even : ::std::marker::MarkerTrait { } -trait Odd { } +trait Odd : ::std::marker::MarkerTrait { } impl MyTrait for T { //~ ERROR E0119 fn get(&self) -> usize { 0 } diff --git a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs index c9dfb8201a98a..a225f6cf47304 100644 --- a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs +++ b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs @@ -10,18 +10,18 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +trait MyTrait : ::std::marker::MarkerTrait {} -struct TestType; +struct TestType(::std::marker::PhantomData); -unsafe impl Send for TestType {} +unsafe impl Send for TestType {} //~^ ERROR conflicting implementations for trait `core::marker::Send` //~^^ ERROR conflicting implementations for trait `core::marker::Send` impl !Send for TestType {} //~^ ERROR conflicting implementations for trait `core::marker::Send` -unsafe impl Send for TestType {} +unsafe impl Send for TestType {} //~^ ERROR error: conflicting implementations for trait `core::marker::Send` impl !Send for TestType {} diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/compile-fail/coherence-subtyping.rs new file mode 100644 index 0000000000000..897cb083f849d --- /dev/null +++ b/src/test/compile-fail/coherence-subtyping.rs @@ -0,0 +1,50 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. + +trait Contravariant { + fn foo(&self) { } +} + +impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) { + //~^ ERROR E0119 +} + +impl Contravariant for for<'a> fn(&'a u8, &'a u8) { +} + +/////////////////////////////////////////////////////////////////////////// + +trait Covariant { + fn foo(&self) { } +} + +impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) { + //~^ ERROR E0119 +} + +impl Covariant for for<'a> fn(&'a u8, &'a u8) { +} + +/////////////////////////////////////////////////////////////////////////// + +trait Invariant { + fn foo(&self) -> Self { } +} + +impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) { +} + +impl Invariant for for<'a> fn(&'a u8, &'a u8) { +} + +fn main() { } diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index 86b7a8c89184a..6bd21101a609d 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -14,7 +14,7 @@ #![feature(box_syntax)] struct Foo; -trait Trait {} +trait Trait { fn foo(&self) {} } impl Trait for Foo {} pub fn main() { diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index f2e068cc4ff1b..4161cce2843b6 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -14,7 +14,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] -trait T {} +trait T { fn foo(&self) {} } impl T for isize {} fn main() { diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs index 2b96c5ebe1284..ddc929017718d 100644 --- a/src/test/compile-fail/dst-bad-coerce1.rs +++ b/src/test/compile-fail/dst-bad-coerce1.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar {} +trait Bar { fn bar(&self) {} } pub fn main() { // With a vec of isize. diff --git a/src/test/compile-fail/dst-bad-coerce2.rs b/src/test/compile-fail/dst-bad-coerce2.rs index 160197368d6d9..aa687266acb8f 100644 --- a/src/test/compile-fail/dst-bad-coerce2.rs +++ b/src/test/compile-fail/dst-bad-coerce2.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar {} +trait Bar : ::std::marker::MarkerTrait {} impl Bar for Foo {} pub fn main() { diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs index 347a2d2ecbe68..7bad3bd69d3b0 100644 --- a/src/test/compile-fail/dst-bad-coerce3.rs +++ b/src/test/compile-fail/dst-bad-coerce3.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar {} +trait Bar { fn bar(&self) {} } impl Bar for Foo {} fn baz<'a>() { diff --git a/src/test/compile-fail/dst-bad-coercions.rs b/src/test/compile-fail/dst-bad-coercions.rs index b30eada162b84..8ec1034bc4d28 100644 --- a/src/test/compile-fail/dst-bad-coercions.rs +++ b/src/test/compile-fail/dst-bad-coercions.rs @@ -10,8 +10,10 @@ // Test implicit coercions involving DSTs and raw pointers. +use std::marker::MarkerTrait; + struct S; -trait T {} +trait T : MarkerTrait {} impl T for S {} struct Foo { diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs index 87ff4291f50e2..b4fd45845f7a0 100644 --- a/src/test/compile-fail/dst-object-from-unsized-type.rs +++ b/src/test/compile-fail/dst-object-from-unsized-type.rs @@ -10,7 +10,7 @@ // Test that we cannot create objects from unsized types. -trait Foo {} +trait Foo { fn foo(&self) {} } impl Foo for str {} fn test1(t: &T) { diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs index 17453bc677f2b..f47f14d587992 100644 --- a/src/test/compile-fail/exclusive-drop-and-copy.rs +++ b/src/test/compile-fail/exclusive-drop-and-copy.rs @@ -20,7 +20,7 @@ impl Drop for Foo { } #[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented -struct Bar; +struct Bar(::std::marker::PhantomData); #[unsafe_destructor] impl Drop for Bar { diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs index 02f09749d614d..9fea5e609d1f4 100644 --- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs +++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo; +use std::marker; + +struct Foo( + marker::PhantomData<(A,B,C)>); impl Foo { - fn new() -> Foo {Foo} + fn new() -> Foo {Foo(marker::PhantomData)} } fn main() { diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs index d88da2625c187..73c19aa012dcf 100644 --- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs +++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Heap; -struct Vec; +struct Vec( + marker::PhantomData<(T,A)>); impl Vec { - fn new() -> Vec {Vec} + fn new() -> Vec {Vec(marker::PhantomData)} } fn main() { diff --git a/src/test/compile-fail/generic-lifetime-trait-impl.rs b/src/test/compile-fail/generic-lifetime-trait-impl.rs index fc54002820e01..9b9f09f477757 100644 --- a/src/test/compile-fail/generic-lifetime-trait-impl.rs +++ b/src/test/compile-fail/generic-lifetime-trait-impl.rs @@ -16,9 +16,12 @@ // // Regression test for issue #16218. -trait Bar<'a> {} +trait Bar<'a> { + fn dummy(&'a self); +} trait Foo<'a> { + fn dummy(&'a self) { } fn bar<'b, T: Bar<'b>>(self) -> &'b str; } diff --git a/src/test/compile-fail/generic-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs index f25d8f99b8d54..37737fda4749e 100644 --- a/src/test/compile-fail/generic-type-less-params-with-defaults.rs +++ b/src/test/compile-fail/generic-type-less-params-with-defaults.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Heap; -struct Vec; +struct Vec( + marker::PhantomData<(T,A)>); fn main() { let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0 diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs index 19d303488acb0..ad7e4f190c5b9 100644 --- a/src/test/compile-fail/generic-type-more-params-with-defaults.rs +++ b/src/test/compile-fail/generic-type-more-params-with-defaults.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Heap; -struct Vec; +struct Vec( + marker::PhantomData<(T,A)>); fn main() { let _: Vec; diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs index 3e34344d78b9d..a452cd35f943f 100644 --- a/src/test/compile-fail/generic-type-params-name-repr.rs +++ b/src/test/compile-fail/generic-type-params-name-repr.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct A; struct B; struct C; -struct Foo; +struct Foo(marker::PhantomData<(T,U,V)>); -struct Hash; -struct HashMap>; +struct Hash(marker::PhantomData); +struct HashMap>(marker::PhantomData<(K,V,H)>); fn main() { // Ensure that the printed type doesn't include the default type params... diff --git a/src/test/compile-fail/issue-11515.rs b/src/test/compile-fail/issue-11515.rs index f0089b0ae5b34..4ff574e939df6 100644 --- a/src/test/compile-fail/issue-11515.rs +++ b/src/test/compile-fail/issue-11515.rs @@ -10,7 +10,7 @@ #![feature(box_syntax)] -struct Test<'s> { +struct Test { func: Box } diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs index ea0d880f4a1cc..dc697e4784f85 100644 --- a/src/test/compile-fail/issue-13853-2.rs +++ b/src/test/compile-fail/issue-13853-2.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait FromStructReader<'a> { } +use std::marker::PhantomFn; + +trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { } trait ResponseHook { fn get<'a, T: FromStructReader<'a>>(&'a self); } diff --git a/src/test/compile-fail/issue-13853-3.rs b/src/test/compile-fail/issue-13853-3.rs index f10c47b594ea2..7ca158c3e3204 100644 --- a/src/test/compile-fail/issue-13853-3.rs +++ b/src/test/compile-fail/issue-13853-3.rs @@ -10,6 +10,8 @@ #![crate_type = "lib"] +use std::marker::PhantomData; + enum NodeContents<'a> { Children(Vec>), } @@ -22,11 +24,12 @@ impl<'a> Drop for NodeContents<'a> { struct Node<'a> { contents: NodeContents<'a>, + marker: PhantomData<&'a ()>, } impl<'a> Node<'a> { fn noName(contents: NodeContents<'a>) -> Node<'a> { - Node{ contents: contents,} + Node { contents: contents, marker: PhantomData } } } diff --git a/src/test/compile-fail/issue-13853.rs b/src/test/compile-fail/issue-13853.rs index 251da2c6b3ee9..cd3f337c4ab65 100644 --- a/src/test/compile-fail/issue-13853.rs +++ b/src/test/compile-fail/issue-13853.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Node { +use std::marker::MarkerTrait; + +trait Node : MarkerTrait { fn zomg(); } diff --git a/src/test/compile-fail/issue-14285.rs b/src/test/compile-fail/issue-14285.rs index cbf4412a81df2..3a5df9e805bdb 100644 --- a/src/test/compile-fail/issue-14285.rs +++ b/src/test/compile-fail/issue-14285.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self) { } +} struct A; diff --git a/src/test/compile-fail/issue-14853.rs b/src/test/compile-fail/issue-14853.rs index 51deb99a4f2cd..0b846651acf46 100644 --- a/src/test/compile-fail/issue-14853.rs +++ b/src/test/compile-fail/issue-14853.rs @@ -9,8 +9,9 @@ // except according to those terms. use std::fmt::Debug; +use std::marker::MarkerTrait; -trait Str {} +trait Str : MarkerTrait {} trait Something { fn yay(_: Option, thing: &[T]); diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs index 814b885e3aafc..a213234b89b0f 100644 --- a/src/test/compile-fail/issue-16747.rs +++ b/src/test/compile-fail/issue-16747.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait ListItem<'a> { +use std::marker::MarkerTrait; + +trait ListItem<'a> : MarkerTrait { fn list_name() -> &'a str; } diff --git a/src/test/compile-fail/issue-17431-4.rs b/src/test/compile-fail/issue-17431-4.rs index 1e27f02556470..22aaa796ad0f4 100644 --- a/src/test/compile-fail/issue-17431-4.rs +++ b/src/test/compile-fail/issue-17431-4.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo { foo: Option>> } +use std::marker; + +struct Foo { foo: Option>>, marker: marker::PhantomData } //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable impl Foo { fn bar(&self) {} } diff --git a/src/test/compile-fail/issue-17431-5.rs b/src/test/compile-fail/issue-17431-5.rs index d22d79ecaa550..cc9cc2e3c035c 100644 --- a/src/test/compile-fail/issue-17431-5.rs +++ b/src/test/compile-fail/issue-17431-5.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Foo { foo: Bar } -struct Bar { x: Bar } +struct Bar { x: Bar , marker: marker::PhantomData } //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable impl Foo { fn foo(&self) {} } diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs index e037ba92b4a6a..5781cb7411743 100644 --- a/src/test/compile-fail/issue-17551.rs +++ b/src/test/compile-fail/issue-17551.rs @@ -10,9 +10,11 @@ #![feature(unboxed_closures)] -struct B; +use std::marker; + +struct B(marker::PhantomData); fn main() { - let foo = B; //~ ERROR: unable to infer enough type information + let foo = B(marker::PhantomData); //~ ERROR unable to infer enough type information let closure = || foo; } diff --git a/src/test/compile-fail/issue-17904-2.rs b/src/test/compile-fail/issue-17904-2.rs new file mode 100644 index 0000000000000..a33ec23a16a51 --- /dev/null +++ b/src/test/compile-fail/issue-17904-2.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we can parse a unit struct with a where clause, even if +// it leads to a error later on since `T` is unused. + +struct Foo where T: Copy; //~ ERROR parameter `T` is never used + +fn main() {} diff --git a/src/test/compile-fail/issue-18107.rs b/src/test/compile-fail/issue-18107.rs index 91689988f583d..d5fb22bdebdb4 100644 --- a/src/test/compile-fail/issue-18107.rs +++ b/src/test/compile-fail/issue-18107.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::MarkerTrait; - -pub trait AbstractRenderer {} +pub trait AbstractRenderer : MarkerTrait {} fn _create_render(_: &()) -> AbstractRenderer diff --git a/src/test/compile-fail/issue-18611.rs b/src/test/compile-fail/issue-18611.rs index a662e9ca98ee8..e81a576fa63d5 100644 --- a/src/test/compile-fail/issue-18611.rs +++ b/src/test/compile-fail/issue-18611.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::MarkerTrait; + fn add_state(op: ::State) { //~^ ERROR the trait `HasState` is not implemented for the type `isize` } -trait HasState { +trait HasState : MarkerTrait { type State; } diff --git a/src/test/compile-fail/issue-18783.rs b/src/test/compile-fail/issue-18783.rs index 5ddf06add9d3e..13908bda9d83b 100644 --- a/src/test/compile-fail/issue-18783.rs +++ b/src/test/compile-fail/issue-18783.rs @@ -26,6 +26,7 @@ fn ufcs() { Push::push(&c, box || y = 0); Push::push(&c, box || y = 0); +//~^ ERROR cannot borrow `y` as mutable more than once at a time } trait Push<'c> { diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs index 3a9de74104364..951d78410b814 100644 --- a/src/test/compile-fail/issue-18819.rs +++ b/src/test/compile-fail/issue-18819.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { type Item; } diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs index 14601e67a77c1..77aba7335bdf9 100644 --- a/src/test/compile-fail/issue-19660.rs +++ b/src/test/compile-fail/issue-19660.rs @@ -13,8 +13,12 @@ #![feature(lang_items, start, no_std)] #![no_std] +#[lang="phantom_fn"] +trait PhantomFn { } +impl PhantomFn for U { } + #[lang = "sized"] -trait Sized {} +trait Sized : PhantomFn {} #[start] fn main(_: int, _: *const *const u8) -> int { diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs index 00607f850347c..aed395d17ea9c 100644 --- a/src/test/compile-fail/issue-2063.rs +++ b/src/test/compile-fail/issue-2063.rs @@ -12,10 +12,11 @@ // cause compiler to loop. Note that no instances // of such a type could ever be constructed. +use std::marker::MarkerTrait; struct t(Box); //~ ERROR this type cannot be instantiated -trait to_str_2 { +trait to_str_2 : MarkerTrait { fn my_to_string() -> String; } diff --git a/src/test/compile-fail/issue-20831-debruijn.rs b/src/test/compile-fail/issue-20831-debruijn.rs index aaf45f2739891..5b623ac377b21 100644 --- a/src/test/compile-fail/issue-20831-debruijn.rs +++ b/src/test/compile-fail/issue-20831-debruijn.rs @@ -13,10 +13,11 @@ // below. Note that changing to a named lifetime made the problem go // away. -use std::ops::{Shl, Shr}; use std::cell::RefCell; +use std::marker::MarkerTrait; +use std::ops::{Shl, Shr}; -pub trait Subscriber { +pub trait Subscriber : MarkerTrait { type Input; } diff --git a/src/test/compile-fail/issue-21160.rs b/src/test/compile-fail/issue-21160.rs index 45b7fbbd0b46a..557bf518a3cfb 100644 --- a/src/test/compile-fail/issue-21160.rs +++ b/src/test/compile-fail/issue-21160.rs @@ -16,6 +16,6 @@ impl Bar { #[derive(Hash)] struct Foo(Bar); -//~^ error: the trait `core::hash::Hash<_>` is not implemented for the type `Bar` +//~^ error: the trait `core::hash::Hash` is not implemented for the type `Bar` fn main() {} diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs index 31796e5e20c44..24cc0099b89a5 100644 --- a/src/test/compile-fail/issue-2611-4.rs +++ b/src/test/compile-fail/issue-2611-4.rs @@ -12,7 +12,7 @@ // than the trait method it's implementing trait A { - fn b(x: C) -> C; + fn b(&self, x: C) -> C; } struct E { @@ -20,7 +20,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { panic!() } + fn b(&self, _x: F) -> F { panic!() } //~^ ERROR `F : core::marker::Sync` appears on the impl method } diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs index a338a01690dea..af6cee1f10749 100644 --- a/src/test/compile-fail/issue-3008-3.rs +++ b/src/test/compile-fail/issue-3008-3.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + enum E1 { V1(E2), } -enum E2 { V2(E2), } +enum E2 { V2(E2, marker::PhantomData), } //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable impl E1 { fn foo(&self) {} } diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs index 9a398796d2abf..f384dba7c9e3d 100644 --- a/src/test/compile-fail/issue-4972.rs +++ b/src/test/compile-fail/issue-4972.rs @@ -11,7 +11,9 @@ #![feature(box_patterns)] #![feature(box_syntax)] -trait MyTrait { } +trait MyTrait { + fn dummy(&self) {} +} pub enum TraitWrapper { A(Box), diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/compile-fail/issue-5035-2.rs index 9e324cdd61eb0..d316b44794ad6 100644 --- a/src/test/compile-fail/issue-5035-2.rs +++ b/src/test/compile-fail/issue-5035-2.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait I {} +use std::marker::MarkerTrait; + +trait I : MarkerTrait {} type K = I+'static; fn foo(_x: K) {} //~ ERROR: the trait `core::marker::Sized` is not implemented diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs index cf98f1572e560..4d721ad76666d 100644 --- a/src/test/compile-fail/issue-5543.rs +++ b/src/test/compile-fail/issue-5543.rs @@ -10,7 +10,7 @@ #![feature(box_syntax)] -trait Foo {} +trait Foo { fn foo(&self) {} } impl Foo for u8 {} fn main() { diff --git a/src/test/compile-fail/issue-5883.rs b/src/test/compile-fail/issue-5883.rs index 9ff957b6e6dea..b0db990619535 100644 --- a/src/test/compile-fail/issue-5883.rs +++ b/src/test/compile-fail/issue-5883.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +use std::marker::MarkerTrait; + +trait A : MarkerTrait {} struct Struct { r: A+'static @@ -20,6 +22,6 @@ fn new_struct(r: A+'static) Struct { r: r } } -trait Curve {} +trait Curve : MarkerTrait {} enum E {X(Curve+'static)} fn main() {} diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs index efa3100360b5c..0bf9a3c2d4867 100644 --- a/src/test/compile-fail/issue-6458.rs +++ b/src/test/compile-fail/issue-6458.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct TypeWithState; +use std::marker; + +pub struct TypeWithState(marker::PhantomData); pub struct MyState; pub fn foo(_: TypeWithState) {} pub fn bar() { - foo(TypeWithState); //~ ERROR type annotations required + foo(TypeWithState(marker::PhantomData)); //~ ERROR type annotations required } fn main() { diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs index 9e6000c050a51..b6643f439529b 100644 --- a/src/test/compile-fail/issue-7575.rs +++ b/src/test/compile-fail/issue-7575.rs @@ -10,12 +10,14 @@ // Test the mechanism for warning about possible missing `self` declarations. +use std::marker::MarkerTrait; + trait CtxtFn { fn f8(self, usize) -> usize; fn f9(usize) -> usize; //~ NOTE candidate } -trait OtherTrait { +trait OtherTrait : MarkerTrait { fn f9(usize) -> usize; //~ NOTE candidate } @@ -24,7 +26,7 @@ trait OtherTrait { // declaration to match against, so we wind up prisizeing it as a // candidate. This seems not unreasonable -- perhaps the user meant to // implement it, after all. -trait UnusedTrait { +trait UnusedTrait : MarkerTrait { fn f9(usize) -> usize; //~ NOTE candidate } @@ -52,7 +54,7 @@ impl Myisize { } } -trait ManyImplTrait { +trait ManyImplTrait : MarkerTrait { fn is_str() -> bool { //~ NOTE candidate false } diff --git a/src/test/compile-fail/issue-8727.rs b/src/test/compile-fail/issue-8727.rs index d1a86d334cb44..72da6dcaa6c45 100644 --- a/src/test/compile-fail/issue-8727.rs +++ b/src/test/compile-fail/issue-8727.rs @@ -13,16 +13,12 @@ // Verify the compiler fails with an error on infinite function // recursions. -struct Data(Box>); - -fn generic( _ : Vec<(Data,T)> ) { - let rec : Vec<(Data,(bool,T))> = Vec::new(); - generic( rec ); +fn generic() { + generic::>(); } fn main () { // Use generic at least once to trigger instantiation. - let input : Vec<(Data,())> = Vec::new(); - generic(input); + generic::(); } diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs index 56f83d9300861..74e372e41eb0a 100644 --- a/src/test/compile-fail/kindck-copy.rs +++ b/src/test/compile-fail/kindck-copy.rs @@ -10,12 +10,12 @@ // Test which of the builtin types are considered POD. - +use std::marker::MarkerTrait; use std::rc::Rc; fn assert_copy() { } -trait Dummy { } +trait Dummy : MarkerTrait { } #[derive(Copy)] struct MyStruct { diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index 2731be7308a4a..b575144f637f1 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { } impl Foo for T { diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs index d5276efa8be98..dffc8fa2abd70 100644 --- a/src/test/compile-fail/kindck-impl-type-params.rs +++ b/src/test/compile-fail/kindck-impl-type-params.rs @@ -13,40 +13,44 @@ #![feature(box_syntax)] -struct S; +use std::marker; -trait Gettable {} +struct S(marker::PhantomData); + +trait Gettable { + fn get(&self) -> T { panic!() } +} impl Gettable for S {} fn f(val: T) { - let t: S = S; + let t: S = S(marker::PhantomData); let a = &t as &Gettable; //~^ ERROR the trait `core::marker::Send` is not implemented //~^^ ERROR the trait `core::marker::Copy` is not implemented } fn g(val: T) { - let t: S = S; + let t: S = S(marker::PhantomData); let a: &Gettable = &t; //~^ ERROR the trait `core::marker::Send` is not implemented //~^^ ERROR the trait `core::marker::Copy` is not implemented } fn foo<'a>() { - let t: S<&'a isize> = S; + let t: S<&'a isize> = S(marker::PhantomData); let a = &t as &Gettable<&'a isize>; - //~^ ERROR the type `&'a isize` does not fulfill the required lifetime + //~^ ERROR cannot infer } fn foo2<'a>() { - let t: Box> = box S; + let t: Box> = box S(marker::PhantomData); let a = t as Box>; //~^ ERROR the trait `core::marker::Copy` is not implemented } fn foo3<'a>() { - let t: Box> = box S; + let t: Box> = box S(marker::PhantomData); let a: Box> = t; //~^ ERROR the trait `core::marker::Copy` is not implemented } diff --git a/src/test/compile-fail/kindck-inherited-copy-bound.rs b/src/test/compile-fail/kindck-inherited-copy-bound.rs index e146cac21a31c..0072b1228af48 100644 --- a/src/test/compile-fail/kindck-inherited-copy-bound.rs +++ b/src/test/compile-fail/kindck-inherited-copy-bound.rs @@ -15,6 +15,7 @@ use std::any::Any; trait Foo : Copy { + fn foo(&self) {} } impl Foo for T { diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs index 570f7ad7fe3bf..0c68401bb2b95 100644 --- a/src/test/compile-fail/kindck-send-object.rs +++ b/src/test/compile-fail/kindck-send-object.rs @@ -12,8 +12,10 @@ // in this file all test the "kind" violates detected during kindck. // See all `regions-bounded-by-send.rs` +use std::marker::MarkerTrait; + fn assert_send() { } -trait Dummy { } +trait Dummy : MarkerTrait { } trait Message : Send { } // careful with object types, who knows what they close over... diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs index 48d5215b7085b..f86eac8b16bd2 100644 --- a/src/test/compile-fail/kindck-send-object1.rs +++ b/src/test/compile-fail/kindck-send-object1.rs @@ -12,8 +12,10 @@ // is broken into two parts because some errors occur in distinct // phases in the compiler. See kindck-send-object2.rs as well! +use std::marker::MarkerTrait; + fn assert_send() { } -trait Dummy { } +trait Dummy : MarkerTrait { } // careful with object types, who knows what they close over... fn test51<'a>() { diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs index d3d166e2a6916..08516e67318ce 100644 --- a/src/test/compile-fail/kindck-send-object2.rs +++ b/src/test/compile-fail/kindck-send-object2.rs @@ -10,8 +10,10 @@ // Continue kindck-send-object1.rs. +use std::marker::MarkerTrait; + fn assert_send() { } -trait Dummy { } +trait Dummy : MarkerTrait { } fn test50() { assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs index 04c5b223cb875..66d8927ee51b7 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs @@ -10,7 +10,9 @@ // ignore-tidy-linelength -struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32 } +use std::marker::PhantomData; + +struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> } fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) { //~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32) (x.bar, &x.baz, &x.baz) diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs index c60e321219bd2..a85776a938b44 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs @@ -10,7 +10,9 @@ // ignore-tidy-linelength -struct Foo<'x> { bar: isize } +use std::marker::PhantomData; + +struct Foo<'x> { bar: isize, marker: PhantomData<&'x ()> } fn foo1<'a>(x: &Foo) -> &'a isize { //~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a isize &x.bar //~ ERROR: cannot infer diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs index 3b96fd64fa200..73a58741bbbbc 100644 --- a/src/test/compile-fail/lint-missing-doc.rs +++ b/src/test/compile-fail/lint-missing-doc.rs @@ -47,20 +47,26 @@ fn foo3() {} /// dox pub trait A { /// dox - fn foo(); + fn foo(&self); /// dox - fn foo_with_impl() {} + fn foo_with_impl(&self) {} } + #[allow(missing_docs)] trait B { - fn foo(); - fn foo_with_impl() {} + fn foo(&self); + fn foo_with_impl(&self) {} } + pub trait C { //~ ERROR: missing documentation - fn foo(); //~ ERROR: missing documentation - fn foo_with_impl() {} //~ ERROR: missing documentation + fn foo(&self); //~ ERROR: missing documentation + fn foo_with_impl(&self) {} //~ ERROR: missing documentation +} + +#[allow(missing_docs)] +pub trait D { + fn dummy(&self) { } } -#[allow(missing_docs)] pub trait D {} impl Foo { pub fn foo() {} diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs index 70d6b240985b0..9f58d5791cb0b 100644 --- a/src/test/compile-fail/lint-non-camel-case-types.rs +++ b/src/test/compile-fail/lint-non-camel-case-types.rs @@ -30,6 +30,7 @@ enum Foo5 { } trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6` + fn dummy(&self) { } } fn f(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty` diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs index f9cdfa4f7d685..88f2cbdea6d7b 100644 --- a/src/test/compile-fail/lint-stability.rs +++ b/src/test/compile-fail/lint-stability.rs @@ -341,7 +341,9 @@ mod this_crate { #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] - pub trait DeprecatedTrait {} + pub trait DeprecatedTrait { + fn dummy(&self) { } + } struct S; diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs index 8cf375f80fbb1..918b4ee209ca7 100644 --- a/src/test/compile-fail/lint-visible-private-types.rs +++ b/src/test/compile-fail/lint-visible-private-types.rs @@ -12,8 +12,10 @@ #![allow(dead_code)] #![crate_type="lib"] -struct Private; -pub struct Public; +use std::marker; + +struct Private(marker::PhantomData); +pub struct Public(marker::PhantomData); impl Private> { pub fn a(&self) -> Private { panic!() } @@ -103,7 +105,7 @@ impl PrivTrait for (Private,) { fn bar(&self) -> Private { panic!() } } -pub trait ParamTrait { +pub trait ParamTrait : marker::MarkerTrait { fn foo() -> T; } diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index a49339ecd7f28..03d8d62e0b4d5 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + fn send(ch: _chan, data: T) { println!("{:?}", ch); println!("{:?}", data); @@ -15,7 +17,7 @@ fn send(ch: _chan, data: T) { } #[derive(Debug)] -struct _chan(isize); +struct _chan(isize, marker::PhantomData); // Tests that "log(debug, message);" is flagged as using // message after the send deinitializes it diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index ba2205f5868d4..6e8719eeaceda 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -14,7 +14,10 @@ extern crate collections; use std::collections::HashMap; -trait Map {} +trait Map +{ + fn get(&self, k: K) -> V { panic!() } +} impl Map for HashMap {} diff --git a/src/test/compile-fail/method-ambig-one-trait-coerce.rs b/src/test/compile-fail/method-ambig-one-trait-coerce.rs deleted file mode 100644 index cb5da4bb54772..0000000000000 --- a/src/test/compile-fail/method-ambig-one-trait-coerce.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that when we pick a trait based on coercion, versus subtyping, -// we consider all possible coercions equivalent and don't try to pick -// a best one. - -trait Object { } - -trait foo { - fn foo(self) -> isize; -} - -impl foo for Box { - fn foo(self) -> isize {1} -} - -impl foo for Box { - fn foo(self) -> isize {2} -} - -fn test1(x: Box) { - // FIXME(#18737) -- we ought to consider this to be ambiguous, - // since we could coerce to either impl. However, what actually - // happens is that we consider both impls applicable because of - // incorrect subtyping relation. We then decide to call this a - // call to the `foo` trait, leading to the following error - // message. - - x.foo(); //~ ERROR `foo` is not implemented -} - -fn test2(x: Box) { - // Not ambiguous because it is a precise match: - x.foo(); -} - -fn test3(x: Box) { - // Not ambiguous because it is a precise match: - x.foo(); -} - -fn main() { } diff --git a/src/test/parse-fail/mod_file_disambig.rs b/src/test/compile-fail/mod_file_disambig.rs similarity index 100% rename from src/test/parse-fail/mod_file_disambig.rs rename to src/test/compile-fail/mod_file_disambig.rs diff --git a/src/test/parse-fail/mod_file_not_owning.rs b/src/test/compile-fail/mod_file_not_owning.rs similarity index 100% rename from src/test/parse-fail/mod_file_not_owning.rs rename to src/test/compile-fail/mod_file_not_owning.rs diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs index cfaf149a49cac..607ab13d12201 100644 --- a/src/test/compile-fail/object-does-not-impl-trait.rs +++ b/src/test/compile-fail/object-does-not-impl-trait.rs @@ -11,8 +11,9 @@ // Test that an object type `Box` is not considered to implement the // trait `Foo`. Issue #5087. +use std::marker::MarkerTrait; -trait Foo {} +trait Foo : MarkerTrait {} fn take_foo(f: F) {} fn take_object(f: Box) { take_foo(f); } //~^ ERROR the trait `Foo` is not implemented diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs index c107c8d131d3a..23ddea4499a72 100644 --- a/src/test/compile-fail/object-lifetime-default-mybox.rs +++ b/src/test/compile-fail/object-lifetime-default-mybox.rs @@ -37,7 +37,6 @@ fn load1<'a,'b>(a: &'a MyBox, a //~^ ERROR cannot infer //~| ERROR mismatched types - //~| ERROR mismatched types } fn main() { diff --git a/src/test/compile-fail/object-safety-issue-22040.rs b/src/test/compile-fail/object-safety-issue-22040.rs new file mode 100644 index 0000000000000..edf32131b6875 --- /dev/null +++ b/src/test/compile-fail/object-safety-issue-22040.rs @@ -0,0 +1,50 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #22040. + +use std::fmt::Debug; + +trait Expr: Debug + PartialEq { + fn print_element_count(&self); +} + +//#[derive(PartialEq)] +#[derive(Debug)] +struct SExpr<'x> { + elements: Vec>, +} + +impl<'x> PartialEq for SExpr<'x> { + fn eq(&self, other:&SExpr<'x>) -> bool { + println!("L1: {} L2: {}", self.elements.len(), other.elements.len()); + let result = self.elements.len() == other.elements.len(); + + println!("Got compare {}", result); + return result; + } +} + +impl <'x> SExpr<'x> { + fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; } +} + +impl <'x> Expr for SExpr<'x> { + fn print_element_count(&self) { + println!("element count: {}", self.elements.len()); + } +} + +fn main() { + let a: Box = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe + let b: Box = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe + + assert_eq!(a , b); +} diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs index 6a010d49692d2..aae829ec7b563 100644 --- a/src/test/compile-fail/object-safety-no-static.rs +++ b/src/test/compile-fail/object-safety-no-static.rs @@ -11,7 +11,7 @@ // Check that we correctly prevent users from making trait objects // from traits with static methods. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { fn foo(); } diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs new file mode 100644 index 0000000000000..1c95ee43d27af --- /dev/null +++ b/src/test/compile-fail/object-safety-phantom-fn.rs @@ -0,0 +1,34 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that `Self` appearing in a phantom fn does not make a trait not object safe. + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +use std::marker::PhantomFn; + +trait Baz : PhantomFn { +} + +trait Bar : PhantomFn<(Self, T)> { +} + +fn make_bar>(t: &T) -> &Bar { + t +} + +fn make_baz(t: &T) -> &Baz { + t +} + +#[rustc_error] +fn main() { //~ ERROR compilation successful +} diff --git a/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs new file mode 100644 index 0000000000000..d3f9dc73020fb --- /dev/null +++ b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs @@ -0,0 +1,32 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return position. + +trait Bar { + fn bar(&self, x: &T); +} + +trait Baz : Bar { +} + +fn make_bar>(t: &T) -> &Bar { + t +} + +fn make_baz(t: &T) -> &Baz { + t + //~^ ERROR `Baz` is not object-safe + //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing +} + +fn main() { +} diff --git a/src/test/compile-fail/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs index dda534cc489b5..7538b1c85e533 100644 --- a/src/test/compile-fail/on-unimplemented-bad-anno.rs +++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs @@ -13,8 +13,12 @@ #![allow(unused)] +use std::marker; + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo{} +trait Foo + : marker::PhantomFn<(Self,Bar,Baz,Quux)> +{} #[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] trait MyFromIterator { @@ -23,15 +27,21 @@ trait MyFromIterator { } #[rustc_on_unimplemented] //~ ERROR this attribute must have a value -trait BadAnnotation1 {} +trait BadAnnotation1 + : marker::MarkerTrait +{} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] //~^ ERROR there is no type parameter C on trait BadAnnotation2 -trait BadAnnotation2 {} +trait BadAnnotation2 + : marker::PhantomFn<(Self,A,B)> +{} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] //~^ only named substitution parameters are allowed -trait BadAnnotation3 {} +trait BadAnnotation3 + : marker::PhantomFn<(Self,A,B)> +{} pub fn main() { } diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs index 7b406afcf1f58..2447d0864226a 100644 --- a/src/test/compile-fail/on-unimplemented.rs +++ b/src/test/compile-fail/on-unimplemented.rs @@ -11,8 +11,12 @@ #![feature(on_unimplemented)] +use std::marker; + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo{} +trait Foo + : marker::PhantomFn<(Self,Bar,Baz,Quux)> +{} fn foobar>() -> T { diff --git a/src/test/compile-fail/orphan-check-diagnostics.rs b/src/test/compile-fail/orphan-check-diagnostics.rs index ff5c101b9178f..8201565c3318d 100644 --- a/src/test/compile-fail/orphan-check-diagnostics.rs +++ b/src/test/compile-fail/orphan-check-diagnostics.rs @@ -15,7 +15,7 @@ extern crate orphan_check_diagnostics; use orphan_check_diagnostics::RemoteTrait; -trait LocalTrait {} +trait LocalTrait { fn dummy(&self) { } } impl RemoteTrait for T where T: LocalTrait {} //~^ ERROR type parameter `T` must be used as the type parameter for some local type diff --git a/src/test/compile-fail/priv-in-bad-locations.rs b/src/test/compile-fail/priv-in-bad-locations.rs index db649ed0cc606..43d112b8aa004 100644 --- a/src/test/compile-fail/priv-in-bad-locations.rs +++ b/src/test/compile-fail/priv-in-bad-locations.rs @@ -14,7 +14,7 @@ pub extern { } trait A { - fn foo() {} + fn foo(&self) {} } struct B; @@ -22,7 +22,7 @@ struct B; pub impl B {} //~ ERROR: unnecessary visibility pub impl A for B { //~ ERROR: unnecessary visibility - pub fn foo() {} //~ ERROR: unnecessary visibility + pub fn foo(&self) {} //~ ERROR: unnecessary visibility } pub fn main() {} diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs index 7fe0574ab7d9a..67bb566ea682c 100644 --- a/src/test/compile-fail/privacy-ns2.rs +++ b/src/test/compile-fail/privacy-ns2.rs @@ -17,7 +17,9 @@ // public type, private value pub mod foo1 { - pub trait Bar { + use std::marker::MarkerTrait; + + pub trait Bar : MarkerTrait { } pub struct Baz; @@ -39,7 +41,7 @@ fn test_list1() { // private type, public value pub mod foo2 { - trait Bar { + trait Bar : ::std::marker::MarkerTrait { } pub struct Baz; @@ -60,7 +62,7 @@ fn test_list2() { // neither public pub mod foo3 { - trait Bar { + trait Bar : ::std::marker::MarkerTrait { } pub struct Baz; diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs index 7ebbcc2809a58..1ae79adbad76a 100644 --- a/src/test/compile-fail/privacy1.rs +++ b/src/test/compile-fail/privacy1.rs @@ -11,11 +11,15 @@ #![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + #[lang="sized"] -pub trait Sized {} +pub trait Sized : PhantomFn {} #[lang="copy"] -pub trait Copy {} +pub trait Copy : PhantomFn {} mod bar { // shouldn't bring in too much diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs index bcb46663aa849..adce93af0794f 100644 --- a/src/test/compile-fail/privacy4.rs +++ b/src/test/compile-fail/privacy4.rs @@ -11,8 +11,12 @@ #![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized {} -#[lang="copy"] pub trait Copy {} +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + +#[lang = "sized"] pub trait Sized : PhantomFn {} +#[lang="copy"] pub trait Copy : PhantomFn {} // Test to make sure that private items imported through globs remain private // when they're used. diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs index 20cc624ab1904..2da414befd897 100644 --- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs +++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs @@ -13,7 +13,7 @@ #![feature(box_syntax)] -trait Foo {} +trait Foo : ::std::marker::MarkerTrait {} impl<'a> Foo for &'a [u8] {} fn a(v: &[u8]) -> Box { diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs index fa26c9c54c8f4..6aa0cc003ce64 100644 --- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs @@ -15,15 +15,12 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; +use std::marker::PhantomFn; /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait { +pub trait TheTrait: PhantomFn { type TheAssocType; - - fn dummy(&self) { } } pub trait TheSubTrait : TheTrait { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs index 7d955065ff455..9736910d7b5fe 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs @@ -14,12 +14,12 @@ #![allow(dead_code)] #![feature(rustc_attrs)] +use std::marker::PhantomFn; + /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait<'b> { +pub trait TheTrait<'b> : PhantomFn<&'b Self,Self> { type TheAssocType; - - fn dummy(&'b self) { } } pub struct TheType<'b> { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs index 6ee65fbdf919b..da7546ce21c60 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs @@ -15,15 +15,12 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; +use std::marker::PhantomFn; /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait { +pub trait TheTrait: PhantomFn { type TheAssocType; - - fn dummy(&self) { } } pub struct TheType<'b> { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs index 49a0726fa3b7b..e1e72e6f56e93 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs @@ -13,16 +13,14 @@ // outlive the location in which the type appears. Issue #22246. #![allow(dead_code)] +#![feature(rustc_attrs)] -use std::mem::transmute; -use std::ops::Deref; +use std::marker::PhantomFn; /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait { +pub trait TheTrait: PhantomFn { type TheAssocType; - - fn dummy(&self) { } } pub struct TheType<'b> { diff --git a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs index f833361e3b505..f921eccef1f8c 100644 --- a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs +++ b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs @@ -11,7 +11,10 @@ // Test that the compiler checks that arbitrary region bounds declared // in the trait must be satisfied on the impl. Issue #20890. -trait Foo<'a> { type Value: 'a; } +trait Foo<'a> { + type Value: 'a; + fn dummy(&'a self) { } +} impl<'a> Foo<'a> for &'a i16 { // OK. diff --git a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs index 0871d8b01f6e4..1cf83b8ac585f 100644 --- a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs +++ b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs @@ -11,7 +11,10 @@ // Test that the compiler checks that the 'static bound declared in // the trait must be satisfied on the impl. Issue #20890. -trait Foo { type Value: 'static; } +trait Foo { + type Value: 'static; + fn dummy(&self) { } +} impl<'a> Foo for &'a i32 { //~^ ERROR cannot infer diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs index a3c38dff6b0f6..278ccd3c11936 100644 --- a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs +++ b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs @@ -21,10 +21,9 @@ pub trait Foo<'a, 't> { fn has_bound<'b:'a>(self, b: Inv<'b>); fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); - fn another_bound<'x: 'a>(self, x: Inv<'x>); + fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); } - impl<'a, 't> Foo<'a, 't> for &'a isize { fn no_bound<'b:'a>(self, b: Inv<'b>) { //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match @@ -51,7 +50,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize { fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) { } - fn another_bound<'x: 't>(self, x: Inv<'x>) {} + fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {} } fn main() { } diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs index 74c2c6e584b43..f13d8a60894cb 100644 --- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs +++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs @@ -8,16 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, no_std)] -#![no_std] - // Check that explicit region bounds are allowed on the various // nominal types (but not on other types) and that they are type // checked. -#[lang="sized"] -trait Sized { } - struct Inv<'a> { // invariant w/r/t 'a x: &'a mut &'a isize } diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs index 8a03f36972dd1..979c1e997d03c 100644 --- a/src/test/compile-fail/regions-close-associated-type-into-object.rs +++ b/src/test/compile-fail/regions-close-associated-type-into-object.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait X {} +use std::marker::MarkerTrait; + +trait X : MarkerTrait {} trait Iter { type Item: X; diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs index 7a0e3cf4611c7..7bbce7dad530d 100644 --- a/src/test/compile-fail/regions-close-object-into-object-1.rs +++ b/src/test/compile-fail/regions-close-object-into-object-1.rs @@ -11,13 +11,16 @@ #![feature(box_syntax)] #![allow(warnings)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> { } struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : ::std::marker::MarkerTrait {} + impl<'a, T> X for B<'a, T> {} -fn f<'a, T, U>(v: Box+'static>) -> Box { +fn f<'a, T:'static, U>(v: Box+'static>) -> Box { box B(&*v) as Box //~ ERROR `*v` does not live long enough } diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs index 7861fb95fef66..6de49020a6fbb 100644 --- a/src/test/compile-fail/regions-close-object-into-object-2.rs +++ b/src/test/compile-fail/regions-close-object-into-object-2.rs @@ -10,10 +10,12 @@ #![feature(box_syntax)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> { } struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : PhantomFn {} impl<'a, T> X for B<'a, T> {} fn g<'a, T: 'static>(v: Box+'a>) -> Box { diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs index 31354de2a27df..e22d0c7d0a4f5 100644 --- a/src/test/compile-fail/regions-close-object-into-object-3.rs +++ b/src/test/compile-fail/regions-close-object-into-object-3.rs @@ -11,10 +11,12 @@ #![feature(box_syntax)] #![allow(warnings)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> {} struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : PhantomFn {} impl<'a, T> X for B<'a, T> {} fn h<'a, T, U>(v: Box+'static>) -> Box { diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs index c60975f97e13d..147a575d38cac 100644 --- a/src/test/compile-fail/regions-close-object-into-object-4.rs +++ b/src/test/compile-fail/regions-close-object-into-object-4.rs @@ -10,10 +10,12 @@ #![feature(box_syntax)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> {} struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : PhantomFn {} impl<'a, T> X for B<'a, T> {} fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs new file mode 100644 index 0000000000000..bdc52eca2cb2d --- /dev/null +++ b/src/test/compile-fail/regions-close-object-into-object-5.rs @@ -0,0 +1,30 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(box_syntax)] +#![allow(warnings)] + +trait A +{ + fn get(&self) -> T { panic!() } +} + +struct B<'a, T>(&'a (A+'a)); + +trait X { fn foo(&self) {} } + +impl<'a, T> X for B<'a, T> {} + +fn f<'a, T, U>(v: Box+'static>) -> Box { + box B(&*v) as Box //~ ERROR the parameter type `T` may not live long enough +} + +fn main() {} + diff --git a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs index 25b8137d29cad..2341d2397c9b0 100644 --- a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs +++ b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait Foo { } +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { } impl<'a> Foo for &'a isize { } diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs index 74b36958c92f1..655ac6f66c97d 100644 --- a/src/test/compile-fail/regions-close-param-into-object.rs +++ b/src/test/compile-fail/regions-close-param-into-object.rs @@ -10,7 +10,7 @@ #![feature(box_syntax)] -trait X {} +trait X { fn foo(&self) {} } fn p1(v: T) -> Box where T : X diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs index 6c5e90a54de2b..b7ef19d1e3bfc 100644 --- a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs +++ b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs @@ -20,7 +20,7 @@ use std::marker; // Contravariant<'foo> <: Contravariant<'static> because // 'foo <= 'static struct Contravariant<'a> { - marker: marker::ContravariantLifetime<'a> + marker: marker::PhantomData<&'a()> } fn use_<'short,'long>(c: Contravariant<'short>, diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs index d8e31fa1374a8..0d3d9dacbd6f6 100644 --- a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs +++ b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs @@ -17,7 +17,7 @@ use std::marker; struct Covariant<'a> { - marker: marker::CovariantLifetime<'a> + marker: marker::PhantomData } fn use_<'short,'long>(c: Covariant<'long>, diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs index e88c96de9e4ea..8c191fbd5bbe7 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs @@ -11,7 +11,7 @@ use std::marker; struct invariant<'a> { - marker: marker::InvariantLifetime<'a> + marker: marker::PhantomData<*mut &'a()> } fn to_same_lifetime<'r>(b_isize: invariant<'r>) { diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs index 7d252604883d6..1b749faf1b8b9 100644 --- a/src/test/compile-fail/required-lang-item.rs +++ b/src/test/compile-fail/required-lang-item.rs @@ -11,7 +11,11 @@ #![feature(lang_items, no_std)] #![no_std] -#[lang="sized"] pub trait Sized {} +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + +#[lang="sized"] pub trait Sized : PhantomFn {} // error-pattern:requires `start` lang_item diff --git a/src/test/compile-fail/shadowed-type-parameter.rs b/src/test/compile-fail/shadowed-type-parameter.rs index 1a3d7821159c3..1f72db1e894fa 100644 --- a/src/test/compile-fail/shadowed-type-parameter.rs +++ b/src/test/compile-fail/shadowed-type-parameter.rs @@ -12,19 +12,21 @@ #![feature(box_syntax)] -struct Foo; +struct Foo(T); impl Foo { fn shadow_in_method(&self) {} //~^ ERROR type parameter `T` shadows another type parameter fn not_shadow_in_item(&self) { - struct Bar; // not a shadow, separate item + struct Bar(T,U); // not a shadow, separate item fn foo() {} // same } } trait Bar { + fn dummy(&self) -> T; + fn shadow_in_required(&self); //~^ ERROR type parameter `T` shadows another type parameter diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs index 23ad5b09950ef..3b992e3bcc321 100644 --- a/src/test/compile-fail/slice-1.rs +++ b/src/test/compile-fail/slice-1.rs @@ -9,14 +9,12 @@ // except according to those terms. // Test slicing &expr[] is deprecated and gives a helpful error message. -// -// ignore-test struct Foo; fn main() { let x = Foo; - &x[]; //~ WARNING deprecated slicing syntax: `[]` - //~^ NOTE use `&expr[..]` to construct a slice of the whole of expr - //~^^ ERROR cannot index a value of type `Foo` + &x[]; + //~^ WARN obsolete syntax + //~| ERROR cannot index } diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs index 1203d62234899..3c1c3796a246f 100644 --- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs +++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo(T); +use std::marker; + +struct Foo(T, marker::PhantomData); fn main() { - match Foo(1.1) { + match Foo(1.1, marker::PhantomData) { 1 => {} //~^ ERROR mismatched types //~| expected `Foo<_, _>` diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs index bf4e46cace304..2dfc9b79ee20a 100644 --- a/src/test/compile-fail/staticness-mismatch.rs +++ b/src/test/compile-fail/staticness-mismatch.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - trait foo { + fn dummy(&self) { } fn bar(); } diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs index a1fcab002e138..fff144140947a 100644 --- a/src/test/compile-fail/trait-as-struct-constructor.rs +++ b/src/test/compile-fail/trait-as-struct-constructor.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait TraitNotAStruct { } +trait TraitNotAStruct : ::std::marker::MarkerTrait { } fn main() { TraitNotAStruct{ value: 0 }; diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs index 79174552ae09c..3129dceffbb66 100644 --- a/src/test/compile-fail/trait-bounds-cant-coerce.rs +++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs @@ -10,6 +10,7 @@ trait Foo { + fn dummy(&self) { } } fn a(_x: Box) { diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs index 477bd4f5be9a1..34e06cc93658a 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs @@ -11,7 +11,10 @@ // Make sure rustc checks the type parameter bounds in implementations of traits, // see #2687 -trait A {} +use std::marker; + +trait A : marker::PhantomFn { +} trait B: A {} @@ -62,15 +65,16 @@ impl Foo for isize { //~^ ERROR the requirement `T : C` appears on the impl } - -trait Getter { } +trait Getter { + fn get(&self) -> T { loop { } } +} trait Trait { - fn method>(); + fn method>(&self); } impl Trait for usize { - fn method>() {} + fn method>(&self) {} //~^ G : Getter` appears on the impl method but not on the corresponding trait method } diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs index 8ad19116e7bb1..284c4fac953f2 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs @@ -14,7 +14,9 @@ trait Iterator { fn next(&mut self) -> Option; } -trait IteratorUtil { +trait IteratorUtil + : ::std::marker::PhantomFn<(),A> +{ fn zip>(self, other: U) -> ZipIterator; } diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs index 434d803d718e7..448b186f6a5c6 100644 --- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs +++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs @@ -9,6 +9,7 @@ // except according to those terms. trait Foo { + fn dummy(&self) { } } // This should emit the less confusing error, not the more confusing one. diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs index 118dfeb37c251..df44e847c50fd 100644 --- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs +++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +trait Trait { + fn dummy(&self) { } +} struct Foo { x: T, diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs index d5369817e9ac1..18871d0d386d7 100644 --- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs +++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +trait Trait { + fn dummy(&self) { } +} struct Foo { x: T, diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs index 490ee0e8ad6f3..8dfdb2f205d6f 100644 --- a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs +++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +use std::marker::MarkerTrait; + +trait Trait : MarkerTrait {} struct Foo { x: T, @@ -51,15 +53,15 @@ enum MoreBadness { EvenMoreBadness(Bar), } -trait PolyTrait { - fn whatever() {} +trait PolyTrait +{ + fn whatever(&self, t: T) {} } struct Struct; impl PolyTrait> for Struct { //~^ ERROR not implemented - fn whatever() {} } fn main() { diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs index 3d264e681a3d2..e4058a0943aad 100644 --- a/src/test/compile-fail/trait-bounds-sugar.rs +++ b/src/test/compile-fail/trait-bounds-sugar.rs @@ -10,8 +10,9 @@ // Tests for "default" bounds inferred for traits with no bounds list. +use std::marker::MarkerTrait; -trait Foo {} +trait Foo : MarkerTrait {} fn a(_x: Box) { } diff --git a/src/test/compile-fail/trait-impl-1.rs b/src/test/compile-fail/trait-impl-1.rs index dadcbd5bce710..2f4793b4d888f 100644 --- a/src/test/compile-fail/trait-impl-1.rs +++ b/src/test/compile-fail/trait-impl-1.rs @@ -12,7 +12,9 @@ // trait impl is only applied to a trait object, not concrete types which implement // the trait. -trait T {} +use std::marker::MarkerTrait; + +trait T : MarkerTrait {} impl<'a> T+'a { fn foo(&self) {} diff --git a/src/test/compile-fail/trait-object-safety.rs b/src/test/compile-fail/trait-object-safety.rs index 761bcd4968abf..d45d13556e121 100644 --- a/src/test/compile-fail/trait-object-safety.rs +++ b/src/test/compile-fail/trait-object-safety.rs @@ -12,6 +12,7 @@ trait Tr { fn foo(); + fn bar(&self) { } } struct St; diff --git a/src/test/compile-fail/trait-static-method-generic-inference.rs b/src/test/compile-fail/trait-static-method-generic-inference.rs index 651f663fc9913..0e357d9d4d531 100644 --- a/src/test/compile-fail/trait-static-method-generic-inference.rs +++ b/src/test/compile-fail/trait-static-method-generic-inference.rs @@ -16,6 +16,7 @@ mod base { pub trait HasNew { fn new() -> T; + fn dummy(&self) { } } pub struct Foo { diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs new file mode 100644 index 0000000000000..8ff514e04e360 --- /dev/null +++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs @@ -0,0 +1,26 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test a default that references `Self` which is then used in an +// object type. Issue #18956. In this case, the value is supplied by +// the user, but pretty-printing the type during the error message +// caused an ICE. + +trait MyAdd { fn add(&self, other: &Rhs) -> Self; } + +impl MyAdd for i32 { + fn add(&self, other: &i32) -> i32 { *self + *other } +} + +fn main() { + let x = 5; + let y = x as MyAdd; + //~^ ERROR as `MyAdd` +} diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs new file mode 100644 index 0000000000000..9982d4850248b --- /dev/null +++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test a default that references `Self` which is then used in an object type. +// Issue #18956. + +#![feature(default_type_params)] + +trait Foo { + fn method(&self); +} + +fn foo(x: &Foo) { } +//~^ ERROR the type parameter `T` must be explicitly specified + +fn main() { } diff --git a/src/test/compile-fail/typeck-negative-impls-builtin.rs b/src/test/compile-fail/typeck-negative-impls-builtin.rs index 9da79b11cf0b7..557fb2f4f8833 100644 --- a/src/test/compile-fail/typeck-negative-impls-builtin.rs +++ b/src/test/compile-fail/typeck-negative-impls-builtin.rs @@ -12,7 +12,9 @@ struct TestType; -trait TestTrait {} +trait TestTrait { + fn dummy(&self) { } +} impl !TestTrait for TestType {} //~^ ERROR negative impls are currently allowed just for `Send` and `Sync` diff --git a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs index a34be63ba6b3c..1daea8f915b3f 100644 --- a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs +++ b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs @@ -11,14 +11,16 @@ // This test checks that genuine type errors with partial // type hints are understandable. -struct Foo; -struct Bar; +use std::marker::PhantomData; + +struct Foo(PhantomData); +struct Bar(PhantomData); pub fn main() { } fn test1() { - let x: Foo<_> = Bar::; + let x: Foo<_> = Bar::(PhantomData); //~^ ERROR mismatched types //~| expected `Foo<_>` //~| found `Bar` @@ -28,7 +30,7 @@ fn test1() { } fn test2() { - let x: Foo<_> = Bar::; + let x: Foo<_> = Bar::(PhantomData); //~^ ERROR mismatched types //~| expected `Foo<_>` //~| found `Bar` diff --git a/src/test/compile-fail/ufcs-qpath-missing-params.rs b/src/test/compile-fail/ufcs-qpath-missing-params.rs index 5fa66eb98e1af..f4e18265fd990 100644 --- a/src/test/compile-fail/ufcs-qpath-missing-params.rs +++ b/src/test/compile-fail/ufcs-qpath-missing-params.rs @@ -12,6 +12,5 @@ use std::borrow::IntoCow; fn main() { ::into_cow("foo".to_string()); - //~^ ERROR wrong number of type arguments: expected 2, found 0 + //~^ ERROR wrong number of type arguments: expected 1, found 0 } - diff --git a/src/test/compile-fail/unboxed-closure-feature-gate.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs index 3536244f01165..74a6f869f63fb 100644 --- a/src/test/compile-fail/unboxed-closure-feature-gate.rs +++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs @@ -11,8 +11,12 @@ // Check that parenthetical notation is feature-gated except with the // `Fn` traits. +use std::marker; + trait Foo { type Output; + + fn dummy(&self, a: A) { } } fn main() { diff --git a/src/test/compile-fail/unboxed-closure-sugar-default.rs b/src/test/compile-fail/unboxed-closure-sugar-default.rs index 870377bc1add7..831db98941c6d 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-default.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-default.rs @@ -19,7 +19,7 @@ trait Foo { fn dummy(&self, t: T, v: V); } -trait Eq { } +trait Eq { fn same_types(&self, x: &X) -> bool { true } } impl Eq for X { } fn eq() where A : Eq { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs index dc5576aee650a..6d315c1b7a996 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs @@ -16,12 +16,14 @@ #![feature(unboxed_closures)] #![allow(dead_code)] +use std::marker::PhantomFn; + trait Foo { type Output; fn dummy(&self, t: T, u: Self::Output); } -trait Eq { } +trait Eq : PhantomFn<(Self,X)> { } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs index d2f781bba11ea..bd3530e6e3026 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs @@ -16,12 +16,14 @@ #![feature(unboxed_closures)] #![allow(dead_code)] +use std::marker; + trait Foo { type Output; fn dummy(&self, t: T); } -trait Eq { } +trait Eq : marker::PhantomFn<(Self, X)> { } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs index 75688e44e8076..057b496bd43eb 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-region.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs @@ -22,7 +22,7 @@ trait Foo<'a,T> { fn dummy(&'a self) -> &'a (T,Self::Output); } -trait Eq { } +trait Eq { fn is_of_eq_type(&self, x: &X) -> bool { true } } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs index 215b2c6798e40..713b64b1349fc 100644 --- a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs +++ b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs @@ -10,7 +10,7 @@ #![feature(core,unboxed_closures)] -use std::marker::CovariantType; +use std::marker::PhantomData; // A erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs` // where we attempt to perform mutation in the recursive function. This fails to compile @@ -18,12 +18,12 @@ use std::marker::CovariantType; struct YCombinator { func: F, - marker: CovariantType<(A,R)>, + marker: PhantomData<(A,R)>, } impl YCombinator { fn new(f: F) -> YCombinator { - YCombinator { func: f, marker: CovariantType } + YCombinator { func: f, marker: PhantomData } } } diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs index e3707292f2495..964db6e9a4546 100644 --- a/src/test/compile-fail/unnecessary-private.rs +++ b/src/test/compile-fail/unnecessary-private.rs @@ -13,10 +13,10 @@ fn main() { pub struct A; //~ ERROR: visibility has no effect pub enum B {} //~ ERROR: visibility has no effect pub trait C { //~ ERROR: visibility has no effect - pub fn foo() {} //~ ERROR: visibility has no effect + pub fn foo(&self) {} //~ ERROR: visibility has no effect } impl A { - pub fn foo() {} //~ ERROR: visibility has no effect + pub fn foo(&self) {} //~ ERROR: visibility has no effect } struct D { diff --git a/src/test/compile-fail/unsized-inherent-impl-self-type.rs b/src/test/compile-fail/unsized-inherent-impl-self-type.rs index 8740346a21750..a03c76b12dd8e 100644 --- a/src/test/compile-fail/unsized-inherent-impl-self-type.rs +++ b/src/test/compile-fail/unsized-inherent-impl-self-type.rs @@ -12,7 +12,7 @@ // impl - struct -struct S5; +struct S5(Y); impl S5 { //~ ERROR not implemented } diff --git a/src/test/compile-fail/unsized-trait-impl-self-type.rs b/src/test/compile-fail/unsized-trait-impl-self-type.rs index 3dd55b0ba7d23..08df1d9b7b8fb 100644 --- a/src/test/compile-fail/unsized-trait-impl-self-type.rs +++ b/src/test/compile-fail/unsized-trait-impl-self-type.rs @@ -12,9 +12,10 @@ // impl - struct trait T3 { + fn foo(&self, z: &Z); } -struct S5; +struct S5(Y); impl T3 for S5 { //~ ERROR not implemented } diff --git a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs index ac8043d6852a9..4723dfeaeb988 100644 --- a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs +++ b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs @@ -12,8 +12,9 @@ // impl - unbounded trait T2 { + fn foo(&self, z: Z); } -struct S4; +struct S4(Box); impl T2 for S4 { //~^ ERROR `core::marker::Sized` is not implemented for the type `X` } diff --git a/src/test/compile-fail/unsized3.rs b/src/test/compile-fail/unsized3.rs index 4fc76c99c60b7..de1cbab82b281 100644 --- a/src/test/compile-fail/unsized3.rs +++ b/src/test/compile-fail/unsized3.rs @@ -10,6 +10,7 @@ // Test sized-ness checking in substitution within fn bodies.. +use std::marker; // Unbounded. fn f1(x: &X) { @@ -20,7 +21,9 @@ fn f2(x: &X) { } // Bounded. -trait T {} +trait T { + fn foo(&self) { } +} fn f3(x: &X) { f4::(x); //~^ ERROR the trait `core::marker::Sized` is not implemented diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs index 217d1f44d8461..f31a6ffdc0d7c 100644 --- a/src/test/compile-fail/unsized6.rs +++ b/src/test/compile-fail/unsized6.rs @@ -10,8 +10,9 @@ // Test `?Sized` local variables. +use std::marker; -trait T {} +trait T : marker::MarkerTrait { } fn f1(x: &X) { let _: X; // <-- this is OK, no bindings created, no initializer. diff --git a/src/test/compile-fail/unsized7.rs b/src/test/compile-fail/unsized7.rs index 6fc547c0b8e86..6ea3d0720eeeb 100644 --- a/src/test/compile-fail/unsized7.rs +++ b/src/test/compile-fail/unsized7.rs @@ -10,13 +10,17 @@ // Test sized-ness checking in substitution in impls. -trait T {} +use std::marker::MarkerTrait; + +trait T : MarkerTrait {} // I would like these to fail eventually. // impl - bounded trait T1 { + fn dummy(&self) -> Z; } -struct S3; + +struct S3(Box); impl T1 for S3 { //~^ ERROR `core::marker::Sized` is not implemented for the type `X` } diff --git a/src/test/compile-fail/unused-attr.rs b/src/test/compile-fail/unused-attr.rs index 2d4bc0c857a9a..af242b96a84a1 100644 --- a/src/test/compile-fail/unused-attr.rs +++ b/src/test/compile-fail/unused-attr.rs @@ -52,9 +52,9 @@ struct Foo { #[foo] //~ ERROR unused attribute trait Baz { #[foo] //~ ERROR unused attribute - fn blah(); + fn blah(&self); #[foo] //~ ERROR unused attribute - fn blah2() {} + fn blah2(&self) {} } fn main() {} diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs index d8531f4543dff..b1120e54434eb 100644 --- a/src/test/compile-fail/useless-priv.rs +++ b/src/test/compile-fail/useless-priv.rs @@ -12,12 +12,14 @@ struct A { pub i: isize } pub enum C { pub Variant } //~ ERROR: unnecessary `pub` pub trait E { - pub fn foo() {} //~ ERROR: unnecessary visibility + pub fn foo(&self) {} //~ ERROR: unnecessary visibility +} +trait F { + pub fn foo(&self) {} //~ ERROR: unnecessary visibility } -trait F { pub fn foo() {} } //~ ERROR: unnecessary visibility impl E for A { - pub fn foo() {} //~ ERROR: unnecessary visibility + pub fn foo(&self) {} //~ ERROR: unnecessary visibility } fn main() {} diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs index 7125a66b294ce..a404d09248f01 100644 --- a/src/test/compile-fail/useless-priv2.rs +++ b/src/test/compile-fail/useless-priv2.rs @@ -9,8 +9,10 @@ // except according to those terms. pub trait E { - pub fn foo(); //~ ERROR: unnecessary visibility + pub fn foo(&self); //~ ERROR: unnecessary visibility +} +trait F { + pub fn foo(&self); //~ ERROR: unnecessary visibility } -trait F { pub fn foo(); } //~ ERROR: unnecessary visibility fn main() {} diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs new file mode 100644 index 0000000000000..3330e1d0d51b0 --- /dev/null +++ b/src/test/compile-fail/variance-contravariant-arg-object.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self, t: T); +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v +} + +fn main() { } diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs new file mode 100644 index 0000000000000..caaad4014adfa --- /dev/null +++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get { + fn get(&self, t: T); +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs new file mode 100644 index 0000000000000..013511ed517a8 --- /dev/null +++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get { + fn get(&self); +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : 'max, &'max G : Get +{ + impls_get::<&'min G>(); //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : 'max, &'min G : Get +{ + impls_get::<&'max G>(); +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs new file mode 100644 index 0000000000000..828c987c08212 --- /dev/null +++ b/src/test/compile-fail/variance-covariant-arg-object.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self) -> T; +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs new file mode 100644 index 0000000000000..17761b9c0b19e --- /dev/null +++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get { + fn get(&self) -> T; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs new file mode 100644 index 0000000000000..4e94a3eeb46e6 --- /dev/null +++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get { + fn get() -> Self; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : 'max, &'max G : Get +{ + impls_get::<&'min G>(); +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : 'max, &'min G : Get +{ + impls_get::<&'max G>(); //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-deprecated-markers.rs b/src/test/compile-fail/variance-deprecated-markers.rs new file mode 100644 index 0000000000000..8f9d24cb132c2 --- /dev/null +++ b/src/test/compile-fail/variance-deprecated-markers.rs @@ -0,0 +1,35 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the deprecated markers still have their old effect. + +#![feature(rustc_attrs)] + +use std::marker; + +#[rustc_variance] +struct A(marker::CovariantType); //~ ERROR types=[[+];[];[]] + +#[rustc_variance] +struct B(marker::ContravariantType); //~ ERROR types=[[-];[];[]] + +#[rustc_variance] +struct C(marker::InvariantType); //~ ERROR types=[[o];[];[]] + +#[rustc_variance] +struct D<'a>(marker::CovariantLifetime<'a>); //~ ERROR regions=[[+];[];[]] + +#[rustc_variance] +struct E<'a>(marker::ContravariantLifetime<'a>); //~ ERROR regions=[[-];[];[]] + +#[rustc_variance] +struct F<'a>(marker::InvariantLifetime<'a>); //~ ERROR regions=[[o];[];[]] + +fn main() { } diff --git a/src/test/compile-fail/variance-invariant-arg-object.rs b/src/test/compile-fail/variance-invariant-arg-object.rs new file mode 100644 index 0000000000000..9edb510b826a1 --- /dev/null +++ b/src/test/compile-fail/variance-invariant-arg-object.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self, t: T) -> T; +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/variance-invariant-arg-trait-match.rs b/src/test/compile-fail/variance-invariant-arg-trait-match.rs new file mode 100644 index 0000000000000..45fed0b083dc1 --- /dev/null +++ b/src/test/compile-fail/variance-invariant-arg-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get { + fn get(&self, t: T) -> T; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-invariant-self-trait-match.rs b/src/test/compile-fail/variance-invariant-self-trait-match.rs new file mode 100644 index 0000000000000..b46cd302ae5ea --- /dev/null +++ b/src/test/compile-fail/variance-invariant-self-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +trait Get { + fn get(&self) -> Self; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, &'max G : Get +{ + impls_get::<&'min G>(); //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, &'min G : Get +{ + impls_get::<&'max G>(); //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-issue-20533.rs b/src/test/compile-fail/variance-issue-20533.rs new file mode 100644 index 0000000000000..0254f56bd1a94 --- /dev/null +++ b/src/test/compile-fail/variance-issue-20533.rs @@ -0,0 +1,54 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #20533. At some point, only 1 out of the +// 3 errors below were being reported. + +use std::marker::PhantomData; + +fn foo<'a, T>(_x: &'a T) -> PhantomData<&'a ()> { + PhantomData +} + +struct Wrap(T); + +fn bar<'a, T>(_x: &'a T) -> Wrap> { + Wrap(PhantomData) +} + +struct Baked<'a>(PhantomData<&'a ()>); + +fn baz<'a, T>(_x: &'a T) -> Baked<'a> { + Baked(PhantomData) +} + +struct AffineU32(u32); + +fn main() { + { + let a = AffineU32(1_u32); + let x = foo(&a); + drop(a); //~ ERROR cannot move out of `a` + drop(x); + } + { + let a = AffineU32(1_u32); + let x = bar(&a); + drop(a); //~ ERROR cannot move out of `a` + drop(x); + } + { + let a = AffineU32(1_u32); + let x = baz(&a); + drop(a); //~ ERROR cannot move out of `a` + drop(x); + } +} + diff --git a/src/test/compile-fail/variance-regions-direct.rs b/src/test/compile-fail/variance-regions-direct.rs index d70305d1106ec..da4d6c75227fc 100644 --- a/src/test/compile-fail/variance-regions-direct.rs +++ b/src/test/compile-fail/variance-regions-direct.rs @@ -60,6 +60,7 @@ struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]] #[rustc_variance] struct Test7<'a> { //~ ERROR regions=[[*];[];[]] + //~^ ERROR parameter `'a` is never used x: isize } diff --git a/src/test/compile-fail/variance-regions-indirect.rs b/src/test/compile-fail/variance-regions-indirect.rs index 4bb329d6304cf..9beb90d0b2483 100644 --- a/src/test/compile-fail/variance-regions-indirect.rs +++ b/src/test/compile-fail/variance-regions-indirect.rs @@ -16,6 +16,7 @@ #[rustc_variance] enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]] + //~^ ERROR parameter `'d` is never used Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), Test8C(&'b mut &'c str), @@ -23,16 +24,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]] #[rustc_variance] struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]] + //~^ ERROR parameter `'w` is never used f: Base<'z, 'y, 'x, 'w> } #[rustc_variance] // Combine - and + to yield o struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]] + //~^ ERROR parameter `'c` is never used f: Base<'a, 'a, 'b, 'c> } #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]] + //~^ ERROR parameter `'c` is never used f: Base<'a, 'b, 'a, 'c> } diff --git a/src/test/run-pass/regions-infer-bivariance.rs b/src/test/compile-fail/variance-regions-unused-direct.rs similarity index 55% rename from src/test/run-pass/regions-infer-bivariance.rs rename to src/test/compile-fail/variance-regions-unused-direct.rs index a3288e2e1b90b..396e77652067d 100644 --- a/src/test/run-pass/regions-infer-bivariance.rs +++ b/src/test/compile-fail/variance-regions-unused-direct.rs @@ -8,21 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that a type whose lifetime parameters is never used is -// inferred to be bivariant. +// Test that disallow lifetime parameters that are unused. use std::marker; -struct Bivariant<'a>; +struct Bivariant<'a>; //~ ERROR parameter `'a` is never used -fn use1<'short,'long>(c: Bivariant<'short>, - _where:Option<&'short &'long ()>) { - let _: Bivariant<'long> = c; +struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used + field: &'a [i32] } -fn use2<'short,'long>(c: Bivariant<'long>, - _where:Option<&'short &'long ()>) { - let _: Bivariant<'short> = c; +trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used + fn method(&'a self); } -pub fn main() {} +fn main() {} diff --git a/src/test/run-pass/export-non-interference.rs b/src/test/compile-fail/variance-regions-unused-indirect.rs similarity index 67% rename from src/test/run-pass/export-non-interference.rs rename to src/test/compile-fail/variance-regions-unused-indirect.rs index 94652e30fe64f..2d234ed7b5781 100644 --- a/src/test/run-pass/export-non-interference.rs +++ b/src/test/compile-fail/variance-regions-unused-indirect.rs @@ -8,7 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Test that disallow lifetime parameters that are unused. -enum list_cell { cons(Box>), nil } +enum Foo<'a> { //~ ERROR parameter `'a` is never used + Foo1(Bar<'a>) +} -pub fn main() { } +enum Bar<'a> { //~ ERROR parameter `'a` is never used + Bar1(Foo<'a>) +} + +fn main() {} diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs new file mode 100644 index 0000000000000..88b50058b6580 --- /dev/null +++ b/src/test/compile-fail/variance-trait-bounds.rs @@ -0,0 +1,65 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(bivariance)] +#![allow(dead_code)] +#![feature(rustc_attrs)] + +// Check that bounds on type parameters (other than `Self`) do not +// influence variance. + +#[rustc_variance] +trait Getter { //~ ERROR types=[[+];[-];[]] + fn get(&self) -> T; +} + +#[rustc_variance] +trait Setter { //~ ERROR types=[[-];[-];[]] + fn get(&self, T); +} + +#[rustc_variance] +struct TestStruct> { //~ ERROR types=[[+, +];[];[]] + t: T, u: U +} + +#[rustc_variance] +enum TestEnum> {//~ ERROR types=[[*, +];[];[]] + //~^ ERROR parameter `U` is never used + Foo(T) +} + +#[rustc_variance] +trait TestTrait> { //~ ERROR types=[[-, +];[-];[]] + fn getter(&self, u: U) -> T; +} + +#[rustc_variance] +trait TestTrait2 : Getter { //~ ERROR types=[[+];[-];[]] +} + +#[rustc_variance] +trait TestTrait3 { //~ ERROR types=[[-];[-];[]] + fn getter>(&self); +} + +#[rustc_variance] +struct TestContraStruct> { //~ ERROR types=[[*, +];[];[]] + //~^ ERROR parameter `U` is never used + t: T +} + +#[rustc_variance] +struct TestBox+Setter> { //~ ERROR types=[[*, +];[];[]] + //~^ ERROR parameter `U` is never used + t: T +} + +pub fn main() { } diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs index 965b9430a5e2d..f0ca1edd56387 100644 --- a/src/test/compile-fail/variance-trait-object-bound.rs +++ b/src/test/compile-fail/variance-trait-object-bound.rs @@ -18,7 +18,7 @@ use std::mem; -trait T { fn foo(); } +trait T { fn foo(&self); } #[rustc_variance] struct TOption<'a> { //~ ERROR regions=[[-];[];[]] diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs new file mode 100644 index 0000000000000..d53e4cd76105b --- /dev/null +++ b/src/test/compile-fail/variance-types-bounds.rs @@ -0,0 +1,76 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we correctly infer variance for type parameters in +// various types and traits. + +#![feature(rustc_attrs)] + +#[rustc_variance] +struct TestImm { //~ ERROR types=[[+, +];[];[]] + x: A, + y: B, +} + +#[rustc_variance] +struct TestMut { //~ ERROR types=[[+, o];[];[]] + x: A, + y: &'static mut B, +} + +#[rustc_variance] +struct TestIndirect { //~ ERROR types=[[+, o];[];[]] + m: TestMut +} + +#[rustc_variance] +struct TestIndirect2 { //~ ERROR types=[[o, o];[];[]] + n: TestMut, + m: TestMut +} + +#[rustc_variance] +trait Getter { //~ ERROR types=[[+];[-];[]] + fn get(&self) -> A; +} + +#[rustc_variance] +trait Setter { //~ ERROR types=[[-];[o];[]] + fn set(&mut self, a: A); +} + +#[rustc_variance] +trait GetterSetter { //~ ERROR types=[[o];[o];[]] + fn get(&self) -> A; + fn set(&mut self, a: A); +} + +#[rustc_variance] +trait GetterInTypeBound { //~ ERROR types=[[-];[-];[]] + // Here, the use of `A` in the method bound *does* affect + // variance. Think of it as if the method requested a dictionary + // for `T:Getter`. Since this dictionary is an input, it is + // contravariant, and the Getter is covariant w/r/t A, yielding an + // overall contravariant result. + fn do_it>(&self); +} + +#[rustc_variance] +trait SetterInTypeBound { //~ ERROR types=[[+];[-];[]] + fn do_it>(&self); +} + +#[rustc_variance] +struct TestObject { //~ ERROR types=[[-, +];[];[]] + n: Box+Send>, + m: Box+Send>, +} + +fn main() {} diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs new file mode 100644 index 0000000000000..e407ebe345a5b --- /dev/null +++ b/src/test/compile-fail/variance-types.rs @@ -0,0 +1,52 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(bivariance)] +#![allow(dead_code)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Check that a type parameter which is only used in a trait bound is +// not considered bivariant. + +#[rustc_variance] +struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[];[]], regions=[[-];[];[]] + t: &'a mut (A,B) +} + +#[rustc_variance] +struct InvariantCell { //~ ERROR types=[[o];[];[]] + t: Cell +} + +#[rustc_variance] +struct InvariantIndirect { //~ ERROR types=[[o];[];[]] + t: InvariantCell +} + +#[rustc_variance] +struct Covariant { //~ ERROR types=[[+];[];[]] + t: A, u: fn() -> A +} + +#[rustc_variance] +struct Contravariant { //~ ERROR types=[[-];[];[]] + t: fn(A) +} + +#[rustc_variance] +enum Enum { //~ ERROR types=[[+, -, o];[];[]] + Foo(Covariant), + Bar(Contravariant), + Zed(Covariant,Contravariant) +} + +pub fn main() { } diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs new file mode 100644 index 0000000000000..5f504226370a4 --- /dev/null +++ b/src/test/compile-fail/variance-unused-region-param.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we report an error for unused type parameters in types. + +struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used +enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used +trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used + +fn main() {} diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs new file mode 100644 index 0000000000000..2e867ec3c9384 --- /dev/null +++ b/src/test/compile-fail/variance-unused-type-param.rs @@ -0,0 +1,36 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +// Test that we report an error for unused type parameters in types and traits, +// and that we offer a helpful suggestion. + +struct SomeStruct { x: u32 } +//~^ ERROR parameter `A` is never used +//~| HELP PhantomData + +enum SomeEnum { Nothing } +//~^ ERROR parameter `A` is never used +//~| HELP PhantomData + +trait SomeTrait { fn foo(&self); } +//~^ ERROR parameter `A` is never used +//~| HELP PhantomFn + +// Here T might *appear* used, but in fact it isn't. +enum ListCell { +//~^ ERROR parameter `T` is never used +//~| HELP PhantomData + Cons(Box>), + Nil +} + +fn main() {} diff --git a/src/test/compile-fail/variance-use-contravariant-struct-1.rs b/src/test/compile-fail/variance-use-contravariant-struct-1.rs new file mode 100644 index 0000000000000..d2fd2978750e7 --- /dev/null +++ b/src/test/compile-fail/variance-use-contravariant-struct-1.rs @@ -0,0 +1,26 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +#![feature(rustc_attrs)] + +struct SomeStruct(fn(T)); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +#[rustc_error] +fn main() { } diff --git a/src/test/compile-fail/variance-use-contravariant-struct-2.rs b/src/test/compile-fail/variance-use-contravariant-struct-2.rs new file mode 100644 index 0000000000000..b38fd0e9ffcc6 --- /dev/null +++ b/src/test/compile-fail/variance-use-contravariant-struct-2.rs @@ -0,0 +1,27 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +#![allow(dead_code)] +#![feature(rustc_attrs)] + +struct SomeStruct(fn(T)); + +fn bar<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v +} + +#[rustc_error] +fn main() { } //~ ERROR compilation successful diff --git a/src/test/compile-fail/variance-use-covariant-struct-1.rs b/src/test/compile-fail/variance-use-covariant-struct-1.rs new file mode 100644 index 0000000000000..2631cfc05e81d --- /dev/null +++ b/src/test/compile-fail/variance-use-covariant-struct-1.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that a covariant struct does not permit the lifetime of a +// reference to be enlarged. + +struct SomeStruct(T); + +fn foo<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/variance-use-covariant-struct-2.rs b/src/test/compile-fail/variance-use-covariant-struct-2.rs new file mode 100644 index 0000000000000..d8e1a5f5f1c54 --- /dev/null +++ b/src/test/compile-fail/variance-use-covariant-struct-2.rs @@ -0,0 +1,26 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that a covariant struct permits the lifetime of a reference to +// be shortened. + +#![allow(dead_code)] +#![feature(rustc_attrs)] + +struct SomeStruct(T); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v +} + +#[rustc_error] fn main() { } //~ ERROR compilation successful diff --git a/src/test/compile-fail/variance-use-invariant-struct-1.rs b/src/test/compile-fail/variance-use-invariant-struct-1.rs new file mode 100644 index 0000000000000..c89436b20949c --- /dev/null +++ b/src/test/compile-fail/variance-use-invariant-struct-1.rs @@ -0,0 +1,33 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +#![feature(rustc_attrs)] + +struct SomeStruct(*mut T); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn bar<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +#[rustc_error] +fn main() { } diff --git a/src/test/compile-fail/visible-private-types-generics.rs b/src/test/compile-fail/visible-private-types-generics.rs index 7ff18f8e0886c..1f2205b5c7198 100644 --- a/src/test/compile-fail/visible-private-types-generics.rs +++ b/src/test/compile-fail/visible-private-types-generics.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self) { } +} pub fn f< T diff --git a/src/test/compile-fail/visible-private-types-supertrait.rs b/src/test/compile-fail/visible-private-types-supertrait.rs index dc6d446154ac7..9d9eae4a0759b 100644 --- a/src/test/compile-fail/visible-private-types-supertrait.rs +++ b/src/test/compile-fail/visible-private-types-supertrait.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self) { } +} pub trait Bar : Foo {} //~ ERROR private trait in exported type diff --git a/src/test/compile-fail/where-clause-method-substituion.rs b/src/test/compile-fail/where-clause-method-substituion.rs index a5108f005dc0e..bf614e6eb512b 100644 --- a/src/test/compile-fail/where-clause-method-substituion.rs +++ b/src/test/compile-fail/where-clause-method-substituion.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self, t: T) { } +} trait Bar { fn method(&self) where A: Foo; diff --git a/src/test/compile-fail/where-clauses-not-parameter.rs b/src/test/compile-fail/where-clauses-not-parameter.rs index 313ae273c07fe..7968cc37090ac 100644 --- a/src/test/compile-fail/where-clauses-not-parameter.rs +++ b/src/test/compile-fail/where-clauses-not-parameter.rs @@ -21,7 +21,7 @@ fn test2() -> bool where Option : Eq {} #[derive(PartialEq)] //~^ ERROR cannot bound type `isize`, where clause bounds -enum Foo where isize : Eq { MkFoo } +enum Foo where isize : Eq { MkFoo(T) } //~^ ERROR cannot bound type `isize`, where clause bounds fn test3() -> bool where Option> : Eq {} @@ -31,7 +31,7 @@ fn test4() -> bool where Option> : Eq {} trait Baz where isize : Eq { //~^ ERROR cannot bound type `isize`, where clause bounds may only - fn baz() where String : Eq; //~ ERROR cannot bound type `collections::string::String` + fn baz(&self, t: T) where String : Eq; //~ ERROR cannot bound type `collections::string::String` //~^ ERROR cannot bound type `isize`, where clause } diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index a592484f1a4c6..bf26fc23d3c16 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -177,10 +177,11 @@ #![omit_gdb_pretty_printer_section] use self::Enum1::{Variant1_1, Variant1_2}; +use std::marker::PhantomData; use std::ptr; struct Struct1; -struct GenericStruct; +struct GenericStruct(PhantomData<(T1,T2)>); enum Enum1 { Variant1_1, @@ -207,8 +208,8 @@ mod Mod1 { } } -trait Trait1 { } -trait Trait2 { } +trait Trait1 { fn dummy(&self) { } } +trait Trait2 { fn dummy(&self, _: T1, _:T2) { } } impl Trait1 for isize {} impl Trait2 for isize {} @@ -240,8 +241,10 @@ fn main() { // Structs let simple_struct = Struct1; - let generic_struct1: GenericStruct = GenericStruct; - let generic_struct2: GenericStruct usize> = GenericStruct; + let generic_struct1: GenericStruct = + GenericStruct(PhantomData); + let generic_struct2: GenericStruct usize> = + GenericStruct(PhantomData); let mod_struct = Mod1::Struct2; // Enums @@ -262,10 +265,10 @@ fn main() { // References let ref1 = (&Struct1, 0i32); - let ref2 = (&GenericStruct::, 0i32); + let ref2 = (&GenericStruct::(PhantomData), 0i32); let mut mut_struct1 = Struct1; - let mut mut_generic_struct = GenericStruct::; + let mut mut_generic_struct = GenericStruct::(PhantomData); let mut_ref1 = (&mut mut_struct1, 0i32); let mut_ref2 = (&mut mut_generic_struct, 0i32); diff --git a/src/test/compile-fail/ascii-only-character-escape.rs b/src/test/parse-fail/ascii-only-character-escape.rs similarity index 100% rename from src/test/compile-fail/ascii-only-character-escape.rs rename to src/test/parse-fail/ascii-only-character-escape.rs diff --git a/src/test/compile-fail/attr-before-eof.rs b/src/test/parse-fail/attr-before-eof.rs similarity index 100% rename from src/test/compile-fail/attr-before-eof.rs rename to src/test/parse-fail/attr-before-eof.rs diff --git a/src/test/compile-fail/attr-before-ext.rs b/src/test/parse-fail/attr-before-ext.rs similarity index 100% rename from src/test/compile-fail/attr-before-ext.rs rename to src/test/parse-fail/attr-before-ext.rs diff --git a/src/test/compile-fail/attr-before-let.rs b/src/test/parse-fail/attr-before-let.rs similarity index 100% rename from src/test/compile-fail/attr-before-let.rs rename to src/test/parse-fail/attr-before-let.rs diff --git a/src/test/compile-fail/attr-before-stmt.rs b/src/test/parse-fail/attr-before-stmt.rs similarity index 100% rename from src/test/compile-fail/attr-before-stmt.rs rename to src/test/parse-fail/attr-before-stmt.rs diff --git a/src/test/compile-fail/attr-dangling-in-fn.rs b/src/test/parse-fail/attr-dangling-in-fn.rs similarity index 100% rename from src/test/compile-fail/attr-dangling-in-fn.rs rename to src/test/parse-fail/attr-dangling-in-fn.rs diff --git a/src/test/compile-fail/attr-dangling-in-mod.rs b/src/test/parse-fail/attr-dangling-in-mod.rs similarity index 100% rename from src/test/compile-fail/attr-dangling-in-mod.rs rename to src/test/parse-fail/attr-dangling-in-mod.rs diff --git a/src/test/compile-fail/attr.rs b/src/test/parse-fail/attr.rs similarity index 100% rename from src/test/compile-fail/attr.rs rename to src/test/parse-fail/attr.rs diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/parse-fail/attrs-after-extern-mod.rs similarity index 100% rename from src/test/compile-fail/attrs-after-extern-mod.rs rename to src/test/parse-fail/attrs-after-extern-mod.rs diff --git a/src/test/compile-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs similarity index 100% rename from src/test/compile-fail/bad-char-literals.rs rename to src/test/parse-fail/bad-char-literals.rs diff --git a/src/test/compile-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs similarity index 100% rename from src/test/compile-fail/bad-lit-suffixes.rs rename to src/test/parse-fail/bad-lit-suffixes.rs diff --git a/src/test/compile-fail/bad-value-ident-false.rs b/src/test/parse-fail/bad-value-ident-false.rs similarity index 100% rename from src/test/compile-fail/bad-value-ident-false.rs rename to src/test/parse-fail/bad-value-ident-false.rs diff --git a/src/test/compile-fail/bad-value-ident-true.rs b/src/test/parse-fail/bad-value-ident-true.rs similarity index 100% rename from src/test/compile-fail/bad-value-ident-true.rs rename to src/test/parse-fail/bad-value-ident-true.rs diff --git a/src/test/compile-fail/doc-before-attr.rs b/src/test/parse-fail/doc-before-attr.rs similarity index 100% rename from src/test/compile-fail/doc-before-attr.rs rename to src/test/parse-fail/doc-before-attr.rs diff --git a/src/test/compile-fail/doc-before-eof.rs b/src/test/parse-fail/doc-before-eof.rs similarity index 100% rename from src/test/compile-fail/doc-before-eof.rs rename to src/test/parse-fail/doc-before-eof.rs diff --git a/src/test/compile-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs similarity index 100% rename from src/test/compile-fail/doc-before-extern-rbrace.rs rename to src/test/parse-fail/doc-before-extern-rbrace.rs diff --git a/src/test/compile-fail/doc-before-macro.rs b/src/test/parse-fail/doc-before-macro.rs similarity index 100% rename from src/test/compile-fail/doc-before-macro.rs rename to src/test/parse-fail/doc-before-macro.rs diff --git a/src/test/compile-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs similarity index 100% rename from src/test/compile-fail/doc-before-rbrace.rs rename to src/test/parse-fail/doc-before-rbrace.rs diff --git a/src/test/compile-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs similarity index 100% rename from src/test/compile-fail/doc-before-semi.rs rename to src/test/parse-fail/doc-before-semi.rs diff --git a/src/test/compile-fail/extern-crate-as-no-string-help.rs b/src/test/parse-fail/extern-crate-as-no-string-help.rs similarity index 100% rename from src/test/compile-fail/extern-crate-as-no-string-help.rs rename to src/test/parse-fail/extern-crate-as-no-string-help.rs diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/generic-non-trailing-defaults.rs similarity index 100% rename from src/test/compile-fail/generic-non-trailing-defaults.rs rename to src/test/parse-fail/generic-non-trailing-defaults.rs diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/parse-fail/int-literal-too-large-span.rs similarity index 100% rename from src/test/compile-fail/int-literal-too-large-span.rs rename to src/test/parse-fail/int-literal-too-large-span.rs diff --git a/src/test/compile-fail/issue-10412.rs b/src/test/parse-fail/issue-10412.rs similarity index 100% rename from src/test/compile-fail/issue-10412.rs rename to src/test/parse-fail/issue-10412.rs diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/parse-fail/issue-12560-1.rs similarity index 100% rename from src/test/compile-fail/issue-12560-1.rs rename to src/test/parse-fail/issue-12560-1.rs diff --git a/src/test/compile-fail/issue-14182.rs b/src/test/parse-fail/issue-14182.rs similarity index 100% rename from src/test/compile-fail/issue-14182.rs rename to src/test/parse-fail/issue-14182.rs diff --git a/src/test/compile-fail/issue-17383.rs b/src/test/parse-fail/issue-17383.rs similarity index 100% rename from src/test/compile-fail/issue-17383.rs rename to src/test/parse-fail/issue-17383.rs diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/parse-fail/issue-17718-const-mut.rs similarity index 100% rename from src/test/compile-fail/issue-17718-const-mut.rs rename to src/test/parse-fail/issue-17718-const-mut.rs diff --git a/src/test/compile-fail/issue-1802-2.rs b/src/test/parse-fail/issue-1802-2.rs similarity index 100% rename from src/test/compile-fail/issue-1802-2.rs rename to src/test/parse-fail/issue-1802-2.rs diff --git a/src/test/compile-fail/issue-5544-a.rs b/src/test/parse-fail/issue-5544-a.rs similarity index 100% rename from src/test/compile-fail/issue-5544-a.rs rename to src/test/parse-fail/issue-5544-a.rs diff --git a/src/test/compile-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs similarity index 100% rename from src/test/compile-fail/issue-5544-b.rs rename to src/test/parse-fail/issue-5544-b.rs diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs similarity index 100% rename from src/test/compile-fail/issue-8537.rs rename to src/test/parse-fail/issue-8537.rs diff --git a/src/test/compile-fail/keyword-as-as-identifier.rs b/src/test/parse-fail/keyword-as-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-as-as-identifier.rs rename to src/test/parse-fail/keyword-as-as-identifier.rs diff --git a/src/test/compile-fail/keyword-break-as-identifier.rs b/src/test/parse-fail/keyword-break-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-break-as-identifier.rs rename to src/test/parse-fail/keyword-break-as-identifier.rs diff --git a/src/test/compile-fail/keyword-else-as-identifier.rs b/src/test/parse-fail/keyword-else-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-else-as-identifier.rs rename to src/test/parse-fail/keyword-else-as-identifier.rs diff --git a/src/test/compile-fail/keyword-enum-as-identifier.rs b/src/test/parse-fail/keyword-enum-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-enum-as-identifier.rs rename to src/test/parse-fail/keyword-enum-as-identifier.rs diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-extern-as-identifier.rs rename to src/test/parse-fail/keyword-extern-as-identifier.rs diff --git a/src/test/compile-fail/keyword-fn-as-identifier.rs b/src/test/parse-fail/keyword-fn-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-fn-as-identifier.rs rename to src/test/parse-fail/keyword-fn-as-identifier.rs diff --git a/src/test/compile-fail/keyword-for-as-identifier.rs b/src/test/parse-fail/keyword-for-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-for-as-identifier.rs rename to src/test/parse-fail/keyword-for-as-identifier.rs diff --git a/src/test/compile-fail/keyword-if-as-identifier.rs b/src/test/parse-fail/keyword-if-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-if-as-identifier.rs rename to src/test/parse-fail/keyword-if-as-identifier.rs diff --git a/src/test/compile-fail/keyword-impl-as-identifier.rs b/src/test/parse-fail/keyword-impl-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-impl-as-identifier.rs rename to src/test/parse-fail/keyword-impl-as-identifier.rs diff --git a/src/test/compile-fail/keyword-let-as-identifier.rs b/src/test/parse-fail/keyword-let-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-let-as-identifier.rs rename to src/test/parse-fail/keyword-let-as-identifier.rs diff --git a/src/test/compile-fail/keyword-loop-as-identifier.rs b/src/test/parse-fail/keyword-loop-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-loop-as-identifier.rs rename to src/test/parse-fail/keyword-loop-as-identifier.rs diff --git a/src/test/compile-fail/keyword-match-as-identifier.rs b/src/test/parse-fail/keyword-match-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-match-as-identifier.rs rename to src/test/parse-fail/keyword-match-as-identifier.rs diff --git a/src/test/compile-fail/keyword-mod-as-identifier.rs b/src/test/parse-fail/keyword-mod-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-mod-as-identifier.rs rename to src/test/parse-fail/keyword-mod-as-identifier.rs diff --git a/src/test/compile-fail/keyword-pub-as-identifier.rs b/src/test/parse-fail/keyword-pub-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-pub-as-identifier.rs rename to src/test/parse-fail/keyword-pub-as-identifier.rs diff --git a/src/test/compile-fail/keyword-return-as-identifier.rs b/src/test/parse-fail/keyword-return-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-return-as-identifier.rs rename to src/test/parse-fail/keyword-return-as-identifier.rs diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/parse-fail/keyword-self-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-self-as-identifier.rs rename to src/test/parse-fail/keyword-self-as-identifier.rs diff --git a/src/test/compile-fail/keyword-static-as-identifier.rs b/src/test/parse-fail/keyword-static-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-static-as-identifier.rs rename to src/test/parse-fail/keyword-static-as-identifier.rs diff --git a/src/test/compile-fail/keyword-struct-as-identifier.rs b/src/test/parse-fail/keyword-struct-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-struct-as-identifier.rs rename to src/test/parse-fail/keyword-struct-as-identifier.rs diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/parse-fail/keyword-super-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-super-as-identifier.rs rename to src/test/parse-fail/keyword-super-as-identifier.rs diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/parse-fail/keyword-super.rs similarity index 100% rename from src/test/compile-fail/keyword-super.rs rename to src/test/parse-fail/keyword-super.rs diff --git a/src/test/compile-fail/keyword-trait-as-identifier.rs b/src/test/parse-fail/keyword-trait-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-trait-as-identifier.rs rename to src/test/parse-fail/keyword-trait-as-identifier.rs diff --git a/src/test/compile-fail/keyword-type-as-identifier.rs b/src/test/parse-fail/keyword-type-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-type-as-identifier.rs rename to src/test/parse-fail/keyword-type-as-identifier.rs diff --git a/src/test/compile-fail/keyword-unsafe-as-identifier.rs b/src/test/parse-fail/keyword-unsafe-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-unsafe-as-identifier.rs rename to src/test/parse-fail/keyword-unsafe-as-identifier.rs diff --git a/src/test/compile-fail/keyword-use-as-identifier.rs b/src/test/parse-fail/keyword-use-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-use-as-identifier.rs rename to src/test/parse-fail/keyword-use-as-identifier.rs diff --git a/src/test/compile-fail/keyword-while-as-identifier.rs b/src/test/parse-fail/keyword-while-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-while-as-identifier.rs rename to src/test/parse-fail/keyword-while-as-identifier.rs diff --git a/src/test/compile-fail/keyword.rs b/src/test/parse-fail/keyword.rs similarity index 100% rename from src/test/compile-fail/keyword.rs rename to src/test/parse-fail/keyword.rs diff --git a/src/test/compile-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs similarity index 100% rename from src/test/compile-fail/keywords-followed-by-double-colon.rs rename to src/test/parse-fail/keywords-followed-by-double-colon.rs diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs similarity index 100% rename from src/test/compile-fail/lex-bad-numeric-literals.rs rename to src/test/parse-fail/lex-bad-numeric-literals.rs diff --git a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs similarity index 100% rename from src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs rename to src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs diff --git a/src/test/compile-fail/lifetime-no-keyword.rs b/src/test/parse-fail/lifetime-no-keyword.rs similarity index 100% rename from src/test/compile-fail/lifetime-no-keyword.rs rename to src/test/parse-fail/lifetime-no-keyword.rs diff --git a/src/test/compile-fail/lifetime-obsoleted-self.rs b/src/test/parse-fail/lifetime-obsoleted-self.rs similarity index 100% rename from src/test/compile-fail/lifetime-obsoleted-self.rs rename to src/test/parse-fail/lifetime-obsoleted-self.rs diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/parse-fail/macros-no-semicolon-items.rs similarity index 100% rename from src/test/compile-fail/macros-no-semicolon-items.rs rename to src/test/parse-fail/macros-no-semicolon-items.rs diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/parse-fail/no-binary-float-literal.rs similarity index 100% rename from src/test/compile-fail/no-binary-float-literal.rs rename to src/test/parse-fail/no-binary-float-literal.rs diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/parse-fail/no-hex-float-literal.rs similarity index 100% rename from src/test/compile-fail/no-hex-float-literal.rs rename to src/test/parse-fail/no-hex-float-literal.rs diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/parse-fail/no-unsafe-self.rs similarity index 100% rename from src/test/compile-fail/no-unsafe-self.rs rename to src/test/parse-fail/no-unsafe-self.rs diff --git a/src/test/compile-fail/non-str-meta.rs b/src/test/parse-fail/non-str-meta.rs similarity index 100% rename from src/test/compile-fail/non-str-meta.rs rename to src/test/parse-fail/non-str-meta.rs diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs similarity index 100% rename from src/test/compile-fail/obsolete-for-sized.rs rename to src/test/parse-fail/obsolete-for-sized.rs diff --git a/src/test/compile-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs similarity index 100% rename from src/test/compile-fail/obsolete-proc.rs rename to src/test/parse-fail/obsolete-proc.rs diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs similarity index 100% rename from src/test/compile-fail/qquote-1.rs rename to src/test/parse-fail/qquote-1.rs diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs similarity index 100% rename from src/test/compile-fail/qquote-2.rs rename to src/test/parse-fail/qquote-2.rs diff --git a/src/test/compile-fail/regions-fn-bound.rs b/src/test/parse-fail/regions-fn-bound.rs similarity index 100% rename from src/test/compile-fail/regions-fn-bound.rs rename to src/test/parse-fail/regions-fn-bound.rs diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs similarity index 100% rename from src/test/compile-fail/require-parens-for-chained-comparison.rs rename to src/test/parse-fail/require-parens-for-chained-comparison.rs diff --git a/src/test/compile-fail/struct-no-fields-2.rs b/src/test/parse-fail/struct-no-fields-2.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-2.rs rename to src/test/parse-fail/struct-no-fields-2.rs diff --git a/src/test/compile-fail/struct-no-fields-3.rs b/src/test/parse-fail/struct-no-fields-3.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-3.rs rename to src/test/parse-fail/struct-no-fields-3.rs diff --git a/src/test/compile-fail/struct-no-fields-4.rs b/src/test/parse-fail/struct-no-fields-4.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-4.rs rename to src/test/parse-fail/struct-no-fields-4.rs diff --git a/src/test/compile-fail/struct-no-fields-5.rs b/src/test/parse-fail/struct-no-fields-5.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-5.rs rename to src/test/parse-fail/struct-no-fields-5.rs diff --git a/src/test/compile-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs similarity index 100% rename from src/test/compile-fail/struct-variant-no-fields.rs rename to src/test/parse-fail/struct-variant-no-fields.rs diff --git a/src/test/compile-fail/struct-variant-no-pub.rs b/src/test/parse-fail/struct-variant-no-pub.rs similarity index 100% rename from src/test/compile-fail/struct-variant-no-pub.rs rename to src/test/parse-fail/struct-variant-no-pub.rs diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs similarity index 100% rename from src/test/compile-fail/syntax-trait-polarity.rs rename to src/test/parse-fail/syntax-trait-polarity.rs diff --git a/src/test/compile-fail/tag-variant-disr-non-nullary.rs b/src/test/parse-fail/tag-variant-disr-non-nullary.rs similarity index 100% rename from src/test/compile-fail/tag-variant-disr-non-nullary.rs rename to src/test/parse-fail/tag-variant-disr-non-nullary.rs diff --git a/src/test/compile-fail/trailing-carriage-return-in-string.rs b/src/test/parse-fail/trailing-carriage-return-in-string.rs similarity index 100% rename from src/test/compile-fail/trailing-carriage-return-in-string.rs rename to src/test/parse-fail/trailing-carriage-return-in-string.rs diff --git a/src/test/compile-fail/trailing-plus-in-bounds.rs b/src/test/parse-fail/trailing-plus-in-bounds.rs similarity index 100% rename from src/test/compile-fail/trailing-plus-in-bounds.rs rename to src/test/parse-fail/trailing-plus-in-bounds.rs diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs similarity index 100% rename from src/test/compile-fail/trait-bounds-not-on-impl.rs rename to src/test/parse-fail/trait-bounds-not-on-impl.rs diff --git a/src/test/compile-fail/type-parameters-in-field-exprs.rs b/src/test/parse-fail/type-parameters-in-field-exprs.rs similarity index 100% rename from src/test/compile-fail/type-parameters-in-field-exprs.rs rename to src/test/parse-fail/type-parameters-in-field-exprs.rs diff --git a/src/test/compile-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs similarity index 100% rename from src/test/compile-fail/unsized2.rs rename to src/test/parse-fail/unsized2.rs diff --git a/src/test/compile-fail/virtual-structs.rs b/src/test/parse-fail/virtual-structs.rs similarity index 100% rename from src/test/compile-fail/virtual-structs.rs rename to src/test/parse-fail/virtual-structs.rs diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs similarity index 100% rename from src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs rename to src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs diff --git a/src/test/pretty/empty-impl.rs b/src/test/pretty/empty-impl.rs index f22f1b4095269..f5205de5c1fcd 100644 --- a/src/test/pretty/empty-impl.rs +++ b/src/test/pretty/empty-impl.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait X { } +trait X { fn dummy(&self) { } } impl X for uint { } -trait Y { } +trait Y { fn dummy(&self) { } } impl Y for uint { } diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs index e27a3365a4105..9e1f2aa8bfe01 100644 --- a/src/test/pretty/path-type-bounds.rs +++ b/src/test/pretty/path-type-bounds.rs @@ -11,7 +11,9 @@ // pp-exact -trait Tr { } +trait Tr { + fn dummy(&self) { } +} impl Tr for int { } fn foo<'a>(x: Box) -> Box { x } diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs index e46564f80760c..4ad81197286bb 100644 --- a/src/test/run-fail/bug-811.rs +++ b/src/test/run-fail/bug-811.rs @@ -9,6 +9,9 @@ // except according to those terms. // error-pattern:quux + +use std::marker::PhantomData; + fn test00_start(ch: chan_t, message: int) { send(ch, message); } type task_id = int; @@ -17,6 +20,7 @@ type port_id = int; struct chan_t { task: task_id, port: port_id, + marker: PhantomData<*mut T>, } fn send(_ch: chan_t, _data: T) { panic!(); } diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/run-make/rustdoc-json/foo.rs index d57a7164cdbce..3bd56c14193a8 100644 --- a/src/test/run-make/rustdoc-json/foo.rs +++ b/src/test/run-make/rustdoc-json/foo.rs @@ -21,5 +21,5 @@ pub mod bar { } /// *wow* - pub trait Doge { } + pub trait Doge { fn dummy(&self) { } } } diff --git a/src/test/run-make/rustdoc-negative-impl/foo.rs b/src/test/run-make/rustdoc-negative-impl/foo.rs index b5fcbf46c5c98..6c56bcc9be67b 100644 --- a/src/test/run-make/rustdoc-negative-impl/foo.rs +++ b/src/test/run-make/rustdoc-negative-impl/foo.rs @@ -13,7 +13,7 @@ // @matches foo/struct.Alpha.html '//pre' "pub struct Alpha" pub struct Alpha; // @matches foo/struct.Bravo.html '//pre' "pub struct Bravo" -pub struct Bravo; +pub struct Bravo(B); // @matches foo/struct.Alpha.html '//*[@class="impl"]//code' "impl !Send for Alpha" impl !Send for Alpha {} diff --git a/src/test/run-make/rustdoc-search-index/index.rs b/src/test/run-make/rustdoc-search-index/index.rs index dd68f2d6f1dee..42469a21f22d0 100644 --- a/src/test/run-make/rustdoc-search-index/index.rs +++ b/src/test/run-make/rustdoc-search-index/index.rs @@ -21,6 +21,6 @@ mod private { } pub trait PrivateTrait { - fn trait_method() {} // @!has - priv_method + fn trait_method(&self) {} // @!has - priv_method } } diff --git a/src/test/run-make/rustdoc-smoke/foo.rs b/src/test/run-make/rustdoc-smoke/foo.rs index 0438c9aba3599..f6b73021bebdf 100644 --- a/src/test/run-make/rustdoc-smoke/foo.rs +++ b/src/test/run-make/rustdoc-smoke/foo.rs @@ -26,7 +26,7 @@ pub mod bar { /// *wow* // @has foo/bar/trait.Doge.html - pub trait Doge { } + pub trait Doge { fn dummy(&self) { } } // @has foo/bar/struct.Foo.html pub struct Foo { x: int, y: uint } diff --git a/src/test/run-make/rustdoc-viewpath-self/foo.rs b/src/test/run-make/rustdoc-viewpath-self/foo.rs index da8f739302390..6fd47d84c30fe 100644 --- a/src/test/run-make/rustdoc-viewpath-self/foo.rs +++ b/src/test/run-make/rustdoc-viewpath-self/foo.rs @@ -9,7 +9,7 @@ // except according to those terms. pub mod io { - pub trait Reader { } + pub trait Reader { fn dummy(&self) { } } } pub enum Maybe { diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs index 68fde60564e2a..91a7e1c9fd4ae 100644 --- a/src/test/run-make/rustdoc-where/foo.rs +++ b/src/test/run-make/rustdoc-where/foo.rs @@ -8,30 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait MyTrait {} +pub trait MyTrait { fn dummy(&self) { } } // @has foo/struct.Alpha.html '//pre' "pub struct Alpha where A: MyTrait" -pub struct Alpha where A: MyTrait; +pub struct Alpha(A) where A: MyTrait; // @has foo/trait.Bravo.html '//pre' "pub trait Bravo where B: MyTrait" -pub trait Bravo where B: MyTrait {} +pub trait Bravo where B: MyTrait { fn get(&self, B: B); } // @has foo/fn.charlie.html '//pre' "pub fn charlie() where C: MyTrait" pub fn charlie() where C: MyTrait {} -pub struct Delta; +pub struct Delta(D); + // @has foo/struct.Delta.html '//*[@class="impl"]//code' \ // "impl Delta where D: MyTrait" impl Delta where D: MyTrait { pub fn delta() {} } -pub struct Echo; +pub struct Echo(E); + // @has foo/struct.Echo.html '//*[@class="impl"]//code' \ // "impl MyTrait for Echo where E: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \ // "impl MyTrait for Echo where E: MyTrait" impl MyTrait for Echo where E: MyTrait {} -pub enum Foxtrot {} +pub enum Foxtrot { Foxtrot1(F) } + // @has foo/enum.Foxtrot.html '//*[@class="impl"]//code' \ // "impl MyTrait for Foxtrot where F: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \ diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index db70a24523266..38381da3670c1 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -34,7 +34,7 @@ use std::mem::size_of; static uni: &'static str = "Les Miséééééééérables"; static yy: usize = 25; -static bob: Option> = None; +static bob: Option<&'static [isize]> = None; // buglink test - see issue #1337. @@ -99,6 +99,7 @@ struct some_fields { type SF = some_fields; trait SuperTrait { + fn dummy(&self) { } } trait SomeTrait: SuperTrait { diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs index 834a2adf01fd3..f418d5d1fb74f 100755 --- a/src/test/run-make/simd-ffi/simd.rs +++ b/src/test/run-make/simd-ffi/simd.rs @@ -70,10 +70,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { } #[lang = "sized"] -trait Sized {} +pub trait Sized : PhantomFn {} #[lang = "copy"] -trait Copy {} +pub trait Copy : PhantomFn {} + +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } mod core { pub mod marker { diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs index 1e0570c95ac12..e1f36ecda53e8 100644 --- a/src/test/run-make/symbols-are-reasonable/lib.rs +++ b/src/test/run-make/symbols-are-reasonable/lib.rs @@ -11,7 +11,7 @@ pub static X: &'static str = "foobarbaz"; pub static Y: &'static [u8] = include_bytes!("lib.rs"); -trait Foo {} +trait Foo { fn dummy(&self) { } } impl Foo for uint {} pub fn dummy() { diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index 365fc039a4ec3..acda8705b19e3 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -11,11 +11,15 @@ #![feature(lang_items, no_std)] #![no_std] +#[lang="phantom_fn"] +trait PhantomFn { } +impl PhantomFn for U { } + #[lang="copy"] -trait Copy { } +trait Copy : PhantomFn { } #[lang="sized"] -trait Sized { } +trait Sized : PhantomFn { } #[lang="start"] fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 } diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs index 195055f12d1e4..aecec44f6fd3d 100644 --- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs +++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs @@ -25,7 +25,7 @@ impl Drop for Foo { } -trait Trait {} +trait Trait { fn dummy(&self) { } } impl Trait for Foo {} pub fn main() { diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs index 47e2a18a9992a..c49a684de945d 100644 --- a/src/test/run-pass-valgrind/dst-dtor-1.rs +++ b/src/test/run-pass-valgrind/dst-dtor-1.rs @@ -19,7 +19,7 @@ impl Drop for Foo { } } -trait Trait {} +trait Trait { fn dummy(&self) { } } impl Trait for Foo {} struct Fat { diff --git a/src/test/run-pass/associated-types-basic.rs b/src/test/run-pass/associated-types-basic.rs index 3314b61320159..f5521f7da853b 100644 --- a/src/test/run-pass/associated-types-basic.rs +++ b/src/test/run-pass/associated-types-basic.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { type T; } diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs index f21b7183d70c4..aa65b0ed10baf 100644 --- a/src/test/run-pass/associated-types-conditional-dispatch.rs +++ b/src/test/run-pass/associated-types-conditional-dispatch.rs @@ -14,6 +14,7 @@ // `Target=[A]`, then the impl marked with `(*)` is seen to conflict // with all the others. +use std::marker::PhantomData; use std::ops::Deref; pub trait MyEq { @@ -41,7 +42,8 @@ impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs } struct DerefWithHelper { - pub helper: H + pub helper: H, + pub marker: PhantomData, } trait Helper { @@ -63,7 +65,8 @@ impl> Deref for DerefWithHelper { } pub fn check(x: T, y: T) -> bool { - let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x) }; + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), + marker: PhantomData }; d.eq(&y) } diff --git a/src/test/run-pass/associated-types-issue-20371.rs b/src/test/run-pass/associated-types-issue-20371.rs index d35b7331d4dbf..40ef7f3531cb5 100644 --- a/src/test/run-pass/associated-types-issue-20371.rs +++ b/src/test/run-pass/associated-types-issue-20371.rs @@ -11,6 +11,8 @@ // Test that we are able to have an impl that defines an associated type // before the actual trait. +use std::marker::MarkerTrait; + impl X for f64 { type Y = int; } -trait X {type Y; } +trait X : MarkerTrait { type Y; } fn main() {} diff --git a/src/test/run-pass/associated-types-issue-21212.rs b/src/test/run-pass/associated-types-issue-21212.rs index ced44250e4d39..3c91577362a7d 100644 --- a/src/test/run-pass/associated-types-issue-21212.rs +++ b/src/test/run-pass/associated-types-issue-21212.rs @@ -20,7 +20,8 @@ pub trait Parser { panic!() } } -impl

Parser for P { + +impl

Parser for P { type Input = (); } diff --git a/src/test/run-pass/associated-types-nested-projections.rs b/src/test/run-pass/associated-types-nested-projections.rs index e3227613159d1..2ee8ef0d3ddac 100644 --- a/src/test/run-pass/associated-types-nested-projections.rs +++ b/src/test/run-pass/associated-types-nested-projections.rs @@ -10,11 +10,12 @@ // Test that we can resolve nested projection types. Issue #20666. +use std::marker::MarkerTrait; use std::slice; -trait Bound {} +trait Bound : MarkerTrait {} -impl<'a> Bound for &'a int {} +impl<'a> Bound for &'a i32 {} trait IntoIterator { type Iter: Iterator; diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs index dd5814f875b08..de96af83f5917 100644 --- a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs +++ b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs @@ -13,7 +13,9 @@ #![allow(dead_code)] -pub trait Integral { +use std::marker::MarkerTrait; + +pub trait Integral : MarkerTrait { type Opposite; } @@ -27,6 +29,8 @@ impl Integral for u32 { pub trait FnLike { type R; + + fn dummy(&self, a: A) -> Self::R { loop { } } } fn foo() diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs index 1d264655bc479..8617750ca538e 100644 --- a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs +++ b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs @@ -11,15 +11,17 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. -struct Splits<'a, T, P>; -struct SplitsN; +use std::marker::PhantomData; + +struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>); +struct SplitsN(PhantomData); trait SliceExt2 { type Item; fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> where P: FnMut(&Self::Item) -> bool; - fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> + fn splitn2<'a, P>(&'a self, n: u32, pred: P) -> SplitsN> where P: FnMut(&Self::Item) -> bool; } @@ -30,7 +32,7 @@ impl SliceExt2 for [T] { loop {} } - fn splitn2

(&self, n: uint, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + fn splitn2

(&self, n: u32, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { SliceExt2::split2(self, pred); loop {} } diff --git a/src/test/run-pass/associated-types-normalize-in-bounds.rs b/src/test/run-pass/associated-types-normalize-in-bounds.rs index 742bab0578e9c..94cfcb8365381 100644 --- a/src/test/run-pass/associated-types-normalize-in-bounds.rs +++ b/src/test/run-pass/associated-types-normalize-in-bounds.rs @@ -11,15 +11,17 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. -struct Splits<'a, T, P>; -struct SplitsN; +use std::marker::PhantomData; + +struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>); +struct SplitsN(PhantomData); trait SliceExt2 { type Item; fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> where P: FnMut(&Self::Item) -> bool; - fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> + fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN> where P: FnMut(&Self::Item) -> bool; } @@ -30,7 +32,7 @@ impl SliceExt2 for [T] { loop {} } - fn splitn2

(&self, n: uint, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + fn splitn2

(&self, n: usize, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { self.split2(pred); loop {} } diff --git a/src/test/run-pass/associated-types-normalize-unifield-struct.rs b/src/test/run-pass/associated-types-normalize-unifield-struct.rs index 5aafe93067c13..2288e19aae0bc 100644 --- a/src/test/run-pass/associated-types-normalize-unifield-struct.rs +++ b/src/test/run-pass/associated-types-normalize-unifield-struct.rs @@ -13,7 +13,10 @@ pub trait OffsetState: Sized {} -pub trait Offset { type State: OffsetState; } +pub trait Offset { + type State: OffsetState; + fn dummy(&self) { } +} #[derive(Copy)] pub struct X; impl Offset for X { type State = Y; } diff --git a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs index 0a1a8589dec82..c65d2db9b0cf0 100644 --- a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs +++ b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs @@ -13,6 +13,8 @@ trait Int { type T; + + fn dummy(&self) { } } trait NonZero diff --git a/src/test/run-pass/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types-projection-in-object-type.rs index 44dd49b72976e..a9c34a605ce16 100644 --- a/src/test/run-pass/associated-types-projection-in-object-type.rs +++ b/src/test/run-pass/associated-types-projection-in-object-type.rs @@ -18,6 +18,8 @@ use std::cell::RefCell; pub trait Subscriber { type Input; + + fn dummy(&self) { } } pub trait Publisher<'a> { diff --git a/src/test/run-pass/associated-types-projection-in-supertrait.rs b/src/test/run-pass/associated-types-projection-in-supertrait.rs index e6fec675b0363..4d2358fae27b1 100644 --- a/src/test/run-pass/associated-types-projection-in-supertrait.rs +++ b/src/test/run-pass/associated-types-projection-in-supertrait.rs @@ -14,6 +14,8 @@ trait A { type TA; + + fn dummy(&self) { } } trait B diff --git a/src/test/run-pass/associated-types-projection-in-where-clause.rs b/src/test/run-pass/associated-types-projection-in-where-clause.rs index 10a459f3c3662..3f3f4fbd1d628 100644 --- a/src/test/run-pass/associated-types-projection-in-where-clause.rs +++ b/src/test/run-pass/associated-types-projection-in-where-clause.rs @@ -13,6 +13,8 @@ trait Int { type T; + + fn dummy(&self) { } } trait NonZero diff --git a/src/test/run-pass/associated-types-ref-in-struct-literal.rs b/src/test/run-pass/associated-types-ref-in-struct-literal.rs index 022c8f4cd0130..67fe11d8fedde 100644 --- a/src/test/run-pass/associated-types-ref-in-struct-literal.rs +++ b/src/test/run-pass/associated-types-ref-in-struct-literal.rs @@ -12,6 +12,8 @@ pub trait Foo { type Bar; + + fn dummy(&self) { } } impl Foo for int { diff --git a/src/test/run-pass/associated-types-resolve-lifetime.rs b/src/test/run-pass/associated-types-resolve-lifetime.rs index e7a8061a3467a..a4b0b1a6e03af 100644 --- a/src/test/run-pass/associated-types-resolve-lifetime.rs +++ b/src/test/run-pass/associated-types-resolve-lifetime.rs @@ -15,6 +15,8 @@ trait Get { trait Trait<'a> { type T: 'static; type U: Get<&'a int>; + + fn dummy(&'a self) { } } fn main() {} diff --git a/src/test/run-pass/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types-struct-field-named.rs index 1ded34ff3ffe3..8667f6c8430ab 100644 --- a/src/test/run-pass/associated-types-struct-field-named.rs +++ b/src/test/run-pass/associated-types-struct-field-named.rs @@ -13,6 +13,8 @@ pub trait UnifyKey { type Value; + + fn dummy(&self) { } } pub struct Node { diff --git a/src/test/run-pass/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types-struct-field-numbered.rs index 3669dec4fbdd4..9503f78a71b90 100644 --- a/src/test/run-pass/associated-types-struct-field-numbered.rs +++ b/src/test/run-pass/associated-types-struct-field-numbered.rs @@ -13,6 +13,8 @@ pub trait UnifyKey { type Value; + + fn dummy(&self) { } } pub struct Node(K, K::Value); diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs index 3b70e941ac50a..c068065ac6ae7 100644 --- a/src/test/run-pass/associated-types-sugar-path.rs +++ b/src/test/run-pass/associated-types-sugar-path.rs @@ -31,8 +31,9 @@ pub fn bar(a: T, x: T::A) -> T::A { // Using a type via an impl. trait C { fn f(); + fn g(&self) { } } -struct B; +struct B(X); impl C for B { fn f() { let x: T::A = panic!(); diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs index b6d428924e3e9..7bb9f042fe891 100644 --- a/src/test/run-pass/bitv-perf-test.rs +++ b/src/test/run-pass/bitv-perf-test.rs @@ -13,11 +13,11 @@ #![feature(box_syntax)] extern crate collections; -use std::collections::Bitv; +use std::collections::BitVec; fn bitv_test() { - let mut v1 = box Bitv::from_elem(31, false); - let v2 = box Bitv::from_elem(31, true); + let mut v1 = box BitVec::from_elem(31, false); + let v2 = box BitVec::from_elem(31, true); v1.union(&*v2); } diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs index b39f03a93c9fe..a2b0fa5663530 100644 --- a/src/test/run-pass/borrowck-trait-lifetime.rs +++ b/src/test/run-pass/borrowck-trait-lifetime.rs @@ -12,8 +12,11 @@ // to the same lifetime on a trait succeeds. See issue #10766. #![allow(dead_code)] + +use std::marker; + fn main() { - trait T {} + trait T { fn foo(&self) {} } fn f<'a, V: T>(v: &'a V) -> &'a T { v as &'a T diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs index ea711d78dd28e..143ebfdabface 100644 --- a/src/test/run-pass/bug-7295.rs +++ b/src/test/run-pass/bug-7295.rs @@ -9,10 +9,10 @@ // except according to those terms. pub trait Foo { - fn func1(&self, t: U); + fn func1(&self, t: U, w: T); - fn func2(&self, t: U) { - self.func1(t); + fn func2(&self, t: U, w: T) { + self.func1(t, w); } } diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs index c115415bb9b7b..7eaed910124d9 100644 --- a/src/test/run-pass/builtin-superkinds-in-metadata.rs +++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs @@ -16,6 +16,7 @@ extern crate trait_superkinds_in_metadata; use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare}; use trait_superkinds_in_metadata::{RequiresCopy}; +use std::marker; #[derive(Copy)] struct X(T); diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs index 7e1b28219373b..964c28dc94517 100644 --- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs +++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs @@ -12,10 +12,12 @@ // super-builtin-kind of a trait, if the type parameter is never used, // the type can implement the trait anyway. +use std::marker; + trait Foo : Send { } -struct X(()); +struct X { marker: marker::PhantomData } -impl Foo for X { } +impl Foo for X { } pub fn main() { } diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index 22c322b86c979..6246ee9c6c41a 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -24,12 +24,12 @@ mod mlibc { } fn atol(s: String) -> int { - let c = CString::from_slice(s.as_bytes()); + let c = CString::new(s).unwrap(); unsafe { mlibc::atol(c.as_ptr()) as int } } fn atoll(s: String) -> i64 { - let c = CString::from_slice(s.as_bytes()); + let c = CString::new(s).unwrap(); unsafe { mlibc::atoll(c.as_ptr()) as i64 } } diff --git a/src/test/run-pass/class-typarams.rs b/src/test/run-pass/class-typarams.rs index 68457095944e3..b56a749d33bb8 100644 --- a/src/test/run-pass/class-typarams.rs +++ b/src/test/run-pass/class-typarams.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::PhantomData; + struct cat { meows : uint, - how_hungry : int, + m: PhantomData } impl cat { @@ -22,7 +24,8 @@ impl cat { fn cat(in_x : uint, in_y : int) -> cat { cat { meows: in_x, - how_hungry: in_y + how_hungry: in_y, + m: PhantomData } } diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs index f8f92a56adb1a..dce12030f7942 100644 --- a/src/test/run-pass/const-polymorphic-paths.rs +++ b/src/test/run-pass/const-polymorphic-paths.rs @@ -11,7 +11,7 @@ #![feature(macro_rules)] use std::borrow::{Cow, IntoCow}; -use std::collections::Bitv; +use std::collections::BitVec; use std::default::Default; use std::iter::FromIterator; use std::ops::Add; @@ -63,8 +63,8 @@ tests! { Vec::<()>::new, fn() -> Vec<()>, (); Vec::with_capacity, fn(uint) -> Vec<()>, (5); Vec::<()>::with_capacity, fn(uint) -> Vec<()>, (5); - Bitv::from_fn, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd); - Bitv::from_fn:: bool>, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd); + BitVec::from_fn, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd); + BitVec::from_fn:: bool>, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd); // Inherent non-static method. Vec::map_in_place, fn(Vec, fn(u8) -> i8) -> Vec, (vec![b'f', b'o', b'o'], u8_as_i8); @@ -100,8 +100,8 @@ tests! { Add::add, fn(i32, i32) -> i32, (5, 6); >::add, fn(i32, i32) -> i32, (5, 6); >::add, fn(i32, i32) -> i32, (5, 6); - >::into_cow, fn(String) -> Cow<'static, String, str>, + >::into_cow, fn(String) -> Cow<'static, str>, ("foo".to_string()); - >::into_cow, fn(String) -> Cow<'static, String, str>, + >::into_cow, fn(String) -> Cow<'static, str>, ("foo".to_string()); } diff --git a/src/test/run-pass/deriving-hash.rs b/src/test/run-pass/deriving-hash.rs index 02ab7e5db5b89..5fe7c8bb94b4f 100644 --- a/src/test/run-pass/deriving-hash.rs +++ b/src/test/run-pass/deriving-hash.rs @@ -17,7 +17,7 @@ struct Person { phone: uint, } -fn hash>(t: &T) -> u64 { +fn hash(t: &T) -> u64 { std::hash::hash::(t) } diff --git a/src/test/run-pass/deriving-meta-multiple.rs b/src/test/run-pass/deriving-meta-multiple.rs index f45dce9da632e..62ec2f8e5902d 100644 --- a/src/test/run-pass/deriving-meta-multiple.rs +++ b/src/test/run-pass/deriving-meta-multiple.rs @@ -20,7 +20,7 @@ struct Foo { baz: int } -fn hash>(_t: &T) {} +fn hash(_t: &T) {} pub fn main() { let a = Foo {bar: 4, baz: -3}; diff --git a/src/test/run-pass/deriving-meta.rs b/src/test/run-pass/deriving-meta.rs index d6a2fad08ed88..82cf9db3232c0 100644 --- a/src/test/run-pass/deriving-meta.rs +++ b/src/test/run-pass/deriving-meta.rs @@ -17,7 +17,7 @@ struct Foo { baz: int } -fn hash>(_t: &T) {} +fn hash(_t: &T) {} pub fn main() { let a = Foo {bar: 4, baz: -3}; diff --git a/src/test/run-pass/dst-coercions.rs b/src/test/run-pass/dst-coercions.rs index dbad546ce1ae3..30ed0b8e40245 100644 --- a/src/test/run-pass/dst-coercions.rs +++ b/src/test/run-pass/dst-coercions.rs @@ -11,7 +11,7 @@ // Test coercions involving DST and/or raw pointers struct S; -trait T {} +trait T { fn dummy(&self) { } } impl T for S {} pub fn main() { diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index 797c26556aaa1..023376ce4736e 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -16,7 +16,7 @@ use std::mem::size_of; use std::rc::Rc; use std::sync::Arc; -trait Trait {} +trait Trait { fn dummy(&self) { } } fn main() { // Functions diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs index 066a5f9580ac4..382c5c58e92ee 100644 --- a/src/test/run-pass/explicit-self-generic.rs +++ b/src/test/run-pass/explicit-self-generic.rs @@ -15,21 +15,19 @@ struct LM { resize_at: uint, size: uint } enum HashMap { - HashMap_(LM) + HashMap_(LM, Vec<(K,V)>) } -impl Copy for HashMap {} - fn linear_map() -> HashMap { HashMap::HashMap_(LM{ resize_at: 32, - size: 0}) + size: 0}, Vec::new()) } impl HashMap { pub fn len(&mut self) -> uint { match *self { - HashMap::HashMap_(l) => l.size + HashMap::HashMap_(ref l, _) => l.size } } } diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index 592ab7d0e6e36..24b711328a18a 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -24,7 +24,7 @@ mod mlibc { fn strlen(str: String) -> uint { // C string is terminated with a zero - let s = CString::from_slice(str.as_bytes()); + let s = CString::new(str).unwrap(); unsafe { mlibc::my_strlen(s.as_ptr()) as uint } diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs index ed8c6e73255bb..bf02b82d1a075 100644 --- a/src/test/run-pass/generic-default-type-params-cross-crate.rs +++ b/src/test/run-pass/generic-default-type-params-cross-crate.rs @@ -12,13 +12,13 @@ extern crate default_type_params_xc; -struct Vec; +struct Vec(Option<(T,A)>); struct Foo; fn main() { - let _a = Vec::; - let _b = Vec::; - let _c = default_type_params_xc::FakeVec::; - let _d = default_type_params_xc::FakeVec::; + let _a = Vec::(None); + let _b = Vec::(None); + let _c = default_type_params_xc::FakeVec:: { f: None }; + let _d = default_type_params_xc::FakeVec:: { f: None }; } diff --git a/src/test/run-pass/hrtb-opt-in-copy.rs b/src/test/run-pass/hrtb-opt-in-copy.rs index 9c9f95f61e9be..7b16bb867e79c 100644 --- a/src/test/run-pass/hrtb-opt-in-copy.rs +++ b/src/test/run-pass/hrtb-opt-in-copy.rs @@ -18,7 +18,7 @@ #![allow(dead_code)] -use std::marker; +use std::marker::PhantomData; #[derive(Copy)] struct Foo { x: T } @@ -26,7 +26,7 @@ struct Foo { x: T } type Ty<'tcx> = &'tcx TyS<'tcx>; enum TyS<'tcx> { - Boop(marker::InvariantLifetime<'tcx>) + Boop(PhantomData<*mut &'tcx ()>) } #[derive(Copy)] diff --git a/src/test/run-pass/inner-static.rs b/src/test/run-pass/inner-static.rs index f9b430c1553dd..e4026a8fd0118 100644 --- a/src/test/run-pass/inner-static.rs +++ b/src/test/run-pass/inner-static.rs @@ -13,9 +13,9 @@ extern crate inner_static; pub fn main() { - let a = inner_static::A::<()>; - let b = inner_static::B::<()>; - let c = inner_static::test::A::<()>; + let a = inner_static::A::<()> { v: () }; + let b = inner_static::B::<()> { v: () }; + let c = inner_static::test::A::<()> { v: () }; assert_eq!(a.bar(), 2); assert_eq!(b.bar(), 4); assert_eq!(c.bar(), 6); diff --git a/src/test/run-pass/issue-10456.rs b/src/test/run-pass/issue-10456.rs index b714d87f4ef20..da73c4b27ac44 100644 --- a/src/test/run-pass/issue-10456.rs +++ b/src/test/run-pass/issue-10456.rs @@ -14,7 +14,9 @@ pub trait Bar { fn bar(&self); } -pub trait Baz {} +pub trait Baz { + fn baz(&self) { } +} impl Bar for T { fn bar(&self) {} diff --git a/src/test/run-pass/issue-10802.rs b/src/test/run-pass/issue-10802.rs index de2b4c51e52a9..174a69e1135cd 100644 --- a/src/test/run-pass/issue-10802.rs +++ b/src/test/run-pass/issue-10802.rs @@ -29,7 +29,7 @@ impl Drop for DroppableEnum { } } -trait MyTrait { } +trait MyTrait { fn dummy(&self) { } } impl MyTrait for Box {} impl MyTrait for Box {} diff --git a/src/test/run-pass/issue-10902.rs b/src/test/run-pass/issue-10902.rs index 324a1701b2feb..7fab6662ee01c 100644 --- a/src/test/run-pass/issue-10902.rs +++ b/src/test/run-pass/issue-10902.rs @@ -9,7 +9,7 @@ // except according to those terms. pub mod two_tuple { - pub trait T {} + pub trait T { fn dummy(&self) { } } pub struct P<'a>(&'a (T + 'a), &'a (T + 'a)); pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> { P(car, cdr) @@ -17,7 +17,7 @@ pub mod two_tuple { } pub mod two_fields { - pub trait T {} + pub trait T { fn dummy(&self) { } } pub struct P<'a> { car: &'a (T + 'a), cdr: &'a (T + 'a) } pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> { P{ car: car, cdr: cdr } diff --git a/src/test/run-pass/issue-11205.rs b/src/test/run-pass/issue-11205.rs index d7c6c1b1bb2c2..1325b51a54ff2 100644 --- a/src/test/run-pass/issue-11205.rs +++ b/src/test/run-pass/issue-11205.rs @@ -12,7 +12,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -trait Foo {} +trait Foo { fn dummy(&self) { } } impl Foo for int {} fn foo(_: [&Foo; 2]) {} fn foos(_: &[&Foo]) {} diff --git a/src/test/run-pass/issue-11384.rs b/src/test/run-pass/issue-11384.rs index a511149b05e2a..26634fabf5a15 100644 --- a/src/test/run-pass/issue-11384.rs +++ b/src/test/run-pass/issue-11384.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Common {} +trait Common { fn dummy(&self) { } } impl<'t, T> Common for (T, &'t T) {} diff --git a/src/test/run-pass/issue-11612.rs b/src/test/run-pass/issue-11612.rs index fa25d25df054e..3c69377b375c6 100644 --- a/src/test/run-pass/issue-11612.rs +++ b/src/test/run-pass/issue-11612.rs @@ -12,7 +12,7 @@ // We weren't updating the auto adjustments with all the resolved // type information after type check. -trait A {} +trait A { fn dummy(&self) { } } struct B<'a, T:'a> { f: &'a T diff --git a/src/test/run-pass/issue-11677.rs b/src/test/run-pass/issue-11677.rs index 6fa4505869478..7cccac4483d49 100644 --- a/src/test/run-pass/issue-11677.rs +++ b/src/test/run-pass/issue-11677.rs @@ -14,13 +14,18 @@ // this code used to cause an ICE -trait X {} +use std::marker; + +trait X { + fn dummy(&self) -> T { panic!() } +} struct S {f: Box+'static>, g: Box+'static>} struct F; -impl X for F {} +impl X for F { +} fn main() { S {f: box F, g: box F}; diff --git a/src/test/run-pass/issue-11736.rs b/src/test/run-pass/issue-11736.rs index d9bae6886fa2e..b901e95ff55ed 100644 --- a/src/test/run-pass/issue-11736.rs +++ b/src/test/run-pass/issue-11736.rs @@ -10,13 +10,13 @@ extern crate collections; -use std::collections::Bitv; +use std::collections::BitVec; use std::num::Float; fn main() { // Generate sieve of Eratosthenes for n up to 1e6 let n = 1000000_usize; - let mut sieve = Bitv::from_elem(n+1, true); + let mut sieve = BitVec::from_elem(n+1, true); let limit: uint = (n as f32).sqrt() as uint; for i in 2..limit+1 { if sieve[i] { diff --git a/src/test/run-pass/issue-13105.rs b/src/test/run-pass/issue-13105.rs index 7fab36bd64ec7..64807dc44e061 100644 --- a/src/test/run-pass/issue-13105.rs +++ b/src/test/run-pass/issue-13105.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { fn quux(u8) {} } diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs index 7e533c2cf86c1..db7eacce9d10b 100644 --- a/src/test/run-pass/issue-14399.rs +++ b/src/test/run-pass/issue-14399.rs @@ -19,7 +19,7 @@ #[derive(Clone)] struct B1; -trait A {} +trait A { fn foo(&self) {} } impl A for B1 {} fn main() { diff --git a/src/test/run-pass/issue-14589.rs b/src/test/run-pass/issue-14589.rs index d9763baa82657..71d88ee621510 100644 --- a/src/test/run-pass/issue-14589.rs +++ b/src/test/run-pass/issue-14589.rs @@ -17,17 +17,18 @@ fn main() { send::>(box Output(0)); Test::>::foo(box Output(0)); - Test::>.send(box Output(0)); + Test::>::new().send(box Output(0)); } fn send(_: T) {} -struct Test; +struct Test { marker: std::marker::PhantomData } impl Test { + fn new() -> Test { Test { marker: ::std::marker::PhantomData } } fn foo(_: T) {} fn send(&self, _: T) {} } -trait Foo {} +trait Foo { fn dummy(&self) { }} struct Output(int); impl Foo for Output {} diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs index 814a743648d3f..6335f79be6c7a 100644 --- a/src/test/run-pass/issue-14958.rs +++ b/src/test/run-pass/issue-14958.rs @@ -10,7 +10,7 @@ #![feature(unboxed_closures)] -trait Foo {} +trait Foo { fn dummy(&self) { }} struct Bar; diff --git a/src/test/run-pass/issue-14959.rs b/src/test/run-pass/issue-14959.rs index 33281d7d78ffb..53d0f7dae0577 100644 --- a/src/test/run-pass/issue-14959.rs +++ b/src/test/run-pass/issue-14959.rs @@ -12,8 +12,8 @@ use std::ops::Fn; -trait Response {} -trait Request {} +trait Response { fn dummy(&self) { } } +trait Request { fn dummy(&self) { } } trait Ingot { fn enter(&mut self, _: &mut R, _: &mut S, a: &mut Alloy) -> Status; } @@ -21,7 +21,7 @@ trait Ingot { #[allow(dead_code)] struct HelloWorld; -struct SendFile<'a>; +struct SendFile; struct Alloy; enum Status { Continue @@ -33,7 +33,7 @@ impl Alloy { } } -impl<'a, 'b> Fn<(&'b mut (Response+'b),)> for SendFile<'a> { +impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile { type Output = (); extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {} diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs index c75c672546125..6a4f78442d149 100644 --- a/src/test/run-pass/issue-15858.rs +++ b/src/test/run-pass/issue-15858.rs @@ -12,21 +12,21 @@ static mut DROP_RAN: bool = false; -trait Bar<'b> { +trait Bar { fn do_something(&mut self); } -struct BarImpl<'b>; +struct BarImpl; -impl<'b> Bar<'b> for BarImpl<'b> { +impl Bar for BarImpl { fn do_something(&mut self) {} } -struct Foo; +struct Foo(B); #[unsafe_destructor] -impl<'b, B: Bar<'b>> Drop for Foo { +impl Drop for Foo { fn drop(&mut self) { unsafe { DROP_RAN = true; @@ -37,7 +37,7 @@ impl<'b, B: Bar<'b>> Drop for Foo { fn main() { { - let _x: Foo = Foo; + let _x: Foo = Foo(BarImpl); } unsafe { assert_eq!(DROP_RAN, true); diff --git a/src/test/run-pass/issue-16596.rs b/src/test/run-pass/issue-16596.rs index e01de3a3262ed..1ba7b142e5e15 100644 --- a/src/test/run-pass/issue-16596.rs +++ b/src/test/run-pass/issue-16596.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait MatrixRow {} +trait MatrixRow { fn dummy(&self) { }} struct Mat; diff --git a/src/test/run-pass/issue-16643.rs b/src/test/run-pass/issue-16643.rs index b118c9573cdcf..4e57c55c5f755 100644 --- a/src/test/run-pass/issue-16643.rs +++ b/src/test/run-pass/issue-16643.rs @@ -13,5 +13,5 @@ extern crate "issue-16643" as i; pub fn main() { - i::TreeBuilder::.process_token(); + i::TreeBuilder { h: 3u }.process_token(); } diff --git a/src/test/run-pass/issue-17662.rs b/src/test/run-pass/issue-17662.rs index 45e70f59f3397..7bd41cc5b52a2 100644 --- a/src/test/run-pass/issue-17662.rs +++ b/src/test/run-pass/issue-17662.rs @@ -12,12 +12,14 @@ extern crate "issue-17662" as i; -struct Bar<'a>; +use std::marker; + +struct Bar<'a> { m: marker::PhantomData<&'a ()> } impl<'a> i::Foo<'a, uint> for Bar<'a> { fn foo(&self) -> uint { 5_usize } } pub fn main() { - assert_eq!(i::foo(&Bar), 5); + assert_eq!(i::foo(&Bar { m: marker::PhantomData }), 5); } diff --git a/src/test/run-pass/issue-17732.rs b/src/test/run-pass/issue-17732.rs index b4bd55da59757..de9611f259227 100644 --- a/src/test/run-pass/issue-17732.rs +++ b/src/test/run-pass/issue-17732.rs @@ -10,8 +10,9 @@ trait Person { type string; + fn dummy(&self) { } } -struct Someone; +struct Someone(std::marker::PhantomData

); fn main() {} diff --git a/src/test/run-pass/issue-17771.rs b/src/test/run-pass/issue-17771.rs index 1e9550acef4cb..2f1b0342b8e04 100644 --- a/src/test/run-pass/issue-17771.rs +++ b/src/test/run-pass/issue-17771.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Aaa {} +trait Aaa { fn dummy(&self) { } } impl<'a> Aaa for &'a mut (Aaa + 'a) {} diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs index f8fbd680dcb9e..a976eccf89ec4 100644 --- a/src/test/run-pass/issue-17816.rs +++ b/src/test/run-pass/issue-17816.rs @@ -10,9 +10,11 @@ #![feature(unboxed_closures)] +use std::marker::PhantomData; + fn main() { - struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F } + struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> } let f = |x: Vec<&str>| -> &str "foobar"; - let sym = Symbol { function: f }; + let sym = Symbol { function: f, marker: PhantomData }; (sym.function)(vec![]); } diff --git a/src/test/run-pass/issue-17904.rs b/src/test/run-pass/issue-17904.rs index 3ce347d67e3d9..58a0872a5719b 100644 --- a/src/test/run-pass/issue-17904.rs +++ b/src/test/run-pass/issue-17904.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo where T: Copy; +// Test that we can parse where clauses on various forms of tuple +// structs. + struct Bar(T) where T: Copy; struct Bleh(T, U) where T: Copy, U: Sized; struct Baz where T: Copy { diff --git a/src/test/run-pass/issue-18232.rs b/src/test/run-pass/issue-18232.rs index 15cf5870d40ad..67b3239d35197 100644 --- a/src/test/run-pass/issue-18232.rs +++ b/src/test/run-pass/issue-18232.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Cursor<'a>; +struct Cursor<'a>(::std::marker::PhantomData<&'a ()>); trait CursorNavigator { fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; @@ -23,7 +23,7 @@ impl CursorNavigator for SimpleNavigator { } fn main() { - let mut c = Cursor; + let mut c = Cursor(::std::marker::PhantomData); let n = SimpleNavigator; n.init_cursor(&mut c); } diff --git a/src/test/run-pass/issue-18906.rs b/src/test/run-pass/issue-18906.rs index 11ffb4198dad8..16dd84315ed2c 100644 --- a/src/test/run-pass/issue-18906.rs +++ b/src/test/run-pass/issue-18906.rs @@ -24,7 +24,7 @@ fn bar(k: &K, q: &Q) where K: Borrow, Q: Foo { q.foo(k.borrow()) } -struct MyTree; +struct MyTree(K); impl MyTree { // This caused a failure in #18906 diff --git a/src/test/run-pass/issue-19121.rs b/src/test/run-pass/issue-19121.rs index d95f74ef2a2ba..222f67af437ef 100644 --- a/src/test/run-pass/issue-19121.rs +++ b/src/test/run-pass/issue-19121.rs @@ -13,6 +13,8 @@ trait Foo { type A; + + fn dummy(&self) { } } fn bar(x: &Foo) {} diff --git a/src/test/run-pass/issue-19129-2.rs b/src/test/run-pass/issue-19129-2.rs index d6b3a1908b82d..cf0f48e025a0e 100644 --- a/src/test/run-pass/issue-19129-2.rs +++ b/src/test/run-pass/issue-19129-2.rs @@ -11,7 +11,7 @@ trait Trait { type Output; - fn method() -> bool { false } + fn method(&self, i: Input) -> bool { false } } fn main() {} diff --git a/src/test/run-pass/issue-19135.rs b/src/test/run-pass/issue-19135.rs index 031a63ba474c1..5e6dd567d6328 100644 --- a/src/test/run-pass/issue-19135.rs +++ b/src/test/run-pass/issue-19135.rs @@ -10,13 +10,15 @@ #![feature(unboxed_closures)] +use std::marker::PhantomData; + #[derive(Debug)] -struct LifetimeStruct<'a>; +struct LifetimeStruct<'a>(PhantomData<&'a ()>); fn main() { takes_hrtb_closure(|lts| println!("{:?}", lts)); } fn takes_hrtb_closureFnMut(LifetimeStruct<'a>)>(mut f: F) { - f(LifetimeStruct); + f(LifetimeStruct(PhantomData)); } diff --git a/src/test/run-pass/issue-19358.rs b/src/test/run-pass/issue-19358.rs index ff657376ecc1f..8b5269ab92f03 100644 --- a/src/test/run-pass/issue-19358.rs +++ b/src/test/run-pass/issue-19358.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +trait Trait { fn dummy(&self) { } } #[derive(Debug)] struct Foo { diff --git a/src/test/run-pass/issue-19398.rs b/src/test/run-pass/issue-19398.rs index 1196162568a91..e603167b26be0 100644 --- a/src/test/run-pass/issue-19398.rs +++ b/src/test/run-pass/issue-19398.rs @@ -9,11 +9,11 @@ // except according to those terms. trait T { - unsafe extern "Rust" fn foo(); + unsafe extern "Rust" fn foo(&self); } impl T for () { - unsafe extern "Rust" fn foo() {} + unsafe extern "Rust" fn foo(&self) {} } fn main() {} diff --git a/src/test/run-pass/issue-19479.rs b/src/test/run-pass/issue-19479.rs index 91bc645b2d486..38a7af3a69597 100644 --- a/src/test/run-pass/issue-19479.rs +++ b/src/test/run-pass/issue-19479.rs @@ -8,12 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Base {} +trait Base { + fn dummy(&self) { } +} trait AssocA { type X: Base; + fn dummy(&self) { } } trait AssocB { type Y: Base; + fn dummy(&self) { } } impl AssocB for T { type Y = ::X; diff --git a/src/test/run-pass/issue-19631.rs b/src/test/run-pass/issue-19631.rs index 43116f63641de..7bb0d055b844d 100644 --- a/src/test/run-pass/issue-19631.rs +++ b/src/test/run-pass/issue-19631.rs @@ -10,6 +10,7 @@ trait PoolManager { type C; + fn dummy(&self) { } } struct InnerPool { diff --git a/src/test/run-pass/issue-19632.rs b/src/test/run-pass/issue-19632.rs index 01a073a6889ae..4339339d74c88 100644 --- a/src/test/run-pass/issue-19632.rs +++ b/src/test/run-pass/issue-19632.rs @@ -10,6 +10,7 @@ trait PoolManager { type C; + fn dummy(&self) { } } struct InnerPool { diff --git a/src/test/run-pass/issue-20055-box-trait.rs b/src/test/run-pass/issue-20055-box-trait.rs index 836e78b5b5143..572a0d825282e 100644 --- a/src/test/run-pass/issue-20055-box-trait.rs +++ b/src/test/run-pass/issue-20055-box-trait.rs @@ -16,7 +16,9 @@ // whichever arm is run, and subsequently dropped at the end of the // statement surrounding the `match`. -trait Boo { } +trait Boo { + fn dummy(&self) { } +} impl Boo for [i8; 1] { } impl Boo for [i8; 2] { } diff --git a/src/test/run-pass/issue-20343.rs b/src/test/run-pass/issue-20343.rs index 79034a4a4a6d6..2f9e8feed2482 100644 --- a/src/test/run-pass/issue-20343.rs +++ b/src/test/run-pass/issue-20343.rs @@ -16,7 +16,7 @@ struct B { b: u32 } struct C; struct D; -trait T {} +trait T { fn dummy(&self, a: A) { } } impl T for () {} impl B { diff --git a/src/test/run-pass/issue-20763-1.rs b/src/test/run-pass/issue-20763-1.rs index 911ee715da281..97c06ac98265f 100644 --- a/src/test/run-pass/issue-20763-1.rs +++ b/src/test/run-pass/issue-20763-1.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait T0 { type O; } +trait T0 { + type O; + fn dummy(&self) { } +} struct S(A); impl T0 for S { type O = A; } diff --git a/src/test/run-pass/issue-20763-2.rs b/src/test/run-pass/issue-20763-2.rs index a17c7b6ade48e..d97017635718c 100644 --- a/src/test/run-pass/issue-20763-2.rs +++ b/src/test/run-pass/issue-20763-2.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait T0 { type O; } +trait T0 { + type O; + fn dummy(&self) { } +} struct S(A); impl T0 for S { type O = A; } diff --git a/src/test/run-pass/issue-21363.rs b/src/test/run-pass/issue-21363.rs index 2fc1d9fd6433c..71bb3d39fe1d6 100644 --- a/src/test/run-pass/issue-21363.rs +++ b/src/test/run-pass/issue-21363.rs @@ -12,6 +12,7 @@ trait Iterator { type Item; + fn dummy(&self) { } } impl<'a, T> Iterator for &'a mut (Iterator + 'a) { diff --git a/src/test/run-pass/issue-21909.rs b/src/test/run-pass/issue-21909.rs index 5bbc90b260639..55b61dd194556 100644 --- a/src/test/run-pass/issue-21909.rs +++ b/src/test/run-pass/issue-21909.rs @@ -8,11 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +trait A { + fn dummy(&self, arg: X); +} trait B { type X; type Y: A; + + fn dummy(&self); } fn main () { } diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs index e0b98ab19652a..5529d51b408c0 100644 --- a/src/test/run-pass/issue-2311-2.rs +++ b/src/test/run-pass/issue-2311-2.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait clam { } +trait clam { + fn get(self) -> A; +} + struct foo { x: A, } diff --git a/src/test/run-pass/issue-2311.rs b/src/test/run-pass/issue-2311.rs index dc873ed08d701..b6b3114e2a487 100644 --- a/src/test/run-pass/issue-2311.rs +++ b/src/test/run-pass/issue-2311.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait clam { } +trait clam { fn get(self) -> A; } trait foo { fn bar>(&self, c: C) -> B; } diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs index 8c597552d75aa..3f273b56efd6c 100644 --- a/src/test/run-pass/issue-2312.rs +++ b/src/test/run-pass/issue-2312.rs @@ -10,7 +10,7 @@ // Testing that the B's are resolved -trait clam { } +trait clam { fn get(self) -> A; } struct foo(int); diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index b8136323df664..a5a05283f80fd 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -10,9 +10,9 @@ // except according to those terms. extern crate collections; -use std::collections::RingBuf; +use std::collections::VecDeque; pub fn main() { - let mut q = RingBuf::new(); + let mut q = VecDeque::new(); q.push_front(10); } diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs index 2608c89d15567..c005699ce30b4 100644 --- a/src/test/run-pass/issue-2611-3.rs +++ b/src/test/run-pass/issue-2611-3.rs @@ -12,7 +12,7 @@ // than the traits require. trait A { - fn b(x: C) -> C; + fn b(&self, x: C) -> C; } struct E { @@ -20,7 +20,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { panic!() } + fn b(&self, _x: F) -> F { panic!() } //~^ ERROR in method `b`, type parameter 0 has 1 bound, but } diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index 7ca439a1a19df..a7b53db6b0553 100644 --- a/src/test/run-pass/issue-2734.rs +++ b/src/test/run-pass/issue-2734.rs @@ -11,7 +11,9 @@ #![allow(unknown_features)] #![feature(box_syntax)] -trait hax { } +trait hax { + fn dummy(&self) { } +} impl hax for A { } fn perform_hax(x: Box) -> Box { diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs index 962359537bf29..1594b94879cee 100644 --- a/src/test/run-pass/issue-2735.rs +++ b/src/test/run-pass/issue-2735.rs @@ -11,7 +11,9 @@ #![allow(unknown_features)] #![feature(box_syntax)] -trait hax { } +trait hax { + fn dummy(&self) { } +} impl hax for A { } fn perform_hax(x: Box) -> Box { diff --git a/src/test/run-pass/issue-4107.rs b/src/test/run-pass/issue-4107.rs index 2ed662e9f2d60..d660f300ada99 100644 --- a/src/test/run-pass/issue-4107.rs +++ b/src/test/run-pass/issue-4107.rs @@ -9,14 +9,14 @@ // except according to those terms. pub fn main() { - let _id: &Mat2 = &Matrix::identity(); + let _id: &Mat2 = &Matrix::identity(1.0); } -pub trait Index { } +pub trait Index { fn get(&self, Index) -> Result { panic!() } } pub trait Dimensional: Index { } -pub struct Mat2 { x: () } -pub struct Vec2 { x: () } +pub struct Mat2 { x: T } +pub struct Vec2 { x: T } impl Dimensional> for Mat2 { } impl Index> for Mat2 { } @@ -25,9 +25,9 @@ impl Dimensional for Vec2 { } impl Index for Vec2 { } pub trait Matrix: Dimensional { - fn identity() -> Self; + fn identity(t:T) -> Self; } impl Matrix> for Mat2 { - fn identity() -> Mat2 { Mat2{ x: () } } + fn identity(t:T) -> Mat2 { Mat2{ x: t } } } diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs index bb79cd4d04667..a6f3771bf62b4 100644 --- a/src/test/run-pass/issue-5192.rs +++ b/src/test/run-pass/issue-5192.rs @@ -12,6 +12,7 @@ #![feature(box_syntax)] pub trait EventLoop { + fn dummy(&self) { } } pub struct UvEventLoop { diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs index fd39bcc6b6121..59bca87bed0b6 100644 --- a/src/test/run-pass/issue-5708.rs +++ b/src/test/run-pass/issue-5708.rs @@ -48,7 +48,9 @@ pub fn main() { // minimal -pub trait MyTrait { } +pub trait MyTrait { + fn dummy(&self, t: T) -> T { panic!() } +} pub struct MyContainer<'a, T> { foos: Vec<&'a (MyTrait+'a)> , diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs index d96862b588f9d..1746a6281dc26 100644 --- a/src/test/run-pass/issue-6128.rs +++ b/src/test/run-pass/issue-6128.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; trait Graph { fn f(&self, Edge); + fn g(&self, Node); } @@ -24,6 +25,9 @@ impl Graph for HashMap { fn f(&self, _e: E) { panic!(); } + fn g(&self, _e: int) { + panic!(); + } } pub fn main() { diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs index 1d8fe8bfce82c..6e608d34bd578 100644 --- a/src/test/run-pass/issue-6318.rs +++ b/src/test/run-pass/issue-6318.rs @@ -15,7 +15,9 @@ pub enum Thing { A(Box) } -pub trait Foo {} +pub trait Foo { + fn dummy(&self) { } +} pub struct Struct; diff --git a/src/test/run-pass/issue-7575.rs b/src/test/run-pass/issue-7575.rs index 225213db6a425..77cfc7f0cf607 100644 --- a/src/test/run-pass/issue-7575.rs +++ b/src/test/run-pass/issue-7575.rs @@ -10,6 +10,7 @@ trait Foo { fn new() -> bool { false } + fn dummy(&self) { } } trait Bar { diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs index b6dfbb1ca42ad..736860947f23c 100644 --- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs @@ -19,7 +19,10 @@ pub fn main() {} -trait A {} +trait A { + fn dummy(&self) { } +} + impl A for T {} fn owned2(a: Box) { a as Box; } diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs index 86948ebcb91e0..3eb593708bee8 100644 --- a/src/test/run-pass/issue-7911.rs +++ b/src/test/run-pass/issue-7911.rs @@ -14,7 +14,9 @@ // with different mutability in macro in two methods #![allow(unused_variable)] // unused foobar_immut + foobar_mut -trait FooBar {} +trait FooBar { + fn dummy(&self) { } +} struct Bar(i32); struct Foo { bar: Bar } diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs index 377b9ce262c73..7bc8dbe616ff3 100644 --- a/src/test/run-pass/issue-8248.rs +++ b/src/test/run-pass/issue-8248.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +trait A { + fn dummy(&self) { } +} struct B; impl A for B {} diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs index 44f07def531bc..83c9e9bf45053 100644 --- a/src/test/run-pass/issue-8249.rs +++ b/src/test/run-pass/issue-8249.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +trait A { + fn dummy(&self) { } +} struct B; impl A for B {} diff --git a/src/test/run-pass/issue-9719.rs b/src/test/run-pass/issue-9719.rs index 8fc86eb49e769..aa1e65efaa41e 100644 --- a/src/test/run-pass/issue-9719.rs +++ b/src/test/run-pass/issue-9719.rs @@ -13,7 +13,9 @@ mod a { A(T), } - pub trait X {} + pub trait X { + fn dummy(&self) { } + } impl X for int {} pub struct Z<'a>(Enum<&'a (X+'a)>); @@ -21,7 +23,9 @@ mod a { } mod b { - trait X {} + trait X { + fn dummy(&self) { } + } impl X for int {} struct Y<'a>{ x:Option<&'a (X+'a)>, diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs index 2194453aac29a..f180ffcd4e823 100644 --- a/src/test/run-pass/lint-cstack.rs +++ b/src/test/run-pass/lint-cstack.rs @@ -15,7 +15,7 @@ extern { } trait A { - fn foo() { + fn foo(&self) { unsafe { rust_get_test_int(); } diff --git a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs index 25ce0d774ebc1..cec9753a2feca 100644 --- a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs +++ b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs @@ -13,7 +13,11 @@ #![allow(dead_code)] -struct Cursor<'a>; +use std::marker; + +struct Cursor<'a> { + m: marker::PhantomData<&'a ()> +} trait CursorNavigator { fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; @@ -28,7 +32,7 @@ impl CursorNavigator for SimpleNavigator { } fn main() { - let mut c = Cursor; + let mut c = Cursor { m: marker::PhantomData }; let n = SimpleNavigator; n.init_cursor(&mut c); } diff --git a/src/test/run-pass/method-recursive-blanket-impl.rs b/src/test/run-pass/method-recursive-blanket-impl.rs index 338bd89ab5cb1..15eb2ae2e4b49 100644 --- a/src/test/run-pass/method-recursive-blanket-impl.rs +++ b/src/test/run-pass/method-recursive-blanket-impl.rs @@ -17,16 +17,16 @@ use std::marker::Sized; // Note: this must be generic for the problem to show up trait Foo { - fn foo(&self); + fn foo(&self, a: A); } impl Foo for [u8] { - fn foo(&self) {} + fn foo(&self, a: u8) {} } impl<'a, A, T> Foo for &'a T where T: Foo { - fn foo(&self) { - Foo::foo(*self) + fn foo(&self, a: A) { + Foo::foo(*self, a) } } diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs index eb17aa78bd9a8..1164ef1a3c98e 100644 --- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs +++ b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs @@ -8,8 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::MarkerTrait; -trait Serializer { +trait Serializer : MarkerTrait { } trait Serializable { diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs index be2b309b8217f..d50f2efe0e7b4 100644 --- a/src/test/run-pass/overloaded-autoderef-vtable.rs +++ b/src/test/run-pass/overloaded-autoderef-vtable.rs @@ -11,7 +11,8 @@ use std::ops::Deref; struct DerefWithHelper { - helper: H + helper: H, + value: T } trait Helper { @@ -39,6 +40,7 @@ impl Foo { } pub fn main() { - let x: DerefWithHelper, Foo> = DerefWithHelper { helper: Some(Foo {x: 5}) }; + let x: DerefWithHelper, Foo> = + DerefWithHelper { helper: Some(Foo {x: 5}), value: Foo { x: 2 } }; assert!(x.foo() == 5); } diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs index 2838909c1be62..2ef9e08134cf7 100644 --- a/src/test/run-pass/overloaded-calls-param-vtables.rs +++ b/src/test/run-pass/overloaded-calls-param-vtables.rs @@ -12,10 +12,11 @@ #![feature(unboxed_closures)] +use std::marker::PhantomData; use std::ops::Fn; use std::ops::Add; -struct G; +struct G(PhantomData); impl<'a, A: Add> Fn<(A,)> for G { type Output = i32; @@ -27,5 +28,5 @@ impl<'a, A: Add> Fn<(A,)> for G { fn main() { // ICE trigger - G(1_i32); + (G(PhantomData))(1_i32); } diff --git a/src/test/run-pass/parameterized-trait-with-bounds.rs b/src/test/run-pass/parameterized-trait-with-bounds.rs index 840e58848a742..061c9168955a4 100644 --- a/src/test/run-pass/parameterized-trait-with-bounds.rs +++ b/src/test/run-pass/parameterized-trait-with-bounds.rs @@ -11,12 +11,12 @@ #![allow(dead_code)] -trait A {} -trait B {} -trait C<'a, U> {} +trait A { fn get(self) -> T; } +trait B { fn get(self) -> (T,U); } +trait C<'a, U> { fn get(self) -> &'a U; } mod foo { - pub trait D<'a, T> {} + pub trait D<'a, T> { fn get(self) -> &'a T; } } fn foo1(_: &(A + Send)) {} diff --git a/src/test/run-pass/privacy-ns.rs b/src/test/run-pass/privacy-ns.rs index f3380352f5fa9..e9b8e694d6060 100644 --- a/src/test/run-pass/privacy-ns.rs +++ b/src/test/run-pass/privacy-ns.rs @@ -19,6 +19,7 @@ // public type, private value pub mod foo1 { pub trait Bar { + fn dummy(&self) { } } pub struct Baz; @@ -50,6 +51,7 @@ fn test_glob1() { // private type, public value pub mod foo2 { trait Bar { + fn dummy(&self) { } } pub struct Baz; @@ -81,6 +83,7 @@ fn test_glob2() { // public type, public value pub mod foo3 { pub trait Bar { + fn dummy(&self) { } } pub struct Baz; diff --git a/src/test/run-pass/regions-assoc-type-static-bound.rs b/src/test/run-pass/regions-assoc-type-static-bound.rs index 6b629a9035db2..80ae371e5091e 100644 --- a/src/test/run-pass/regions-assoc-type-static-bound.rs +++ b/src/test/run-pass/regions-assoc-type-static-bound.rs @@ -11,7 +11,10 @@ // Test that the compiler considers the 'static bound declared in the // trait. Issue #20890. -trait Foo { type Value: 'static; } +trait Foo { + type Value: 'static; + fn dummy(&self) { } +} fn require_static() {} diff --git a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs index 0a95a89d57c32..a06e0f6da785a 100644 --- a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs +++ b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs @@ -12,7 +12,9 @@ #![feature(issue_5723_bootstrap)] -trait Foo { } +trait Foo { + fn dummy(&self) { } +} fn foo<'a, 'b, 'c:'a+'b, 'd>() { } diff --git a/src/test/run-pass/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions-bound-lists-feature-gate.rs index c5baecf7272fa..996583dc6de93 100644 --- a/src/test/run-pass/regions-bound-lists-feature-gate.rs +++ b/src/test/run-pass/regions-bound-lists-feature-gate.rs @@ -12,8 +12,9 @@ #![feature(issue_5723_bootstrap)] - -trait Foo { } +trait Foo { + fn dummy(&self) { } +} fn foo<'a>(x: Box) { } diff --git a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs index 978383c244780..bdc0d41c94e82 100644 --- a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs +++ b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs @@ -14,6 +14,8 @@ // lifetime parameters must be early bound in the type of the // associated item. +use std::marker; + pub enum Value<'v> { A(&'v str), B, @@ -23,7 +25,9 @@ pub trait Decoder<'v> { fn read(&mut self) -> Value<'v>; } -pub trait Decodable<'v, D: Decoder<'v>> { +pub trait Decodable<'v, D: Decoder<'v>> + : marker::PhantomFn<(), &'v int> +{ fn decode(d: &mut D) -> Self; } diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs index 6fcfaf58a023b..3f434a4838d42 100644 --- a/src/test/run-pass/regions-early-bound-trait-param.rs +++ b/src/test/run-pass/regions-early-bound-trait-param.rs @@ -53,11 +53,11 @@ fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> int { x.f.short() } -trait MakerTrait<'o> { +trait MakerTrait { fn mk() -> Self; } -fn make_val<'p, T:MakerTrait<'p>>() -> T { +fn make_val() -> T { MakerTrait::mk() } @@ -80,7 +80,7 @@ impl<'s> Trait<'s> for (int,int) { } } -impl<'t> MakerTrait<'t> for Box+'static> { +impl<'t> MakerTrait for Box+'static> { fn mk() -> Box+'static> { box() (4,5) as Box } } diff --git a/src/test/run-pass/regions-issue-21422.rs b/src/test/run-pass/regions-issue-21422.rs new file mode 100644 index 0000000000000..c59bf15afc3b0 --- /dev/null +++ b/src/test/run-pass/regions-issue-21422.rs @@ -0,0 +1,25 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #21422, which was related to failing to +// add inference constraints that the operands of a binary operator +// should outlive the binary operation itself. + +pub struct P<'a> { + _ptr: *const &'a u8, +} + +impl <'a> PartialEq for P<'a> { + fn eq(&self, other: &P<'a>) -> bool { + (self as *const _) == (other as *const _) + } +} + +fn main() {} diff --git a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs index d3464f01203ac..5964ac65d5f6e 100644 --- a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs +++ b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs @@ -10,7 +10,9 @@ #![feature(unsafe_destructor)] -pub struct Foo; +use std::marker; + +pub struct Foo(marker::PhantomData); impl Iterator for Foo { type Item = T; diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs index a35ab1bfc0ce6..80c478afa644f 100644 --- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs +++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs @@ -12,7 +12,9 @@ // should not upset the variance inference for actual occurrences of // that lifetime in type expressions. -pub trait HasLife<'a> { } +pub trait HasLife<'a> { + fn dummy(&'a self) { } // just to induce a variance on 'a +} trait UseLife01 { fn refs<'a, H: HasLife<'a>>(&'a self) -> H; @@ -23,7 +25,11 @@ trait UseLife02 { } -pub trait HasType { } +pub trait HasType +{ + fn dummy(&self, t: T) -> T { panic!() } +} + trait UseLife03 { fn refs<'a, H: HasType<&'a T>>(&'a self) -> H; diff --git a/src/test/run-pass/regions-refcell.rs b/src/test/run-pass/regions-refcell.rs index 10c9aef7c3b1e..a224017780e2d 100644 --- a/src/test/run-pass/regions-refcell.rs +++ b/src/test/run-pass/regions-refcell.rs @@ -19,7 +19,7 @@ use std::cell::RefCell; #[cfg(cannot_use_this_yet)] fn foo<'a>(map: RefCell>) { let one = [1_usize]; - assert_eq!(map.borrow().get("one"), Some(&one[])); + assert_eq!(map.borrow().get("one"), Some(&one[..])); } #[cfg(cannot_use_this_yet_either)] @@ -45,9 +45,9 @@ fn main() { let one = [1u8]; let two = [2u8]; let mut map = HashMap::new(); - map.insert("zero", &zer[]); - map.insert("one", &one[]); - map.insert("two", &two[]); + map.insert("zero", &zer[..]); + map.insert("one", &one[..]); + map.insert("two", &two[..]); let map = RefCell::new(map); foo(map); } diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs index a21b5aa1dab6c..abe6ffe7d4cca 100644 --- a/src/test/run-pass/rename-directory.rs +++ b/src/test/run-pass/rename-directory.rs @@ -31,12 +31,12 @@ fn rename_directory() { let test_file = &old_path.join("temp.txt"); /* Write the temp input file */ - let fromp = CString::from_slice(test_file.as_vec()); - let modebuf = CString::from_slice(b"w+b"); + let fromp = CString::new(test_file.as_vec()).unwrap(); + let modebuf = CString::new(b"w+b").unwrap(); let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr()); assert!((ostream as uint != 0_usize)); let s = "hello".to_string(); - let buf = CString::from_slice(b"hello"); + let buf = CString::new(b"hello").unwrap(); let write_len = libc::fwrite(buf.as_ptr() as *mut _, 1_usize as libc::size_t, (s.len() + 1_usize) as libc::size_t, diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs index 40a4dc52a70b3..af2b2de8ab8ba 100644 --- a/src/test/run-pass/self-impl.rs +++ b/src/test/run-pass/self-impl.rs @@ -29,6 +29,7 @@ pub struct Baz { trait Bar { fn bar(x: Self, y: &Self, z: Box) -> Self; + fn dummy(&self, x: X) { } } impl Bar for Box> { diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs index c58654670d1a3..33e4fa85bcb81 100644 --- a/src/test/run-pass/send_str_hashmap.rs +++ b/src/test/run-pass/send_str_hashmap.rs @@ -13,7 +13,7 @@ extern crate collections; use std::collections::HashMap; use std::borrow::{Cow, IntoCow}; -type SendStr = Cow<'static, String, str>; +type SendStr = Cow<'static, str>; pub fn main() { let mut map: HashMap = HashMap::new(); diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index 438724a2b06bf..3390369242d13 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -13,7 +13,7 @@ extern crate collections; use self::collections::BTreeMap; use std::borrow::{Cow, IntoCow}; -type SendStr = Cow<'static, String, str>; +type SendStr = Cow<'static, str>; pub fn main() { let mut map: BTreeMap = BTreeMap::new(); diff --git a/src/test/run-pass/simple-match-generic-tag.rs b/src/test/run-pass/simple-match-generic-tag.rs index 7ed8cb434caf5..2217dddbd21f0 100644 --- a/src/test/run-pass/simple-match-generic-tag.rs +++ b/src/test/run-pass/simple-match-generic-tag.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - - -enum opt { none, } +enum opt { none, some(T) } pub fn main() { let x = opt::none::; - match x { opt::none:: => { println!("hello world"); } } + match x { + opt::none:: => { println!("hello world"); } + opt::some(_) => { } + } } diff --git a/src/test/run-pass/syntax-trait-polarity.rs b/src/test/run-pass/syntax-trait-polarity.rs index 3344844d49ff7..340ad2a531a73 100644 --- a/src/test/run-pass/syntax-trait-polarity.rs +++ b/src/test/run-pass/syntax-trait-polarity.rs @@ -10,17 +10,17 @@ #![feature(optin_builtin_traits)] -use std::marker::Send; +use std::marker::{MarkerTrait, Send}; struct TestType; impl TestType {} -trait TestTrait {} +trait TestTrait : MarkerTrait {} impl !Send for TestType {} -struct TestType2; +struct TestType2(T); impl TestType2 {} diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs index b5ae259bc630e..76c62a83e758c 100644 --- a/src/test/run-pass/trailing-comma.rs +++ b/src/test/run-pass/trailing-comma.rs @@ -12,7 +12,7 @@ fn f(_: T,) {} -struct Foo; +struct Foo(T); struct Bar; @@ -34,7 +34,7 @@ pub fn main() { let [_, _, .., _,] = [1, 1, 1, 1,]; let [_, _, _.., _,] = [1, 1, 1, 1,]; - let x: Foo = Foo::; + let x: Foo = Foo::(1); Bar::f(0,); Bar.g(0,); diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs index d03496403ad2a..ed25bf8b02e88 100644 --- a/src/test/run-pass/trait-bounds-basic.rs +++ b/src/test/run-pass/trait-bounds-basic.rs @@ -9,7 +9,7 @@ // except according to those terms. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { } fn b(_x: Box) { diff --git a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs index e3234f037547b..976120908b27a 100644 --- a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs +++ b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait U {} -trait T {} +trait U : ::std::marker::MarkerTrait {} +trait T { fn get(self) -> X; } -trait S2 { +trait S2 : ::std::marker::MarkerTrait { fn m(x: Box+'static>) {} } diff --git a/src/test/run-pass/trait-bounds-recursion.rs b/src/test/run-pass/trait-bounds-recursion.rs index 49f8999cd45e4..7135dad7d190c 100644 --- a/src/test/run-pass/trait-bounds-recursion.rs +++ b/src/test/run-pass/trait-bounds-recursion.rs @@ -10,17 +10,17 @@ trait I { fn i(&self) -> Self; } -trait A { +trait A : ::std::marker::MarkerTrait { fn id(x:T) -> T { x.i() } } -trait J { fn j(&self) -> Self; } +trait J { fn j(&self) -> T; } -trait B> { +trait B> : ::std::marker::MarkerTrait { fn id(x:T) -> T { x.j() } } -trait C { +trait C : ::std::marker::MarkerTrait { fn id>(x:T) -> T { x.j() } } diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs index 3efe2507470d9..383849ca51267 100644 --- a/src/test/run-pass/trait-default-method-bound-subst4.rs +++ b/src/test/run-pass/trait-default-method-bound-subst4.rs @@ -11,6 +11,7 @@ trait A { fn g(&self, x: uint) -> uint { x } + fn h(&self, x: T) { } } impl A for int { } diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs index 16ef315c206d5..325fba8a0ee42 100644 --- a/src/test/run-pass/trait-impl.rs +++ b/src/test/run-pass/trait-impl.rs @@ -16,7 +16,9 @@ use traitimpl::Bar; static mut COUNT: uint = 1; -trait T {} +trait T { + fn t(&self) {} +} impl<'a> T+'a { fn foo(&self) { diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index 1e6e7227a067c..f89eea46090d0 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -14,8 +14,7 @@ use std::cmp::{PartialEq, PartialOrd}; use std::num::NumCast; -pub trait TypeExt {} - +pub trait TypeExt : ::std::marker::MarkerTrait { } impl TypeExt for u8 {} impl TypeExt for u16 {} diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs index 3b454aad03e48..8f3b325a513fe 100644 --- a/src/test/run-pass/trait-inheritance-static2.rs +++ b/src/test/run-pass/trait-inheritance-static2.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait MyEq { } +pub trait MyEq : ::std::marker::MarkerTrait { } -pub trait MyNum { +pub trait MyNum : ::std::marker::MarkerTrait { fn from_int(int) -> Self; } diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs index 76352c799a0f2..6f89490716f08 100644 --- a/src/test/run-pass/trait-object-generics.rs +++ b/src/test/run-pass/trait-object-generics.rs @@ -13,11 +13,14 @@ #![allow(unknown_features)] #![feature(box_syntax)] +use std::marker; + pub trait Trait2 { - fn doit(&self); + fn doit(&self) -> A; } pub struct Impl { + m1: marker::PhantomData<(A1,A2,A3)>, /* * With A2 we get the ICE: * task failed at 'index out of bounds: the len is 1 but the index is 1', @@ -28,13 +31,13 @@ pub struct Impl { impl Impl { pub fn step(&self) { - self.t.doit() + self.t.doit(); } } // test for #8601 -enum Type { Constant } +enum Type { Constant(T) } trait Trait { fn method(&self,Type<(K,V)>) -> int; @@ -46,5 +49,5 @@ impl Trait for () { pub fn main() { let a = box() () as Box>; - assert_eq!(a.method(Type::Constant), 0); + assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0); } diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs index a8cea24db0c0c..10439d5c86aa3 100644 --- a/src/test/run-pass/trait-static-method-overwriting.rs +++ b/src/test/run-pass/trait-static-method-overwriting.rs @@ -10,7 +10,7 @@ // except according to those terms. mod base { - pub trait HasNew { + pub trait HasNew { fn new() -> Self; } @@ -18,7 +18,7 @@ mod base { dummy: (), } - impl ::base::HasNew for Foo { + impl ::base::HasNew for Foo { fn new() -> Foo { println!("Foo"); Foo { dummy: () } @@ -29,7 +29,7 @@ mod base { dummy: (), } - impl ::base::HasNew for Bar { + impl ::base::HasNew for Bar { fn new() -> Bar { println!("Bar"); Bar { dummy: () } @@ -38,6 +38,6 @@ mod base { } pub fn main() { - let _f: base::Foo = base::HasNew::::new(); - let _b: base::Bar = base::HasNew::::new(); + let _f: base::Foo = base::HasNew::new(); + let _b: base::Bar = base::HasNew::new(); } diff --git a/src/test/run-pass/traits-issue-22019.rs b/src/test/run-pass/traits-issue-22019.rs index 5d3195e193708..7e0f60d55a827 100644 --- a/src/test/run-pass/traits-issue-22019.rs +++ b/src/test/run-pass/traits-issue-22019.rs @@ -23,18 +23,18 @@ pub type Node<'a> = &'a CFGNode; pub trait GraphWalk<'c, N> { /// Returns all the nodes in this graph. - fn nodes(&'c self) where [N]:ToOwned>; + fn nodes(&'c self) where [N]:ToOwned>; } impl<'g> GraphWalk<'g, Node<'g>> for u32 { - fn nodes(&'g self) where [Node<'g>]:ToOwned>> + fn nodes(&'g self) where [Node<'g>]:ToOwned>> { loop { } } } impl<'h> GraphWalk<'h, Node<'h>> for u64 { - fn nodes(&'h self) where [Node<'h>]:ToOwned>> + fn nodes(&'h self) where [Node<'h>]:ToOwned>> { loop { } } } diff --git a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs index 1f9b821178c46..2d1ba7f39b27b 100644 --- a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs +++ b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs @@ -10,7 +10,7 @@ #![feature(core,unboxed_closures)] -use std::marker::CovariantType; +use std::marker::PhantomData; // Test that we are able to infer a suitable kind for a "recursive" // closure. As far as I can tell, coding up a recursive closure @@ -20,12 +20,12 @@ use std::marker::CovariantType; struct YCombinator { func: F, - marker: CovariantType<(A,R)>, + marker: PhantomData<(A,R)>, } impl YCombinator { fn new(f: F) -> YCombinator { - YCombinator { func: f, marker: CovariantType } + YCombinator { func: f, marker: PhantomData } } } diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs index cec523a06712e..f01a56142e073 100644 --- a/src/test/run-pass/unique-object-move.rs +++ b/src/test/run-pass/unique-object-move.rs @@ -13,7 +13,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -pub trait EventLoop { } +pub trait EventLoop { fn foo(&self) {} } pub struct UvEventLoop { uvio: int diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs index e6dd8d46952eb..ae175d27b0a4e 100644 --- a/src/test/run-pass/unsized.rs +++ b/src/test/run-pass/unsized.rs @@ -12,17 +12,19 @@ // Test syntax checks for `?Sized` syntax. -trait T1 {} -pub trait T2 {} -trait T3 : T2 {} -trait T4 {} -trait T5 {} -trait T6 {} -trait T7 {} -trait T8 {} -trait T9 {} -struct S1; -enum E {} +use std::marker::{PhantomData, PhantomFn}; + +trait T1 : PhantomFn { } +pub trait T2 : PhantomFn { } +trait T3 : T2 + PhantomFn { } +trait T4 : PhantomFn<(Self,X)> {} +trait T5 : PhantomFn<(Self,X,Y)> {} +trait T6 : PhantomFn<(Self,X,Y)> {} +trait T7 : PhantomFn<(Self,X,Y)> {} +trait T8 : PhantomFn<(Self,X)> {} +trait T9 : PhantomFn<(Self,X)> {} +struct S1(PhantomData); +enum E { E1(PhantomData) } impl T1 for S1 {} fn f() {} type TT = T; diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs index 285100dd7197c..10b2f2fb70924 100644 --- a/src/test/run-pass/unsized2.rs +++ b/src/test/run-pass/unsized2.rs @@ -15,6 +15,8 @@ // Test sized-ness checking in substitution. +use std::marker; + // Unbounded. fn f1(x: &X) { f1::(x); @@ -25,7 +27,7 @@ fn f2(x: &X) { } // Bounded. -trait T {} +trait T { fn dummy(&self) { } } fn f3(x: &X) { f3::(x); } @@ -66,20 +68,24 @@ fn f7(x: &X) { } trait T4 { - fn m1(x: &T4); - fn m2(x: &T5); + fn dummy(&self) { } + fn m1(x: &T4, y: X); + fn m2(x: &T5, y: X); } trait T5 { + fn dummy(&self) { } // not an error (for now) fn m1(x: &T4); fn m2(x: &T5); } trait T6 { + fn dummy(&self) { } fn m1(x: &T4); fn m2(x: &T5); } trait T7 { + fn dummy(&self) { } // not an error (for now) fn m1(x: &T4); fn m2(x: &T5); diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index a729fedb27157..5a476ed9ee2f8 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -29,11 +29,11 @@ pub fn main() { unsafe { // Call with just the named parameter - let c = CString::from_slice(b"Hello World\n"); + let c = CString::new(b"Hello World\n").unwrap(); check("Hello World\n", |s| sprintf(s, c.as_ptr())); // Call with variable number of arguments - let c = CString::from_slice(b"%d %f %c %s\n"); + let c = CString::new(b"%d %f %c %s\n").unwrap(); check("42 42.500000 a %d %f %c %s\n\n", |s| { sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); }); @@ -44,11 +44,11 @@ pub fn main() { // A function that takes a function pointer unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) { // Call with just the named parameter - let c = CString::from_slice(b"Hello World\n"); + let c = CString::new(b"Hello World\n").unwrap(); check("Hello World\n", |s| sprintf(s, c.as_ptr())); // Call with variable number of arguments - let c = CString::from_slice(b"%d %f %c %s\n"); + let c = CString::new(b"%d %f %c %s\n").unwrap(); check("42 42.500000 a %d %f %c %s\n\n", |s| { sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); }); diff --git a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs new file mode 100644 index 0000000000000..948d68e0ccd7d --- /dev/null +++ b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs @@ -0,0 +1,34 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Elaborated version of the opening example from RFC 738. This failed +// to compile before variance because invariance of `Option` prevented +// us from approximating the lifetimes of `field1` and `field2` to a +// common intersection. + +#![allow(dead_code)] + +struct List<'l> { + field1: &'l i32, + field2: Option<&'l i32>, +} + +fn foo(field1: &i32, field2: Option<&i32>) -> i32 { + let list = List { field1: field1, field2: field2 }; + *list.field1 + list.field2.cloned().unwrap_or(0) +} + +fn main() { + let x = 22; + let y = Some(3); + let z = None; + assert_eq!(foo(&x, y.as_ref()), 25); + assert_eq!(foo(&x, z.as_ref()), 22); +} diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs new file mode 100644 index 0000000000000..10441bee3cb9f --- /dev/null +++ b/src/test/run-pass/variance-trait-matching.rs @@ -0,0 +1,49 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +// Get is covariant in T +trait Get { + fn get(&self) -> T; +} + +struct Cloner { + t: T +} + +impl Get for Cloner { + fn get(&self) -> T { + self.t.clone() + } +} + +fn get<'a, G>(get: &G) -> i32 + where G : Get<&'a i32> +{ + // This call only type checks if we can use `G : Get<&'a i32>` as + // evidence that `G : Get<&'b i32>` where `'a : 'b`. + pick(get, &22) +} + +fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32 + where G : Get<&'b i32> +{ + let v = *get.get(); + if v % 2 != 0 { v } else { *if_odd } +} + +fn main() { + let x = Cloner { t: &23 }; + let y = get(&x); + assert_eq!(y, 23); +} + + diff --git a/src/test/run-pass/variance-vec-covariant.rs b/src/test/run-pass/variance-vec-covariant.rs new file mode 100644 index 0000000000000..caec6df5a4d81 --- /dev/null +++ b/src/test/run-pass/variance-vec-covariant.rs @@ -0,0 +1,28 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that vec is now covariant in its argument type. + +#![allow(dead_code)] + +fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 { + bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b +} + +fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> { + v1.get(0).cloned().or_else(|| v2.get(0).cloned()) +} + +fn main() { + let x = 22; + let y = 44; + assert_eq!(foo(vec![&x], vec![&y]), 22); + assert_eq!(foo(vec![&y], vec![&x]), 44); +} diff --git a/src/test/run-pass/visible-private-types-feature-gate.rs b/src/test/run-pass/visible-private-types-feature-gate.rs index 9518671b4799d..46e93b25697bb 100644 --- a/src/test/run-pass/visible-private-types-feature-gate.rs +++ b/src/test/run-pass/visible-private-types-feature-gate.rs @@ -10,7 +10,7 @@ #![feature(visible_private_types)] -trait Foo {} +trait Foo { fn dummy(&self) { } } pub trait Bar : Foo {} diff --git a/src/test/run-pass/where-clause-bounds-inconsistency.rs b/src/test/run-pass/where-clause-bounds-inconsistency.rs index a1a61127f68e0..3374f47ed5f80 100644 --- a/src/test/run-pass/where-clause-bounds-inconsistency.rs +++ b/src/test/run-pass/where-clause-bounds-inconsistency.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Bound {} +trait Bound { + fn dummy(&self) { } +} trait Trait { fn a(&self, T) where T: Bound; diff --git a/src/test/run-pass/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clause-early-bound-lifetimes.rs index cade99b83a2fe..4a149d4d3df44 100644 --- a/src/test/run-pass/where-clause-early-bound-lifetimes.rs +++ b/src/test/run-pass/where-clause-early-bound-lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait TheTrait { } +trait TheTrait { fn dummy(&self) { } } impl TheTrait for &'static int { } diff --git a/src/test/run-pass/where-clause-method-substituion.rs b/src/test/run-pass/where-clause-method-substituion.rs index b391df8500bb7..ecc210ea579db 100644 --- a/src/test/run-pass/where-clause-method-substituion.rs +++ b/src/test/run-pass/where-clause-method-substituion.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { fn dummy(&self, arg: T) { } } trait Bar { fn method(&self) where A: Foo; @@ -19,7 +19,7 @@ struct X; impl Foo for X {} -impl Bar for int { +impl Bar for i32 { fn method(&self) where X: Foo { } } diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs index 5d426793c2e36..1fd223b0dd3f6 100644 --- a/src/test/run-pass/where-for-self.rs +++ b/src/test/run-pass/where-for-self.rs @@ -11,13 +11,19 @@ // Test that we can quantify lifetimes outside a constraint (i.e., including // the self type) in a where clause. +use std::marker::PhantomFn; + static mut COUNT: u32 = 1; -trait Bar<'a> { +trait Bar<'a> + : PhantomFn<&'a ()> +{ fn bar(&self); } -trait Baz<'a> { +trait Baz<'a> + : PhantomFn<&'a ()> +{ fn baz(&self); }