auto merge of #19049 : jakub-/rust/roll-up, r=alexcrichton

r? @alexcrichton
This commit is contained in:
bors 2014-11-18 01:02:19 +00:00
commit 9c96a79a74
84 changed files with 744 additions and 367 deletions

View File

@ -13,7 +13,7 @@ CFG_LIB_NAME_arm-apple-ios = lib$(1).a
CFG_LIB_GLOB_arm-apple-ios = lib$(1)-*.a
CFG_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
CFG_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
CFG_JEMALLOC_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
CFG_GCCISH_CFLAGS_arm-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) -mfpu=vfp3 -arch armv7
CFG_GCCISH_CXXFLAGS_arm-apple-ios := -fno-rtti $(CFG_IOS_FLAGS) -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_arm-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK) -Wl,-no_compact_unwind

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_arm-linux-androideabi=lib$(1).so
CFG_STATIC_LIB_NAME_arm-linux-androideabi=lib$(1).a
CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-linux-androideabi=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_arm-linux-androideabi := -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
CFG_JEMALLOC_CFLAGS_arm-linux-androideabi := -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
CFG_GCCISH_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++

View File

@ -8,7 +8,7 @@ CFG_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).so
CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfpu=vfp $(CFLAGS)
CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfpu=vfp $(CFLAGS)
CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfpu=vfp $(CFLAGS)
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g

View File

@ -8,7 +8,7 @@ CFG_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).so
CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).a
CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_arm-unknown-linux-gnueabihf := -D__arm__ $(CFLAGS)
CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabihf := -D__arm__ $(CFLAGS)
CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC -D__arm__ $(CFLAGS)
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g

View File

@ -13,7 +13,6 @@ CFG_LIB_NAME_i386-apple-ios = lib$(1).a
CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
CFG_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS)
CFG_GCCISH_CFLAGS_i386-apple-ios = -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS)
CFG_GCCISH_CXXFLAGS_i386-apple-ios = -fno-rtti $(CFG_IOSSIM_FLAGS) -I$(CFG_IOSSIM_SDK)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_i386-apple-ios = -lpthread -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK)
@ -30,5 +29,5 @@ CFG_PATH_MUNGE_i386-apple-ios = true
CFG_LDPATH_i386-apple-ios =
CFG_RUN_i386-apple-ios = $(2)
CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
CFG_JEMALLOC_CFLAGS_i386-apple-ios = -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
CFG_JEMALLOC_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS) -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
CFG_GNU_TRIPLE_i386-apple-ios := i386-apple-ios

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_i686-apple-darwin=lib$(1).dylib
CFG_STATIC_LIB_NAME_i686-apple-darwin=lib$(1).a
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_i686-apple-darwin := -m32 -arch i386 $(CFLAGS)
CFG_JEMALLOC_CFLAGS_i686-apple-darwin := -m32 -arch i386 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32

View File

@ -8,7 +8,7 @@ CFG_LIB_NAME_i686-pc-windows-gnu=$(1).dll
CFG_STATIC_LIB_NAME_i686-pc-windows-gnu=$(1).lib
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
CFG_LIB_DSYM_GLOB_i686-pc-windows-gnu=$(1)-*.dylib.dSYM
CFG_CFLAGS_i686-pc-windows-gnu := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_JEMALLOC_CFLAGS_i686-pc-windows-gnu := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_i686-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
CFG_JEMALLOC_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_mipsel-unknown-linux-gnu := -mips32 -mabi=32 $(CFLAGS)
CFG_JEMALLOC_CFLAGS_mipsel-unknown-linux-gnu := -mips32 -mabi=32 $(CFLAGS)
CFG_GCCISH_CFLAGS_mipsel-unknown-linux-gnu := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_mipsel-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mipsel-unknown-linux-gnu := -shared -fPIC -g -mips32

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_x86_64-apple-darwin=lib$(1).dylib
CFG_STATIC_LIB_NAME_x86_64-apple-darwin=lib$(1).a
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_x86_64-apple-darwin := -m64 -arch x86_64 $(CFLAGS)
CFG_JEMALLOC_CFLAGS_x86_64-apple-darwin := -m64 -arch x86_64 $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64

View File

@ -8,7 +8,7 @@ CFG_LIB_NAME_x86_64-pc-windows-gnu=$(1).dll
CFG_STATIC_LIB_NAME_x86_64-pc-windows-gnu=$(1).lib
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-gnu=$(1)-*.dylib.dSYM
CFG_CFLAGS_x86_64-pc-windows-gnu := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-gnu := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-gnu := -shared -g -m64

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
CFG_CFLAGS_x86_64-unknown-dragonfly := -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_JEMALLOC_CFLAGS_x86_64-unknown-dragonfly := -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_x86_64-unknown-freebsd=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-freebsd=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
CFG_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
CFG_JEMALLOC_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=

View File

@ -7,7 +7,7 @@ CFG_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_x86_64-unknown-linux-gnu := -m64
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-gnu := -m64
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64

View File

@ -177,11 +177,11 @@ $$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ $(CFG_JEMALLOC_FLAGS) \
--build=$$(CFG_GNU_TRIPLE_$(CFG_BUILD)) --host=$$(CFG_GNU_TRIPLE_$(1)) \
CC="$$(CC_$(1))" \
CC="$$(CC_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1))" \
AR="$$(AR_$(1))" \
RANLIB="$$(AR_$(1)) s" \
CPPFLAGS="-I $(S)src/rt/" \
EXTRA_CFLAGS="$$(CFG_CFLAGS_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1)) -g1"
EXTRA_CFLAGS="-g1"
$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
ifeq ($$(CFG_DISABLE_JEMALLOC),)

View File

