mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 03:44:24 +00:00
auto merge of #19049 : jakub-/rust/roll-up, r=alexcrichton
r? @alexcrichton
This commit is contained in:
commit
9c96a79a74
@ -13,7 +13,7 @@ CFG_LIB_NAME_arm-apple-ios = lib$(1).a
|
|||||||
CFG_LIB_GLOB_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_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
|
||||||
CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
|
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_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_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
|
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_STATIC_LIB_NAME_arm-linux-androideabi=lib$(1).a
|
||||||
CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
|
CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_arm-linux-androideabi=lib$(1)-*.dylib.dSYM
|
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_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
|
||||||
CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
|
CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++
|
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_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
|
||||||
CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
|
CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
|
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_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_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
|
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_STATIC_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).a
|
||||||
CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
|
CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM
|
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_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC -D__arm__ $(CFLAGS)
|
||||||
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
|
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g
|
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_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
|
||||||
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
|
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
|
||||||
CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
|
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_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_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)
|
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_LDPATH_i386-apple-ios =
|
||||||
CFG_RUN_i386-apple-ios = $(2)
|
CFG_RUN_i386-apple-ios = $(2)
|
||||||
CFG_RUN_TARG_i386-apple-ios = $(call 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
|
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_STATIC_LIB_NAME_i686-apple-darwin=lib$(1).a
|
||||||
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
|
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
|
||||||
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
|
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_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(CFLAGS)
|
||||||
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
|
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32
|
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_STATIC_LIB_NAME_i686-pc-windows-gnu=$(1).lib
|
||||||
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
|
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
|
||||||
CFG_LIB_DSYM_GLOB_i686-pc-windows-gnu=$(1)-*.dylib.dSYM
|
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_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_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32
|
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_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
|
||||||
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
|
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
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_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
|
||||||
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
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
|
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_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
|
||||||
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
|
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
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_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_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
|
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_STATIC_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).a
|
||||||
CFG_LIB_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.so
|
CFG_LIB_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
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_CFLAGS_mipsel-unknown-linux-gnu := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
|
||||||
CFG_GCCISH_CXXFLAGS_mipsel-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
CFG_GCCISH_CXXFLAGS_mipsel-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_mipsel-unknown-linux-gnu := -shared -fPIC -g -mips32
|
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_STATIC_LIB_NAME_x86_64-apple-darwin=lib$(1).a
|
||||||
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
|
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
|
||||||
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
|
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_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_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64
|
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_STATIC_LIB_NAME_x86_64-pc-windows-gnu=$(1).lib
|
||||||
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
|
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
|
||||||
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-gnu=$(1)-*.dylib.dSYM
|
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_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_CXXFLAGS_x86_64-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
|
||||||
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-gnu := -shared -g -m64
|
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_STATIC_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).a
|
||||||
CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
|
CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
|
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_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_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread -lrt
|
||||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
|
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_STATIC_LIB_NAME_x86_64-unknown-freebsd=lib$(1).a
|
||||||
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
|
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
|
||||||
CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
|
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_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_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
|
||||||
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
|
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_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
|
||||||
CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
|
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_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_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
|
||||||
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
|
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
|
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" \
|
cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
|
||||||
$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ $(CFG_JEMALLOC_FLAGS) \
|
$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ $(CFG_JEMALLOC_FLAGS) \
|
||||||
--build=$$(CFG_GNU_TRIPLE_$(CFG_BUILD)) --host=$$(CFG_GNU_TRIPLE_$(1)) \
|
--build=$$(CFG_GNU_TRIPLE_$(CFG_BUILD)) --host=$$(CFG_GNU_TRIPLE_$(1)) \
|
||||||
CC="$$(CC_$(1))" \
|
CC="$$(CC_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1))" \
|
||||||
AR="$$(AR_$(1))" \
|
AR="$$(AR_$(1))" \
|
||||||
RANLIB="$$(AR_$(1)) s" \
|
RANLIB="$$(AR_$(1)) s" \
|
||||||
CPPFLAGS="-I $(S)src/rt/" \
|
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
|
$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
|
||||||
|
|
||||||
ifeq ($$(CFG_DISABLE_JEMALLOC),)
|
ifeq ($$(CFG_DISABLE_JEMALLOC),)
|
||||||
|
@ -304,8 +304,8 @@ r##"foo #"# bar"##; // foo #"# bar
|
|||||||
#### Byte and byte string literals
|
#### Byte and byte string literals
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
byte_lit : 'b' '\x27' byte_body '\x27' ;
|
byte_lit : "b\x27" byte_body '\x27' ;
|
||||||
byte_string_lit : 'b' '"' string_body * '"' | 'b' 'r' raw_byte_string ;
|
byte_string_lit : "b\x22" string_body * '\x22' | "br" raw_byte_string ;
|
||||||
|
|
||||||
byte_body : ascii_non_single_quote
|
byte_body : ascii_non_single_quote
|
||||||
| '\x5c' [ '\x27' | common_escape ] ;
|
| '\x5c' [ '\x27' | common_escape ] ;
|
||||||
@ -381,10 +381,10 @@ num_suffix : int_suffix | float_suffix ;
|
|||||||
|
|
||||||
int_suffix : 'u' int_suffix_size ?
|
int_suffix : 'u' int_suffix_size ?
|
||||||
| 'i' 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 : [ 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 ;
|
exponent : ['E' | 'e'] ['-' | '+' ] ? dec_lit ;
|
||||||
dec_lit : [ dec_digit | '_' ] + ;
|
dec_lit : [ dec_digit | '_' ] + ;
|
||||||
```
|
```
|
||||||
@ -1862,7 +1862,7 @@ the namespace hierarchy as it normally would.
|
|||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
attribute : '#' '!' ? '[' meta_item ']' ;
|
attribute : "#!" ? '[' meta_item ']' ;
|
||||||
meta_item : ident [ '=' literal
|
meta_item : ident [ '=' literal
|
||||||
| '(' meta_seq ')' ] ? ;
|
| '(' meta_seq ')' ] ? ;
|
||||||
meta_seq : meta_item [ ',' 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 toknum = m.name("toknum");
|
||||||
let content = m.name("content");
|
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());
|
toknum).as_slice());
|
||||||
|
|
||||||
let nm = parse::token::intern(content);
|
let nm = parse::token::intern(content);
|
||||||
|
@ -283,7 +283,7 @@ impl Bitv {
|
|||||||
x != 0
|
x != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the value of a bit at a index `i`.
|
/// Sets the value of a bit at an index `i`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
@ -582,7 +582,7 @@ impl Bitv {
|
|||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the the `Bitv` and slice are of different length.
|
/// Panics if the `Bitv` and slice are of different length.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -21,6 +21,7 @@ use core::prelude::*;
|
|||||||
|
|
||||||
use self::StackOp::*;
|
use self::StackOp::*;
|
||||||
use super::node::*;
|
use super::node::*;
|
||||||
|
use core::borrow::BorrowFrom;
|
||||||
use std::hash::{Writer, Hash};
|
use std::hash::{Writer, Hash};
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::{iter, fmt, mem};
|
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
|
/// 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,
|
/// 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
|
/// 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.
|
/// 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
|
/// 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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -195,7 +199,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// assert_eq!(map.get(&2), None);
|
/// assert_eq!(map.get(&2), None);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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;
|
let mut cur_node = &self.root;
|
||||||
loop {
|
loop {
|
||||||
match cur_node.search(key) {
|
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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -224,7 +231,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// assert_eq!(map.contains_key(&2), false);
|
/// assert_eq!(map.contains_key(&2), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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()
|
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.
|
/// 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
|
/// # 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
|
// 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"]
|
#[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
|
// temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
|
||||||
let mut temp_node = &mut self.root;
|
let mut temp_node = &mut self.root;
|
||||||
loop {
|
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
|
/// Removes a key from the map, returning the value at the key if the key
|
||||||
/// was previously in the map.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -421,7 +434,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// assert_eq!(map.remove(&1), None);
|
/// assert_eq!(map.remove(&1), None);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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
|
// See `swap` for a more thorough description of the stuff going on in here
|
||||||
let mut stack = stack::PartialSearchStack::new(self);
|
let mut stack = stack::PartialSearchStack::new(self);
|
||||||
loop {
|
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> {
|
impl<K: Ord, Sized? Q, V> Index<Q, V> for BTreeMap<K, V>
|
||||||
fn index(&self, key: &K) -> &V {
|
where Q: BorrowFrom<K> + Ord
|
||||||
|
{
|
||||||
|
fn index(&self, key: &Q) -> &V {
|
||||||
self.get(key).expect("no entry found for key")
|
self.get(key).expect("no entry found for key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Ord, V> IndexMut<K, V> for BTreeMap<K, V> {
|
impl<K: Ord, Sized? Q, V> IndexMut<Q, V> for BTreeMap<K, V>
|
||||||
fn index_mut(&mut self, key: &K) -> &mut 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")
|
self.get_mut(key).expect("no entry found for key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ use core::prelude::*;
|
|||||||
|
|
||||||
use core::{slice, mem, ptr};
|
use core::{slice, mem, ptr};
|
||||||
use core::iter::Zip;
|
use core::iter::Zip;
|
||||||
|
use core::borrow::BorrowFrom;
|
||||||
|
|
||||||
use vec;
|
use vec;
|
||||||
use vec::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,
|
// 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
|
// 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
|
// 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
|
// (ptr, size, is_leaf). This could also have cache benefits for very small nodes, as keys
|
||||||
// could bleed into edges and vals.
|
// 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,
|
/// 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,
|
/// `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.
|
/// `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).
|
// 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*
|
// For the B configured as of this writing (B = 6), binary search was *significantly*
|
||||||
// worse for uints.
|
// worse for uints.
|
||||||
self.search_linear(key)
|
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() {
|
for (i, k) in self.keys.iter().enumerate() {
|
||||||
match k.cmp(key) {
|
match key.cmp(BorrowFrom::borrow_from(k)) {
|
||||||
Less => {},
|
Greater => {},
|
||||||
Equal => return Found(i),
|
Equal => return Found(i),
|
||||||
Greater => return GoDown(i),
|
Less => return GoDown(i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GoDown(self.len())
|
GoDown(self.len())
|
||||||
|
@ -15,6 +15,7 @@ use core::prelude::*;
|
|||||||
|
|
||||||
use btree_map::{BTreeMap, Keys, MoveEntries};
|
use btree_map::{BTreeMap, Keys, MoveEntries};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use core::borrow::BorrowFrom;
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::{iter, fmt};
|
use core::{iter, fmt};
|
||||||
use core::iter::Peekable;
|
use core::iter::Peekable;
|
||||||
@ -167,6 +168,10 @@ impl<T: Ord> BTreeSet<T> {
|
|||||||
|
|
||||||
/// Returns `true` if the set contains a value.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -177,7 +182,7 @@ impl<T: Ord> BTreeSet<T> {
|
|||||||
/// assert_eq!(set.contains(&4), false);
|
/// assert_eq!(set.contains(&4), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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)
|
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
|
/// Removes a value from the set. Returns `true` if the value was
|
||||||
/// present in the set.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -303,7 +312,7 @@ impl<T: Ord> BTreeSet<T> {
|
|||||||
/// assert_eq!(set.remove(&2), false);
|
/// assert_eq!(set.remove(&2), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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()
|
self.map.remove(value).is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,7 @@
|
|||||||
|
|
||||||
use self::Direction::*;
|
use self::Direction::*;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use core::borrow::{BorrowFrom, BorrowFromMut};
|
||||||
use core::cmp;
|
use core::cmp;
|
||||||
use core::kinds::Sized;
|
use core::kinds::Sized;
|
||||||
use core::mem::size_of;
|
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
|
/// Unsafe operations
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
|
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
pub use self::MaybeOwned::*;
|
pub use self::MaybeOwned::*;
|
||||||
use self::RecompositionState::*;
|
use self::RecompositionState::*;
|
||||||
use self::DecompositionType::*;
|
use self::DecompositionType::*;
|
||||||
|
use core::borrow::BorrowFrom;
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::cmp;
|
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.
|
/// Unsafe string operations.
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
|
pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
|
||||||
@ -1258,13 +1263,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_slice_shift_char() {
|
fn test_slice_shift_char() {
|
||||||
let data = "ประเทศไทย中";
|
let data = "ประเทศไทย中";
|
||||||
assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中"));
|
assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_shift_char_2() {
|
fn test_slice_shift_char_2() {
|
||||||
let empty = "";
|
let empty = "";
|
||||||
assert_eq!(empty.slice_shift_char(), (None, ""));
|
assert_eq!(empty.slice_shift_char(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -549,7 +549,7 @@ impl String {
|
|||||||
///
|
///
|
||||||
/// # Warning
|
/// # 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.
|
/// buffer.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
@ -586,7 +586,7 @@ impl String {
|
|||||||
///
|
///
|
||||||
/// # Warning
|
/// # 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.
|
/// buffer.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
|
use core::borrow::BorrowFrom;
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::fmt::Show;
|
use core::fmt::Show;
|
||||||
@ -188,16 +190,16 @@ impl<K: Ord, V> Default for TreeMap<K,V> {
|
|||||||
fn default() -> TreeMap<K, V> { TreeMap::new() }
|
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]
|
#[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")
|
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]
|
#[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")
|
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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -458,12 +463,17 @@ impl<K: Ord, V> TreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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>
|
||||||
tree_find_with(&self.root, |k2| key.cmp(k2))
|
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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -476,7 +486,9 @@ impl<K: Ord, V> TreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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()
|
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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -503,8 +518,10 @@ impl<K: Ord, V> TreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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>
|
||||||
tree_find_with_mut(&mut self.root, |x| key.cmp(x))
|
where Q: BorrowFrom<K> + Ord
|
||||||
|
{
|
||||||
|
tree_find_with_mut(&mut self.root, |x| key.cmp(BorrowFrom::borrow_from(x)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deprecated: Renamed to `insert`.
|
/// 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
|
/// Removes a key from the map, returning the value at the key if the key
|
||||||
/// was previously in the map.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -556,7 +576,9 @@ impl<K: Ord, V> TreeMap<K, V> {
|
|||||||
/// assert_eq!(map.remove(&1), None);
|
/// assert_eq!(map.remove(&1), None);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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);
|
let ret = remove(&mut self.root, key);
|
||||||
if ret.is_some() { self.length -= 1 }
|
if ret.is_some() { self.length -= 1 }
|
||||||
ret
|
ret
|
||||||
@ -589,6 +611,7 @@ impl<K, V> TreeMap<K, V> {
|
|||||||
/// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1");
|
/// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1");
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[experimental = "likely to be renamed, may be removed"]
|
||||||
pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> {
|
pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> {
|
||||||
tree_find_with(&self.root, f)
|
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));
|
/// assert_eq!(t.get(&"User-Agent"), Some(&new_ua));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[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> {
|
pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
|
||||||
tree_find_with_mut(&mut self.root, f)
|
tree_find_with_mut(&mut self.root, f)
|
||||||
}
|
}
|
||||||
@ -1168,8 +1192,9 @@ fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
|
fn remove<K, Sized? Q, V>(node: &mut Option<Box<TreeNode<K, V>>>, key: &Q) -> Option<V>
|
||||||
key: &K) -> Option<V> {
|
where K: Ord, Q: BorrowFrom<K> + Ord
|
||||||
|
{
|
||||||
fn heir_swap<K: Ord, V>(node: &mut Box<TreeNode<K, V>>,
|
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
|
// *could* be done without recursion, but it won't borrow check
|
||||||
@ -1188,7 +1213,7 @@ fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
|
|||||||
return None; // bottom of tree
|
return None; // bottom of tree
|
||||||
}
|
}
|
||||||
Some(ref mut save) => {
|
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),
|
Less => (remove(&mut save.left, key), true),
|
||||||
Greater => (remove(&mut save.right, key), true),
|
Greater => (remove(&mut save.right, key), true),
|
||||||
Equal => {
|
Equal => {
|
||||||
@ -1918,4 +1943,3 @@ mod bench {
|
|||||||
bench_iter(b, 100000);
|
bench_iter(b, 100000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
|
use core::borrow::BorrowFrom;
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::fmt::Show;
|
use core::fmt::Show;
|
||||||
@ -396,6 +397,10 @@ impl<T: Ord> TreeSet<T> {
|
|||||||
|
|
||||||
/// Returns `true` if the set contains a value.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -407,7 +412,9 @@ impl<T: Ord> TreeSet<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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)
|
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
|
/// Removes a value from the set. Returns `true` if the value was
|
||||||
/// present in the set.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -532,7 +543,11 @@ impl<T: Ord> TreeSet<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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.
|
/// A lazy forward iterator over a set.
|
||||||
|
@ -1057,7 +1057,7 @@ impl<'a, T> VacantEntry<'a, T> {
|
|||||||
search_stack.map.root.count = temp;
|
search_stack.map.root.count = temp;
|
||||||
value_ref
|
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 {
|
else {
|
||||||
match *search_stack.get_ref(old_length - 2) {
|
match *search_stack.get_ref(old_length - 2) {
|
||||||
Internal(box ref mut parent) => {
|
Internal(box ref mut parent) => {
|
||||||
@ -1741,7 +1741,7 @@ mod test {
|
|||||||
// Update it to i^3 using the returned mutable reference.
|
// Update it to i^3 using the returned mutable reference.
|
||||||
*inserted_val = i * i * i;
|
*inserted_val = i * i * i;
|
||||||
},
|
},
|
||||||
_ => panic!("Non-existant key found.")
|
_ => panic!("Non-existent key found.")
|
||||||
}
|
}
|
||||||
assert_eq!(map.get(&i).unwrap(), &(i * i * i));
|
assert_eq!(map.get(&i).unwrap(), &(i * i * i));
|
||||||
}
|
}
|
||||||
|
@ -8,22 +8,36 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
/*!
|
//! Implementations of things like `Eq` for fixed-length arrays
|
||||||
* Implementations of things like `Eq` for fixed-length arrays
|
//! up to a certain length. Eventually we should able to generalize
|
||||||
* up to a certain length. Eventually we should able to generalize
|
//! to all lengths.
|
||||||
* to all lengths.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#![stable]
|
|
||||||
#![experimental] // not yet reviewed
|
#![experimental] // not yet reviewed
|
||||||
|
|
||||||
use cmp::*;
|
use clone::Clone;
|
||||||
use option::{Option};
|
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 for implementing n-ary tuple functions and operations
|
||||||
macro_rules! array_impls {
|
macro_rules! array_impls {
|
||||||
($($N:expr)+) => {
|
($($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"]
|
#[unstable = "waiting for PartialEq to stabilize"]
|
||||||
impl<T:PartialEq> PartialEq for [T, ..$N] {
|
impl<T:PartialEq> PartialEq for [T, ..$N] {
|
||||||
#[inline]
|
#[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]
|
#![unstable]
|
||||||
|
|
||||||
|
use kinds::Sized;
|
||||||
|
|
||||||
/// A common trait for cloning an object.
|
/// A common trait for cloning an object.
|
||||||
pub trait Clone {
|
pub trait Clone {
|
||||||
/// Returns a copy of the value.
|
/// 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.
|
/// Return a shallow copy of the reference.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> &'a T { *self }
|
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(
|
macro_rules! clone_impl(
|
||||||
($t:ty) => {
|
($t:ty) => {
|
||||||
impl Clone for $t {
|
impl Clone for $t {
|
||||||
|
@ -108,6 +108,7 @@ pub mod default;
|
|||||||
pub mod any;
|
pub mod any;
|
||||||
pub mod atomic;
|
pub mod atomic;
|
||||||
pub mod bool;
|
pub mod bool;
|
||||||
|
pub mod borrow;
|
||||||
pub mod cell;
|
pub mod cell;
|
||||||
pub mod char;
|
pub mod char;
|
||||||
pub mod panicking;
|
pub mod panicking;
|
||||||
|
@ -88,7 +88,7 @@ pub fn align_of_val<T>(_val: &T) -> uint {
|
|||||||
|
|
||||||
/// Create a value initialized to zero.
|
/// 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).
|
/// zeroing it out (an unsafe operation).
|
||||||
///
|
///
|
||||||
/// Care must be taken when using this function, if the type `T` has a
|
/// 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;
|
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.
|
/// 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() }
|
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.
|
/// 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() {
|
let (is_positive, src) = match src.slice_shift_char() {
|
||||||
(None, _) => return None,
|
None => return None,
|
||||||
(Some('-'), "") => return None,
|
Some(('-', "")) => return None,
|
||||||
(Some('-'), src) => (false, src),
|
Some(('-', src)) => (false, src),
|
||||||
(Some(_), _) => (true, src),
|
Some((_, _)) => (true, src),
|
||||||
};
|
};
|
||||||
|
|
||||||
// The significand to accumulate
|
// The significand to accumulate
|
||||||
@ -1563,10 +1563,10 @@ macro_rules! from_str_radix_float_impl {
|
|||||||
// Parse the exponent as decimal integer
|
// Parse the exponent as decimal integer
|
||||||
let src = src[offset..];
|
let src = src[offset..];
|
||||||
let (is_positive, exp) = match src.slice_shift_char() {
|
let (is_positive, exp) = match src.slice_shift_char() {
|
||||||
(Some('-'), src) => (false, from_str::<uint>(src)),
|
Some(('-', src)) => (false, from_str::<uint>(src)),
|
||||||
(Some('+'), src) => (true, from_str::<uint>(src)),
|
Some(('+', src)) => (true, from_str::<uint>(src)),
|
||||||
(Some(_), _) => (true, from_str::<uint>(src)),
|
Some((_, _)) => (true, from_str::<uint>(src)),
|
||||||
(None, _) => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match (is_positive, exp) {
|
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();
|
let is_signed_ty = (0 as $T) > Int::min_value();
|
||||||
|
|
||||||
match src.slice_shift_char() {
|
match src.slice_shift_char() {
|
||||||
(Some('-'), src) if is_signed_ty => {
|
Some(('-', src)) if is_signed_ty => {
|
||||||
// The number is negative
|
// The number is negative
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
for c in src.chars() {
|
for c in src.chars() {
|
||||||
@ -1625,7 +1625,7 @@ macro_rules! from_str_radix_int_impl {
|
|||||||
}
|
}
|
||||||
Some(result)
|
Some(result)
|
||||||
},
|
},
|
||||||
(Some(_), _) => {
|
Some((_, _)) => {
|
||||||
// The number is signed
|
// The number is signed
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
for c in src.chars() {
|
for c in src.chars() {
|
||||||
@ -1644,7 +1644,7 @@ macro_rules! from_str_radix_int_impl {
|
|||||||
}
|
}
|
||||||
Some(result)
|
Some(result)
|
||||||
},
|
},
|
||||||
(None, _) => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,7 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
#[lang="index"]
|
#[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
|
/// The method for the indexing (`Foo[Bar]`) operation
|
||||||
fn index<'a>(&'a self, index: &Index) -> &'a Result;
|
fn index<'a>(&'a self, index: &Index) -> &'a Result;
|
||||||
}
|
}
|
||||||
@ -669,7 +669,7 @@ pub trait Index<Index, Sized? Result> for Sized? {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
#[lang="index_mut"]
|
#[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
|
/// The method for the indexing (`Foo[Bar]`) operation
|
||||||
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
|
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
|
/// it. This does not allocate a new string; instead, it returns a
|
||||||
/// slice that point one character beyond the character that was
|
/// slice that point one character beyond the character that was
|
||||||
/// shifted. If the string does not contain any characters,
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let s = "Löwe 老虎 Léopard";
|
/// let s = "Löwe 老虎 Léopard";
|
||||||
/// let (c, s1) = s.slice_shift_char();
|
/// let (c, s1) = s.slice_shift_char().unwrap();
|
||||||
/// assert_eq!(c, Some('L'));
|
/// assert_eq!(c, 'L');
|
||||||
/// assert_eq!(s1, "öwe 老虎 Léopard");
|
/// assert_eq!(s1, "öwe 老虎 Léopard");
|
||||||
///
|
///
|
||||||
/// let (c, s2) = s1.slice_shift_char();
|
/// let (c, s2) = s1.slice_shift_char().unwrap();
|
||||||
/// assert_eq!(c, Some('ö'));
|
/// assert_eq!(c, 'ö');
|
||||||
/// assert_eq!(s2, "we 老虎 Léopard");
|
/// 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.
|
/// Returns the byte offset of an inner slice relative to an enclosing outer slice.
|
||||||
///
|
///
|
||||||
@ -2197,13 +2197,13 @@ impl StrPrelude for str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn slice_shift_char(&self) -> (Option<char>, &str) {
|
fn slice_shift_char(&self) -> Option<(char, &str)> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
return (None, self);
|
None
|
||||||
} else {
|
} else {
|
||||||
let CharRange {ch, next} = self.char_range_at(0u);
|
let CharRange {ch, next} = self.char_range_at(0u);
|
||||||
let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
|
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 {
|
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> {
|
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 {
|
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> {
|
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> {
|
fn node_label<'a>(&'a self, n: &Nd) -> dot::LabelText<'a> {
|
||||||
dot::LabelStr(str::Slice(self.nodes[*n].as_slice()))
|
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 {
|
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> {
|
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> {
|
fn node_label<'a>(&'a self, n: &Nd<'a>) -> dot::LabelText<'a> {
|
||||||
let &(i, _) = n;
|
let &(i, _) = n;
|
||||||
@ -354,14 +354,22 @@ impl<'a> Id<'a> {
|
|||||||
/// defined by the DOT language. This function may change in the
|
/// defined by the DOT language. This function may change in the
|
||||||
/// future to accept a broader subset, or the entirety, of DOT's
|
/// future to accept a broader subset, or the entirety, of DOT's
|
||||||
/// `ID` format.)
|
/// `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 name = name.into_maybe_owned();
|
||||||
{
|
{
|
||||||
let mut chars = name.as_slice().chars();
|
let mut chars = name.as_slice().chars();
|
||||||
assert!(is_letter_or_underscore(chars.next().unwrap()));
|
match chars.next() {
|
||||||
assert!(chars.all(is_constituent));
|
Some(c) if is_letter_or_underscore(c) => { ; },
|
||||||
|
_ => return Err(())
|
||||||
}
|
}
|
||||||
return Id{ name: name };
|
if !chars.all(is_constituent) {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(Id{ name: name });
|
||||||
|
|
||||||
fn is_letter_or_underscore(c: char) -> bool {
|
fn is_letter_or_underscore(c: char) -> bool {
|
||||||
in_range('a', c, 'z') || in_range('A', c, 'Z') || c == '_'
|
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> {
|
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 {
|
impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph {
|
||||||
fn graph_id(&'a self) -> Id<'a> {
|
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> {
|
fn node_id(&'a self, n: &Node) -> Id<'a> {
|
||||||
id_name(n)
|
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'.
|
//! includes 'foo'.
|
||||||
//! * `info/f.o` turns on all info logging where the log message includes 'foo',
|
//! * `info/f.o` turns on all info logging where the log message includes 'foo',
|
||||||
//! 'f1o', 'fao', etc.
|
//! '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.
|
//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.
|
||||||
//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for
|
//! * `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
|
//! 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.
|
/// Replacer describes types that can be used to replace matches in a string.
|
||||||
pub trait Replacer {
|
pub trait Replacer {
|
||||||
/// Returns a possibly owned string that is used to replace the match
|
/// 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
|
/// The `'a` lifetime refers to the lifetime of a borrowed string when
|
||||||
/// a new owned string isn't needed (e.g., for `NoExpand`).
|
/// a new owned string isn't needed (e.g., for `NoExpand`).
|
||||||
@ -726,7 +726,7 @@ impl<'t> Captures<'t> {
|
|||||||
match self.named {
|
match self.named {
|
||||||
None => "",
|
None => "",
|
||||||
Some(ref h) => {
|
Some(ref h) => {
|
||||||
match h.find_equiv(name) {
|
match h.get(name) {
|
||||||
None => "",
|
None => "",
|
||||||
Some(i) => self.at(*i),
|
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 {
|
if sess.target.target.options.morestack {
|
||||||
ab.add_native_library("morestack").unwrap();
|
ab.add_native_library("morestack").unwrap();
|
||||||
}
|
}
|
||||||
|
if !sess.target.target.options.no_compiler_rt {
|
||||||
ab.add_native_library("compiler-rt").unwrap();
|
ab.add_native_library("compiler-rt").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
|
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
|
||||||
let mut all_native_libs = vec![];
|
let mut all_native_libs = vec![];
|
||||||
|
@ -143,5 +143,6 @@ register_diagnostics!(
|
|||||||
E0164,
|
E0164,
|
||||||
E0165,
|
E0165,
|
||||||
E0166,
|
E0166,
|
||||||
E0167
|
E0167,
|
||||||
|
E0168
|
||||||
)
|
)
|
||||||
|
@ -623,6 +623,7 @@ impl LintPass for UnusedAttributes {
|
|||||||
"link",
|
"link",
|
||||||
"link_name",
|
"link_name",
|
||||||
"link_section",
|
"link_section",
|
||||||
|
"linkage",
|
||||||
"no_builtins",
|
"no_builtins",
|
||||||
"no_mangle",
|
"no_mangle",
|
||||||
"no_split_stack",
|
"no_split_stack",
|
||||||
|
@ -165,7 +165,7 @@ impl LintStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_renamed(&mut self, old_name: &str, new_name: &str) {
|
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(),
|
Some(&Id(lint_id)) => lint_id.clone(),
|
||||||
_ => panic!("invalid lint renaming of {} to {}", old_name, new_name)
|
_ => 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>)
|
fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
|
||||||
-> Option<LintId>
|
-> 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(&Id(lint_id)) => Some(lint_id),
|
||||||
Some(&Renamed(ref new_name, lint_id)) => {
|
Some(&Renamed(ref new_name, lint_id)) => {
|
||||||
let warning = format!("lint {} has been renamed to {}",
|
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()))
|
match self.lint_groups.iter().map(|(&x, pair)| (x, pair.ref0().clone()))
|
||||||
.collect::<FnvHashMap<&'static str,
|
.collect::<FnvHashMap<&'static str,
|
||||||
Vec<LintId>>>()
|
Vec<LintId>>>()
|
||||||
.find_equiv(lint_name.as_slice()) {
|
.get(lint_name.as_slice()) {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
v.iter()
|
v.iter()
|
||||||
.map(|lint_id: &LintId|
|
.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)) {
|
match self.lints.find_lint(lint_name.get(), &self.tcx.sess, Some(span)) {
|
||||||
Some(lint_id) => vec![(lint_id, level, span)],
|
Some(lint_id) => vec![(lint_id, level, span)],
|
||||||
None => {
|
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()
|
Some(&(ref v, _)) => v.iter()
|
||||||
.map(|lint_id: &LintId|
|
.map(|lint_id: &LintId|
|
||||||
(*lint_id, level, span))
|
(*lint_id, level, span))
|
||||||
|
@ -242,6 +242,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
|||||||
cstore::NativeFramework
|
cstore::NativeFramework
|
||||||
} else if k.equiv(&("framework")) {
|
} else if k.equiv(&("framework")) {
|
||||||
cstore::NativeFramework
|
cstore::NativeFramework
|
||||||
|
} else if k.equiv(&("dylib")) {
|
||||||
|
cstore::NativeUnknown
|
||||||
} else {
|
} else {
|
||||||
e.sess.span_err(m.span,
|
e.sess.span_err(m.span,
|
||||||
format!("unknown kind: `{}`",
|
format!("unknown kind: `{}`",
|
||||||
@ -321,7 +323,7 @@ fn existing_match(e: &Env, name: &str,
|
|||||||
// `source` stores paths which are normalized which may be different
|
// `source` stores paths which are normalized which may be different
|
||||||
// from the strings on the command line.
|
// from the strings on the command line.
|
||||||
let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
|
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) => {
|
Some(locs) => {
|
||||||
let found = locs.iter().any(|l| {
|
let found = locs.iter().any(|l| {
|
||||||
let l = fs::realpath(&Path::new(l.as_slice())).ok();
|
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 {
|
fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
|
||||||
let name = reader::get_doc(item, tag_paths_data_name);
|
let name = reader::get_doc(item, tag_paths_data_name);
|
||||||
let string = name.as_str_slice();
|
let string = name.as_str_slice();
|
||||||
match intr.find_equiv(string) {
|
match intr.find(string) {
|
||||||
None => token::intern(string),
|
None => token::intern(string),
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
}
|
}
|
||||||
@ -1449,4 +1449,3 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
|
|||||||
Some(item) => item_sort(item) == 't',
|
Some(item) => item_sort(item) == 't',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ impl<'a> FileSearch<'a> {
|
|||||||
debug!("filesearch: searching lib path");
|
debug!("filesearch: searching lib path");
|
||||||
let tlib_path = make_target_lib_path(self.sysroot,
|
let tlib_path = make_target_lib_path(self.sysroot,
|
||||||
self.triple);
|
self.triple);
|
||||||
if !visited_dirs.contains_equiv(tlib_path.as_vec()) {
|
if !visited_dirs.contains(tlib_path.as_vec()) {
|
||||||
match f(&tlib_path) {
|
match f(&tlib_path) {
|
||||||
FileMatches => found = true,
|
FileMatches => found = true,
|
||||||
FileDoesntMatch => ()
|
FileDoesntMatch => ()
|
||||||
@ -69,9 +69,9 @@ impl<'a> FileSearch<'a> {
|
|||||||
let tlib_path = make_rustpkg_lib_path(
|
let tlib_path = make_rustpkg_lib_path(
|
||||||
self.sysroot, path, self.triple);
|
self.sysroot, path, self.triple);
|
||||||
debug!("is {} in visited_dirs? {}", tlib_path.display(),
|
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());
|
visited_dirs.insert(tlib_path.as_vec().to_vec());
|
||||||
// Don't keep searching the RUST_PATH if one match turns up --
|
// Don't keep searching the RUST_PATH if one match turns up --
|
||||||
// if we did, we'd get a "multiple matching crates" error
|
// 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> {
|
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,
|
Some(s) => s,
|
||||||
None => return None,
|
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> {
|
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> {
|
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> {
|
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) {
|
fn visit_item(&mut self, item: &ast::Item) {
|
||||||
match extract(item.attrs.as_slice()) {
|
match extract(item.attrs.as_slice()) {
|
||||||
Some(value) => {
|
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 {
|
match item_index {
|
||||||
Some(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,
|
fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
|
||||||
b: &'v Block, s: Span, _: NodeId) {
|
_: &'v Block, _: Span, _: NodeId) {
|
||||||
match fk {
|
match fk {
|
||||||
FkMethod(_, _, meth) => {
|
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) {
|
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
|
// matches this obligation, then we can assume that the
|
||||||
// obligation is satisfied for now (still all other conditions
|
// obligation is satisfied for now (still all other conditions
|
||||||
// must be met of course). One obvious case this comes up is
|
// 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>>> {
|
// 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::driver::{CrateAnalysis, CrateTranslation, ModuleTranslation};
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use lint;
|
use lint;
|
||||||
use llvm::{BasicBlockRef, ValueRef, Vector, get_param};
|
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
|
||||||
use llvm;
|
use llvm;
|
||||||
use metadata::{csearch, encoder, loader};
|
use metadata::{csearch, encoder, loader};
|
||||||
use middle::astencode;
|
use middle::astencode;
|
||||||
@ -216,7 +216,7 @@ pub fn get_extern_fn(ccx: &CrateContext,
|
|||||||
ty: Type,
|
ty: Type,
|
||||||
output: ty::t)
|
output: ty::t)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
match externs.find_equiv(name) {
|
match externs.get(name) {
|
||||||
Some(n) => return *n,
|
Some(n) => return *n,
|
||||||
None => {}
|
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 {
|
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,
|
Some(n) => return *n,
|
||||||
None => ()
|
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.
|
/// Enum describing the origin of an LLVM `Value`, for linkage purposes.
|
||||||
pub enum ValueOrigin {
|
pub enum ValueOrigin {
|
||||||
/// The LLVM `Value` is in this context because the corresponding item was
|
/// The LLVM `Value` is in this context because the corresponding item was
|
||||||
@ -2174,6 +2200,23 @@ pub fn update_linkage(ccx: &CrateContext,
|
|||||||
OriginalTranslation => {},
|
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 {
|
match id {
|
||||||
Some(id) if ccx.reachable().contains(&id) => {
|
Some(id) if ccx.reachable().contains(&id) => {
|
||||||
llvm::SetLinkage(llval, llvm::ExternalLinkage);
|
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);
|
let name = CString::new(llvm::LLVMGetValueName(val), false);
|
||||||
if !declared.contains(&name) &&
|
if !declared.contains(&name) &&
|
||||||
!reachable.contains_equiv(name.as_str().unwrap()) {
|
!reachable.contains(name.as_str().unwrap()) {
|
||||||
llvm::SetLinkage(val, llvm::InternalLinkage);
|
llvm::SetLinkage(val, llvm::InternalLinkage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1677,7 +1677,7 @@ fn declare_local(bcx: Block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
|
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,
|
Some(file_metadata) => return *file_metadata,
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
use back::{link};
|
use back::{link};
|
||||||
use llvm::{ValueRef, CallConv, Linkage, get_param};
|
use llvm::{ValueRef, CallConv, get_param};
|
||||||
use llvm;
|
use llvm;
|
||||||
use middle::weak_lang_items;
|
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::base;
|
||||||
use middle::trans::build::*;
|
use middle::trans::build::*;
|
||||||
use middle::trans::cabi;
|
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,
|
pub fn register_static(ccx: &CrateContext,
|
||||||
foreign_item: &ast::ForeignItem) -> ValueRef {
|
foreign_item: &ast::ForeignItem) -> ValueRef {
|
||||||
let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);
|
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> {
|
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 {
|
pub fn type_to_string(&self, ty: Type) -> String {
|
||||||
|
@ -297,11 +297,25 @@ pub fn check_pat_struct(pcx: &pat_ctxt, pat: &ast::Pat,
|
|||||||
let tcx = pcx.fcx.ccx.tcx;
|
let tcx = pcx.fcx.ccx.tcx;
|
||||||
|
|
||||||
let def = tcx.def_map.borrow()[pat.id].clone();
|
let def = tcx.def_map.borrow()[pat.id].clone();
|
||||||
|
let (enum_def_id, variant_def_id) = match def {
|
||||||
|
def::DefTrait(_) => {
|
||||||
|
let name = pprust::path_to_string(path);
|
||||||
|
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());
|
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 {
|
match ty::get(def_type.ty).sty {
|
||||||
ty::ty_struct(struct_def_id, _) =>
|
ty::ty_struct(struct_def_id, _) =>
|
||||||
(struct_def_id, 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) =>
|
ty::ty_enum(enum_def_id, _)
|
||||||
|
if def == def::DefVariant(enum_def_id, def.def_id(), true) =>
|
||||||
(enum_def_id, def.def_id()),
|
(enum_def_id, def.def_id()),
|
||||||
_ => {
|
_ => {
|
||||||
let name = pprust::path_to_string(path);
|
let name = pprust::path_to_string(path);
|
||||||
@ -314,6 +328,8 @@ pub fn check_pat_struct(pcx: &pat_ctxt, pat: &ast::Pat,
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
instantiate_path(pcx.fcx, path, ty::lookup_item_type(tcx, enum_def_id),
|
instantiate_path(pcx.fcx, path, ty::lookup_item_type(tcx, enum_def_id),
|
||||||
|
@ -2122,7 +2122,7 @@ impl<'a> fmt::Show for Sidebar<'a> {
|
|||||||
|
|
||||||
fn block(w: &mut fmt::Formatter, short: &str, longty: &str,
|
fn block(w: &mut fmt::Formatter, short: &str, longty: &str,
|
||||||
cur: &clean::Item, cx: &Context) -> fmt::Result {
|
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(),
|
Some(items) => items.as_slice(),
|
||||||
None => return Ok(())
|
None => return Ok(())
|
||||||
};
|
};
|
||||||
|
@ -901,7 +901,7 @@ impl Json {
|
|||||||
/// Otherwise, returns None.
|
/// Otherwise, returns None.
|
||||||
pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
|
pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
|
||||||
match self {
|
match self {
|
||||||
&Object(ref map) => map.find_with(|s| key.cmp(s.as_slice())),
|
&Object(ref map) => map.get(key),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,7 +926,7 @@ impl Json {
|
|||||||
pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
|
pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
|
||||||
match self {
|
match self {
|
||||||
&Object(ref map) => {
|
&Object(ref map) => {
|
||||||
match map.find_with(|s| key.cmp(s.as_slice())) {
|
match map.get(key) {
|
||||||
Some(json_value) => Some(json_value),
|
Some(json_value) => Some(json_value),
|
||||||
None => {
|
None => {
|
||||||
for (_, v) in map.iter() {
|
for (_, v) in map.iter() {
|
||||||
|
@ -14,6 +14,7 @@ pub use self::Entry::*;
|
|||||||
use self::SearchResult::*;
|
use self::SearchResult::*;
|
||||||
use self::VacantEntryState::*;
|
use self::VacantEntryState::*;
|
||||||
|
|
||||||
|
use borrow::BorrowFrom;
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use cmp::{max, Eq, Equiv, PartialEq};
|
use cmp::{max, Eq, Equiv, PartialEq};
|
||||||
use default::Default;
|
use default::Default;
|
||||||
@ -142,7 +143,7 @@ impl DefaultResizePolicy {
|
|||||||
// about the size of rust executables.
|
// about the size of rust executables.
|
||||||
//
|
//
|
||||||
// Annotate exceedingly likely branches in `table::make_hash`
|
// 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).
|
// and mispredictions once it becomes possible (blocked on issue #11092).
|
||||||
//
|
//
|
||||||
// Shrinking the table could simply reallocate in place after moving buckets
|
// Shrinking the table could simply reallocate in place after moving buckets
|
||||||
@ -286,7 +287,7 @@ pub struct HashMap<K, V, H = RandomSipHasher> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Search for a pre-hashed key.
|
/// Search for a pre-hashed key.
|
||||||
fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
|
fn search_hashed<K, V, M: Deref<RawTable<K, V>>>(table: M,
|
||||||
hash: &SafeHash,
|
hash: &SafeHash,
|
||||||
is_match: |&K| -> bool)
|
is_match: |&K| -> bool)
|
||||||
-> SearchResult<K, V, M> {
|
-> SearchResult<K, V, M> {
|
||||||
@ -325,11 +326,6 @@ fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
|
|||||||
TableRef(probe.into_table())
|
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) {
|
fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
|
||||||
let (empty, retkey, retval) = starting_bucket.take();
|
let (empty, retkey, retval) = starting_bucket.take();
|
||||||
let mut gap = match empty.gap_peek() {
|
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)
|
fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
|
||||||
-> Option<FullBucketImm<'a, K, V>> {
|
-> Option<FullBucketImm<'a, K, V>> {
|
||||||
let hash = self.make_hash(q);
|
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)
|
fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
|
||||||
-> Option<FullBucketMut<'a, K, V>> {
|
-> Option<FullBucketMut<'a, K, V>> {
|
||||||
let hash = self.make_hash(q);
|
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.
|
/// 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
|
/// If you already have the hash for the key lying around, use
|
||||||
/// search_hashed.
|
/// search_hashed.
|
||||||
fn search<'a>(&'a self, k: &K) -> Option<FullBucketImm<'a, K, V>> {
|
fn search<'a, Sized? Q>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
|
||||||
let hash = self.make_hash(k);
|
where Q: BorrowFrom<K> + Eq + Hash<S>
|
||||||
search_hashed(&self.table, &hash, k).into_option()
|
{
|
||||||
|
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>> {
|
fn search_mut<'a, Sized? Q>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
|
||||||
let hash = self.make_hash(k);
|
where Q: BorrowFrom<K> + Eq + Hash<S>
|
||||||
search_hashed(&mut self.table, &hash, k).into_option()
|
{
|
||||||
|
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.
|
// 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,
|
/// Deprecated: use `contains_key` and `BorrowFrom` instead.
|
||||||
/// using equivalence.
|
#[deprecated = "use contains_key and BorrowFrom instead"]
|
||||||
///
|
|
||||||
/// See [pop_equiv](#method.pop_equiv) for an extended example.
|
|
||||||
pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
|
pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
|
||||||
self.search_equiv(key).is_some()
|
self.search_equiv(key).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value corresponding to the key in the map, using
|
/// Deprecated: use `get` and `BorrowFrom` instead.
|
||||||
/// equivalence.
|
#[deprecated = "use get and BorrowFrom instead"]
|
||||||
///
|
|
||||||
/// See [pop_equiv](#method.pop_equiv) for an extended example.
|
|
||||||
pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
|
pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
|
||||||
match self.search_equiv(k) {
|
match self.search_equiv(k) {
|
||||||
None => None,
|
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
|
/// Deprecated: use `remove` and `BorrowFrom` instead.
|
||||||
/// key if the key was previously in the map.
|
#[deprecated = "use remove and BorrowFrom instead"]
|
||||||
///
|
|
||||||
/// # 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]
|
|
||||||
pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
|
pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
|
||||||
if self.table.size() == 0 {
|
if self.table.size() == 0 {
|
||||||
return None
|
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.
|
/// 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
|
/// # 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);
|
/// assert_eq!(map.get(&2), None);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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| {
|
self.search(k).map(|bucket| {
|
||||||
let (_, v) = bucket.into_refs();
|
let (_, v) = bucket.into_refs();
|
||||||
v
|
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.
|
/// 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
|
/// # 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);
|
/// assert_eq!(map.contains_key(&2), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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()
|
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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -1093,7 +1063,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
|||||||
/// assert_eq!(map[1], "b");
|
/// assert_eq!(map[1], "b");
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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) {
|
match self.search_mut(k) {
|
||||||
Some(bucket) => {
|
Some(bucket) => {
|
||||||
let (_, v) = bucket.into_mut_refs();
|
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
|
/// Removes a key from the map, returning the value at the key if the key
|
||||||
/// was previously in the map.
|
/// 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
|
/// # 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);
|
/// assert_eq!(map.remove(&1), None);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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 {
|
if self.table.size() == 0 {
|
||||||
return None
|
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]
|
#[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")
|
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]
|
#[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) {
|
match self.get_mut(index) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => panic!("no entry found for key")
|
None => panic!("no entry found for key")
|
||||||
@ -1962,11 +1944,11 @@ mod test_map {
|
|||||||
m.insert("baz".to_string(), baz);
|
m.insert("baz".to_string(), baz);
|
||||||
|
|
||||||
|
|
||||||
assert_eq!(m.find_equiv("foo"), Some(&foo));
|
assert_eq!(m.get("foo"), Some(&foo));
|
||||||
assert_eq!(m.find_equiv("bar"), Some(&bar));
|
assert_eq!(m.get("bar"), Some(&bar));
|
||||||
assert_eq!(m.find_equiv("baz"), Some(&baz));
|
assert_eq!(m.get("baz"), Some(&baz));
|
||||||
|
|
||||||
assert_eq!(m.find_equiv("qux"), None);
|
assert_eq!(m.get("qux"), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
//
|
//
|
||||||
// ignore-lexer-test FIXME #15883
|
// ignore-lexer-test FIXME #15883
|
||||||
|
|
||||||
|
use borrow::BorrowFrom;
|
||||||
use cmp::{Eq, Equiv, PartialEq};
|
use cmp::{Eq, Equiv, PartialEq};
|
||||||
use core::kinds::Sized;
|
use core::kinds::Sized;
|
||||||
use default::Default;
|
use default::Default;
|
||||||
@ -184,47 +185,9 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
|
|||||||
self.map.reserve(n)
|
self.map.reserve(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the hash set contains a value equivalent to the
|
/// Deprecated: use `contains` and `BorrowFrom`.
|
||||||
/// given query value.
|
#[deprecated = "use contains and BorrowFrom"]
|
||||||
///
|
#[allow(deprecated)]
|
||||||
/// # 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 }));
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
pub fn contains_equiv<Sized? Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
|
pub fn contains_equiv<Sized? Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
|
||||||
self.map.contains_key_equiv(value)
|
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.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -437,7 +404,11 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
|
|||||||
/// assert_eq!(set.contains(&4), false);
|
/// assert_eq!(set.contains(&4), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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`.
|
/// Returns `true` if the set has no elements in common with `other`.
|
||||||
/// This is equivalent to checking for an empty intersection.
|
/// 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
|
/// Removes a value from the set. Returns `true` if the value was
|
||||||
/// present in the set.
|
/// 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -539,7 +514,11 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
|
|||||||
/// assert_eq!(set.remove(&2), false);
|
/// assert_eq!(set.remove(&2), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
#[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> {
|
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
|
/// 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.
|
/// the table's remaining entries. It's used in the implementation of Drop.
|
||||||
struct RevMoveBuckets<'a, K, V> {
|
struct RevMoveBuckets<'a, K, V> {
|
||||||
raw: RawBucket<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 reader = try!(File::open(from));
|
||||||
let mut writer = try!(File::create(to));
|
let mut writer = try!(File::create(to));
|
||||||
let mut buf = [0, ..io::DEFAULT_BUF_SIZE];
|
|
||||||
|
|
||||||
loop {
|
try!(update_err(super::util::copy(&mut reader, &mut writer), from, to));
|
||||||
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]));
|
|
||||||
}
|
|
||||||
|
|
||||||
chmod(to, try!(update_err(from.stat(), from, to)).perm)
|
chmod(to, try!(update_err(from.stat(), from, to)).perm)
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,7 @@ extern crate rustrt;
|
|||||||
|
|
||||||
pub use core::any;
|
pub use core::any;
|
||||||
pub use core::bool;
|
pub use core::bool;
|
||||||
|
pub use core::borrow;
|
||||||
pub use core::cell;
|
pub use core::cell;
|
||||||
pub use core::clone;
|
pub use core::clone;
|
||||||
#[cfg(not(test))] pub use core::cmp;
|
#[cfg(not(test))] pub use core::cmp;
|
||||||
|
@ -81,7 +81,7 @@ const BUF_BYTES : uint = 2048u;
|
|||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Fails if the current working directory value is invalid:
|
/// Fails if the current working directory value is invalid:
|
||||||
/// Possibles cases:
|
/// Possible cases:
|
||||||
///
|
///
|
||||||
/// * Current directory does not exist.
|
/// * Current directory does not exist.
|
||||||
/// * There are insufficient permissions to access the current directory.
|
/// * 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)),
|
assert_eq!(format!("{:30}", Duration::days(1) + Duration::milliseconds(2345)),
|
||||||
"P1DT2.345S".to_string());
|
"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> {
|
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
|
// cannot be shared with any other operand (usually when
|
||||||
// a register is clobbered early.)
|
// a register is clobbered early.)
|
||||||
let output = match constraint.get().slice_shift_char() {
|
let output = match constraint.get().slice_shift_char() {
|
||||||
(Some('='), _) => None,
|
Some(('=', _)) => None,
|
||||||
(Some('+'), operand) => {
|
Some(('+', operand)) => {
|
||||||
Some(token::intern_and_get_ident(format!(
|
Some(token::intern_and_get_ident(format!(
|
||||||
"={}",
|
"={}",
|
||||||
operand).as_slice()))
|
operand).as_slice()))
|
||||||
|
@ -144,7 +144,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
|
|||||||
let name = interned_name.get();
|
let name = interned_name.get();
|
||||||
p.expect(&token::Eq);
|
p.expect(&token::Eq);
|
||||||
let e = p.parse_expr();
|
let e = p.parse_expr();
|
||||||
match names.find_equiv(name) {
|
match names.get(name) {
|
||||||
None => {}
|
None => {}
|
||||||
Some(prev) => {
|
Some(prev) => {
|
||||||
ecx.span_err(e.span,
|
ecx.span_err(e.span,
|
||||||
@ -366,7 +366,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
self.ecx.expr_path(path)
|
self.ecx.expr_path(path)
|
||||||
}
|
}
|
||||||
parse::CountIsName(n) => {
|
parse::CountIsName(n) => {
|
||||||
let i = match self.name_positions.find_equiv(n) {
|
let i = match self.name_positions.get(n) {
|
||||||
Some(&i) => i,
|
Some(&i) => i,
|
||||||
None => 0, // error already emitted elsewhere
|
None => 0, // error already emitted elsewhere
|
||||||
};
|
};
|
||||||
@ -410,7 +410,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
// Named arguments are converted to positional arguments at
|
// Named arguments are converted to positional arguments at
|
||||||
// the end of the list of arguments
|
// the end of the list of arguments
|
||||||
parse::ArgumentNamed(n) => {
|
parse::ArgumentNamed(n) => {
|
||||||
let i = match self.name_positions.find_equiv(n) {
|
let i = match self.name_positions.get(n) {
|
||||||
Some(&i) => i,
|
Some(&i) => i,
|
||||||
None => 0, // error already emitted elsewhere
|
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 \
|
"`#[thread_local]` is an experimental feature, and does not \
|
||||||
currently handle destructors. There is no corresponding \
|
currently handle destructors. There is no corresponding \
|
||||||
`#[task_local]` mapping to the task model");
|
`#[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 {
|
match i.node {
|
||||||
|
@ -1232,7 +1232,8 @@ impl<'a> Parser<'a> {
|
|||||||
{
|
{
|
||||||
if self.eat(&token::Lt) {
|
if self.eat(&token::Lt) {
|
||||||
if lifetime_defs.is_empty() {
|
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();
|
let lifetime_defs = self.parse_lifetime_defs();
|
||||||
self.expect_gt();
|
self.expect_gt();
|
||||||
lifetime_defs
|
lifetime_defs
|
||||||
@ -5178,7 +5179,15 @@ impl<'a> Parser<'a> {
|
|||||||
if self.eat(&token::OpenDelim(token::Brace)) {
|
if self.eat(&token::OpenDelim(token::Brace)) {
|
||||||
// Parse a struct variant.
|
// Parse a struct variant.
|
||||||
all_nullary = false;
|
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) {
|
} else if self.token == token::OpenDelim(token::Paren) {
|
||||||
all_nullary = false;
|
all_nullary = false;
|
||||||
let arg_tys = self.parse_enum_variant_seq(
|
let arg_tys = self.parse_enum_variant_seq(
|
||||||
|
@ -1855,7 +1855,7 @@ impl<'a> State<'a> {
|
|||||||
try!(self.commasep(Inconsistent, a.outputs.as_slice(),
|
try!(self.commasep(Inconsistent, a.outputs.as_slice(),
|
||||||
|s, &(ref co, ref o, is_rw)| {
|
|s, &(ref co, ref o, is_rw)| {
|
||||||
match co.get().slice_shift_char() {
|
match co.get().slice_shift_char() {
|
||||||
(Some('='), operand) if is_rw => {
|
Some(('=', operand)) if is_rw => {
|
||||||
try!(s.print_string(format!("+{}", operand).as_slice(),
|
try!(s.print_string(format!("+{}", operand).as_slice(),
|
||||||
ast::CookedStr))
|
ast::CookedStr))
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
use ast::Name;
|
use ast::Name;
|
||||||
|
|
||||||
|
use std::borrow::BorrowFrom;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::Equiv;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -75,9 +75,10 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> {
|
|||||||
(*vect).len()
|
(*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();
|
let map = self.map.borrow();
|
||||||
match (*map).find_equiv(val) {
|
match (*map).get(val) {
|
||||||
Some(v) => Some(*v),
|
Some(v) => Some(*v),
|
||||||
None => None,
|
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 {
|
impl RcStr {
|
||||||
pub fn new(string: &str) -> RcStr {
|
pub fn new(string: &str) -> RcStr {
|
||||||
RcStr {
|
RcStr {
|
||||||
@ -149,7 +156,7 @@ impl StrInterner {
|
|||||||
|
|
||||||
pub fn intern(&self, val: &str) -> Name {
|
pub fn intern(&self, val: &str) -> Name {
|
||||||
let mut map = self.map.borrow_mut();
|
let mut map = self.map.borrow_mut();
|
||||||
match map.find_equiv(val) {
|
match map.get(val) {
|
||||||
Some(&idx) => return idx,
|
Some(&idx) => return idx,
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
@ -195,8 +202,9 @@ impl StrInterner {
|
|||||||
self.vect.borrow().len()
|
self.vect.borrow().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_equiv<Sized? Q:Hash + Equiv<RcStr>>(&self, val: &Q) -> Option<Name> {
|
pub fn find<Sized? Q>(&self, val: &Q) -> Option<Name>
|
||||||
match (*self.map.borrow()).find_equiv(val) {
|
where Q: BorrowFrom<RcStr> + Eq + Hash {
|
||||||
|
match (*self.map.borrow()).get(val) {
|
||||||
Some(v) => Some(*v),
|
Some(v) => Some(*v),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
|
|||||||
if self.num_colors > color {
|
if self.num_colors > color {
|
||||||
let s = expand(self.ti
|
let s = expand(self.ti
|
||||||
.strings
|
.strings
|
||||||
.find_equiv("setaf")
|
.get("setaf")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
&[Number(color as int)], &mut Variables::new());
|
&[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 {
|
if self.num_colors > color {
|
||||||
let s = expand(self.ti
|
let s = expand(self.ti
|
||||||
.strings
|
.strings
|
||||||
.find_equiv("setab")
|
.get("setab")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_slice(),
|
.as_slice(),
|
||||||
&[Number(color as int)], &mut Variables::new());
|
&[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),
|
attr::BackgroundColor(c) => self.bg(c),
|
||||||
_ => {
|
_ => {
|
||||||
let cap = cap_for_attr(attr);
|
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() {
|
if parm.is_some() {
|
||||||
let s = expand(parm.unwrap().as_slice(),
|
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);
|
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<()> {
|
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() {
|
if cap.is_none() {
|
||||||
// are there any terminals that have color/attrs and not sgr0?
|
// are there any terminals that have color/attrs and not sgr0?
|
||||||
// Try falling back to sgr, then op
|
// Try falling back to sgr, then op
|
||||||
cap = self.ti.strings.find_equiv("sgr");
|
cap = self.ti.strings.get("sgr");
|
||||||
if cap.is_none() {
|
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| {
|
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 inf = ti.unwrap();
|
||||||
let nc = if inf.strings.find_equiv("setaf").is_some()
|
let nc = if inf.strings.get("setaf").is_some()
|
||||||
&& inf.strings.find_equiv("setab").is_some() {
|
&& inf.strings.get("setab").is_some() {
|
||||||
inf.numbers.find_equiv("colors").map_or(0, |&n| n)
|
inf.numbers.get("colors").map_or(0, |&n| n)
|
||||||
} else { 0 };
|
} else { 0 };
|
||||||
|
|
||||||
return Some(box TerminfoTerminal {out: out,
|
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
|
// given a map, search for the frequency of a pattern
|
||||||
fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
|
fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
|
||||||
let key = key.into_ascii().as_slice().to_lowercase().into_string();
|
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::None => { return 0u; }
|
||||||
option::Some(&num) => { return num; }
|
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();
|
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]
|
#[deprecated]
|
||||||
pub trait DeprecatedTrait {}
|
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