mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-19 18:34:08 +00:00
auto merge of #19049 : jakub-/rust/roll-up, r=alexcrichton
r? @alexcrichton
This commit is contained in:
commit
9c96a79a74
mk
cfg
arm-apple-iosarm-linux-androideabiarm-unknown-linux-gnueabiarm-unknown-linux-gnueabihfi386-apple-iosi686-apple-darwini686-pc-windows-gnui686-unknown-linux-gnumips-unknown-linux-gnumipsel-unknown-linux-gnux86_64-apple-darwinx86_64-pc-windows-gnux86_64-unknown-dragonflyx86_64-unknown-freebsdx86_64-unknown-linux-gnu
rt.mksrc
doc
grammar
libcollections
libcore
libgraphviz
liblog
libregex
librustc
librustdoc/html
libserialize
libstd
libsyntax
libterm/terminfo
test
bench
compile-fail-fulldeps
compile-fail
run-make/linkage-attr-on-static
run-pass
@ -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
|
||||
|
@ -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++
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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=
|
||||
|
@ -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=
|
||||
|
@ -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
|
||||
|
4
mk/rt.mk
4
mk/rt.mk
@ -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),)
|
||||
|
@ -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 ] ? ;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,4 +33,4 @@
|
||||
//! ```
|
||||
|
||||
pub mod map;
|
||||
pub mod set;
|
||||
pub mod set;
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -17,4 +17,4 @@
|
||||
//! `TrieMap` is ordered.
|
||||
|
||||
pub mod map;
|
||||
pub mod set;
|
||||
pub mod set;
|
||||
|
@ -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
127
src/libcore/borrow.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(_) => {;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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![];
|
||||
|
@ -143,5 +143,6 @@ register_diagnostics!(
|
||||
E0164,
|
||||
E0165,
|
||||
E0166,
|
||||
E0167
|
||||
E0167,
|
||||
E0168
|
||||
)
|
||||
|
@ -623,6 +623,7 @@ impl LintPass for UnusedAttributes {
|
||||
"link",
|
||||
"link_name",
|
||||
"link_section",
|
||||
"linkage",
|
||||
"no_builtins",
|
||||
"no_mangle",
|
||||
"no_split_stack",
|
||||
|
@ -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))
|
||||
|
@ -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();
|
||||
|
@ -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',
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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> {
|
||||
|
@ -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) => {
|
||||
|
@ -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) {
|
||||
|
@ -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>>> {
|
||||
//
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 => ()
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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(())
|
||||
};
|
||||
|
@ -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() {
|
||||
|
@ -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]
|
||||
|
@ -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> {
|
||||
|
@ -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>,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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()))
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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; }
|
||||
}
|
||||
|
20
src/test/compile-fail-fulldeps/issue-18986.rs
Normal file
20
src/test/compile-fail-fulldeps/issue-18986.rs
Normal 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
|
||||
}
|
||||
}
|
15
src/test/compile-fail/linkage4.rs
Normal file
15
src/test/compile-fail/linkage4.rs
Normal 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() {}
|
@ -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 {}
|
||||
|
||||
|
13
src/test/compile-fail/struct-variant-no-fields.rs
Normal file
13
src/test/compile-fail/struct-variant-no-fields.rs
Normal 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,`
|
||||
}
|
8
src/test/run-make/linkage-attr-on-static/Makefile
Normal file
8
src/test/run-make/linkage-attr-on-static/Makefile
Normal 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
|
||||
|
25
src/test/run-make/linkage-attr-on-static/bar.rs
Normal file
25
src/test/run-make/linkage-attr-on-static/bar.rs
Normal 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);
|
||||
}
|
||||
}
|
7
src/test/run-make/linkage-attr-on-static/foo.c
Normal file
7
src/test/run-make/linkage-attr-on-static/foo.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern int32_t BAZ;
|
||||
|
||||
int32_t what() {
|
||||
return BAZ;
|
||||
}
|
26
src/test/run-pass/issue-19037.rs
Normal file
26
src/test/run-pass/issue-19037.rs
Normal 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() {}
|
Loading…
Reference in New Issue
Block a user