CFG_LIB_DSYM_GLOB_aarch64-apple-ios = lib$(1)-*.a.dSYM
CFG_CFLAGS_aarch64-apple-ios := $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
CFG_JEMALLOC_CFLAGS_aarch64-apple-ios := $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
-CFG_GCCISH_CFLAGS_aarch64-apple-ios := -Wall -Werror -fPIC $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
+CFG_GCCISH_CFLAGS_aarch64-apple-ios := -fPIC $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios)
CFG_GCCISH_CXXFLAGS_aarch64-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios) -I$(CFG_IOS_SDK_aarch64-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_aarch64-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_aarch64-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_aarch64-apple-ios := -Wl,-exported_symbols_list,
CFG_STATIC_LIB_NAME_armv7-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_armv7-apple-ios = lib$(1)-*.a.dSYM
CFG_JEMALLOC_CFLAGS_armv7-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_SDK_FLAGS_armv7-apple-ios)
-CFG_GCCISH_CFLAGS_armv7-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -mfpu=vfp3 -arch armv7
+CFG_GCCISH_CFLAGS_armv7-apple-ios := -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -mfpu=vfp3 -arch armv7
CFG_GCCISH_CXXFLAGS_armv7-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -I$(CFG_IOS_SDK_armv7-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_armv7-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_armv7-apple-ios := -Wl,-exported_symbols_list,
CFG_STATIC_LIB_NAME_armv7s-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_armv7s-apple-ios = lib$(1)-*.a.dSYM
CFG_JEMALLOC_CFLAGS_armv7s-apple-ios := -arch armv7s $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios)
-CFG_GCCISH_CFLAGS_armv7s-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -arch armv7s
+CFG_GCCISH_CFLAGS_armv7s-apple-ios := -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -arch armv7s
CFG_GCCISH_CXXFLAGS_armv7s-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -I$(CFG_IOS_SDK_armv7s-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_armv7s-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7s-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_armv7s-apple-ios := -Wl,-exported_symbols_list,
CFG_LIB_GLOB_asmjs-unknown-emscripten=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_asmjs-unknown-emscripten=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_asmjs-unknown-emscripten := -m32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_asmjs-unknown-emscripten := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_asmjs-unknown-emscripten := -g -fPIC -m32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_asmjs-unknown-emscripten := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_asmjs-unknown-emscripten := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_asmjs-unknown-emscripten := -Wl,--export-dynamic,--dynamic-list=
CFG_INSTALL_ONLY_RLIB_i386-apple-ios = 1
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
-CFG_GCCISH_CFLAGS_i386-apple-ios := -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS_i386-apple-ios)
+CFG_GCCISH_CFLAGS_i386-apple-ios := -g -fPIC -m32 $(CFG_IOSSIM_FLAGS_i386-apple-ios)
CFG_GCCISH_CXXFLAGS_i386-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_i386-apple-ios) -I$(CFG_IOSSIM_SDK_i386-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_i386-apple-ios := -lpthread -m32 -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK_i386-apple-ios)
CFG_GCCISH_DEF_FLAG_i386-apple-ios := -Wl,-exported_symbols_list,
CFG_LIB_GLOB_i586-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i586-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i586-unknown-linux-gnu := -m32 $(CFLAGS) -march=pentium
-CFG_GCCISH_CFLAGS_i586-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) -march=pentium
+CFG_GCCISH_CFLAGS_i586-unknown-linux-gnu := -g -fPIC -m32 $(CFLAGS) -march=pentium
CFG_GCCISH_CXXFLAGS_i586-unknown-linux-gnu := -fno-rtti $(CXXFLAGS) -march=pentium
CFG_GCCISH_LINK_FLAGS_i586-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_i586-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
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 := -g -fPIC -m32 -arch i386 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32
CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
CFG_LIB_DSYM_GLOB_i686-pc-windows-gnu=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-pc-windows-gnu := -march=i686 -m32 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -g -m32 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32
CFG_GCCISH_DEF_FLAG_i686-pc-windows-gnu :=
CFG_LIB_GLOB_i686-unknown-freebsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i686-unknown-freebsd=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-unknown-freebsd := -m32 -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-unknown-freebsd := -Wall -Werror -g -fPIC -m32 -arch i386 -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-unknown-freebsd := -g -fPIC -m32 -arch i386 -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-unknown-freebsd := -m32 -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_i686-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_i686-unknown-freebsd :=
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) -march=i686
+CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -g -fPIC -m32 $(CFLAGS) -march=i686
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_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_STATIC_LIB_NAME_i686-unknown-linux-musl=lib$(1).a
CFG_LIB_GLOB_i686-unknown-linux-musl=lib$(1)-*.so
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-musl := -m32 -Wl,-melf_i386
-CFG_GCCISH_CFLAGS_i686-unknown-linux-musl := -Wall -Werror -g -fPIC -m32 -Wl,-melf_i386
+CFG_GCCISH_CFLAGS_i686-unknown-linux-musl := -g -fPIC -m32 -Wl,-melf_i386
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-musl :=
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-musl :=
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-musl :=
CFG_LIB_GLOB_powerpc-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_powerpc-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_powerpc-unknown-linux-gnu := -m32 $(CFLAGS)
-CFG_GCCISH_CFLAGS_powerpc-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_powerpc-unknown-linux-gnu := -g -fPIC -m32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_powerpc-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_powerpc-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_powerpc-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_LIB_DSYM_GLOB_powerpc64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_powerpc64-unknown-linux-gnu := -m64
CFG_CFLAGS_powerpc64-unknown-linux-gnu := -m64 $(CFLAGS)
-CFG_GCCISH_CFLAGS_powerpc64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64 $(CFLAGS)
+CFG_GCCISH_CFLAGS_powerpc64-unknown-linux-gnu := -g -fPIC -m64 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_powerpc64-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_powerpc64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
CFG_GCCISH_DEF_FLAG_powerpc64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_LIB_GLOB_powerpc64le-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_powerpc64le-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_CFLAGS_powerpc64le-unknown-linux-gnu := -m64 $(CFLAGS)
-CFG_GCCISH_CFLAGS_powerpc64le-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64 $(CFLAGS)
+CFG_GCCISH_CFLAGS_powerpc64le-unknown-linux-gnu := -g -fPIC -m64 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_powerpc64le-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_powerpc64le-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
CFG_GCCISH_DEF_FLAG_powerpc64le-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
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 := -g -fPIC -m64 -arch x86_64 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64
CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
CFG_LIB_DSYM_GLOB_x86_64-apple-ios = lib$(1)-*.a.dSYM
CFG_CFLAGS_x86_64-apple-ios := $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
CFG_JEMALLOC_CFLAGS_x86_64-apple-ios := $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
-CFG_GCCISH_CFLAGS_x86_64-apple-ios := -Wall -Werror -fPIC $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
+CFG_GCCISH_CFLAGS_x86_64-apple-ios := -fPIC $(CFG_IOSSIM_FLAGS_x86_64-apple-ios)
CFG_GCCISH_CXXFLAGS_x86_64-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_x86_64-apple-ios) -I$(CFG_IOSSIM_SDK_x86_64-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_x86_64-apple-ios := -lpthread -Wl,-no_compact_unwind -m64 -Wl,-syslibroot $(CFG_IOSSIM_SDK_x86_64-apple-ios)
CFG_GCCISH_DEF_FLAG_x86_64-apple-ios := -Wl,-exported_symbols_list,
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-gnu=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-gnu := -m64 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -g -m64 -D_WIN32_WINNT=0x0600 -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS)
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_DEF_FLAG_x86_64-pc-windows-gnu :=
CFG_STATIC_LIB_NAME_x86_64-rumprun-netbsd=lib$(1).a
CFG_LIB_GLOB_x86_64-rumprun-netbsd=lib$(1)-*.so
CFG_JEMALLOC_CFLAGS_x86_64-rumprun-netbsd := -m64
-CFG_GCCISH_CFLAGS_x86_64-rumprun-netbsd := -Wall -Werror -g -fPIC -m64
+CFG_GCCISH_CFLAGS_x86_64-rumprun-netbsd := -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-rumprun-netbsd :=
CFG_GCCISH_LINK_FLAGS_x86_64-rumprun-netbsd :=
CFG_GCCISH_DEF_FLAG_x86_64-rumprun-netbsd :=
CFG_LIB_GLOB_x86_64-sun-solaris=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-sun-solaris=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-sun-solaris := -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-sun-solaris := -Wall -Werror -g -D_POSIX_PTHREAD_SEMANTICS -fPIC -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-sun-solaris := -g -D_POSIX_PTHREAD_SEMANTICS -fPIC -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-sun-solaris := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-sun-solaris := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_x86_64-sun-solaris :=
CFG_LIB_GLOB_x86_64-unknown-bitrig=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-bitrig=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-bitrig := -m64 -I/usr/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -Wall -Werror -fPIE -fPIC -m64 -I/usr/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -fPIE -fPIC -m64 -I/usr/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-bitrig := -shared -pic -pthread -m64 $(LDFLAGS)
CFG_GCCISH_DEF_FLAG_x86_64-unknown-bitrig := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_x86_64-unknown-bitrig :=
CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-dragonfly := -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -g -fPIC -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread -lrt -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_x86_64-unknown-dragonfly :=
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
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 := -g -fPIC -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
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_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 := -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_STATIC_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-linux-musl=lib$(1)-*.so
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64
-CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl := -Wall -Werror -g -fPIC -m64
+CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl := -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-musl :=
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-musl :=
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-musl :=
CFG_LIB_GLOB_x86_64-unknown-netbsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-netbsd=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-netbsd := -I/usr/local/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-unknown-netbsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-netbsd := -g -fPIC -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-netbsd := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-netbsd := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_x86_64-unknown-netbsd :=
CFG_LIB_GLOB_x86_64-unknown-openbsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-openbsd=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-openbsd := -m64 -I/usr/include $(CFLAGS)
-CFG_GCCISH_CFLAGS_x86_64-unknown-openbsd := -Wall -Werror -g -fPIC -m64 -I/usr/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-openbsd := -g -fPIC -m64 -I/usr/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-openbsd := -shared -fPIC -g -pthread -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-openbsd := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_x86_64-unknown-openbsd :=
# compiler-rt
################################################################################
-ifdef CFG_ENABLE_FAST_MAKE
-COMPRT_DEPS := $(S)/.gitmodules
-else
-COMPRT_DEPS := $(wildcard \
- $(S)src/compiler-rt/* \
- $(S)src/compiler-rt/*/* \
- $(S)src/compiler-rt/*/*/* \
- $(S)src/compiler-rt/*/*/*/*)
-endif
-
-# compiler-rt's build system is a godawful mess. Here we figure out
-# the ridiculous platform-specific values and paths necessary to get
-# useful artifacts out of it.
+# Everything below is a manual compilation of compiler-rt, disregarding its
+# build system. See comments in `src/bootstrap/native.rs` for more information.
COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
-COMPRT_ARCH_$(1) := $$(word 1,$$(subst -, ,$(1)))
+# GENERIC_SOURCES in CMakeLists.txt
+COMPRT_OBJS_$(1) := \
+ absvdi2.o \
+ absvsi2.o \
+ adddf3.o \
+ addsf3.o \
+ addvdi3.o \
+ addvsi3.o \
+ apple_versioning.o \
+ ashldi3.o \
+ ashrdi3.o \
+ clear_cache.o \
+ clzdi2.o \
+ clzsi2.o \
+ cmpdi2.o \
+ comparedf2.o \
+ comparesf2.o \
+ ctzdi2.o \
+ ctzsi2.o \
+ divdc3.o \
+ divdf3.o \
+ divdi3.o \
+ divmoddi4.o \
+ divmodsi4.o \
+ divsc3.o \
+ divsf3.o \
+ divsi3.o \
+ divxc3.o \
+ extendsfdf2.o \
+ extendhfsf2.o \
+ ffsdi2.o \
+ fixdfdi.o \
+ fixdfsi.o \
+ fixsfdi.o \
+ fixsfsi.o \
+ fixunsdfdi.o \
+ fixunsdfsi.o \
+ fixunssfdi.o \
+ fixunssfsi.o \
+ fixunsxfdi.o \
+ fixunsxfsi.o \
+ fixxfdi.o \
+ floatdidf.o \
+ floatdisf.o \
+ floatdixf.o \
+ floatsidf.o \
+ floatsisf.o \
+ floatundidf.o \
+ floatundisf.o \
+ floatundixf.o \
+ floatunsidf.o \
+ floatunsisf.o \
+ int_util.o \
+ lshrdi3.o \
+ moddi3.o \
+ modsi3.o \
+ muldc3.o \
+ muldf3.o \
+ muldi3.o \
+ mulodi4.o \
+ mulosi4.o \
+ muloti4.o \
+ mulsc3.o \
+ mulsf3.o \
+ mulvdi3.o \
+ mulvsi3.o \
+ mulxc3.o \
+ negdf2.o \
+ negdi2.o \
+ negsf2.o \
+ negvdi2.o \
+ negvsi2.o \
+ paritydi2.o \
+ paritysi2.o \
+ popcountdi2.o \
+ popcountsi2.o \
+ powidf2.o \
+ powisf2.o \
+ powixf2.o \
+ subdf3.o \
+ subsf3.o \
+ subvdi3.o \
+ subvsi3.o \
+ truncdfhf2.o \
+ truncdfsf2.o \
+ truncsfhf2.o \
+ ucmpdi2.o \
+ udivdi3.o \
+ udivmoddi4.o \
+ udivmodsi4.o \
+ udivsi3.o \
+ umoddi3.o \
+ umodsi3.o
-# All this is to figure out the path to the compiler-rt bin
-ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
-COMPRT_DIR_$(1) := windows/Release
-COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(patsubst i%86,i386,$$(COMPRT_ARCH_$(1)))
+ifeq ($$(findstring ios,$(1)),)
+COMPRT_OBJS_$(1) += \
+ absvti2.o \
+ addtf3.o \
+ addvti3.o \
+ ashlti3.o \
+ ashrti3.o \
+ clzti2.o \
+ cmpti2.o \
+ ctzti2.o \
+ divtf3.o \
+ divti3.o \
+ ffsti2.o \
+ fixdfti.o \
+ fixsfti.o \
+ fixunsdfti.o \
+ fixunssfti.o \
+ fixunsxfti.o \
+ fixxfti.o \
+ floattidf.o \
+ floattisf.o \
+ floattixf.o \
+ floatuntidf.o \
+ floatuntisf.o \
+ floatuntixf.o \
+ lshrti3.o \
+ modti3.o \
+ multf3.o \
+ multi3.o \
+ mulvti3.o \
+ negti2.o \
+ negvti2.o \
+ parityti2.o \
+ popcountti2.o \
+ powitf2.o \
+ subtf3.o \
+ subvti3.o \
+ trampoline_setup.o \
+ ucmpti2.o \
+ udivmodti4.o \
+ udivti3.o \
+ umodti3.o
endif
-ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
-COMPRT_DIR_$(1) := windows
-COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
+ifeq ($$(findstring apple,$(1)),apple)
+COMPRT_OBJS_$(1) += \
+ atomic_flag_clear.o \
+ atomic_flag_clear_explicit.o \
+ atomic_flag_test_and_set.o \
+ atomic_flag_test_and_set_explicit.o \
+ atomic_signal_fence.o \
+ atomic_thread_fence.o
endif
-ifeq ($$(findstring darwin,$(1)),darwin)
-COMPRT_DIR_$(1) := builtins
-COMPRT_LIB_NAME_$(1) := clang_rt.builtins_$$(patsubst i686,i386,$$(COMPRT_ARCH_$(1)))_osx
+
+ifeq ($$(findstring windows,$(1)),)
+COMPRT_OBJS_$(1) += emutls.o
endif
-ifeq ($$(findstring ios,$(1)),ios)
-COMPRT_DIR_$(1) := builtins
-COMPRT_ARCH_$(1) := $$(patsubst armv7s,armv7em,$$(COMPRT_ARCH_$(1)))
-COMPRT_LIB_NAME_$(1) := clang_rt.hard_pic_$$(COMPRT_ARCH_$(1))_macho_embedded
-ifeq ($$(COMPRT_ARCH_$(1)),aarch64)
-COMPRT_LIB_NAME_$(1) := clang_rt.builtins_arm64_ios
+ifeq ($$(findstring msvc,$(1)),)
+COMPRT_OBJS_$(1) += gcc_personality_v0.o
+COMPRT_OBJS_$(1) += emutls.o
+
+ifeq ($$(findstring x86_64,$(1)),x86_64)
+COMPRT_OBJS_$(1) += \
+ x86_64/chkstk.o \
+ x86_64/chkstk2.o \
+ x86_64/floatdidf.o \
+ x86_64/floatdisf.o \
+ x86_64/floatdixf.o \
+ x86_64/floatundidf.o \
+ x86_64/floatundisf.o \
+ x86_64/floatundixf.o
endif
-COMPRT_DEFINES_$(1) := -DCOMPILER_RT_ENABLE_IOS=ON
+
+ifeq ($$(findstring i686,$$(patsubts i%86,i686,$(1))),i686)
+COMPRT_OBJS_$(1) += \
+ i386/ashldi3.o \
+ i386/ashrdi3.o \
+ i386/chkstk.o \
+ i386/chkstk2.o \
+ i386/divdi3.o \
+ i386/floatdidf.o \
+ i386/floatdisf.o \
+ i386/floatdixf.o \
+ i386/floatundidf.o \
+ i386/floatundisf.o \
+ i386/floatundixf.o \
+ i386/lshrdi3.o \
+ i386/moddi3.o \
+ i386/muldi3.o \
+ i386/udivdi3.o \
+ i386/umoddi3.o
endif
-ifndef COMPRT_DIR_$(1)
-# NB: FreeBSD and NetBSD output to "linux"...
-COMPRT_DIR_$(1) := linux
-COMPRT_ARCH_$(1) := $$(patsubst i586,i386,$$(COMPRT_ARCH_$(1)))
+else
-ifeq ($$(findstring android,$(1)),android)
-ifeq ($$(findstring arm,$$(COMPRT_ARCH_$(1))),arm)
-COMPRT_ARCH_$(1) := armhf
-endif
+ifeq ($$(findstring x86_64,$(1)),x86_64)
+COMPRT_OBJS_$(1) += \
+ x86_64/floatdidf.o \
+ x86_64/floatdisf.o \
+ x86_64/floatdixf.o
endif
-ifeq ($$(findstring eabihf,$(1)),eabihf)
-ifeq ($$(findstring armv7,$(1)),)
-COMPRT_LIB_NAME_$(1) := clang_rt.builtins-armhf
-endif
endif
-ifndef COMPRT_LIB_NAME_$(1)
-COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
+# Generic ARM sources, nothing compiles on iOS though
+ifeq ($$(findstring arm,$(1)),arm)
+ifeq ($$(findstring ios,$(1)),)
+COMPRT_OBJS_$(1) += \
+ arm/aeabi_cdcmp.o \
+ arm/aeabi_cdcmpeq_check_nan.o \
+ arm/aeabi_cfcmp.o \
+ arm/aeabi_cfcmpeq_check_nan.o \
+ arm/aeabi_dcmp.o \
+ arm/aeabi_div0.o \
+ arm/aeabi_drsub.o \
+ arm/aeabi_fcmp.o \
+ arm/aeabi_frsub.o \
+ arm/aeabi_idivmod.o \
+ arm/aeabi_ldivmod.o \
+ arm/aeabi_memcmp.o \
+ arm/aeabi_memcpy.o \
+ arm/aeabi_memmove.o \
+ arm/aeabi_memset.o \
+ arm/aeabi_uidivmod.o \
+ arm/aeabi_uldivmod.o \
+ arm/bswapdi2.o \
+ arm/bswapsi2.o \
+ arm/clzdi2.o \
+ arm/clzsi2.o \
+ arm/comparesf2.o \
+ arm/divmodsi4.o \
+ arm/divsi3.o \
+ arm/modsi3.o \
+ arm/switch16.o \
+ arm/switch32.o \
+ arm/switch8.o \
+ arm/switchu8.o \
+ arm/sync_synchronize.o \
+ arm/udivmodsi4.o \
+ arm/udivsi3.o \
+ arm/umodsi3.o
endif
endif
-
-ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
-COMPRT_LIB_FILE_$(1) := lib$$(COMPRT_LIB_NAME_$(1)).a
+# Thumb sources
+ifeq ($$(findstring armv7,$(1)),armv7)
+COMPRT_OBJS_$(1) += \
+ arm/sync_fetch_and_add_4.o \
+ arm/sync_fetch_and_add_8.o \
+ arm/sync_fetch_and_and_4.o \
+ arm/sync_fetch_and_and_8.o \
+ arm/sync_fetch_and_max_4.o \
+ arm/sync_fetch_and_max_8.o \
+ arm/sync_fetch_and_min_4.o \
+ arm/sync_fetch_and_min_8.o \
+ arm/sync_fetch_and_nand_4.o \
+ arm/sync_fetch_and_nand_8.o \
+ arm/sync_fetch_and_or_4.o \
+ arm/sync_fetch_and_or_8.o \
+ arm/sync_fetch_and_sub_4.o \
+ arm/sync_fetch_and_sub_8.o \
+ arm/sync_fetch_and_umax_4.o \
+ arm/sync_fetch_and_umax_8.o \
+ arm/sync_fetch_and_umin_4.o \
+ arm/sync_fetch_and_umin_8.o \
+ arm/sync_fetch_and_xor_4.o \
+ arm/sync_fetch_and_xor_8.o
endif
-ifeq ($$(findstring android,$(1)),android)
-ifeq ($$(findstring arm,$(1)),arm)
-COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1))-android)
-endif
+# VFP sources
+ifeq ($$(findstring eabihf,$(1)),eabihf)
+COMPRT_OBJS_$(1) += \
+ arm/adddf3vfp.o \
+ arm/addsf3vfp.o \
+ arm/divdf3vfp.o \
+ arm/divsf3vfp.o \
+ arm/eqdf2vfp.o \
+ arm/eqsf2vfp.o \
+ arm/extendsfdf2vfp.o \
+ arm/fixdfsivfp.o \
+ arm/fixsfsivfp.o \
+ arm/fixunsdfsivfp.o \
+ arm/fixunssfsivfp.o \
+ arm/floatsidfvfp.o \
+ arm/floatsisfvfp.o \
+ arm/floatunssidfvfp.o \
+ arm/floatunssisfvfp.o \
+ arm/gedf2vfp.o \
+ arm/gesf2vfp.o \
+ arm/gtdf2vfp.o \
+ arm/gtsf2vfp.o \
+ arm/ledf2vfp.o \
+ arm/lesf2vfp.o \
+ arm/ltdf2vfp.o \
+ arm/ltsf2vfp.o \
+ arm/muldf3vfp.o \
+ arm/mulsf3vfp.o \
+ arm/negdf2vfp.o \
+ arm/negsf2vfp.o \
+ arm/nedf2vfp.o \
+ arm/nesf2vfp.o \
+ arm/restore_vfp_d8_d15_regs.o \
+ arm/save_vfp_d8_d15_regs.o \
+ arm/subdf3vfp.o \
+ arm/subsf3vfp.o \
+ arm/truncdfsf2vfp.o \
+ arm/unorddf2vfp.o \
+ arm/unordsf2vfp.o
endif
-ifndef COMPRT_LIB_FILE_$(1)
-COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1)))
+ifeq ($$(findstring aarch64,$(1)),aarch64)
+COMPRT_OBJS_$(1) += \
+ comparetf2.o \
+ extenddftf2.o \
+ extendsftf2.o \
+ fixtfdi.o \
+ fixtfsi.o \
+ fixtfti.o \
+ fixunstfdi.o \
+ fixunstfsi.o \
+ fixunstfti.o \
+ floatditf.o \
+ floatsitf.o \
+ floatunditf.o \
+ floatunsitf.o \
+ multc3.o \
+ trunctfdf2.o \
+ trunctfsf2.o
endif
-COMPRT_OUTPUT_$(1) := $$(COMPRT_BUILD_DIR_$(1))/lib/$$(COMPRT_DIR_$(1))/$$(COMPRT_LIB_FILE_$(1))
-
-ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
-COMPRT_BUILD_ARGS_$(1) := //v:m //nologo
-COMPRT_BUILD_TARGET_$(1) := lib/builtins/builtins
-COMPRT_BUILD_CC_$(1) :=
+ifeq ($$(findstring msvc,$(1)),msvc)
+$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -Zl -D__func__=__FUNCTION__
else
-COMPRT_BUILD_ARGS_$(1) :=
-ifndef COMPRT_BUILD_TARGET_$(1)
-COMPRT_BUILD_TARGET_$(1) := $$(COMPRT_LIB_NAME_$(1))
+$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -fno-builtin -fvisibility=hidden \
+ -fomit-frame-pointer -ffreestanding
endif
-COMPRT_BUILD_CC_$(1) := -DCMAKE_C_COMPILER=$$(call FIND_COMPILER,$$(CC_$(1))) \
- -DCMAKE_CXX_COMPILER=$$(call FIND_COMPILER,$$(CXX_$(1)))
-ifeq ($$(findstring ios,$(1)),)
-COMPRT_BUILD_CC_$(1) := $$(COMPRT_BUILD_CC_$(1)) \
- -DCMAKE_C_FLAGS="$$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error"
-endif
+COMPRT_OBJS_$(1) := $$(COMPRT_OBJS_$(1):%=$$(COMPRT_BUILD_DIR_$(1))/%)
+
+$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.c
+ @mkdir -p $$(@D)
+ @$$(call E, compile: $$@)
+ $$(Q)$$(call CFG_COMPILE_C_$(1),$$@,$$<)
+
+$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.S \
+ $$(LLVM_CONFIG_$$(CFG_BUILD))
+ @mkdir -p $$(@D)
+ @$$(call E, compile: $$@)
+ $$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
+ifeq ($$(findstring msvc,$(1)),msvc)
+$$(COMPRT_BUILD_DIR_$(1))/%.o: \
+ export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(1)))
endif
ifeq ($$(findstring emscripten,$(1)),emscripten)
-
# FIXME: emscripten doesn't use compiler-rt and can't build it without
# further hacks
-$$(COMPRT_LIB_$(1)):
- touch $$@
-
-else
-
-$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
- @$$(call E, cmake: compiler-rt)
- $$(Q)rm -rf $$(COMPRT_BUILD_DIR_$(1))
- $$(Q)mkdir $$(COMPRT_BUILD_DIR_$(1))
- $$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; \
- $$(CFG_CMAKE) "$(S)src/compiler-rt" \
- -DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \
- -DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \
- -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$(1) \
- -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
- -DCOMPILER_RT_BUILD_EMUTLS=OFF \
- $$(COMPRT_DEFINES_$(1)) \
- $$(COMPRT_BUILD_CC_$(1)) \
- -G"$$(CFG_CMAKE_GENERATOR)"
-ifneq ($$(CFG_NINJA),)
- $$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
- --target $$(COMPRT_BUILD_TARGET_$(1)) \
- --config $$(LLVM_BUILD_CONFIG_MODE) \
- -- $$(COMPRT_BUILD_ARGS_$(1))
-else
- $$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
- --target $$(COMPRT_BUILD_TARGET_$(1)) \
- --config $$(LLVM_BUILD_CONFIG_MODE) \
- -- $$(COMPRT_BUILD_ARGS_$(1)) $$(MFLAGS)
+COMPRT_OBJS_$(1) :=
endif
- $$(Q)cp "$$(COMPRT_OUTPUT_$(1))" $$@
-endif
+$$(COMPRT_LIB_$(1)): $$(COMPRT_OBJS_$(1))
+ @$$(call E, link: $$@)
+ $$(Q)$$(call CFG_CREATE_ARCHIVE_$(1),$$@) $$^
################################################################################
# libbacktrace
"build_helper 0.1.0",
"cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
[[package]]
name = "gcc"
-version = "0.3.26"
+version = "0.3.31"
+source = "git+https://github.com/alexcrichton/gcc-rs#b8e2400883f1a2749b323354dad372cdd1c838c7"
+
+[[package]]
+name = "gcc"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
rustc-serialize = "0.3"
winapi = "0.2"
kernel32-sys = "0.2"
-gcc = "0.3.17"
+gcc = { git = "https://github.com/alexcrichton/gcc-rs" }
libc = "0.2"
md5 = "0.1"
/// Compiles the `compiler-rt` library, or at least the builtins part of it.
///
-/// This uses the CMake build system and an existing LLVM build directory to
-/// compile the project.
+/// Note that while compiler-rt has a build system associated with it, we
+/// specifically don't use it here. The compiler-rt build system, written in
+/// CMake, is actually *very* difficult to work with in terms of getting it to
+/// compile on all the relevant platforms we want it to compile on. In the end
+/// it became so much pain to work with local patches, work around the oddities
+/// of the build system, etc, that we're just building everything by hand now.
+///
+/// In general compiler-rt is just a bunch of intrinsics that are in practice
+/// *very* stable. We just need to make sure that all the relevant functions and
+/// such are compiled somewhere and placed in an object file somewhere.
+/// Eventually, these should all be written in Rust!
+///
+/// So below you'll find a listing of every single file in the compiler-rt repo
+/// that we're compiling. We just reach in and compile with the `gcc` crate
+/// which should have all the relevant flags and such already configured.
+///
+/// The risk here is that if we update compiler-rt we may need to compile some
+/// new intrinsics, but to be honest we surely don't use all of the intrinsics
+/// listed below today so the likelihood of us actually needing a new intrinsic
+/// is quite low. The failure case is also just that someone reports a link
+/// error (if any) and then we just add it to the list. Overall, that cost is
+/// far far less than working with compiler-rt's build system over time.
pub fn compiler_rt(build: &Build, target: &str) {
- let dst = build.compiler_rt_out(target);
- let arch = target.split('-').next().unwrap();
- let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
+ let build_dir = build.compiler_rt_out(target);
+ let output = build_dir.join(staticlib("compiler-rt", target));
+ build.compiler_rt_built.borrow_mut().insert(target.to_string(),
+ output.clone());
+ t!(fs::create_dir_all(&build_dir));
- let build_llvm_config = build.llvm_config(&build.config.build);
- let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
- cfg.target(target)
+ let mut cfg = gcc::Config::new();
+ cfg.cargo_metadata(false)
+ .out_dir(&build_dir)
+ .target(target)
.host(&build.config.build)
- .out_dir(&dst)
- .profile(mode)
- .define("LLVM_CONFIG_PATH", build_llvm_config)
- .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
- .define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
- .define("COMPILER_RT_BUILD_EMUTLS", "OFF")
- // inform about c/c++ compilers, the c++ compiler isn't actually used but
- // it's needed to get the initial configure to work on all platforms.
- .define("CMAKE_C_COMPILER", build.cc(target))
- .define("CMAKE_CXX_COMPILER", build.cc(target));
-
- let (dir, build_target, libname) = if target.contains("linux") ||
- target.contains("freebsd") ||
- target.contains("netbsd") {
- let os_extra = if target.contains("android") && target.contains("arm") {
- "-android"
- } else {
- ""
- };
- let builtins_arch = match arch {
- "i586" => "i386",
- "arm" | "armv7" if target.contains("android") => "armhf",
- "arm" if target.contains("eabihf") => "armhf",
- _ => arch,
- };
- let target = format!("clang_rt.builtins-{}", builtins_arch);
- ("linux".to_string(),
- target.clone(),
- format!("{}{}", target, os_extra))
- } else if target.contains("apple-darwin") {
- let builtins_arch = match arch {
- "i686" => "i386",
- _ => arch,
- };
- let target = format!("clang_rt.builtins_{}_osx", builtins_arch);
- ("builtins".to_string(), target.clone(), target)
- } else if target.contains("apple-ios") {
- cfg.define("COMPILER_RT_ENABLE_IOS", "ON");
- let target = match arch {
- "armv7s" => "hard_pic_armv7em_macho_embedded".to_string(),
- "aarch64" => "builtins_arm64_ios".to_string(),
- _ => format!("hard_pic_{}_macho_embedded", arch),
- };
- ("builtins".to_string(), target.clone(), target)
- } else if target.contains("windows-gnu") {
- let target = format!("clang_rt.builtins-{}", arch);
- ("windows".to_string(), target.clone(), target)
- } else if target.contains("windows-msvc") {
- let builtins_arch = match arch {
- "i586" | "i686" => "i386",
- _ => arch,
- };
- (format!("windows/{}", mode),
- "lib/builtins/builtins".to_string(),
- format!("clang_rt.builtins-{}", builtins_arch))
+ .opt_level(2)
+ .debug(false);
+
+ if target.contains("msvc") {
+ // Don't pull in extra libraries on MSVC
+ cfg.flag("/Zl");
+
+ // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
+ cfg.define("__func__", Some("__FUNCTION__"));
} else {
- panic!("can't get os from target: {}", target)
- };
- let output = dst.join("build/lib").join(dir)
- .join(staticlib(&libname, target));
- build.compiler_rt_built.borrow_mut().insert(target.to_string(),
- output.clone());
- if fs::metadata(&output).is_ok() {
+ // Turn off various features of gcc and such, mostly copying
+ // compiler-rt's build system already
+ cfg.flag("-fno-builtin");
+ cfg.flag("-fvisibility=hidden");
+ cfg.flag("-fomit-frame-pointer");
+ cfg.flag("-ffreestanding");
+ }
+
+ let mut sources = vec![
+ "absvdi2.c",
+ "absvsi2.c",
+ "adddf3.c",
+ "addsf3.c",
+ "addvdi3.c",
+ "addvsi3.c",
+ "apple_versioning.c",
+ "ashldi3.c",
+ "ashrdi3.c",
+ "clear_cache.c",
+ "clzdi2.c",
+ "clzsi2.c",
+ "cmpdi2.c",
+ "comparedf2.c",
+ "comparesf2.c",
+ "ctzdi2.c",
+ "ctzsi2.c",
+ "divdc3.c",
+ "divdf3.c",
+ "divdi3.c",
+ "divmoddi4.c",
+ "divmodsi4.c",
+ "divsc3.c",
+ "divsf3.c",
+ "divsi3.c",
+ "divxc3.c",
+ "extendsfdf2.c",
+ "extendhfsf2.c",
+ "ffsdi2.c",
+ "fixdfdi.c",
+ "fixdfsi.c",
+ "fixsfdi.c",
+ "fixsfsi.c",
+ "fixunsdfdi.c",
+ "fixunsdfsi.c",
+ "fixunssfdi.c",
+ "fixunssfsi.c",
+ "fixunsxfdi.c",
+ "fixunsxfsi.c",
+ "fixxfdi.c",
+ "floatdidf.c",
+ "floatdisf.c",
+ "floatdixf.c",
+ "floatsidf.c",
+ "floatsisf.c",
+ "floatundidf.c",
+ "floatundisf.c",
+ "floatundixf.c",
+ "floatunsidf.c",
+ "floatunsisf.c",
+ "int_util.c",
+ "lshrdi3.c",
+ "moddi3.c",
+ "modsi3.c",
+ "muldc3.c",
+ "muldf3.c",
+ "muldi3.c",
+ "mulodi4.c",
+ "mulosi4.c",
+ "muloti4.c",
+ "mulsc3.c",
+ "mulsf3.c",
+ "mulvdi3.c",
+ "mulvsi3.c",
+ "mulxc3.c",
+ "negdf2.c",
+ "negdi2.c",
+ "negsf2.c",
+ "negvdi2.c",
+ "negvsi2.c",
+ "paritydi2.c",
+ "paritysi2.c",
+ "popcountdi2.c",
+ "popcountsi2.c",
+ "powidf2.c",
+ "powisf2.c",
+ "powixf2.c",
+ "subdf3.c",
+ "subsf3.c",
+ "subvdi3.c",
+ "subvsi3.c",
+ "truncdfhf2.c",
+ "truncdfsf2.c",
+ "truncsfhf2.c",
+ "ucmpdi2.c",
+ "udivdi3.c",
+ "udivmoddi4.c",
+ "udivmodsi4.c",
+ "udivsi3.c",
+ "umoddi3.c",
+ "umodsi3.c",
+ ];
+
+ if !target.contains("ios") {
+ sources.extend(vec![
+ "absvti2.c",
+ "addtf3.c",
+ "addvti3.c",
+ "ashlti3.c",
+ "ashrti3.c",
+ "clzti2.c",
+ "cmpti2.c",
+ "ctzti2.c",
+ "divtf3.c",
+ "divti3.c",
+ "ffsti2.c",
+ "fixdfti.c",
+ "fixsfti.c",
+ "fixunsdfti.c",
+ "fixunssfti.c",
+ "fixunsxfti.c",
+ "fixxfti.c",
+ "floattidf.c",
+ "floattisf.c",
+ "floattixf.c",
+ "floatuntidf.c",
+ "floatuntisf.c",
+ "floatuntixf.c",
+ "lshrti3.c",
+ "modti3.c",
+ "multf3.c",
+ "multi3.c",
+ "mulvti3.c",
+ "negti2.c",
+ "negvti2.c",
+ "parityti2.c",
+ "popcountti2.c",
+ "powitf2.c",
+ "subtf3.c",
+ "subvti3.c",
+ "trampoline_setup.c",
+ "ucmpti2.c",
+ "udivmodti4.c",
+ "udivti3.c",
+ "umodti3.c",
+ ]);
+ }
+
+ if target.contains("apple") {
+ sources.extend(vec![
+ "atomic_flag_clear.c",
+ "atomic_flag_clear_explicit.c",
+ "atomic_flag_test_and_set.c",
+ "atomic_flag_test_and_set_explicit.c",
+ "atomic_signal_fence.c",
+ "atomic_thread_fence.c",
+ ]);
+ }
+
+ if !target.contains("windows") {
+ sources.push("emutls.c");
+ }
+
+ if target.contains("msvc") {
+ if target.contains("x86_64") {
+ sources.extend(vec![
+ "x86_64/floatdidf.c",
+ "x86_64/floatdisf.c",
+ "x86_64/floatdixf.c",
+ ]);
+ }
+ } else {
+ sources.push("gcc_personality_v0.c");
+
+ if target.contains("x86_64") {
+ sources.extend(vec![
+ "x86_64/chkstk.S",
+ "x86_64/chkstk2.S",
+ "x86_64/floatdidf.c",
+ "x86_64/floatdisf.c",
+ "x86_64/floatdixf.c",
+ "x86_64/floatundidf.S",
+ "x86_64/floatundisf.S",
+ "x86_64/floatundixf.S",
+ ]);
+ }
+
+ if target.contains("i386") ||
+ target.contains("i586") ||
+ target.contains("i686") {
+ sources.extend(vec![
+ "i386/ashldi3.S",
+ "i386/ashrdi3.S",
+ "i386/chkstk.S",
+ "i386/chkstk2.S",
+ "i386/divdi3.S",
+ "i386/floatdidf.S",
+ "i386/floatdisf.S",
+ "i386/floatdixf.S",
+ "i386/floatundidf.S",
+ "i386/floatundisf.S",
+ "i386/floatundixf.S",
+ "i386/lshrdi3.S",
+ "i386/moddi3.S",
+ "i386/muldi3.S",
+ "i386/udivdi3.S",
+ "i386/umoddi3.S",
+ ]);
+ }
+ }
+
+ if target.contains("arm") && !target.contains("ios") {
+ sources.extend(vec![
+ "arm/aeabi_cdcmp.S",
+ "arm/aeabi_cdcmpeq_check_nan.c",
+ "arm/aeabi_cfcmp.S",
+ "arm/aeabi_cfcmpeq_check_nan.c",
+ "arm/aeabi_dcmp.S",
+ "arm/aeabi_div0.c",
+ "arm/aeabi_drsub.c",
+ "arm/aeabi_fcmp.S",
+ "arm/aeabi_frsub.c",
+ "arm/aeabi_idivmod.S",
+ "arm/aeabi_ldivmod.S",
+ "arm/aeabi_memcmp.S",
+ "arm/aeabi_memcpy.S",
+ "arm/aeabi_memmove.S",
+ "arm/aeabi_memset.S",
+ "arm/aeabi_uidivmod.S",
+ "arm/aeabi_uldivmod.S",
+ "arm/bswapdi2.S",
+ "arm/bswapsi2.S",
+ "arm/clzdi2.S",
+ "arm/clzsi2.S",
+ "arm/comparesf2.S",
+ "arm/divmodsi4.S",
+ "arm/divsi3.S",
+ "arm/modsi3.S",
+ "arm/switch16.S",
+ "arm/switch32.S",
+ "arm/switch8.S",
+ "arm/switchu8.S",
+ "arm/sync_synchronize.S",
+ "arm/udivmodsi4.S",
+ "arm/udivsi3.S",
+ "arm/umodsi3.S",
+ ]);
+ }
+
+ if target.contains("armv7") {
+ sources.extend(vec![
+ "arm/sync_fetch_and_add_4.S",
+ "arm/sync_fetch_and_add_8.S",
+ "arm/sync_fetch_and_and_4.S",
+ "arm/sync_fetch_and_and_8.S",
+ "arm/sync_fetch_and_max_4.S",
+ "arm/sync_fetch_and_max_8.S",
+ "arm/sync_fetch_and_min_4.S",
+ "arm/sync_fetch_and_min_8.S",
+ "arm/sync_fetch_and_nand_4.S",
+ "arm/sync_fetch_and_nand_8.S",
+ "arm/sync_fetch_and_or_4.S",
+ "arm/sync_fetch_and_or_8.S",
+ "arm/sync_fetch_and_sub_4.S",
+ "arm/sync_fetch_and_sub_8.S",
+ "arm/sync_fetch_and_umax_4.S",
+ "arm/sync_fetch_and_umax_8.S",
+ "arm/sync_fetch_and_umin_4.S",
+ "arm/sync_fetch_and_umin_8.S",
+ "arm/sync_fetch_and_xor_4.S",
+ "arm/sync_fetch_and_xor_8.S",
+ ]);
+ }
+
+ if target.contains("eabihf") {
+ sources.extend(vec![
+ "arm/adddf3vfp.S",
+ "arm/addsf3vfp.S",
+ "arm/divdf3vfp.S",
+ "arm/divsf3vfp.S",
+ "arm/eqdf2vfp.S",
+ "arm/eqsf2vfp.S",
+ "arm/extendsfdf2vfp.S",
+ "arm/fixdfsivfp.S",
+ "arm/fixsfsivfp.S",
+ "arm/fixunsdfsivfp.S",
+ "arm/fixunssfsivfp.S",
+ "arm/floatsidfvfp.S",
+ "arm/floatsisfvfp.S",
+ "arm/floatunssidfvfp.S",
+ "arm/floatunssisfvfp.S",
+ "arm/gedf2vfp.S",
+ "arm/gesf2vfp.S",
+ "arm/gtdf2vfp.S",
+ "arm/gtsf2vfp.S",
+ "arm/ledf2vfp.S",
+ "arm/lesf2vfp.S",
+ "arm/ltdf2vfp.S",
+ "arm/ltsf2vfp.S",
+ "arm/muldf3vfp.S",
+ "arm/mulsf3vfp.S",
+ "arm/negdf2vfp.S",
+ "arm/negsf2vfp.S",
+ "arm/nedf2vfp.S",
+ "arm/nesf2vfp.S",
+ "arm/restore_vfp_d8_d15_regs.S",
+ "arm/save_vfp_d8_d15_regs.S",
+ "arm/subdf3vfp.S",
+ "arm/subsf3vfp.S",
+ "arm/truncdfsf2vfp.S",
+ "arm/unorddf2vfp.S",
+ "arm/unordsf2vfp.S",
+ ]);
+ }
+
+ if target.contains("aarch64") {
+ sources.extend(vec![
+ "comparetf2.c",
+ "extenddftf2.c",
+ "extendsftf2.c",
+ "fixtfdi.c",
+ "fixtfsi.c",
+ "fixtfti.c",
+ "fixunstfdi.c",
+ "fixunstfsi.c",
+ "fixunstfti.c",
+ "floatditf.c",
+ "floatsitf.c",
+ "floatunditf.c",
+ "floatunsitf.c",
+ "multc3.c",
+ "trunctfdf2.c",
+ "trunctfsf2.c",
+ ]);
+ }
+
+ let mut out_of_date = false;
+ for src in sources {
+ let src = build.src.join("src/compiler-rt/lib/builtins").join(src);
+ out_of_date = out_of_date || !up_to_date(&src, &output);
+ cfg.file(src);
+ }
+ if !out_of_date {
return
}
- let _ = fs::remove_dir_all(&dst);
- t!(fs::create_dir_all(&dst));
- cfg.build_target(&build_target);
- cfg.build();
+ cfg.compile("libcompiler-rt.a");
}
/// Compiles the `rust_test_helpers.c` library which we used in various
vec![self.libstd(compiler),
self.target(host).rustc(compiler.stage)]
}
- Source::CompilerRt { _dummy } => {
- vec![self.llvm(()).target(&build.config.build)]
- }
+ Source::CompilerRt { _dummy } => Vec::new(),
Source::Llvm { _dummy } => Vec::new(),
Source::TestHelpers { _dummy } => Vec::new(),
Source::DebuggerScripts { stage: _ } => Vec::new(),
/// Uses last-modified time checks to verify this.
pub fn up_to_date(src: &Path, dst: &Path) -> bool {
let threshold = mtime(dst);
- let meta = t!(fs::metadata(src));
+ let meta = match fs::metadata(src) {
+ Ok(meta) => meta,
+ Err(e) => panic!("source {:?} failed to get metadata: {}", src, e),
+ };
if meta.is_dir() {
dir_up_to_date(src, &threshold)
} else {
: "eax"
);
# } }
+# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+# fn main() {}
```
Whitespace also doesn't matter:
# fn main() { unsafe {
asm!("xor %eax, %eax" ::: "eax");
# } }
+# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+# fn main() {}
```
## Operands
// Put the value 0x200 in eax
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
# } }
+# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+# fn main() {}
```
Input and output registers need not be listed since that information
}
println!("eax is currently {}", result);
# }
+# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+# fn main() {}
```
## More Information
#### On ranges:
```rust
-for (i, j) in (5..10).enumerate() {
- println!("i = {} and j = {}", i, j);
+for (index, value) in (5..10).enumerate() {
+ println!("index = {} and value = {}", index, value);
}
```
Outputs:
```text
-i = 0 and j = 5
-i = 1 and j = 6
-i = 2 and j = 7
-i = 3 and j = 8
-i = 4 and j = 9
+index = 0 and value = 5
+index = 1 and value = 6
+index = 2 and value = 7
+index = 3 and value = 8
+index = 4 and value = 9
```
Don't forget to add the parentheses around the range.
OccupiedEntry<'a, K, V>),
}
+#[stable(feature= "debug_btree_map", since = "1.12.0")]
+impl<'a, K: 'a + Debug + Ord, V: 'a + Debug> Debug for Entry<'a, K, V> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Vacant(ref v) => f.debug_tuple("Entry")
+ .field(v)
+ .finish(),
+ Occupied(ref o) => f.debug_tuple("Entry")
+ .field(o)
+ .finish(),
+ }
+ }
+}
+
/// A vacant Entry.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K: 'a, V: 'a> {
_marker: PhantomData<&'a mut (K, V)>,
}
+#[stable(feature= "debug_btree_map", since = "1.12.0")]
+impl<'a, K: 'a + Debug + Ord, V: 'a> Debug for VacantEntry<'a, K, V> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("VacantEntry")
+ .field(self.key())
+ .finish()
+ }
+}
+
/// An occupied Entry.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
_marker: PhantomData<&'a mut (K, V)>,
}
+#[stable(feature= "debug_btree_map", since = "1.12.0")]
+impl<'a, K: 'a + Debug + Ord, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("OccupiedEntry")
+ .field("key", self.key())
+ .field("value", self.get())
+ .finish()
+ }
+}
+
// An iterator for merging two sorted sequences into one
struct MergeIter<K, V, I: Iterator<Item = (K, V)>> {
left: Peekable<I>,
impl<T> LinkedList<T> {
/// Creates an empty `LinkedList`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::LinkedList;
+ ///
+ /// let list: LinkedList<u32> = LinkedList::new();
+ /// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> Self {
}
/// Provides a forward iterator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::LinkedList;
+ ///
+ /// let mut list: LinkedList<u32> = LinkedList::new();
+ ///
+ /// list.push_back(0);
+ /// list.push_back(1);
+ /// list.push_back(2);
+ ///
+ /// let mut iter = list.iter();
+ /// assert_eq!(iter.next(), Some(&0));
+ /// assert_eq!(iter.next(), Some(&1));
+ /// assert_eq!(iter.next(), Some(&2));
+ /// assert_eq!(iter.next(), None);
+ /// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter(&self) -> Iter<T> {
}
/// Provides a forward iterator with mutable references.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::LinkedList;
+ ///
+ /// let mut list: LinkedList<u32> = LinkedList::new();
+ ///
+ /// list.push_back(0);
+ /// list.push_back(1);
+ /// list.push_back(2);
+ ///
+ /// for element in list.iter_mut() {
+ /// *element += 10;
+ /// }
+ ///
+ /// let mut iter = list.iter();
+ /// assert_eq!(iter.next(), Some(&10));
+ /// assert_eq!(iter.next(), Some(&11));
+ /// assert_eq!(iter.next(), Some(&12));
+ /// assert_eq!(iter.next(), None);
+ /// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter_mut(&mut self) -> IterMut<T> {
///
/// dl.push_back(3);
/// assert_eq!(dl.len(), 3);
- ///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// dl.clear();
/// assert_eq!(dl.len(), 0);
/// assert_eq!(dl.front(), None);
- ///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Returns `true` if the `LinkedList` contains an element equal to the
/// given value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(linked_list_contains)]
+ ///
+ /// use std::collections::LinkedList;
+ ///
+ /// let mut list: LinkedList<u32> = LinkedList::new();
+ ///
+ /// list.push_back(0);
+ /// list.push_back(1);
+ /// list.push_back(2);
+ ///
+ /// assert_eq!(list.contains(&0), true);
+ /// assert_eq!(list.contains(&10), false);
+ /// ```
#[unstable(feature = "linked_list_contains", reason = "recently added",
issue = "32630")]
pub fn contains(&self, x: &T) -> bool
///
/// dl.push_front(1);
/// assert_eq!(dl.front(), Some(&1));
- ///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Some(x) => *x = 5,
/// }
/// assert_eq!(dl.front(), Some(&5));
- ///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
///
/// dl.push_back(1);
/// assert_eq!(dl.back(), Some(&1));
- ///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Some(x) => *x = 5,
/// }
/// assert_eq!(dl.back(), Some(&5));
- ///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
///
/// dl.push_front(1);
/// assert_eq!(dl.front().unwrap(), &1);
- ///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push_front(&mut self, elt: T) {
/// assert_eq!(d.pop_front(), Some(3));
/// assert_eq!(d.pop_front(), Some(1));
/// assert_eq!(d.pop_front(), None);
- ///
/// ```
- ///
#[stable(feature = "rust1", since = "1.0.0")]
pub fn pop_front(&mut self) -> Option<T> {
self.pop_front_node().map(Node::into_element)
/// Violating these may cause problems like corrupting the allocator's
/// internal datastructures.
///
+ /// The ownership of `ptr` is effectively transferred to the
+ /// `String` which may then deallocate, reallocate or change the
+ /// contents of memory pointed to by the pointer at will. Ensure
+ /// that nothing else uses the pointer after calling this
+ /// function.
+ ///
/// # Examples
///
/// Basic usage:
///
/// * `ptr` needs to have been previously allocated via `String`/`Vec<T>`
/// (at least, it's highly likely to be incorrect if it wasn't).
- /// * `length` needs to be the length that less than or equal to `capacity`.
+ /// * `length` needs to be less than or equal to `capacity`.
/// * `capacity` needs to be the capacity that the pointer was allocated with.
///
/// Violating these may cause problems like corrupting the allocator's
/// internal datastructures.
///
+ /// The ownership of `ptr` is effectively transferred to the
+ /// `Vec<T>` which may then deallocate, reallocate or change the
+ /// contents of memory pointed to by the pointer at will. Ensure
+ /// that nothing else uses the pointer after calling this
+ /// function.
+ ///
/// # Examples
///
/// ```
}
}
- /// Shorten a vector to be `len` elements long, dropping excess elements.
+ /// Shortens the vector, keeping the first `len` elements and dropping
+ /// the rest.
///
/// If `len` is greater than the vector's current length, this has no
/// effect.
///
+ /// The [`drain`] method can emulate `truncate`, but causes the excess
+ /// elements to be returned instead of dropped.
+ ///
/// # Examples
///
+ /// Truncating a five element vector to two elements:
+ ///
/// ```
/// let mut vec = vec![1, 2, 3, 4, 5];
/// vec.truncate(2);
/// assert_eq!(vec, [1, 2]);
/// ```
+ ///
+ /// No truncation occurs when `len` is greater than the vector's current
+ /// length:
+ ///
+ /// ```
+ /// let mut vec = vec![1, 2, 3];
+ /// vec.truncate(8);
+ /// assert_eq!(vec, [1, 2, 3]);
+ /// ```
+ ///
+ /// Truncating when `len == 0` is equivalent to calling the [`clear`]
+ /// method.
+ ///
+ /// ```
+ /// let mut vec = vec![1, 2, 3];
+ /// vec.truncate(0);
+ /// assert_eq!(vec, []);
+ /// ```
+ ///
+ /// [`clear`]: #method.clear
+ /// [`drain`]: #method.drain
#[stable(feature = "rust1", since = "1.0.0")]
pub fn truncate(&mut self, len: usize) {
unsafe {
#[inline]
#[stable(feature = "vec_as_slice", since = "1.7.0")]
pub fn as_mut_slice(&mut self) -> &mut [T] {
- &mut self[..]
+ self
}
/// Sets the length of a vector.
impl<T> VecDeque<T> {
/// Creates an empty `VecDeque`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::VecDeque;
+ ///
+ /// let vector: VecDeque<u32> = VecDeque::new();
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> VecDeque<T> {
VecDeque::with_capacity(INITIAL_CAPACITY)
}
/// Creates an empty `VecDeque` with space for at least `n` elements.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::VecDeque;
+ ///
+ /// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn with_capacity(n: usize) -> VecDeque<T> {
// +1 since the ringbuffer always leaves one space empty
/// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::VecDeque;
+ ///
+ /// let mut vector: VecDeque<u32> = VecDeque::new();
+ ///
+ /// vector.push_back(0);
+ /// vector.push_back(1);
+ /// vector.push_back(2);
+ ///
+ /// assert_eq!(vector.as_slices(), (&[0u32, 1, 2] as &[u32], &[] as &[u32]));
+ ///
+ /// vector.push_front(10);
+ /// vector.push_front(9);
+ ///
+ /// assert_eq!(vector.as_slices(), (&[9u32, 10] as &[u32], &[0u32, 1, 2] as &[u32]));
+ /// ```
#[inline]
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn as_slices(&self) -> (&[T], &[T]) {
/// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::VecDeque;
+ ///
+ /// let mut vector: VecDeque<u32> = VecDeque::new();
+ ///
+ /// vector.push_back(0);
+ /// vector.push_back(1);
+ ///
+ /// vector.push_front(10);
+ /// vector.push_front(9);
+ ///
+ /// vector.as_mut_slices().0[0] = 42;
+ /// vector.as_mut_slices().1[0] = 24;
+ /// assert_eq!(vector.as_slices(), (&[42u32, 10] as &[u32], &[24u32, 1] as &[u32]));
+ /// ```
#[inline]
#[stable(feature = "deque_extras_15", since = "1.5.0")]
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
///
/// ```
/// use std::collections::VecDeque;
-
+ ///
/// let mut v: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
/// assert_eq!(vec![3].into_iter().collect::<VecDeque<_>>(), v.drain(2..).collect());
/// assert_eq!(vec![1, 2].into_iter().collect::<VecDeque<_>>(), v);
/// Returns `true` if the `VecDeque` contains an element equal to the
/// given value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(vec_deque_contains)]
+ ///
+ /// use std::collections::VecDeque;
+ ///
+ /// let mut vector: VecDeque<u32> = VecDeque::new();
+ ///
+ /// vector.push_back(0);
+ /// vector.push_back(1);
+ ///
+ /// assert_eq!(vector.contains(&1), true);
+ /// assert_eq!(vector.contains(&10), false);
+ /// ```
#[unstable(feature = "vec_deque_contains", reason = "recently added",
issue = "32630")]
pub fn contains(&self, x: &T) -> bool
/// Returns `None` if `index` is out of bounds.
///
/// # Examples
+ ///
/// ```
/// use std::collections::VecDeque;
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ExactSizeIterator: Iterator {
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
/// Returns the exact number of times the iterator will iterate.
///
/// This method has a default implementation, so you usually should not
///
/// assert_eq!(5, five.len());
/// ```
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
fn len(&self) -> usize {
let (lower, upper) = self.size_hint();
// Note: This assertion is overly defensive, but it checks the invariant
assert_eq!(upper, Some(lower));
lower
}
+
+ /// Returns whether the iterator is empty.
+ ///
+ /// This method has a default implementation using `self.len()`, so you
+ /// don't need to implement it yourself.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(exact_size_is_empty)]
+ ///
+ /// let mut one_element = 0..1;
+ /// assert!(!one_element.is_empty());
+ ///
+ /// assert_eq!(one_element.next(), Some(0));
+ /// assert!(one_element.is_empty());
+ ///
+ /// assert_eq!(one_element.next(), None);
+ /// ```
+ #[inline]
+ #[unstable(feature = "exact_size_is_empty", issue = "0")]
+ fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
use self::Option::*;
use clone::Clone;
+use convert::From;
use default::Default;
use iter::ExactSizeIterator;
use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator};
}
}
+#[stable(since = "1.12.0", feature = "option_from")]
+impl<T> From<T> for Option<T> {
+ fn from(val: T) -> Option<T> {
+ Some(val)
+ }
+}
+
/////////////////////////////////////////////////////////////////////////////
// The Option Iterators
/////////////////////////////////////////////////////////////////////////////
}
macro_rules! fnptr_impls_args {
- ($($Arg: ident),*) => {
+ ($($Arg: ident),+) => {
fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
+ fnptr_impls_safety_abi! { extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
- }
+ fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
+ };
+ () => {
+ // No variadic functions with 0 parameters
+ fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, }
+ fnptr_impls_safety_abi! { extern "C" fn() -> Ret, }
+ fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, }
+ fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, }
+ };
}
fnptr_impls_args! { }
/// Immutable slice iterator
///
+/// This struct is created by the [`iter`] method on [slices].
+///
/// # Examples
///
/// Basic usage:
/// println!("{}", element);
/// }
/// ```
+///
+/// [`iter`]: ../../std/primitive.slice.html#method.iter
+/// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> {
ptr: *const T,
/// Mutable slice iterator.
///
+/// This struct is created by the [`iter_mut`] method on [slices].
+///
/// # Examples
///
/// Basic usage:
/// // We now have "[2, 3, 4]":
/// println!("{:?}", slice);
/// ```
+///
+/// [`iter_mut`]: ../../std/primitive.slice.html#method.iter_mut
+/// [slices]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
ptr: *mut T,
let zs: &mut [i32] = &mut [1, 2, 3];
assert!(ys == zs);
}
+
+#[test]
+fn test_variadic_fnptr() {
+ use core::hash::{Hash, SipHasher};
+ extern "C" {
+ fn printf(_: *const u8, ...);
+ }
+ let p: unsafe extern "C" fn(*const u8, ...) = printf;
+ let q = p.clone();
+ assert_eq!(p, q);
+ assert!(!(p < q));
+ let mut s = SipHasher::new();
+ assert_eq!(p.hash(&mut s), q.hash(&mut s));
+}
"for every macro invocation, print its name and arguments"),
enable_nonzeroing_move_hints: bool = (false, parse_bool,
"force nonzeroing move optimization on"),
- keep_mtwt_tables: bool = (false, parse_bool,
- "don't clear the resolution tables after analysis"),
+ keep_hygiene_data: bool = (false, parse_bool,
+ "don't clear the hygiene data after analysis"),
keep_ast: bool = (false, parse_bool,
"keep the AST after lowering it to HIR"),
show_span: Option<String> = (None, parse_opt_string,
Ok(())
}
-fn keep_mtwt_tables(sess: &Session) -> bool {
- sess.opts.debugging_opts.keep_mtwt_tables
+fn keep_hygiene_data(sess: &Session) -> bool {
+ sess.opts.debugging_opts.keep_hygiene_data
}
fn keep_ast(sess: &Session) -> bool {
input: &Input)
-> PResult<'a, ast::Crate> {
// These may be left in an incoherent state after a previous compile.
- // `clear_tables` and `clear_ident_interner` can be used to free
- // memory, but they do not restore the initial state.
- syntax::ext::mtwt::reset_tables();
+ syntax::ext::hygiene::reset_hygiene_data();
+ // `clear_ident_interner` can be used to free memory, but it does not restore the initial state.
token::reset_ident_interner();
let continue_after_error = sess.opts.continue_parse_after_error;
sess.diagnostic().set_continue_after_error(continue_after_error);
hir_map::Forest::new(lower_crate(sess, &krate, &mut resolver), &sess.dep_graph)
});
- // Discard MTWT tables that aren't required past lowering to HIR.
- if !keep_mtwt_tables(sess) {
- syntax::ext::mtwt::clear_tables();
+ // Discard hygiene data, which isn't required past lowering to HIR.
+ if !keep_hygiene_data(sess) {
+ syntax::ext::hygiene::reset_hygiene_data();
}
Ok(ExpansionResult {
pp::space(&mut s.s)?;
// FIXME #16420: this doesn't display the connections
// between syntax contexts
- s.synth_comment(format!("{}#{}", nm, ctxt.0))
+ s.synth_comment(format!("{}{:?}", nm, ctxt))
}
pprust::NodeName(&ast::Name(nm)) => {
pp::space(&mut s.s)?;
}
}
- // As a special case, iterate over all static methods of
- // associated implementations too. This is a bit of a botch.
- // --pcwalton
- for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
- tag_items_data_item_inherent_impl) {
- let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata);
- if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.index) {
- for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
- tag_item_impl_item) {
- let impl_item_def_id = item_def_id(impl_item_def_id_doc,
- cdata);
- if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.index) {
- if let StaticMethod = item_family(impl_method_doc) {
- // Hand off the static method to the callback.
- let static_method_name = item_name(impl_method_doc);
- let static_method_def_like = item_to_def_like(cdata, impl_method_doc,
- impl_item_def_id);
- callback(static_method_def_like,
- static_method_name,
- item_visibility(impl_method_doc));
- }
- }
- }
- }
- }
-
for reexport_doc in reexports(item_doc) {
let def_id_doc = reader::get_doc(reexport_doc,
tag_items_data_item_reexport_def_id);
ALIGN,
comment(tcx, data.terminator().source_info))?;
- writeln!(w, "{}}}\n", INDENT)
+ writeln!(w, "{}}}", INDENT)
}
fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String {
use Resolver;
use rustc::session::Session;
use syntax::ast;
-use syntax::ext::mtwt;
+use syntax::ext::hygiene::Mark;
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::util::move_map::MoveMap;
struct NodeIdAssigner<'a> {
sess: &'a Session,
- macros_at_scope: &'a mut HashMap<ast::NodeId, Vec<ast::Mrk>>,
+ macros_at_scope: &'a mut HashMap<ast::NodeId, Vec<Mark>>,
}
impl<'a> Folder for NodeIdAssigner<'a> {
block.stmts = block.stmts.move_flat_map(|stmt| {
if let ast::StmtKind::Item(ref item) = stmt.node {
if let ast::ItemKind::Mac(..) = item.node {
- macros.push(mtwt::outer_mark(item.ident.ctxt));
+ macros.push(item.ident.ctxt.data().outer_mark);
return None;
}
}
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
-use syntax::ext::mtwt;
+use syntax::ext::hygiene::Mark;
use syntax::ast::{self, FloatTy};
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
use syntax::parse::token::{self, keywords};
ModuleRibKind(Module<'a>),
// We passed through a `macro_rules!` statement with the given expansion
- MacroDefinition(ast::Mrk),
+ MacroDefinition(Mark),
}
#[derive(Copy, Clone)]
// Maps the node id of a statement to the expansions of the `macro_rules!`s
// immediately above the statement (if appropriate).
- macros_at_scope: HashMap<NodeId, Vec<ast::Mrk>>,
+ macros_at_scope: HashMap<NodeId, Vec<Mark>>,
graph_root: Module<'a>,
if let MacroDefinition(mac) = self.get_ribs(ns)[i].kind {
// If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition.
- if let Some((source_ident, source_macro)) = mtwt::source(ident) {
- if mac == source_macro {
- ident = source_ident;
- }
+ let (source_ctxt, source_macro) = ident.ctxt.source();
+ if source_macro == mac {
+ ident.ctxt = source_ctxt;
}
}
}
MacroDefinition(mac) => {
// If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition.
- if let Some((source_ident, source_macro)) = mtwt::source(ident) {
- if mac == source_macro {
- ident = source_ident;
- }
+ let (source_ctxt, source_macro) = ident.ctxt.source();
+ if source_macro == mac {
+ ident.ctxt = source_ctxt;
}
}
_ => {
let is_decl = llvm::LLVMIsDeclaration(val) != 0;
if is_decl || is_available_externally {
- let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
- .to_bytes()
- .to_vec();
+ let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
declared.insert(name);
}
-
}
}
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
let linkage = llvm::LLVMGetLinkage(val);
- let is_external = linkage == llvm::ExternalLinkage as c_uint;
- let is_weak_odr = linkage == llvm::WeakODRLinkage as c_uint;
- let is_decl = llvm::LLVMIsDeclaration(val) != 0;
-
- // We only care about external definitions.
- if (is_external || is_weak_odr) && !is_decl {
+ let is_externally_visible = (linkage == llvm::ExternalLinkage as c_uint) ||
+ (linkage == llvm::LinkOnceODRLinkage as c_uint) ||
+ (linkage == llvm::WeakODRLinkage as c_uint);
+ let is_definition = llvm::LLVMIsDeclaration(val) != 0;
- let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
- .to_bytes()
- .to_vec();
+ // If this is a definition (as opposed to just a declaration)
+ // and externally visible, check if we can internalize it
+ if is_definition && is_externally_visible {
+ let name_cstr = CStr::from_ptr(llvm::LLVMGetValueName(val));
+ let name_str = name_cstr.to_str().unwrap();
- let is_declared = declared.contains(&name);
- let reachable = reachable.contains(str::from_utf8(&name).unwrap());
+ let is_referenced_somewhere = declared.contains(&name_cstr);
+ let is_reachable = reachable.contains(name_str);
- if !is_declared && !reachable {
+ if !is_referenced_somewhere && !is_reachable {
llvm::SetLinkage(val, llvm::InternalLinkage);
llvm::SetDLLStorageClass(val, llvm::DefaultStorageClass);
llvm::UnsetComdat(val);
// Run the translation item collector and partition the collected items into
// codegen units.
let (codegen_units, symbol_map) = collect_and_partition_translation_items(&shared_ccx);
- let codegen_unit_count = codegen_units.len();
let symbol_map = Rc::new(symbol_map);
}));
}
- if codegen_unit_count > 1 {
- internalize_symbols(&crate_context_list,
- &reachable_symbols.iter().map(|x| &x[..]).collect());
- }
+ internalize_symbols(&crate_context_list,
+ &reachable_symbols.iter().map(|x| &x[..]).collect());
if sess.target.target.options.is_like_msvc &&
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
/// that can fail for a good number of reasons. Some errors can include, but not
/// be limited to, filesystem operations failing or general syscall failures.
///
+/// # Security
+///
+/// The output of this function should not be used in anything that might have
+/// security implications. For example:
+///
+/// ```
+/// fn main() {
+/// println!("{:?}", std::env::current_exe());
+/// }
+/// ```
+///
+/// On Linux systems, if this is compiled as `foo`:
+///
+/// ```bash
+/// $ rustc foo.rs
+/// $ ./foo
+/// Ok("/home/alex/foo")
+/// ```
+///
+/// And you make a symbolic link of the program:
+///
+/// ```bash
+/// $ ln foo bar
+/// ```
+///
+/// When you run it, you won't get the original executable, you'll get the
+/// symlink:
+///
+/// ```bash
+/// $ ./bar
+/// Ok("/home/alex/bar")
+/// ```
+///
+/// This sort of behavior has been known to [lead to privledge escalation] when
+/// used incorrectly, for example.
+///
+/// [lead to privledge escalation]: http://securityvulns.com/Wdocument183.html
+///
/// # Examples
///
/// ```
}
}
+fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
+ let mut buf = [0];
+ loop {
+ return match reader.read(&mut buf) {
+ Ok(0) => None,
+ Ok(..) => Some(Ok(buf[0])),
+ Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+ Err(e) => Some(Err(e)),
+ };
+ }
+}
+
/// An iterator over `u8` values of a reader.
///
/// This struct is generally created by calling [`bytes()`][bytes] on a reader.
type Item = Result<u8>;
fn next(&mut self) -> Option<Result<u8>> {
- let mut buf = [0];
- match self.inner.read(&mut buf) {
- Ok(0) => None,
- Ok(..) => Some(Ok(buf[0])),
- Err(e) => Some(Err(e)),
- }
+ read_one_byte(&mut self.inner)
}
}
type Item = result::Result<char, CharsError>;
fn next(&mut self) -> Option<result::Result<char, CharsError>> {
- let mut buf = [0];
- let first_byte = match self.inner.read(&mut buf) {
- Ok(0) => return None,
- Ok(..) => buf[0],
- Err(e) => return Some(Err(CharsError::Other(e))),
+ let first_byte = match read_one_byte(&mut self.inner) {
+ None => return None,
+ Some(Ok(b)) => b,
+ Some(Err(e)) => return Some(Err(CharsError::Other(e))),
};
let width = core_str::utf8_char_width(first_byte);
if width == 1 { return Some(Ok(first_byte as char)) }
match self.inner.read(&mut buf[start..width]) {
Ok(0) => return Some(Err(CharsError::NotUtf8)),
Ok(n) => start += n,
+ Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Some(Err(CharsError::Other(e))),
}
}
Global
}
+impl IpAddr {
+ /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
+ /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
+ /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
+ #[unstable(feature="ip", issue="27709",
+ reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")]
+ pub fn is_unspecified(&self) -> bool {
+ match *self {
+ IpAddr::V4(ref a) => a.is_unspecified(),
+ IpAddr::V6(ref a) => a.is_unspecified(),
+ }
+ }
+
+ /// Returns true if this is a loopback address ([IPv4], [IPv6]).
+ /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
+ /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
+ #[unstable(feature="ip", reason="recently added", issue="27709")]
+ pub fn is_loopback(&self) -> bool {
+ match *self {
+ IpAddr::V4(ref a) => a.is_loopback(),
+ IpAddr::V6(ref a) => a.is_loopback(),
+ }
+ }
+
+ /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
+ /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
+ /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
+ #[unstable(feature="ip", issue="27709",
+ reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")]
+ pub fn is_global(&self) -> bool {
+ match *self {
+ IpAddr::V4(ref a) => a.is_global(),
+ IpAddr::V6(ref a) => a.is_global(),
+ }
+ }
+
+ /// Returns true if this is a multicast address ([IPv4], [IPv6]).
+ /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
+ /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
+ #[unstable(feature="ip", reason="recently added", issue="27709")]
+ pub fn is_multicast(&self) -> bool {
+ match *self {
+ IpAddr::V4(ref a) => a.is_multicast(),
+ IpAddr::V6(ref a) => a.is_multicast(),
+ }
+ }
+
+ /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
+ /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
+ /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
+ #[unstable(feature="ip", issue="27709",
+ reason="recently added and depends on unstable Ipv6Addr.is_documentation()")]
+ pub fn is_documentation(&self) -> bool {
+ match *self {
+ IpAddr::V4(ref a) => a.is_documentation(),
+ IpAddr::V6(ref a) => a.is_documentation(),
+ }
+ }
+}
+
impl Ipv4Addr {
/// Creates a new IPv4 address from four eight-bit octets.
///
None);
}
+ #[test]
+ fn ip_properties() {
+ fn check4(octets: &[u8; 4], unspec: bool, loopback: bool,
+ global: bool, multicast: bool, documentation: bool) {
+ let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]));
+ assert_eq!(ip.is_unspecified(), unspec);
+ assert_eq!(ip.is_loopback(), loopback);
+ assert_eq!(ip.is_global(), global);
+ assert_eq!(ip.is_multicast(), multicast);
+ assert_eq!(ip.is_documentation(), documentation);
+ }
+
+ fn check6(str_addr: &str, unspec: bool, loopback: bool,
+ global: bool, u_doc: bool, mcast: bool) {
+ let ip = IpAddr::V6(str_addr.parse().unwrap());
+ assert_eq!(ip.is_unspecified(), unspec);
+ assert_eq!(ip.is_loopback(), loopback);
+ assert_eq!(ip.is_global(), global);
+ assert_eq!(ip.is_documentation(), u_doc);
+ assert_eq!(ip.is_multicast(), mcast);
+ }
+
+ // address unspec loopbk global multicast doc
+ check4(&[0, 0, 0, 0], true, false, false, false, false);
+ check4(&[0, 0, 0, 1], false, false, true, false, false);
+ check4(&[0, 1, 0, 0], false, false, true, false, false);
+ check4(&[10, 9, 8, 7], false, false, false, false, false);
+ check4(&[127, 1, 2, 3], false, true, false, false, false);
+ check4(&[172, 31, 254, 253], false, false, false, false, false);
+ check4(&[169, 254, 253, 242], false, false, false, false, false);
+ check4(&[192, 0, 2, 183], false, false, false, false, true);
+ check4(&[192, 1, 2, 183], false, false, true, false, false);
+ check4(&[192, 168, 254, 253], false, false, false, false, false);
+ check4(&[198, 51, 100, 0], false, false, false, false, true);
+ check4(&[203, 0, 113, 0], false, false, false, false, true);
+ check4(&[203, 2, 113, 0], false, false, true, false, false);
+ check4(&[224, 0, 0, 0], false, false, true, true, false);
+ check4(&[239, 255, 255, 255], false, false, true, true, false);
+ check4(&[255, 255, 255, 255], false, false, false, false, false);
+
+ // address unspec loopbk global doc mcast
+ check6("::", true, false, false, false, false);
+ check6("::1", false, true, false, false, false);
+ check6("::0.0.0.2", false, false, true, false, false);
+ check6("1::", false, false, true, false, false);
+ check6("fc00::", false, false, false, false, false);
+ check6("fdff:ffff::", false, false, false, false, false);
+ check6("fe80:ffff::", false, false, false, false, false);
+ check6("febf:ffff::", false, false, false, false, false);
+ check6("fec0::", false, false, false, false, false);
+ check6("ff01::", false, false, false, false, true);
+ check6("ff02::", false, false, false, false, true);
+ check6("ff03::", false, false, false, false, true);
+ check6("ff04::", false, false, false, false, true);
+ check6("ff05::", false, false, false, false, true);
+ check6("ff08::", false, false, false, false, true);
+ check6("ff0e::", false, false, true, false, true);
+ check6("2001:db8:85a3::8a2e:370:7334", false, false, false, true, false);
+ check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true, false, false);
+ }
+
#[test]
fn ipv4_properties() {
fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
use codemap::{respan, Spanned};
use abi::Abi;
+use ext::hygiene::SyntaxContext;
use parse::token::{self, keywords, InternedString};
use print::pprust;
use ptr::P;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Name(pub u32);
-/// A SyntaxContext represents a chain of macro-expandings
-/// and renamings. Each macro expansion corresponds to
-/// a fresh u32. This u32 is a reference to a table stored
-/// in thread-local storage.
-/// The special value EMPTY_CTXT is used to indicate an empty
-/// syntax context.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct SyntaxContext(pub u32);
-
/// An identifier contains a Name (index into the interner
/// table) and a SyntaxContext to track renaming and
/// macro expansion per Flatt et al., "Macros That Work Together"
}
}
-pub const EMPTY_CTXT : SyntaxContext = SyntaxContext(0);
-
impl Ident {
- pub fn new(name: Name, ctxt: SyntaxContext) -> Ident {
- Ident {name: name, ctxt: ctxt}
- }
pub const fn with_empty_ctxt(name: Name) -> Ident {
- Ident {name: name, ctxt: EMPTY_CTXT}
+ Ident { name: name, ctxt: SyntaxContext::empty() }
}
}
impl fmt::Debug for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}#{}", self.name, self.ctxt.0)
+ write!(f, "{}{:?}", self.name, self.ctxt)
}
}
}
}
-/// A mark represents a unique id associated with a macro expansion
-pub type Mrk = u32;
-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct Lifetime {
pub id: NodeId,
// except according to those terms.
use ast::{Block, Crate, Ident, Mac_, Name, PatKind};
-use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
+use ast::{MacStmtStyle, Stmt, StmtKind, ItemKind};
use ast;
-use attr::HasAttrs;
-use ext::mtwt;
-use attr;
+use ext::hygiene::Mark;
+use attr::{self, HasAttrs};
use attr::AttrMetaMethods;
-use codemap::{dummy_spanned, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
+use codemap::{dummy_spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
use syntax_pos::{self, Span, ExpnId};
use config::StripUnconfigured;
use ext::base::*;
use feature_gate::{self, Features};
use fold;
use fold::*;
-use parse::token::{fresh_mark, intern, keywords};
+use parse::token::{intern, keywords};
use ptr::P;
use tokenstream::TokenTree;
use util::small_vector::SmallVector;
// It would almost certainly be cleaner to pass the whole macro invocation in,
// rather than pulling it apart and marking the tts and the ctxt separately.
let Mac_ { path, tts, .. } = mac.node;
- let mark = fresh_mark();
+ let mark = Mark::fresh();
- fn mac_result<'a>(path: &ast::Path, ident: Option<Ident>, tts: Vec<TokenTree>, mark: Mrk,
+ fn mac_result<'a>(path: &ast::Path, ident: Option<Ident>, tts: Vec<TokenTree>, mark: Mark,
attrs: Vec<ast::Attribute>, call_site: Span, fld: &'a mut MacroExpander)
-> Option<Box<MacResult + 'a>> {
// Detect use of feature-gated or invalid attributes on macro invoations
return (ret, cx.syntax_env.names);
}
-// HYGIENIC CONTEXT EXTENSION:
-// all of these functions are for walking over
-// ASTs and making some change to the context of every
-// element that has one. a CtxtFn is a trait-ified
-// version of a closure in (SyntaxContext -> SyntaxContext).
-// the ones defined here include:
-// Marker - add a mark to a context
-
// A Marker adds the given mark to the syntax context and
// sets spans' `expn_id` to the given expn_id (unless it is `None`).
-struct Marker { mark: Mrk, expn_id: Option<ExpnId> }
+struct Marker { mark: Mark, expn_id: Option<ExpnId> }
impl Folder for Marker {
- fn fold_ident(&mut self, id: Ident) -> Ident {
- ast::Ident::new(id.name, mtwt::apply_mark(self.mark, id.ctxt))
- }
- fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac {
- Spanned {
- node: Mac_ {
- path: self.fold_path(node.path),
- tts: self.fold_tts(&node.tts),
- },
- span: self.new_span(span),
- }
+ fn fold_ident(&mut self, mut ident: Ident) -> Ident {
+ ident.ctxt = ident.ctxt.apply_mark(self.mark);
+ ident
+ }
+ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+ noop_fold_mac(mac, self)
}
fn new_span(&mut self, mut span: Span) -> Span {
}
// apply a given mark to the given token trees. Used prior to expansion of a macro.
-fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
+fn mark_tts(tts: &[TokenTree], m: Mark) -> Vec<TokenTree> {
noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None})
}
--- /dev/null
+// Copyright 2012-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.
+
+//! Machinery for hygienic macros, inspired by the MTWT[1] paper.
+//!
+//! [1] Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler.
+//! 2012. *Macros that work together: Compile-time bindings, partial expansion,
+//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216.
+//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093
+
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::fmt;
+
+/// A SyntaxContext represents a chain of macro expansions (represented by marks).
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Default)]
+pub struct SyntaxContext(u32);
+
+#[derive(Copy, Clone)]
+pub struct SyntaxContextData {
+ pub outer_mark: Mark,
+ pub prev_ctxt: SyntaxContext,
+}
+
+/// A mark represents a unique id associated with a macro expansion.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
+pub struct Mark(u32);
+
+impl Mark {
+ pub fn fresh() -> Self {
+ HygieneData::with(|data| {
+ let next_mark = Mark(data.next_mark.0 + 1);
+ ::std::mem::replace(&mut data.next_mark, next_mark)
+ })
+ }
+}
+
+struct HygieneData {
+ syntax_contexts: Vec<SyntaxContextData>,
+ markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
+ next_mark: Mark,
+}
+
+impl HygieneData {
+ fn new() -> Self {
+ HygieneData {
+ syntax_contexts: vec![SyntaxContextData {
+ outer_mark: Mark(0), // the null mark
+ prev_ctxt: SyntaxContext(0), // the empty context
+ }],
+ markings: HashMap::new(),
+ next_mark: Mark(1),
+ }
+ }
+
+ fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
+ thread_local! {
+ static HYGIENE_DATA: RefCell<HygieneData> = RefCell::new(HygieneData::new());
+ }
+ HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut()))
+ }
+}
+
+pub fn reset_hygiene_data() {
+ HygieneData::with(|data| *data = HygieneData::new())
+}
+
+impl SyntaxContext {
+ pub const fn empty() -> Self {
+ SyntaxContext(0)
+ }
+
+ pub fn data(self) -> SyntaxContextData {
+ HygieneData::with(|data| data.syntax_contexts[self.0 as usize])
+ }
+
+ /// Extend a syntax context with a given mark
+ pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
+ // Applying the same mark twice is a no-op
+ let ctxt_data = self.data();
+ if mark == ctxt_data.outer_mark {
+ return ctxt_data.prev_ctxt;
+ }
+
+ HygieneData::with(|data| {
+ let syntax_contexts = &mut data.syntax_contexts;
+ *data.markings.entry((self, mark)).or_insert_with(|| {
+ syntax_contexts.push(SyntaxContextData {
+ outer_mark: mark,
+ prev_ctxt: self,
+ });
+ SyntaxContext(syntax_contexts.len() as u32 - 1)
+ })
+ })
+ }
+
+ /// If `ident` is macro expanded, return the source ident from the macro definition
+ /// and the mark of the expansion that created the macro definition.
+ pub fn source(self) -> (Self /* source context */, Mark /* source macro */) {
+ let macro_def_ctxt = self.data().prev_ctxt.data();
+ (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark)
+ }
+}
+
+impl fmt::Debug for SyntaxContext {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "#{}", self.0)
+ }
+}
+++ /dev/null
-// Copyright 2012-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.
-
-//! Machinery for hygienic macros, as described in the MTWT[1] paper.
-//!
-//! [1] Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler.
-//! 2012. *Macros that work together: Compile-time bindings, partial expansion,
-//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216.
-//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093
-
-pub use self::SyntaxContext_::*;
-
-use ast::{Ident, Mrk, SyntaxContext};
-
-use std::cell::RefCell;
-use std::collections::HashMap;
-
-/// The SCTable contains a table of SyntaxContext_'s. It
-/// represents a flattened tree structure, to avoid having
-/// managed pointers everywhere (that caused an ICE).
-/// The `marks` ensures that adding the same mark to the
-/// same context gives you back the same context as before.
-pub struct SCTable {
- table: RefCell<Vec<SyntaxContext_>>,
- marks: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
-}
-
-#[derive(PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, Clone)]
-pub enum SyntaxContext_ {
- EmptyCtxt,
- Mark (Mrk,SyntaxContext),
-}
-
-/// Extend a syntax context with a given mark
-pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
- with_sctable(|table| apply_mark_internal(m, ctxt, table))
-}
-
-/// Extend a syntax context with a given mark and sctable (explicit memoization)
-fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
- let ctxts = &mut *table.table.borrow_mut();
- match ctxts[ctxt.0 as usize] {
- // Applying the same mark twice is a no-op.
- Mark(outer_mark, prev_ctxt) if outer_mark == m => return prev_ctxt,
- _ => *table.marks.borrow_mut().entry((ctxt, m)).or_insert_with(|| {
- SyntaxContext(idx_push(ctxts, Mark(m, ctxt)))
- }),
- }
-}
-
-/// Fetch the SCTable from TLS, create one if it doesn't yet exist.
-pub fn with_sctable<T, F>(op: F) -> T where
- F: FnOnce(&SCTable) -> T,
-{
- thread_local!(static SCTABLE_KEY: SCTable = new_sctable_internal());
- SCTABLE_KEY.with(move |slot| op(slot))
-}
-
-// Make a fresh syntax context table with EmptyCtxt in slot zero.
-fn new_sctable_internal() -> SCTable {
- SCTable {
- table: RefCell::new(vec![EmptyCtxt]),
- marks: RefCell::new(HashMap::new()),
- }
-}
-
-/// Clear the tables from TLD to reclaim memory.
-pub fn clear_tables() {
- with_sctable(|table| {
- *table.table.borrow_mut() = Vec::new();
- *table.marks.borrow_mut() = HashMap::new();
- });
-}
-
-/// Reset the tables to their initial state
-pub fn reset_tables() {
- with_sctable(|table| {
- *table.table.borrow_mut() = vec![EmptyCtxt];
- *table.marks.borrow_mut() = HashMap::new();
- });
-}
-
-/// Add a value to the end of a vec, return its index
-fn idx_push<T>(vec: &mut Vec<T>, val: T) -> u32 {
- vec.push(val);
- (vec.len() - 1) as u32
-}
-
-/// Return the outer mark for a context with a mark at the outside.
-/// FAILS when outside is not a mark.
-pub fn outer_mark(ctxt: SyntaxContext) -> Mrk {
- with_sctable(|sctable| {
- match (*sctable.table.borrow())[ctxt.0 as usize] {
- Mark(mrk, _) => mrk,
- _ => panic!("can't retrieve outer mark when outside is not a mark")
- }
- })
-}
-
-/// If `ident` is macro expanded, return the source ident from the macro definition
-/// and the mark of the expansion that created the macro definition.
-pub fn source(ident: Ident) -> Option<(Ident /* source ident */, Mrk /* source macro */)> {
- with_sctable(|sctable| {
- let ctxts = sctable.table.borrow();
- if let Mark(_expansion_mark, macro_ctxt) = ctxts[ident.ctxt.0 as usize] {
- if let Mark(definition_mark, orig_ctxt) = ctxts[macro_ctxt.0 as usize] {
- return Some((Ident::new(ident.name, orig_ctxt), definition_mark));
- }
- }
- None
- })
-}
-
-#[cfg(test)]
-mod tests {
- use ast::{EMPTY_CTXT, Mrk, SyntaxContext};
- use super::{apply_mark_internal, new_sctable_internal, Mark, SCTable};
-
- // extend a syntax context with a sequence of marks given
- // in a vector. v[0] will be the outermost mark.
- fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
- -> SyntaxContext {
- mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
- {apply_mark_internal(*mrk,tail,table)})
- }
-
- #[test] fn unfold_marks_test() {
- let mut t = new_sctable_internal();
-
- assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),SyntaxContext(2));
- {
- let table = t.table.borrow();
- assert!((*table)[1] == Mark(7,EMPTY_CTXT));
- assert!((*table)[2] == Mark(3,SyntaxContext(1)));
- }
- }
-
- #[test]
- fn hashing_tests () {
- let mut t = new_sctable_internal();
- assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1));
- assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),SyntaxContext(2));
- // using the same one again should result in the same index:
- assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1));
- // I'm assuming that the rename table will behave the same....
- }
-}
pub mod base;
pub mod build;
pub mod expand;
- pub mod mtwt;
+ pub mod hygiene;
pub mod quote;
pub mod source_util;
/// Parse a statement. This stops just before trailing semicolons on everything but items.
/// e.g. a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
- ///
- /// Also, if a macro begins an expression statement, this only parses the macro. For example,
- /// ```rust
- /// vec![1].into_iter(); //< `parse_stmt` only parses the "vec![1]"
- /// ```
pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
- Ok(self.parse_stmt_())
+ Ok(self.parse_stmt_(true))
}
// Eat tokens until we can be relatively sure we reached the end of the
}
}
- fn parse_stmt_(&mut self) -> Option<Stmt> {
- self.parse_stmt_without_recovery().unwrap_or_else(|mut e| {
+ fn parse_stmt_(&mut self, macro_expanded: bool) -> Option<Stmt> {
+ self.parse_stmt_without_recovery(macro_expanded).unwrap_or_else(|mut e| {
e.emit();
self.recover_stmt_(SemiColonMode::Break);
None
})
}
- fn parse_stmt_without_recovery(&mut self) -> PResult<'a, Option<Stmt>> {
+ fn parse_stmt_without_recovery(&mut self, macro_expanded: bool) -> PResult<'a, Option<Stmt>> {
maybe_whole!(Some deref self, NtStmt);
let attrs = self.parse_outer_attributes()?;
if id.name == keywords::Invalid.name() {
let mac = spanned(lo, hi, Mac_ { path: pth, tts: tts });
+ let node = if delim == token::Brace ||
+ self.token == token::Semi || self.token == token::Eof {
+ StmtKind::Mac(P((mac, style, attrs.into())))
+ }
+ // We used to incorrectly stop parsing macro-expanded statements here.
+ // If the next token will be an error anyway but could have parsed with the
+ // earlier behavior, stop parsing here and emit a warning to avoid breakage.
+ else if macro_expanded && self.token.can_begin_expr() && match self.token {
+ // These can continue an expression, so we can't stop parsing and warn.
+ token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
+ token::BinOp(token::Minus) | token::BinOp(token::Star) |
+ token::BinOp(token::And) | token::BinOp(token::Or) |
+ token::AndAnd | token::OrOr |
+ token::DotDot | token::DotDotDot => false,
+ _ => true,
+ } {
+ self.warn_missing_semicolon();
+ StmtKind::Mac(P((mac, style, attrs.into())))
+ } else {
+ let e = self.mk_mac_expr(lo, hi, mac.node, ThinVec::new());
+ let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
+ let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
+ StmtKind::Expr(e)
+ };
Stmt {
id: ast::DUMMY_NODE_ID,
- node: StmtKind::Mac(P((mac, style, attrs.into()))),
span: mk_sp(lo, hi),
+ node: node,
}
} else {
// if it has a special ident, it's definitely an item
}
/// Parse a statement, including the trailing semicolon.
- /// This parses expression statements that begin with macros correctly (c.f. `parse_stmt`).
pub fn parse_full_stmt(&mut self, macro_expanded: bool) -> PResult<'a, Option<Stmt>> {
- let mut stmt = match self.parse_stmt_() {
+ let mut stmt = match self.parse_stmt_(macro_expanded) {
Some(stmt) => stmt,
None => return Ok(None),
};
- if let StmtKind::Mac(mac) = stmt.node {
- if mac.1 != MacStmtStyle::NoBraces ||
- self.token == token::Semi || self.token == token::Eof {
- stmt.node = StmtKind::Mac(mac);
- } else {
- // We used to incorrectly stop parsing macro-expanded statements here.
- // If the next token will be an error anyway but could have parsed with the
- // earlier behavior, stop parsing here and emit a warning to avoid breakage.
- if macro_expanded && self.token.can_begin_expr() && match self.token {
- // These tokens can continue an expression, so we can't stop parsing and warn.
- token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
- token::BinOp(token::Minus) | token::BinOp(token::Star) |
- token::BinOp(token::And) | token::BinOp(token::Or) |
- token::AndAnd | token::OrOr |
- token::DotDot | token::DotDotDot => false,
- _ => true,
- } {
- self.warn_missing_semicolon();
- stmt.node = StmtKind::Mac(mac);
- return Ok(Some(stmt));
- }
-
- let (mac, _style, attrs) = mac.unwrap();
- let e = self.mk_mac_expr(stmt.span.lo, stmt.span.hi, mac.node, ThinVec::new());
- let e = self.parse_dot_or_call_expr_with(e, stmt.span.lo, attrs)?;
- let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
- stmt.node = StmtKind::Expr(e);
- }
- }
-
- stmt = self.handle_trailing_semicolon(stmt, macro_expanded)?;
- Ok(Some(stmt))
- }
-
- fn handle_trailing_semicolon(&mut self, mut stmt: Stmt, macro_expanded: bool)
- -> PResult<'a, Stmt> {
match stmt.node {
StmtKind::Expr(ref expr) if self.token != token::Eof => {
// expression without semicolon
}
stmt.span.hi = self.last_span.hi;
- Ok(stmt)
+ Ok(Some(stmt))
}
fn warn_missing_semicolon(&self) {
/*let num = rand::thread_rng().gen_uint_range(0,0xffff);
gensym(format!("{}_{}",ident_to_string(src),num))*/
}
-
-// create a fresh mark.
-pub fn fresh_mark() -> ast::Mrk {
- gensym("mark").0
-}
use deriving::generic::ty::*;
use syntax::ast::MetaItem;
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax_pos::Span;
pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt,
span: Span,
_: &MetaItem,
_: &Annotatable,
- _: &mut FnMut(Annotatable))
-{
+ _: &mut FnMut(Annotatable)) {
cx.span_err(span, "this unsafe trait should be implemented explicitly");
}
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
let mut v = cx.crate_root.map(|s| vec![s]).unwrap_or(Vec::new());
v.push("marker");
v.push("Copy");
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{Expr, ItemKind, Generics, MetaItem, VariantData};
+use syntax::ast::{Expr, Generics, ItemKind, MetaItem, VariantData};
use syntax::attr;
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax_pos::Span;
#[derive(PartialEq)]
-enum Mode { Deep, Shallow }
+enum Mode {
+ Deep,
+ Shallow,
+}
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
// check if we can use a short form
//
// the short form is `fn clone(&self) -> Self { *self }`
match annitem.node {
ItemKind::Struct(_, Generics { ref ty_params, .. }) |
ItemKind::Enum(_, Generics { ref ty_params, .. })
- if ty_params.is_empty()
- && attr::contains_name(&annitem.attrs, "derive_Copy") => {
+ if ty_params.is_empty() &&
+ attr::contains_name(&annitem.attrs, "derive_Copy") => {
bounds = vec![Literal(path_std!(cx, core::marker::Copy))];
unify_fieldless_variants = true;
}
}
- _ => cx.span_bug(span, "#[derive(Clone)] on trait item or impl item")
+ _ => cx.span_bug(span, "#[derive(Clone)] on trait item or impl item"),
}
let inline = cx.meta_word(span, InternedString::new("inline"));
- let attrs = vec!(cx.attribute(span, inline));
+ let attrs = vec![cx.attribute(span, inline)];
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
additional_bounds: bounds,
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec!(
- MethodDef {
- name: "clone",
- generics: LifetimeBounds::empty(),
- explicit_self: borrowed_explicit_self(),
- args: Vec::new(),
- ret_ty: Self_,
- attributes: attrs,
- is_unsafe: false,
- unify_fieldless_variants: unify_fieldless_variants,
- combine_substructure: substructure,
- }
- ),
+ methods: vec![MethodDef {
+ name: "clone",
+ generics: LifetimeBounds::empty(),
+ explicit_self: borrowed_explicit_self(),
+ args: Vec::new(),
+ ret_ty: Self_,
+ attributes: attrs,
+ is_unsafe: false,
+ unify_fieldless_variants: unify_fieldless_variants,
+ combine_substructure: substructure,
+ }],
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
}
-fn cs_clone(
- name: &str,
- cx: &mut ExtCtxt, trait_span: Span,
- substr: &Substructure,
- mode: Mode) -> P<Expr> {
+fn cs_clone(name: &str,
+ cx: &mut ExtCtxt,
+ trait_span: Span,
+ substr: &Substructure,
+ mode: Mode)
+ -> P<Expr> {
let ctor_path;
let all_fields;
let fn_path = match mode {
Mode::Shallow => cx.std_path(&["clone", "assert_receiver_is_clone"]),
- Mode::Deep => cx.std_path(&["clone", "Clone", "clone"]),
+ Mode::Deep => cx.std_path(&["clone", "Clone", "clone"]),
};
let subcall = |field: &FieldInfo| {
let args = vec![cx.expr_addr_of(field.span, field.self_.clone())];
let span = if mode == Mode::Shallow {
// set the expn ID so we can call the unstable method
- Span { expn_id: cx.backtrace(), .. trait_span }
+ Span { expn_id: cx.backtrace(), ..trait_span }
} else {
field.span
};
ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.node.name]);
all_fields = af;
vdata = &variant.node.data;
- },
- EnumNonMatchingCollapsed (..) => {
+ }
+ EnumNonMatchingCollapsed(..) => {
cx.span_bug(trait_span,
&format!("non-matching enum variants in \
- `derive({})`", name))
+ `derive({})`",
+ name))
}
StaticEnum(..) | StaticStruct(..) => {
- cx.span_bug(trait_span,
- &format!("static method in `derive({})`", name))
+ cx.span_bug(trait_span, &format!("static method in `derive({})`", name))
}
}
Mode::Deep => {
match *vdata {
VariantData::Struct(..) => {
- let fields = all_fields.iter().map(|field| {
- let ident = match field.name {
- Some(i) => i,
- None => {
- cx.span_bug(trait_span,
- &format!("unnamed field in normal struct in \
- `derive({})`", name))
- }
- };
- cx.field_imm(field.span, ident, subcall(field))
- }).collect::<Vec<_>>();
+ let fields = all_fields.iter()
+ .map(|field| {
+ let ident = match field.name {
+ Some(i) => i,
+ None => {
+ cx.span_bug(trait_span,
+ &format!("unnamed field in normal struct in \
+ `derive({})`",
+ name))
+ }
+ };
+ cx.field_imm(field.span, ident, subcall(field))
+ })
+ .collect::<Vec<_>>();
cx.expr_struct(trait_span, ctor_path, fields)
}
let path = cx.expr_path(ctor_path);
cx.expr_call(trait_span, path, subcalls)
}
- VariantData::Unit(..) => {
- cx.expr_path(ctor_path)
- }
+ VariantData::Unit(..) => cx.expr_path(ctor_path),
}
}
}
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
- cs_same_method(
- |cx, span, exprs| {
- // create `a.<method>(); b.<method>(); c.<method>(); ...`
- // (where method is `assert_receiver_is_total_eq`)
- let stmts = exprs.into_iter().map(|e| cx.stmt_expr(e)).collect();
- let block = cx.block(span, stmts);
- cx.expr_block(block)
- },
- Box::new(|cx, sp, _, _| {
- cx.span_bug(sp, "non matching enums in derive(Eq)?") }),
- cx,
- span,
- substr
- )
+ cs_same_method(|cx, span, exprs| {
+ // create `a.<method>(); b.<method>(); c.<method>(); ...`
+ // (where method is `assert_receiver_is_total_eq`)
+ let stmts = exprs.into_iter().map(|e| cx.stmt_expr(e)).collect();
+ let block = cx.block(span, stmts);
+ cx.expr_block(block)
+ },
+ Box::new(|cx, sp, _, _| {
+ cx.span_bug(sp, "non matching enums in derive(Eq)?")
+ }),
+ cx,
+ span,
+ substr)
}
let inline = cx.meta_word(span, InternedString::new("inline"));
let hidden = cx.meta_word(span, InternedString::new("hidden"));
- let doc = cx.meta_list(span, InternedString::new("doc"), vec!(hidden));
- let attrs = vec!(cx.attribute(span, inline),
- cx.attribute(span, doc));
+ let doc = cx.meta_list(span, InternedString::new("doc"), vec![hidden]);
+ let attrs = vec![cx.attribute(span, inline), cx.attribute(span, doc)];
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec!(
- MethodDef {
- name: "assert_receiver_is_total_eq",
- generics: LifetimeBounds::empty(),
- explicit_self: borrowed_explicit_self(),
- args: vec!(),
- ret_ty: nil_ty(),
- attributes: attrs,
- is_unsafe: false,
- unify_fieldless_variants: true,
- combine_substructure: combine_substructure(Box::new(|a, b, c| {
- cs_total_eq_assert(a, b, c)
- }))
- }
- ),
+ methods: vec![MethodDef {
+ name: "assert_receiver_is_total_eq",
+ generics: LifetimeBounds::empty(),
+ explicit_self: borrowed_explicit_self(),
+ args: vec![],
+ ret_ty: nil_ty(),
+ attributes: attrs,
+ is_unsafe: false,
+ unify_fieldless_variants: true,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
+ cs_total_eq_assert(a, b, c)
+ })),
+ }],
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr, self};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{self, Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
let inline = cx.meta_word(span, InternedString::new("inline"));
- let attrs = vec!(cx.attribute(span, inline));
+ let attrs = vec![cx.attribute(span, inline)];
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec!(
- MethodDef {
- name: "cmp",
- generics: LifetimeBounds::empty(),
- explicit_self: borrowed_explicit_self(),
- args: vec!(borrowed_self()),
- ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
- attributes: attrs,
- is_unsafe: false,
- unify_fieldless_variants: true,
- combine_substructure: combine_substructure(Box::new(|a, b, c| {
- cs_cmp(a, b, c)
- })),
- }
- ),
+ methods: vec![MethodDef {
+ name: "cmp",
+ generics: LifetimeBounds::empty(),
+ explicit_self: borrowed_explicit_self(),
+ args: vec![borrowed_self()],
+ ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
+ attributes: attrs,
+ is_unsafe: false,
+ unify_fieldless_variants: true,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
+ cs_cmp(a, b, c)
+ })),
+ }],
associated_types: Vec::new(),
};
pub fn ordering_collapsed(cx: &mut ExtCtxt,
span: Span,
- self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
+ self_arg_tags: &[ast::Ident])
+ -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
}
-pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
- substr: &Substructure) -> P<Expr> {
+pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
let test_id = cx.ident_of("__cmp");
- let equals_path = cx.path_global(span,
- cx.std_path(&["cmp", "Ordering", "Equal"]));
+ let equals_path = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
let cmp_path = cx.std_path(&["cmp", "Ord", "cmp"]);
- /*
- Builds:
+ // Builds:
+ //
+ // match ::std::cmp::Ord::cmp(&self_field1, &other_field1) {
+ // ::std::cmp::Ordering::Equal =>
+ // match ::std::cmp::Ord::cmp(&self_field2, &other_field2) {
+ // ::std::cmp::Ordering::Equal => {
+ // ...
+ // }
+ // __cmp => __cmp
+ // },
+ // __cmp => __cmp
+ // }
+ //
+ cs_fold(// foldr nests the if-elses correctly, leaving the first field
+ // as the outermost one, and the last as the innermost.
+ false,
+ |cx, span, old, self_f, other_fs| {
+ // match new {
+ // ::std::cmp::Ordering::Equal => old,
+ // __cmp => __cmp
+ // }
- match ::std::cmp::Ord::cmp(&self_field1, &other_field1) {
- ::std::cmp::Ordering::Equal =>
- match ::std::cmp::Ord::cmp(&self_field2, &other_field2) {
- ::std::cmp::Ordering::Equal => {
- ...
- }
- __cmp => __cmp
- },
- __cmp => __cmp
- }
- */
- cs_fold(
- // foldr nests the if-elses correctly, leaving the first field
- // as the outermost one, and the last as the innermost.
- false,
- |cx, span, old, self_f, other_fs| {
- // match new {
- // ::std::cmp::Ordering::Equal => old,
- // __cmp => __cmp
- // }
-
- let new = {
- let other_f = match (other_fs.len(), other_fs.get(0)) {
- (1, Some(o_f)) => o_f,
- _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
- };
+ let new = {
+ let other_f = match (other_fs.len(), other_fs.get(0)) {
+ (1, Some(o_f)) => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
+ };
- let args = vec![
+ let args = vec![
cx.expr_addr_of(span, self_f),
cx.expr_addr_of(span, other_f.clone()),
];
- cx.expr_call_global(span, cmp_path.clone(), args)
- };
+ cx.expr_call_global(span, cmp_path.clone(), args)
+ };
- let eq_arm = cx.arm(span,
- vec![cx.pat_enum(span,
- equals_path.clone(),
- vec![])],
- old);
- let neq_arm = cx.arm(span,
- vec![cx.pat_ident(span, test_id)],
- cx.expr_ident(span, test_id));
+ let eq_arm = cx.arm(span,
+ vec![cx.pat_enum(span, equals_path.clone(), vec![])],
+ old);
+ let neq_arm = cx.arm(span,
+ vec![cx.pat_ident(span, test_id)],
+ cx.expr_ident(span, test_id));
- cx.expr_match(span, new, vec![eq_arm, neq_arm])
- },
- cx.expr_path(equals_path.clone()),
- Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
- if self_args.len() != 2 {
- cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
- } else {
- ordering_collapsed(cx, span, tag_tuple)
- }
- }),
- cx, span, substr)
+ cx.expr_match(span, new, vec![eq_arm, neq_arm])
+ },
+ cx.expr_path(equals_path.clone()),
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
+ } else {
+ ordering_collapsed(cx, span, tag_tuple)
+ }
+ }),
+ cx,
+ span,
+ substr)
}
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr, BinOpKind};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{BinOpKind, Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
// structures are equal if all fields are equal, and non equal, if
// any fields are not equal or if the enum variants are different
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
- cs_fold(
- true, // use foldl
- |cx, span, subexpr, self_f, other_fs| {
- let other_f = match (other_fs.len(), other_fs.get(0)) {
- (1, Some(o_f)) => o_f,
- _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
- };
+ cs_fold(true, // use foldl
+ |cx, span, subexpr, self_f, other_fs| {
+ let other_f = match (other_fs.len(), other_fs.get(0)) {
+ (1, Some(o_f)) => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`"),
+ };
- let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone());
+ let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone());
- cx.expr_binary(span, BinOpKind::And, subexpr, eq)
- },
- cx.expr_bool(span, true),
- Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
- cx, span, substr)
+ cx.expr_binary(span, BinOpKind::And, subexpr, eq)
+ },
+ cx.expr_bool(span, true),
+ Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
+ cx,
+ span,
+ substr)
}
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
- cs_fold(
- true, // use foldl
- |cx, span, subexpr, self_f, other_fs| {
- let other_f = match (other_fs.len(), other_fs.get(0)) {
- (1, Some(o_f)) => o_f,
- _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
- };
+ cs_fold(true, // use foldl
+ |cx, span, subexpr, self_f, other_fs| {
+ let other_f = match (other_fs.len(), other_fs.get(0)) {
+ (1, Some(o_f)) => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`"),
+ };
- let eq = cx.expr_binary(span, BinOpKind::Ne, self_f, other_f.clone());
+ let eq = cx.expr_binary(span, BinOpKind::Ne, self_f, other_f.clone());
- cx.expr_binary(span, BinOpKind::Or, subexpr, eq)
- },
- cx.expr_bool(span, false),
- Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
- cx, span, substr)
+ cx.expr_binary(span, BinOpKind::Or, subexpr, eq)
+ },
+ cx.expr_bool(span, false),
+ Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
+ cx,
+ span,
+ substr)
}
macro_rules! md {
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr, BinOpKind, self};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{self, BinOpKind, Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
macro_rules! md {
($name:expr, $op:expr, $equal:expr) => { {
let inline = cx.meta_word(span, InternedString::new("inline"));
true));
let inline = cx.meta_word(span, InternedString::new("inline"));
- let attrs = vec!(cx.attribute(span, inline));
+ let attrs = vec![cx.attribute(span, inline)];
let partial_cmp_def = MethodDef {
name: "partial_cmp",
unify_fieldless_variants: true,
combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr)
- }))
+ })),
};
// avoid defining extra methods if we can
let methods = if is_type_without_fields(item) {
vec![partial_cmp_def]
} else {
- vec![
- partial_cmp_def,
- md!("lt", true, false),
- md!("le", true, true),
- md!("gt", false, false),
- md!("ge", false, true)
- ]
+ vec![partial_cmp_def,
+ md!("lt", true, false),
+ md!("le", true, true),
+ md!("gt", false, false),
+ md!("ge", false, true)]
};
let trait_def = TraitDef {
#[derive(Copy, Clone)]
pub enum OrderingOp {
- PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
+ PartialCmpOp,
+ LtOp,
+ LeOp,
+ GtOp,
+ GeOp,
}
pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
span: Span,
op: OrderingOp,
- self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
+ self_arg_tags: &[ast::Ident])
+ -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
let op_str = match op {
PartialCmpOp => "partial_cmp",
- LtOp => "lt", LeOp => "le",
- GtOp => "gt", GeOp => "ge",
+ LtOp => "lt",
+ LeOp => "le",
+ GtOp => "gt",
+ GeOp => "ge",
};
cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
}
-pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
- substr: &Substructure) -> P<Expr> {
+pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
let test_id = cx.ident_of("__cmp");
- let ordering = cx.path_global(span,
- cx.std_path(&["cmp", "Ordering", "Equal"]));
+ let ordering = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
let ordering_expr = cx.expr_path(ordering.clone());
let equals_expr = cx.expr_some(span, ordering_expr);
let partial_cmp_path = cx.std_path(&["cmp", "PartialOrd", "partial_cmp"]);
- /*
- Builds:
-
- match ::std::cmp::PartialOrd::partial_cmp(&self_field1, &other_field1) {
- ::std::option::Option::Some(::std::cmp::Ordering::Equal) =>
- match ::std::cmp::PartialOrd::partial_cmp(&self_field2, &other_field2) {
- ::std::option::Option::Some(::std::cmp::Ordering::Equal) => {
- ...
- }
- __cmp => __cmp
- },
- __cmp => __cmp
- }
- */
- cs_fold(
- // foldr nests the if-elses correctly, leaving the first field
- // as the outermost one, and the last as the innermost.
- false,
- |cx, span, old, self_f, other_fs| {
- // match new {
- // Some(::std::cmp::Ordering::Equal) => old,
- // __cmp => __cmp
- // }
-
- let new = {
- let other_f = match (other_fs.len(), other_fs.get(0)) {
- (1, Some(o_f)) => o_f,
- _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
- };
-
- let args = vec![
+ // Builds:
+ //
+ // match ::std::cmp::PartialOrd::partial_cmp(&self_field1, &other_field1) {
+ // ::std::option::Option::Some(::std::cmp::Ordering::Equal) =>
+ // match ::std::cmp::PartialOrd::partial_cmp(&self_field2, &other_field2) {
+ // ::std::option::Option::Some(::std::cmp::Ordering::Equal) => {
+ // ...
+ // }
+ // __cmp => __cmp
+ // },
+ // __cmp => __cmp
+ // }
+ //
+ cs_fold(// foldr nests the if-elses correctly, leaving the first field
+ // as the outermost one, and the last as the innermost.
+ false,
+ |cx, span, old, self_f, other_fs| {
+ // match new {
+ // Some(::std::cmp::Ordering::Equal) => old,
+ // __cmp => __cmp
+ // }
+
+ let new = {
+ let other_f = match (other_fs.len(), other_fs.get(0)) {
+ (1, Some(o_f)) => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
+ };
+
+ let args = vec![
cx.expr_addr_of(span, self_f),
cx.expr_addr_of(span, other_f.clone()),
];
- cx.expr_call_global(span, partial_cmp_path.clone(), args)
- };
-
- let eq_arm = cx.arm(span,
- vec![cx.pat_some(span,
- cx.pat_enum(span,
- ordering.clone(),
- vec![]))],
- old);
- let neq_arm = cx.arm(span,
- vec![cx.pat_ident(span, test_id)],
- cx.expr_ident(span, test_id));
-
- cx.expr_match(span, new, vec![eq_arm, neq_arm])
- },
- equals_expr.clone(),
- Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
- if self_args.len() != 2 {
- cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
- } else {
- some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
- }
- }),
- cx, span, substr)
+ cx.expr_call_global(span, partial_cmp_path.clone(), args)
+ };
+
+ let eq_arm = cx.arm(span,
+ vec![cx.pat_some(span, cx.pat_enum(span, ordering.clone(), vec![]))],
+ old);
+ let neq_arm = cx.arm(span,
+ vec![cx.pat_ident(span, test_id)],
+ cx.expr_ident(span, test_id));
+
+ cx.expr_match(span, new, vec![eq_arm, neq_arm])
+ },
+ equals_expr.clone(),
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+ } else {
+ some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
+ }
+ }),
+ cx,
+ span,
+ substr)
}
/// Strict inequality.
-fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
- span: Span, substr: &Substructure) -> P<Expr> {
+fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
let op = if less { BinOpKind::Lt } else { BinOpKind::Gt };
- cs_fold(
- false, // need foldr,
- |cx, span, subexpr, self_f, other_fs| {
- /*
- build up a series of chain ||'s and &&'s from the inside
- out (hence foldr) to get lexical ordering, i.e. for op ==
- `ast::lt`
-
- ```
- self.f1 < other.f1 || (!(other.f1 < self.f1) &&
- (self.f2 < other.f2 || (!(other.f2 < self.f2) &&
- (false)
- ))
- )
- ```
-
- The optimiser should remove the redundancy. We explicitly
- get use the binops to avoid auto-deref dereferencing too many
- layers of pointers, if the type includes pointers.
- */
- let other_f = match (other_fs.len(), other_fs.get(0)) {
- (1, Some(o_f)) => o_f,
- _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+ cs_fold(false, // need foldr,
+ |cx, span, subexpr, self_f, other_fs| {
+ // build up a series of chain ||'s and &&'s from the inside
+ // out (hence foldr) to get lexical ordering, i.e. for op ==
+ // `ast::lt`
+ //
+ // ```
+ // self.f1 < other.f1 || (!(other.f1 < self.f1) &&
+ // (self.f2 < other.f2 || (!(other.f2 < self.f2) &&
+ // (false)
+ // ))
+ // )
+ // ```
+ //
+ // The optimiser should remove the redundancy. We explicitly
+ // get use the binops to avoid auto-deref dereferencing too many
+ // layers of pointers, if the type includes pointers.
+ //
+ let other_f = match (other_fs.len(), other_fs.get(0)) {
+ (1, Some(o_f)) => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
+ };
+
+ let cmp = cx.expr_binary(span, op, self_f.clone(), other_f.clone());
+
+ let not_cmp = cx.expr_unary(span,
+ ast::UnOp::Not,
+ cx.expr_binary(span, op, other_f.clone(), self_f));
+
+ let and = cx.expr_binary(span, BinOpKind::And, not_cmp, subexpr);
+ cx.expr_binary(span, BinOpKind::Or, cmp, and)
+ },
+ cx.expr_bool(span, equal),
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+ } else {
+ let op = match (less, equal) {
+ (true, true) => LeOp,
+ (true, false) => LtOp,
+ (false, true) => GeOp,
+ (false, false) => GtOp,
};
-
- let cmp = cx.expr_binary(span, op, self_f.clone(), other_f.clone());
-
- let not_cmp = cx.expr_unary(span, ast::UnOp::Not,
- cx.expr_binary(span, op, other_f.clone(), self_f));
-
- let and = cx.expr_binary(span, BinOpKind::And, not_cmp, subexpr);
- cx.expr_binary(span, BinOpKind::Or, cmp, and)
- },
- cx.expr_bool(span, equal),
- Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
- if self_args.len() != 2 {
- cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
- } else {
- let op = match (less, equal) {
- (true, true) => LeOp, (true, false) => LtOp,
- (false, true) => GeOp, (false, false) => GtOp,
- };
- some_ordering_collapsed(cx, span, op, tag_tuple)
- }
- }),
- cx, span, substr)
+ some_ordering_collapsed(cx, span, op, tag_tuple)
+ }
+ }),
+ cx,
+ span,
+ substr)
}
use deriving::generic::ty::*;
use syntax::ast;
-use syntax::ast::{MetaItem, Expr};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::ptr::P;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::{DUMMY_SP, Span};
pub fn expand_deriving_debug(cx: &mut ExtCtxt,
- span: Span,
- mitem: &MetaItem,
- item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ span: Span,
+ mitem: &MetaItem,
+ item: &Annotatable,
+ push: &mut FnMut(Annotatable)) {
// &mut ::std::fmt::Formatter
let fmtr = Ptr(Box::new(Literal(path_std!(cx, core::fmt::Formatter))),
Borrowed(None, ast::Mutability::Mutable));
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec![
- MethodDef {
- name: "fmt",
- generics: LifetimeBounds::empty(),
- explicit_self: borrowed_explicit_self(),
- args: vec!(fmtr),
- ret_ty: Literal(path_std!(cx, core::fmt::Result)),
- attributes: Vec::new(),
- is_unsafe: false,
- unify_fieldless_variants: false,
- combine_substructure: combine_substructure(Box::new(|a, b, c| {
- show_substructure(a, b, c)
- }))
- }
- ],
+ methods: vec![MethodDef {
+ name: "fmt",
+ generics: LifetimeBounds::empty(),
+ explicit_self: borrowed_explicit_self(),
+ args: vec![fmtr],
+ ret_ty: Literal(path_std!(cx, core::fmt::Result)),
+ attributes: Vec::new(),
+ is_unsafe: false,
+ unify_fieldless_variants: false,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
+ show_substructure(a, b, c)
+ })),
+ }],
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
}
/// We use the debug builders to do the heavy lifting here
-fn show_substructure(cx: &mut ExtCtxt, span: Span,
- substr: &Substructure) -> P<Expr> {
+fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
// build fmt.debug_struct(<name>).field(<fieldname>, &<fieldval>)....build()
// or fmt.debug_tuple(<name>).field(&<fieldval>)....build()
// based on the "shape".
let (ident, is_struct) = match *substr.fields {
Struct(vdata, _) => (substr.type_ident, vdata.is_struct()),
EnumMatching(_, v, _) => (v.node.name, v.node.data.is_struct()),
- EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
- cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
- }
+ EnumNonMatchingCollapsed(..) |
+ StaticStruct(..) |
+ StaticEnum(..) => cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`"),
};
// We want to make sure we have the expn_id set so that we can use unstable methods
- let span = Span { expn_id: cx.backtrace(), .. span };
- let name = cx.expr_lit(span, ast::LitKind::Str(ident.name.as_str(), ast::StrStyle::Cooked));
+ let span = Span { expn_id: cx.backtrace(), ..span };
+ let name = cx.expr_lit(span,
+ ast::LitKind::Str(ident.name.as_str(), ast::StrStyle::Cooked));
let builder = token::str_to_ident("builder");
let builder_expr = cx.expr_ident(span, builder.clone());
let fmt = substr.nonself_args[0].clone();
let mut stmts = match *substr.fields {
- Struct(_, ref fields) | EnumMatching(_, _, ref fields) => {
+ Struct(_, ref fields) |
+ EnumMatching(_, _, ref fields) => {
let mut stmts = vec![];
if !is_struct {
// tuple struct/"normal" variant
- let expr = cx.expr_method_call(span,
- fmt,
- token::str_to_ident("debug_tuple"),
- vec![name]);
+ let expr =
+ cx.expr_method_call(span, fmt, token::str_to_ident("debug_tuple"), vec![name]);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields {
}
} else {
// normal struct/struct variant
- let expr = cx.expr_method_call(span,
- fmt,
- token::str_to_ident("debug_struct"),
- vec![name]);
+ let expr =
+ cx.expr_method_call(span, fmt, token::str_to_ident("debug_struct"), vec![name]);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields {
- let name = cx.expr_lit(field.span, ast::LitKind::Str(
- field.name.unwrap().name.as_str(),
- ast::StrStyle::Cooked));
+ let name = cx.expr_lit(field.span,
+ ast::LitKind::Str(field.name.unwrap().name.as_str(),
+ ast::StrStyle::Cooked));
// Use double indirection to make sure this works for unsized types
let field = cx.expr_addr_of(field.span, field.self_.clone());
}
stmts
}
- _ => unreachable!()
+ _ => unreachable!(),
};
- let expr = cx.expr_method_call(span,
- builder_expr,
- token::str_to_ident("finish"),
- vec![]);
+ let expr = cx.expr_method_call(span, builder_expr, token::str_to_ident("finish"), vec![]);
stmts.push(cx.stmt_expr(expr));
let block = cx.block(span, stmts);
cx.expr_block(block)
}
-fn stmt_let_undescore(cx: &mut ExtCtxt,
- sp: Span,
- expr: P<ast::Expr>) -> ast::Stmt {
+fn stmt_let_undescore(cx: &mut ExtCtxt, sp: Span, expr: P<ast::Expr>) -> ast::Stmt {
let local = P(ast::Local {
pat: cx.pat_wild(sp),
ty: None,
use deriving::generic::ty::*;
use syntax::ast;
-use syntax::ast::{MetaItem, Expr, Mutability};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{Expr, MetaItem, Mutability};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::parse::token;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
expand_deriving_decodable_imp(cx, span, mitem, item, push, "rustc_serialize")
}
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize")
}
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable),
- krate: &'static str)
-{
+ krate: &'static str) {
if cx.crate_root != Some("std") {
// FIXME(#21880): lift this requirement.
- cx.span_err(span, "this trait cannot be derived with #![no_std] \
+ cx.span_err(span,
+ "this trait cannot be derived with #![no_std] \
or #![no_core]");
- return
+ return;
}
let typaram = &*deriving::hygienic_type_parameter(item, "__D");
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
- path: Path::new_(vec!(krate, "Decodable"), None, vec!(), true),
+ path: Path::new_(vec![krate, "Decodable"], None, vec![], true),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec!(
- MethodDef {
- name: "decode",
- generics: LifetimeBounds {
- lifetimes: Vec::new(),
- bounds: vec![(typaram,
- vec![Path::new_(vec!(krate, "Decoder"), None, vec!(), true)])]
- },
- explicit_self: None,
- args: vec!(Ptr(Box::new(Literal(Path::new_local(typaram))),
- Borrowed(None, Mutability::Mutable))),
- ret_ty: Literal(Path::new_(
- pathvec_std!(cx, core::result::Result),
- None,
- vec!(Box::new(Self_), Box::new(Literal(Path::new_(
+ methods: vec![MethodDef {
+ name: "decode",
+ generics: LifetimeBounds {
+ lifetimes: Vec::new(),
+ bounds: vec![(typaram,
+ vec![Path::new_(vec![krate, "Decoder"],
+ None,
+ vec![],
+ true)])],
+ },
+ explicit_self: None,
+ args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
+ Borrowed(None, Mutability::Mutable))],
+ ret_ty:
+ Literal(Path::new_(pathvec_std!(cx, core::result::Result),
+ None,
+ vec!(Box::new(Self_), Box::new(Literal(Path::new_(
vec![typaram, "Error"], None, vec![], false
)))),
- true
- )),
- attributes: Vec::new(),
- is_unsafe: false,
- unify_fieldless_variants: false,
- combine_substructure: combine_substructure(Box::new(|a, b, c| {
- decodable_substructure(a, b, c, krate)
- })),
- }
- ),
+ true)),
+ attributes: Vec::new(),
+ is_unsafe: false,
+ unify_fieldless_variants: false,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
+ decodable_substructure(a, b, c, krate)
+ })),
+ }],
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
}
-fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
+fn decodable_substructure(cx: &mut ExtCtxt,
+ trait_span: Span,
substr: &Substructure,
- krate: &str) -> P<Expr> {
+ krate: &str)
+ -> P<Expr> {
let decoder = substr.nonself_args[0].clone();
- let recurse = vec!(cx.ident_of(krate),
- cx.ident_of("Decodable"),
- cx.ident_of("decode"));
+ let recurse = vec![cx.ident_of(krate), cx.ident_of("Decodable"), cx.ident_of("decode")];
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
// throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_d");
StaticStruct(_, ref summary) => {
let nfields = match *summary {
Unnamed(ref fields) => fields.len(),
- Named(ref fields) => fields.len()
+ Named(ref fields) => fields.len(),
};
let read_struct_field = cx.ident_of("read_struct_field");
let path = cx.path_ident(trait_span, substr.type_ident);
- let result = decode_static_fields(cx,
- trait_span,
- path,
- summary,
- |cx, span, name, field| {
- cx.expr_try(span,
- cx.expr_method_call(span, blkdecoder.clone(), read_struct_field,
- vec!(cx.expr_str(span, name),
- cx.expr_usize(span, field),
- exprdecode.clone())))
- });
+ let result =
+ decode_static_fields(cx, trait_span, path, summary, |cx, span, name, field| {
+ cx.expr_try(span,
+ cx.expr_method_call(span,
+ blkdecoder.clone(),
+ read_struct_field,
+ vec![cx.expr_str(span, name),
+ cx.expr_usize(span, field),
+ exprdecode.clone()]))
+ });
let result = cx.expr_ok(trait_span, result);
cx.expr_method_call(trait_span,
decoder,
cx.ident_of("read_struct"),
- vec!(
- cx.expr_str(trait_span, substr.type_ident.name.as_str()),
- cx.expr_usize(trait_span, nfields),
- cx.lambda_expr_1(trait_span, result, blkarg)
- ))
+ vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()),
+ cx.expr_usize(trait_span, nfields),
+ cx.lambda_expr_1(trait_span, result, blkarg)])
}
StaticEnum(_, ref fields) => {
let variant = cx.ident_of("i");
variants.push(cx.expr_str(v_span, ident.name.as_str()));
let path = cx.path(trait_span, vec![substr.type_ident, ident]);
- let decoded = decode_static_fields(cx,
- v_span,
- path,
- parts,
- |cx, span, _, field| {
+ let decoded = decode_static_fields(cx, v_span, path, parts, |cx, span, _, field| {
let idx = cx.expr_usize(span, field);
cx.expr_try(span,
- cx.expr_method_call(span, blkdecoder.clone(), rvariant_arg,
- vec!(idx, exprdecode.clone())))
+ cx.expr_method_call(span,
+ blkdecoder.clone(),
+ rvariant_arg,
+ vec![idx, exprdecode.clone()]))
});
arms.push(cx.arm(v_span,
- vec!(cx.pat_lit(v_span, cx.expr_usize(v_span, i))),
+ vec![cx.pat_lit(v_span, cx.expr_usize(v_span, i))],
decoded));
}
arms.push(cx.arm_unreachable(trait_span));
- let result = cx.expr_ok(trait_span,
- cx.expr_match(trait_span,
- cx.expr_ident(trait_span, variant), arms));
- let lambda = cx.lambda_expr(trait_span, vec!(blkarg, variant), result);
+ let result =
+ cx.expr_ok(trait_span,
+ cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms));
+ let lambda = cx.lambda_expr(trait_span, vec![blkarg, variant], result);
let variant_vec = cx.expr_vec(trait_span, variants);
let variant_vec = cx.expr_addr_of(trait_span, variant_vec);
- let result = cx.expr_method_call(trait_span, blkdecoder,
+ let result = cx.expr_method_call(trait_span,
+ blkdecoder,
cx.ident_of("read_enum_variant"),
- vec!(variant_vec, lambda));
+ vec![variant_vec, lambda]);
cx.expr_method_call(trait_span,
decoder,
cx.ident_of("read_enum"),
- vec!(
- cx.expr_str(trait_span, substr.type_ident.name.as_str()),
- cx.lambda_expr_1(trait_span, result, blkarg)
- ))
+ vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()),
+ cx.lambda_expr_1(trait_span, result, blkarg)])
}
- _ => cx.bug("expected StaticEnum or StaticStruct in derive(Decodable)")
+ _ => cx.bug("expected StaticEnum or StaticStruct in derive(Decodable)"),
};
}
outer_pat_path: ast::Path,
fields: &StaticFields,
mut getarg: F)
- -> P<Expr> where
- F: FnMut(&mut ExtCtxt, Span, InternedString, usize) -> P<Expr>,
+ -> P<Expr>
+ where F: FnMut(&mut ExtCtxt, Span, InternedString, usize) -> P<Expr>
{
match *fields {
Unnamed(ref fields) => {
if fields.is_empty() {
path_expr
} else {
- let fields = fields.iter().enumerate().map(|(i, &span)| {
- getarg(cx, span,
- token::intern_and_get_ident(&format!("_field{}", i)),
- i)
- }).collect();
+ let fields = fields.iter()
+ .enumerate()
+ .map(|(i, &span)| {
+ getarg(cx,
+ span,
+ token::intern_and_get_ident(&format!("_field{}", i)),
+ i)
+ })
+ .collect();
cx.expr_call(trait_span, path_expr, fields)
}
}
Named(ref fields) => {
// use the field's span to get nicer error messages.
- let fields = fields.iter().enumerate().map(|(i, &(ident, span))| {
- let arg = getarg(cx, span, ident.name.as_str(), i);
- cx.field_imm(span, ident, arg)
- }).collect();
+ let fields = fields.iter()
+ .enumerate()
+ .map(|(i, &(ident, span))| {
+ let arg = getarg(cx, span, ident.name.as_str(), i);
+ cx.field_imm(span, ident, arg)
+ })
+ .collect();
cx.expr_struct(trait_span, outer_pat_path, fields)
}
}
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
let inline = cx.meta_word(span, InternedString::new("inline"));
- let attrs = vec!(cx.attribute(span, inline));
+ let attrs = vec![cx.attribute(span, inline)];
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec!(
- MethodDef {
- name: "default",
- generics: LifetimeBounds::empty(),
- explicit_self: None,
- args: Vec::new(),
- ret_ty: Self_,
- attributes: attrs,
- is_unsafe: false,
- unify_fieldless_variants: false,
- combine_substructure: combine_substructure(Box::new(|a, b, c| {
- default_substructure(a, b, c)
- }))
- }
- ),
+ methods: vec![MethodDef {
+ name: "default",
+ generics: LifetimeBounds::empty(),
+ explicit_self: None,
+ args: Vec::new(),
+ ret_ty: Self_,
+ attributes: attrs,
+ is_unsafe: false,
+ unify_fieldless_variants: false,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
+ default_substructure(a, b, c)
+ })),
+ }],
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
}
}
Named(ref fields) => {
- let default_fields = fields.iter().map(|&(ident, span)| {
- cx.field_imm(span, ident, default_call(span))
- }).collect();
+ let default_fields = fields.iter()
+ .map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
+ .collect();
cx.expr_struct_ident(trait_span, substr.type_ident, default_fields)
}
}
}
StaticEnum(..) => {
- cx.span_err(trait_span, "`Default` cannot be derived for enums, only structs");
+ cx.span_err(trait_span,
+ "`Default` cannot be derived for enums, only structs");
// let compilation continue
cx.expr_usize(trait_span, 0)
}
- _ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`")
+ _ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`"),
};
}
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr, ExprKind, Mutability};
-use syntax::ext::base::{ExtCtxt,Annotatable};
+use syntax::ast::{Expr, ExprKind, MetaItem, Mutability};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::ptr::P;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
expand_deriving_encodable_imp(cx, span, mitem, item, push, "rustc_serialize")
}
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize")
}
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable),
- krate: &'static str)
-{
+ krate: &'static str) {
if cx.crate_root != Some("std") {
// FIXME(#21880): lift this requirement.
- cx.span_err(span, "this trait cannot be derived with #![no_std] \
+ cx.span_err(span,
+ "this trait cannot be derived with #![no_std] \
or #![no_core]");
return;
}
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
- path: Path::new_(vec!(krate, "Encodable"), None, vec!(), true),
+ path: Path::new_(vec![krate, "Encodable"], None, vec![], true),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
trait_def.expand(cx, mitem, item, push)
}
-fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
- substr: &Substructure, krate: &'static str) -> P<Expr> {
+fn encodable_substructure(cx: &mut ExtCtxt,
+ trait_span: Span,
+ substr: &Substructure,
+ krate: &'static str)
+ -> P<Expr> {
let encoder = substr.nonself_args[0].clone();
// throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_e");
let blkencoder = cx.expr_ident(trait_span, blkarg);
- let fn_path = cx.expr_path(cx.path_global(trait_span, vec![cx.ident_of(krate),
- cx.ident_of("Encodable"),
- cx.ident_of("encode")]));
+ let fn_path = cx.expr_path(cx.path_global(trait_span,
+ vec![cx.ident_of(krate),
+ cx.ident_of("Encodable"),
+ cx.ident_of("encode")]));
return match *substr.fields {
Struct(_, ref fields) => {
let emit_struct_field = cx.ident_of("emit_struct_field");
let mut stmts = Vec::new();
- for (i, &FieldInfo {
- name,
- ref self_,
- span,
- ..
- }) in fields.iter().enumerate() {
+ for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
let name = match name {
Some(id) => id.name.as_str(),
- None => {
- token::intern_and_get_ident(&format!("_field{}", i))
- }
+ None => token::intern_and_get_ident(&format!("_field{}", i)),
};
let self_ref = cx.expr_addr_of(span, self_.clone());
let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
let lambda = cx.lambda_expr_1(span, enc, blkarg);
- let call = cx.expr_method_call(span, blkencoder.clone(),
+ let call = cx.expr_method_call(span,
+ blkencoder.clone(),
emit_struct_field,
- vec!(cx.expr_str(span, name),
- cx.expr_usize(span, i),
- lambda));
+ vec![cx.expr_str(span, name),
+ cx.expr_usize(span, i),
+ lambda]);
// last call doesn't need a try!
let last = fields.len() - 1;
cx.expr_method_call(trait_span,
encoder,
cx.ident_of("emit_struct"),
- vec!(
- cx.expr_str(trait_span, substr.type_ident.name.as_str()),
- cx.expr_usize(trait_span, fields.len()),
- blk
- ))
+ vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()),
+ cx.expr_usize(trait_span, fields.len()),
+ blk])
}
EnumMatching(idx, variant, ref fields) => {
if !fields.is_empty() {
let last = fields.len() - 1;
for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
- let self_ref = cx.expr_addr_of(span, self_.clone());
- let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref,
- blkencoder.clone()]);
+ let self_ref = cx.expr_addr_of(span, self_.clone());
+ let enc =
+ cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
let lambda = cx.lambda_expr_1(span, enc, blkarg);
- let call = cx.expr_method_call(span, blkencoder.clone(),
+ let call = cx.expr_method_call(span,
+ blkencoder.clone(),
emit_variant_arg,
- vec!(cx.expr_usize(span, i),
- lambda));
+ vec![cx.expr_usize(span, i), lambda]);
let call = if i != last {
cx.expr_try(span, call)
} else {
let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
let name = cx.expr_str(trait_span, variant.node.name.name.as_str());
- let call = cx.expr_method_call(trait_span, blkencoder,
+ let call = cx.expr_method_call(trait_span,
+ blkencoder,
cx.ident_of("emit_enum_variant"),
- vec!(name,
- cx.expr_usize(trait_span, idx),
- cx.expr_usize(trait_span, fields.len()),
- blk));
+ vec![name,
+ cx.expr_usize(trait_span, idx),
+ cx.expr_usize(trait_span, fields.len()),
+ blk]);
let blk = cx.lambda_expr_1(trait_span, call, blkarg);
let ret = cx.expr_method_call(trait_span,
encoder,
cx.ident_of("emit_enum"),
- vec!(
- cx.expr_str(trait_span, substr.type_ident.name.as_str()),
- blk
- ));
+ vec![cx.expr_str(trait_span,
+ substr.type_ident.name.as_str()),
+ blk]);
cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
}
- _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)")
+ _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),
};
}
use std::vec;
use syntax::abi::Abi;
-use syntax::ast::{self, EnumDef, Expr, Ident, Generics, VariantData, BinOpKind, PatKind};
+use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind, VariantData};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::codemap::{self, respan};
use syntax::util::move_map::MoveMap;
-use syntax::parse::token::{keywords, InternedString};
+use syntax::parse::token::{InternedString, keywords};
use syntax::ptr::P;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::{DUMMY_SP, Span};
use errors::Handler;
use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
pub self_args: &'a [P<Expr>],
/// verbatim access to any other arguments
pub nonself_args: &'a [P<Expr>],
- pub fields: &'a SubstructureFields<'a>
+ pub fields: &'a SubstructureFields<'a>,
}
/// Summary of the relevant parts of a struct/enum field.
Box<FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
- -> RefCell<CombineSubstructureFunc<'a>> {
+ -> RefCell<CombineSubstructureFunc<'a>> {
RefCell::new(f)
}
/// This method helps to extract all the type parameters referenced from a
/// type. For a type parameter `<T>`, it looks for either a `TyPath` that
/// is not global and starts with `T`, or a `TyQPath`.
-fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name], span: Span, cx: &ExtCtxt)
+fn find_type_parameters(ty: &ast::Ty,
+ ty_param_names: &[ast::Name],
+ span: Span,
+ cx: &ExtCtxt)
-> Vec<P<ast::Ty>> {
use syntax::visit;
cx: &mut ExtCtxt,
mitem: &ast::MetaItem,
item: &'a Annotatable,
- push: &mut FnMut(Annotatable))
- {
+ push: &mut FnMut(Annotatable)) {
match *item {
Annotatable::Item(ref item) => {
let newitem = match item.node {
ast::ItemKind::Struct(ref struct_def, ref generics) => {
- self.expand_struct_def(cx,
- &struct_def,
- item.ident,
- generics)
+ self.expand_struct_def(cx, &struct_def, item.ident, generics)
}
ast::ItemKind::Enum(ref enum_def, ref generics) => {
- self.expand_enum_def(cx,
- enum_def,
- &item.attrs,
- item.ident,
- generics)
+ self.expand_enum_def(cx, enum_def, &item.attrs, item.ident, generics)
}
_ => {
cx.span_err(mitem.span,
// Keep the lint attributes of the previous item to control how the
// generated implementations are linted
let mut attrs = newitem.attrs.clone();
- attrs.extend(item.attrs.iter().filter(|a| {
- match &a.name()[..] {
- "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
- _ => false,
- }
- }).cloned());
- push(Annotatable::Item(P(ast::Item {
- attrs: attrs,
- ..(*newitem).clone()
- })))
+ attrs.extend(item.attrs
+ .iter()
+ .filter(|a| {
+ match &a.name()[..] {
+ "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
+ _ => false,
+ }
+ })
+ .cloned());
+ push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
}
_ => {
- cx.span_err(mitem.span, "`derive` may only be applied to structs and enums");
+ cx.span_err(mitem.span,
+ "`derive` may only be applied to structs and enums");
}
}
}
type_ident: Ident,
generics: &Generics,
field_tys: Vec<P<ast::Ty>>,
- methods: Vec<ast::ImplItem>) -> P<ast::Item> {
+ methods: Vec<ast::ImplItem>)
+ -> P<ast::Item> {
let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
// Transform associated types from `deriving::ty::Ty` into `ast::ImplItem`
vis: ast::Visibility::Inherited,
defaultness: ast::Defaultness::Final,
attrs: Vec::new(),
- node: ast::ImplItemKind::Type(type_def.to_ty(cx,
- self.span,
- type_ident,
- generics
- )),
+ node: ast::ImplItemKind::Type(type_def.to_ty(cx, self.span, type_ident, generics)),
}
});
- let Generics { mut lifetimes, ty_params, mut where_clause } =
- self.generics.to_generics(cx, self.span, type_ident, generics);
+ let Generics { mut lifetimes, ty_params, mut where_clause } = self.generics
+ .to_generics(cx, self.span, type_ident, generics);
let mut ty_params = ty_params.into_vec();
// Copy the lifetimes
bounds.push((*declared_bound).clone());
}
- cx.typaram(self.span,
- ty_param.ident,
- P::from_vec(bounds),
- None)
+ cx.typaram(self.span, ty_param.ident, P::from_vec(bounds), None)
}));
// and similarly for where clauses
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
span: self.span,
lifetime: rb.lifetime,
- bounds: rb.bounds.iter().cloned().collect()
+ bounds: rb.bounds.iter().cloned().collect(),
})
}
ast::WherePredicate::EqPredicate(ref we) => {
id: ast::DUMMY_NODE_ID,
span: self.span,
path: we.path.clone(),
- ty: we.ty.clone()
+ ty: we.ty.clone(),
})
}
}
for ty in tys {
// if we have already handled this type, skip it
if let ast::TyKind::Path(_, ref p) = ty.node {
- if p.segments.len() == 1
- && ty_param_names.contains(&p.segments[0].identifier.name)
- || processed_field_types.contains(&p.segments) {
+ if p.segments.len() == 1 &&
+ ty_param_names.contains(&p.segments[0].identifier.name) ||
+ processed_field_types.contains(&p.segments) {
continue;
};
processed_field_types.insert(p.segments.clone());
}
- let mut bounds: Vec<_> = self.additional_bounds.iter().map(|p| {
- cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
- }).collect();
+ let mut bounds: Vec<_> = self.additional_bounds
+ .iter()
+ .map(|p| cx.typarambound(p.to_path(cx, self.span, type_ident, generics)))
+ .collect();
// require the current trait
bounds.push(cx.typarambound(trait_path.clone()));
let trait_generics = Generics {
lifetimes: lifetimes,
ty_params: P::from_vec(ty_params),
- where_clause: where_clause
+ where_clause: where_clause,
};
// Create the reference to the trait.
let trait_ref = cx.trait_ref(trait_path);
// Create the type parameters on the `self` path.
- let self_ty_params = generics.ty_params.iter().map(|ty_param| {
- cx.ty_ident(self.span, ty_param.ident)
- }).collect();
+ let self_ty_params = generics.ty_params
+ .iter()
+ .map(|ty_param| cx.ty_ident(self.span, ty_param.ident))
+ .collect();
- let self_lifetimes: Vec<ast::Lifetime> =
- generics.lifetimes
+ let self_lifetimes: Vec<ast::Lifetime> = generics.lifetimes
.iter()
.map(|ld| ld.lifetime)
.collect();
// Create the type of `self`.
- let self_type = cx.ty_path(
- cx.path_all(self.span, false, vec!( type_ident ), self_lifetimes,
- self_ty_params, Vec::new()));
-
- let attr = cx.attribute(
- self.span,
- cx.meta_word(self.span,
- InternedString::new("automatically_derived")));
+ let self_type = cx.ty_path(cx.path_all(self.span,
+ false,
+ vec![type_ident],
+ self_lifetimes,
+ self_ty_params,
+ Vec::new()));
+
+ let attr = cx.attribute(self.span,
+ cx.meta_word(self.span,
+ InternedString::new("automatically_derived")));
// Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr);
let opt_trait_ref = Some(trait_ref);
- let unused_qual = cx.attribute(
- self.span,
- cx.meta_list(self.span,
- InternedString::new("allow"),
- vec![cx.meta_word(self.span,
+ let unused_qual = cx.attribute(self.span,
+ cx.meta_list(self.span,
+ InternedString::new("allow"),
+ vec![cx.meta_word(self.span,
InternedString::new("unused_qualifications"))]));
let mut a = vec![attr, unused_qual];
a.extend(self.attributes.iter().cloned());
ast::Unsafety::Normal
};
- cx.item(
- self.span,
- keywords::Invalid.ident(),
- a,
- ast::ItemKind::Impl(unsafety,
- ast::ImplPolarity::Positive,
- trait_generics,
- opt_trait_ref,
- self_type,
- methods.into_iter().chain(associated_types).collect()))
+ cx.item(self.span,
+ keywords::Invalid.ident(),
+ a,
+ ast::ItemKind::Impl(unsafety,
+ ast::ImplPolarity::Positive,
+ trait_generics,
+ opt_trait_ref,
+ self_type,
+ methods.into_iter().chain(associated_types).collect()))
}
fn expand_struct_def(&self,
cx: &mut ExtCtxt,
struct_def: &'a VariantData,
type_ident: Ident,
- generics: &Generics) -> P<ast::Item> {
- let field_tys: Vec<P<ast::Ty>> = struct_def.fields().iter()
+ generics: &Generics)
+ -> P<ast::Item> {
+ let field_tys: Vec<P<ast::Ty>> = struct_def.fields()
+ .iter()
.map(|field| field.ty.clone())
.collect();
- let methods = self.methods.iter().map(|method_def| {
- let (explicit_self, self_args, nonself_args, tys) =
- method_def.split_self_nonself_args(
- cx, self, type_ident, generics);
-
- let body = if method_def.is_static() {
- method_def.expand_static_struct_method_body(
- cx,
- self,
- struct_def,
- type_ident,
- &self_args[..],
- &nonself_args[..])
- } else {
- method_def.expand_struct_method_body(cx,
- self,
- struct_def,
- type_ident,
- &self_args[..],
- &nonself_args[..])
- };
-
- method_def.create_method(cx,
- self,
- type_ident,
- generics,
- Abi::Rust,
- explicit_self,
- tys,
- body)
- }).collect();
+ let methods = self.methods
+ .iter()
+ .map(|method_def| {
+ let (explicit_self, self_args, nonself_args, tys) =
+ method_def.split_self_nonself_args(cx, self, type_ident, generics);
+
+ let body = if method_def.is_static() {
+ method_def.expand_static_struct_method_body(cx,
+ self,
+ struct_def,
+ type_ident,
+ &self_args[..],
+ &nonself_args[..])
+ } else {
+ method_def.expand_struct_method_body(cx,
+ self,
+ struct_def,
+ type_ident,
+ &self_args[..],
+ &nonself_args[..])
+ };
+
+ method_def.create_method(cx,
+ self,
+ type_ident,
+ generics,
+ Abi::Rust,
+ explicit_self,
+ tys,
+ body)
+ })
+ .collect();
self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
}
enum_def: &'a EnumDef,
type_attrs: &[ast::Attribute],
type_ident: Ident,
- generics: &Generics) -> P<ast::Item> {
+ generics: &Generics)
+ -> P<ast::Item> {
let mut field_tys = Vec::new();
for variant in &enum_def.variants {
- field_tys.extend(variant.node.data.fields().iter()
+ field_tys.extend(variant.node
+ .data
+ .fields()
+ .iter()
.map(|field| field.ty.clone()));
}
- let methods = self.methods.iter().map(|method_def| {
- let (explicit_self, self_args, nonself_args, tys) =
- method_def.split_self_nonself_args(cx, self,
- type_ident, generics);
-
- let body = if method_def.is_static() {
- method_def.expand_static_enum_method_body(
- cx,
- self,
- enum_def,
- type_ident,
- &self_args[..],
- &nonself_args[..])
- } else {
- method_def.expand_enum_method_body(cx,
- self,
- enum_def,
- type_attrs,
- type_ident,
- self_args,
- &nonself_args[..])
- };
-
- method_def.create_method(cx,
- self,
- type_ident,
- generics,
- Abi::Rust,
- explicit_self,
- tys,
- body)
- }).collect();
+ let methods = self.methods
+ .iter()
+ .map(|method_def| {
+ let (explicit_self, self_args, nonself_args, tys) =
+ method_def.split_self_nonself_args(cx, self, type_ident, generics);
+
+ let body = if method_def.is_static() {
+ method_def.expand_static_enum_method_body(cx,
+ self,
+ enum_def,
+ type_ident,
+ &self_args[..],
+ &nonself_args[..])
+ } else {
+ method_def.expand_enum_method_body(cx,
+ self,
+ enum_def,
+ type_attrs,
+ type_ident,
+ self_args,
+ &nonself_args[..])
+ };
+
+ method_def.create_method(cx,
+ self,
+ type_ident,
+ generics,
+ Abi::Rust,
+ explicit_self,
+ tys,
+ body)
+ })
+ .collect();
self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
}
}
-fn find_repr_type_name(diagnostic: &Handler,
- type_attrs: &[ast::Attribute]) -> &'static str {
+fn find_repr_type_name(diagnostic: &Handler, type_attrs: &[ast::Attribute]) -> &'static str {
let mut repr_type_name = "isize";
for a in type_attrs {
for r in &attr::find_repr_attrs(diagnostic, a) {
self_args: &[P<Expr>],
nonself_args: &[P<Expr>],
fields: &SubstructureFields)
- -> P<Expr> {
+ -> P<Expr> {
let substructure = Substructure {
type_ident: type_ident,
method_ident: cx.ident_of(self.name),
self_args: self_args,
nonself_args: nonself_args,
- fields: fields
+ fields: fields,
};
let mut f = self.combine_substructure.borrow_mut();
let f: &mut CombineSubstructureFunc = &mut *f;
self.explicit_self.is_none()
}
- fn split_self_nonself_args(&self,
- cx: &mut ExtCtxt,
- trait_: &TraitDef,
- type_ident: Ident,
- generics: &Generics)
- -> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
+ fn split_self_nonself_args
+ (&self,
+ cx: &mut ExtCtxt,
+ trait_: &TraitDef,
+ type_ident: Ident,
+ generics: &Generics)
+ -> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
let mut self_args = Vec::new();
let mut nonself_args = Vec::new();
match *ty {
// for static methods, just treat any Self
// arguments as a normal arg
- Self_ if nonstatic => {
+ Self_ if nonstatic => {
self_args.push(arg_expr);
}
Ptr(ref ty, _) if **ty == Self_ && nonstatic => {
generics: &Generics,
abi: Abi,
explicit_self: Option<ast::ExplicitSelf>,
- arg_types: Vec<(Ident, P<ast::Ty>)> ,
- body: P<Expr>) -> ast::ImplItem {
+ arg_types: Vec<(Ident, P<ast::Ty>)>,
+ body: P<Expr>)
+ -> ast::ImplItem {
// create the generics that aren't for Self
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
let args = {
let self_args = explicit_self.map(|explicit_self| {
- ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident()))
+ ast::Arg::from_self(explicit_self,
+ respan(trait_.span, keywords::SelfValue.ident()))
});
let nonself_args = arg_types.into_iter()
- .map(|(name, ty)| cx.arg(trait_.span, name, ty));
+ .map(|(name, ty)| cx.arg(trait_.span, name, ty));
self_args.into_iter().chain(nonself_args).collect()
};
defaultness: ast::Defaultness::Final,
ident: method_ident,
node: ast::ImplItemKind::Method(ast::MethodSig {
- generics: fn_generics,
- abi: abi,
- unsafety: unsafety,
- constness: ast::Constness::NotConst,
- decl: fn_decl
- }, body_block)
+ generics: fn_generics,
+ abi: abi,
+ unsafety: unsafety,
+ constness: ast::Constness::NotConst,
+ decl: fn_decl,
+ },
+ body_block),
}
}
/// }
/// ```
fn expand_struct_method_body<'b>(&self,
- cx: &mut ExtCtxt,
- trait_: &TraitDef<'b>,
- struct_def: &'b VariantData,
- type_ident: Ident,
- self_args: &[P<Expr>],
- nonself_args: &[P<Expr>])
- -> P<Expr> {
+ cx: &mut ExtCtxt,
+ trait_: &TraitDef<'b>,
+ struct_def: &'b VariantData,
+ type_ident: Ident,
+ self_args: &[P<Expr>],
+ nonself_args: &[P<Expr>])
+ -> P<Expr> {
let mut raw_fields = Vec::new(); // Vec<[fields of self],
// [fields of next Self arg], [etc]>
let mut patterns = Vec::new();
for i in 0..self_args.len() {
- let struct_path= cx.path(DUMMY_SP, vec!( type_ident ));
- let (pat, ident_expr) =
- trait_.create_struct_pattern(cx,
- struct_path,
- struct_def,
- &format!("__self_{}",
- i),
- ast::Mutability::Immutable);
+ let struct_path = cx.path(DUMMY_SP, vec![type_ident]);
+ let (pat, ident_expr) = trait_.create_struct_pattern(cx,
+ struct_path,
+ struct_def,
+ &format!("__self_{}", i),
+ ast::Mutability::Immutable);
patterns.push(pat);
raw_fields.push(ident_expr);
}
let fields = if !raw_fields.is_empty() {
let mut raw_fields = raw_fields.into_iter().map(|v| v.into_iter());
let first_field = raw_fields.next().unwrap();
- let mut other_fields: Vec<vec::IntoIter<_>>
- = raw_fields.collect();
+ let mut other_fields: Vec<vec::IntoIter<_>> = raw_fields.collect();
first_field.map(|(span, opt_id, field, attrs)| {
- FieldInfo {
- span: span,
- name: opt_id,
- self_: field,
- other: other_fields.iter_mut().map(|l| {
- match l.next().unwrap() {
- (_, _, ex, _) => ex
- }
- }).collect(),
- attrs: attrs,
- }
- }).collect()
+ FieldInfo {
+ span: span,
+ name: opt_id,
+ self_: field,
+ other: other_fields.iter_mut()
+ .map(|l| {
+ match l.next().unwrap() {
+ (_, _, ex, _) => ex,
+ }
+ })
+ .collect(),
+ attrs: attrs,
+ }
+ })
+ .collect()
} else {
cx.span_bug(trait_.span,
"no self arguments to non-static method in generic \
};
// body of the inner most destructuring match
- let mut body = self.call_substructure_method(
- cx,
- trait_,
- type_ident,
- self_args,
- nonself_args,
- &Struct(struct_def, fields));
+ let mut body = self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ self_args,
+ nonself_args,
+ &Struct(struct_def, fields));
// make a series of nested matches, to destructure the
// structs. This is actually right-to-left, but it shouldn't
// matter.
for (arg_expr, pat) in self_args.iter().zip(patterns) {
- body = cx.expr_match(trait_.span, arg_expr.clone(),
- vec!( cx.arm(trait_.span, vec!(pat.clone()), body) ))
+ body = cx.expr_match(trait_.span,
+ arg_expr.clone(),
+ vec![cx.arm(trait_.span, vec![pat.clone()], body)])
}
body
type_ident: Ident,
self_args: &[P<Expr>],
nonself_args: &[P<Expr>])
- -> P<Expr> {
+ -> P<Expr> {
let summary = trait_.summarise_struct(cx, struct_def);
self.call_substructure_method(cx,
trait_,
type_ident,
- self_args, nonself_args,
+ self_args,
+ nonself_args,
&StaticStruct(struct_def, summary))
}
/// as their results are unused. The point of `__self_vi` and
/// `__arg_1_vi` is for `PartialOrd`; see #15503.)
fn expand_enum_method_body<'b>(&self,
- cx: &mut ExtCtxt,
- trait_: &TraitDef<'b>,
- enum_def: &'b EnumDef,
- type_attrs: &[ast::Attribute],
- type_ident: Ident,
- self_args: Vec<P<Expr>>,
- nonself_args: &[P<Expr>])
- -> P<Expr> {
- self.build_enum_match_tuple(
- cx, trait_, enum_def, type_attrs, type_ident, self_args, nonself_args)
+ cx: &mut ExtCtxt,
+ trait_: &TraitDef<'b>,
+ enum_def: &'b EnumDef,
+ type_attrs: &[ast::Attribute],
+ type_ident: Ident,
+ self_args: Vec<P<Expr>>,
+ nonself_args: &[P<Expr>])
+ -> P<Expr> {
+ self.build_enum_match_tuple(cx,
+ trait_,
+ enum_def,
+ type_attrs,
+ type_ident,
+ self_args,
+ nonself_args)
}
/// ... // catch-all remainder can inspect above variant index values.
/// }
/// ```
- fn build_enum_match_tuple<'b>(
- &self,
- cx: &mut ExtCtxt,
- trait_: &TraitDef<'b>,
- enum_def: &'b EnumDef,
- type_attrs: &[ast::Attribute],
- type_ident: Ident,
- self_args: Vec<P<Expr>>,
- nonself_args: &[P<Expr>]) -> P<Expr> {
+ fn build_enum_match_tuple<'b>(&self,
+ cx: &mut ExtCtxt,
+ trait_: &TraitDef<'b>,
+ enum_def: &'b EnumDef,
+ type_attrs: &[ast::Attribute],
+ type_ident: Ident,
+ self_args: Vec<P<Expr>>,
+ nonself_args: &[P<Expr>])
+ -> P<Expr> {
let sp = trait_.span;
let variants = &enum_def.variants;
- let self_arg_names = self_args.iter().enumerate()
+ let self_arg_names = self_args.iter()
+ .enumerate()
.map(|(arg_count, _self_arg)| {
if arg_count == 0 {
"__self".to_string()
.collect::<Vec<String>>();
let self_arg_idents = self_arg_names.iter()
- .map(|name|cx.ident_of(&name[..]))
+ .map(|name| cx.ident_of(&name[..]))
.collect::<Vec<ast::Ident>>();
// The `vi_idents` will be bound, solely in the catch-all, to
// a series of let statements mapping each self_arg to an int
// value corresponding to its discriminant.
let vi_idents: Vec<ast::Ident> = self_arg_names.iter()
- .map(|name| { let vi_suffix = format!("{}_vi", &name[..]);
- cx.ident_of(&vi_suffix[..]) })
+ .map(|name| {
+ let vi_suffix = format!("{}_vi", &name[..]);
+ cx.ident_of(&vi_suffix[..])
+ })
.collect::<Vec<ast::Ident>>();
// Builds, via callback to call_substructure_method, the
// delegated expression that handles the catch-all case,
// using `__variants_tuple` to drive logic if necessary.
- let catch_all_substructure = EnumNonMatchingCollapsed(
- self_arg_idents, &variants[..], &vi_idents[..]);
+ let catch_all_substructure =
+ EnumNonMatchingCollapsed(self_arg_idents, &variants[..], &vi_idents[..]);
let first_fieldless = variants.iter().find(|v| v.node.data.fields().is_empty());
// (Variant2, Variant2, ...) => Body2
// ...
// where each tuple has length = self_args.len()
- let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
+ let mut match_arms: Vec<ast::Arm> = variants.iter()
+ .enumerate()
.filter(|&(_, v)| !(self.unify_fieldless_variants && v.node.data.fields().is_empty()))
.map(|(index, variant)| {
let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| {
- let (p, idents) = trait_.create_enum_variant_pattern(
- cx, type_ident,
- variant,
- self_arg_name,
- ast::Mutability::Immutable);
+ let (p, idents) = trait_.create_enum_variant_pattern(cx,
+ type_ident,
+ variant,
+ self_arg_name,
+ ast::Mutability::Immutable);
(cx.pat(sp, PatKind::Ref(p, ast::Mutability::Immutable)), idents)
};
// expressions for referencing every field of every
// Self arg, assuming all are instances of VariantK.
// Build up code associated with such a case.
- let substructure = EnumMatching(index,
- variant,
- field_tuples);
- let arm_expr = self.call_substructure_method(
- cx, trait_, type_ident, &self_args[..], nonself_args,
- &substructure);
+ let substructure = EnumMatching(index, variant, field_tuples);
+ let arm_expr = self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ &self_args[..],
+ nonself_args,
+ &substructure);
cx.arm(sp, vec![single_pat], arm_expr)
- }).collect();
+ })
+ .collect();
let default = match first_fieldless {
Some(v) if self.unify_fieldless_variants => {
// We need a default case that handles the fieldless variants.
// The index and actual variant aren't meaningful in this case,
// so just use whatever
- Some(self.call_substructure_method(
- cx, trait_, type_ident, &self_args[..], nonself_args,
- &EnumMatching(0, v, Vec::new())))
+ Some(self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ &self_args[..],
+ nonself_args,
+ &EnumMatching(0, v, Vec::new())))
}
_ if variants.len() > 1 && self_args.len() > 1 => {
// Since we know that all the arguments will match if we reach
// result of the catch all which should help llvm in optimizing it
Some(deriving::call_intrinsic(cx, sp, "unreachable", vec![]))
}
- _ => None
+ _ => None,
};
if let Some(arm) = default {
match_arms.push(cx.arm(sp, vec![cx.pat_wild(sp)], arm));
// ```
let mut index_let_stmts: Vec<ast::Stmt> = Vec::new();
- //We also build an expression which checks whether all discriminants are equal
+ // We also build an expression which checks whether all discriminants are equal
// discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
let mut discriminant_test = cx.expr_bool(sp, true);
- let target_type_name =
- find_repr_type_name(&cx.parse_sess.span_diagnostic, type_attrs);
+ let target_type_name = find_repr_type_name(&cx.parse_sess.span_diagnostic, type_attrs);
let mut first_ident = None;
for (&ident, self_arg) in vi_idents.iter().zip(&self_args) {
let self_addr = cx.expr_addr_of(sp, self_arg.clone());
- let variant_value = deriving::call_intrinsic(cx,
- sp,
- "discriminant_value",
- vec![self_addr]);
+ let variant_value =
+ deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name));
let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
let first_expr = cx.expr_ident(sp, first);
let id = cx.expr_ident(sp, ident);
let test = cx.expr_binary(sp, BinOpKind::Eq, first_expr, id);
- discriminant_test = cx.expr_binary(sp, BinOpKind::And,
- discriminant_test, test)
+ discriminant_test =
+ cx.expr_binary(sp, BinOpKind::And, discriminant_test, test)
}
None => {
first_ident = Some(ident);
}
}
- let arm_expr = self.call_substructure_method(
- cx, trait_, type_ident, &self_args[..], nonself_args,
- &catch_all_substructure);
+ let arm_expr = self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ &self_args[..],
+ nonself_args,
+ &catch_all_substructure);
// Final wrinkle: the self_args are expressions that deref
// down to desired l-values, but we cannot actually deref
let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg));
let match_arg = cx.expr(sp, ast::ExprKind::Tup(borrowed_self_args));
- //Lastly we create an expression which branches on all discriminants being equal
+ // Lastly we create an expression which branches on all discriminants being equal
// if discriminant_test {
// match (...) {
// (Variant1, Variant1, ...) => Body1
// that needs the feature gate enabled.)
deriving::call_intrinsic(cx, sp, "unreachable", vec![])
- }
- else {
+ } else {
// Final wrinkle: the self_args are expressions that deref
// down to desired l-values, but we cannot actually deref
type_ident: Ident,
self_args: &[P<Expr>],
nonself_args: &[P<Expr>])
- -> P<Expr> {
- let summary = enum_def.variants.iter().map(|v| {
- let ident = v.node.name;
- let summary = trait_.summarise_struct(cx, &v.node.data);
- (ident, v.span, summary)
- }).collect();
- self.call_substructure_method(cx, trait_, type_ident,
- self_args, nonself_args,
+ -> P<Expr> {
+ let summary = enum_def.variants
+ .iter()
+ .map(|v| {
+ let ident = v.node.name;
+ let summary = trait_.summarise_struct(cx, &v.node.data);
+ (ident, v.span, summary)
+ })
+ .collect();
+ self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ self_args,
+ nonself_args,
&StaticEnum(enum_def, summary))
}
}
// general helper methods.
impl<'a> TraitDef<'a> {
- fn summarise_struct(&self,
- cx: &mut ExtCtxt,
- struct_def: &VariantData) -> StaticFields {
+ fn summarise_struct(&self, cx: &mut ExtCtxt, struct_def: &VariantData) -> StaticFields {
let mut named_idents = Vec::new();
let mut just_spans = Vec::new();
- for field in struct_def.fields(){
+ for field in struct_def.fields() {
let sp = Span { expn_id: self.span.expn_id, ..field.span };
match field.ident {
Some(ident) => named_idents.push((ident, sp)),
}
match (just_spans.is_empty(), named_idents.is_empty()) {
- (false, false) => cx.span_bug(self.span,
- "a struct with named and unnamed \
- fields in generic `derive`"),
+ (false, false) => {
+ cx.span_bug(self.span,
+ "a struct with named and unnamed \
+ fields in generic `derive`")
+ }
// named fields
(_, false) => Named(named_idents),
// empty structs
fn create_subpatterns(&self,
cx: &mut ExtCtxt,
- field_paths: Vec<ast::SpannedIdent> ,
+ field_paths: Vec<ast::SpannedIdent>,
mutbl: ast::Mutability)
-> Vec<P<ast::Pat>> {
- field_paths.iter().map(|path| {
- cx.pat(path.span,
- PatKind::Ident(ast::BindingMode::ByRef(mutbl), (*path).clone(), None))
- }).collect()
+ field_paths.iter()
+ .map(|path| {
+ cx.pat(path.span,
+ PatKind::Ident(ast::BindingMode::ByRef(mutbl), (*path).clone(), None))
+ })
+ .collect()
}
- fn create_struct_pattern(&self,
- cx: &mut ExtCtxt,
- struct_path: ast::Path,
- struct_def: &'a VariantData,
- prefix: &str,
- mutbl: ast::Mutability)
- -> (P<ast::Pat>, Vec<(Span, Option<Ident>,
- P<Expr>,
- &'a [ast::Attribute])>) {
+ fn create_struct_pattern
+ (&self,
+ cx: &mut ExtCtxt,
+ struct_path: ast::Path,
+ struct_def: &'a VariantData,
+ prefix: &str,
+ mutbl: ast::Mutability)
+ -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
let mut paths = Vec::new();
let mut ident_exprs = Vec::new();
for (i, struct_field) in struct_def.fields().iter().enumerate() {
let sp = Span { expn_id: self.span.expn_id, ..struct_field.span };
let ident = cx.ident_of(&format!("{}_{}", prefix, i));
- paths.push(codemap::Spanned{span: sp, node: ident});
- let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)));
+ paths.push(codemap::Spanned {
+ span: sp,
+ node: ident,
+ });
+ let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp, ident)));
let val = cx.expr(sp, ast::ExprKind::Paren(val));
ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
}
let subpats = self.create_subpatterns(cx, paths, mutbl);
let pattern = if struct_def.is_struct() {
- let field_pats = subpats.into_iter().zip(&ident_exprs).map(|(pat, &(sp, ident, _, _))| {
- if ident.is_none() {
- cx.span_bug(sp, "a braced struct with unnamed fields in `derive`");
- }
- codemap::Spanned {
- span: pat.span,
- node: ast::FieldPat { ident: ident.unwrap(), pat: pat, is_shorthand: false },
- }
- }).collect();
+ let field_pats = subpats.into_iter()
+ .zip(&ident_exprs)
+ .map(|(pat, &(sp, ident, _, _))| {
+ if ident.is_none() {
+ cx.span_bug(sp, "a braced struct with unnamed fields in `derive`");
+ }
+ codemap::Spanned {
+ span: pat.span,
+ node: ast::FieldPat {
+ ident: ident.unwrap(),
+ pat: pat,
+ is_shorthand: false,
+ },
+ }
+ })
+ .collect();
cx.pat_struct(self.span, struct_path, field_pats)
} else {
cx.pat_enum(self.span, struct_path, subpats)
(pattern, ident_exprs)
}
- fn create_enum_variant_pattern(&self,
- cx: &mut ExtCtxt,
- enum_ident: ast::Ident,
- variant: &'a ast::Variant,
- prefix: &str,
- mutbl: ast::Mutability)
- -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
+ fn create_enum_variant_pattern
+ (&self,
+ cx: &mut ExtCtxt,
+ enum_ident: ast::Ident,
+ variant: &'a ast::Variant,
+ prefix: &str,
+ mutbl: ast::Mutability)
+ -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
let variant_ident = variant.node.name;
let variant_path = cx.path(variant.span, vec![enum_ident, variant_ident]);
self.create_struct_pattern(cx, variant_path, &variant.node.data, prefix, mutbl)
}
}
-/* helpful premade recipes */
+// helpful premade recipes
/// Fold the fields. `use_foldl` controls whether this is done
/// left-to-right (`true`) or right-to-left (`false`).
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
- -> P<Expr> where
- F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
+ -> P<Expr>
+ where F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>
{
match *substructure.fields {
- EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
+ EnumMatching(_, _, ref all_fields) |
+ Struct(_, ref all_fields) => {
if use_foldl {
all_fields.iter().fold(base, |old, field| {
- f(cx,
- field.span,
- old,
- field.self_.clone(),
- &field.other)
+ f(cx, field.span, old, field.self_.clone(), &field.other)
})
} else {
all_fields.iter().rev().fold(base, |old, field| {
- f(cx,
- field.span,
- old,
- field.self_.clone(),
- &field.other)
+ f(cx, field.span, old, field.self_.clone(), &field.other)
})
}
- },
- EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
- enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple),
- substructure.nonself_args),
- StaticEnum(..) | StaticStruct(..) => {
- cx.span_bug(trait_span, "static function in `derive`")
}
+ EnumNonMatchingCollapsed(ref all_args, _, tuple) => {
+ enum_nonmatch_f(cx,
+ trait_span,
+ (&all_args[..], tuple),
+ substructure.nonself_args)
+ }
+ StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
}
}
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
- -> P<Expr> where
- F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>,
+ -> P<Expr>
+ where F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>
{
match *substructure.fields {
- EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
+ EnumMatching(_, _, ref all_fields) |
+ Struct(_, ref all_fields) => {
// call self_n.method(other_1_n, other_2_n, ...)
- let called = all_fields.iter().map(|field| {
- cx.expr_method_call(field.span,
- field.self_.clone(),
- substructure.method_ident,
- field.other.iter()
- .map(|e| cx.expr_addr_of(field.span, e.clone()))
- .collect())
- }).collect();
+ let called = all_fields.iter()
+ .map(|field| {
+ cx.expr_method_call(field.span,
+ field.self_.clone(),
+ substructure.method_ident,
+ field.other
+ .iter()
+ .map(|e| cx.expr_addr_of(field.span, e.clone()))
+ .collect())
+ })
+ .collect();
f(cx, trait_span, called)
- },
- EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
- enum_nonmatch_f(cx, trait_span, (&all_self_args[..], tuple),
- substructure.nonself_args),
- StaticEnum(..) | StaticStruct(..) => {
- cx.span_bug(trait_span, "static function in `derive`")
}
+ EnumNonMatchingCollapsed(ref all_self_args, _, tuple) => {
+ enum_nonmatch_f(cx,
+ trait_span,
+ (&all_self_args[..], tuple),
+ substructure.nonself_args)
+ }
+ StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
}
}
ast::ItemKind::Enum(ref enum_def, _) => {
enum_def.variants.iter().all(|v| v.node.data.fields().is_empty())
}
- ast::ItemKind::Struct(ref variant_data, _) => {
- variant_data.fields().is_empty()
- }
- _ => false
+ ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(),
+ _ => false,
}
} else {
false
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast::{MetaItem, Expr, Mutability};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{Expr, MetaItem, Mutability};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use syntax_pos::Span;
span: Span,
mitem: &MetaItem,
item: &Annotatable,
- push: &mut FnMut(Annotatable))
-{
+ push: &mut FnMut(Annotatable)) {
- let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
- vec!(), true);
+ let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None, vec![], true);
let typaram = &*deriving::hygienic_type_parameter(item, "__H");
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
- methods: vec!(
- MethodDef {
- name: "hash",
- generics: LifetimeBounds {
- lifetimes: Vec::new(),
- bounds: vec![(typaram,
- vec![path_std!(cx, core::hash::Hasher)])],
- },
- explicit_self: borrowed_explicit_self(),
- args: vec!(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mutable))),
- ret_ty: nil_ty(),
- attributes: vec![],
- is_unsafe: false,
- unify_fieldless_variants: true,
- combine_substructure: combine_substructure(Box::new(|a, b, c| {
- hash_substructure(a, b, c)
- }))
- }
- ),
+ methods: vec![MethodDef {
+ name: "hash",
+ generics: LifetimeBounds {
+ lifetimes: Vec::new(),
+ bounds: vec![(typaram, vec![path_std!(cx, core::hash::Hasher)])],
+ },
+ explicit_self: borrowed_explicit_self(),
+ args: vec![Ptr(Box::new(Literal(arg)),
+ Borrowed(None, Mutability::Mutable))],
+ ret_ty: nil_ty(),
+ attributes: vec![],
+ is_unsafe: false,
+ unify_fieldless_variants: true,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
+ hash_substructure(a, b, c)
+ })),
+ }],
associated_types: Vec::new(),
};
fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
let state_expr = match (substr.nonself_args.len(), substr.nonself_args.get(0)) {
(1, Some(o_f)) => o_f,
- _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`")
+ _ => {
+ cx.span_bug(trait_span,
+ "incorrect number of arguments in `derive(Hash)`")
+ }
};
let call_hash = |span, thing_expr| {
let hash_path = {
cx.expr_path(cx.path_global(span, strs))
};
let ref_thing = cx.expr_addr_of(span, thing_expr);
- let expr = cx.expr_call(span, hash_path, vec!(ref_thing, state_expr.clone()));
+ let expr = cx.expr_call(span, hash_path, vec![ref_thing, state_expr.clone()]);
cx.stmt_expr(expr)
};
let mut stmts = Vec::new();
fs
}
- _ => cx.span_bug(trait_span, "impossible substructure in `derive(Hash)`")
+ _ => cx.span_bug(trait_span, "impossible substructure in `derive(Hash)`"),
};
for &FieldInfo { ref self_, span, .. } in fields {
//! The compiler code necessary to implement the `#[derive]` extensions.
-use syntax::ast::{MetaItem, MetaItemKind, self};
+use syntax::ast::{self, MetaItem, MetaItemKind};
use syntax::attr::AttrMetaMethods;
-use syntax::ext::base::{ExtCtxt, SyntaxEnv, Annotatable};
+use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxEnv};
use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate;
span: Some(titem.span),
allow_internal_unstable: true,
},
- }), ..titem.span
+ }),
+ ..titem.span
};
if &tname[..] == "Eq" {
}
// #[derive(Foo, Bar)] expands to #[derive_Foo] #[derive_Bar]
- item.attrs.push(cx.attribute(span, cx.meta_word(titem.span,
- intern_and_get_ident(&format!("derive_{}", tname)))));
+ item.attrs.push(cx.attribute(span,
+ cx.meta_word(titem.span,
+ intern_and_get_ident(&format!("derive_{}", tname)))));
}
// RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
if let Some(eq_span) = eq_span {
if found_partial_eq {
let structural_match = intern_and_get_ident("structural_match");
- item.attrs.push(cx.attribute(eq_span,
- cx.meta_word(eq_span,
- structural_match)));
+ item.attrs.push(cx.attribute(eq_span, cx.meta_word(eq_span, structural_match)));
}
}
item
})
- }, |a| {
- cx.span_err(span, "`derive` can only be applied to items");
- a
- });
+ },
+ |a| {
+ cx.span_err(span,
+ "`derive` can only be applied to items");
+ a
+ });
debug!("expand_derive: annotatable output = {:?}", annot);
annot
}
"Decodable" => Some("RustcDecodable"),
_ => None,
} {
- ecx.span_warn(sp, &format!("derive({}) is deprecated in favor of derive({})",
- name, replacement));
+ ecx.span_warn(sp,
+ &format!("derive({}) is deprecated in favor of derive({})",
+ name,
+ replacement));
}
}
if let Annotatable::Item(ref item) = *item {
match item.node {
ast::ItemKind::Struct(_, ast::Generics { ref ty_params, .. }) |
- ast::ItemKind::Enum(_, ast::Generics { ref ty_params, .. }) => {
-
+ ast::ItemKind::Enum(_, ast::Generics { ref ty_params, .. }) => {
for ty in ty_params.iter() {
typaram.push_str(&ty.ident.name.as_str());
}
fn call_intrinsic(cx: &ExtCtxt,
span: Span,
intrinsic: &str,
- args: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+ args: Vec<P<ast::Expr>>)
+ -> P<ast::Expr> {
let path = cx.std_path(&["intrinsics", intrinsic]);
let call = cx.expr_call_global(span, path, args);
stmts: vec![cx.stmt_expr(call)],
id: ast::DUMMY_NODE_ID,
rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
- span: span }))
+ span: span,
+ }))
}
-
--- /dev/null
+// Copyright 2016 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(rustc_attrs)]
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+ macro_rules! m { ($s:stmt;) => { $s } }
+ m!(vec![].push(0););
+}
fn main() {
foo(|s| s.is_empty());
//~^ ERROR no method named `is_empty` found
- //~^^ HELP #1: `core::slice::SliceExt`
- //~^^^ HELP #2: `core::str::StrExt`
- //~^^^^ HELP items from traits can only be used if the trait is implemented and in scope; the following traits define an item `is_empty`, perhaps you need to implement one of them:
+ //~^^ HELP #1: `std::iter::ExactSizeIterator`
+ //~^^^ HELP #2: `core::slice::SliceExt`
+ //~^^^^ HELP #3: `core::str::StrExt`
+ //~^^^^^ HELP items from traits can only be used if the trait is implemented and in scope; the following traits define an item `is_empty`, perhaps you need to implement one of them:
}
//~^ ERROR unresolved import `use_from_trait_xc::Bar::new`
use use_from_trait_xc::Baz::new as baznew;
-//~^ ERROR `baznew` is not directly importable
+//~^ ERROR unresolved import `use_from_trait_xc::Baz::new`
fn main() {}
// ignore-tidy-linelength
// ignore-lldb
// ignore-android: FIXME(#24958)
+// ignore-arm: FIXME(#24958)
+// ignore-aarch64: FIXME(#24958)
// compile-flags:-g