Forgot two methods, but @alexcrichton was a bit too quick to accept #15943, so I made a new PR.
# Cleanup
######################################################################
-CLEAN_STAGE_RULES := \
- $(foreach stage, $(STAGES), \
- $(foreach host, $(CFG_HOST), \
- clean$(stage)_H_$(host) \
- $(foreach target, $(CFG_TARGET), \
+CLEAN_STAGE_RULES := \
+ $(foreach stage, $(STAGES), \
+ $(foreach host, $(CFG_HOST), \
+ clean$(stage)_H_$(host) \
+ $(foreach target, $(CFG_TARGET), \
clean$(stage)_T_$(target)_H_$(host))))
-CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
+CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
$(foreach host, $(CFG_HOST), clean-generic-H-$(host))
-CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
+CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
$(foreach host, $(CFG_TARGET), clean-generic-T-$(host))
-CLEAN_LLVM_RULES = \
- $(foreach target, $(CFG_HOST), \
+CLEAN_LLVM_RULES = \
+ $(foreach target, $(CFG_HOST), \
clean-llvm$(target))
.PHONY: clean clean-all clean-misc clean-llvm
$(1)/rt \
$(1)/test \
$(1)/stage* \
- -type f \( \
+ -type f \( \
-name '*.[odasS]' -o \
- -name '*.so' -o \
- -name '*.dylib' -o \
- -name '*.rlib' -o \
- -name 'stamp.*' -o \
- -name '*.lib' -o \
- -name '*.dll' -o \
- -name '*.def' -o \
- -name '*.bc' \
- \) \
+ -name '*.so' -o \
+ -name '*.dylib' -o \
+ -name '*.rlib' -o \
+ -name 'stamp.*' -o \
+ -name '*.lib' -o \
+ -name '*.dll' -o \
+ -name '*.def' -o \
+ -name '*.bc' \
+ \) \
| xargs rm -f
- $(Q)find $(1)\
- -name '*.dSYM' \
+ $(Q)find $(1) \
+ -name '*.dSYM' \
| xargs rm -Rf
endef
define CLEAN_HOST_STAGE_N
-clean$(1)_H_$(2): \
- $$(foreach crate,$$(CRATES),clean$(1)_H_$(2)-lib-$$(crate)) \
+clean$(1)_H_$(2): \
+ $$(foreach crate,$$(CRATES),clean$(1)_H_$(2)-lib-$$(crate)) \
$$(foreach tool,$$(TOOLS),clean$(1)_H_$(2)-tool-$$(tool))
$$(Q)rm -fr $(2)/rt/libbacktrace
define CLEAN_TARGET_STAGE_N
-clean$(1)_T_$(2)_H_$(3): \
- $$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate)) \
+clean$(1)_T_$(2)_H_$(3): \
+ $$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate)) \
$$(foreach tool,$$(TOOLS),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
# This is using a blacklist approach, probably more durable than a whitelist.
# We exclude: external dependencies (llvm, libuv, gyp, rt/{msvc,sundown,vg}),
# tests (compiletest, test) and a couple of other things (rt/arch, etc)
-CTAGS_LOCATIONS=$(patsubst ${CFG_SRC_DIR}src/llvm,,\
- $(patsubst ${CFG_SRC_DIR}src/libuv,,\
- $(patsubst ${CFG_SRC_DIR}src/compiletest,,\
- $(patsubst ${CFG_SRC_DIR}src/test,,\
- $(patsubst ${CFG_SRC_DIR}src/gyp,,\
- $(patsubst ${CFG_SRC_DIR}src/etc,,\
- $(patsubst ${CFG_SRC_DIR}src/rt,,\
- $(patsubst ${CFG_SRC_DIR}src/rt/arch,,\
- $(patsubst ${CFG_SRC_DIR}src/rt/msvc,,\
- $(patsubst ${CFG_SRC_DIR}src/rt/sundown,,\
- $(patsubst ${CFG_SRC_DIR}src/rt/vg,,\
- $(wildcard ${CFG_SRC_DIR}src/*) $(wildcard ${CFG_SRC_DIR}src/rt/*)\
+CTAGS_LOCATIONS=$(patsubst ${CFG_SRC_DIR}src/llvm,, \
+ $(patsubst ${CFG_SRC_DIR}src/libuv,, \
+ $(patsubst ${CFG_SRC_DIR}src/compiletest,, \
+ $(patsubst ${CFG_SRC_DIR}src/test,, \
+ $(patsubst ${CFG_SRC_DIR}src/gyp,, \
+ $(patsubst ${CFG_SRC_DIR}src/etc,, \
+ $(patsubst ${CFG_SRC_DIR}src/rt,, \
+ $(patsubst ${CFG_SRC_DIR}src/rt/arch,, \
+ $(patsubst ${CFG_SRC_DIR}src/rt/msvc,, \
+ $(patsubst ${CFG_SRC_DIR}src/rt/sundown,, \
+ $(patsubst ${CFG_SRC_DIR}src/rt/vg,, \
+ $(wildcard ${CFG_SRC_DIR}src/*) $(wildcard ${CFG_SRC_DIR}src/rt/*) \
)))))))))))
CTAGS_OPTS=--options="${CFG_SRC_DIR}src/etc/ctags.rust" --languages=-javascript --recurse ${CTAGS_LOCATIONS}
# We could use `--languages=Rust`, but there is value in producing tags for the
doc/version_info.html: $(D)/version_info.html.template $(MKFILE_DEPS) \
$(wildcard $(D)/*.*) | doc/
@$(call E, version-info: $@)
- $(Q)sed -e "s/VERSION/$(CFG_RELEASE)/; s/SHORT_HASH/$(\
- CFG_SHORT_VER_HASH)/;\
+ $(Q)sed -e "s/VERSION/$(CFG_RELEASE)/; s/SHORT_HASH/$( \
+ CFG_SHORT_VER_HASH)/; \
s/STAMP/$(CFG_VER_HASH)/;" $< >$@
GENERATED += doc/version.tex doc/version_info.html
define CP_HOST_STAGE_N_CRATE
ifeq ($$(ONLY_RLIB_$(5)),)
-$$(HLIB$(2)_H_$(4))/stamp.$(5): \
- $$(TLIB$(1)_T_$(3)_H_$(4))/stamp.$(5) \
- $$(RUST_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%) \
+$$(HLIB$(2)_H_$(4))/stamp.$(5): \
+ $$(TLIB$(1)_T_$(3)_H_$(4))/stamp.$(5) \
+ $$(RUST_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$(@D)/lib$(5))
- $$(call REMOVE_ALL_OLD_GLOB_MATCHES,\
+ $$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(3),$(5)))
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(3)_H_$(4))/$$(call CFG_LIB_GLOB_$(3),$(5)) \
$$(HLIB$(2)_H_$(4))
- $$(call LIST_ALL_OLD_GLOB_MATCHES,\
+ $$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(3),$(5)))
else
$$(HLIB$(2)_H_$(4))/stamp.$(5):
endef
-$(foreach t,$(CFG_HOST), \
- $(eval $(call CP_HOST_STAGE_N,0,1,$(t),$(t))) \
- $(eval $(call CP_HOST_STAGE_N,1,2,$(t),$(t))) \
+$(foreach t,$(CFG_HOST), \
+ $(eval $(call CP_HOST_STAGE_N,0,1,$(t),$(t))) \
+ $(eval $(call CP_HOST_STAGE_N,1,2,$(t),$(t))) \
$(eval $(call CP_HOST_STAGE_N,2,3,$(t),$(t))))
-$(foreach crate,$(CRATES), \
- $(foreach t,$(CFG_HOST), \
- $(eval $(call CP_HOST_STAGE_N_CRATE,0,1,$(t),$(t),$(crate))) \
- $(eval $(call CP_HOST_STAGE_N_CRATE,1,2,$(t),$(t),$(crate))) \
+$(foreach crate,$(CRATES), \
+ $(foreach t,$(CFG_HOST), \
+ $(eval $(call CP_HOST_STAGE_N_CRATE,0,1,$(t),$(t),$(crate))) \
+ $(eval $(call CP_HOST_STAGE_N_CRATE,1,2,$(t),$(t),$(crate))) \
$(eval $(call CP_HOST_STAGE_N_CRATE,2,3,$(t),$(t),$(crate)))))
-$(foreach tool,$(TOOLS), \
- $(foreach t,$(CFG_HOST), \
- $(eval $(call CP_HOST_STAGE_N_TOOL,0,1,$(t),$(t),$(tool))) \
- $(eval $(call CP_HOST_STAGE_N_TOOL,1,2,$(t),$(t),$(tool))) \
+$(foreach tool,$(TOOLS), \
+ $(foreach t,$(CFG_HOST), \
+ $(eval $(call CP_HOST_STAGE_N_TOOL,0,1,$(t),$(t),$(tool))) \
+ $(eval $(call CP_HOST_STAGE_N_TOOL,1,2,$(t),$(t),$(tool))) \
$(eval $(call CP_HOST_STAGE_N_TOOL,2,3,$(t),$(t),$(tool)))))
define INSTALL_RUNTIME_TARGET_N
install-runtime-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
$$(Q)$$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
- $$(Q)$$(foreach crate,$$(TARGET_CRATES),\
- $$(call ADB_PUSH,$$(TL$(1)$(2))/$$(call CFG_LIB_GLOB_$(1),$$(crate)),\
+ $$(Q)$$(foreach crate,$$(TARGET_CRATES), \
+ $$(call ADB_PUSH,$$(TL$(1)$(2))/$$(call CFG_LIB_GLOB_$(1),$$(crate)), \
$$(CFG_RUNTIME_PUSH_DIR));)
endef
define INSTALL_RUNTIME_TARGET_CLEANUP_N
install-runtime-target-$(1)-cleanup:
$$(Q)$$(call ADB,remount)
- $$(Q)$$(foreach crate,$$(TARGET_CRATES),\
+ $$(Q)$$(foreach crate,$$(TARGET_CRATES), \
$$(call ADB_SHELL,rm,$$(CFG_RUNTIME_PUSH_DIR)/$$(call CFG_LIB_GLOB_$(1),$$(crate)));)
endef
define DEF_X
X_$(1) := $(CFG_EXE_SUFFIX_$(1))
endef
-$(foreach target,$(CFG_TARGET),\
+$(foreach target,$(CFG_TARGET), \
$(eval $(call DEF_X,$(target))))
# "Source" files we generate in builddir along the way.
# target
SREQ$(1)_T_$(2)_H_$(3) = \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
- $$(foreach dep,$$(TARGET_CRATES),\
+ $$(foreach dep,$$(TARGET_CRATES), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep))
# Prerequisites for a working stageN compiler and complete set of target
endif
endif
-STAGE$(1)_T_$(2)_H_$(3) := \
- $$(Q)$$(RPATH_VAR$(1)_T_$(2)_H_$(3)) \
- $$(call CFG_RUN_TARG_$(3),$(1), \
- $$(CFG_VALGRIND_COMPILE$(1)) \
- $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
- --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
+STAGE$(1)_T_$(2)_H_$(3) := \
+ $$(Q)$$(RPATH_VAR$(1)_T_$(2)_H_$(3)) \
+ $$(call CFG_RUN_TARG_$(3),$(1), \
+ $$(CFG_VALGRIND_COMPILE$(1)) \
+ $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
+ --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
$$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
$$(RUSTC_FLAGS_$(2))
-PERF_STAGE$(1)_T_$(2)_H_$(3) := \
- $$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \
- $$(CFG_PERF_TOOL) \
- $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
- --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
+PERF_STAGE$(1)_T_$(2)_H_$(3) := \
+ $$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \
+ $$(CFG_PERF_TOOL) \
+ $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
+ --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
$$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
$$(RUSTC_FLAGS_$(2))
# $(1) == architecture
# $(2) == stage
-rustc-stage$(2)-H-$(1): \
+rustc-stage$(2)-H-$(1): \
$$(foreach target,$$(CFG_TARGET),$$(SREQ$(2)_T_$$(target)_H_$(1)))
endef
-$(foreach host,$(CFG_HOST), \
- $(eval $(foreach stage,1 2 3, \
+$(foreach host,$(CFG_HOST), \
+ $(eval $(foreach stage,1 2 3, \
$(eval $(call DEF_RUSTC_STAGE_TARGET,$(host),$(stage))))))
rustc-stage1: rustc-stage1-H-$(CFG_BUILD)
rustc-H-$(1): rustc-stage2-H-$(1)
endef
-$(foreach host,$(CFG_TARGET), \
+$(foreach host,$(CFG_TARGET), \
$(eval $(call DEF_RUSTC_TARGET,$(host))))
rustc-stage1: rustc-stage1-H-$(CFG_BUILD)
CFG_DSYMUTIL := true
# Hack: not sure how to test if a file exists in make other than this
-OS_SUPP = $(patsubst %,--suppressions=%,\
+OS_SUPP = $(patsubst %,--suppressions=%, \
$(wildcard $(CFG_SRC_DIR)src/etc/$(CFG_OSTYPE).supp*))
ifdef CFG_DISABLE_OPTIMIZE_CXX
endif
else
ifdef CFG_VALGRIND
- CFG_PERF_TOOL :=\
+ CFG_PERF_TOOL := \
$(CFG_VALGRIND) --tool=cachegrind --cache-sim=yes --branch-sim=yes
else
CFG_PERF_TOOL := /usr/bin/time --verbose
endif
endef
-$(foreach cvar,CC CXX CPP CFLAGS CXXFLAGS CPPFLAGS,\
+$(foreach cvar,CC CXX CPP CFLAGS CXXFLAGS CPPFLAGS, \
$(eval $(call SET_FROM_CFG,$(cvar))))
CFG_RLIB_GLOB=lib$(1)-*.rlib
CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
CFG_WINDOWSY_i586-mingw32msvc := 1
CFG_UNIXY_i586-mingw32msvc :=
-CFG_PATH_MUNGE_i586-mingw32msvc := $(strip perl -i.bak -p \
- -e 's@\\(\S)@/\1@go;' \
+CFG_PATH_MUNGE_i586-mingw32msvc := $(strip perl -i.bak -p \
+ -e 's@\\(\S)@/\1@go;' \
-e 's@^/([a-zA-Z])/@\1:/@o;')
CFG_LDPATH_i586-mingw32msvc :=
CFG_RUN_i586-mingw32msvc=
endif
endef
-$(foreach target,$(CFG_TARGET),\
+$(foreach target,$(CFG_TARGET), \
$(eval $(call FILTER_FLAGS,$(target))))
RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))
endif
- CFG_COMPILE_C_$(1) = $$(CC_$(1)) \
- $$(CFG_GCCISH_CFLAGS) \
+ CFG_COMPILE_C_$(1) = $$(CC_$(1)) \
+ $$(CFG_GCCISH_CFLAGS) \
$$(CFG_GCCISH_CFLAGS_$(1)) \
- $$(CFG_DEPEND_FLAGS) \
+ $$(CFG_DEPEND_FLAGS) \
-c -o $$(1) $$(2)
CFG_LINK_C_$(1) = $$(CC_$(1)) \
- $$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
- $$(CFG_GCCISH_LINK_FLAGS_$(1)) \
- $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
+ $$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
+ $$(CFG_GCCISH_LINK_FLAGS_$(1)) \
+ $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(call CFG_INSTALL_NAME_$(1),$$(4))
CFG_COMPILE_CXX_$(1) = $$(CXX_$(1)) \
- $$(CFG_GCCISH_CFLAGS) \
- $$(CFG_GCCISH_CXXFLAGS) \
+ $$(CFG_GCCISH_CFLAGS) \
+ $$(CFG_GCCISH_CXXFLAGS) \
$$(CFG_GCCISH_CFLAGS_$(1)) \
- $$(CFG_GCCISH_CXXFLAGS_$(1)) \
- $$(CFG_DEPEND_FLAGS) \
+ $$(CFG_GCCISH_CXXFLAGS_$(1)) \
+ $$(CFG_DEPEND_FLAGS) \
-c -o $$(1) $$(2)
CFG_LINK_CXX_$(1) = $$(CXX_$(1)) \
- $$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
- $$(CFG_GCCISH_LINK_FLAGS_$(1)) \
- $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
+ $$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
+ $$(CFG_GCCISH_LINK_FLAGS_$(1)) \
+ $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(call CFG_INSTALL_NAME_$(1),$$(4))
ifeq ($$(findstring $(HOST_$(1)),arm mips mipsel),)
endef
-$(foreach target,$(CFG_TARGET),\
+$(foreach target,$(CFG_TARGET), \
$(eval $(call CFG_MAKE_TOOLCHAIN,$(target))))
$(nop)
@$(call E, prepare: $(PREPARE_WORKING_DEST_LIB_DIR)/$(1))
$(Q)LIB_NAME="$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1))))"; \
- MATCHES="$(filter-out %$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1)))),\
+ MATCHES="$(filter-out %$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1)))), \
$(wildcard $(PREPARE_WORKING_DEST_LIB_DIR)/$(1)))"; \
- if [ -n "$$MATCHES" ]; then \
- echo "warning: one or libraries matching Rust library '$(1)'" && \
- echo " (other than '$$LIB_NAME' itself) already present" && \
- echo " at destination $(PREPARE_WORKING_DEST_LIB_DIR):" && \
- echo $$MATCHES ; \
+ if [ -n "$$MATCHES" ]; then \
+ echo "warning: one or libraries matching Rust library '$(1)'" && \
+ echo " (other than '$$LIB_NAME' itself) already present" && \
+ echo " at destination $(PREPARE_WORKING_DEST_LIB_DIR):" && \
+ echo $$MATCHES ; \
fi
$(Q)$(PREPARE_LIB_CMD) `ls -drt1 $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1) | tail -1` $(PREPARE_WORKING_DEST_LIB_DIR)/
endef
$$(foreach dep,$$(TOOL_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)-$(4)) \
$$(HBIN$(2)_H_$(3))/$(1)$$(X_$(3)) \
prepare-host-dirs-$(4)
- $$(if $$(findstring $(2), $$(PREPARE_STAGE)),\
- $$(if $$(findstring $(3), $$(PREPARE_HOST)),\
+ $$(if $$(findstring $(2), $$(PREPARE_STAGE)), \
+ $$(if $$(findstring $(3), $$(PREPARE_HOST)), \
$$(call PREPARE_BIN,$(1)$$(X_$$(PREPARE_HOST))),),)
- $$(if $$(findstring $(2), $$(PREPARE_STAGE)),\
- $$(if $$(findstring $(3), $$(PREPARE_HOST)),\
+ $$(if $$(findstring $(2), $$(PREPARE_STAGE)), \
+ $$(if $$(findstring $(3), $$(PREPARE_HOST)), \
$$(call PREPARE_MAN,$(1).1),),)
endef
prepare-host-lib-$(1)-$(2)-$(3)-$(4): PREPARE_WORKING_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_LIB_DIR)
prepare-host-lib-$(1)-$(2)-$(3)-$(4): PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_LIB_DIR)
prepare-host-lib-$(1)-$(2)-$(3)-$(4): prepare-maybe-clean-$(4) \
- $$(foreach dep,$$(RUST_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)-$(4))\
+ $$(foreach dep,$$(RUST_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)-$(4)) \
$$(HLIB$(2)_H_$(3))/stamp.$(1) \
prepare-host-dirs-$(4)
- $$(if $$(findstring $(2), $$(PREPARE_STAGE)),\
- $$(if $$(findstring $(3), $$(PREPARE_HOST)),\
- $$(if $$(findstring 1,$$(ONLY_RLIB_$(1))),,\
+ $$(if $$(findstring $(2), $$(PREPARE_STAGE)), \
+ $$(if $$(findstring $(3), $$(PREPARE_HOST)), \
+ $$(if $$(findstring 1,$$(ONLY_RLIB_$(1))),, \
$$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$$(PREPARE_HOST),$(1)))),),)
endef
# *not* install the rlibs for host crates because there's no need to statically
# link against most of them. They just produce a large amount of extra size
# bloat.
- $$(if $$(findstring $(1), $$(PREPARE_STAGE)),\
- $$(if $$(findstring $(2), $$(PREPARE_TARGETS)),\
- $$(if $$(findstring $(3), $$(PREPARE_HOST)),\
- $$(call PREPARE_DIR,$$(PREPARE_WORKING_DEST_LIB_DIR))\
- $$(foreach crate,$$(TARGET_CRATES),\
- $$(if $$(findstring 1, $$(ONLY_RLIB_$$(crate))),,\
- $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate))))\
- $$(call PREPARE_LIB,$$(call CFG_RLIB_GLOB,$$(crate))))\
- $$(if $$(findstring $(2),$$(CFG_HOST)),\
- $$(foreach crate,$$(HOST_CRATES),\
- $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))),)\
+ $$(if $$(findstring $(1), $$(PREPARE_STAGE)), \
+ $$(if $$(findstring $(2), $$(PREPARE_TARGETS)), \
+ $$(if $$(findstring $(3), $$(PREPARE_HOST)), \
+ $$(call PREPARE_DIR,$$(PREPARE_WORKING_DEST_LIB_DIR)) \
+ $$(foreach crate,$$(TARGET_CRATES), \
+ $$(if $$(findstring 1, $$(ONLY_RLIB_$$(crate))),, \
+ $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))) \
+ $$(call PREPARE_LIB,$$(call CFG_RLIB_GLOB,$$(crate)))) \
+ $$(if $$(findstring $(2),$$(CFG_HOST)), \
+ $$(foreach crate,$$(HOST_CRATES), \
+ $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))),) \
$$(call PREPARE_LIB,libmorestack.a) \
$$(call PREPARE_LIB,libcompiler-rt.a),),),)
endef
prepare-host-$(1): prepare-host-tools-$(1)
prepare-host-tools-$(1): \
- $$(foreach tool, $$(PREPARE_TOOLS),\
- $$(foreach host,$$(CFG_HOST),\
+ $$(foreach tool, $$(PREPARE_TOOLS), \
+ $$(foreach host,$$(CFG_HOST), \
prepare-host-tool-$$(tool)-$$(PREPARE_STAGE)-$$(host)-$(1)))
prepare-host-dirs-$(1): prepare-maybe-clean-$(1)
$$(call PREPARE_DIR,$$(PREPARE_DEST_LIB_DIR))
$$(call PREPARE_DIR,$$(PREPARE_DEST_MAN_DIR))
-$$(foreach tool,$$(PREPARE_TOOLS),\
- $$(foreach host,$$(CFG_HOST),\
+$$(foreach tool,$$(PREPARE_TOOLS), \
+ $$(foreach host,$$(CFG_HOST), \
$$(eval $$(call DEF_PREPARE_HOST_TOOL,$$(tool),$$(PREPARE_STAGE),$$(host),$(1)))))
-$$(foreach lib,$$(CRATES),\
- $$(foreach host,$$(CFG_HOST),\
+$$(foreach lib,$$(CRATES), \
+ $$(foreach host,$$(CFG_HOST), \
$$(eval $$(call DEF_PREPARE_HOST_LIB,$$(lib),$$(PREPARE_STAGE),$$(host),$(1)))))
-prepare-targets-$(1):\
- $$(foreach host,$$(CFG_HOST),\
- $$(foreach target,$$(CFG_TARGET),\
+prepare-targets-$(1): \
+ $$(foreach host,$$(CFG_HOST), \
+ $$(foreach target,$$(CFG_TARGET), \
prepare-target-$$(target)-host-$$(host)-$$(PREPARE_STAGE)-$(1)))
-$$(foreach host,$$(CFG_HOST),\
+$$(foreach host,$$(CFG_HOST), \
$$(foreach target,$$(CFG_TARGET), \
$$(eval $$(call DEF_PREPARE_TARGET_N,$$(PREPARE_STAGE),$$(target),$$(host),$(1)))))
prepare-maybe-clean-$(1):
- $$(if $$(findstring true,$$(PREPARE_CLEAN)),\
+ $$(if $$(findstring true,$$(PREPARE_CLEAN)), \
@$$(call E, cleaning destination $$(PREPARE_DEST_DIR)),)
- $$(if $$(findstring true,$$(PREPARE_CLEAN)),\
+ $$(if $$(findstring true,$$(PREPARE_CLEAN)), \
$$(Q)rm -rf $$(PREPARE_DEST_DIR),)
endef
-$(foreach target,$(CFG_TARGET), \
+$(foreach target,$(CFG_TARGET), \
$(eval $(call RUNTIME_RULES,$(target))))
-$(foreach lib,$(NATIVE_LIBS), \
- $(foreach target,$(CFG_TARGET), \
+$(foreach lib,$(NATIVE_LIBS), \
+ $(foreach target,$(CFG_TARGET), \
$(eval $(call THIRD_PARTY_LIB,$(target),$(lib)))))
endef
-$(foreach host,$(CFG_HOST), \
- $(eval $(foreach stage,1 2 3, \
+$(foreach host,$(CFG_HOST), \
+ $(eval $(foreach stage,1 2 3, \
$(eval $(call DEF_SNAP_FOR_STAGE_H,$(stage),$(host))))))
snap-stage1: snap-stage1-H-$(CFG_BUILD)
$(HLIB0_H_$(CFG_BUILD))/:
mkdir -p $@
-$(SNAPSHOT_RUSTC_POST_CLEANUP): \
- $(S)src/snapshots.txt \
- $(S)src/etc/get-snapshot.py $(MKFILE_DEPS) \
+$(SNAPSHOT_RUSTC_POST_CLEANUP): \
+ $(S)src/snapshots.txt \
+ $(S)src/etc/get-snapshot.py $(MKFILE_DEPS) \
| $(HBIN0_H_$(CFG_BUILD))/
@$(call E, fetch: $@)
# Use stage1 to build other architectures: then you don't have to wait
# for stage2, but you get the latest updates to the compiler source.
-$(foreach t,$(NON_BUILD_HOST), \
+$(foreach t,$(NON_BUILD_HOST), \
$(eval $(call BOOTSTRAP_STAGE0,$(t),1,$(CFG_BUILD))))
# $(3) - host
# $(4) crate
define RUST_CRATE_FULLDEPS
-CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) := \
- $$(CRATEFILE_$(4)) \
- $$(RSINPUTS_$(4)) \
- $$(foreach dep,$$(RUST_DEPS_$(4)), \
- $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
- $$(foreach dep,$$(NATIVE_DEPS_$(4)), \
+CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) := \
+ $$(CRATEFILE_$(4)) \
+ $$(RSINPUTS_$(4)) \
+ $$(foreach dep,$$(RUST_DEPS_$(4)), \
+ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
+ $$(foreach dep,$$(NATIVE_DEPS_$(4)), \
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),$$(dep)))
endef
-$(foreach host,$(CFG_HOST), \
- $(foreach target,$(CFG_TARGET), \
- $(foreach stage,$(STAGES), \
- $(foreach crate,$(CRATES), \
+$(foreach host,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+ $(foreach stage,$(STAGES), \
+ $(foreach crate,$(CRATES), \
$(eval $(call RUST_CRATE_FULLDEPS,$(stage),$(target),$(host),$(crate)))))))
# RUST_TARGET_STAGE_N template: This defines how target artifacts are built
define RUST_TARGET_STAGE_N
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER_HOST_TRIPLE = $(2)
-$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
- $$(CRATEFILE_$(4)) \
- $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
- $$(TSREQ$(1)_T_$(2)_H_$(3)) \
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
+ $$(CRATEFILE_$(4)) \
+ $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
+ $$(TSREQ$(1)_T_$(2)_H_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, rustc: $$(@D)/lib$(4))
- $$(call REMOVE_ALL_OLD_GLOB_MATCHES,\
+ $$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
- $$(call REMOVE_ALL_OLD_GLOB_MATCHES,\
+ $$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_RLIB_GLOB,$(4)))
$$(STAGE$(1)_T_$(2)_H_$(3)) \
$$(WFLAGS_ST$(1)) \
-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
$$<
@touch $$@
- $$(call LIST_ALL_OLD_GLOB_MATCHES,\
+ $$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
- $$(call LIST_ALL_OLD_GLOB_MATCHES,\
+ $$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_RLIB_GLOB,$(4)))
endef
# $(4) - name of the tool being built
define TARGET_TOOL
-$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \
- $$(TOOL_SOURCE_$(4)) \
- $$(TOOL_INPUTS_$(4)) \
- $$(foreach dep,$$(TOOL_DEPS_$(4)), \
- $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
- $$(TSREQ$(1)_T_$(2)_H_$(3)) \
+$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \
+ $$(TOOL_SOURCE_$(4)) \
+ $$(TOOL_INPUTS_$(4)) \
+ $$(foreach dep,$$(TOOL_DEPS_$(4)), \
+ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
+ $$(TSREQ$(1)_T_$(2)_H_$(3)) \
| $$(TBIN$(1)_T_$(4)_H_$(3))/
@$$(call E, rustc: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --cfg $(4)
$$(Q)cp $$< $$@
endef
-$(foreach source,$(CFG_HOST), \
- $(foreach target,$(CFG_TARGET), \
- $(eval $(call TARGET_HOST_RULES,0,$(target),$(source))) \
- $(eval $(call TARGET_HOST_RULES,1,$(target),$(source))) \
- $(eval $(call TARGET_HOST_RULES,2,$(target),$(source))) \
+$(foreach source,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+ $(eval $(call TARGET_HOST_RULES,0,$(target),$(source))) \
+ $(eval $(call TARGET_HOST_RULES,1,$(target),$(source))) \
+ $(eval $(call TARGET_HOST_RULES,2,$(target),$(source))) \
$(eval $(call TARGET_HOST_RULES,3,$(target),$(source)))))
# In principle, each host can build each target for both libs and tools
-$(foreach crate,$(CRATES), \
- $(foreach source,$(CFG_HOST), \
- $(foreach target,$(CFG_TARGET), \
- $(eval $(call RUST_TARGET_STAGE_N,0,$(target),$(source),$(crate))) \
- $(eval $(call RUST_TARGET_STAGE_N,1,$(target),$(source),$(crate))) \
- $(eval $(call RUST_TARGET_STAGE_N,2,$(target),$(source),$(crate))) \
+$(foreach crate,$(CRATES), \
+ $(foreach source,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+ $(eval $(call RUST_TARGET_STAGE_N,0,$(target),$(source),$(crate))) \
+ $(eval $(call RUST_TARGET_STAGE_N,1,$(target),$(source),$(crate))) \
+ $(eval $(call RUST_TARGET_STAGE_N,2,$(target),$(source),$(crate))) \
$(eval $(call RUST_TARGET_STAGE_N,3,$(target),$(source),$(crate))))))
-$(foreach host,$(CFG_HOST), \
- $(foreach target,$(CFG_TARGET), \
- $(foreach stage,$(STAGES), \
- $(foreach tool,$(TOOLS), \
+$(foreach host,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+ $(foreach stage,$(STAGES), \
+ $(foreach tool,$(TOOLS), \
$(eval $(call TARGET_TOOL,$(stage),$(target),$(host),$(tool)))))))
# Whether to ratchet or merely save benchmarks
ifdef CFG_RATCHET_BENCH
-CRATE_TEST_EXTRA_ARGS=\
+CRATE_TEST_EXTRA_ARGS= \
--test $(TEST_BENCH) \
--ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
--ratchet-noise-percent $(TEST_RATCHET_NOISE_PERCENT)
else
-CRATE_TEST_EXTRA_ARGS=\
+CRATE_TEST_EXTRA_ARGS= \
--test $(TEST_BENCH) \
--save-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4))
endif
$(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)) \
$(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)/tmp) \
$(shell $(CFG_ADB) push $(S)src/etc/adb_run_wrapper.sh $(CFG_ADB_TEST_DIR) 1>/dev/null) \
- $(foreach crate,$(TARGET_CRATES),\
+ $(foreach crate,$(TARGET_CRATES), \
$(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(call CFG_LIB_GLOB_arm-linux-androideabi,$(crate)) \
- $(CFG_ADB_TEST_DIR)))\
+ $(CFG_ADB_TEST_DIR))) \
)
else
CFG_ADB_TEST_DIR=
cleantestlibs:
$(Q)find $(CFG_BUILD)/test \
-name '*.[odasS]' -o \
- -name '*.so' -o \
- -name '*.dylib' -o \
- -name '*.dll' -o \
- -name '*.def' -o \
- -name '*.bc' -o \
- -name '*.dSYM' -o \
- -name '*.libaux' -o \
- -name '*.out' -o \
- -name '*.err' -o \
+ -name '*.so' -o \
+ -name '*.dylib' -o \
+ -name '*.dll' -o \
+ -name '*.def' -o \
+ -name '*.bc' -o \
+ -name '*.dSYM' -o \
+ -name '*.libaux' -o \
+ -name '*.out' -o \
+ -name '*.err' -o \
-name '*.debugger.script' \
| xargs rm -rf
define DEF_TEST_SETS
-check-stage$(1)-T-$(2)-H-$(3)-exec: \
- check-stage$(1)-T-$(2)-H-$(3)-rpass-exec \
- check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \
- check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \
- check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
- check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \
- check-stage$(1)-T-$(2)-H-$(3)-rmake-exec \
- check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
- check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
- check-stage$(1)-T-$(2)-H-$(3)-bench-exec \
+check-stage$(1)-T-$(2)-H-$(3)-exec: \
+ check-stage$(1)-T-$(2)-H-$(3)-rpass-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-rmake-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-bench-exec \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-$$(docname)-exec)
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec: \
- check-stage$(1)-T-$(2)-H-$(3)-pretty-rpass-exec \
- check-stage$(1)-T-$(2)-H-$(3)-pretty-rpass-full-exec \
- check-stage$(1)-T-$(2)-H-$(3)-pretty-rfail-exec \
- check-stage$(1)-T-$(2)-H-$(3)-pretty-bench-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-pretty-rpass-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-pretty-rpass-full-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-pretty-rfail-exec \
+ check-stage$(1)-T-$(2)-H-$(3)-pretty-bench-exec \
check-stage$(1)-T-$(2)-H-$(3)-pretty-pretty-exec
endef
# parent crates.
ifeq ($(NO_REBUILD),)
TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
- $$(foreach crate,$$(TARGET_CRATES),\
+ $$(foreach crate,$$(TARGET_CRATES), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))
endif
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): CFG_COMPILER_HOST_TRIPLE = $(2)
-$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
+$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
$$(CRATEFILE_$(4)) \
$$(TESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, rustc: $$@)
- $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
- -L "$$(RT_OUTPUT_DIR_$(2))" \
- -L "$$(LLVM_LIBDIR_$(2))" \
+ $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
+ -L "$$(RT_OUTPUT_DIR_$(2))" \
+ -L "$$(LLVM_LIBDIR_$(2))" \
$$(RUSTFLAGS_$(4))
endef
CTEST_RUSTC_FLAGS += -O
endif
-CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
- --compile-lib-path $$(HLIB$(1)_H_$(3)) \
- --run-lib-path $$(TLIB$(1)_T_$(2)_H_$(3)) \
- --rustc-path $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
+CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
+ --compile-lib-path $$(HLIB$(1)_H_$(3)) \
+ --run-lib-path $$(TLIB$(1)_T_$(2)_H_$(3)) \
+ --rustc-path $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
--clang-path $(if $(CFG_CLANG),$(CFG_CLANG),clang) \
--llvm-bin-path $(CFG_LLVM_INST_DIR_$(CFG_BUILD))/bin \
- --aux-base $$(S)src/test/auxiliary/ \
- --stage-id stage$(1)-$(2) \
- --target $(2) \
- --host $(3) \
- --android-cross-path=$(CFG_ANDROID_CROSS_PATH) \
- --adb-path=$(CFG_ADB) \
- --adb-test-dir=$(CFG_ADB_TEST_DIR) \
+ --aux-base $$(S)src/test/auxiliary/ \
+ --stage-id stage$(1)-$(2) \
+ --target $(2) \
+ --host $(3) \
+ --android-cross-path=$(CFG_ANDROID_CROSS_PATH) \
+ --adb-path=$(CFG_ADB) \
+ --adb-test-dir=$(CFG_ADB_TEST_DIR) \
--host-rustcflags "$(RUSTC_FLAGS_$(3)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(3))" \
--lldb-python-dir=$(CFG_LLDB_PYTHON_DIR) \
--target-rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) -L $$(RT_OUTPUT_DIR_$(2))" \
define DEF_RUN_COMPILETEST
CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
- $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \
+ $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \
--src-base $$(S)src/test/$$(CTEST_SRC_BASE_$(4))/ \
--build-base $(3)/test/$$(CTEST_BUILD_BASE_$(4))/ \
--ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
define DEF_RUN_PRETTY_TEST
-PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
- $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \
+PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
+ $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \
--src-base $$(S)src/test/$$(PRETTY_DIRNAME_$(4))/ \
--build-base $(3)/test/$$(PRETTY_DIRNAME_$(4))/ \
--mode pretty
check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4))
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
- $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
+ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(PRETTY_DEPS_$(4))
@$$(call E, run pretty-rpass [$(2)]: $$<)
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
ifeq ($(NO_REBUILD),)
DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
$$(D)/$(4).md \
- $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
+ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(RUSTDOC_EXE_$(1)_T_$(2)_H_$(3))
else
DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(D)/$(4).md
# rebuilding any of the parent crates.
ifeq ($(NO_REBUILD),)
CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
- $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
- $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
+ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
+ $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
$$(RUSTDOC_EXE_$(1)_T_$(2)_H_$(3))
else
CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
$(eval $(call DEF_CHECK_FOR_STAGE_AND_HOSTS_AND_GROUP,$(stage),$(host),$(group))))))
define DEF_CHECK_DOC_FOR_STAGE
-check-stage$(1)-docs: $$(foreach docname,$$(DOCS),\
+check-stage$(1)-docs: $$(foreach docname,$$(DOCS), \
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-$$(docname)) \
- $$(foreach crate,$$(TEST_DOC_CRATES),\
+ $$(foreach crate,$$(TEST_DOC_CRATES), \
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-crate-$$(crate))
endef
spawn(proc() {
let numbers = rx.recv();
- println!("{:d}", numbers[num as uint]);
+ println!("{:d}", numbers[num]);
})
}
}
and `fn f(mut x: Box<int>, y: Box<int>)` declare one mutable variable `x` and
one immutable variable `y`).
-Methods that take either `self` or `~self` can optionally place them in a
+Methods that take either `self` or `Box<Self>` can optionally place them in a
mutable slot by prefixing them with `mut` (similar to regular arguments):
~~~
trait Changer {
fn change(mut self) -> Self;
- fn modify(mut ~self) -> Box<Self>;
+ fn modify(mut self: Box<Self>) -> Box<Self>;
}
~~~
The type of `self` is the type on which the method is implemented,
or a pointer thereof. As an argument it is written either `self`,
-`&self`, or `~self`.
+`&self`, or `self: TYPE`.
A caller must in turn have a compatible pointer type to call the method.
~~~
# }
impl Shape {
fn draw_reference(&self) { /* ... */ }
- fn draw_owned(~self) { /* ... */ }
+ fn draw_owned(self: Box<Shape>) { /* ... */ }
fn draw_value(self) { /* ... */ }
}
# }
# impl Shape {
# fn draw_reference(&self) { /* ... */ }
-# fn draw_owned(~self) { /* ... */ }
+# fn draw_owned(self: Box<Shape>) { /* ... */ }
# fn draw_value(self) { /* ... */ }
# }
# let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0);
"test/bench/shootout-meteor.rs", # BSD
"test/bench/shootout-pidigits.rs", # BSD
"test/bench/shootout-regex-dna.rs", # BSD
+ "test/bench/shootout-threadring.rs", # BSD
]
def check_license(name, contents):
// measure
let mut i = 0;
b.iter(|| {
- map.find(keys.get(i));
+ map.find(&keys[i]);
i = (i + 1) % n;
})
}
use slice;
use vec::Vec;
-/// A priority queue implemented with a binary heap
+/// A priority queue implemented with a binary heap.
+///
+/// This will be a max-heap.
#[deriving(Clone)]
pub struct PriorityQueue<T> {
data: Vec<T>,
}
impl<T: Ord> PriorityQueue<T> {
+ /// Create an empty PriorityQueue as a max-heap.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ /// let pq: PriorityQueue<uint> = PriorityQueue::new();
+ /// ```
+ pub fn new() -> PriorityQueue<T> { PriorityQueue{data: vec!(),} }
+
+ /// Create an empty PriorityQueue with a specific capacity.
+ /// This preallocates enough memory for `capacity` elements,
+ /// so that the PriorityQueue does not have to be reallocated
+ /// until it contains at least that many values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ /// let pq: PriorityQueue<uint> = PriorityQueue::with_capacity(10u);
+ /// ```
+ pub fn with_capacity(capacity: uint) -> PriorityQueue<T> {
+ PriorityQueue { data: Vec::with_capacity(capacity) }
+ }
+
+ /// Create a PriorityQueue from a vector. This is sometimes called
+ /// `heapifying` the vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ /// let pq = PriorityQueue::from_vec(vec![9i, 1, 2, 7, 3, 2]);
+ /// ```
+ pub fn from_vec(xs: Vec<T>) -> PriorityQueue<T> {
+ let mut q = PriorityQueue{data: xs,};
+ let mut n = q.len() / 2;
+ while n > 0 {
+ n -= 1;
+ q.siftdown(n)
+ }
+ q
+ }
+
/// An iterator visiting all values in underlying vector, in
/// arbitrary order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ /// let pq = PriorityQueue::from_vec(vec![1i, 2, 3, 4]);
+ ///
+ /// // Print 1, 2, 3, 4 in arbitrary order
+ /// for x in pq.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
pub fn iter<'a>(&'a self) -> Items<'a, T> {
Items { iter: self.data.iter() }
}
- /// Returns the greatest item in a queue or None if it is empty
+ /// Returns the greatest item in a queue or `None` if it is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq = PriorityQueue::new();
+ /// assert_eq!(pq.top(), None);
+ ///
+ /// pq.push(1i);
+ /// pq.push(5i);
+ /// pq.push(2i);
+ /// assert_eq!(pq.top(), Some(&5i));
+ ///
+ /// ```
pub fn top<'a>(&'a self) -> Option<&'a T> {
if self.is_empty() { None } else { Some(self.data.get(0)) }
}
#[deprecated="renamed to `top`"]
pub fn maybe_top<'a>(&'a self) -> Option<&'a T> { self.top() }
- /// Returns the number of elements the queue can hold without reallocating
+ /// Returns the number of elements the queue can hold without reallocating.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let pq: PriorityQueue<uint> = PriorityQueue::with_capacity(100u);
+ /// assert!(pq.capacity() >= 100u);
+ /// ```
pub fn capacity(&self) -> uint { self.data.capacity() }
- /// Reserve capacity for exactly n elements in the PriorityQueue.
+ /// Reserve capacity for exactly `n` elements in the PriorityQueue.
/// Do nothing if the capacity is already sufficient.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq: PriorityQueue<uint> = PriorityQueue::new();
+ /// pq.reserve_exact(100u);
+ /// assert!(pq.capacity() == 100u);
+ /// ```
pub fn reserve_exact(&mut self, n: uint) { self.data.reserve_exact(n) }
- /// Reserve capacity for at least n elements in the PriorityQueue.
+ /// Reserve capacity for at least `n` elements in the PriorityQueue.
/// Do nothing if the capacity is already sufficient.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq: PriorityQueue<uint> = PriorityQueue::new();
+ /// pq.reserve(100u);
+ /// assert!(pq.capacity() >= 100u);
+ /// ```
pub fn reserve(&mut self, n: uint) {
self.data.reserve(n)
}
/// Remove the greatest item from a queue and return it, or `None` if it is
/// empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq = PriorityQueue::from_vec(vec![1i, 3]);
+ ///
+ /// assert_eq!(pq.pop(), Some(3i));
+ /// assert_eq!(pq.pop(), Some(1i));
+ /// assert_eq!(pq.pop(), None);
+ /// ```
pub fn pop(&mut self) -> Option<T> {
match self.data.pop() {
None => { None }
#[deprecated="renamed to `pop`"]
pub fn maybe_pop(&mut self) -> Option<T> { self.pop() }
- /// Push an item onto the queue
+ /// Push an item onto the queue.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq = PriorityQueue::new();
+ /// pq.push(3i);
+ /// pq.push(5i);
+ /// pq.push(1i);
+ ///
+ /// assert_eq!(pq.len(), 3);
+ /// assert_eq!(pq.top(), Some(&5i));
+ /// ```
pub fn push(&mut self, item: T) {
self.data.push(item);
let new_len = self.len() - 1;
self.siftup(0, new_len);
}
- /// Optimized version of a push followed by a pop
+ /// Optimized version of a push followed by a pop.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq = PriorityQueue::new();
+ /// pq.push(1i);
+ /// pq.push(5i);
+ ///
+ /// assert_eq!(pq.push_pop(3i), 5);
+ /// assert_eq!(pq.push_pop(9i), 9);
+ /// assert_eq!(pq.len(), 2);
+ /// assert_eq!(pq.top(), Some(&3i));
+ /// ```
pub fn push_pop(&mut self, mut item: T) -> T {
if !self.is_empty() && *self.top().unwrap() > item {
swap(&mut item, self.data.get_mut(0));
/// Optimized version of a pop followed by a push. The push is done
/// regardless of whether the queue is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq = PriorityQueue::new();
+ ///
+ /// assert_eq!(pq.replace(1i), None);
+ /// assert_eq!(pq.replace(3i), Some(1i));
+ /// assert_eq!(pq.len(), 1);
+ /// assert_eq!(pq.top(), Some(&3i));
+ /// ```
pub fn replace(&mut self, mut item: T) -> Option<T> {
if !self.is_empty() {
swap(&mut item, self.data.get_mut(0));
fn to_sorted_vec(self) -> Vec<T> { self.into_sorted_vec() }
/// Consume the PriorityQueue and return the underlying vector
+ /// in arbitrary order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let pq = PriorityQueue::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
+ /// let vec = pq.into_vec();
+ ///
+ /// // Will print in some order
+ /// for x in vec.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
pub fn into_vec(self) -> Vec<T> { let PriorityQueue{data: v} = self; v }
/// Consume the PriorityQueue and return a vector in sorted
- /// (ascending) order
+ /// (ascending) order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::PriorityQueue;
+ ///
+ /// let mut pq = PriorityQueue::from_vec(vec![1i, 2, 4, 5, 7]);
+ /// pq.push(6);
+ /// pq.push(3);
+ ///
+ /// let vec = pq.into_sorted_vec();
+ /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]);
+ /// ```
pub fn into_sorted_vec(self) -> Vec<T> {
let mut q = self;
let mut end = q.len();
q.into_vec()
}
- /// Create an empty PriorityQueue
- pub fn new() -> PriorityQueue<T> { PriorityQueue{data: vec!(),} }
-
- /// Create an empty PriorityQueue with capacity `capacity`
- pub fn with_capacity(capacity: uint) -> PriorityQueue<T> {
- PriorityQueue { data: Vec::with_capacity(capacity) }
- }
-
- /// Create a PriorityQueue from a vector (heapify)
- pub fn from_vec(xs: Vec<T>) -> PriorityQueue<T> {
- let mut q = PriorityQueue{data: xs,};
- let mut n = q.len() / 2;
- while n > 0 {
- n -= 1;
- q.siftdown(n)
- }
- q
- }
-
// The implementations of siftup and siftdown use unsafe blocks in
// order to move an element out of the vector (leaving behind a
// zeroed element), shift along the others and move it back into the
}
}
-/// PriorityQueue iterator
+/// PriorityQueue iterator.
pub struct Items <'a, T> {
iter: slice::Items<'a, T>,
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*!
- * A simple map based on a vector for small integer keys. Space requirements
- * are O(highest integer key).
- */
+//! A simple map based on a vector for small integer keys. Space requirements
+//! are O(highest integer key).
#![allow(missing_doc)]
use {vec, slice};
use vec::Vec;
-#[allow(missing_doc)]
+/// A map optimized for small integer keys.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::SmallIntMap;
+///
+/// let mut months = SmallIntMap::new();
+/// months.insert(1, "Jan");
+/// months.insert(2, "Feb");
+/// months.insert(3, "Mar");
+///
+/// if !months.contains_key(&12) {
+/// println!("The end is near!");
+/// }
+///
+/// assert_eq!(months.find(&1), Some(&"Jan"));
+///
+/// match months.find_mut(&3) {
+/// Some(value) => *value = "Venus",
+/// None => (),
+/// }
+///
+/// assert_eq!(months.find(&3), Some(&"Venus"));
+///
+/// // Print out all months
+/// for (key, value) in months.iter() {
+/// println!("month {} is {}", key, value);
+/// }
+///
+/// months.clear();
+/// assert!(months.is_empty());
+/// ```
pub struct SmallIntMap<T> {
v: Vec<Option<T>>,
}
impl<V> Collection for SmallIntMap<V> {
- /// Return the number of elements in the map
+ /// Return the number of elements in the map.
fn len(&self) -> uint {
self.v.iter().filter(|elt| elt.is_some()).count()
}
- /// Return true if there are no elements in the map
+ /// Return `true` if there are no elements in the map.
fn is_empty(&self) -> bool {
self.v.iter().all(|elt| elt.is_none())
}
}
impl<V> Map<uint, V> for SmallIntMap<V> {
- /// Return a reference to the value corresponding to the key
+ /// Return a reference to the value corresponding to the key.
fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
if *key < self.v.len() {
match *self.v.get(*key) {
}
impl<V> MutableMap<uint, V> for SmallIntMap<V> {
- /// Return a mutable reference to the value corresponding to the key
+ /// Return a mutable reference to the value corresponding to the key.
fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> {
if *key < self.v.len() {
match *self.v.get_mut(*key) {
}
/// Insert a key-value pair into the map. An existing value for a
- /// key is replaced by the new value. Return true if the key did
+ /// key is replaced by the new value. Return `true` if the key did
/// not already exist in the map.
fn insert(&mut self, key: uint, value: V) -> bool {
let exists = self.contains_key(&key);
!exists
}
- /// Remove a key-value pair from the map. Return true if the key
- /// was present in the map, otherwise false.
+ /// Remove a key-value pair from the map. Return `true` if the key
+ /// was present in the map, otherwise `false`.
fn remove(&mut self, key: &uint) -> bool {
self.pop(key).is_some()
}
/// Insert a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise None is returned.
+ /// present in the map, that value is returned. Otherwise `None` is returned.
fn swap(&mut self, key: uint, value: V) -> Option<V> {
match self.find_mut(&key) {
Some(loc) => { return Some(replace(loc, value)); }
}
impl<V> SmallIntMap<V> {
- /// Create an empty SmallIntMap
+ /// Create an empty SmallIntMap.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::SmallIntMap;
+ /// let mut map: SmallIntMap<&str> = SmallIntMap::new();
+ /// ```
pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
- /// Create an empty SmallIntMap with capacity `capacity`
+ /// Create an empty SmallIntMap with space for at least `capacity` elements
+ /// before resizing.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::SmallIntMap;
+ /// let mut map: SmallIntMap<&str> = SmallIntMap::with_capacity(10);
+ /// ```
pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
SmallIntMap { v: Vec::with_capacity(capacity) }
}
+ /// Retrieves a value for the given key.
+ /// See [`find`](../trait.Map.html#tymethod.find) for a non-failing alternative.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the key is not present.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::SmallIntMap;
+ ///
+ /// let mut map = SmallIntMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.get(&1), &"a");
+ /// ```
pub fn get<'a>(&'a self, key: &uint) -> &'a V {
self.find(key).expect("key not present")
}
/// An iterator visiting all key-value pairs in ascending order by the keys.
- /// Iterator element type is (uint, &'r V)
+ /// Iterator element type is `(uint, &'r V)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::SmallIntMap;
+ ///
+ /// let mut map = SmallIntMap::new();
+ /// map.insert(1, "a");
+ /// map.insert(3, "c");
+ /// map.insert(2, "b");
+ ///
+ /// // Print `1: a` then `2: b` then `3: c`
+ /// for (key, value) in map.iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ /// ```
pub fn iter<'r>(&'r self) -> Entries<'r, V> {
Entries {
front: 0,
/// An iterator visiting all key-value pairs in ascending order by the keys,
/// with mutable references to the values
- /// Iterator element type is (uint, &'r mut V)
+ /// Iterator element type is `(uint, &'r mut V)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::SmallIntMap;
+ ///
+ /// let mut map = SmallIntMap::new();
+ /// map.insert(1, "a");
+ /// map.insert(2, "b");
+ /// map.insert(3, "c");
+ ///
+ /// for (key, value) in map.mut_iter() {
+ /// *value = "x";
+ /// }
+ ///
+ /// for (key, value) in map.iter() {
+ /// assert_eq!(value, &"x");
+ /// }
+ /// ```
pub fn mut_iter<'r>(&'r mut self) -> MutEntries<'r, V> {
MutEntries {
front: 0,
}
}
- /// Empties the hash map, moving all values into the specified closure
+ /// Empties the hash map, moving all values into the specified closure.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::SmallIntMap;
+ ///
+ /// let mut map = SmallIntMap::new();
+ /// map.insert(1, "a");
+ /// map.insert(3, "c");
+ /// map.insert(2, "b");
+ ///
+ /// // Not possible with .iter()
+ /// let vec: Vec<(uint, &str)> = map.move_iter().collect();
+ ///
+ /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]);
+ /// ```
pub fn move_iter(&mut self)
-> FilterMap<(uint, Option<V>), (uint, V),
Enumerate<vec::MoveItems<Option<V>>>>
}
}
+/// Forward iterator over a map.
pub struct Entries<'a, T> {
front: uint,
back: uint,
iterator!(impl Entries -> (uint, &'a T), get_ref)
double_ended_iterator!(impl Entries -> (uint, &'a T), get_ref)
+/// Forward iterator over the key-value pairs of a map, with the
+/// values being mutable.
pub struct MutEntries<'a, T> {
front: uint,
back: uint,
/// Unsafe operations
pub mod raw {
- use core::prelude::*;
- use core::mem;
- use core::raw::Slice;
-
+ use string;
use string::String;
use vec::Vec;
pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
pub use core::str::raw::{slice_unchecked};
- /// Create a Rust string from a *u8 buffer of the given length
+ /// Deprecated. Replaced by `string::raw::from_buf_len`
+ #[deprecated = "Use string::raw::from_buf_len"]
pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
- let mut result = String::new();
- result.push_bytes(mem::transmute(Slice {
- data: buf,
- len: len,
- }));
- result
+ string::raw::from_buf_len(buf, len)
}
- /// Create a Rust string from a null-terminated C string
+ /// Deprecated. Use `string::raw::from_buf`
+ #[deprecated = "Use string::raw::from_buf"]
pub unsafe fn from_c_str(c_string: *const i8) -> String {
- let mut buf = String::new();
- let mut len = 0;
- while *c_string.offset(len) != 0 {
- len += 1;
- }
- buf.push_bytes(mem::transmute(Slice {
- data: c_string,
- len: len as uint,
- }));
- buf
+ string::raw::from_buf(c_string as *const u8)
}
- /// Converts an owned vector of bytes to a new owned string. This assumes
- /// that the utf-8-ness of the vector has already been validated
- #[inline]
+ /// Deprecated. Replaced by `string::raw::from_utf8`
+ #[deprecated = "Use string::raw::from_utf8"]
pub unsafe fn from_utf8_owned(v: Vec<u8>) -> String {
- mem::transmute(v)
+ string::raw::from_utf8(v)
}
- /// Converts a byte to a string.
+ /// Deprecated. Use `string::raw::from_utf8`
+ #[deprecated = "Use string::raw::from_utf8"]
pub unsafe fn from_byte(u: u8) -> String {
- from_utf8_owned(vec![u])
- }
-
- /// Sets the length of a string
- ///
- /// This will explicitly set the size of the string, without actually
- /// modifying its buffers, so it is up to the caller to ensure that
- /// the string is actually the specified size.
- #[test]
- fn test_from_buf_len() {
- use slice::ImmutableVector;
-
- unsafe {
- let a = vec![65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
- let b = a.as_ptr();
- let c = from_buf_len(b, 3u);
- assert_eq!(c, String::from_str("AAA"));
- }
+ string::raw::from_utf8(vec![u])
}
}
}
}
-/// Methods for owned strings
-pub trait OwnedStr {
- /// Consumes the string, returning the underlying byte buffer.
- ///
- /// The buffer does not have a null terminator.
- fn into_bytes(self) -> Vec<u8>;
-
- /// Pushes the given string onto this string, returning the concatenation of the two strings.
- fn append(self, rhs: &str) -> String;
-}
-
-impl OwnedStr for String {
- #[inline]
- fn into_bytes(self) -> Vec<u8> {
- unsafe { mem::transmute(self) }
- }
-
- #[inline]
- fn append(mut self, rhs: &str) -> String {
- self.push_str(rhs);
- self
- }
-}
-
#[cfg(test)]
mod tests {
use std::iter::AdditiveIterator;
[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
}
- #[test]
- fn test_raw_from_c_str() {
- unsafe {
- let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
- let b = a.as_ptr();
- let c = raw::from_c_str(b);
- assert_eq!(c, String::from_str("AAAAAAA"));
- }
- }
-
#[test]
fn test_as_bytes() {
// no null
}
}
- /// Creates a new string buffer from length, capacity, and a pointer.
- #[inline]
- pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
- String {
- vec: Vec::from_raw_parts(length, capacity, ptr),
- }
- }
-
/// Creates a new string buffer from the given string.
#[inline]
pub fn from_str(string: &str) -> String {
}
}
+ /// Deprecated. Replaced by `string::raw::from_parts`
+ #[inline]
+ #[deprecated = "Replaced by string::raw::from_parts"]
+ pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
+ raw::from_parts(ptr, length, capacity)
+ }
+
#[allow(missing_doc)]
#[deprecated = "obsoleted by the removal of ~str"]
#[inline]
}
}
+pub mod raw {
+ use core::mem;
+ use core::ptr::RawPtr;
+ use core::raw::Slice;
+
+ use super::String;
+ use vec::Vec;
+
+ /// Creates a new `String` from length, capacity, and a pointer.
+ ///
+ /// This is unsafe because:
+ /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`
+ /// * We assume that the `Vec` contains valid UTF-8
+ #[inline]
+ pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
+ String {
+ vec: Vec::from_raw_parts(length, capacity, buf),
+ }
+ }
+
+ /// Create `String` from a *u8 buffer of the given length
+ ///
+ /// This function is unsafe because of two reasons:
+ /// * A raw pointer is dereferenced and transmuted to `&[u8]`
+ /// * The slice is not checked to see whether it contains valid UTF-8
+ pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
+ use slice::CloneableVector;
+ let slice: &[u8] = mem::transmute(Slice {
+ data: buf,
+ len: len,
+ });
+ self::from_utf8(slice.to_vec())
+ }
+
+ /// Create a `String` from a null-terminated *u8 buffer
+ ///
+ /// This function is unsafe because we dereference memory until we find the NUL character,
+ /// which is not guaranteed to be present. Additionaly, the slice is not checked to see
+ /// whether it contains valid UTF-8
+ pub unsafe fn from_buf(buf: *const u8) -> String {
+ let mut len = 0;
+ while *buf.offset(len) != 0 {
+ len += 1;
+ }
+ self::from_buf_len(buf, len as uint)
+ }
+
+ /// Converts a vector of bytes to a new `String` without checking if
+ /// it contains valid UTF-8. This is unsafe because it assumes that
+ /// the utf-8-ness of the vector has already been validated.
+ #[inline]
+ pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
+ String { vec: bytes }
+ }
+}
+
#[cfg(test)]
mod tests {
use std::prelude::*;
String::from_str("\uFFFD𐒋\uFFFD"));
}
+ #[test]
+ fn test_from_buf_len() {
+ unsafe {
+ let a = vec![65u8, 65, 65, 65, 65, 65, 65, 0];
+ assert_eq!(super::raw::from_buf_len(a.as_ptr(), 3), String::from_str("AAA"));
+ }
+ }
+
+ #[test]
+ fn test_from_buf() {
+ unsafe {
+ let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
+ let b = a.as_ptr();
+ let c = super::raw::from_buf(b);
+ assert_eq!(c, String::from_str("AAAAAAA"));
+ }
+ }
+
#[test]
fn test_push_bytes() {
let mut s = String::from_str("ABC");
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
+//! Ordered containers with unsigned integer keys,
+//! implemented as radix tries (`TrieSet` and `TrieMap` types).
use core::prelude::*;
Nothing
}
-#[allow(missing_doc)]
+/// A map implemented as a radix trie.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::TrieMap;
+///
+/// let mut map = TrieMap::new();
+/// map.insert(27, "Olaf");
+/// map.insert(1, "Edgar");
+/// map.insert(13, "Ruth");
+/// map.insert(1, "Martin");
+///
+/// assert_eq!(map.len(), 3);
+/// assert_eq!(map.find(&1), Some(&"Martin"));
+///
+/// if !map.contains_key(&90) {
+/// println!("Nobody is keyed 90");
+/// }
+///
+/// // Update a key
+/// match map.find_mut(&1) {
+/// Some(value) => *value = "Olga",
+/// None => (),
+/// }
+///
+/// map.remove(&13);
+/// assert_eq!(map.len(), 2);
+///
+/// // Print the key value pairs, ordered by key.
+/// for (key, value) in map.iter() {
+/// // Prints `1: Olga` then `27: Olaf`
+/// println!("{}: {}", key, value);
+/// }
+///
+/// map.clear();
+/// assert!(map.is_empty());
+/// ```
pub struct TrieMap<T> {
root: TrieNode<T>,
length: uint
impl<T: Eq> Eq for TrieMap<T> {}
impl<T> Collection for TrieMap<T> {
- /// Return the number of elements in the map
+ /// Return the number of elements in the map.
#[inline]
fn len(&self) -> uint { self.length }
}
}
impl<T> Map<uint, T> for TrieMap<T> {
- /// Return a reference to the value corresponding to the key
+ /// Return a reference to the value corresponding to the key.
#[inline]
fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
let mut node: &'a TrieNode<T> = &self.root;
}
impl<T> MutableMap<uint, T> for TrieMap<T> {
- /// Return a mutable reference to the value corresponding to the key
+ /// Return a mutable reference to the value corresponding to the key.
#[inline]
fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
}
impl<T> TrieMap<T> {
- /// Create an empty TrieMap
+ /// Create an empty TrieMap.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<&str> = TrieMap::new();
+ /// ```
#[inline]
pub fn new() -> TrieMap<T> {
TrieMap{root: TrieNode::new(), length: 0}
}
- /// Visit all key-value pairs in reverse order
+ /// Visit all key-value pairs in reverse order. Abort traversal when f returns false.
+ /// Return true if f returns true for all elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(1, "a"), (2, "b"), (3, "c")].iter().map(|&x| x).collect();
+ ///
+ /// let mut vec = Vec::new();
+ /// assert_eq!(true, map.each_reverse(|&key, &value| { vec.push((key, value)); true }));
+ /// assert_eq!(vec, vec![(3, "c"), (2, "b"), (1, "a")]);
+ ///
+ /// // Stop when we reach 2
+ /// let mut vec = Vec::new();
+ /// assert_eq!(false, map.each_reverse(|&key, &value| { vec.push(value); key != 2 }));
+ /// assert_eq!(vec, vec!["c", "b"]);
+ /// ```
#[inline]
pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
self.root.each_reverse(f)
}
- /// Get an iterator over the key-value pairs in the map
+ /// Get an iterator over the key-value pairs in the map, ordered by keys.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(3, "c"), (1, "a"), (2, "b")].iter().map(|&x| x).collect();
+ ///
+ /// for (key, value) in map.iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ /// ```
pub fn iter<'a>(&'a self) -> Entries<'a, T> {
let mut iter = unsafe {Entries::new()};
iter.stack[0] = self.root.children.iter();
/// Get an iterator over the key-value pairs in the map, with the
/// ability to mutate the values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<int> = [(1, 2), (2, 4), (3, 6)].iter().map(|&x| x).collect();
+ ///
+ /// for (key, value) in map.mut_iter() {
+ /// *value = -(key as int);
+ /// }
+ ///
+ /// assert_eq!(map.find(&1), Some(&-1));
+ /// assert_eq!(map.find(&2), Some(&-2));
+ /// assert_eq!(map.find(&3), Some(&-3));
+ /// ```
pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, T> {
let mut iter = unsafe {MutEntries::new()};
iter.stack[0] = self.root.children.mut_iter();
/// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
/// If all keys in the map are less than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.lower_bound(4).next(), Some((4, &"b")));
+ /// assert_eq!(map.lower_bound(5).next(), Some((6, &"c")));
+ /// assert_eq!(map.lower_bound(10).next(), None);
+ /// ```
pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
self.bound(key, false)
}
/// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
/// If all keys in the map are not greater than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.upper_bound(4).next(), Some((6, &"c")));
+ /// assert_eq!(map.upper_bound(5).next(), Some((6, &"c")));
+ /// assert_eq!(map.upper_bound(10).next(), None);
+ /// ```
pub fn upper_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
self.bound(key, true)
}
/// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
/// If all keys in the map are less than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.mut_lower_bound(4).next(), Some((4, &mut "b")));
+ /// assert_eq!(map.mut_lower_bound(5).next(), Some((6, &mut "c")));
+ /// assert_eq!(map.mut_lower_bound(10).next(), None);
+ ///
+ /// for (key, value) in map.mut_lower_bound(4) {
+ /// *value = "changed";
+ /// }
+ ///
+ /// assert_eq!(map.find(&2), Some(&"a"));
+ /// assert_eq!(map.find(&4), Some(&"changed"));
+ /// assert_eq!(map.find(&6), Some(&"changed"));
+ /// ```
pub fn mut_lower_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
self.mut_bound(key, false)
}
/// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
/// If all keys in the map are not greater than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.mut_upper_bound(4).next(), Some((6, &mut "c")));
+ /// assert_eq!(map.mut_upper_bound(5).next(), Some((6, &mut "c")));
+ /// assert_eq!(map.mut_upper_bound(10).next(), None);
+ ///
+ /// for (key, value) in map.mut_upper_bound(4) {
+ /// *value = "changed";
+ /// }
+ ///
+ /// assert_eq!(map.find(&2), Some(&"a"));
+ /// assert_eq!(map.find(&4), Some(&"b"));
+ /// assert_eq!(map.find(&6), Some(&"changed"));
+ /// ```
pub fn mut_upper_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
self.mut_bound(key, true)
}
}
}
-#[allow(missing_doc)]
+/// A set implemented as a radix trie.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::TrieSet;
+///
+/// let mut set = TrieSet::new();
+/// set.insert(6);
+/// set.insert(28);
+/// set.insert(6);
+///
+/// assert_eq!(set.len(), 2);
+///
+/// if !set.contains(&3) {
+/// println!("3 is not in the set");
+/// }
+///
+/// // Print contents in order
+/// for x in set.iter() {
+/// println!("{}", x);
+/// }
+///
+/// set.remove(&6);
+/// assert_eq!(set.len(), 1);
+///
+/// set.clear();
+/// assert!(set.is_empty());
+/// ```
#[deriving(Hash, PartialEq, Eq)]
pub struct TrieSet {
map: TrieMap<()>
}
impl Collection for TrieSet {
- /// Return the number of elements in the set
+ /// Return the number of elements in the set.
#[inline]
fn len(&self) -> uint { self.map.len() }
}
}
impl TrieSet {
- /// Create an empty TrieSet
+ /// Create an empty TrieSet.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ /// let mut set = TrieSet::new();
+ /// ```
#[inline]
pub fn new() -> TrieSet {
TrieSet{map: TrieMap::new()}
}
- /// Visit all values in reverse order
+ /// Visit all values in reverse order. Abort traversal when `f` returns false.
+ /// Return `true` if `f` returns `true` for all elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect();
+ ///
+ /// let mut vec = Vec::new();
+ /// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true }));
+ /// assert_eq!(vec, vec![5, 4, 3, 2, 1]);
+ ///
+ /// // Stop when we reach 3
+ /// let mut vec = Vec::new();
+ /// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 }));
+ /// assert_eq!(vec, vec![5, 4, 3]);
+ /// ```
#[inline]
pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
self.map.each_reverse(|k, _| f(k))
}
- /// Get an iterator over the values in the set
+ /// Get an iterator over the values in the set, in sorted order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut set = TrieSet::new();
+ /// set.insert(3);
+ /// set.insert(2);
+ /// set.insert(1);
+ /// set.insert(2);
+ ///
+ /// // Print 1, 2, 3
+ /// for x in set.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
#[inline]
pub fn iter<'a>(&'a self) -> SetItems<'a> {
SetItems{iter: self.map.iter()}
/// Get an iterator pointing to the first value that is not less than `val`.
/// If all values in the set are less than `val` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
+ /// assert_eq!(set.lower_bound(4).next(), Some(4));
+ /// assert_eq!(set.lower_bound(5).next(), Some(6));
+ /// assert_eq!(set.lower_bound(10).next(), None);
+ /// ```
pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.lower_bound(val)}
}
/// Get an iterator pointing to the first value that key is greater than `val`.
- /// If all values in the set are not greater than `val` an empty iterator is returned.
+ /// If all values in the set are less than or equal to `val` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
+ /// assert_eq!(set.upper_bound(4).next(), Some(6));
+ /// assert_eq!(set.upper_bound(5).next(), Some(6));
+ /// assert_eq!(set.upper_bound(10).next(), None);
+ /// ```
pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.upper_bound(val)}
}
return ret;
}
-/// Forward iterator over a map
+/// Forward iterator over a map.
pub struct Entries<'a, T> {
stack: [slice::Items<'a, Child<T>>, .. NUM_CHUNKS],
length: uint,
iterator_impl! { Entries, iter = iter, mutability = }
iterator_impl! { MutEntries, iter = mut_iter, mutability = mut }
-/// Forward iterator over a set
+/// Forward iterator over a set.
pub struct SetItems<'a> {
iter: Entries<'a, ()>
}
/// Performs addition that returns `None` instead of wrapping around on overflow.
pub trait CheckedAdd: Add<Self, Self> {
/// Adds two numbers, checking for overflow. If overflow happens, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::num::CheckedAdd;
+ /// assert_eq!(5u16.checked_add(&65530), Some(65535));
+ /// assert_eq!(6u16.checked_add(&65530), None);
+ /// ```
fn checked_add(&self, v: &Self) -> Option<Self>;
}
/// Performs subtraction that returns `None` instead of wrapping around on underflow.
pub trait CheckedSub: Sub<Self, Self> {
/// Subtracts two numbers, checking for underflow. If underflow happens, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::num::CheckedSub;
+ /// assert_eq!((-127i8).checked_sub(&1), Some(-128));
+ /// assert_eq!((-128i8).checked_sub(&1), None);
+ /// ```
fn checked_sub(&self, v: &Self) -> Option<Self>;
}
pub trait CheckedMul: Mul<Self, Self> {
/// Multiplies two numbers, checking for underflow or overflow. If underflow or overflow
/// happens, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::num::CheckedMul;
+ /// assert_eq!(5u8.checked_mul(&51), Some(255));
+ /// assert_eq!(5u8.checked_mul(&52), None);
+ /// ```
fn checked_mul(&self, v: &Self) -> Option<Self>;
}
pub trait CheckedDiv: Div<Self, Self> {
/// Divides two numbers, checking for underflow or overflow. If underflow or overflow happens,
/// `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::num::CheckedDiv;
+ /// assert_eq!((-127i8).checked_div(&-1), Some(127));
+ /// assert_eq!((-128i8).checked_div(&-1), None);
+ /// ```
fn checked_div(&self, v: &Self) -> Option<Self>;
}
fn call_once(self, args: Args) -> Result;
}
+macro_rules! def_fn_mut(
+ ($($args:ident)*) => (
+ #[cfg(not(stage0))]
+ impl<Result$(,$args)*>
+ FnMut<($($args,)*),Result>
+ for extern "Rust" fn($($args: $args,)*) -> Result {
+ #[rust_call_abi_hack]
+ #[allow(uppercase_variables)]
+ fn call_mut(&mut self, args: ($($args,)*)) -> Result {
+ let ($($args,)*) = args;
+ (*self)($($args,)*)
+ }
+ }
+ )
+)
+
+def_fn_mut!()
+def_fn_mut!(A0)
+def_fn_mut!(A0 A1)
+def_fn_mut!(A0 A1 A2)
+def_fn_mut!(A0 A1 A2 A3)
+def_fn_mut!(A0 A1 A2 A3 A4)
+def_fn_mut!(A0 A1 A2 A3 A4 A5)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14)
+def_fn_mut!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15)
+
use core::ptr::*;
use libc::c_char;
use core::mem;
-use std::str;
use libc;
+use std::c_str::CString;
#[test]
fn test() {
let mut ctr = 0;
let mut iteration_count = 0;
array_each_with_len(arr.as_ptr(), arr.len(), |e| {
- let actual = str::raw::from_c_str(e);
- let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr());
- assert_eq!(actual.as_slice(), expected.as_slice());
+ let actual = CString::new(e, false);
+ assert_eq!(actual.as_str(), expected_arr[ctr].as_str());
ctr += 1;
iteration_count += 1;
});
let mut ctr = 0u;
let mut iteration_count = 0u;
array_each(arr_ptr, |e| {
- let actual = str::raw::from_c_str(e);
- let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr());
- assert_eq!(actual.as_slice(), expected.as_slice());
+ let actual = CString::new(e, false);
+ assert_eq!(actual.as_str(), expected_arr[ctr].as_str());
ctr += 1;
iteration_count += 1;
});
fn test_ptr_array_each_with_len_null_ptr() {
unsafe {
array_each_with_len(0 as *const *const libc::c_char, 1, |e| {
- str::raw::from_c_str(e);
+ CString::new(e, false).as_str().unwrap();
});
}
}
fn test_ptr_array_each_null_ptr() {
unsafe {
array_each(0 as *const *const libc::c_char, |e| {
- str::raw::from_c_str(e);
+ CString::new(e, false).as_str().unwrap();
});
}
}
// Take a main task to run, and a scheduler to run it in. Create a
// scheduler task and bootstrap into it.
- pub fn bootstrap(mut ~self) {
+ pub fn bootstrap(mut self: Box<Scheduler>) {
// Build an Idle callback.
let cb = box SchedRunner as Box<Callback + Send>;
// This does not return a scheduler, as the scheduler is placed
// inside the task.
- pub fn run(mut ~self, stask: Box<GreenTask>) -> Box<GreenTask> {
+ pub fn run(mut self: Box<Scheduler>, stask: Box<GreenTask>)
+ -> Box<GreenTask> {
// This is unsafe because we need to place the scheduler, with
// the event_loop inside, inside our task. But we still need a
// If we try really hard to do some work, but no work is available to be
// done, then we fall back to epoll() to block this thread waiting for more
// work (instead of busy waiting).
- fn run_sched_once(mut ~self, stask: Box<GreenTask>) {
+ fn run_sched_once(mut self: Box<Scheduler>, stask: Box<GreenTask>) {
// Make sure that we're not lying in that the `stask` argument is indeed
// the scheduler task for this scheduler.
assert!(self.sched_task.is_none());
// returns the still-available scheduler. At this point all
// message-handling will count as a turn of work, and as a result
// return None.
- fn interpret_message_queue(mut ~self, stask: Box<GreenTask>,
+ fn interpret_message_queue(mut self: Box<Scheduler>,
+ stask: Box<GreenTask>,
effort: EffortLevel)
- -> (Box<Scheduler>, Box<GreenTask>, bool)
- {
-
+ -> (Box<Scheduler>, Box<GreenTask>, bool) {
let msg = if effort == DontTryTooHard {
self.message_queue.casual_pop()
} else {
}
}
- fn do_work(mut ~self, stask: Box<GreenTask>)
+ fn do_work(mut self: Box<Scheduler>, stask: Box<GreenTask>)
-> (Box<Scheduler>, Box<GreenTask>, bool) {
rtdebug!("scheduler calling do work");
match self.find_work() {
// * Task Routing Functions - Make sure tasks send up in the right
// place.
- fn process_task(mut ~self,
+ fn process_task(mut self: Box<Scheduler>,
cur: Box<GreenTask>,
mut next: Box<GreenTask>,
schedule_fn: SchedulingFn)
// cleanup function f, which takes the scheduler and the
// old task as inputs.
- pub fn change_task_context(mut ~self,
+ pub fn change_task_context(mut self: Box<Scheduler>,
mut current_task: Box<GreenTask>,
mut next_task: Box<GreenTask>,
f: |&mut Scheduler, Box<GreenTask>|)
// * Context Swapping Helpers - Here be ugliness!
- pub fn resume_task_immediately(~self,
+ pub fn resume_task_immediately(self: Box<Scheduler>,
cur: Box<GreenTask>,
next: Box<GreenTask>)
-> (Box<Scheduler>, Box<GreenTask>) {
/// This situation is currently prevented, or in other words it is
/// guaranteed that this function will not return before the given closure
/// has returned.
- pub fn deschedule_running_task_and_then(mut ~self,
+ pub fn deschedule_running_task_and_then(mut self: Box<Scheduler>,
cur: Box<GreenTask>,
f: |&mut Scheduler, BlockedTask|) {
// Trickier - we need to get the scheduler task out of self
self.switch_running_tasks_and_then(cur, stask, f)
}
- pub fn switch_running_tasks_and_then(~self,
+ pub fn switch_running_tasks_and_then(self: Box<Scheduler>,
cur: Box<GreenTask>,
next: Box<GreenTask>,
f: |&mut Scheduler, BlockedTask|) {
/// Called by a running task to end execution, after which it will
/// be recycled by the scheduler for reuse in a new task.
- pub fn terminate_current_task(mut ~self, cur: Box<GreenTask>) -> ! {
+ pub fn terminate_current_task(mut self: Box<Scheduler>,
+ cur: Box<GreenTask>)
+ -> ! {
// Similar to deschedule running task and then, but cannot go through
// the task-blocking path. The task is already dying.
let stask = self.sched_task.take_unwrap();
fail!("should never return!");
}
- pub fn run_task(~self, cur: Box<GreenTask>, next: Box<GreenTask>) {
+ pub fn run_task(self: Box<Scheduler>,
+ cur: Box<GreenTask>,
+ next: Box<GreenTask>) {
let (sched, task) =
self.process_task(cur, next, Scheduler::switch_task);
task.put_with_sched(sched);
/// to introduce some amount of randomness to the scheduler. Currently the
/// randomness is a result of performing a round of work stealing (which
/// may end up stealing from the current scheduler).
- pub fn yield_now(mut ~self, cur: Box<GreenTask>) {
+ pub fn yield_now(mut self: Box<Scheduler>, cur: Box<GreenTask>) {
// Async handles trigger the scheduler by calling yield_now on the local
// task, which eventually gets us to here. See comments in SchedRunner
// for more info on this.
}
}
- pub fn maybe_yield(mut ~self, cur: Box<GreenTask>) {
+ pub fn maybe_yield(mut self: Box<Scheduler>, cur: Box<GreenTask>) {
// It's possible for sched tasks to possibly call this function, and it
// just means that they're likely sending on channels (which
// occasionally call this function). Sched tasks follow different paths
impl Runtime for SimpleTask {
// Implement the simple tasks of descheduling and rescheduling, but only in
// a simple number of cases.
- fn deschedule(mut ~self, times: uint, mut cur_task: Box<Task>,
+ fn deschedule(mut self: Box<SimpleTask>,
+ times: uint,
+ mut cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>) {
assert!(times == 1);
}
Local::put(cur_task);
}
- fn reawaken(mut ~self, mut to_wake: Box<Task>) {
+ fn reawaken(mut self: Box<SimpleTask>, mut to_wake: Box<Task>) {
let me = &mut *self as *mut SimpleTask;
to_wake.put_runtime(self);
unsafe {
// purpose. A "simple task" is just that, a very simple task that can't
// really do a whole lot. The only purpose of the task is to get us off our
// feet and running.
- fn yield_now(~self, _cur_task: Box<Task>) { fail!() }
- fn maybe_yield(~self, _cur_task: Box<Task>) { fail!() }
- fn spawn_sibling(~self,
+ fn yield_now(self: Box<SimpleTask>, _cur_task: Box<Task>) { fail!() }
+ fn maybe_yield(self: Box<SimpleTask>, _cur_task: Box<Task>) { fail!() }
+ fn spawn_sibling(self: Box<SimpleTask>,
_cur_task: Box<Task>,
_opts: TaskOpts,
_f: proc():Send) {
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
fn stack_bounds(&self) -> (uint, uint) { fail!() }
fn can_block(&self) -> bool { true }
- fn wrap(~self) -> Box<Any> { fail!() }
+ fn wrap(self: Box<SimpleTask>) -> Box<Any> { fail!() }
}
pub fn task() -> Box<Task> {
// Runtime glue functions and helpers
- pub fn put_with_sched(mut ~self, sched: Box<Scheduler>) {
+ pub fn put_with_sched(mut self: Box<GreenTask>, sched: Box<Scheduler>) {
assert!(self.sched.is_none());
self.sched = Some(sched);
self.put();
self.task = Some(task);
}
- pub fn swap(mut ~self) -> Box<Task> {
+ pub fn swap(mut self: Box<GreenTask>) -> Box<Task> {
let mut task = self.task.take_unwrap();
task.put_runtime(self);
return task;
}
- pub fn put(~self) {
+ pub fn put(self: Box<GreenTask>) {
assert!(self.sched.is_some());
Local::put(self.swap());
}
- fn terminate(mut ~self) -> ! {
+ fn terminate(mut self: Box<GreenTask>) -> ! {
let sched = self.sched.take_unwrap();
sched.terminate_current_task(self)
}
// *not* a cheap operation to clone a handle. Until the day comes that we
// need to optimize this, a lock should do just fine (it's completely
// uncontended except for when the task is rescheduled).
- fn reawaken_remotely(mut ~self) {
+ fn reawaken_remotely(mut self: Box<GreenTask>) {
unsafe {
let mtx = &mut self.nasty_deschedule_lock as *mut NativeMutex;
let handle = self.handle.get_mut_ref() as *mut SchedHandle;
}
impl Runtime for GreenTask {
- fn yield_now(mut ~self, cur_task: Box<Task>) {
+ fn yield_now(mut self: Box<GreenTask>, cur_task: Box<Task>) {
self.put_task(cur_task);
let sched = self.sched.take_unwrap();
sched.yield_now(self);
}
- fn maybe_yield(mut ~self, cur_task: Box<Task>) {
+ fn maybe_yield(mut self: Box<GreenTask>, cur_task: Box<Task>) {
self.put_task(cur_task);
let sched = self.sched.take_unwrap();
sched.maybe_yield(self);
}
- fn deschedule(mut ~self, times: uint, cur_task: Box<Task>,
+ fn deschedule(mut self: Box<GreenTask>,
+ times: uint,
+ cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>) {
self.put_task(cur_task);
let mut sched = self.sched.take_unwrap();
}
}
- fn reawaken(mut ~self, to_wake: Box<Task>) {
+ fn reawaken(mut self: Box<GreenTask>, to_wake: Box<Task>) {
self.put_task(to_wake);
assert!(self.sched.is_none());
}
}
- fn spawn_sibling(mut ~self,
+ fn spawn_sibling(mut self: Box<GreenTask>,
cur_task: Box<Task>,
opts: TaskOpts,
f: proc():Send) {
fn can_block(&self) -> bool { false }
- fn wrap(~self) -> Box<Any> { self as Box<Any> }
+ fn wrap(self: Box<GreenTask>) -> Box<Any> { self as Box<Any> }
}
#[cfg(test)]
use libc::{c_char, c_int};
use libc;
-use std::c_str::CString;
use std::mem;
use std::ptr::{null, mut_null};
use std::rt::rtio;
{
assert!(host.is_some() || servname.is_some());
- let c_host = host.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
- let c_serv = servname.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
+ let c_host = host.map(|x| x.to_c_str());
+ let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
+ let c_serv = servname.map(|x| x.to_c_str());
+ let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
let hint = hint.map(|hint| {
libc::addrinfo {
// Make the call
let s = unsafe {
- let ch = if c_host.is_null() { null() } else { c_host.as_ptr() };
- let cs = if c_serv.is_null() { null() } else { c_serv.as_ptr() };
- getaddrinfo(ch, cs, hint_ptr, &mut res)
+ getaddrinfo(c_host, c_serv, hint_ptr, &mut res)
};
// Error?
#[cfg(not(windows))]
fn get_error(s: c_int) -> IoError {
+ use std::c_str::CString;
let err_str = unsafe {
CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
}
impl rtio::RtioTcpListener for TcpListener {
- fn listen(~self) -> IoResult<Box<rtio::RtioTcpAcceptor + Send>> {
+ fn listen(self: Box<TcpListener>)
+ -> IoResult<Box<rtio::RtioTcpAcceptor + Send>> {
self.native_listen(128).map(|a| {
box a as Box<rtio::RtioTcpAcceptor + Send>
})
}
impl rtio::RtioUnixListener for UnixListener {
- fn listen(~self) -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
+ fn listen(self: Box<UnixListener>)
+ -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
self.native_listen(128).map(|a| {
box a as Box<rtio::RtioUnixAcceptor + Send>
})
}
impl rtio::RtioUnixListener for UnixListener {
- fn listen(~self) -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
+ fn listen(self: Box<UnixListener>)
+ -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
self.native_listen().map(|a| {
box a as Box<rtio::RtioUnixAcceptor + Send>
})
}
impl rt::Runtime for Ops {
- fn yield_now(~self, mut cur_task: Box<Task>) {
+ fn yield_now(self: Box<Ops>, mut cur_task: Box<Task>) {
// put the task back in TLS and then invoke the OS thread yield
cur_task.put_runtime(self);
Local::put(cur_task);
Thread::yield_now();
}
- fn maybe_yield(~self, mut cur_task: Box<Task>) {
+ fn maybe_yield(self: Box<Ops>, mut cur_task: Box<Task>) {
// just put the task back in TLS, on OS threads we never need to
// opportunistically yield b/c the OS will do that for us (preemption)
cur_task.put_runtime(self);
Local::put(cur_task);
}
- fn wrap(~self) -> Box<Any> {
+ fn wrap(self: Box<Ops>) -> Box<Any> {
self as Box<Any>
}
// `awoken` field which indicates whether we were actually woken up via some
// invocation of `reawaken`. This flag is only ever accessed inside the
// lock, so there's no need to make it atomic.
- fn deschedule(mut ~self, times: uint, mut cur_task: Box<Task>,
+ fn deschedule(mut self: Box<Ops>,
+ times: uint,
+ mut cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>) {
let me = &mut *self as *mut Ops;
cur_task.put_runtime(self);
// See the comments on `deschedule` for why the task is forgotten here, and
// why it's valid to do so.
- fn reawaken(mut ~self, mut to_wake: Box<Task>) {
+ fn reawaken(mut self: Box<Ops>, mut to_wake: Box<Task>) {
unsafe {
let me = &mut *self as *mut Ops;
to_wake.put_runtime(self);
}
}
- fn spawn_sibling(~self,
+ fn spawn_sibling(self: Box<Ops>,
mut cur_task: Box<Task>,
opts: TaskOpts,
f: proc():Send) {
use std::mem;
use std::ptr;
use std::slice;
-use std::str;
+use std::string;
use std::collections::{HashMap, HashSet};
use flate;
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
let mut name_buf = ptr::null();
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
- let name = str::raw::from_buf_len(name_buf as *const u8,
+ let name = string::raw::from_buf_len(name_buf as *const u8,
name_len as uint);
debug!("get_metadata_section: name {}", name);
if read_meta_section_name(os).as_slice() == name.as_slice() {
TrByCopy(llbinding) => {
let llval = Load(bcx, binding_info.llmatch);
let datum = Datum::new(llval, binding_info.ty, Lvalue);
+ call_lifetime_start(bcx, llbinding);
bcx = datum.store_to(bcx, llbinding);
+ match cs {
+ Some(cs) => bcx.fcx.schedule_lifetime_end(cs, llbinding),
+ _ => {}
+ }
llbinding
},
let datum = Datum::new(llval, binding_info.ty, Lvalue);
match cs {
- Some(cs) => bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty),
+ Some(cs) => {
+ bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty);
+ bcx.fcx.schedule_lifetime_end(cs, binding_info.llmatch);
+ }
_ => {}
}
let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
let val = val.to_llbool(bcx);
+ for (_, &binding_info) in data.bindings_map.iter() {
+ match binding_info.trmode {
+ TrByCopy(llbinding) => call_lifetime_end(bcx, llbinding),
+ _ => {}
+ }
+ }
+
return with_cond(bcx, Not(bcx, val), |bcx| {
// Guard does not match: remove all bindings from the lllocals table
for (_, &binding_info) in data.bindings_map.iter() {
+ call_lifetime_end(bcx, binding_info.llmatch);
bcx.fcx.lllocals.borrow_mut().remove(&binding_info.id);
}
match chk {
let data = &m[0].data;
for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
let llmatch = data.bindings_map.get(ident).llmatch;
+ call_lifetime_start(bcx, llmatch);
Store(bcx, *value_ptr, llmatch);
}
match data.arm.guard {
match bm {
ast::BindByValue(_)
if !ty::type_moves_by_default(tcx, variable_ty) => {
- llmatch = alloca(bcx,
+ llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),
"__llmatch");
- trmode = TrByCopy(alloca(bcx,
+ trmode = TrByCopy(alloca_no_lifetime(bcx,
llvariable_ty,
bcx.ident(ident).as_slice()));
}
// in this case, the final type of the variable will be T,
// but during matching we need to store a *T as explained
// above
- llmatch = alloca(bcx,
+ llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),
bcx.ident(ident).as_slice());
trmode = TrByMove;
}
ast::BindByRef(_) => {
- llmatch = alloca(bcx,
+ llmatch = alloca_no_lifetime(bcx,
llvariable_ty,
bcx.ident(ident).as_slice());
trmode = TrByRef;
}
pub fn alloca(cx: &Block, ty: Type, name: &str) -> ValueRef {
- alloca_maybe_zeroed(cx, ty, name, false)
+ let p = alloca_no_lifetime(cx, ty, name);
+ call_lifetime_start(cx, p);
+ p
}
-pub fn alloca_maybe_zeroed(cx: &Block, ty: Type, name: &str, zero: bool) -> ValueRef {
+pub fn alloca_no_lifetime(cx: &Block, ty: Type, name: &str) -> ValueRef {
let _icx = push_ctxt("alloca");
if cx.unreachable.get() {
unsafe {
}
}
debuginfo::clear_source_location(cx.fcx);
- let p = Alloca(cx, ty, name);
- if zero {
- let b = cx.fcx.ccx.builder();
- b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
- memzero(&b, p, ty);
- } else {
- call_lifetime_start(cx, p);
+ Alloca(cx, ty, name)
+}
+
+pub fn alloca_zeroed(cx: &Block, ty: Type, name: &str) -> ValueRef {
+ if cx.unreachable.get() {
+ unsafe {
+ return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
+ }
}
+ let p = alloca_no_lifetime(cx, ty, name);
+ let b = cx.fcx.ccx.builder();
+ b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
+ memzero(&b, p, ty);
p
}
*/
let llty = type_of::type_of(bcx.ccx(), ty);
- let scratch = alloca_maybe_zeroed(bcx, llty, name, zero);
+ let scratch = if zero {
+ alloca_zeroed(bcx, llty, name)
+ } else {
+ alloca(bcx, llty, name)
+ };
// Subtle. Populate the scratch memory *before* scheduling cleanup.
let bcx = populate(arg, bcx, scratch);
*/
let llty = type_of::type_of(bcx.ccx(), ty);
- let scratch = alloca_maybe_zeroed(bcx, llty, name, false);
+ let scratch = alloca(bcx, llty, name);
Datum::new(scratch, ty, Rvalue::new(ByRef))
}
use std::c_str::ToCStr;
use std::mem;
+use std::string;
use std::cell::RefCell;
use std::collections::HashMap;
-use std::str::raw::from_c_str;
use libc::{c_uint, c_void, free};
pub fn type_to_string(&self, ty: Type) -> String {
unsafe {
let s = llvm::LLVMTypeToString(ty.to_ref());
- let ret = from_c_str(s);
+ let ret = string::raw::from_buf(s as *const u8);
free(s as *mut c_void);
- ret.to_string()
+ ret
}
}
pub fn val_to_string(&self, val: ValueRef) -> String {
unsafe {
let s = llvm::LLVMValueToString(val);
- let ret = from_c_str(s);
+ let ret = string::raw::from_buf(s as *const u8);
free(s as *mut c_void);
- ret.to_string()
+ ret
}
}
}
use middle::def;
use middle::lang_items::FnMutTraitLangItem;
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
+use middle::subst::{VecPerParamSpace};
use middle::ty;
use middle::ty_fold::TypeFolder;
use middle::typeck::rscope::{ExplicitRscope, ImpliedSingleRscope};
TypeAndSubsts { substs: substs, ty: ty }
}
+/// Returns the type that this AST path refers to. If the path has no type
+/// parameters and the corresponding type has type parameters, fresh type
+/// and/or region variables are substituted.
+///
+/// This is used when checking the constructor in struct literals.
+pub fn ast_path_to_ty_relaxed<AC:AstConv,
+ RS:RegionScope>(
+ this: &AC,
+ rscope: &RS,
+ did: ast::DefId,
+ path: &ast::Path)
+ -> TypeAndSubsts {
+ let tcx = this.tcx();
+ let ty::Polytype {
+ generics: generics,
+ ty: decl_ty
+ } = this.get_item_ty(did);
+
+ let substs = if (generics.has_type_params(TypeSpace) ||
+ generics.has_region_params(TypeSpace)) &&
+ path.segments.iter().all(|s| {
+ s.lifetimes.len() == 0 && s.types.len() == 0
+ }) {
+ let type_params = Vec::from_fn(generics.types.len(TypeSpace),
+ |_| this.ty_infer(path.span));
+ let region_params =
+ rscope.anon_regions(path.span, generics.regions.len(TypeSpace))
+ .unwrap();
+ Substs::new(VecPerParamSpace::params_from_type(type_params),
+ VecPerParamSpace::params_from_type(region_params))
+ } else {
+ ast_path_substs(this, rscope, &generics, None, path)
+ };
+
+ let ty = decl_ty.subst(tcx, &substs);
+ TypeAndSubsts {
+ substs: substs,
+ ty: ty,
+ }
+}
+
pub static NO_REGIONS: uint = 1;
pub static NO_TPS: uint = 2;
lifetime);
ty::ByReferenceExplicitSelfCategory(region, mutability)
}
- ast::SelfUniq(_) => ty::ByBoxExplicitSelfCategory,
ast::SelfExplicit(ast_type, _) => {
let explicit_type = ast_ty_to_ty(this, rscope, &*ast_type);
callee_type: ty::t,
args: &[Gc<ast::Expr>])
-> bool {
+ // Bail out if the callee is a bare function or a closure. We check those
+ // manually.
+ match *structure_of(fcx, callee.span, callee_type) {
+ ty::ty_bare_fn(_) | ty::ty_closure(_) => return false,
+ _ => {}
+ }
+
// Try `FnOnce`, then `FnMut`, then `Fn`.
for &(maybe_function_trait, method_name) in [
(fcx.tcx().lang_items.fn_once_trait(), token::intern("call_once")),
ast::ExprStruct(ref path, ref fields, base_expr) => {
// Resolve the path.
let def = tcx.def_map.borrow().find(&id).map(|i| *i);
- match def {
+ let struct_id = match def {
Some(def::DefVariant(enum_id, variant_id, _)) => {
check_struct_enum_variant(fcx, id, expr.span, enum_id,
variant_id, fields.as_slice());
+ enum_id
}
Some(def) => {
// Verify that this was actually a struct.
pprust::path_to_string(path));
}
}
+
+ def.def_id()
}
_ => {
tcx.sess.span_bug(path.span,
"structure constructor wasn't resolved")
}
+ };
+
+ // Turn the path into a type and verify that that type unifies with
+ // the resulting structure type. This is needed to handle type
+ // parameters correctly.
+ let actual_structure_type = fcx.expr_ty(&*expr);
+ if !ty::type_is_error(actual_structure_type) {
+ let type_and_substs = astconv::ast_path_to_ty_relaxed(fcx,
+ fcx.infcx(),
+ struct_id,
+ path);
+ match fcx.mk_subty(false,
+ infer::Misc(path.span),
+ actual_structure_type,
+ type_and_substs.ty) {
+ Ok(()) => {}
+ Err(type_error) => {
+ let type_error_description =
+ ty::type_err_to_str(tcx, &type_error);
+ fcx.tcx()
+ .sess
+ .span_err(path.span,
+ format!("structure constructor specifies a \
+ structure of type `{}`, but this \
+ structure has type `{}`: {}",
+ fcx.infcx()
+ .ty_to_string(type_and_substs.ty),
+ fcx.infcx()
+ .ty_to_string(
+ actual_structure_type),
+ type_error_description).as_slice());
+ ty::note_and_explain_type_err(tcx, &type_error);
+ }
+ }
}
}
ast::ExprField(ref base, ref field, ref tys) => {
match *self {
ast::SelfStatic => SelfStatic,
ast::SelfValue(_) => SelfValue,
- ast::SelfUniq(_) => SelfOwned,
ast::SelfRegion(lt, mt, _) => {
SelfBorrowed(lt.clean(), mt.clean())
}
match *selfty {
clean::SelfStatic => {},
clean::SelfValue => args.push_str("self"),
- clean::SelfOwned => args.push_str("~self"),
+ clean::SelfOwned => args.push_str("self: Box<Self>"),
clean::SelfBorrowed(Some(ref lt), mtbl) => {
args.push_str(format!("&{} {}self", *lt,
MutableSpace(mtbl)).as_slice());
use std::fmt;
use std::slice;
use std::str;
+use std::string;
use std::collections::HashMap;
use html::toc::TocBuilder;
"".to_string()
} else {
unsafe {
- str::raw::from_buf_len((*text).data, (*text).size as uint)
+ string::raw::from_buf_len((*text).data, (*text).size as uint)
}
};
optopt("w", "output-format", "the output type to write",
"[html|json]"),
optopt("o", "output", "where to place the output", "PATH"),
+ optopt("", "crate-name", "specify the name of this crate", "NAME"),
optmulti("L", "library-path", "directory to add to crate search path",
"DIR"),
optmulti("", "cfg", "pass a --cfg to rustc", ""),
Markdown file or generated documentation",
"FILES"),
optopt("", "markdown-playground-url",
- "URL to send code snippets to", "URL")
+ "URL to send code snippets to", "URL"),
+ optflag("", "markdown-no-toc", "don't include table of contents")
)
}
return test::run(input, cfgs, libs, externs, test_args)
}
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
- &matches, &external_html),
+ &matches, &external_html,
+ !matches.opt_present("markdown-no-toc")),
(false, false) => {}
}
let cr = Path::new(cratefile);
info!("starting to run rustc");
- let (krate, analysis) = std::task::try(proc() {
+ let (mut krate, analysis) = std::task::try(proc() {
let cr = cr;
core::run_core(libs.move_iter().collect(),
cfgs,
info!("finished with rustc");
analysiskey.replace(Some(analysis));
+ match matches.opt_str("crate-name") {
+ Some(name) => krate.name = name,
+ None => {}
+ }
+
// Process all of the crate attributes, extracting plugin metadata along
// with the passes which we are supposed to run.
match krate.module.get_ref().doc_list() {
use html::escape::Escape;
use html::markdown;
-use html::markdown::{MarkdownWithToc, find_testable_code, reset_headers};
+use html::markdown::{Markdown, MarkdownWithToc, find_testable_code, reset_headers};
use test::Collector;
/// Separate any lines at the start of the file that begin with `%`.
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
/// (e.g. output = "bar" => "bar/foo.html").
pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
- external_html: &ExternalHtml) -> int {
+ external_html: &ExternalHtml, include_toc: bool) -> int {
let input_p = Path::new(input);
output.push(input_p.filestem().unwrap());
output.set_extension("html");
reset_headers();
+ let rendered = if include_toc {
+ format!("{}", MarkdownWithToc(text))
+ } else {
+ format!("{}", Markdown(text))
+ };
+
let err = write!(
&mut out,
r#"<!DOCTYPE html>
css = css,
in_header = external_html.in_header,
before_content = external_html.before_content,
- text = MarkdownWithToc(text),
+ text = rendered,
after_content = external_html.after_content,
playground = playground,
);
use alloc::libc_heap::malloc_raw;
use collections::string::String;
use collections::hash;
+use core::fmt;
use core::kinds::marker;
use core::mem;
use core::ptr;
/// reasons, this is always a deep clone, rather than the usual shallow
/// clone.
fn clone(&self) -> CString {
- if self.buf.is_null() {
- CString { buf: self.buf, owns_buffer_: self.owns_buffer_ }
- } else {
- let len = self.len() + 1;
- let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
- unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
- CString { buf: buf as *const libc::c_char, owns_buffer_: true }
- }
+ let len = self.len() + 1;
+ let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
+ unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
+ CString { buf: buf as *const libc::c_char, owns_buffer_: true }
}
}
impl PartialEq for CString {
fn eq(&self, other: &CString) -> bool {
+ // Check if the two strings share the same buffer
if self.buf as uint == other.buf as uint {
true
- } else if self.buf.is_null() || other.buf.is_null() {
- false
} else {
unsafe {
libc::strcmp(self.buf, other.buf) == 0
impl CString {
/// Create a C String from a pointer.
+ ///
+ ///# Failure
+ ///
+ /// Fails if `buf` is null
pub unsafe fn new(buf: *const libc::c_char, owns_buffer: bool) -> CString {
+ assert!(!buf.is_null());
CString { buf: buf, owns_buffer_: owns_buffer }
}
/// let p = foo.to_c_str().as_ptr();
/// ```
///
- /// # Failure
- ///
- /// Fails if the CString is null.
- ///
/// # Example
///
/// ```rust
/// }
/// ```
pub fn as_ptr(&self) -> *const libc::c_char {
- if self.buf.is_null() { fail!("CString is null!"); }
-
self.buf
}
/// // wrong (the CString will be freed, invalidating `p`)
/// let p = foo.to_c_str().as_mut_ptr();
/// ```
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
pub fn as_mut_ptr(&mut self) -> *mut libc::c_char {
- if self.buf.is_null() { fail!("CString is null!") }
-
self.buf as *mut _
}
/// Calls a closure with a reference to the underlying `*libc::c_char`.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
#[deprecated="use `.as_ptr()`"]
pub fn with_ref<T>(&self, f: |*const libc::c_char| -> T) -> T {
- if self.buf.is_null() { fail!("CString is null!"); }
f(self.buf)
}
/// Calls a closure with a mutable reference to the underlying `*libc::c_char`.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
#[deprecated="use `.as_mut_ptr()`"]
pub fn with_mut_ref<T>(&mut self, f: |*mut libc::c_char| -> T) -> T {
- if self.buf.is_null() { fail!("CString is null!"); }
f(self.buf as *mut libc::c_char)
}
/// Returns true if the CString is a null.
+ #[deprecated="a CString cannot be null"]
pub fn is_null(&self) -> bool {
self.buf.is_null()
}
/// Returns true if the CString is not null.
+ #[deprecated="a CString cannot be null"]
pub fn is_not_null(&self) -> bool {
self.buf.is_not_null()
}
/// Converts the CString into a `&[u8]` without copying.
/// Includes the terminating NUL byte.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
#[inline]
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
- if self.buf.is_null() { fail!("CString is null!"); }
unsafe {
mem::transmute(Slice { data: self.buf, len: self.len() + 1 })
}
/// Converts the CString into a `&[u8]` without copying.
/// Does not include the terminating NUL byte.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
#[inline]
pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
- if self.buf.is_null() { fail!("CString is null!"); }
unsafe {
mem::transmute(Slice { data: self.buf, len: self.len() })
}
/// Converts the CString into a `&str` without copying.
/// Returns None if the CString is not UTF-8.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
#[inline]
pub fn as_str<'a>(&'a self) -> Option<&'a str> {
let buf = self.as_bytes_no_nul();
}
/// Return a CString iterator.
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
pub fn iter<'a>(&'a self) -> CChars<'a> {
- if self.buf.is_null() { fail!("CString is null!"); }
CChars {
ptr: self.buf,
marker: marker::ContravariantLifetime,
impl Collection for CString {
/// Return the number of bytes in the CString (not including the NUL terminator).
- ///
- /// # Failure
- ///
- /// Fails if the CString is null.
#[inline]
fn len(&self) -> uint {
- if self.buf.is_null() { fail!("CString is null!"); }
let mut cur = self.buf;
let mut len = 0;
unsafe {
}
}
+impl fmt::Show for CString {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ String::from_utf8_lossy(self.as_bytes_no_nul()).fmt(f)
+ }
+}
+
/// A generic trait for converting a value to a CString.
pub trait ToCStr {
/// Copy the receiver into a CString.
}
}
- #[test]
- fn test_is_null() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- assert!(c_str.is_null());
- assert!(!c_str.is_not_null());
- }
-
#[test]
fn test_unwrap() {
let c_str = "hello".to_c_str();
fn test_as_ptr() {
let c_str = "hello".to_c_str();
let len = unsafe { libc::strlen(c_str.as_ptr()) };
- assert!(!c_str.is_null());
- assert!(c_str.is_not_null());
assert_eq!(len, 5);
}
- #[test]
- #[should_fail]
- fn test_as_ptr_empty_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.as_ptr();
- }
#[test]
fn test_iterator() {
assert_eq!(c_str.as_bytes_no_nul(), b"foo\xFF");
}
- #[test]
- #[should_fail]
- fn test_as_bytes_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.as_bytes();
- }
-
- #[test]
- #[should_fail]
- fn test_as_bytes_no_nul_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.as_bytes_no_nul();
- }
-
#[test]
fn test_as_str() {
let c_str = "hello".to_c_str();
#[test]
#[should_fail]
- fn test_as_str_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.as_str();
- }
-
- #[test]
- #[should_fail]
- fn test_len_fail() {
+ fn test_new_fail() {
let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.len();
- }
-
- #[test]
- #[should_fail]
- fn test_iter_fail() {
- let c_str = unsafe { CString::new(ptr::null(), false) };
- c_str.iter();
}
#[test]
// force a copy, reading the memory
c_.as_bytes().to_vec();
}
-
- #[test]
- fn test_clone_eq_null() {
- let x = unsafe { CString::new(ptr::null(), false) };
- let y = x.clone();
- assert!(x == y);
- }
}
#[cfg(test)]
pub trait Runtime {
// Necessary scheduling functions, used for channels and blocking I/O
// (sometimes).
- fn yield_now(~self, cur_task: Box<Task>);
- fn maybe_yield(~self, cur_task: Box<Task>);
- fn deschedule(~self, times: uint, cur_task: Box<Task>,
+ fn yield_now(self: Box<Self>, cur_task: Box<Task>);
+ fn maybe_yield(self: Box<Self>, cur_task: Box<Task>);
+ fn deschedule(self: Box<Self>,
+ times: uint,
+ cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>);
- fn reawaken(~self, to_wake: Box<Task>);
+ fn reawaken(self: Box<Self>, to_wake: Box<Task>);
// Miscellaneous calls which are very different depending on what context
// you're in.
- fn spawn_sibling(~self,
+ fn spawn_sibling(self: Box<Self>,
cur_task: Box<Task>,
opts: TaskOpts,
f: proc():Send);
fn can_block(&self) -> bool;
// FIXME: This is a serious code smell and this should not exist at all.
- fn wrap(~self) -> Box<Any>;
+ fn wrap(self: Box<Self>) -> Box<Any>;
}
/// The default error code of the rust runtime if the main task fails instead
}
pub trait RtioTcpListener : RtioSocket {
- fn listen(~self) -> IoResult<Box<RtioTcpAcceptor + Send>>;
+ fn listen(self: Box<Self>) -> IoResult<Box<RtioTcpAcceptor + Send>>;
}
pub trait RtioTcpAcceptor : RtioSocket {
}
pub trait RtioUnixListener {
- fn listen(~self) -> IoResult<Box<RtioUnixAcceptor + Send>>;
+ fn listen(self: Box<Self>) -> IoResult<Box<RtioUnixAcceptor + Send>>;
}
pub trait RtioUnixAcceptor {
/// }).destroy();
/// # }
/// ```
- pub fn run(~self, f: ||) -> Box<Task> {
+ pub fn run(self: Box<Task>, f: ||) -> Box<Task> {
assert!(!self.is_destroyed(), "cannot re-use a destroyed task");
// First, make sure that no one else is in TLS. This does not allow
///
/// The returned task cannot be used for running any more code, but it may
/// be used to extract the runtime as necessary.
- pub fn destroy(~self) -> Box<Task> {
+ pub fn destroy(self: Box<Task>) -> Box<Task> {
if self.is_destroyed() {
self
} else {
/// This function consumes ownership of the task, deallocating it once it's
/// done being processed. It is assumed that TLD and the local heap have
/// already been destroyed and/or annihilated.
- fn cleanup(~self, result: Result) -> Box<Task> {
+ fn cleanup(self: Box<Task>, result: Result) -> Box<Task> {
// The first thing to do when cleaning up is to deallocate our local
// resources, such as TLD and GC data.
//
/// Spawns a sibling to this task. The newly spawned task is configured with
/// the `opts` structure and will run `f` as the body of its code.
- pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc(): Send) {
+ pub fn spawn_sibling(mut self: Box<Task>,
+ opts: TaskOpts,
+ f: proc(): Send) {
let ops = self.imp.take_unwrap();
ops.spawn_sibling(self, opts, f)
}
/// Deschedules the current task, invoking `f` `amt` times. It is not
/// recommended to use this function directly, but rather communication
/// primitives in `std::comm` should be used.
- pub fn deschedule(mut ~self, amt: uint,
+ pub fn deschedule(mut self: Box<Task>,
+ amt: uint,
f: |BlockedTask| -> ::core::result::Result<(), BlockedTask>) {
let ops = self.imp.take_unwrap();
ops.deschedule(amt, self, f)
/// Wakes up a previously blocked task, optionally specifying whether the
/// current task can accept a change in scheduling. This function can only
/// be called on tasks that were previously blocked in `deschedule`.
- pub fn reawaken(mut ~self) {
+ pub fn reawaken(mut self: Box<Task>) {
let ops = self.imp.take_unwrap();
ops.reawaken(self);
}
/// Yields control of this task to another task. This function will
/// eventually return, but possibly not immediately. This is used as an
/// opportunity to allow other tasks a chance to run.
- pub fn yield_now(mut ~self) {
+ pub fn yield_now(mut self: Box<Task>) {
let ops = self.imp.take_unwrap();
ops.yield_now(self);
}
/// Similar to `yield_now`, except that this function may immediately return
/// without yielding (depending on what the runtime decides to do).
- pub fn maybe_yield(mut ~self) {
+ pub fn maybe_yield(mut self: Box<Task>) {
let ops = self.imp.take_unwrap();
ops.maybe_yield(self);
}
use std::fmt;
use std::mem;
use std::ptr;
+use std::string;
use std::rt::local::Local;
use std::rt::rtio;
use std::rt::rtio::{IoResult, IoError};
use std::rt::task::{BlockedTask, Task};
-use std::str::raw::from_c_str;
use std::task;
pub use self::async::AsyncWatcher;
mem::transmute(uvll::get_data_for_uv_handle(*h))
}
- fn install(~self) -> Box<Self> {
+ fn install(self: Box<Self>) -> Box<Self> {
unsafe {
let myptr = mem::transmute::<&Box<Self>, &*mut u8>(&self);
uvll::set_data_for_uv_handle(self.uv_handle(), *myptr);
let inner = match self { &UvError(a) => a };
let name_str = uvll::uv_err_name(inner);
assert!(name_str.is_not_null());
- from_c_str(name_str).to_string()
+ string::raw::from_buf(name_str as *const u8)
}
}
let inner = match self { &UvError(a) => a };
let desc_str = uvll::uv_strerror(inner);
assert!(desc_str.is_not_null());
- from_c_str(desc_str).to_string()
+ string::raw::from_buf(desc_str as *const u8)
}
}
}
impl rtio::RtioTcpListener for TcpListener {
- fn listen(~self) -> Result<Box<rtio::RtioTcpAcceptor + Send>, IoError> {
+ fn listen(self: Box<TcpListener>)
+ -> Result<Box<rtio::RtioTcpAcceptor + Send>, IoError> {
// create the acceptor object from ourselves
let mut acceptor = box TcpAcceptor {
listener: self,
}
impl rtio::RtioUnixListener for PipeListener {
- fn listen(~self) -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
+ fn listen(self: Box<PipeListener>)
+ -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
// create the acceptor object from ourselves
let mut acceptor = box PipeAcceptor {
listener: self,
// ignore-lexer-test FIXME #15679
//! Base64 binary-to-text encoding
-use std::str;
use std::fmt;
+use std::string;
/// Available encoding character sets
pub enum CharacterSet {
}
unsafe {
- str::raw::from_utf8_owned(v)
+ string::raw::from_utf8(v)
}
}
}
// ignore-lexer-test FIXME #15679
//! Hex binary-to-text encoding
-use std::str;
use std::fmt;
+use std::string;
/// A trait for converting a value to hexadecimal encoding
pub trait ToHex {
}
unsafe {
- str::raw::from_utf8_owned(v)
+ string::raw::from_utf8(v)
}
}
}
use mem;
use option::{Option, Some, None};
use slice::{ImmutableVector, MutableVector, Vector};
-use str::{OwnedStr, Str, StrAllocating, StrSlice};
+use str::{Str, StrAllocating, StrSlice};
use string::String;
use to_string::IntoStr;
use vec::Vec;
use result::{Err, Ok, Result};
use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector};
use str::{Str, StrSlice, StrAllocating};
-use str;
use string::String;
use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
use vec::Vec;
use c_str::ToCStr;
#[cfg(unix)]
use libc::c_char;
-#[cfg(windows)]
-use str::OwnedStr;
/// Get the number of cores available
pub fn num_cpus() -> uint {
fail!();
}
}
- Path::new(String::from_utf16(str::truncate_utf16_at_nul(buf))
+ Path::new(String::from_utf16(::str::truncate_utf16_at_nul(buf))
.expect("GetCurrentDirectoryW returned invalid UTF-16"))
}
fn _setenv(n: &str, v: &[u8]) {
let n: Vec<u16> = n.utf16_units().collect();
let n = n.append_one(0);
- let v: Vec<u16> = str::from_utf8(v).unwrap().utf16_units().collect();
+ let v: Vec<u16> = ::str::from_utf8(v).unwrap().utf16_units().collect();
let v = v.append_one(0);
unsafe {
#[cfg(windows)]
fn load_self() -> Option<Vec<u8>> {
- use str::OwnedStr;
-
unsafe {
use os::win32::fill_utf16_buf_and_decode;
fill_utf16_buf_and_decode(|buf, sz| {
fail!("strerror_r failure");
}
- str::raw::from_c_str(p as *const c_char).into_string()
+ ::string::raw::from_buf(p as *const u8)
}
}
return format!("OS Error {} (FormatMessageW() returned error {})", errnum, fm_err);
}
- let msg = String::from_utf16(str::truncate_utf16_at_nul(buf));
+ let msg = String::from_utf16(::str::truncate_utf16_at_nul(buf));
match msg {
Some(msg) => format!("OS Error {}: {}", errnum, msg),
None => format!("OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum),
// Push it onto the list.
let opt_s = slice::raw::buf_as_slice(ptr as *const _, len, |buf| {
- String::from_utf16(str::truncate_utf16_at_nul(buf))
+ String::from_utf16(::str::truncate_utf16_at_nul(buf))
});
opt_s.expect("CommandLineToArgvW returned invalid UTF-16")
});
#[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
#[doc(no_inline)] pub use ptr::RawPtr;
#[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek};
-#[doc(no_inline)] pub use str::{Str, StrVector, StrSlice, OwnedStr};
+#[doc(no_inline)] pub use str::{Str, StrVector, StrSlice};
#[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating, UnicodeStrSlice};
#[doc(no_inline)] pub use to_string::{ToString, IntoStr};
#[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
SelfValue(Ident),
/// `&'lt self`, `&'lt mut self`
SelfRegion(Option<Lifetime>, Mutability, Ident),
- /// `~self`
- SelfUniq(Ident),
/// `self: TYPE`
SelfExplicit(P<Ty>, Ident),
}
fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
match *es {
- SelfStatic | SelfValue(_) | SelfUniq(_) => *es,
+ SelfStatic | SelfValue(_) => *es,
SelfRegion(ref lifetime, m, id) => {
SelfRegion(fold_opt_lifetime(lifetime, self), m, id)
}
ObsoleteOwnedExpr,
ObsoleteOwnedPattern,
ObsoleteOwnedVector,
+ ObsoleteOwnedSelf,
ObsoleteManagedType,
ObsoleteManagedExpr,
}
"`~[T]` is no longer a type",
"use the `Vec` type instead"
),
+ ObsoleteOwnedSelf => (
+ "`~self` is no longer supported",
+ "write `self: Box<Self>` instead"
+ ),
ObsoleteManagedType => (
"`@` notation for managed pointers",
"use `Gc<T>` in `std::gc` instead"
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
use ast::{StructVariantKind, BiSub};
use ast::StrStyle;
-use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfUniq, SelfValue};
+use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
// We need to make sure it isn't a type
if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
self.bump();
- SelfUniq(self.expect_self_ident())
- } else {
- SelfStatic
+ drop(self.expect_self_ident());
+ let last_span = self.last_span;
+ self.obsolete(last_span, ObsoleteOwnedSelf)
}
+ SelfStatic
}
token::IDENT(..) if self.is_self_ident() => {
let self_ident = self.expect_self_ident();
self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
mutbl_self = self.parse_mutability();
self.bump();
- SelfUniq(self.expect_self_ident())
+ drop(self.expect_self_ident());
+ let last_span = self.last_span;
+ self.obsolete(last_span, ObsoleteOwnedSelf);
+ SelfStatic
}
_ => SelfStatic
};
}
SelfValue(id) => parse_remaining_arguments!(id),
SelfRegion(_,_,id) => parse_remaining_arguments!(id),
- SelfUniq(id) => parse_remaining_arguments!(id),
SelfExplicit(_,id) => parse_remaining_arguments!(id),
};
/// Parse a method in a trait impl, starting with `attrs` attributes.
pub fn parse_method(&mut self,
- already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
+ already_parsed_attrs: Option<Vec<Attribute>>)
+ -> Gc<Method> {
let next_attrs = self.parse_outer_attributes();
let attrs = match already_parsed_attrs {
Some(mut a) => { a.push_all_move(next_attrs); a }
let visa = self.parse_visibility();
let abi = if self.eat_keyword(keywords::Extern) {
self.parse_opt_abi().unwrap_or(abi::C)
+ } else if attr::contains_name(attrs.as_slice(),
+ "rust_call_abi_hack") {
+ // FIXME(stage0, pcwalton): Remove this awful hack after a
+ // snapshot, and change to `extern "rust-call" fn`.
+ abi::RustCall
} else {
abi::Rust
};
ast::SelfValue(_) => {
try!(word(&mut self.s, "self"));
}
- ast::SelfUniq(_) => {
- try!(word(&mut self.s, "~self"));
- }
ast::SelfRegion(ref lt, m, _) => {
try!(word(&mut self.s, "&"));
try!(self.print_opt_lifetime(lt));
explicit_self: &ExplicitSelf,
env: E) {
match explicit_self.node {
- SelfStatic | SelfValue(_) | SelfUniq(_) => {},
+ SelfStatic | SelfValue(_) => {},
SelfRegion(ref lifetime, _, _) => {
visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
}
-Subproject commit d66318a4aae089bae5c3c38ee42daaa1bd8fadb7
+Subproject commit cd24b5c6633b27df2b84249a65a46a610b734494
static char *LastError;
+#if LLVM_VERSION_MINOR >= 5
+extern "C" LLVMMemoryBufferRef
+LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
+ -1,
+ false);
+ if (!buf_or) {
+ LLVMRustSetLastError(buf_or.getError().message().c_str());
+ return nullptr;
+ }
+ return wrap(buf_or.get().release());
+}
+#else
extern "C" LLVMMemoryBufferRef
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
- LLVMMemoryBufferRef MemBuf = NULL;
- char *err = NULL;
- LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, &err);
- if (err != NULL) {
- LLVMRustSetLastError(err);
+ OwningPtr<MemoryBuffer> buf;
+ error_code err = MemoryBuffer::getFile(Path, buf, -1, false);
+ if (err) {
+ LLVMRustSetLastError(err.message().c_str());
+ return NULL;
}
- return MemBuf;
+ return wrap(buf.take());
}
+#endif
extern "C" char *LLVMRustGetLastError(void) {
char *ret = LastError;
#if LLVM_VERSION_MINOR >= 5
extern "C" void*
LLVMRustOpenArchive(char *path) {
- std::unique_ptr<MemoryBuffer> buf;
- std::error_code err = MemoryBuffer::getFile(path, buf);
- if (err) {
- LLVMRustSetLastError(err.message().c_str());
- return NULL;
+ ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
+ -1,
+ false);
+ if (!buf_or) {
+ LLVMRustSetLastError(buf_or.getError().message().c_str());
+ return nullptr;
}
- Archive *ret = new Archive(buf.release(), err);
+
+ std::error_code err;
+ Archive *ret = new Archive(std::move(buf_or.get()), err);
if (err) {
LLVMRustSetLastError(err.message().c_str());
return NULL;
extern "C" void*
LLVMRustOpenArchive(char *path) {
OwningPtr<MemoryBuffer> buf;
- error_code err = MemoryBuffer::getFile(path, buf);
+ error_code err = MemoryBuffer::getFile(path, buf, -1, false);
if (err) {
LLVMRustSetLastError(err.message().c_str());
return NULL;
# If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
-2014-07-21
+2014-07-22
-// 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.
+// The Computer Language Benchmarks Game
+// http://benchmarksgame.alioth.debian.org/
//
-// 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.
+// contributed by the Rust Project Developers
+
+// Copyright (c) 2012-2014 The Rust Project Developers
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// - Neither the name of "The Computer Language Benchmarks Game" nor
+// the name of "The Computer Language Shootout Benchmarks" nor the
+// names of its contributors may be used to endorse or promote
+// products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
#![feature(phase)]
#[phase(plugin)] extern crate green;
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Point<T> {
+ x: T,
+ y: T,
+}
+
+type PointF = Point<f32>;
+
+struct Pair<T,U> {
+ x: T,
+ y: U,
+}
+
+type PairF<U> = Pair<f32,U>;
+
+fn main() {
+ let pt = PointF {
+ //~^ ERROR expected f32 but found int
+ x: 1i,
+ y: 2i,
+ };
+
+ let pt2 = Point::<f32> {
+ //~^ ERROR expected f32 but found int
+ x: 3i,
+ y: 4i,
+ };
+
+ let pair = PairF {
+ //~^ ERROR expected f32 but found int
+ x: 5i,
+ y: 6i,
+ };
+
+ let pair2 = PairF::<int> {
+ //~^ ERROR expected f32 but found int
+ x: 7i,
+ y: 8i,
+ };
+
+ let pt3 = PointF::<int> {
+ //~^ ERROR wrong number of type arguments
+ x: 9i,
+ y: 10i,
+ };
+}
+
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(overloaded_calls)]
+
+use std::ops::FnMut;
+
+fn call_f<F:FnMut<(),()>>(mut f: F) {
+ f();
+}
+
+fn f() {
+ println!("hello");
+}
+
+fn call_g<G:FnMut<(String,String),String>>(mut g: G, x: String, y: String)
+ -> String {
+ g(x, y)
+}
+
+fn g(x: String, y: String) -> String {
+ x.append(y.as_slice())
+}
+
+fn main() {
+ call_f(f);
+ assert_eq!(call_g(g, "foo".to_string(), "bar".to_string()).as_slice(),
+ "foobar");
+}
+
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::str;
+use std::{str, string};
static A: [u8, ..2] = ['h' as u8, 'i' as u8];
static B: &'static [u8, ..2] = &A;
unsafe {
let foo = &A as *const u8;
assert_eq!(str::raw::from_utf8(A), "hi");
- assert_eq!(str::raw::from_buf_len(foo, A.len()), "hi".to_string());
- assert_eq!(str::raw::from_buf_len(C, B.len()), "hi".to_string());
+ assert_eq!(string::raw::from_buf_len(foo, A.len()), "hi".to_string());
+ assert_eq!(string::raw::from_buf_len(C, B.len()), "hi".to_string());
assert!(*C == A[0]);
assert!(*(&B[0] as *const u8) == A[0]);
let bar = str::raw::from_utf8(A).to_c_str();
- assert_eq!(str::raw::from_c_str(bar.as_ptr()), "hi".to_string());
+ assert_eq!(bar.as_str(), "hi".to_c_str().as_str());
}
}