@ -304,8 +304,8 @@ r##"foo #"# bar"##; // foo #"# bar
#### Byte and byte string literals
```{.ebnf .gram}
byte_lit : 'b' '\x27' byte_body '\x27' ;
byte_string_lit : 'b' '"' string_body * '"' | 'b' 'r' raw_byte_string ;
byte_lit : "b\x27" byte_body '\x27' ;
byte_string_lit : "b\x22" string_body * '\x22' | "br" raw_byte_string ;
byte_body : ascii_non_single_quote
| '\x5c' [ '\x27' | common_escape ] ;
@ -381,10 +381,10 @@ num_suffix : int_suffix | float_suffix ;
int_suffix : 'u' int_suffix_size ?
| 'i' int_suffix_size ? ;
int_suffix_size : [ '8' | '1' '6' | '3' '2' | '6' '4' ] ;
int_suffix_size : [ '8' | "16" | "32" | "64" ] ;
float_suffix : [ exponent | '.' dec_lit exponent ? ] ? float_suffix_ty ? ;
float_suffix_ty : 'f' [ '3' '2' | '6' '4' ] ;
float_suffix_ty : 'f' [ "32" | "64" ] ;
exponent : ['E' | 'e'] ['-' | '+' ] ? dec_lit ;
dec_lit : [ dec_digit | '_' ] + ;
```
@ -1862,7 +1862,7 @@ the namespace hierarchy as it normally would.
## Attributes
```{.ebnf .gram}
attribute : '#' '!' ? '[' meta_item ']' ;
attribute : "#!" ? '[' meta_item ']' ;
meta_item : ident [ '=' literal
| '(' meta_seq ')' ] ? ;
meta_seq : meta_item [ ',' meta_seq ] ? ;

View File

@ -178,7 +178,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan {
let toknum = m.name("toknum");
let content = m.name("content");
let proto_tok = tokens.find_equiv(&toknum).expect(format!("didn't find token {} in the map",
let proto_tok = tokens.get(&toknum).expect(format!("didn't find token {} in the map",
toknum).as_slice());
let nm = parse::token::intern(content);

View File

@ -283,7 +283,7 @@ impl Bitv {
x != 0
}
/// Sets the value of a bit at a index `i`.
/// Sets the value of a bit at an index `i`.
///
/// # Panics
///
@ -582,7 +582,7 @@ impl Bitv {
///
/// # Panics
///
/// Panics if the the `Bitv` and slice are of different length.
/// Panics if the `Bitv` and slice are of different length.
///
/// # Example
///

View File

@ -21,6 +21,7 @@ use core::prelude::*;
use self::StackOp::*;
use super::node::*;
use core::borrow::BorrowFrom;
use std::hash::{Writer, Hash};
use core::default::Default;
use core::{iter, fmt, mem};
@ -56,7 +57,7 @@ use ring_buf::RingBuf;
/// and possibly other factors. Using linear search, searching for a random element is expected
/// to take O(B log<sub>B</sub>n) comparisons, which is generally worse than a BST. In practice,
/// however, performance is excellent. `BTreeMap` is able to readily outperform `TreeMap` under
/// many workloads, and is competetive where it doesn't. BTreeMap also generally *scales* better
/// many workloads, and is competitive where it doesn't. BTreeMap also generally *scales* better
/// than TreeMap, making it more appropriate for large datasets.
///
/// However, `TreeMap` may still be more appropriate to use in many contexts. If elements are very
@ -184,6 +185,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// Returns a reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -195,7 +199,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// assert_eq!(map.get(&2), None);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn get(&self, key: &K) -> Option<&V> {
pub fn get<Sized? Q>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord {
let mut cur_node = &self.root;
loop {
match cur_node.search(key) {
@ -213,6 +217,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// 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 the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -224,7 +231,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// assert_eq!(map.contains_key(&2), false);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains_key(&self, key: &K) -> bool {
pub fn contains_key<Sized? Q>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + Ord {
self.get(key).is_some()
}
@ -236,6 +243,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// 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 the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -251,7 +261,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// ```
// See `get` for implementation notes, this is basically a copy-paste with mut's added
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
pub fn get_mut<Sized? Q>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom<K> + Ord {
// temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
let mut temp_node = &mut self.root;
loop {
@ -410,6 +420,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// 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 the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -421,7 +434,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// assert_eq!(map.remove(&1), None);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, key: &K) -> Option<V> {
pub fn remove<Sized? Q>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K> + Ord {
// See `swap` for a more thorough description of the stuff going on in here
let mut stack = stack::PartialSearchStack::new(self);
loop {
@ -790,14 +803,18 @@ impl<K: Show, V: Show> Show for BTreeMap<K, V> {
}
}
impl<K: Ord, V> Index<K, V> for BTreeMap<K, V> {
fn index(&self, key: &K) -> &V {
impl<K: Ord, Sized? Q, V> Index<Q, V> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
{
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}
impl<K: Ord, V> IndexMut<K, V> for BTreeMap<K, V> {
fn index_mut(&mut self, key: &K) -> &mut V {
impl<K: Ord, Sized? Q, V> IndexMut<Q, V> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
{
fn index_mut(&mut self, key: &Q) -> &mut V {
self.get_mut(key).expect("no entry found for key")
}
}

View File

@ -19,6 +19,7 @@ use core::prelude::*;
use core::{slice, mem, ptr};
use core::iter::Zip;
use core::borrow::BorrowFrom;
use vec;
use vec::Vec;
@ -47,7 +48,7 @@ pub struct Node<K, V> {
// theory, if we take full control of allocation like HashMap's RawTable does,
// and restrict leaves to max size 256 (not unreasonable for a btree node) we can cut
// this down to just (ptr, cap: u8, size: u8, is_leaf: bool). With generic
// integer arguments, cap can even move into the the type, reducing this just to
// integer arguments, cap can even move into the type, reducing this just to
// (ptr, size, is_leaf). This could also have cache benefits for very small nodes, as keys
// could bleed into edges and vals.
//
@ -73,19 +74,19 @@ impl<K: Ord, V> Node<K, V> {
/// Searches for the given key in the node. If it finds an exact match,
/// `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(&self, key: &K) -> SearchResult {
pub fn search<Sized? Q>(&self, key: &Q) -> SearchResult where Q: BorrowFrom<K> + 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 uints.
self.search_linear(key)
}
fn search_linear(&self, key: &K) -> SearchResult {
fn search_linear<Sized? Q>(&self, key: &Q) -> SearchResult where Q: BorrowFrom<K> + Ord {
for (i, k) in self.keys.iter().enumerate() {
match k.cmp(key) {
Less => {},
match key.cmp(BorrowFrom::borrow_from(k)) {
Greater => {},
Equal => return Found(i),
Greater => return GoDown(i),
Less => return GoDown(i),
}
}
GoDown(self.len())

View File

@ -15,6 +15,7 @@ use core::prelude::*;
use btree_map::{BTreeMap, Keys, MoveEntries};
use std::hash::Hash;
use core::borrow::BorrowFrom;
use core::default::Default;
use core::{iter, fmt};
use core::iter::Peekable;
@ -167,6 +168,10 @@ impl<T: Ord> BTreeSet<T> {
/// Returns `true` if the set contains a value.
///
/// The value may be any borrowed form of the set's value type,
/// but the ordering on the borrowed form *must* match the
/// ordering on the value type.
///
/// # Example
///
/// ```
@ -177,7 +182,7 @@ impl<T: Ord> BTreeSet<T> {
/// assert_eq!(set.contains(&4), false);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains(&self, value: &T) -> bool {
pub fn contains<Sized? Q>(&self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
self.map.contains_key(value)
}
@ -291,6 +296,10 @@ impl<T: Ord> BTreeSet<T> {
/// 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 the ordering on the borrowed form *must* match the
/// ordering on the value type.
///
/// # Example
///
/// ```
@ -303,7 +312,7 @@ impl<T: Ord> BTreeSet<T> {
/// assert_eq!(set.remove(&2), false);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, value: &T) -> bool {
pub fn remove<Sized? Q>(&mut self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
self.map.remove(value).is_some()
}
}

View File

@ -89,6 +89,7 @@
use self::Direction::*;
use alloc::boxed::Box;
use core::borrow::{BorrowFrom, BorrowFromMut};
use core::cmp;
use core::kinds::Sized;
use core::mem::size_of;
@ -647,6 +648,16 @@ impl<T> SliceAllocPrelude<T> for [T] {
}
}
#[unstable = "trait is unstable"]
impl<T> BorrowFrom<Vec<T>> for [T] {
fn borrow_from(owned: &Vec<T>) -> &[T] { owned[] }
}
#[unstable = "trait is unstable"]
impl<T> BorrowFromMut<Vec<T>> for [T] {
fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned[mut] }
}
/// Unsafe operations
pub mod raw {
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};

View File

@ -54,7 +54,7 @@
pub use self::MaybeOwned::*;
use self::RecompositionState::*;
use self::DecompositionType::*;
use core::borrow::BorrowFrom;
use core::default::Default;
use core::fmt;
use core::cmp;
@ -604,6 +604,11 @@ impl<'a> fmt::Show for MaybeOwned<'a> {
}
}
#[unstable = "trait is unstable"]
impl BorrowFrom<String> for str {
fn borrow_from(owned: &String) -> &str { owned[] }
}
/// Unsafe string operations.
pub mod raw {
pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
@ -1258,13 +1263,13 @@ mod tests {
#[test]
fn test_slice_shift_char() {
let data = "ประเทศไทย中";
assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中"));
assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
}
#[test]
fn test_slice_shift_char_2() {
let empty = "";
assert_eq!(empty.slice_shift_char(), (None, ""));
assert_eq!(empty.slice_shift_char(), None);
}
#[test]

View File

@ -549,7 +549,7 @@ impl String {
///
/// # Warning
///
/// This is a O(n) operation as it requires copying every element in the
/// This is an O(n) operation as it requires copying every element in the
/// buffer.
///
/// # Panics
@ -586,7 +586,7 @@ impl String {
///
/// # Warning
///
/// This is a O(n) operation as it requires copying every element in the
/// This is an O(n) operation as it requires copying every element in the
/// buffer.
///
/// # Panics

View File

@ -11,6 +11,8 @@
use core::prelude::*;
use alloc::boxed::Box;
use core::borrow::BorrowFrom;
use core::default::Default;
use core::fmt;
use core::fmt::Show;
@ -188,16 +190,16 @@ impl<K: Ord, V> Default for TreeMap<K,V> {
fn default() -> TreeMap<K, V> { TreeMap::new() }
}
impl<K: Ord, V> Index<K, V> for TreeMap<K, V> {
impl<K: Ord, Sized? Q, V> Index<Q, V> for TreeMap<K, V> where Q: BorrowFrom<K> + Ord {
#[inline]
fn index<'a>(&'a self, i: &K) -> &'a V {
fn index<'a>(&'a self, i: &Q) -> &'a V {
self.get(i).expect("no entry found for key")
}
}
impl<K: Ord, V> IndexMut<K, V> for TreeMap<K, V> {
impl<K: Ord, Sized? Q, V> IndexMut<Q, V> for TreeMap<K, V> where Q: BorrowFrom<K> + Ord {
#[inline]
fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V {
fn index_mut<'a>(&'a mut self, i: &Q) -> &'a mut V {
self.get_mut(i).expect("no entry found for key")
}
}
@ -446,6 +448,9 @@ impl<K: Ord, V> TreeMap<K, V> {
/// Returns a reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -458,12 +463,17 @@ impl<K: Ord, V> TreeMap<K, V> {
/// ```
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn get(&self, key: &K) -> Option<&V> {
tree_find_with(&self.root, |k2| key.cmp(k2))
pub fn get<Sized? Q>(&self, key: &Q) -> Option<&V>
where Q: BorrowFrom<K> + Ord
{
tree_find_with(&self.root, |k2| key.cmp(BorrowFrom::borrow_from(k2)))
}
/// 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 the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -476,7 +486,9 @@ impl<K: Ord, V> TreeMap<K, V> {
/// ```
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains_key(&self, key: &K) -> bool {
pub fn contains_key<Sized? Q>(&self, key: &Q) -> bool
where Q: BorrowFrom<K> + Ord
{
self.get(key).is_some()
}
@ -488,6 +500,9 @@ impl<K: Ord, V> TreeMap<K, V> {
/// 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 the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -503,8 +518,10 @@ impl<K: Ord, V> TreeMap<K, V> {
/// ```
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
tree_find_with_mut(&mut self.root, |x| key.cmp(x))
pub fn get_mut<Sized? Q>(&mut self, key: &Q) -> Option<&mut V>
where Q: BorrowFrom<K> + Ord
{
tree_find_with_mut(&mut self.root, |x| key.cmp(BorrowFrom::borrow_from(x)))
}
/// Deprecated: Renamed to `insert`.
@ -545,6 +562,9 @@ impl<K: Ord, V> TreeMap<K, V> {
/// 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 the ordering
/// on the borrowed form *must* match the ordering on the key type.
///
/// # Example
///
/// ```
@ -556,7 +576,9 @@ impl<K: Ord, V> TreeMap<K, V> {
/// assert_eq!(map.remove(&1), None);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, key: &K) -> Option<V> {
pub fn remove<Sized? Q>(&mut self, key: &Q) -> Option<V>
where Q: BorrowFrom<K> + Ord
{
let ret = remove(&mut self.root, key);
if ret.is_some() { self.length -= 1 }
ret
@ -589,6 +611,7 @@ impl<K, V> TreeMap<K, V> {
/// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1");
/// ```
#[inline]
#[experimental = "likely to be renamed, may be removed"]
pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> {
tree_find_with(&self.root, f)
}
@ -613,6 +636,7 @@ impl<K, V> TreeMap<K, V> {
/// assert_eq!(t.get(&"User-Agent"), Some(&new_ua));
/// ```
#[inline]
#[experimental = "likely to be renamed, may be removed"]
pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
tree_find_with_mut(&mut self.root, f)
}
@ -1168,10 +1192,11 @@ fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
}
}
fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
key: &K) -> Option<V> {
fn remove<K, Sized? Q, V>(node: &mut Option<Box<TreeNode<K, V>>>, key: &Q) -> Option<V>
where K: Ord, Q: BorrowFrom<K> + Ord
{
fn heir_swap<K: Ord, V>(node: &mut Box<TreeNode<K, V>>,
child: &mut Option<Box<TreeNode<K, V>>>) {
child: &mut Option<Box<TreeNode<K, V>>>) {
// *could* be done without recursion, but it won't borrow check
for x in child.iter_mut() {
if x.right.is_some() {
@ -1188,7 +1213,7 @@ fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
return None; // bottom of tree
}
Some(ref mut save) => {
let (ret, rebalance) = match key.cmp(&save.key) {
let (ret, rebalance) = match key.cmp(BorrowFrom::borrow_from(&save.key)) {
Less => (remove(&mut save.left, key), true),
Greater => (remove(&mut save.right, key), true),
Equal => {
@ -1918,4 +1943,3 @@ mod bench {
bench_iter(b, 100000);
}
}

View File

@ -33,4 +33,4 @@
//! ```
pub mod map;
pub mod set;
pub mod set;

View File

@ -10,6 +10,7 @@
use core::prelude::*;
use core::borrow::BorrowFrom;
use core::default::Default;
use core::fmt;
use core::fmt::Show;
@ -396,6 +397,10 @@ impl<T: Ord> TreeSet<T> {
/// Returns `true` if the set contains a value.
///
/// The value may be any borrowed form of the set's value type,
/// but the ordering on the borrowed form *must* match the
/// ordering on the value type.
///
/// # Example
///
/// ```
@ -407,7 +412,9 @@ impl<T: Ord> TreeSet<T> {
/// ```
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains(&self, value: &T) -> bool {
pub fn contains<Sized? Q>(&self, value: &Q) -> bool
where Q: Ord + BorrowFrom<T>
{
self.map.contains_key(value)
}
@ -519,6 +526,10 @@ impl<T: Ord> TreeSet<T> {
/// 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 the ordering on the borrowed form *must* match the
/// ordering on the value type.
///
/// # Example
///
/// ```
@ -532,7 +543,11 @@ impl<T: Ord> TreeSet<T> {
/// ```
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() }
pub fn remove<Sized? Q>(&mut self, value: &Q) -> bool
where Q: Ord + BorrowFrom<T>
{
self.map.remove(value).is_some()
}
}
/// A lazy forward iterator over a set.

View File

@ -1057,7 +1057,7 @@ impl<'a, T> VacantEntry<'a, T> {
search_stack.map.root.count = temp;
value_ref
}
// Otherwise, find the predeccessor of the last stack node, and insert as normal.
// Otherwise, find the predecessor of the last stack node, and insert as normal.
else {
match *search_stack.get_ref(old_length - 2) {
Internal(box ref mut parent) => {
@ -1741,7 +1741,7 @@ mod test {
// Update it to i^3 using the returned mutable reference.
*inserted_val = i * i * i;
},
_ => panic!("Non-existant key found.")
_ => panic!("Non-existent key found.")
}
assert_eq!(map.get(&i).unwrap(), &(i * i * i));
}

View File

@ -17,4 +17,4 @@
//! `TrieMap` is ordered.
pub mod map;
pub mod set;
pub mod set;

View File

@ -8,22 +8,36 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
* Implementations of things like `Eq` for fixed-length arrays
* up to a certain length. Eventually we should able to generalize
* to all lengths.
*/
//! Implementations of things like `Eq` for fixed-length arrays
//! up to a certain length. Eventually we should able to generalize
//! to all lengths.
#![stable]
#![experimental] // not yet reviewed
use cmp::*;
use option::{Option};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use fmt;
use kinds::Copy;
use option::Option;
// macro for implementing n-ary tuple functions and operations
macro_rules! array_impls {
($($N:expr)+) => {
$(
#[unstable = "waiting for Clone to stabilize"]
impl<T:Copy> Clone for [T, ..$N] {
fn clone(&self) -> [T, ..$N] {
*self
}
}
#[unstable = "waiting for Show to stabilize"]
impl<T:fmt::Show> fmt::Show for [T, ..$N] {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Show::fmt(&self[], f)
}
}
#[unstable = "waiting for PartialEq to stabilize"]
impl<T:PartialEq> PartialEq for [T, ..$N] {
#[inline]

127
src/libcore/borrow.rs Normal file
View File

@ -0,0 +1,127 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! 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<T>` 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<U>`, then `&T` can be borrowed from `&U`. A given
//! type can be borrowed as multiple different types. In particular, `Vec<T>:
//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`.
//!
//! # 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` and `DerefMut`, which means that you can call
//! methods directly on the data it encloses. The first time a mutable reference
//! is required, the data will be cloned (via `to_owned`) if it is not
//! already owned.
#![unstable = "recently added as part of collections reform"]
use clone::Clone;
use kinds::Sized;
use ops::Deref;
use self::Cow::*;
/// A trait for borrowing data.
pub trait BorrowFrom<Sized? Owned> for Sized? {
/// Immutably borrow from an owned value.
fn borrow_from(owned: &Owned) -> &Self;
}
/// A trait for mutably borrowing data.
pub trait BorrowFromMut<Sized? Owned> for Sized? : BorrowFrom<Owned> {
/// Mutably borrow from an owned value.
fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
}
impl<Sized? T> BorrowFrom<T> for T {
fn borrow_from(owned: &T) -> &T { owned }
}
impl<Sized? T> BorrowFromMut<T> for T {
fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
}
impl BorrowFrom<&'static str> for str {
fn borrow_from<'a>(owned: &'a &'static str) -> &'a str { &**owned }
}
/// A generalization of Clone to borrowed data.
pub trait ToOwned<Owned> for Sized?: BorrowFrom<Owned> {
/// Create owned data from borrowed data, usually by copying.
fn to_owned(&self) -> Owned;
}
impl<T> ToOwned<T> for T where T: Clone {
fn to_owned(&self) -> T { self.clone() }
}
/// A clone-on-write smart pointer.
pub enum Cow<'a, T, B: 'a> where B: ToOwned<T> {
/// Borrowed data.
Borrowed(&'a B),
/// Owned data.
Owned(T)
}
impl<'a, T, B> Cow<'a, T, B> where B: ToOwned<T> {
/// 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
}
}
}
impl<'a, T, B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> {
fn deref(&self) -> &B {
match *self {
Borrowed(borrowed) => borrowed,
Owned(ref owned) => BorrowFrom::borrow_from(owned)
}
}
}

View File

@ -23,6 +23,8 @@ the `clone` method.
#![unstable]
use kinds::Sized;
/// A common trait for cloning an object.
pub trait Clone {
/// Returns a copy of the value.
@ -40,24 +42,12 @@ pub trait Clone {
}
}
impl<'a, T> Clone for &'a T {
impl<'a, Sized? T> Clone for &'a T {
/// Return a shallow copy of the reference.
#[inline]
fn clone(&self) -> &'a T { *self }
}
impl<'a, T> Clone for &'a [T] {
/// Return a shallow copy of the slice.
#[inline]
fn clone(&self) -> &'a [T] { *self }
}
impl<'a> Clone for &'a str {
/// Return a shallow copy of the slice.
#[inline]
fn clone(&self) -> &'a str { *self }
}
macro_rules! clone_impl(
($t:ty) => {
impl Clone for $t {

View File

@ -108,6 +108,7 @@ pub mod default;
pub mod any;
pub mod atomic;
pub mod bool;
pub mod borrow;
pub mod cell;
pub mod char;
pub mod panicking;

View File

@ -88,7 +88,7 @@ pub fn align_of_val<T>(_val: &T) -> uint {
/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a a local variable and
/// This function is similar to allocating space for a local variable and
/// zeroing it out (an unsafe operation).
///
/// Care must be taken when using this function, if the type `T` has a

View File

@ -198,7 +198,7 @@ pub trait Int
/// ```
fn swap_bytes(self) -> Self;
/// Convert a integer from big endian to the target's endianness.
/// Convert an integer from big endian to the target's endianness.
///
/// On big endian this is a no-op. On little endian the bytes are swapped.
///
@ -220,7 +220,7 @@ pub trait Int
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
}
/// Convert a integer from little endian to the target's endianness.
/// Convert an integer from little endian to the target's endianness.
///
/// On little endian this is a no-op. On big endian the bytes are swapped.
///
@ -1457,10 +1457,10 @@ macro_rules! from_str_radix_float_impl {
}
let (is_positive, src) = match src.slice_shift_char() {
(None, _) => return None,
(Some('-'), "") => return None,
(Some('-'), src) => (false, src),
(Some(_), _) => (true, src),
None => return None,
Some(('-', "")) => return None,
Some(('-', src)) => (false, src),
Some((_, _)) => (true, src),
};
// The significand to accumulate
@ -1563,10 +1563,10 @@ macro_rules! from_str_radix_float_impl {
// Parse the exponent as decimal integer
let src = src[offset..];
let (is_positive, exp) = match src.slice_shift_char() {
(Some('-'), src) => (false, from_str::<uint>(src)),
(Some('+'), src) => (true, from_str::<uint>(src)),
(Some(_), _) => (true, from_str::<uint>(src)),
(None, _) => return None,
Some(('-', src)) => (false, from_str::<uint>(src)),
Some(('+', src)) => (true, from_str::<uint>(src)),
Some((_, _)) => (true, from_str::<uint>(src)),
None => return None,
};
match (is_positive, exp) {
@ -1606,7 +1606,7 @@ macro_rules! from_str_radix_int_impl {
let is_signed_ty = (0 as $T) > Int::min_value();
match src.slice_shift_char() {
(Some('-'), src) if is_signed_ty => {
Some(('-', src)) if is_signed_ty => {
// The number is negative
let mut result = 0;
for c in src.chars() {
@ -1625,7 +1625,7 @@ macro_rules! from_str_radix_int_impl {
}
Some(result)
},
(Some(_), _) => {
Some((_, _)) => {
// The number is signed
let mut result = 0;
for c in src.chars() {
@ -1644,7 +1644,7 @@ macro_rules! from_str_radix_int_impl {
}
Some(result)
},
(None, _) => None,
None => None,
}
}
}

View File

@ -638,7 +638,7 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
* ```
*/
#[lang="index"]
pub trait Index<Index, Sized? Result> for Sized? {
pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
}
@ -669,7 +669,7 @@ pub trait Index<Index, Sized? Result> for Sized? {
* ```
*/
#[lang="index_mut"]
pub trait IndexMut<Index, Result> for Sized? {
pub trait IndexMut<Sized? Index, Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
}

View File

@ -1811,21 +1811,21 @@ pub trait StrPrelude for Sized? {
/// it. This does not allocate a new string; instead, it returns a
/// slice that point one character beyond the character that was
/// shifted. If the string does not contain any characters,
/// a tuple of None and an empty string is returned instead.
/// None is returned instead.
///
/// # Example
///
/// ```rust
/// let s = "Löwe 老虎 Léopard";
/// let (c, s1) = s.slice_shift_char();
/// assert_eq!(c, Some('L'));
/// let (c, s1) = s.slice_shift_char().unwrap();
/// assert_eq!(c, 'L');
/// assert_eq!(s1, "öwe 老虎 Léopard");
///
/// let (c, s2) = s1.slice_shift_char();
/// assert_eq!(c, Some('ö'));
/// let (c, s2) = s1.slice_shift_char().unwrap();
/// assert_eq!(c, 'ö');
/// assert_eq!(s2, "we 老虎 Léopard");
/// ```
fn slice_shift_char<'a>(&'a self) -> (Option<char>, &'a str);
fn slice_shift_char<'a>(&'a self) -> Option<(char, &'a str)>;
/// Returns the byte offset of an inner slice relative to an enclosing outer slice.
///
@ -2197,13 +2197,13 @@ impl StrPrelude for str {
}
#[inline]
fn slice_shift_char(&self) -> (Option<char>, &str) {
fn slice_shift_char(&self) -> Option<(char, &str)> {
if self.is_empty() {
return (None, self);
None
} else {
let CharRange {ch, next} = self.char_range_at(0u);
let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
return (Some(ch), next_s);
Some((ch, next_s))
}
}

View File

@ -60,10 +60,10 @@ pub fn render_to<W:Writer>(output: &mut W) {
}
impl<'a> dot::Labeller<'a, Nd, Ed> for Edges {
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example1") }
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example1").unwrap() }
fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
dot::Id::new(format!("N{}", *n))
dot::Id::new(format!("N{}", *n)).unwrap()
}
}
@ -163,9 +163,9 @@ pub fn render_to<W:Writer>(output: &mut W) {
}
impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph {
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example2") }
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example2").unwrap() }
fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
dot::Id::new(format!("N{}", n))
dot::Id::new(format!("N{}", n)).unwrap()
}
fn node_label<'a>(&'a self, n: &Nd) -> dot::LabelText<'a> {
dot::LabelStr(str::Slice(self.nodes[*n].as_slice()))
@ -219,9 +219,9 @@ pub fn render_to<W:Writer>(output: &mut W) {
}
impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph {
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example3") }
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example3").unwrap() }
fn node_id(&'a self, n: &Nd<'a>) -> dot::Id<'a> {
dot::Id::new(format!("N{:u}", n.val0()))
dot::Id::new(format!("N{:u}", n.val0())).unwrap()
}
fn node_label<'a>(&'a self, n: &Nd<'a>) -> dot::LabelText<'a> {
let &(i, _) = n;
@ -354,14 +354,22 @@ impl<'a> Id<'a> {
/// defined by the DOT language. This function may change in the
/// future to accept a broader subset, or the entirety, of DOT's
/// `ID` format.)
pub fn new<Name:str::IntoMaybeOwned<'a>>(name: Name) -> Id<'a> {
///
/// Passing an invalid string (containing spaces, brackets,
/// quotes, ...) will return an empty `Err` value.
pub fn new<Name:str::IntoMaybeOwned<'a>>(name: Name) -> Result<Id<'a>, ()> {
let name = name.into_maybe_owned();
{
let mut chars = name.as_slice().chars();
assert!(is_letter_or_underscore(chars.next().unwrap()));
assert!(chars.all(is_constituent));
match chars.next() {
Some(c) if is_letter_or_underscore(c) => { ; },
_ => return Err(())
}
if !chars.all(is_constituent) {
return Err(());
}
}
return Id{ name: name };
return Ok(Id{ name: name });
fn is_letter_or_underscore(c: char) -> bool {
in_range('a', c, 'z') || in_range('A', c, 'Z') || c == '_'
@ -627,12 +635,12 @@ mod tests {
}
fn id_name<'a>(n: &Node) -> Id<'a> {
Id::new(format!("N{:u}", *n))
Id::new(format!("N{:u}", *n)).unwrap()
}
impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph {
fn graph_id(&'a self) -> Id<'a> {
Id::new(self.name.as_slice())
Id::new(self.name.as_slice()).unwrap()
}
fn node_id(&'a self, n: &Node) -> Id<'a> {
id_name(n)
@ -825,4 +833,22 @@ r#"digraph syntax_tree {
}
"#);
}
#[test]
fn simple_id_construction() {
let id1 = Id::new("hello");
match id1 {
Ok(_) => {;},
Err(_) => panic!("'hello' is not a valid value for id anymore")
}
}
#[test]
fn badly_formatted_id() {
let id2 = Id::new("Weird { struct : ure } !!!");
match id2 {
Ok(_) => panic!("graphviz id suddenly allows spaces, brackets and stuff"),
Err(_) => {;}
}
}
}

View File

@ -137,7 +137,7 @@
//! includes 'foo'.
//! * `info/f.o` turns on all info logging where the log message includes 'foo',
//! 'f1o', 'fao', etc.
//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the the log
//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log
//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.
//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for
//! hello. In both cases the log message must include a single digit number

View File

@ -561,7 +561,7 @@ pub struct NoExpand<'t>(pub &'t str);
/// Replacer describes types that can be used to replace matches in a string.
pub trait Replacer {
/// Returns a possibly owned string that is used to replace the match
/// corresponding the the `caps` capture group.
/// corresponding to the `caps` capture group.
///
/// The `'a` lifetime refers to the lifetime of a borrowed string when
/// a new owned string isn't needed (e.g., for `NoExpand`).
@ -726,7 +726,7 @@ impl<'t> Captures<'t> {
match self.named {
None => "",
Some(ref h) => {
match h.find_equiv(name) {
match h.get(name) {
None => "",
Some(i) => self.at(*i),
}

View File

@ -728,7 +728,9 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
if sess.target.target.options.morestack {
ab.add_native_library("morestack").unwrap();
}
ab.add_native_library("compiler-rt").unwrap();
if !sess.target.target.options.no_compiler_rt {
ab.add_native_library("compiler-rt").unwrap();
}
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
let mut all_native_libs = vec![];

View File

@ -143,5 +143,6 @@ register_diagnostics!(
E0164,
E0165,
E0166,
E0167
E0167,
E0168
)

View File

@ -623,6 +623,7 @@ impl LintPass for UnusedAttributes {
"link",
"link_name",
"link_section",
"linkage",
"no_builtins",
"no_mangle",
"no_split_stack",

View File

@ -165,7 +165,7 @@ impl LintStore {
}
fn register_renamed(&mut self, old_name: &str, new_name: &str) {
let target = match self.by_name.find_equiv(new_name) {
let target = match self.by_name.get(new_name) {
Some(&Id(lint_id)) => lint_id.clone(),
_ => panic!("invalid lint renaming of {} to {}", old_name, new_name)
};
@ -259,7 +259,7 @@ impl LintStore {
fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
-> Option<LintId>
{
match self.by_name.find_equiv(lint_name) {
match self.by_name.get(lint_name) {
Some(&Id(lint_id)) => Some(lint_id),
Some(&Renamed(ref new_name, lint_id)) => {
let warning = format!("lint {} has been renamed to {}",
@ -282,7 +282,7 @@ impl LintStore {
match self.lint_groups.iter().map(|(&x, pair)| (x, pair.ref0().clone()))
.collect::<FnvHashMap<&'static str,
Vec<LintId>>>()
.find_equiv(lint_name.as_slice()) {
.get(lint_name.as_slice()) {
Some(v) => {
v.iter()
.map(|lint_id: &LintId|
@ -489,7 +489,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
match self.lints.find_lint(lint_name.get(), &self.tcx.sess, Some(span)) {
Some(lint_id) => vec![(lint_id, level, span)],
None => {
match self.lints.lint_groups.find_equiv(lint_name.get()) {
match self.lints.lint_groups.get(lint_name.get()) {
Some(&(ref v, _)) => v.iter()
.map(|lint_id: &LintId|
(*lint_id, level, span))

View File

@ -242,6 +242,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
cstore::NativeFramework
} else if k.equiv(&("framework")) {
cstore::NativeFramework
} else if k.equiv(&("dylib")) {
cstore::NativeUnknown
} else {
e.sess.span_err(m.span,
format!("unknown kind: `{}`",
@ -321,7 +323,7 @@ fn existing_match(e: &Env, name: &str,
// `source` stores paths which are normalized which may be different
// from the strings on the command line.
let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
match e.sess.opts.externs.find_equiv(name) {
match e.sess.opts.externs.get(name) {
Some(locs) => {
let found = locs.iter().any(|l| {
let l = fs::realpath(&Path::new(l.as_slice())).ok();

View File

@ -298,7 +298,7 @@ fn item_path(item_doc: rbml::Doc) -> Vec<ast_map::PathElem> {
fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
let name = reader::get_doc(item, tag_paths_data_name);
let string = name.as_str_slice();
match intr.find_equiv(string) {
match intr.find(string) {
None => token::intern(string),
Some(val) => val,
}
@ -1449,4 +1449,3 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
Some(item) => item_sort(item) == 't',
}
}

View File

@ -54,7 +54,7 @@ impl<'a> FileSearch<'a> {
debug!("filesearch: searching lib path");
let tlib_path = make_target_lib_path(self.sysroot,
self.triple);
if !visited_dirs.contains_equiv(tlib_path.as_vec()) {
if !visited_dirs.contains(tlib_path.as_vec()) {
match f(&tlib_path) {
FileMatches => found = true,
FileDoesntMatch => ()
@ -69,9 +69,9 @@ impl<'a> FileSearch<'a> {
let tlib_path = make_rustpkg_lib_path(
self.sysroot, path, self.triple);
debug!("is {} in visited_dirs? {}", tlib_path.display(),
visited_dirs.contains_equiv(&tlib_path.as_vec().to_vec()));
visited_dirs.contains(&tlib_path.as_vec().to_vec()));
if !visited_dirs.contains_equiv(tlib_path.as_vec()) {
if !visited_dirs.contains(tlib_path.as_vec()) {
visited_dirs.insert(tlib_path.as_vec().to_vec());
// Don't keep searching the RUST_PATH if one match turns up --
// if we did, we'd get a "multiple matching crates" error

View File

@ -596,7 +596,7 @@ impl<'a> Context<'a> {
}
fn find_commandline_library(&mut self) -> Option<Library> {
let locs = match self.sess.opts.externs.find_equiv(self.crate_name) {
let locs = match self.sess.opts.externs.get(self.crate_name) {
Some(s) => s,
None => return None,
};

View File

@ -50,10 +50,10 @@ fn replace_newline_with_backslash_l(s: String) -> String {
}
impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(self.name.as_slice()) }
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(self.name.as_slice()).unwrap() }
fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> {
dot::Id::new(format!("N{:u}", i.node_id()))
dot::Id::new(format!("N{:u}", i.node_id())).unwrap()
}
fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> {

View File

@ -132,7 +132,7 @@ impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
fn visit_item(&mut self, item: &ast::Item) {
match extract(item.attrs.as_slice()) {
Some(value) => {
let item_index = self.item_refs.find_equiv(&value).map(|x| *x);
let item_index = self.item_refs.get(value.get()).map(|x| *x);
match item_index {
Some(item_index) => {

View File

@ -79,14 +79,17 @@ impl<'v> Visitor<'v> for Annotator {
}
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, _: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
_: &'v Block, _: Span, _: NodeId) {
match fk {
FkMethod(_, _, meth) => {
self.annotate(meth.id, &meth.attrs, |v| visit::walk_fn(v, fk, fd, b, s));
// Methods are not already annotated, so we annotate it
self.annotate(meth.id, &meth.attrs, |_| {});
}
_ => visit::walk_fn(self, fk, fd, b, s)
_ => {}
}
// Items defined in a function body have no reason to have
// a stability attribute, so we don't recurse.
}
fn visit_trait_item(&mut self, t: &TraitItem) {

View File

@ -353,7 +353,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// matches this obligation, then we can assume that the
// obligation is satisfied for now (still all other conditions
// must be met of course). One obvious case this comes up is
// marker traits like `Send`. Think of a a linked list:
// marker traits like `Send`. Think of a linked list:
//
// struct List<T> { data: T, next: Option<Box<List<T>>> {
//

View File

@ -36,7 +36,7 @@ use driver::config::{NoDebugInfo, FullDebugInfo};
use driver::driver::{CrateAnalysis, CrateTranslation, ModuleTranslation};
use driver::session::Session;
use lint;
use llvm::{BasicBlockRef, ValueRef, Vector, get_param};
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
use llvm;
use metadata::{csearch, encoder, loader};
use middle::astencode;
@ -216,7 +216,7 @@ pub fn get_extern_fn(ccx: &CrateContext,
ty: Type,
output: ty::t)
-> ValueRef {
match externs.find_equiv(name) {
match externs.get(name) {
Some(n) => return *n,
None => {}
}
@ -226,7 +226,7 @@ pub fn get_extern_fn(ccx: &CrateContext,
}
fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::DefId) -> ValueRef {
match ccx.externs().borrow().find_equiv(name) {
match ccx.externs().borrow().get(name) {
Some(n) => return *n,
None => ()
}
@ -2137,6 +2137,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> {
}
}
pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
// applicable to variable declarations and may not really make sense for
// Rust code in the first place but whitelist them anyway and trust that
// the user knows what s/he's doing. Who knows, unanticipated use cases
// may pop up in the future.
//
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
// and don't have to be, LLVM treats them as no-ops.
match name {
"appending" => Some(llvm::AppendingLinkage),
"available_externally" => Some(llvm::AvailableExternallyLinkage),
"common" => Some(llvm::CommonLinkage),
"extern_weak" => Some(llvm::ExternalWeakLinkage),
"external" => Some(llvm::ExternalLinkage),
"internal" => Some(llvm::InternalLinkage),
"linkonce" => Some(llvm::LinkOnceAnyLinkage),
"linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
"private" => Some(llvm::PrivateLinkage),
"weak" => Some(llvm::WeakAnyLinkage),
"weak_odr" => Some(llvm::WeakODRLinkage),
_ => None,
}
}
/// Enum describing the origin of an LLVM `Value`, for linkage purposes.
pub enum ValueOrigin {
/// The LLVM `Value` is in this context because the corresponding item was
@ -2174,6 +2200,23 @@ pub fn update_linkage(ccx: &CrateContext,
OriginalTranslation => {},
}
match id {
Some(id) => {
let item = ccx.tcx().map.get(id);
if let ast_map::NodeItem(i) = item {
if let Some(name) = attr::first_attr_value_str_by_name(i.attrs[], "linkage") {
if let Some(linkage) = llvm_linkage_by_name(name.get()) {
llvm::SetLinkage(llval, linkage);
} else {
ccx.sess().span_fatal(i.span, "invalid linkage specified");
}
return;
}
}
}
_ => {}
}
match id {
Some(id) if ccx.reachable().contains(&id) => {
llvm::SetLinkage(llval, llvm::ExternalLinkage);
@ -2983,7 +3026,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
let name = CString::new(llvm::LLVMGetValueName(val), false);
if !declared.contains(&name) &&
!reachable.contains_equiv(name.as_str().unwrap()) {
!reachable.contains(name.as_str().unwrap()) {
llvm::SetLinkage(val, llvm::InternalLinkage);
}
}

View File

@ -1677,7 +1677,7 @@ fn declare_local(bcx: Block,
}
fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
match debug_context(cx).created_files.borrow().find_equiv(full_path) {
match debug_context(cx).created_files.borrow().get(full_path) {
Some(file_metadata) => return *file_metadata,
None => ()
}

View File

@ -10,10 +10,10 @@
use back::{link};
use llvm::{ValueRef, CallConv, Linkage, get_param};
use llvm::{ValueRef, CallConv, get_param};
use llvm;
use middle::weak_lang_items;
use middle::trans::base::push_ctxt;
use middle::trans::base::{llvm_linkage_by_name, push_ctxt};
use middle::trans::base;
use middle::trans::build::*;
use middle::trans::cabi;
@ -101,31 +101,6 @@ pub fn llvm_calling_convention(ccx: &CrateContext,
}
}
pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
// applicable to variable declarations and may not really make sense for
// Rust code in the first place but whitelist them anyway and trust that
// the user knows what s/he's doing. Who knows, unanticipated use cases
// may pop up in the future.
//
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
// and don't have to be, LLVM treats them as no-ops.
match name {
"appending" => Some(llvm::AppendingLinkage),
"available_externally" => Some(llvm::AvailableExternallyLinkage),
"common" => Some(llvm::CommonLinkage),
"extern_weak" => Some(llvm::ExternalWeakLinkage),
"external" => Some(llvm::ExternalLinkage),
"internal" => Some(llvm::InternalLinkage),
"linkonce" => Some(llvm::LinkOnceAnyLinkage),
"linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
"private" => Some(llvm::PrivateLinkage),
"weak" => Some(llvm::WeakAnyLinkage),
"weak_odr" => Some(llvm::WeakODRLinkage),
_ => None,
}
}
pub fn register_static(ccx: &CrateContext,
foreign_item: &ast::ForeignItem) -> ValueRef {
let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);

View File

@ -336,7 +336,7 @@ impl TypeNames {
}
pub fn find_type(&self, s: &str) -> Option<Type> {
self.named_types.borrow().find_equiv(s).map(|x| Type::from_ref(*x))
self.named_types.borrow().get(s).map(|x| Type::from_ref(*x))
}
pub fn type_to_string(&self, ty: Type) -> String {

View File

@ -297,22 +297,38 @@ pub fn check_pat_struct(pcx: &pat_ctxt, pat: &ast::Pat,
let tcx = pcx.fcx.ccx.tcx;
let def = tcx.def_map.borrow()[pat.id].clone();
let def_type = ty::lookup_item_type(tcx, def.def_id());
let (enum_def_id, variant_def_id) = match ty::get(def_type.ty).sty {
ty::ty_struct(struct_def_id, _) =>
(struct_def_id, struct_def_id),
ty::ty_enum(enum_def_id, _) if def == def::DefVariant(enum_def_id, def.def_id(), true) =>
(enum_def_id, def.def_id()),
_ => {
let (enum_def_id, variant_def_id) = match def {
def::DefTrait(_) => {
let name = pprust::path_to_string(path);
span_err!(tcx.sess, pat.span, E0163,
"`{}` does not name a struct or a struct variant", name);
span_err!(tcx.sess, pat.span, E0168,
"use of trait `{}` in a struct pattern", name);
fcx.write_error(pat.id);
for field in fields.iter() {
check_pat(pcx, &*field.node.pat, ty::mk_err());
}
return;
},
_ => {
let def_type = ty::lookup_item_type(tcx, def.def_id());
match ty::get(def_type.ty).sty {
ty::ty_struct(struct_def_id, _) =>
(struct_def_id, struct_def_id),
ty::ty_enum(enum_def_id, _)
if def == def::DefVariant(enum_def_id, def.def_id(), true) =>
(enum_def_id, def.def_id()),
_ => {
let name = pprust::path_to_string(path);
span_err!(tcx.sess, pat.span, E0163,
"`{}` does not name a struct or a struct variant", name);
fcx.write_error(pat.id);
for field in fields.iter() {
check_pat(pcx, &*field.node.pat, ty::mk_err());
}
return;
}
}
}
};

View File

@ -2122,7 +2122,7 @@ impl<'a> fmt::Show for Sidebar<'a> {
fn block(w: &mut fmt::Formatter, short: &str, longty: &str,
cur: &clean::Item, cx: &Context) -> fmt::Result {
let items = match cx.sidebar.find_equiv(short) {
let items = match cx.sidebar.get(short) {
Some(items) => items.as_slice(),
None => return Ok(())
};

View File

@ -901,7 +901,7 @@ impl Json {
/// Otherwise, returns None.
pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
match self {
&Object(ref map) => map.find_with(|s| key.cmp(s.as_slice())),
&Object(ref map) => map.get(key),
_ => None
}
}
@ -926,7 +926,7 @@ impl Json {
pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
match self {
&Object(ref map) => {
match map.find_with(|s| key.cmp(s.as_slice())) {
match map.get(key) {
Some(json_value) => Some(json_value),
None => {
for (_, v) in map.iter() {

View File

@ -14,6 +14,7 @@ pub use self::Entry::*;
use self::SearchResult::*;
use self::VacantEntryState::*;
use borrow::BorrowFrom;
use clone::Clone;
use cmp::{max, Eq, Equiv, PartialEq};
use default::Default;
@ -142,7 +143,7 @@ impl DefaultResizePolicy {
// about the size of rust executables.
//
// Annotate exceedingly likely branches in `table::make_hash`
// and `search_hashed_generic` to reduce instruction cache pressure
// 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
@ -286,10 +287,10 @@ pub struct HashMap<K, V, H = RandomSipHasher> {
}
/// Search for a pre-hashed key.
fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
hash: &SafeHash,
is_match: |&K| -> bool)
-> SearchResult<K, V, M> {
fn search_hashed<K, V, M: Deref<RawTable<K, V>>>(table: M,
hash: &SafeHash,
is_match: |&K| -> bool)
-> SearchResult<K, V, M> {
let size = table.size();
let mut probe = Bucket::new(table, hash);
let ib = probe.index();
@ -325,11 +326,6 @@ fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
TableRef(probe.into_table())
}
fn search_hashed<K: Eq, V, M: Deref<RawTable<K, V>>>(table: M, hash: &SafeHash, k: &K)
-> SearchResult<K, V, M> {
search_hashed_generic(table, hash, |k_| *k == *k_)
}
fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
let (empty, retkey, retval) = starting_bucket.take();
let mut gap = match empty.gap_peek() {
@ -432,26 +428,32 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
-> Option<FullBucketImm<'a, K, V>> {
let hash = self.make_hash(q);
search_hashed_generic(&self.table, &hash, |k| q.equiv(k)).into_option()
search_hashed(&self.table, &hash, |k| q.equiv(k)).into_option()
}
fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
-> Option<FullBucketMut<'a, K, V>> {
let hash = self.make_hash(q);
search_hashed_generic(&mut self.table, &hash, |k| q.equiv(k)).into_option()
search_hashed(&mut self.table, &hash, |k| q.equiv(k)).into_option()
}
/// 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>(&'a self, k: &K) -> Option<FullBucketImm<'a, K, V>> {
let hash = self.make_hash(k);
search_hashed(&self.table, &hash, k).into_option()
fn search<'a, Sized? Q>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
where Q: BorrowFrom<K> + Eq + Hash<S>
{
let hash = self.make_hash(q);
search_hashed(&self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k)))
.into_option()
}
fn search_mut<'a>(&'a mut self, k: &K) -> Option<FullBucketMut<'a, K, V>> {
let hash = self.make_hash(k);
search_hashed(&mut self.table, &hash, k).into_option()
fn search_mut<'a, Sized? Q>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
where Q: BorrowFrom<K> + Eq + Hash<S>
{
let hash = self.make_hash(q);
search_hashed(&mut self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k)))
.into_option()
}
// The caller should ensure that invariants by Robin Hood Hashing hold.
@ -748,18 +750,14 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
}
}
/// Return true if the map contains a value for the specified key,
/// using equivalence.
///
/// See [pop_equiv](#method.pop_equiv) for an extended example.
/// Deprecated: use `contains_key` and `BorrowFrom` instead.
#[deprecated = "use contains_key and BorrowFrom instead"]
pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
self.search_equiv(key).is_some()
}
/// Return the value corresponding to the key in the map, using
/// equivalence.
///
/// See [pop_equiv](#method.pop_equiv) for an extended example.
/// Deprecated: use `get` and `BorrowFrom` instead.
#[deprecated = "use get and BorrowFrom instead"]
pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
match self.search_equiv(k) {
None => None,
@ -770,52 +768,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
}
}
/// Remove an equivalent key from the map, returning the value at the
/// key if the key was previously in the map.
///
/// # Example
///
/// This is a slightly silly example where we define the number's
/// parity as the equivalence class. It is important that the
/// values hash the same, which is why we implement `Hash`.
///
/// ```
/// use std::collections::HashMap;
/// use std::hash::Hash;
/// use std::hash::sip::SipState;
///
/// #[deriving(Eq, PartialEq)]
/// struct EvenOrOdd {
/// num: uint
/// };
///
/// impl Hash for EvenOrOdd {
/// fn hash(&self, state: &mut SipState) {
/// let parity = self.num % 2;
/// parity.hash(state);
/// }
/// }
///
/// impl Equiv<EvenOrOdd> for EvenOrOdd {
/// fn equiv(&self, other: &EvenOrOdd) -> bool {
/// self.num % 2 == other.num % 2
/// }
/// }
///
/// let mut map = HashMap::new();
/// map.insert(EvenOrOdd { num: 3 }, "foo");
///
/// assert!(map.contains_key_equiv(&EvenOrOdd { num: 1 }));
/// assert!(!map.contains_key_equiv(&EvenOrOdd { num: 4 }));
///
/// assert_eq!(map.find_equiv(&EvenOrOdd { num: 5 }), Some(&"foo"));
/// assert_eq!(map.find_equiv(&EvenOrOdd { num: 2 }), None);
///
/// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 1 }), Some("foo"));
/// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 2 }), None);
///
/// ```
#[experimental]
/// Deprecated: use `remove` and `BorrowFrom` instead.
#[deprecated = "use remove and BorrowFrom instead"]
pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
if self.table.size() == 0 {
return None
@ -1036,6 +990,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// 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
///
/// ```
@ -1047,7 +1005,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// assert_eq!(map.get(&2), None);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn get(&self, k: &K) -> Option<&V> {
pub fn get<Sized? Q>(&self, k: &Q) -> Option<&V>
where Q: Hash<S> + Eq + BorrowFrom<K>
{
self.search(k).map(|bucket| {
let (_, v) = bucket.into_refs();
v
@ -1056,6 +1016,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// 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
///
/// ```
@ -1067,7 +1031,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// assert_eq!(map.contains_key(&2), false);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains_key(&self, k: &K) -> bool {
pub fn contains_key<Sized? Q>(&self, k: &Q) -> bool
where Q: Hash<S> + Eq + BorrowFrom<K>
{
self.search(k).is_some()
}
@ -1079,6 +1045,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// 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
///
/// ```
@ -1093,7 +1063,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// assert_eq!(map[1], "b");
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
pub fn get_mut<Sized? Q>(&mut self, k: &Q) -> Option<&mut V>
where Q: Hash<S> + Eq + BorrowFrom<K>
{
match self.search_mut(k) {
Some(bucket) => {
let (_, v) = bucket.into_mut_refs();
@ -1147,6 +1119,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// 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
///
/// ```
@ -1158,7 +1134,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// assert_eq!(map.remove(&1), None);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, k: &K) -> Option<V> {
pub fn remove<Sized? Q>(&mut self, k: &Q) -> Option<V>
where Q: Hash<S> + Eq + BorrowFrom<K>
{
if self.table.size() == 0 {
return None
}
@ -1271,16 +1249,20 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H>
}
}
impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Index<K, V> for HashMap<K, V, H> {
impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> Index<Q, V> for HashMap<K, V, H>
where Q: BorrowFrom<K> + Hash<S> + Eq
{
#[inline]
fn index<'a>(&'a self, index: &K) -> &'a V {
fn index<'a>(&'a self, index: &Q) -> &'a V {
self.get(index).expect("no entry found for key")
}
}
impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> IndexMut<K, V> for HashMap<K, V, H> {
impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> IndexMut<Q, V> for HashMap<K, V, H>
where Q: BorrowFrom<K> + Hash<S> + Eq
{
#[inline]
fn index_mut<'a>(&'a mut self, index: &K) -> &'a mut V {
fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
match self.get_mut(index) {
Some(v) => v,
None => panic!("no entry found for key")
@ -1962,11 +1944,11 @@ mod test_map {
m.insert("baz".to_string(), baz);
assert_eq!(m.find_equiv("foo"), Some(&foo));
assert_eq!(m.find_equiv("bar"), Some(&bar));
assert_eq!(m.find_equiv("baz"), Some(&baz));
assert_eq!(m.get("foo"), Some(&foo));
assert_eq!(m.get("bar"), Some(&bar));
assert_eq!(m.get("baz"), Some(&baz));
assert_eq!(m.find_equiv("qux"), None);
assert_eq!(m.get("qux"), None);
}
#[test]

View File

@ -10,6 +10,7 @@
//
// ignore-lexer-test FIXME #15883
use borrow::BorrowFrom;
use cmp::{Eq, Equiv, PartialEq};
use core::kinds::Sized;
use default::Default;
@ -184,47 +185,9 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
self.map.reserve(n)
}
/// Returns true if the hash set contains a value equivalent to the
/// given query value.
///
/// # Example
///
/// This is a slightly silly example where we define the number's
/// parity as the equivalance class. It is important that the
/// values hash the same, which is why we implement `Hash`.
///
/// ```
/// use std::collections::HashSet;
/// use std::hash::Hash;
/// use std::hash::sip::SipState;
///
/// #[deriving(Eq, PartialEq)]
/// struct EvenOrOdd {
/// num: uint
/// };
///
/// impl Hash for EvenOrOdd {
/// fn hash(&self, state: &mut SipState) {
/// let parity = self.num % 2;
/// parity.hash(state);
/// }
/// }
///
/// impl Equiv<EvenOrOdd> for EvenOrOdd {
/// fn equiv(&self, other: &EvenOrOdd) -> bool {
/// self.num % 2 == other.num % 2
/// }
/// }
///
/// let mut set = HashSet::new();
/// set.insert(EvenOrOdd { num: 3u });
///
/// assert!(set.contains_equiv(&EvenOrOdd { num: 3u }));
/// assert!(set.contains_equiv(&EvenOrOdd { num: 5u }));
/// assert!(!set.contains_equiv(&EvenOrOdd { num: 4u }));
/// assert!(!set.contains_equiv(&EvenOrOdd { num: 2u }));
///
/// ```
/// Deprecated: use `contains` and `BorrowFrom`.
#[deprecated = "use contains and BorrowFrom"]
#[allow(deprecated)]
pub fn contains_equiv<Sized? Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
self.map.contains_key_equiv(value)
}
@ -427,6 +390,10 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
/// 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
///
/// ```
@ -437,7 +404,11 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
/// assert_eq!(set.contains(&4), false);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
pub fn contains<Sized? Q>(&self, value: &Q) -> bool
where Q: BorrowFrom<T> + Hash<S> + 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.
@ -527,6 +498,10 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
/// 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
///
/// ```
@ -539,7 +514,11 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
/// assert_eq!(set.remove(&2), false);
/// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() }
pub fn remove<Sized? Q>(&mut self, value: &Q) -> bool
where Q: BorrowFrom<T> + Hash<S> + Eq
{
self.map.remove(value).is_some()
}
}
impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {

View File

@ -718,7 +718,7 @@ impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
}
/// An iterator that moves out buckets in reverse order. It leaves the table
/// in an an inconsistent state and should only be used for dropping
/// in an inconsistent state and should only be used for dropping
/// the table's remaining entries. It's used in the implementation of Drop.
struct RevMoveBuckets<'a, K, V> {
raw: RawBucket<K, V>,

View File

@ -381,16 +381,8 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
let mut reader = try!(File::open(from));
let mut writer = try!(File::create(to));
let mut buf = [0, ..io::DEFAULT_BUF_SIZE];
loop {
let amt = match reader.read(&mut buf) {
Ok(n) => n,
Err(ref e) if e.kind == io::EndOfFile => { break }
Err(e) => return update_err(Err(e), from, to)
};
try!(writer.write(buf[..amt]));
}
try!(update_err(super::util::copy(&mut reader, &mut writer), from, to));
chmod(to, try!(update_err(from.stat(), from, to)).perm)
}

View File

@ -141,6 +141,7 @@ extern crate rustrt;
pub use core::any;
pub use core::bool;
pub use core::borrow;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;

View File

@ -81,7 +81,7 @@ const BUF_BYTES : uint = 2048u;
/// # Failure
///
/// Fails if the current working directory value is invalid:
/// Possibles cases:
/// Possible cases:
///
/// * Current directory does not exist.
/// * There are insufficient permissions to access the current directory.

View File

@ -554,11 +554,4 @@ mod tests {
assert_eq!(format!("{:30}", Duration::days(1) + Duration::milliseconds(2345)),
"P1DT2.345S".to_string());
}
#[test]
fn span() {
use io::timer::sleep;
let dur = Duration::span(|| sleep(Duration::milliseconds(5)));
assert!(dur > Duration::milliseconds(1));
}
}

View File

@ -20,6 +20,6 @@ impl Registry {
}
pub fn find_description(&self, code: &str) -> Option<&'static str> {
self.descriptions.find_equiv(code).map(|desc| *desc)
self.descriptions.get(code).map(|desc| *desc)
}
}

View File

@ -97,8 +97,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
// cannot be shared with any other operand (usually when
// a register is clobbered early.)
let output = match constraint.get().slice_shift_char() {
(Some('='), _) => None,
(Some('+'), operand) => {
Some(('=', _)) => None,
Some(('+', operand)) => {
Some(token::intern_and_get_ident(format!(
"={}",
operand).as_slice()))

View File

@ -144,7 +144,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
let name = interned_name.get();
p.expect(&token::Eq);
let e = p.parse_expr();
match names.find_equiv(name) {
match names.get(name) {
None => {}
Some(prev) => {
ecx.span_err(e.span,
@ -366,7 +366,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.expr_path(path)
}
parse::CountIsName(n) => {
let i = match self.name_positions.find_equiv(n) {
let i = match self.name_positions.get(n) {
Some(&i) => i,
None => 0, // error already emitted elsewhere
};
@ -410,7 +410,7 @@ impl<'a, 'b> Context<'a, 'b> {
// Named arguments are converted to positional arguments at
// the end of the list of arguments
parse::ArgumentNamed(n) => {
let i = match self.name_positions.find_equiv(n) {
let i = match self.name_positions.get(n) {
Some(&i) => i,
None => 0, // error already emitted elsewhere
};

View File

@ -182,6 +182,10 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
"`#[thread_local]` is an experimental feature, and does not \
currently handle destructors. There is no corresponding \
`#[task_local]` mapping to the task model");
} else if attr.name().equiv(&("linkage")) {
self.gate_feature("linkage", i.span,
"the `linkage` attribute is experimental \
and not portable across platforms")
}
}
match i.node {

View File

@ -1232,7 +1232,8 @@ impl<'a> Parser<'a> {
{
if self.eat(&token::Lt) {
if lifetime_defs.is_empty() {
self.warn("deprecated syntax, use `for` keyword now");
self.warn("deprecated syntax; use the `for` keyword now \
(e.g. change `fn<'a>` to `for<'a> fn`)");
let lifetime_defs = self.parse_lifetime_defs();
self.expect_gt();
lifetime_defs
@ -5178,7 +5179,15 @@ impl<'a> Parser<'a> {
if self.eat(&token::OpenDelim(token::Brace)) {
// Parse a struct variant.
all_nullary = false;
kind = StructVariantKind(self.parse_struct_def());
let start_span = self.span;
let struct_def = self.parse_struct_def();
if struct_def.fields.len() == 0 {
self.span_err(start_span,
format!("unit-like struct variant should be written \
without braces, as `{},`",
token::get_ident(ident)).as_slice());
}
kind = StructVariantKind(struct_def);
} else if self.token == token::OpenDelim(token::Paren) {
all_nullary = false;
let arg_tys = self.parse_enum_variant_seq(

View File

@ -1855,7 +1855,7 @@ impl<'a> State<'a> {
try!(self.commasep(Inconsistent, a.outputs.as_slice(),
|s, &(ref co, ref o, is_rw)| {
match co.get().slice_shift_char() {
(Some('='), operand) if is_rw => {
Some(('=', operand)) if is_rw => {
try!(s.print_string(format!("+{}", operand).as_slice(),
ast::CookedStr))
}

View File

@ -14,9 +14,9 @@
use ast::Name;
use std::borrow::BorrowFrom;
use std::collections::HashMap;
use std::cell::RefCell;
use std::cmp::Equiv;
use std::fmt;
use std::hash::Hash;
use std::rc::Rc;
@ -75,9 +75,10 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> {
(*vect).len()
}
pub fn find_equiv<Sized? Q: Hash + Equiv<T>>(&self, val: &Q) -> Option<Name> {
pub fn find<Sized? Q>(&self, val: &Q) -> Option<Name>
where Q: BorrowFrom<T> + Eq + Hash {
let map = self.map.borrow();
match (*map).find_equiv(val) {
match (*map).get(val) {
Some(v) => Some(*v),
None => None,
}
@ -117,6 +118,12 @@ impl fmt::Show for RcStr {
}
}
impl BorrowFrom<RcStr> for str {
fn borrow_from(owned: &RcStr) -> &str {
owned.string.as_slice()
}
}
impl RcStr {
pub fn new(string: &str) -> RcStr {
RcStr {
@ -149,7 +156,7 @@ impl StrInterner {
pub fn intern(&self, val: &str) -> Name {
let mut map = self.map.borrow_mut();
match map.find_equiv(val) {
match map.get(val) {
Some(&idx) => return idx,
None => (),
}
@ -195,8 +202,9 @@ impl StrInterner {
self.vect.borrow().len()
}
pub fn find_equiv<Sized? Q:Hash + Equiv<RcStr>>(&self, val: &Q) -> Option<Name> {
match (*self.map.borrow()).find_equiv(val) {
pub fn find<Sized? Q>(&self, val: &Q) -> Option<Name>
where Q: BorrowFrom<RcStr> + Eq + Hash {
match (*self.map.borrow()).get(val) {
Some(v) => Some(*v),
None => None,
}

View File

@ -78,7 +78,7 @@ impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
if self.num_colors > color {
let s = expand(self.ti
.strings
.find_equiv("setaf")
.get("setaf")
.unwrap()
.as_slice(),
&[Number(color as int)], &mut Variables::new());
@ -95,7 +95,7 @@ impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
if self.num_colors > color {
let s = expand(self.ti
.strings
.find_equiv("setab")
.get("setab")
.unwrap()
.as_slice(),
&[Number(color as int)], &mut Variables::new());
@ -113,7 +113,7 @@ impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
attr::BackgroundColor(c) => self.bg(c),
_ => {
let cap = cap_for_attr(attr);
let parm = self.ti.strings.find_equiv(cap);
let parm = self.ti.strings.get(cap);
if parm.is_some() {
let s = expand(parm.unwrap().as_slice(),
&[],
@ -135,19 +135,19 @@ impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
}
_ => {
let cap = cap_for_attr(attr);
self.ti.strings.find_equiv(cap).is_some()
self.ti.strings.get(cap).is_some()
}
}
}
fn reset(&mut self) -> IoResult<()> {
let mut cap = self.ti.strings.find_equiv("sgr0");
let mut cap = self.ti.strings.get("sgr0");
if cap.is_none() {
// are there any terminals that have color/attrs and not sgr0?
// Try falling back to sgr, then op
cap = self.ti.strings.find_equiv("sgr");
cap = self.ti.strings.get("sgr");
if cap.is_none() {
cap = self.ti.strings.find_equiv("op");
cap = self.ti.strings.get("op");
}
}
let s = cap.map_or(Err("can't find terminfo capability `sgr0`".to_string()), |op| {
@ -202,9 +202,9 @@ impl<T: Writer+Send> TerminfoTerminal<T> {
}
let inf = ti.unwrap();
let nc = if inf.strings.find_equiv("setaf").is_some()
&& inf.strings.find_equiv("setab").is_some() {
inf.numbers.find_equiv("colors").map_or(0, |&n| n)
let nc = if inf.strings.get("setaf").is_some()
&& inf.strings.get("setab").is_some() {
inf.numbers.get("colors").map_or(0, |&n| n)
} else { 0 };
return Some(box TerminfoTerminal {out: out,

View File

@ -76,7 +76,7 @@ fn sort_and_fmt(mm: &HashMap<Vec<u8> , uint>, total: uint) -> String {
// given a map, search for the frequency of a pattern
fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
let key = key.into_ascii().as_slice().to_lowercase().into_string();
match mm.find_equiv(key.as_bytes()) {
match mm.get(key.as_bytes()) {
option::None => { return 0u; }
option::Some(&num) => { return num; }
}

View File

@ -0,0 +1,20 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:use_from_trait_xc.rs
extern crate use_from_trait_xc;
pub use use_from_trait_xc::Trait;
fn main() {
match () {
Trait { x: 42u } => () //~ ERROR use of trait `Trait` in a struct pattern
}
}

View File

@ -0,0 +1,15 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[linkage = "external"]
static foo: int = 0;
//~^ ERROR: the `linkage` attribute is experimental and not portable
fn main() {}

View File

@ -459,6 +459,20 @@ mod this_crate {
foo.trait_stable();
}
#[deprecated]
fn test_fn_body() {
fn fn_in_body() {}
fn_in_body();
}
impl MethodTester {
#[deprecated]
fn test_method_body(&self) {
fn fn_in_body() {}
fn_in_body();
}
}
#[deprecated]
pub trait DeprecatedTrait {}

View File

@ -0,0 +1,13 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum Foo {
Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
}

View File

@ -0,0 +1,8 @@
-include ../tools.mk
all:
$(CC) foo.c -c -o $(TMPDIR)/foo.o
$(AR) rcs $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
$(RUSTC) bar.rs -lfoo -L $(TMPDIR)
$(call RUN,bar) || exit 1

View File

@ -0,0 +1,25 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(linkage)]
#[no_mangle]
#[linkage = "external"]
static BAZ: i32 = 21;
extern {
fn what() -> i32;
}
fn main() {
unsafe {
assert_eq!(what(), BAZ);
}
}

View File

@ -0,0 +1,7 @@
#include <stdint.h>
extern int32_t BAZ;
int32_t what() {
return BAZ;
}

View File

@ -0,0 +1,26 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct Str([u8]);
#[deriving(Clone)]
struct CharSplits<'a, Sep> {
string: &'a Str,
sep: Sep,
allow_trailing_empty: bool,
only_ascii: bool,
finished: bool,
}
fn clone(s: &Str) -> &Str {
Clone::clone(&s)
}
fn main() {}