From 6a585375a01b7c6b52ad93f764220bcb18027ef6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 29 May 2014 18:50:12 -0700 Subject: [PATCH] std: Recreate a `collections` module As with the previous commit with `librand`, this commit shuffles around some `collections` code. The new state of the world is similar to that of librand: * The libcollections crate now only depends on libcore and liballoc. * The standard library has a new module, `std::collections`. All functionality of libcollections is reexported through this module. I would like to stress that this change is purely cosmetic. There are very few alterations to these primitives. There are a number of notable points about the new organization: * std::{str, slice, string, vec} all moved to libcollections. There is no reason that these primitives shouldn't be necessarily usable in a freestanding context that has allocation. These are all reexported in their usual places in the standard library. * The `hashmap`, and transitively the `lru_cache`, modules no longer reside in `libcollections`, but rather in libstd. The reason for this is because the `HashMap::new` contructor requires access to the OSRng for initially seeding the hash map. Beyond this requirement, there is no reason that the hashmap could not move to libcollections. I do, however, have a plan to move the hash map to the collections module. The `HashMap::new` function could be altered to require that the `H` hasher parameter ascribe to the `Default` trait, allowing the entire `hashmap` module to live in libcollections. The key idea would be that the default hasher would be different in libstd. Something along the lines of: // src/libstd/collections/mod.rs pub type HashMap = core_collections::HashMap; This is not possible today because you cannot invoke static methods through type aliases. If we modified the compiler, however, to allow invocation of static methods through type aliases, then this type definition would essentially be switching the default hasher from `SipHasher` in libcollections to a libstd-defined `RandomizedSipHasher` type. This type's `Default` implementation would randomly seed the `SipHasher` instance, and otherwise perform the same as `SipHasher`. This future state doesn't seem incredibly far off, but until that time comes, the hashmap module will live in libstd to not compromise on functionality. * In preparation for the hashmap moving to libcollections, the `hash` module has moved from libstd to libcollections. A previously snapshotted commit enables a distinct `Writer` trait to live in the `hash` module which `Hash` implementations are now parameterized over. Due to using a custom trait, the `SipHasher` implementation has lost its specialized methods for writing integers. These can be re-added backwards-compatibly in the future via default methods if necessary, but the FNV hashing should satisfy much of the need for speedier hashing. A list of breaking changes: * HashMap::{get, get_mut} no longer fails with the key formatted into the error message with `{:?}`, instead, a generic message is printed. With backtraces, it should still be not-too-hard to track down errors. * The HashMap, HashSet, and LruCache types are now available through std::collections instead of the collections crate. * Manual implementations of hash should be parameterized over `hash::Writer` instead of just `Writer`. [breaking-change] --- mk/crates.mk | 23 ++-- src/libcollections/bitv.rs | 17 +-- src/libcollections/btree.rs | 9 +- src/libcollections/deque.rs | 2 +- src/libcollections/dlist.rs | 9 +- src/libcollections/enum_set.rs | 4 +- src/{libstd => libcollections}/hash/mod.rs | 43 +++----- src/{libstd => libcollections}/hash/sip.rs | 101 ++---------------- src/libcollections/lib.rs | 43 ++++++-- src/libcollections/macros.rs | 22 ++++ src/libcollections/priority_queue.rs | 10 +- src/libcollections/ringbuf.rs | 12 ++- src/{libstd => libcollections}/slice.rs | 30 +++--- src/libcollections/smallintmap.rs | 12 ++- src/{libstd => libcollections}/str.rs | 65 ++++++----- src/{libstd => libcollections}/string.rs | 48 ++++----- src/libcollections/treemap.rs | 18 ++-- src/libcollections/trie.rs | 16 +-- src/{libstd => libcollections}/unicode.rs | 4 +- src/{libstd => libcollections}/vec.rs | 53 +++++---- src/libcore/cell.rs | 6 +- src/libcore/fmt/mod.rs | 6 -- src/libcore/macros.rs | 31 ++++++ .../collections}/hashmap.rs | 101 ++++++++++-------- .../collections}/lru_cache.rs | 19 ++-- src/libstd/collections/mod.rs | 25 +++++ src/libstd/from_str.rs | 9 ++ src/libstd/lib.rs | 20 ++-- src/libstd/path/posix.rs | 7 +- src/libstd/path/windows.rs | 3 +- 30 files changed, 397 insertions(+), 371 deletions(-) rename src/{libstd => libcollections}/hash/mod.rs (93%) rename src/{libstd => libcollections}/hash/sip.rs (88%) create mode 100644 src/libcollections/macros.rs rename src/{libstd => libcollections}/slice.rs (99%) rename src/{libstd => libcollections}/str.rs (98%) rename src/{libstd => libcollections}/string.rs (94%) rename src/{libstd => libcollections}/unicode.rs (98%) rename src/{libstd => libcollections}/vec.rs (97%) rename src/{libcollections => libstd/collections}/hashmap.rs (97%) rename src/{libcollections => libstd/collections}/lru_cache.rs (97%) create mode 100644 src/libstd/collections/mod.rs diff --git a/mk/crates.mk b/mk/crates.mk index 9b252267aba..cea9133e835 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -60,36 +60,36 @@ DEPS_core := DEPS_rlibc := DEPS_alloc := core libc native:jemalloc DEPS_debug := std -DEPS_std := core rand libc alloc native:rustrt native:backtrace +DEPS_std := core rand libc alloc collections native:rustrt native:backtrace DEPS_graphviz := std DEPS_green := std native:context_switch DEPS_rustuv := std native:uv native:uv_support DEPS_native := std -DEPS_syntax := std term serialize collections log fmt_macros debug +DEPS_syntax := std term serialize log fmt_macros debug DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \ - collections time log graphviz debug -DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \ + time log graphviz debug +DEPS_rustdoc := rustc native:hoedown serialize sync getopts \ test time debug DEPS_flate := std native:miniz -DEPS_arena := std collections +DEPS_arena := std DEPS_graphviz := std DEPS_glob := std -DEPS_serialize := std collections log -DEPS_term := std collections log +DEPS_serialize := std log +DEPS_term := std log DEPS_semver := std DEPS_uuid := std serialize DEPS_sync := std alloc DEPS_getopts := std -DEPS_collections := std debug +DEPS_collections := core alloc DEPS_fourcc := syntax std DEPS_hexfloat := syntax std DEPS_num := std -DEPS_test := std collections getopts serialize term time regex +DEPS_test := std getopts serialize term time regex DEPS_time := std serialize sync DEPS_rand := core -DEPS_url := std collections +DEPS_url := std DEPS_log := std sync -DEPS_regex := std collections +DEPS_regex := std DEPS_regex_macros = syntax std regex DEPS_fmt_macros = std @@ -105,6 +105,7 @@ ONLY_RLIB_libc := 1 ONLY_RLIB_rlibc := 1 ONLY_RLIB_alloc := 1 ONLY_RLIB_rand := 1 +ONLY_RLIB_collections := 1 ################################################################################ # You should not need to edit below this line diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index c91a5289faa..6cd3616fc71 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -10,14 +10,17 @@ #![allow(missing_doc)] +use core::prelude::*; -use std::cmp; -use std::fmt; -use std::iter::RandomAccessIterator; -use std::iter::{Enumerate, Repeat, Map, Zip}; -use std::ops; -use std::slice; -use std::uint; +use core::cmp; +use core::fmt; +use core::iter::{Enumerate, Repeat, Map, Zip}; +use core::ops; +use core::slice; +use core::uint; + +use string::String; +use vec::Vec; #[deriving(Clone)] struct SmallBitv { diff --git a/src/libcollections/btree.rs b/src/libcollections/btree.rs index cebf21ee7e7..d589aa73a52 100644 --- a/src/libcollections/btree.rs +++ b/src/libcollections/btree.rs @@ -18,8 +18,13 @@ ///a length (the height of the tree), and lower and upper bounds on the ///number of elements that a given node can contain. -use std::fmt; -use std::fmt::Show; +use core::prelude::*; + +use alloc::owned::Box; +use core::fmt; +use core::fmt::Show; + +use vec::Vec; #[allow(missing_doc)] pub struct BTree { diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs index fa2cb233873..b4930173bb6 100644 --- a/src/libcollections/deque.rs +++ b/src/libcollections/deque.rs @@ -10,7 +10,7 @@ //! Container traits for collections -use std::container::Mutable; +use core::prelude::*; /// A double-ended sequence that allows querying, insertion and deletion at both ends. pub trait Deque : Mutable { diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 014d4e680ee..062e94d21c0 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -21,9 +21,12 @@ // Backlinks over DList::prev are raw pointers that form a full chain in // the reverse direction. -use std::iter; -use std::mem; -use std::ptr; +use core::prelude::*; + +use alloc::owned::Box; +use core::iter; +use core::mem; +use core::ptr; use deque::Deque; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 78485321aa5..856aff64b6a 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -13,7 +13,9 @@ //! This module defines a container which uses an efficient bit mask //! representation to hold C-like enum variants. -use std::num::Bitwise; +use core::prelude::*; + +use core::num::Bitwise; #[deriving(Clone, PartialEq, Eq, Hash, Show)] /// A specialized Set implementation to use enum types. diff --git a/src/libstd/hash/mod.rs b/src/libcollections/hash/mod.rs similarity index 93% rename from src/libstd/hash/mod.rs rename to src/libcollections/hash/mod.rs index 8e95263d48e..067f266f63f 100644 --- a/src/libstd/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -63,22 +63,17 @@ #![allow(unused_must_use)] -use container::Container; -use intrinsics::TypeId; -use iter::Iterator; -use option::{Option, Some, None}; -use owned::Box; -use rc::Rc; -use result::{Result, Ok, Err}; -use slice::{Vector, ImmutableVector}; -use str::{Str, StrSlice}; +use core::prelude::*; + +use alloc::owned::Box; +use alloc::rc::Rc; +use core::intrinsics::TypeId; + use vec::Vec; /// Reexport the `sip::hash` function as our default hasher. pub use hash = self::sip::hash; -pub use Writer = io::Writer; - pub mod sip; /// A trait that represents a hashable type. The `S` type parameter is an @@ -96,33 +91,29 @@ pub trait Hasher { fn hash>(&self, value: &T) -> u64; } +pub trait Writer { + fn write(&mut self, bytes: &[u8]); +} + ////////////////////////////////////////////////////////////////////////////// macro_rules! impl_hash( - ( $( $ty:ty => $method:ident;)* ) => ( + ( $($ty:ident)* ) => ( $( impl Hash for $ty { #[inline] fn hash(&self, state: &mut S) { - state.$method(*self); + let a: [u8, ..::core::$ty::BYTES] = unsafe { + ::core::mem::transmute(*self) + }; + state.write(a.as_slice()) } } )* ) ) -impl_hash!( - u8 => write_u8; - u16 => write_le_u16; - u32 => write_le_u32; - u64 => write_le_u64; - uint => write_le_uint; - i8 => write_i8; - i16 => write_le_i16; - i32 => write_le_i32; - i64 => write_le_i64; - int => write_le_int; -) +impl_hash!( u8 u16 u32 u64 uint i8 i16 i32 i64 int ) impl Hash for bool { #[inline] @@ -142,7 +133,7 @@ impl<'a, S: Writer> Hash for &'a str { #[inline] fn hash(&self, state: &mut S) { state.write(self.as_bytes()); - state.write_u8(0xFF); + 0xffu8.hash(state) } } diff --git a/src/libstd/hash/sip.rs b/src/libcollections/hash/sip.rs similarity index 88% rename from src/libstd/hash/sip.rs rename to src/libcollections/hash/sip.rs index 90767908612..039aee7347b 100644 --- a/src/libstd/hash/sip.rs +++ b/src/libcollections/hash/sip.rs @@ -24,17 +24,11 @@ * discouraged. */ -use clone::Clone; -use container::Container; -use default::Default; -use int; -use io::{IoResult, Writer}; -use iter::Iterator; -use result::Ok; -use slice::ImmutableVector; -use uint; +use core::prelude::*; -use super::{Hash, Hasher}; +use core::default::Default; + +use super::{Hash, Hasher, Writer}; /// `SipState` computes a SipHash 2-4 hash over a stream of bytes. pub struct SipState { @@ -151,41 +145,11 @@ impl SipState { v0 ^ v1 ^ v2 ^ v3 } - - #[inline] - fn write_le(&mut self, n: u64, size: uint) { - self.tail |= n << 8*self.ntail; - self.ntail += size; - - if self.ntail >= 8 { - let m = self.tail; - - self.v3 ^= m; - compress!(self.v0, self.v1, self.v2, self.v3); - compress!(self.v0, self.v1, self.v2, self.v3); - self.v0 ^= m; - - self.ntail -= 8; - if self.ntail == 0 { - self.tail = 0; - } else { - self.tail = n >> 64 - 8*self.ntail; - } - } - } } -macro_rules! make_write_le( - ($this:expr, $n:expr, $size:expr) => ({ - $this.write_le($n as u64, $size); - $this.length += $size; - Ok(()) - }) -) - impl Writer for SipState { #[inline] - fn write(&mut self, msg: &[u8]) -> IoResult<()> { + fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -196,7 +160,7 @@ impl Writer for SipState { if length < needed { self.tail |= u8to64_le!(msg, 0, length) << 8*self.ntail; self.ntail += length; - return Ok(()); + return } let m = self.tail | u8to64_le!(msg, 0, needed) << 8*self.ntail; @@ -228,60 +192,7 @@ impl Writer for SipState { self.tail = u8to64_le!(msg, i, left); self.ntail = left; - - Ok(()) } - - #[inline] - fn write_u8(&mut self, n: u8) -> IoResult<()> { - make_write_le!(self, n, 1) - } - - #[inline] - fn write_le_u16(&mut self, n: u16) -> IoResult<()> { - make_write_le!(self, n, 2) - } - - #[inline] - fn write_le_u32(&mut self, n: u32) -> IoResult<()> { - make_write_le!(self, n, 4) - } - - #[inline] - fn write_le_u64(&mut self, n: u64) -> IoResult<()> { - make_write_le!(self, n, 8) - } - - #[inline] - fn write_le_uint(&mut self, n: uint) -> IoResult<()> { - make_write_le!(self, n, uint::BYTES) - } - - #[inline] - fn write_i8(&mut self, n: i8) -> IoResult<()> { - make_write_le!(self, n, 1) - } - - #[inline] - fn write_le_i16(&mut self, n: i16) -> IoResult<()> { - make_write_le!(self, n, 2) - } - - #[inline] - fn write_le_i32(&mut self, n: i32) -> IoResult<()> { - make_write_le!(self, n, 4) - } - - #[inline] - fn write_le_i64(&mut self, n: i64) -> IoResult<()> { - make_write_le!(self, n, 8) - } - - #[inline] - fn write_le_int(&mut self, n: int) -> IoResult<()> { - make_write_le!(self, n, int::BYTES) - } - } impl Clone for SipState { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index d1c75b89579..0ac26e686cd 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -14,43 +14,66 @@ #![crate_id = "collections#0.11.0-pre"] #![crate_type = "rlib"] -#![crate_type = "dylib"] #![license = "MIT/ASL2"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/")] -#![feature(macro_rules, managed_boxes, default_type_params, phase)] +#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)] +#![no_std] -#![deny(deprecated_owned_vector)] - -extern crate debug; +#[phase(syntax, link)] extern crate core; +extern crate alloc; +#[cfg(test)] extern crate native; +#[cfg(test)] extern crate std; #[cfg(test)] extern crate test; #[cfg(test)] #[phase(syntax, link)] extern crate log; -pub use bitv::Bitv; +pub use bitv::{Bitv, BitvSet}; pub use btree::BTree; pub use deque::Deque; pub use dlist::DList; pub use enum_set::EnumSet; -pub use hashmap::{HashMap, HashSet}; -pub use lru_cache::LruCache; pub use priority_queue::PriorityQueue; pub use ringbuf::RingBuf; pub use smallintmap::SmallIntMap; pub use treemap::{TreeMap, TreeSet}; pub use trie::{TrieMap, TrieSet}; +mod macros; + pub mod bitv; pub mod btree; pub mod deque; pub mod dlist; pub mod enum_set; -pub mod hashmap; -pub mod lru_cache; pub mod priority_queue; pub mod ringbuf; pub mod smallintmap; pub mod treemap; pub mod trie; +pub mod slice; +pub mod str; +pub mod string; +pub mod vec; +pub mod hash; + +// Internal unicode fiddly bits for the str module +mod unicode; + +// FIXME(#14008) should this actually exist, or should a method be added? +fn expect(a: core::option::Option, b: &str) -> T { + match a { + core::option::Some(a) => a, + core::option::None => fail!(b), + } +} + +mod std { + pub use core::fmt; // necessary for fail!() + pub use core::option; // necessary for fail!() + pub use core::clone; // deriving(Clone) + pub use core::cmp; // deriving(Eq, Ord, etc.) + pub use hash; // deriving(Hash) +} diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs new file mode 100644 index 00000000000..db062a70bbb --- /dev/null +++ b/src/libcollections/macros.rs @@ -0,0 +1,22 @@ +// 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. + +#![macro_escape] + +/// Create a `std::vec::Vec` containing the arguments. +macro_rules! vec( + ($($e:expr),*) => ({ + // leading _ to allow empty construction without a warning. + let mut _temp = ::vec::Vec::new(); + $(_temp.push($e);)* + _temp + }); + ($($e:expr),+,) => (vec!($($e),+)) +) diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index d73c07ee17d..d40051faf13 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -12,10 +12,12 @@ #![allow(missing_doc)] -use std::clone::Clone; -use std::mem::{zeroed, replace, swap}; -use std::ptr; -use std::slice; +use core::prelude::*; + +use core::mem::{overwrite, zeroed, replace, swap}; + +use slice; +use vec::Vec; /// A priority queue implemented with a binary heap #[deriving(Clone)] diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs index 7b8d416c4fe..713888cf473 100644 --- a/src/libcollections/ringbuf.rs +++ b/src/libcollections/ringbuf.rs @@ -13,12 +13,14 @@ //! RingBuf implements the trait Deque. It should be imported with `use //! collections::deque::Deque`. -use std::cmp; -use std::fmt; -use std::fmt::Show; -use std::iter::RandomAccessIterator; +use core::prelude::*; + +use core::cmp; +use core::fmt; +use core::iter::RandomAccessIterator; use deque::Deque; +use vec::Vec; static INITIAL_CAPACITY: uint = 8u; // 2^3 static MINIMUM_CAPACITY: uint = 2u; @@ -393,7 +395,7 @@ impl Extendable for RingBuf { } } -impl Show for RingBuf { +impl fmt::Show for RingBuf { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "[")); diff --git a/src/libstd/slice.rs b/src/libcollections/slice.rs similarity index 99% rename from src/libstd/slice.rs rename to src/libcollections/slice.rs index d6f63da09f2..a724307a70e 100644 --- a/src/libstd/slice.rs +++ b/src/libcollections/slice.rs @@ -99,20 +99,16 @@ There are a number of free functions that create or take vectors, for example: #![doc(primitive = "slice")] -use mem::transmute; -use clone::Clone; -use cmp::{Ord, Ordering, Less, Greater}; -use cmp; -use container::Container; -use iter::*; -use mem::size_of; -use mem; -use ops::Drop; -use option::{None, Option, Some}; -use ptr::RawPtr; -use ptr; -use rt::heap::{allocate, deallocate}; -use finally::try_finally; +use core::prelude::*; + +use alloc::heap::{allocate, deallocate}; +use core::cmp; +use core::finally::try_finally; +use core::mem::size_of; +use core::mem::transmute; +use core::mem; +use core::ptr; +use core::iter::{range_step, MultiplicativeIterator}; use vec::Vec; pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows}; @@ -295,13 +291,13 @@ impl<'a, T: Clone> CloneableVector for &'a [T] { #[inline] fn to_owned(&self) -> ~[T] { use RawVec = core::raw::Vec; - use num::{CheckedAdd, CheckedMul}; + use core::num::{CheckedAdd, CheckedMul}; let len = self.len(); let data_size = len.checked_mul(&mem::size_of::()); - let data_size = data_size.expect("overflow in to_owned()"); + let data_size = ::expect(data_size, "overflow in to_owned()"); let size = mem::size_of::>().checked_add(&data_size); - let size = size.expect("overflow in to_owned()"); + let size = ::expect(size, "overflow in to_owned()"); unsafe { // this should pass the real required alignment diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs index 932011baa56..c284a73d8bc 100644 --- a/src/libcollections/smallintmap.rs +++ b/src/libcollections/smallintmap.rs @@ -15,9 +15,13 @@ #![allow(missing_doc)] -use std::iter::{Enumerate, FilterMap}; -use std::mem::replace; -use std::{vec, slice}; +use core::prelude::*; + +use core::iter::{Enumerate, FilterMap}; +use core::mem::replace; + +use {vec, slice}; +use vec::Vec; #[allow(missing_doc)] pub struct SmallIntMap { @@ -118,7 +122,7 @@ impl SmallIntMap { } pub fn get<'a>(&'a self, key: &uint) -> &'a V { - self.find(key).expect("key not present") + ::expect(self.find(key), "key not present") } /// An iterator visiting all key-value pairs in ascending order by the keys. diff --git a/src/libstd/str.rs b/src/libcollections/str.rs similarity index 98% rename from src/libstd/str.rs rename to src/libcollections/str.rs index 3af3821486f..144f14acdcd 100644 --- a/src/libstd/str.rs +++ b/src/libcollections/str.rs @@ -67,21 +67,17 @@ is the same as `&[u8]`. #![doc(primitive = "str")] -use char::Char; -use char; -use clone::Clone; -use cmp::{PartialEq, Eq, PartialOrd, Ord, Equiv, Ordering}; -use container::Container; -use default::Default; -use fmt; -use io::Writer; -use iter::{Iterator, range, AdditiveIterator}; -use mem::transmute; -use mem; -use option::{None, Option, Some}; -use result::Result; -use slice::Vector; -use slice::{ImmutableVector, MutableVector}; +use core::prelude::*; + +use core::char; +use core::default::Default; +use core::fmt; +use core::cmp; +use core::iter::AdditiveIterator; +use core::mem; + +use hash; +use slice::CloneableVector; use string::String; use vec::Vec; @@ -201,9 +197,6 @@ Section: Iterators // Helper functions used for Unicode normalization fn canonical_sort(comb: &mut [(char, u8)]) { - use iter::range; - use tuple::Tuple2; - let len = comb.len(); for i in range(0, len) { let mut swapped = false; @@ -638,13 +631,10 @@ impl<'a> Default for MaybeOwned<'a> { fn default() -> MaybeOwned<'a> { Slice("") } } -impl<'a, H: Writer> ::hash::Hash for MaybeOwned<'a> { +impl<'a, H: hash::Writer> hash::Hash for MaybeOwned<'a> { #[inline] fn hash(&self, hasher: &mut H) { - match *self { - Slice(s) => s.hash(hasher), - Owned(ref s) => s.as_slice().hash(hasher), - } + self.as_slice().hash(hasher) } } @@ -660,10 +650,10 @@ impl<'a> fmt::Show for MaybeOwned<'a> { /// Unsafe operations pub mod raw { - use c_str::CString; - use libc; - use mem; - use raw::Slice; + use core::prelude::*; + use core::mem; + use core::raw::Slice; + use string::String; use vec::Vec; @@ -681,9 +671,16 @@ pub mod raw { } /// Create a Rust string from a null-terminated C string - pub unsafe fn from_c_str(c_string: *libc::c_char) -> String { + pub unsafe fn from_c_str(c_string: *i8) -> String { let mut buf = String::new(); - buf.push_bytes(CString::new(c_string, false).as_bytes_no_nul()); + let mut len = 0; + while *c_string.offset(len) != 0 { + len += 1; + } + buf.push_bytes(mem::transmute(Slice { + data: c_string, + len: len as uint, + })); buf } @@ -800,10 +797,8 @@ pub trait StrAllocating: Str { #[deprecated = "obsolete, use `to_string`"] #[inline] fn to_owned(&self) -> String { - use slice::Vector; - unsafe { - ::mem::transmute(Vec::from_slice(self.as_slice().as_bytes())) + mem::transmute(Vec::from_slice(self.as_slice().as_bytes())) } } @@ -852,9 +847,9 @@ pub trait StrAllocating: Str { if sc == tc { *dcol.get_mut(j + 1) = current; } else { - *dcol.get_mut(j + 1) = ::cmp::min(current, next); - *dcol.get_mut(j + 1) = ::cmp::min(*dcol.get(j + 1), - *dcol.get(j)) + 1; + *dcol.get_mut(j + 1) = cmp::min(current, next); + *dcol.get_mut(j + 1) = cmp::min(*dcol.get(j + 1), + *dcol.get(j)) + 1; } current = next; diff --git a/src/libstd/string.rs b/src/libcollections/string.rs similarity index 94% rename from src/libstd/string.rs rename to src/libcollections/string.rs index 80973bb5328..764811e92c7 100644 --- a/src/libstd/string.rs +++ b/src/libcollections/string.rs @@ -10,23 +10,17 @@ //! An owned, growable string that enforces that its contents are valid UTF-8. -use c_vec::CVec; -use char::Char; -use cmp::Equiv; -use container::{Container, Mutable}; -use default::Default; -use fmt; -use from_str::FromStr; -use io::Writer; -use iter::{Extendable, FromIterator, Iterator, range}; -use mem; -use option::{None, Option, Some}; -use ptr::RawPtr; -use ptr; -use result::{Result, Ok, Err}; -use slice::Vector; -use str::{CharRange, Str, StrSlice, StrAllocating}; +use core::prelude::*; + +use core::default::Default; +use core::fmt; +use core::mem; +use core::ptr; +use core::raw::Slice; + +use hash; use str; +use str::{CharRange, StrAllocating}; use vec::Vec; /// A growable string stored as a UTF-8 encoded buffer. @@ -168,14 +162,17 @@ impl String { #[inline] pub fn push_char(&mut self, ch: char) { let cur_len = self.len(); - unsafe { - // This may use up to 4 bytes. - self.vec.reserve_additional(4); + // This may use up to 4 bytes. + self.vec.reserve_additional(4); + unsafe { // Attempt to not use an intermediate buffer by just pushing bytes // directly onto this string. - let mut c_vector = CVec::new(self.vec.as_mut_ptr().offset(cur_len as int), 4); - let used = ch.encode_utf8(c_vector.as_mut_slice()); + let slice = Slice { + data: self.vec.as_ptr().offset(cur_len as int), + len: 4, + }; + let used = ch.encode_utf8(mem::transmute(slice)); self.vec.set_len(cur_len + used); } } @@ -340,7 +337,7 @@ impl fmt::Show for String { } } -impl ::hash::Hash for String { +impl hash::Hash for String { #[inline] fn hash(&self, hasher: &mut H) { self.as_slice().hash(hasher) @@ -354,13 +351,6 @@ impl<'a, S: Str> Equiv for String { } } -impl FromStr for String { - #[inline] - fn from_str(s: &str) -> Option { - Some(s.to_string()) - } -} - #[cfg(test)] mod tests { extern crate test; diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 1184c9b7b52..1fd9fce2089 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -12,13 +12,17 @@ //! trees. The only requirement for the types is that the key implements //! `Ord`. -use std::cmp::Ordering; -use std::fmt::Show; -use std::fmt; -use std::iter::Peekable; -use std::iter; -use std::mem::{replace, swap}; -use std::ptr; +use core::prelude::*; + +use alloc::owned::Box; +use core::fmt; +use core::fmt::Show; +use core::iter::Peekable; +use core::iter; +use core::mem::{replace, swap}; +use core::ptr; + +use vec::Vec; // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where red (horizontal) nodes can only be added diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index e6df4fd87e1..a70b466623f 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -10,11 +10,15 @@ //! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types) -use std::mem::zeroed; -use std::mem; -use std::slice::{Items, MutItems}; -use std::slice; -use std::uint; +use core::prelude::*; + +use alloc::owned::Box; +use core::mem::zeroed; +use core::mem; +use core::uint; + +use slice::{Items, MutItems}; +use slice; // FIXME: #5244: need to manually update the TrieNode constructor static SHIFT: uint = 4; @@ -457,7 +461,7 @@ fn insert(count: &mut uint, child: &mut Child, key: uint, value: T, *child = Internal(new); return ret; } - _ => unreachable!() + _ => fail!("unreachable code"), } } diff --git a/src/libstd/unicode.rs b/src/libcollections/unicode.rs similarity index 98% rename from src/libstd/unicode.rs rename to src/libcollections/unicode.rs index 03c960e96ff..440290164c3 100644 --- a/src/libstd/unicode.rs +++ b/src/libcollections/unicode.rs @@ -13,11 +13,9 @@ #![allow(missing_doc, non_uppercase_statics)] pub mod normalization { - use option::{Some, None}; - use slice::ImmutableVector; + use core::prelude::*; fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 { - use cmp::{Equal, Less, Greater}; match r.bsearch(|&(lo, hi, _)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } diff --git a/src/libstd/vec.rs b/src/libcollections/vec.rs similarity index 97% rename from src/libstd/vec.rs rename to src/libcollections/vec.rs index cdcee9464de..faa9db7c919 100644 --- a/src/libstd/vec.rs +++ b/src/libcollections/vec.rs @@ -10,25 +10,22 @@ //! An owned, growable vector. -use RawVec = raw::Vec; -use clone::Clone; -use cmp::{PartialOrd, PartialEq, Ordering, Eq, Ord, max}; -use container::{Container, Mutable}; -use default::Default; -use fmt; -use iter::{DoubleEndedIterator, FromIterator, Extendable, Iterator, range}; -use mem; -use num::{CheckedMul, CheckedAdd}; -use num; -use ops::{Add, Drop}; -use option::{None, Option, Some}; -use ptr::RawPtr; -use ptr; -use raw::Slice; -use rt::heap::{allocate, reallocate, deallocate}; -use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector}; -use slice::{MutableOrdVector, OwnedVector, Vector}; -use slice::{MutableVectorAllocating}; +use core::prelude::*; + +use alloc::heap::{allocate, reallocate, deallocate}; +use RawVec = core::raw::Vec; +use core::raw::Slice; +use core::cmp::max; +use core::default::Default; +use core::fmt; +use core::mem; +use core::num::{CheckedMul, CheckedAdd}; +use core::num; +use core::ptr; +use core::uint; + +use slice::{MutableTotalOrdVector, OwnedVector, MutableVectorAllocating}; +use slice::{Items, MutItems}; /// An owned, growable vector. /// @@ -90,12 +87,12 @@ impl Vec { /// ``` pub fn with_capacity(capacity: uint) -> Vec { if mem::size_of::() == 0 { - Vec { len: 0, cap: ::uint::MAX, ptr: 0 as *mut T } + Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T } } else if capacity == 0 { Vec::new() } else { - let size = capacity.checked_mul(&mem::size_of::()) - .expect("capacity overflow"); + let size = ::expect(capacity.checked_mul(&mem::size_of::()), + "capacity overflow"); let ptr = unsafe { allocate(size, mem::min_align_of::()) }; Vec { len: 0, cap: capacity, ptr: ptr as *mut T } } @@ -503,8 +500,8 @@ impl Vec { if mem::size_of::() == 0 { return } if capacity > self.cap { - let size = capacity.checked_mul(&mem::size_of::()) - .expect("capacity overflow"); + let size = ::expect(capacity.checked_mul(&mem::size_of::()), + "capacity overflow"); unsafe { self.ptr = alloc_or_realloc(self.ptr, size, self.cap * mem::size_of::()); @@ -583,7 +580,7 @@ impl Vec { pub fn push(&mut self, value: T) { if mem::size_of::() == 0 { // zero-size types consume no memory, so we can't rely on the address space running out - self.len = self.len.checked_add(&1).expect("length overflow"); + self.len = ::expect(self.len.checked_add(&1), "length overflow"); unsafe { mem::forget(value); } return } @@ -1530,9 +1527,9 @@ impl FromVec for ~[T] { fn from_vec(mut v: Vec) -> ~[T] { let len = v.len(); let data_size = len.checked_mul(&mem::size_of::()); - let data_size = data_size.expect("overflow in from_vec()"); + let data_size = ::expect(data_size, "overflow in from_vec()"); let size = mem::size_of::>().checked_add(&data_size); - let size = size.expect("overflow in from_vec()"); + let size = ::expect(size, "overflow in from_vec()"); // In a post-DST world, we can attempt to reuse the Vec allocation by calling // shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no @@ -1563,7 +1560,7 @@ impl FromVec for ~[T] { /// Unsafe operations pub mod raw { use super::Vec; - use ptr; + use core::ptr; /// Constructs a vector from an unsafe pointer to a buffer. /// diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index f6c438698b4..eef133181e1 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -61,9 +61,7 @@ //! types to reintroduce mutability: //! //! ``` -//! extern crate collections; -//! -//! use collections::HashMap; +//! use std::collections::HashMap; //! use std::cell::RefCell; //! use std::rc::Rc; //! @@ -86,8 +84,6 @@ //! to take `&self`. //! //! ``` -//! extern crate collections; -//! //! use std::cell::RefCell; //! //! struct Graph { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index f41efdbc1db..2cce68d5f60 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -31,12 +31,6 @@ pub use self::num::radix; pub use self::num::Radix; pub use self::num::RadixFmt; -macro_rules! write( - ($dst:expr, $($arg:tt)*) => ({ - format_args!(|args| { $dst.write_fmt(args) }, $($arg)*) - }) -) - mod num; mod float; pub mod rt; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 6474c5e37a4..94901aff001 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -54,7 +54,18 @@ macro_rules! assert( ); ) +/// Runtime assertion, only without `--cfg ndebug` +#[macro_export] +macro_rules! debug_assert( + ($(a:tt)*) => ({ + if cfg!(not(ndebug)) { + assert!($($a)*); + } + }) +) + /// Runtime assertion for equality, for details see std::macros +#[macro_export] macro_rules! assert_eq( ($cond1:expr, $cond2:expr) => ({ let c1 = $cond1; @@ -65,6 +76,16 @@ macro_rules! assert_eq( }) ) +/// Runtime assertion for equality, only without `--cfg ndebug` +#[macro_export] +macro_rules! debug_assert_eq( + ($($a:tt)*) => ({ + if cfg!(not(ndebug)) { + assert_eq!($($a)*); + } + }) +) + /// Runtime assertion, disableable at compile time #[macro_export] macro_rules! debug_assert( @@ -86,3 +107,13 @@ macro_rules! vec( ($($e:expr),*) => ({ #[cfg(test)] macro_rules! format( ($($arg:tt)*) => (format_args!(::fmt::format, $($arg)*)) ) + +/// Write some formatted data into a stream. +/// +/// Identical to the macro in `std::macros` +#[macro_export] +macro_rules! write( + ($dst:expr, $($arg:tt)*) => ({ + format_args_method!($dst, write_fmt, $($arg)*) + }) +) diff --git a/src/libcollections/hashmap.rs b/src/libstd/collections/hashmap.rs similarity index 97% rename from src/libcollections/hashmap.rs rename to src/libstd/collections/hashmap.rs index dfcb85a3e39..bcf6d139c35 100644 --- a/src/libcollections/hashmap.rs +++ b/src/libstd/collections/hashmap.rs @@ -10,40 +10,39 @@ //! Unordered containers, implemented as hash-tables (`HashSet` and `HashMap` types) -use std::container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; -use std::clone::Clone; -use std::cmp::{PartialEq, Eq, Equiv, max}; -use std::default::Default; -use std::fmt; -use std::fmt::Show; -use std::hash::{Hash, Hasher, sip}; -use std::iter; -use std::iter::{Iterator, FromIterator, Extendable}; -use std::iter::{FilterMap, Chain, Repeat, Zip}; -use std::iter::{range, range_inclusive}; -use std::mem::replace; -use std::num; -use std::option::{Option, Some, None}; -use std::rand; -use std::rand::Rng; -use std::result::{Ok, Err}; -use std::slice::ImmutableVector; +use clone::Clone; +use cmp::{max, Eq, Equiv, PartialEq}; +use container::{Container, Mutable, Set, MutableSet, Map, MutableMap}; +use default::Default; +use fmt::Show; +use fmt; +use hash::{Hash, Hasher, sip}; +use iter::{Iterator, FilterMap, Chain, Repeat, Zip, Extendable}; +use iter::{range, range_inclusive, FromIterator}; +use iter; +use mem::replace; +use num; +use option::{Some, None, Option}; +use rand::Rng; +use rand; +use result::{Ok, Err}; mod table { - use std::clone::Clone; - use std::cmp; - use std::cmp::PartialEq; - use std::hash::{Hash, Hasher}; - use std::kinds::marker; - use std::num::{CheckedMul, is_power_of_two}; - use std::option::{Option, Some, None}; - use std::prelude::Drop; - use std::ptr; - use std::ptr::RawPtr; - use std::mem::{min_align_of, size_of}; - use std::intrinsics::{move_val_init, set_memory, transmute}; - use std::iter::{Iterator, range_step_inclusive}; - use std::rt::heap::{allocate, deallocate}; + use clone::Clone; + use cmp; + use hash::{Hash, Hasher}; + use iter::range_step_inclusive; + use iter::{Iterator, range}; + use kinds::marker; + use mem::{min_align_of, size_of}; + use mem::{overwrite, transmute}; + use num::{CheckedMul, is_power_of_two}; + use ops::Drop; + use option::{Some, None, Option, Expect}; + use ptr::RawPtr; + use ptr::set_memory; + use ptr; + use rt::heap::{allocate, deallocate}; static EMPTY_BUCKET: u64 = 0u64; @@ -217,12 +216,12 @@ mod table { /// Does not initialize the buckets. The caller should ensure they, /// at the very least, set every hash to EMPTY_BUCKET. unsafe fn new_uninitialized(capacity: uint) -> RawTable { - let hashes_size = - capacity.checked_mul(&size_of::()).expect("capacity overflow"); - let keys_size = - capacity.checked_mul(&size_of::< K >()).expect("capacity overflow"); - let vals_size = - capacity.checked_mul(&size_of::< V >()).expect("capacity overflow"); + let hashes_size = capacity.checked_mul(&size_of::()) + .expect("capacity overflow"); + let keys_size = capacity.checked_mul(&size_of::< K >()) + .expect("capacity overflow"); + let vals_size = capacity.checked_mul(&size_of::< V >()) + .expect("capacity overflow"); // Allocating hashmaps is a little tricky. We need to allocate three // arrays, but since we know their sizes and alignments up front, @@ -339,8 +338,8 @@ mod table { unsafe { debug_assert_eq!(*self.hashes.offset(idx), EMPTY_BUCKET); *self.hashes.offset(idx) = hash.inspect(); - move_val_init(&mut *self.keys.offset(idx), k); - move_val_init(&mut *self.vals.offset(idx), v); + overwrite(&mut *self.keys.offset(idx), k); + overwrite(&mut *self.vals.offset(idx), v); } self.size += 1; @@ -519,8 +518,8 @@ mod table { let hash = idx.hash().inspect(); let (k, v) = self.read(&idx); *new_ht.hashes.offset(i as int) = hash; - move_val_init(&mut *new_ht.keys.offset(i as int), (*k).clone()); - move_val_init(&mut *new_ht.vals.offset(i as int), (*v).clone()); + overwrite(&mut *new_ht.keys.offset(i as int), (*k).clone()); + overwrite(&mut *new_ht.vals.offset(i as int), (*v).clone()); } } } @@ -1037,6 +1036,7 @@ impl HashMap { HashMap::with_capacity(INITIAL_CAPACITY) } + /// Creates an empty hash map with the given initial capacity. pub fn with_capacity(capacity: uint) -> HashMap { let mut r = rand::task_rng(); let r0 = r.gen(); @@ -1047,6 +1047,9 @@ impl HashMap { } impl, V, S, H: Hasher> HashMap { + /// Creates an empty hashmap which will use the given hasher to hash keys. + /// + /// The creates map has the default initial capacity. pub fn with_hasher(hasher: H) -> HashMap { HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, hasher) } @@ -1326,7 +1329,7 @@ impl, V, S, H: Hasher> HashMap { pub fn get<'a>(&'a self, k: &K) -> &'a V { match self.find(k) { Some(v) => v, - None => fail!("No entry found for key: {:?}", k) + None => fail!("no entry found for key") } } @@ -1334,7 +1337,7 @@ impl, V, S, H: Hasher> HashMap { pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V { match self.find_mut(k) { Some(v) => v, - None => fail!("No entry found for key: {:?}", k) + None => fail!("no entry found for key") } } @@ -1533,6 +1536,10 @@ impl HashSet { } impl, S, H: Hasher> HashSet { + /// 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. pub fn with_hasher(hasher: H) -> HashSet { HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher) } @@ -1632,8 +1639,10 @@ impl, S, H: Hasher + Default> Extendable for HashSet } } -impl Default for HashSet { - fn default() -> HashSet { HashSet::new() } +impl, S, H: Hasher + Default> Default for HashSet { + fn default() -> HashSet { + HashSet::with_hasher(Default::default()) + } } // `Repeat` is used to feed the filter closure an explicit capture diff --git a/src/libcollections/lru_cache.rs b/src/libstd/collections/lru_cache.rs similarity index 97% rename from src/libcollections/lru_cache.rs rename to src/libstd/collections/lru_cache.rs index ea25eee06d0..09511316a67 100644 --- a/src/libcollections/lru_cache.rs +++ b/src/libstd/collections/lru_cache.rs @@ -37,13 +37,18 @@ //! assert!(cache.get(&2).is_none()); //! ``` -use std::container::Container; -use std::hash::Hash; -use std::fmt; -use std::mem; -use std::ptr; - -use HashMap; +use cmp::{Eq, TotalEq}; +use collections::HashMap; +use container::{Container, Mutable, MutableMap}; +use fmt; +use hash::Hash; +use iter::{range, Iterator}; +use mem; +use ops::Drop; +use option::{Some, None, Option}; +use owned::Box; +use ptr; +use result::{Ok, Err}; struct KeyRef { k: *K } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs new file mode 100644 index 00000000000..16a6a35d9d5 --- /dev/null +++ b/src/libstd/collections/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// 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. + +/*! + * Collection types. + */ + +pub use core_collections::{Bitv, BitvSet, BTree, Deque, DList, EnumSet}; +pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap}; +pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet}; +pub use core_collections::{bitv, btree, deque, dlist, enum_set}; +pub use core_collections::{priority_queue, ringbuf, smallintmap, treemap, trie}; + +pub use self::hashmap::{HashMap, HashSet}; +pub use self::lru_cache::LruCache; + +pub mod hashmap; +pub mod lru_cache; diff --git a/src/libstd/from_str.rs b/src/libstd/from_str.rs index 62bb8e4d969..4394fb9d355 100644 --- a/src/libstd/from_str.rs +++ b/src/libstd/from_str.rs @@ -11,6 +11,8 @@ //! The `FromStr` trait for types that can be created from strings use option::{Option, Some, None}; +use string::String; +use str::StrAllocating; /// A trait to abstract the idea of creating a new instance of a type from a /// string. @@ -47,6 +49,13 @@ impl FromStr for bool { } } +impl FromStr for String { + #[inline] + fn from_str(s: &str) -> Option { + Some(s.to_string()) + } +} + #[cfg(test)] mod test { use prelude::*; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index db84a724adb..90d6677d612 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -124,6 +124,7 @@ extern crate alloc; extern crate core; extern crate libc; extern crate core_rand = "rand"; +extern crate core_collections = "collections"; // Make std testable by not duplicating lang items. See #2912 #[cfg(test)] extern crate realstd = "std"; @@ -160,6 +161,12 @@ pub use core::option; pub use alloc::owned; pub use alloc::rc; +pub use core_collections::hash; +pub use core_collections::slice; +pub use core_collections::str; +pub use core_collections::string; +pub use core_collections::vec; + // Run tests with libgreen instead of libnative. // // FIXME: This egregiously hacks around starting the test runner in a different @@ -203,10 +210,6 @@ pub mod prelude; #[path = "num/f32.rs"] pub mod f32; #[path = "num/f64.rs"] pub mod f64; -pub mod slice; -pub mod vec; -pub mod str; -pub mod string; pub mod rand; pub mod ascii; @@ -218,7 +221,10 @@ pub mod gc; pub mod from_str; pub mod num; pub mod to_str; -pub mod hash; + +/* Common data structures */ + +pub mod collections; /* Tasks and communication */ @@ -242,10 +248,6 @@ pub mod cleanup; #[unstable] pub mod unstable; -/* For internal use, not exported */ - -mod unicode; - // FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable' // but name resolution doesn't work without it being pub. #[unstable] diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index a6bbf22b401..8dfb64194e7 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -10,16 +10,17 @@ //! POSIX file path handling -use container::Container; use c_str::{CString, ToCStr}; use clone::Clone; use cmp::{PartialEq, Eq}; +use container::Container; use from_str::FromStr; +use hash; use io::Writer; use iter::{DoubleEndedIterator, AdditiveIterator, Extendable, Iterator, Map}; use option::{Option, None, Some}; -use str; use str::Str; +use str; use slice::{CloneableVector, Splits, Vector, VectorVector, ImmutableEqVector, OwnedVector, ImmutableVector}; use vec::Vec; @@ -105,7 +106,7 @@ impl<'a> ToCStr for &'a Path { } } -impl ::hash::Hash for Path { +impl hash::Hash for Path { #[inline] fn hash(&self, state: &mut S) { self.repr.hash(state) diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 865e53cbe38..e53842ecd8f 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -16,6 +16,7 @@ use clone::Clone; use cmp::{PartialEq, Eq}; use container::Container; use from_str::FromStr; +use hash; use io::Writer; use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Iterator, Map}; use mem; @@ -126,7 +127,7 @@ impl<'a> ToCStr for &'a Path { } } -impl ::hash::Hash for Path { +impl hash::Hash for Path { #[cfg(not(test))] #[inline] fn hash(&self, state: &mut S) {