Imported Upstream version 1.1.0+dfsg1

This commit is contained in:
Angus Lees 2015-06-26 16:41:04 -06:00
parent bd371182c2
commit d9579d0f11
6165 changed files with 35488 additions and 1625428 deletions

View File

@ -735,8 +735,8 @@ Rob Arnold <robarnold@cs.cmu.edu>
Rob Hoelz <rob@hoelz.ro>
Robert Buonpastore <robert.buonpastore@gmail.com>
Robert Clipsham <robert@octarineparrot.com>
Robert Foss <dev@robertfoss.se>
Robert Gawdzik <rgawdzik@hotmail.com>
Robert Foss <dev@robertfoss.se>
Robert Irelan <rirelan@gmail.com>
Robert Knight <robertknight@gmail.com>
Robert Millar <robert.millar@cantab.net>

View File

@ -76,7 +76,7 @@
#
# * `CFG_ENABLE_VALGRIND=1` - Run tests under valgrind
# * `VALGRIND_COMPILE=1` - Run the compiler itself under valgrind
# (may require `CFG_ENABLE_VALGRIND`)
# (requires `CFG_ENABLE_VALGRIND`)
#
# * `NO_REBUILD=1` - Don't rebootstrap when testing std
# (and possibly other crates)

View File

@ -87,9 +87,11 @@ fetch snapshots, and an OS that can execute the available snapshot binaries.
Snapshot binaries are currently built and tested on several platforms:
* Windows (7, 8, Server 2008 R2), x86 and x86-64 (64-bit support added in Rust 0.12.0)
* Linux (2.6.18 or later, various distributions), x86 and x86-64
* OSX 10.7 (Lion) or greater, x86 and x86-64
| Platform \ Architecture | x86 | x86_64 |
|--------------------------------|-----|--------|
| Windows (7, 8, Server 2008 R2) | ✓ | ✓ |
| Linux (2.6.18 or later) | ✓ | ✓ |
| OSX (10.7 Lion or later) | ✓ | ✓ |
You may find that other platforms work, but these are our officially
supported build environments that are most likely to work.

View File

@ -1,3 +1,116 @@
Version 1.1.0 (June 2015)
=========================
* ~850 changes, numerous bugfixes
Highlights
----------
* The [`std::fs` module has been expanded][fs-expand] to expand the set of
functionality exposed:
* `DirEntry` now supports optimizations like `file_type` and `metadata` which
don't incur a syscall on some platforms.
* A `symlink_metadata` function has been added.
* The `fs::Metadata` structure now lowers to its OS counterpart, providing
access to all underlying information.
* The compiler contains extended explanations of many errors. When it
emits such an error it also suggests using the `--explain` flag to
read the extended explanations, which are also [cataloged on the web
site][err].
* Thanks to multiple [improvements][sk] to [type checking][pre], as
well as other work, the time to bootstrap the compiler decreased by
32%.
Libraries
---------
* The `str::split_whitespace` method splits a string on unicode
whitespace boundaries.
* On both Windows and Unix, new extension traits provide conversion of
I/O types to and from the underlying system handles. On Unix, these
traits are [`FrowRawFd`] and [`AsRawFd`], on Windows `FromRawHandle`
and `AsRawHandle`. These are implemented for `File`, `TcpStream`,
`TcpListener`, and `UpdSocket`. Further implementations for
`std::process` will be stabilized later.
* On Unix, [`std::os::unix::symlink`] creates symlinks. On
Windows, symlinks can be created with
`std::os::windows::symlink_dir` and
`std::os::windows::symlink_file`.
* The `mpsc::Receiver` type can now be converted into an iterator with
`into_iter` on the [`IntoIterator`] trait.
* `Ipv4Addr` can be created from `u32` with the `From<u32>`
implementation of the [`From`] trait.
* The `Debug` implementation for `RangeFull` [creates output that is
more consistent with other implementations][rf].
* [`Debug` is implemented for `File`][file].
* The `Default` implementation for `Arc` [no longer requires `Sync +
Send`][arc].
* [The `Iterator` methods `count`, `nth`, and `last` have been
overridden for slices to have O(1) performance instead of O(n)][si].
* Incorrect handling of paths on Windows has been improved in both the
compiler and the standard library.
* [`AtomicPtr` gained a `Default` implementation][ap].
* In accordance with Rust's policy on arithmetic overflow `abs` now
[panics on overflow when debug assertions are enabled][abs].
* The [`Cloned`] iterator, which was accidentally left unstable for
1.0 [has been stabilized][c].
* The [`Incoming`] iterator, which iterates over incoming TCP
connections, and which was accidentally unnamable in 1.0, [is now
properly exported][inc].
* [`BinaryHeap`] no longer corrupts itself [when functions called by
`sift_up` or `sift_down` panic][bh].
* The [`split_off`] method of `LinkedList` [no longer corrupts
the list in certain scenarios][ll].
Misc
----
* Type checking performance [has improved notably][sk] with
[multiple improvements][pre].
* The compiler [suggests code changes][ch] for more errors.
* rustc and it's build system have experimental support for [building
toolchains against MUSL][m] instead of glibc on Linux.
* The compiler defines the `target_env` cfg value, which is used for
distinguishing toolchains that are otherwise for the same
platform. Presently this is set to `gnu` for common GNU Linux
targets and for MinGW targets, and `musl` for MUSL Linux targets.
* The [`cargo rustc`][crc] command invokes a build with custom flags
to rustc.
* [Android executables are always position independent][pie].
* [The `drop_with_repr_extern` lint warns about mixing `repr(C)`
with `Drop`][drop].
[`split_whitespace`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_whitespace
[`Iterator::cloned`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.cloned
[`FromRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.FromRawFd.html
[`AsRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.AsRawFd.html
[`std::os::unix::symlink`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/fn.symlink.html
[`IntoIterator`]: http://doc.rust-lang.org/nightly/std/iter/trait.IntoIterator.html
[`From`]: http://doc.rust-lang.org/nightly/std/convert/trait.From.html
[rf]: https://github.com/rust-lang/rust/pull/24491
[err]: http://doc.rust-lang.org/error-index.html
[sk]: https://github.com/rust-lang/rust/pull/24615
[pre]: https://github.com/rust-lang/rust/pull/25323
[file]: https://github.com/rust-lang/rust/pull/24598
[ch]: https://github.com/rust-lang/rust/pull/24683
[arc]: https://github.com/rust-lang/rust/pull/24695
[si]: https://github.com/rust-lang/rust/pull/24701
[ap]: https://github.com/rust-lang/rust/pull/24834
[m]: https://github.com/rust-lang/rust/pull/24777
[fs]: https://github.com/rust-lang/rfcs/blob/master/text/1044-io-fs-2.1.md
[crc]: https://github.com/rust-lang/cargo/pull/1568
[pie]: https://github.com/rust-lang/rust/pull/24953
[abs]: https://github.com/rust-lang/rust/pull/25441
[c]: https://github.com/rust-lang/rust/pull/25496
[`Cloned`]: http://doc.rust-lang.org/nightly/std/iter/struct.Cloned.html
[`Incoming`]: http://doc.rust-lang.org/nightly/std/net/struct.Incoming.html
[inc]: https://github.com/rust-lang/rust/pull/25522
[bh]: https://github.com/rust-lang/rust/pull/25856
[`BinaryHeap`]: http://doc.rust-lang.org/nightly/std/collections/struct.BinaryHeap.html
[ll]: https://github.com/rust-lang/rust/pull/26022
[`split_off`]: http://doc.rust-lang.org/nightly/collections/linked_list/struct.LinkedList.html#method.split_off
[drop]: https://github.com/rust-lang/rust/pull/24935
Version 1.0.0 (May 2015)
========================

75
configure vendored
View File

@ -19,6 +19,11 @@ err() {
exit 1
}
run() {
msg "$@"
"$@"
}
need_ok() {
if [ $? -ne 0 ]
then
@ -36,8 +41,7 @@ need_cmd() {
make_dir() {
if [ ! -d $1 ]
then
msg "mkdir -p $1"
mkdir -p $1
run mkdir -p $1
fi
}
@ -46,8 +50,7 @@ copy_if_changed() {
then
msg "leaving $2 unchanged"
else
msg "cp $1 $2"
cp -f $1 $2
run cp -f $1 $2
chmod u-w $2 # make copied artifact read-only
fi
}
@ -57,8 +60,7 @@ move_if_changed() {
then
msg "leaving $2 unchanged"
else
msg "mv $1 $2"
mv -f $1 $2
run mv -f $1 $2
chmod u-w $2 # make moved artifact read-only
fi
}
@ -104,8 +106,8 @@ probe() {
T=$(command -v $P 2>&1)
if [ $? -eq 0 ]
then
VER0=$($P --version 2>/dev/null | head -1 \
| sed -e 's/[^0-9]*\([vV]\?[0-9.]\+[^ ]*\).*/\1/' )
VER0=$($P --version 2>/dev/null \
| grep -o '[vV]\?[0-9][0-9.][a-z0-9.-]*' | head -1 )
if [ $? -eq 0 -a "x${VER0}" != "x" ]
then
VER="($VER0)"
@ -337,6 +339,15 @@ to_gnu_triple() {
esac
}
# Prints the absolute path of a directory to stdout
abs_path() {
local _path="$1"
# Unset CDPATH because it causes havok: it makes the destination unpredictable
# and triggers 'cd' to print the path to stdout. Route `cd`'s output to /dev/null
# for good measure.
(unset CDPATH && cd "$_path" > /dev/null && pwd)
}
msg "looking for configure programs"
need_cmd cmp
need_cmd mkdir
@ -509,7 +520,7 @@ fi
DEFAULT_BUILD="${CFG_CPUTYPE}-${CFG_OSTYPE}"
CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
CFG_SRC_DIR="$(abs_path $(dirname $0))/"
CFG_BUILD_DIR="$(pwd)/"
CFG_SELF="$0"
CFG_CONFIGURE_ARGS="$@"
@ -535,13 +546,14 @@ fi
BOOL_OPTIONS=""
VAL_OPTIONS=""
opt debug 0 "debug mode"
opt debug 0 "debug mode; disables optimization unless \`--enable-optimize\` given"
opt valgrind 0 "run tests with valgrind (memcheck by default)"
opt helgrind 0 "run tests with helgrind instead of memcheck"
opt valgrind-rpass 1 "run rpass-valgrind tests with valgrind"
opt docs 1 "build standard library documentation"
opt compiler-docs 0 "build compiler documentation"
opt optimize-tests 1 "build tests with optimizations"
opt debuginfo-tests 0 "build tests with debugger metadata"
opt libcpp 1 "build with llvm with libc++ instead of libstdc++ when using clang"
opt llvm-assertions 0 "build LLVM with assertions"
opt debug-assertions 0 "build with debugging assertions"
@ -574,12 +586,14 @@ valopt jemalloc-root "" "set directory where libjemalloc_pic.a is located"
valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple"
valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path"
valopt release-channel "dev" "the name of the release channel to build"
valopt musl-root "/usr/local" "MUSL root installation directory"
# Many of these are saved below during the "writing configuration" step
# (others are conditionally saved).
opt_nosave manage-submodules 1 "let the build manage the git submodules"
opt_nosave clang 0 "prefer clang to gcc for building the runtime"
opt_nosave jemalloc 1 "build liballoc with jemalloc"
opt elf-tls 1 "elf thread local storage on platforms where supported"
valopt_nosave prefix "/usr/local" "set installation prefix"
valopt_nosave local-rust-root "/usr/local" "set prefix for local rust binary"
@ -650,9 +664,10 @@ if [ -n "$CFG_ENABLE_DEBUG" ]; then
CFG_DISABLE_OPTIMIZE=1
CFG_DISABLE_OPTIMIZE_CXX=1
fi
CFG_ENABLE_LLVM_ASSERTIONS=1
CFG_ENABLE_DEBUG_ASSERTIONS=1
CFG_ENABLE_DEBUG_JEMALLOC=1
CFG_ENABLE_DEBUGINFO=1
CFG_ENABLE_LLVM_ASSERTIONS=1
fi
# OK, now write the debugging options
@ -697,6 +712,20 @@ else
probe_need CFG_GIT git
fi
# Use `md5sum` on GNU platforms, or `md5 -q` on BSD
probe CFG_MD5 md5
probe CFG_MD5SUM md5sum
if [ -n "$CFG_MD5" ]
then
CFG_HASH_COMMAND="$CFG_MD5 -q | head -c 8"
elif [ -n "$CFG_MD5SUM" ]
then
CFG_HASH_COMMAND="$CFG_MD5SUM | head -c 8"
else
err 'could not find one of: md5 md5sum'
fi
putvar CFG_HASH_COMMAND
probe CFG_CLANG clang++
probe CFG_CCACHE ccache
probe CFG_GCC gcc
@ -721,6 +750,20 @@ then
probe CFG_JAVAC javac
fi
# the valgrind rpass tests will fail if you don't have a valgrind, but they're
# only disabled if you opt out.
if [ -z "$CFG_VALGRIND" ]
then
# If the user has explicitly asked for valgrind tests, then fail
if [ -n "$CFG_ENABLE_VALGRIND" ] && [ -n "$CFG_ENABLE_VALGRIND_PROVIDED" ]
then
err "No valgrind present, but valgrind tests explicitly requested"
else
CFG_DISABLE_VALGRIND_RPASS=1
putvar CFG_DISABLE_VALGRIND_RPASS
fi
fi
if [ ! -z "$CFG_GDB" ]
then
# Store GDB's version
@ -832,7 +875,7 @@ then
CFG_OSX_GCC_VERSION=$("$CFG_GCC" --version 2>&1 | grep "Apple LLVM version")
if [ $? -eq 0 ]
then
step_msg "on OS X 10.9, forcing use of clang"
step_msg "on OS X >=10.9, forcing use of clang"
CFG_ENABLE_CLANG=1
else
if [ $("$CFG_GCC" --version 2>&1 | grep -c ' 4\.[0-6]') -ne 0 ]; then
@ -1048,6 +1091,13 @@ do
fi
;;
*-musl)
if [ ! -f $CFG_MUSL_ROOT/lib/libc.a ]
then
err "musl libc $CFG_MUSL_ROOT/lib/libc.a not found"
fi
;;
*)
;;
esac
@ -1134,6 +1184,7 @@ do
make_dir $h/test/run-pass-valgrind
make_dir $h/test/run-pass-fulldeps
make_dir $h/test/run-fail
make_dir $h/test/run-fail-fulldeps
make_dir $h/test/compile-fail
make_dir $h/test/parse-fail
make_dir $h/test/compile-fail-fulldeps

View File

@ -1,4 +1,4 @@
.TH RUSTC "1" "March 2014" "rustc 0.13.0" "User Commands"
.TH RUSTC "1" "June 2015" "rustc 1.1.0" "User Commands"
.SH NAME
rustc \- The Rust compiler
.SH SYNOPSIS
@ -160,7 +160,7 @@ If the value is 'help', then a list of available CPUs is printed.
\fBtarget\-feature\fR='\fI+feature1\fR,\fI\-feature2\fR'
A comma\[hy]separated list of features to enable or disable for the target.
A preceding '+' enables a feature while a preceding '\-' disables it.
Available features can be discovered through \fItarget\-cpu=help\fR.
Available features can be discovered through \fIllc -mcpu=help\fR.
.TP
\fBpasses\fR=\fIval\fR
A space\[hy]separated list of extra LLVM passes to run.

View File

@ -1,4 +1,4 @@
.TH RUSTDOC "1" "March 2014" "rustdoc 0.13.0" "User Commands"
.TH RUSTDOC "1" "June 2015" "rustdoc 1.1.0" "User Commands"
.SH NAME
rustdoc \- generate documentation from Rust source code
.SH SYNOPSIS

View File

@ -20,16 +20,12 @@ CFG_GCCISH_CFLAGS_aarch64-apple-ios := -Wall -Werror -fPIC $(CFG_IOS_SDK_FLAGS_a
CFG_GCCISH_CXXFLAGS_aarch64-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_aarch64-apple-ios) -I$(CFG_IOS_SDK_aarch64-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_aarch64-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_aarch64-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_aarch64-apple-ios := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_aarch64-apple-ios :=
CFG_GCCISH_POST_LIB_FLAGS_aarch64-apple-ios :=
CFG_DEF_SUFFIX_aarch64-apple-ios := .darwin.def
CFG_LLC_FLAGS_aarch64-apple-ios := -mattr=+neon,+cyclone,+fp-armv8
CFG_INSTALL_NAME_aarch64-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_LIBUV_LINK_FLAGS_aarch64-apple-ios =
CFG_EXE_SUFFIX_aarch64-apple-ios :=
CFG_WINDOWSY_aarch64-apple-ios :=
CFG_UNIXY_aarch64-apple-ios := 1
CFG_PATH_MUNGE_aarch64-apple-ios := true
CFG_LDPATH_aarch64-apple-ios :=
CFG_RUN_aarch64-apple-ios = $(2)
CFG_RUN_TARG_aarch64-apple-ios = $(call CFG_RUN_aarch64-apple-ios,,$(2))

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_aarch64-linux-android := -Wall -g -fPIC -D__aarch64__ -DANDROI
CFG_GCCISH_CXXFLAGS_aarch64-linux-android := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_aarch64-linux-android := -shared -fPIC -ldl -g -lm -lsupc++
CFG_GCCISH_DEF_FLAG_aarch64-linux-android := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_aarch64-linux-android := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_aarch64-linux-android := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_aarch64-linux-android := .android.def
CFG_LLC_FLAGS_aarch64-linux-android :=
CFG_INSTALL_NAME_aarch64-linux-android =
CFG_EXE_SUFFIX_aarch64-linux-android :=
CFG_WINDOWSY_aarch64-linux-android :=
CFG_UNIXY_aarch64-linux-android := 1
CFG_PATH_MUNGE_aarch64-linux-android := true
CFG_LDPATH_aarch64-linux-android :=
CFG_RUN_aarch64-linux-android=
CFG_RUN_TARG_aarch64-linux-android=

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_aarch64-unknown-linux-gnu := -Wall -g -fPIC -D__aarch64__ $(CF
CFG_GCCISH_CXXFLAGS_aarch64-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_aarch64-unknown-linux-gnu := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_aarch64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_aarch64-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_aarch64-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_aarch64-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_aarch64-unknown-linux-gnu :=
CFG_INSTALL_NAME_aarch64-unknown-linux-gnu =
CFG_EXE_SUFFIX_aarch64-unknown-linux-gnu :=
CFG_WINDOWSY_aarch64-unknown-linux-gnu :=
CFG_UNIXY_aarch64-unknown-linux-gnu := 1
CFG_PATH_MUNGE_aarch64-unknown-linux-gnu := true
CFG_LDPATH_aarch64-unknown-linux-gnu :=
CFG_RUN_aarch64-unknown-linux-gnu=$(2)
CFG_RUN_TARG_aarch64-unknown-linux-gnu=$(call CFG_RUN_aarch64-unknown-linux-gnu,,$(2))

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D
CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++
CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
CFG_LLC_FLAGS_arm-linux-androideabi :=
CFG_INSTALL_NAME_arm-linux-androideabi =
CFG_EXE_SUFFIX_arm-linux-androideabi :=
CFG_WINDOWSY_arm-linux-androideabi :=
CFG_UNIXY_arm-linux-androideabi := 1
CFG_PATH_MUNGE_arm-linux-androideabi := true
CFG_LDPATH_arm-linux-androideabi :=
CFG_RUN_arm-linux-androideabi=
CFG_RUN_TARG_arm-linux-androideabi=

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfpu=vf
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabi := .linux.def
CFG_LLC_FLAGS_arm-unknown-linux-gnueabi :=
CFG_INSTALL_NAME_arm-unknown-linux-gnueabi =
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabi :=
CFG_WINDOWSY_arm-unknown-linux-gnueabi :=
CFG_UNIXY_arm-unknown-linux-gnueabi := 1
CFG_PATH_MUNGE_arm-unknown-linux-gnueabi := true
CFG_LDPATH_arm-unknown-linux-gnueabi :=
CFG_RUN_arm-unknown-linux-gnueabi=$(2)
CFG_RUN_TARG_arm-unknown-linux-gnueabi=$(call CFG_RUN_arm-unknown-linux-gnueabi,,$(2))

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC -D__arm__ $(CFLA
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
CFG_LLC_FLAGS_arm-unknown-linux-gnueabihf :=
CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
CFG_WINDOWSY_arm-unknown-linux-gnueabihf :=
CFG_UNIXY_arm-unknown-linux-gnueabihf := 1
CFG_PATH_MUNGE_arm-unknown-linux-gnueabihf := true
CFG_LDPATH_arm-unknown-linux-gnueabihf :=
CFG_RUN_arm-unknown-linux-gnueabihf=$(2)
CFG_RUN_TARG_arm-unknown-linux-gnueabihf=$(call CFG_RUN_arm-unknown-linux-gnueabihf,,$(2))

View File

@ -19,15 +19,11 @@ CFG_GCCISH_CFLAGS_armv7-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_
CFG_GCCISH_CXXFLAGS_armv7-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -I$(CFG_IOS_SDK_armv7-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_armv7-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_armv7-apple-ios := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_armv7-apple-ios :=
CFG_GCCISH_POST_LIB_FLAGS_armv7-apple-ios :=
CFG_DEF_SUFFIX_armv7-apple-ios := .darwin.def
CFG_LLC_FLAGS_armv7-apple-ios := -mattr=+vfp3,+v7,+neon -march=arm
CFG_INSTALL_NAME_armv7-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_armv7-apple-ios :=
CFG_WINDOWSY_armv7-apple-ios :=
CFG_UNIXY_armv7-apple-ios := 1
CFG_PATH_MUNGE_armv7-apple-ios := true
CFG_LDPATH_armv7-apple-ios :=
CFG_RUN_armv7-apple-ios = $(2)
CFG_RUN_TARG_armv7-apple-ios = $(call CFG_RUN_armv7-apple-ios,,$(2))

View File

@ -19,15 +19,11 @@ CFG_GCCISH_CFLAGS_armv7s-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS
CFG_GCCISH_CXXFLAGS_armv7s-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -I$(CFG_IOS_SDK_armv7s-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_armv7s-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7s-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_armv7s-apple-ios := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_armv7s-apple-ios :=
CFG_GCCISH_POST_LIB_FLAGS_armv7s-apple-ios :=
CFG_DEF_SUFFIX_armv7s-apple-ios := .darwin.def
CFG_LLC_FLAGS_armv7s-apple-ios := -mattr=+vfp4,+v7,+neon
CFG_INSTALL_NAME_armv7s-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_armv7s-apple-ios :=
CFG_WINDOWSY_armv7s-apple-ios :=
CFG_UNIXY_armv7s-apple-ios := 1
CFG_PATH_MUNGE_armv7s-apple-ios := true
CFG_LDPATH_armv7s-apple-ios :=
CFG_RUN_armv7s-apple-ios = $(2)
CFG_RUN_TARG_armv7s-apple-ios = $(call CFG_RUN_armv7s-apple-ios,,$(2))

View File

@ -18,15 +18,11 @@ CFG_GCCISH_CFLAGS_i386-apple-ios := -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLA
CFG_GCCISH_CXXFLAGS_i386-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_i386-apple-ios) -I$(CFG_IOSSIM_SDK_i386-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_i386-apple-ios := -lpthread -m32 -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK_i386-apple-ios)
CFG_GCCISH_DEF_FLAG_i386-apple-ios := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios :=
CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios :=
CFG_DEF_SUFFIX_i386-apple-ios := .darwin.def
CFG_LLC_FLAGS_i386-apple-ios =
CFG_INSTALL_NAME_i386-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_i386-apple-ios :=
CFG_WINDOWSY_i386-apple-ios :=
CFG_UNIXY_i386-apple-ios := 1
CFG_PATH_MUNGE_i386-apple-ios = :true
CFG_LDPATH_i386-apple-ios =
CFG_RUN_i386-apple-ios = $(2)
CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32
CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
CFG_LLC_FLAGS_i686-apple-darwin :=
CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_i686-apple-darwin :=
CFG_WINDOWSY_i686-apple-darwin :=
CFG_UNIXY_i686-apple-darwin := 1
CFG_PATH_MUNGE_i686-apple-darwin := true
CFG_LDPATH_i686-apple-darwin :=
CFG_RUN_i686-apple-darwin=$(2)
CFG_RUN_TARG_i686-apple-darwin=$(call CFG_RUN_i686-apple-darwin,,$(2))

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x
CFG_GCCISH_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32
CFG_GCCISH_DEF_FLAG_i686-pc-windows-gnu :=
CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-windows-gnu :=
CFG_GCCISH_POST_LIB_FLAGS_i686-pc-windows-gnu :=
CFG_DEF_SUFFIX_i686-pc-windows-gnu := .windows.def
CFG_LLC_FLAGS_i686-pc-windows-gnu :=
CFG_INSTALL_NAME_i686-pc-windows-gnu =
CFG_EXE_SUFFIX_i686-pc-windows-gnu := .exe
CFG_WINDOWSY_i686-pc-windows-gnu := 1
CFG_UNIXY_i686-pc-windows-gnu :=
CFG_PATH_MUNGE_i686-pc-windows-gnu :=
CFG_LDPATH_i686-pc-windows-gnu :=
CFG_RUN_i686-pc-windows-gnu=$(2)
CFG_RUN_TARG_i686-pc-windows-gnu=$(call CFG_RUN_i686-pc-windows-gnu,,$(2))

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
CFG_INSTALL_NAME_i686-unknown-linux-gnu =
CFG_EXE_SUFFIX_i686-unknown-linux-gnu =
CFG_WINDOWSY_i686-unknown-linux-gnu :=
CFG_UNIXY_i686-unknown-linux-gnu := 1
CFG_PATH_MUNGE_i686-unknown-linux-gnu := true
CFG_LDPATH_i686-unknown-linux-gnu :=
CFG_RUN_i686-unknown-linux-gnu=$(2)
CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-floa
CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
CFG_WINDOWSY_mips-unknown-linux-gnu :=
CFG_UNIXY_mips-unknown-linux-gnu := 1
CFG_PATH_MUNGE_mips-unknown-linux-gnu := true
CFG_LDPATH_mips-unknown-linux-gnu :=
CFG_RUN_mips-unknown-linux-gnu=
CFG_RUN_TARG_mips-unknown-linux-gnu=

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_mipsel-unknown-linux-gnu := -Wall -g -fPIC -mips32 -mabi=32 $(
CFG_GCCISH_CXXFLAGS_mipsel-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mipsel-unknown-linux-gnu := -shared -fPIC -g -mips32
CFG_GCCISH_DEF_FLAG_mipsel-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_mipsel-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_mipsel-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_mipsel-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_mipsel-unknown-linux-gnu :=
CFG_INSTALL_NAME_mipsel-unknown-linux-gnu =
CFG_EXE_SUFFIX_mipsel-unknown-linux-gnu :=
CFG_WINDOWSY_mipsel-unknown-linux-gnu :=
CFG_UNIXY_mipsel-unknown-linux-gnu := 1
CFG_PATH_MUNGE_mipsel-unknown-linux-gnu := true
CFG_LDPATH_mipsel-unknown-linux-gnu :=
CFG_RUN_mipsel-unknown-linux-gnu=
CFG_RUN_TARG_mipsel-unknown-linux-gnu=

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_powerpc-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFL
CFG_GCCISH_CXXFLAGS_powerpc-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_powerpc-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_powerpc-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_powerpc-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_powerpc-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_powerpc-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_powerpc-unknown-linux-gnu :=
CFG_INSTALL_NAME_powerpc-unknown-linux-gnu =
CFG_EXE_SUFFIX_powerpc-unknown-linux-gnu =
CFG_WINDOWSY_powerpc-unknown-linux-gnu :=
CFG_UNIXY_powerpc-unknown-linux-gnu := 1
CFG_PATH_MUNGE_powerpc-unknown-linux-gnu := true
CFG_LDPATH_powerpc-unknown-linux-gnu :=
CFG_RUN_powerpc-unknown-linux-gnu=$(2)
CFG_RUN_TARG_powerpc-unknown-linux-gnu=$(call CFG_RUN_powerpc-unknown-linux-gnu,,$(2))

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_6
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64
CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
CFG_LLC_FLAGS_x86_64-apple-darwin :=
CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_x86_64-apple-darwin :=
CFG_WINDOWSY_x86_64-apple-darwin :=
CFG_UNIXY_x86_64-apple-darwin := 1
CFG_PATH_MUNGE_x86_64-apple-darwin := true
CFG_LDPATH_x86_64-apple-darwin :=
CFG_RUN_x86_64-apple-darwin=$(2)
CFG_RUN_TARG_x86_64-apple-darwin=$(call CFG_RUN_x86_64-apple-darwin,,$(2))

View File

@ -20,16 +20,12 @@ CFG_GCCISH_CFLAGS_x86_64-apple-ios := -Wall -Werror -fPIC $(CFG_IOSSIM_FLAGS_x86
CFG_GCCISH_CXXFLAGS_x86_64-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_x86_64-apple-ios) -I$(CFG_IOSSIM_SDK_x86_64-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_x86_64-apple-ios := -lpthread -Wl,-no_compact_unwind -m64 -Wl,-syslibroot $(CFG_IOSSIM_SDK_x86_64-apple-ios)
CFG_GCCISH_DEF_FLAG_x86_64-apple-ios := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-ios :=
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-ios :=
CFG_DEF_SUFFIX_x86_64-apple-ios := .darwin.def
CFG_LLC_FLAGS_x86_64-apple-ios :=
CFG_INSTALL_NAME_x86_64-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_LIBUV_LINK_FLAGS_x86_64-apple-ios :=
CFG_EXE_SUFFIX_x86_64-apple-ios :=
CFG_WINDOWSY_x86_64-apple-ios :=
CFG_UNIXY_x86_64-apple-ios := 1
CFG_PATH_MUNGE_x86_64-apple-ios := true
CFG_LDPATH_x86_64-apple-ios :=
CFG_RUN_x86_64-apple-ios = $(2)
CFG_RUN_TARG_x86_64-apple-ios = $(call CFG_RUN_x86_64-apple-ios,,$(2))

View File

@ -13,15 +13,11 @@ CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -Wall -Werror -g -m64 -D_WIN32_WINNT=
CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-gnu := -shared -g -m64
CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-gnu :=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-pc-windows-gnu :=
CFG_GCCISH_POST_LIB_FLAGS_x86_64-pc-windows-gnu :=
CFG_DEF_SUFFIX_x86_64-pc-windows-gnu := .windows.def
CFG_LLC_FLAGS_x86_64-pc-windows-gnu :=
CFG_INSTALL_NAME_x86_64-pc-windows-gnu =
CFG_EXE_SUFFIX_x86_64-pc-windows-gnu := .exe
CFG_WINDOWSY_x86_64-pc-windows-gnu := 1
CFG_UNIXY_x86_64-pc-windows-gnu :=
CFG_PATH_MUNGE_x86_64-pc-windows-gnu :=
CFG_LDPATH_x86_64-pc-windows-gnu :=
CFG_RUN_x86_64-pc-windows-gnu=$(2)
CFG_RUN_TARG_x86_64-pc-windows-gnu=$(call CFG_RUN_x86_64-pc-windows-gnu,,$(2))

View File

@ -11,15 +11,11 @@ CFG_JEMALLOC_CFLAGS_x86_64-unknown-bitrig := -m64 -I/usr/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -Wall -Werror -fPIC -m64 -I/usr/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-bitrig := -shared -pic -pthread -m64 $(LDFLAGS)
CFG_GCCISH_DEF_FLAG_x86_64-unknown-bitrig := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-bitrig := -Wl,-pic -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-bitrig := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-bitrig := .bsd.def
CFG_LLC_FLAGS_x86_64-unknown-bitrig :=
CFG_INSTALL_NAME_x86_64-unknown-bitrig =
CFG_EXE_SUFFIX_x86_64-unknown-bitrig :=
CFG_WINDOWSY_x86_64-unknown-bitrig :=
CFG_UNIXY_x86_64-unknown-bitrig := 1
CFG_PATH_MUNGE_x86_64-unknown-bitrig :=
CFG_LDPATH_x86_64-unknown-bitrig :=
CFG_RUN_x86_64-unknown-bitrig=$(2)
CFG_RUN_TARG_x86_64-unknown-bitrig=$(call CFG_RUN_x86_64-unknown-bitrig,,$(2))

View File

@ -11,15 +11,11 @@ CFG_JEMALLOC_CFLAGS_x86_64-unknown-dragonfly := -m64 -I/usr/include -I/usr/local
CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread -lrt -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-dragonfly := .bsd.def
CFG_LLC_FLAGS_x86_64-unknown-dragonfly :=
CFG_INSTALL_NAME_x86_64-unknown-dragonfly =
CFG_EXE_SUFFIX_x86_64-unknown-dragonfly :=
CFG_WINDOWSY_x86_64-unknown-dragonfly :=
CFG_UNIXY_x86_64-unknown-dragonfly := 1
CFG_PATH_MUNGE_x86_64-unknown-dragonfly :=
CFG_LDPATH_x86_64-unknown-dragonfly :=
CFG_RUN_x86_64-unknown-dragonfly=$(2)
CFG_RUN_TARG_x86_64-unknown-dragonfly=$(call CFG_RUN_x86_64-unknown-dragonfly,,$(2))

View File

@ -11,15 +11,11 @@ CFG_JEMALLOC_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
CFG_INSTALL_NAME_x86_64-unknown-freebsd =
CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=
CFG_WINDOWSY_x86_64-unknown-freebsd :=
CFG_UNIXY_x86_64-unknown-freebsd := 1
CFG_PATH_MUNGE_x86_64-unknown-freebsd :=
CFG_LDPATH_x86_64-unknown-freebsd :=
CFG_RUN_x86_64-unknown-freebsd=$(2)
CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))

View File

@ -12,15 +12,11 @@ CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_x86_64-unknown-linux-gnu :=
CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
CFG_EXE_SUFFIX_x86_64-unknown-linux-gnu =
CFG_WINDOWSY_x86_64-unknown-linux-gnu :=
CFG_UNIXY_x86_64-unknown-linux-gnu := 1
CFG_PATH_MUNGE_x86_64-unknown-linux-gnu := true
CFG_LDPATH_x86_64-unknown-linux-gnu :=
CFG_RUN_x86_64-unknown-linux-gnu=$(2)
CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))

View File

@ -0,0 +1,27 @@
# x86_64-unknown-linux-musl configuration
CC_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc
CXX_x86_64-unknown-linux-musl=notaprogram
CPP_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc -E
AR_x86_64-unknown-linux-musl=$(AR)
CFG_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-linux-musl=lib$(1)-*.so
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl := -Wall -Werror -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-musl :=
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-musl :=
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-musl :=
CFG_LLC_FLAGS_x86_64-unknown-linux-musl :=
CFG_INSTALL_NAME_x86_64-unknown-linux-musl =
CFG_EXE_SUFFIX_x86_64-unknown-linux-musl =
CFG_WINDOWSY_x86_64-unknown-linux-musl :=
CFG_UNIXY_x86_64-unknown-linux-musl := 1
CFG_LDPATH_x86_64-unknown-linux-musl :=
CFG_RUN_x86_64-unknown-linux-musl=$(2)
CFG_RUN_TARG_x86_64-unknown-linux-musl=$(call CFG_RUN_x86_64-unknown-linux-musl,,$(2))
CFG_GNU_TRIPLE_x86_64-unknown-linux-musl := x86_64-unknown-linux-musl
NATIVE_DEPS_libc_T_x86_64-unknown-linux-musl += libc.a
NATIVE_DEPS_std_T_x86_64-unknown-linux-musl += libunwind.a \
crt1.o crti.o crtn.o
INSTALLED_OBJECTS_x86_64-unknown-linux-musl += crt1.o crti.o crtn.o

View File

@ -11,15 +11,11 @@ CFG_JEMALLOC_CFLAGS_x86_64-unknown-openbsd := -m64 -I/usr/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-openbsd := -Wall -Werror -g -fPIC -m64 -I/usr/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-openbsd := -shared -fPIC -g -pthread -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-openbsd := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-openbsd := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-openbsd := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-openbsd := .bsd.def
CFG_LLC_FLAGS_x86_64-unknown-openbsd :=
CFG_INSTALL_NAME_x86_64-unknown-openbsd =
CFG_EXE_SUFFIX_x86_64-unknown-openbsd :=
CFG_WINDOWSY_x86_64-unknown-openbsd :=
CFG_UNIXY_x86_64-unknown-openbsd := 1
CFG_PATH_MUNGE_x86_64-unknown-openbsd :=
CFG_LDPATH_x86_64-unknown-openbsd :=
CFG_RUN_x86_64-unknown-openbsd=$(2)
CFG_RUN_TARG_x86_64-unknown-openbsd=$(call CFG_RUN_x86_64-unknown-openbsd,,$(2))

View File

@ -52,18 +52,19 @@
TARGET_CRATES := libc std flate arena term \
serialize getopts collections test rand \
log graphviz core rbml alloc \
unicode rustc_bitflags
rustc_unicode rustc_bitflags
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
rustc_data_structures
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc rustbook
TOOLS := compiletest rustdoc rustc rustbook error-index-generator
DEPS_core :=
DEPS_libc := core
DEPS_unicode := core
DEPS_rustc_unicode := core
DEPS_alloc := core libc native:jemalloc
DEPS_std := core libc rand alloc collections unicode \
DEPS_std := core libc rand alloc collections rustc_unicode \
native:rust_builtin native:backtrace native:rustrt_native \
rustc_bitflags
DEPS_graphviz := std
@ -80,9 +81,10 @@ DEPS_rustc_resolve := rustc log syntax
DEPS_rustc_privacy := rustc log syntax
DEPS_rustc_lint := rustc log syntax
DEPS_rustc := syntax flate arena serialize getopts rbml \
log graphviz rustc_llvm rustc_back
log graphviz rustc_llvm rustc_back rustc_data_structures
DEPS_rustc_llvm := native:rustllvm libc std
DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustc_data_structures := std log serialize
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test rustc_lint
DEPS_rustc_bitflags := core
@ -94,7 +96,7 @@ DEPS_serialize := std log
DEPS_rbml := std log serialize
DEPS_term := std log
DEPS_getopts := std
DEPS_collections := core alloc unicode
DEPS_collections := core alloc rustc_unicode
DEPS_num := std
DEPS_test := std getopts serialize rbml term native:rust_test_helpers
DEPS_rand := core
@ -105,21 +107,26 @@ TOOL_DEPS_compiletest := test getopts
TOOL_DEPS_rustdoc := rustdoc
TOOL_DEPS_rustc := rustc_driver
TOOL_DEPS_rustbook := std rustdoc
TOOL_DEPS_error-index-generator := rustdoc syntax serialize
TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
TOOL_SOURCE_rustbook := $(S)src/rustbook/main.rs
TOOL_SOURCE_error-index-generator := $(S)src/error-index-generator/main.rs
ONLY_RLIB_core := 1
ONLY_RLIB_libc := 1
ONLY_RLIB_alloc := 1
ONLY_RLIB_rand := 1
ONLY_RLIB_collections := 1
ONLY_RLIB_unicode := 1
ONLY_RLIB_rustc_unicode := 1
ONLY_RLIB_rustc_bitflags := 1
# Documented-by-default crates
DOC_CRATES := std alloc collections core libc unicode
DOC_CRATES := std alloc collections core libc rustc_unicode
# Installed objects/libraries by default
INSTALLED_OBJECTS := libmorestack.a libcompiler-rt.a
################################################################################
# You should not need to edit below this line
@ -146,3 +153,7 @@ TOOL_INPUTS_$(1) := $$(call rwildcard,$$(dir $$(TOOL_SOURCE_$(1))),*.rs)
endef
$(foreach crate,$(TOOLS),$(eval $(call RUST_TOOL,$(crate))))
ifdef CFG_DISABLE_ELF_TLS
RUSTFLAGS_std := --cfg no_elf_tls
endif

View File

@ -52,6 +52,7 @@ PKG_FILES := \
doc \
driver \
etc \
error-index-generator \
$(foreach crate,$(CRATES),lib$(crate)) \
libcollectionstest \
libcoretest \

View File

@ -71,9 +71,13 @@ RUSTBOOK_EXE = $(HBIN2_H_$(CFG_BUILD))/rustbook$(X_$(CFG_BUILD))
# ./configure
RUSTBOOK = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTBOOK_EXE)
# The error-index-generator executable...
ERR_IDX_GEN_EXE = $(HBIN2_H_$(CFG_BUILD))/error-index-generator$(X_$(CFG_BUILD))
ERR_IDX_GEN = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE)
D := $(S)src/doc
DOC_TARGETS := trpl style
DOC_TARGETS := trpl style error-index
COMPILER_DOC_TARGETS :=
DOC_L10N_TARGETS :=
@ -288,3 +292,9 @@ doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
@$(call E, rustbook: $@)
$(Q)rm -rf doc/style
$(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
error-index: doc/error-index.html
doc/error-index.html: $(ERR_IDX_GEN_EXE) | doc/
$(Q)$(call E, error-index-generator: $@)
$(Q)$(ERR_IDX_GEN)

View File

@ -13,14 +13,16 @@
######################################################################
# The version number
CFG_RELEASE_NUM=1.0.0
CFG_RELEASE_NUM=1.1.0
# An optional number to put after the label, e.g. '.2' -> '-beta.2'
# NB Make sure it starts with a dot to conform to semver pre-release
# versions (section 9)
CFG_PRERELEASE_VERSION=.5
CFG_FILENAME_EXTRA=4e7c5e5c
# Append a version-dependent hash to each library, so we can install different
# versions in the same place
CFG_FILENAME_EXTRA=$(shell printf '%s' $(CFG_RELEASE) | $(CFG_HASH_COMMAND))
ifeq ($(CFG_RELEASE_CHANNEL),stable)
# This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly"
@ -31,7 +33,11 @@ CFG_DISABLE_UNSTABLE_FEATURES=1
endif
ifeq ($(CFG_RELEASE_CHANNEL),beta)
CFG_RELEASE=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
# When building beta distributables just reuse the same "beta" name
# so when we upload we'll always override the previous beta. This
# doesn't actually impact the version reported by rustc - it's just
# for file naming.
CFG_PACKAGE_VERS=beta
CFG_DISABLE_UNSTABLE_FEATURES=1
endif
ifeq ($(CFG_RELEASE_CHANNEL),nightly)
@ -68,9 +74,6 @@ ifneq ($(wildcard $(subst $(SPACE),\$(SPACE),$(CFG_GIT_DIR))),)
endif
endif
CFG_BUILD_DATE = $(shell date +%F)
CFG_VERSION += (built $(CFG_BUILD_DATE))
# Windows exe's need numeric versions - don't use anything but
# numbers and dots here
CFG_VERSION_WIN = $(CFG_RELEASE_NUM)
@ -191,6 +194,7 @@ ifndef CFG_DISABLE_VALGRIND_RPASS
$(info cfg: valgrind-rpass command set to $(CFG_VALGRIND))
CFG_VALGRIND_RPASS :=$(CFG_VALGRIND)
else
$(info cfg: disabling valgrind run-pass tests)
CFG_VALGRIND_RPASS :=
endif
@ -326,7 +330,6 @@ endif
ifdef CFG_VER_HASH
export CFG_VER_HASH
endif
export CFG_BUILD_DATE
export CFG_VERSION
export CFG_VERSION_WIN
export CFG_RELEASE
@ -395,8 +398,10 @@ endif
# Prerequisites for using the stageN compiler to build target artifacts
TSREQ$(1)_T_$(2)_H_$(3) = \
$$(HSREQ$(1)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a \
$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
$$(foreach obj,$$(INSTALLED_OBJECTS),\
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(obj)) \
$$(foreach obj,$$(INSTALLED_OBJECTS_$(2)),\
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(obj))
# Prerequisites for a working stageN compiler and libraries, for a specific
# target

View File

@ -46,8 +46,9 @@ endif
# see https://blog.mozilla.org/jseward/2012/06/05/valgrind-now-supports-jemalloc-builds-directly/
ifdef CFG_VALGRIND
CFG_VALGRIND += --error-exitcode=100 \
--soname-synonyms=somalloc=NONE \
--fair-sched=try \
--quiet \
--soname-synonyms=somalloc=NONE \
--suppressions=$(CFG_SRC_DIR)src/etc/x86.supp \
$(OS_SUPP)
ifdef CFG_ENABLE_HELGRIND

View File

@ -70,7 +70,7 @@ define PREPARE_MAN
$(Q)$(PREPARE_MAN_CMD) $(PREPARE_SOURCE_MAN_DIR)/$(1) $(PREPARE_DEST_MAN_DIR)/$(1)
endef
PREPARE_TOOLS = $(filter-out compiletest rustbook, $(TOOLS))
PREPARE_TOOLS = $(filter-out compiletest rustbook error-index-generator, $(TOOLS))
# $(1) is tool
@ -140,8 +140,8 @@ prepare-target-$(2)-host-$(3)-$(1)-$(4): prepare-maybe-clean-$(4) \
$$(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),),),)
$$(foreach object,$$(INSTALLED_OBJECTS) $$(INSTALLED_OBJECTS_$(2)),\
$$(call PREPARE_LIB,$$(object))),),),)
endef
define INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS

View File

@ -74,7 +74,8 @@ $$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.ll $$(MKFILE_DEPS) \
@mkdir -p $$(@D)
@$$(call E, compile: $$@)
$$(Q)$$(LLC_$$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) \
-filetype=obj -mtriple=$$(CFG_LLVM_TARGET_$(1)) -relocation-model=pic -o $$@ $$<
-filetype=obj -mtriple=$$(CFG_LLVM_TARGET_$(1)) \
-relocation-model=pic -o $$@ $$<
$$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.c $$(MKFILE_DEPS)
@mkdir -p $$(@D)
@ -110,6 +111,11 @@ $$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)): $$(OBJS_$(2)_$(1))
@$$(call E, link: $$@)
$$(Q)$$(AR_$(1)) rcs $$@ $$^
ifeq ($$(findstring windows,$(1)),windows)
$$(RT_OUTPUT_DIR_$(1))/lib$(2).a: $$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1))
$$(Q)cp $$^ $$@
endif
endef
$(foreach target,$(CFG_TARGET), \
@ -221,7 +227,7 @@ COMPRT_DEPS := $(wildcard \
$(S)src/compiler-rt/*/*/*/*)
endif
COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
COMPRT_NAME_$(1) := libcompiler-rt.a
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
@ -312,6 +318,19 @@ endif # endif for windowsy
endif # endif for ios
endif # endif for darwin
################################################################################
# libc/libunwind for musl
#
# When we're building a musl-like target we're going to link libc/libunwind
# statically into the standard library and liblibc, so we need to make sure
# they're in a location that we can find
################################################################################
ifeq ($$(findstring musl,$(1)),musl)
$$(RT_OUTPUT_DIR_$(1))/%: $$(CFG_MUSL_ROOT)/lib/%
cp $$^ $$@
endif
endef
# Instantiate template for all stages/targets

View File

@ -25,8 +25,6 @@ endif
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp)
RUSTLLVM_DEF_$(1) := $(1)/rustllvm/rustllvm$(CFG_DEF_SUFFIX_$(1))
RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
-iquote $$(LLVM_INCDIR_$(1)) \
-iquote $$(S)src/rustllvm/include

View File

@ -35,7 +35,9 @@ CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(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)))
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),$$(dep))) \
$$(foreach dep,$$(NATIVE_DEPS_$(4)_T_$(2)), \
$$(RT_OUTPUT_DIR_$(2))/$$(dep))
endef
$(foreach host,$(CFG_HOST), \
@ -143,14 +145,7 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/:
$$(TLIB$(1)_T_$(2)_H_$(3))/:
mkdir -p $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a: \
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),compiler-rt) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),morestack) \
$$(TLIB$(1)_T_$(2)_H_$(3))/%: $$(RT_OUTPUT_DIR_$(2))/% \
| $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@

View File

@ -15,14 +15,14 @@
# The names of crates that must be tested
# libcore/libunicode tests are in a separate crate
# libcore/librustc_unicode tests are in a separate crate
DEPS_coretest :=
$(eval $(call RUST_CRATE,coretest))
DEPS_collectionstest :=
$(eval $(call RUST_CRATE,collectionstest))
TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) \
TEST_TARGET_CRATES = $(filter-out core rustc_unicode,$(TARGET_CRATES)) \
collectionstest coretest
TEST_DOC_CRATES = $(DOC_CRATES)
TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve \
@ -304,6 +304,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
check-stage$(1)-T-$(2)-H-$(3)-pfail-exec \
check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \
check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-rfail-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)-rustdocck-exec \
@ -345,6 +346,7 @@ check-stage$(1)-T-$(2)-H-$(3)-pretty-exec: \
check-stage$(1)-T-$(2)-H-$(3)-pretty-rpass-valgrind-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-rfail-full-exec \
check-stage$(1)-T-$(2)-H-$(3)-pretty-bench-exec \
check-stage$(1)-T-$(2)-H-$(3)-pretty-pretty-exec
@ -464,6 +466,7 @@ $(foreach host,$(CFG_HOST), \
RPASS_RS := $(wildcard $(S)src/test/run-pass/*.rs)
RPASS_VALGRIND_RS := $(wildcard $(S)src/test/run-pass-valgrind/*.rs)
RPASS_FULL_RS := $(wildcard $(S)src/test/run-pass-fulldeps/*.rs)
RFAIL_FULL_RS := $(wildcard $(S)src/test/run-fail-fulldeps/*.rs)
CFAIL_FULL_RS := $(wildcard $(S)src/test/compile-fail-fulldeps/*.rs)
RFAIL_RS := $(wildcard $(S)src/test/run-fail/*.rs)
CFAIL_RS := $(wildcard $(S)src/test/compile-fail/*.rs)
@ -483,6 +486,7 @@ PERF_RS := $(wildcard $(S)src/test/bench/*.rs)
RPASS_TESTS := $(RPASS_RS)
RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS)
RPASS_FULL_TESTS := $(RPASS_FULL_RS)
RFAIL_FULL_TESTS := $(RFAIL_FULL_RS)
CFAIL_FULL_TESTS := $(CFAIL_FULL_RS)
RFAIL_TESTS := $(RFAIL_RS)
CFAIL_TESTS := $(CFAIL_RS)
@ -510,6 +514,11 @@ CTEST_BUILD_BASE_rpass-full = run-pass-fulldeps
CTEST_MODE_rpass-full = run-pass
CTEST_RUNTOOL_rpass-full = $(CTEST_RUNTOOL)
CTEST_SRC_BASE_rfail-full = run-fail-fulldeps
CTEST_BUILD_BASE_rfail-full = run-fail-fulldeps
CTEST_MODE_rfail-full = run-fail
CTEST_RUNTOOL_rfail-full = $(CTEST_RUNTOOL)
CTEST_SRC_BASE_cfail-full = compile-fail-fulldeps
CTEST_BUILD_BASE_cfail-full = compile-fail-fulldeps
CTEST_MODE_cfail-full = compile-fail
@ -623,6 +632,13 @@ ifndef CFG_DISABLE_OPTIMIZE_TESTS
CTEST_RUSTC_FLAGS += -O
endif
# Analogously to the above, whether to pass `-g` when compiling tests
# is a separate choice from whether to pass `-g` when building the
# compiler and standard library themselves.
CTEST_RUSTC_FLAGS := $$(subst -g,,$$(CTEST_RUSTC_FLAGS))
ifdef CFG_ENABLE_DEBUGINFO_TESTS
CTEST_RUSTC_FLAGS += -g
endif
CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
--compile-lib-path $$(HLIB$(1)_H_$(3)) \
@ -661,6 +677,7 @@ endif
CTEST_DEPS_rpass_$(1)-T-$(2)-H-$(3) = $$(RPASS_TESTS)
CTEST_DEPS_rpass-valgrind_$(1)-T-$(2)-H-$(3) = $$(RPASS_VALGRIND_TESTS)
CTEST_DEPS_rpass-full_$(1)-T-$(2)-H-$(3) = $$(RPASS_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
CTEST_DEPS_rfail-full_$(1)-T-$(2)-H-$(3) = $$(RFAIL_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
CTEST_DEPS_cfail-full_$(1)-T-$(2)-H-$(3) = $$(CFAIL_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
CTEST_DEPS_rfail_$(1)-T-$(2)-H-$(3) = $$(RFAIL_TESTS)
CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS)
@ -737,7 +754,7 @@ endif
endef
CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail pfail \
CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \
bench perf debuginfo-gdb debuginfo-lldb codegen rustdocck
$(foreach host,$(CFG_HOST), \
@ -746,27 +763,33 @@ $(foreach host,$(CFG_HOST), \
$(eval $(foreach name,$(CTEST_NAMES), \
$(eval $(call DEF_RUN_COMPILETEST,$(stage),$(target),$(host),$(name))))))))))
PRETTY_NAMES = pretty-rpass pretty-rpass-valgrind pretty-rpass-full pretty-rfail pretty-bench pretty-pretty
PRETTY_NAMES = pretty-rpass pretty-rpass-valgrind pretty-rpass-full pretty-rfail-full pretty-rfail \
pretty-bench pretty-pretty
PRETTY_DEPS_pretty-rpass = $(RPASS_TESTS)
PRETTY_DEPS_pretty-rpass-valgrind = $(RPASS_VALGRIND_TESTS)
PRETTY_DEPS_pretty-rpass-full = $(RPASS_FULL_TESTS)
PRETTY_DEPS_pretty-rfail-full = $(RFAIL_FULL_TESTS)
PRETTY_DEPS_pretty-rfail = $(RFAIL_TESTS)
PRETTY_DEPS_pretty-bench = $(BENCH_TESTS)
PRETTY_DEPS_pretty-pretty = $(PRETTY_TESTS)
# The stage- and host-specific dependencies are for e.g. macro_crate_test which pulls in
# external crates.
PRETTY_DEPS$(1)_H_$(3)_pretty-rpass =
PRETTY_DEPS$(1)_H_$(3)_pretty-rpass-full = $$(HLIB$(1)_H_$(3))/stamp.syntax $$(HLIB$(1)_H_$(3))/stamp.rustc
PRETTY_DEPS$(1)_H_$(3)_pretty-rfail =
PRETTY_DEPS$(1)_H_$(3)_pretty-bench =
PRETTY_DEPS$(1)_H_$(3)_pretty-pretty =
PRETTY_DIRNAME_pretty-rpass = run-pass
PRETTY_DIRNAME_pretty-rpass-valgrind = run-pass-valgrind
PRETTY_DIRNAME_pretty-rpass-full = run-pass-fulldeps
PRETTY_DIRNAME_pretty-rfail-full = run-fail-fulldeps
PRETTY_DIRNAME_pretty-rfail = run-fail
PRETTY_DIRNAME_pretty-bench = bench
PRETTY_DIRNAME_pretty-pretty = pretty
define DEF_PRETTY_FULLDEPS
PRETTY_DEPS$(1)_T_$(2)_H_$(3)_pretty-rpass-full = $$(CSREQ$(1)_T_$(3)_H_$(3))
PRETTY_DEPS$(1)_T_$(2)_H_$(3)_pretty-rfail-full = $$(CSREQ$(1)_T_$(3)_H_$(3))
endef
$(foreach host,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(foreach stage,$(STAGES), \
$(eval $(call DEF_PRETTY_FULLDEPS,$(stage),$(target),$(host))))))
define DEF_RUN_PRETTY_TEST
PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
@ -780,7 +803,7 @@ 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)) \
$$(PRETTY_DEPS_$(4)) \
$$(PRETTY_DEPS$(1)_H_$(3)_$(4))
$$(PRETTY_DEPS$(1)_T_$(2)_H_$(3)_$(4))
@$$(call E, run pretty-rpass [$(2)]: $$<)
$$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
@ -899,6 +922,7 @@ TEST_GROUPS = \
rpass \
rpass-valgrind \
rpass-full \
rfail-full \
cfail-full \
rfail \
cfail \
@ -916,6 +940,7 @@ TEST_GROUPS = \
pretty-rpass \
pretty-rpass-valgrind \
pretty-rpass-full \
pretty-rfail-full \
pretty-rfail \
pretty-bench \
pretty-pretty \

View File

@ -269,7 +269,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
run_ignored: config.run_ignored,
logfile: config.logfile.clone(),
run_tests: true,
run_benchmarks: true,
bench_benchmarks: true,
nocapture: env::var("RUST_TEST_NOCAPTURE").is_ok(),
color: test::AutoColor,
}

View File

@ -170,6 +170,9 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
format!("ignore-{}",
config.stage_id.split('-').next().unwrap())
}
fn ignore_env(config: &Config) -> String {
format!("ignore-{}", util::get_env(&config.target).unwrap_or("<unknown>"))
}
fn ignore_gdb(config: &Config, line: &str) -> bool {
if config.mode != common::DebugInfoGdb {
return false;
@ -231,6 +234,7 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
!parse_name_directive(ln, &ignore_target(config)) &&
!parse_name_directive(ln, &ignore_architecture(config)) &&
!parse_name_directive(ln, &ignore_stage(config)) &&
!parse_name_directive(ln, &ignore_env(config)) &&
!(config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty")) &&
!(config.target != config.host && parse_name_directive(ln, "ignore-cross-compile")) &&
!ignore_gdb(config, ln) &&

View File

@ -979,6 +979,7 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
// is the ending point, and * represents ANSI color codes.
for line in proc_res.stderr.lines() {
let mut was_expected = false;
let mut prev = 0;
for (i, ee) in expected_errors.iter().enumerate() {
if !found_flags[i] {
debug!("prefix={} ee.kind={} ee.msg={} line={}",
@ -986,6 +987,17 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
ee.kind,
ee.msg,
line);
// Suggestions have no line number in their output, so take on the line number of
// the previous expected error
if ee.kind == "suggestion" {
assert!(expected_errors[prev].kind == "help",
"SUGGESTIONs must be preceded by a HELP");
if line.contains(&ee.msg) {
found_flags[i] = true;
was_expected = true;
break;
}
}
if (prefix_matches(line, &prefixes[i]) || continuation(line)) &&
line.contains(&ee.kind) &&
line.contains(&ee.msg) {
@ -994,6 +1006,7 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
break;
}
}
prev = i;
}
// ignore this msg which gets printed at the end
@ -1220,7 +1233,20 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps,
let mut crate_type = if aux_props.no_prefer_dynamic {
Vec::new()
} else {
vec!("--crate-type=dylib".to_string())
// We primarily compile all auxiliary libraries as dynamic libraries
// to avoid code size bloat and large binaries as much as possible
// for the test suite (otherwise including libstd statically in all
// executables takes up quite a bit of space).
//
// For targets like MUSL, however, there is no support for dynamic
// libraries so we just go back to building a normal library. Note,
// however, that if the library is built with `force_host` then it's
// ok to be a dylib as the host should always support dylibs.
if config.target.contains("musl") && !aux_props.force_host {
vec!("--crate-type=lib".to_string())
} else {
vec!("--crate-type=dylib".to_string())
}
};
crate_type.extend(extra_link_args.clone().into_iter());
let aux_args =
@ -1452,7 +1478,7 @@ fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf {
fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
let f = output_base_name(config, testfile);
let mut fname = f.file_name().unwrap().to_os_string();
fname.push("libaux");
fname.push(&format!(".{}.libaux", config.mode));
f.with_file_name(&fname)
}

View File

@ -60,6 +60,10 @@ pub fn get_arch(triple: &str) -> &'static str {
panic!("Cannot determine Architecture from triple");
}
pub fn get_env(triple: &str) -> Option<&str> {
triple.split('-').nth(3)
}
pub fn make_new_path(path: &str) -> String {
assert!(cfg!(windows));
// Windows just uses PATH as the library search path, so we have to

View File

@ -39,7 +39,7 @@ representation as a primitive. This allows using Rust `enum`s in FFI where C
`enum`s are also used, for most use cases. The attribute can also be applied
to `struct`s to get the same layout as a C struct would.
[repr]: reference.html#miscellaneous-attributes
[repr]: reference.html#ffi-attributes
## There is no GC

View File

@ -109,7 +109,7 @@ This does mean that indexed access to a Unicode codepoint inside a `str` value i
* Most "character oriented" operations on text only work under very restricted language assumptions sets such as "ASCII-range codepoints only". Outside ASCII-range, you tend to have to use a complex (non-constant-time) algorithm for determining linguistic-unit (glyph, word, paragraph) boundaries anyways. We recommend using an "honest" linguistically-aware, Unicode-approved algorithm.
* The `char` type is UCS4. If you honestly need to do a codepoint-at-a-time algorithm, it's trivial to write a `type wstr = [char]`, and unpack a `str` into it in a single pass, then work with the `wstr`. In other words: the fact that the language is not "decoding to UCS4 by default" shouldn't stop you from decoding (or re-encoding any other way) if you need to work with that encoding.
## Why are strings, vectors etc. built-in types rather than (say) special kinds of trait/impl?
## Why are `str`s, slices, arrays etc. built-in types rather than (say) special kinds of trait/impl?
In each case there is one or more operator, literal constructor, overloaded use or integration with a built-in control structure that makes us think it would be awkward to phrase the type in terms of more-general type constructors. Same as, say, with numbers! But this is partly an aesthetic call, and we'd be willing to look at a worked-out proposal for eliminating or rephrasing these special cases.
@ -121,7 +121,7 @@ Yes. Calling C code from Rust is simple and exactly as efficient as calling C co
Yes. The Rust code has to be exposed via an `extern` declaration, which makes it C-ABI compatible. Such a function can be passed to C code as a function pointer or, if given the `#[no_mangle]` attribute to disable symbol mangling, can be called directly from C code.
## Why aren't function signatures inferred? Why only local slots?
## Why aren't function signatures inferred? Why only local variables?
* Mechanically, it simplifies the inference algorithm; inference only requires looking at one function at a time.
* The same simplification goes double for human readers. A reader does not need an IDE running an inference algorithm across an entire crate to be able to guess at a function's argument types; it's always explicit and nearby.

View File

@ -1346,6 +1346,8 @@ vtable when the trait is used as a [trait object](#trait-objects).
Traits are implemented for specific types through separate
[implementations](#implementations).
Consider the following trait:
```
# type Surface = i32;
# type BoundingBox = i32;
@ -1360,6 +1362,20 @@ This defines a trait with two methods. All values that have
`draw` and `bounding_box` methods called, using `value.bounding_box()`
[syntax](#method-call-expressions).
Traits can include default implementations of methods, as in:
```
trait Foo {
fn bar(&self);
fn baz(&self) { println!("We called baz."); }
}
```
Here the `baz` method has a default implementation, so types that implement
`Foo` need only implement `bar`. It is also possible for implementing types
to override a method that has a default implementation.
Type parameters can be specified for a trait to make it generic. These appear
after the trait name, using the same syntax used in [generic
functions](#generic-functions).
@ -1372,6 +1388,35 @@ trait Seq<T> {
}
```
It is also possible to define associated types for a trait. Consider the
following example of a `Container` trait. Notice how the type is available
for use in the method signatures:
```
trait Container {
type E;
fn empty() -> Self;
fn insert(&mut self, Self::E);
}
```
In order for a type to implement this trait, it must not only provide
implementations for every method, but it must specify the type `E`. Here's
an implementation of `Container` for the standard library type `Vec`:
```
# trait Container {
# type E;
# fn empty() -> Self;
# fn insert(&mut self, Self::E);
# }
impl<T> Container for Vec<T> {
type E = T;
fn empty() -> Vec<T> { Vec::new() }
fn insert(&mut self, x: T) { self.push(x); }
}
```
Generic functions may use traits as _bounds_ on their type parameters. This
will have two effects: only types that have the trait may instantiate the
parameter, and within the generic function, the methods of the trait can be
@ -3470,13 +3515,23 @@ more of the closure traits:
### Trait objects
Every trait item (see [traits](#traits)) defines a type with the same name as
the trait. This type is called the _trait object_ of the trait. Trait objects
permit "late binding" of methods, dispatched using _virtual method tables_
("vtables"). Whereas most calls to trait methods are "early bound" (statically
resolved) to specific implementations at compile time, a call to a method on an
trait objects is only resolved to a vtable entry at compile time. The actual
implementation for each vtable entry can vary on an object-by-object basis.
In Rust, a type like `&SomeTrait` or `Box<SomeTrait>` is called a _trait object_.
Each instance of a trait object includes:
- a pointer to an instance of a type `T` that implements `SomeTrait`
- a _virtual method table_, often just called a _vtable_, which contains, for
each method of `SomeTrait` that `T` implements, a pointer to `T`'s
implementation (i.e. a function pointer).
The purpose of trait objects is to permit "late binding" of methods. A call to
a method on a trait object is only resolved to a vtable entry at compile time.
The actual implementation for each vtable entry can vary on an object-by-object
basis.
Note that for a trait object to be instantiated, the trait must be
_object-safe_. Object safety rules are defined in [RFC 255].
[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md
Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
implements trait `R`, casting `E` to the corresponding pointer type `&R` or

View File

@ -175,7 +175,7 @@ data, we call the `clone()` method. In this example, `y` is no longer a referenc
to the vector stored in `x`, but a copy of its first element, `"Hello"`. Now
that we dont have a reference, our `push()` works just fine.
[move]: move-semantics.html
[move]: ownership.html#move-semantics
If we truly want a reference, we need the other option: ensure that our reference
goes out of scope before we try to do the mutation. That looks like this:

View File

@ -2,7 +2,7 @@
With the `associated_consts` feature, you can define constants like this:
```rust,ignore
```rust
#![feature(associated_consts)]
trait Foo {
@ -41,7 +41,7 @@ error: not all trait items implemented, missing: `ID` [E0046]
A default value can be implemented as well:
```rust,ignore
```rust
#![feature(associated_consts)]
trait Foo {
@ -68,7 +68,7 @@ add our own definition.
Associated constants dont have to be associated with a trait. An `impl` block
for a `struct` works fine too:
```rust,ignore
```rust
#![feature(associated_consts)]
struct Foo;

View File

@ -6,7 +6,7 @@ and more cores, yet many programmers aren't prepared to fully utilize them.
Rust's memory safety features also apply to its concurrency story too. Even
concurrent Rust programs must be memory safe, having no data races. Rust's type
system is up to the thread, and gives you powerful ways to reason about
system is up to the task, and gives you powerful ways to reason about
concurrent code at compile time.
Before we talk about the concurrency features that come with Rust, it's important

View File

@ -1,3 +0,0 @@
% `const`
Coming soon!

View File

@ -1,3 +0,0 @@
% Debug and Display
Coming soon!

View File

@ -73,6 +73,9 @@ a name is all we need. We choose the [`String`][string] type for the name,
rather than `&str`. Generally speaking, working with a type which owns its
data is easier than working with one that uses references.
[struct]: structs.html
[string]: strings.html
Lets continue:
```rust
@ -393,7 +396,7 @@ let handles: Vec<_> = philosophers.into_iter().map(|p| {
}).collect();
```
While this is only five lines, theyre a dense four. Lets break it down.
While this is only five lines, theyre a dense five. Lets break it down.
```rust,ignore
let handles: Vec<_> =
@ -450,7 +453,7 @@ which blocks execution until the thread has completed execution. This ensures
that the threads complete their work before the program exits.
If you run this program, youll see that the philosophers eat out of order!
We have mult-threading!
We have multi-threading!
```text
Gilles Deleuze is eating.

View File

@ -55,9 +55,6 @@ fn process_color_change(msg: Message) {
}
```
Both variants are named `Digit`, but since theyre scoped to the `enum` name
there's no ambiguity.
Not supporting these operations may seem rather limiting, but its a limitation
which we can overcome. There are two ways: by implementing equality ourselves,
or by pattern matching variants with [`match`][match] expressions, which youll
@ -66,3 +63,4 @@ equality yet, but well find out in the [`traits`][traits] section.
[match]: match.html
[if-let]: if-let.html
[traits]: traits.html

View File

@ -181,6 +181,8 @@ match version {
This function makes use of an enum, `ParseError`, to enumerate the various
errors that can occur.
The [`Debug`](../std/fmt/trait.Debug.html) trait is what lets us print the enum value using the `{:?}` format operation.
# Non-recoverable errors with `panic!`
In the case of an error that is unexpected and not recoverable, the `panic!`

View File

@ -27,7 +27,7 @@ Check out the generated `Cargo.toml`:
[package]
name = "guessing_game"
version = "0.0.1"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
```
@ -46,7 +46,7 @@ Lets try compiling what Cargo gave us:
```{bash}
$ cargo build
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
```
Excellent! Open up your `src/main.rs` again. Well be writing all of
@ -58,7 +58,7 @@ Try it out:
```bash
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/debug/guessing_game`
Hello, world!
```
@ -213,12 +213,12 @@ The next part will use this handle to get input from the user:
```
Here, we call the [`read_line()`][read_line] method on our handle.
[Method][method]s are like associated functions, but are only available on a
[Methods][method] are like associated functions, but are only available on a
particular instance of a type, rather than the type itself. Were also passing
one argument to `read_line()`: `&mut guess`.
[read_line]: ../std/io/struct.Stdin.html#method.read_line
[method]: methods.html
[method]: method-syntax.html
Remember how we bound `guess` above? We said it was mutable. However,
`read_line` doesnt take a `String` as an argument: it takes a `&mut String`.
@ -727,7 +727,7 @@ Lets try our program out!
```bash
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 58
@ -792,7 +792,7 @@ and quit. Observe:
```bash
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 59
@ -929,7 +929,7 @@ Now we should be good! Lets try:
```bash
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 61

View File

@ -20,11 +20,9 @@ $ sh rustup.sh
[insecurity]: http://curlpipesh.tumblr.com
If you're on Windows, please download either the [32-bit installer][win32] or
the [64-bit installer][win64] and run it.
If you're on Windows, please download the appropriate [installer][install-page].
[win32]: https://static.rust-lang.org/dist/rust-1.0.0-beta-i686-pc-windows-gnu.msi
[win64]: https://static.rust-lang.org/dist/rust-1.0.0-beta-x86_64-pc-windows-gnu.msi
[install-page]: http://www.rust-lang.org/install.html
## Uninstalling
@ -44,10 +42,9 @@ Some people, and somewhat rightfully so, get very upset when we tell you to
people who maintain Rust aren't going to hack your computer and do bad things.
That's a good instinct! If you're one of those people, please check out the
documentation on [building Rust from Source][from source], or [the official
binary downloads][install page].
binary downloads][install-page].
[from source]: https://github.com/rust-lang/rust#building-from-source
[install page]: http://www.rust-lang.org/install.html
Oh, we should also mention the officially supported platforms:
@ -71,10 +68,11 @@ If you've got Rust installed, you can open up a shell, and type this:
$ rustc --version
```
You should see the version number, commit hash, commit date and build date:
You should see the version number, commit hash, and commit date. If you just
installed version 1.0.0, you should see:
```bash
rustc 1.0.0-beta (9854143cb 2015-04-02) (built 2015-04-02)
rustc 1.0.0 (a59de37e9 2015-05-13)
```
If you did, Rust has been installed successfully! Congrats!

View File

@ -42,7 +42,7 @@ loop is just a handy way to write this `loop`/`match`/`break` construct.
`for` loops aren't the only thing that uses iterators, however. Writing your
own iterator involves implementing the `Iterator` trait. While doing that is
outside of the scope of this guide, Rust provides a number of useful iterators
to accomplish various threads. Before we talk about those, we should talk about a
to accomplish various tasks. Before we talk about those, we should talk about a
Rust anti-pattern. And that's using ranges like this.
Yes, we just talked about how ranges are cool. But ranges are also very

View File

@ -97,4 +97,4 @@ Unlike the previous uses of `match`, you cant use the normal `if`
statement to do this. You can use the [`if let`][if-let] statement,
which can be seen as an abbreviated form of `match`.
[if-let][if-let.html]
[if-let]: if-let.html

View File

@ -1,3 +0,0 @@
% Move Semantics
Coming Soon

View File

@ -35,7 +35,7 @@ let y = &mut x;
`y` is an immutable binding to a mutable reference, which means that you cant
bind `y` to something else (`y = &mut z`), but you can mutate the thing thats
bound to `y`. (`*y = 5`) A subtle distinction.
bound to `y` (`*y = 5`). A subtle distinction.
Of course, if you need both:

View File

@ -66,7 +66,7 @@ match x {
}
```
This prints `something else`
This prints `something else`.
# Bindings
@ -152,7 +152,7 @@ match x {
}
```
This prints `Got an int!`
This prints `Got an int!`.
# ref and ref mut

View File

@ -1,3 +0,0 @@
% `static`
Coming soon!

View File

@ -196,3 +196,5 @@ useful. For instance, a library may ask you to create a structure that
implements a certain [trait][trait] to handle events. If you dont have
any data you need to store in the structure, you can just create a
unit-like struct.
[trait]: traits.html

View File

@ -80,7 +80,7 @@ This memory is kind of like a giant array: addresses start at zero and go
up to the final number. So heres a diagram of our first stack frame:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 0 | x | 42 |
Weve got `x` located at address `0`, with the value `42`.
@ -88,7 +88,7 @@ Weve got `x` located at address `0`, with the value `42`.
When `foo()` is called, a new stack frame is allocated:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 2 | z | 100 |
| 1 | y | 5 |
| 0 | x | 42 |
@ -107,7 +107,7 @@ value being stored.
After `foo()` is over, its frame is deallocated:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 0 | x | 42 |
And then, after `main()`, even this last value goes away. Easy!
@ -142,13 +142,13 @@ fn main() {
Okay, first, we call `main()`:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 0 | x | 42 |
Next up, `main()` calls `foo()`:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 3 | c | 1 |
| 2 | b | 100 |
| 1 | a | 5 |
@ -157,7 +157,7 @@ Next up, `main()` calls `foo()`:
And then `foo()` calls `bar()`:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 4 | i | 6 |
| 3 | c | 1 |
| 2 | b | 100 |
@ -170,7 +170,7 @@ After `bar()` is over, its frame is deallocated, leaving just `foo()` and
`main()`:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 3 | c | 1 |
| 2 | b | 100 |
| 1 | a | 5 |
@ -179,7 +179,7 @@ After `bar()` is over, its frame is deallocated, leaving just `foo()` and
And then `foo()` ends, leaving just `main()`
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 0 | x | 42 |
And then were done. Getting the hang of it? Its like piling up dishes: you
@ -206,7 +206,7 @@ fn main() {
Heres what happens in memory when `main()` is called:
| Address | Name | Value |
+---------+------+--------+
|---------|------|--------|
| 1 | y | 42 |
| 0 | x | ?????? |
@ -218,7 +218,7 @@ it allocates some memory for the heap, and puts `5` there. The memory now looks
like this:
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 5 |
| ... | ... | ... |
| 1 | y | 42 |
@ -243,7 +243,7 @@ layout of a program which has been running for a while now:
| Address | Name | Value |
+----------------------+------+----------------------+
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 5 |
| (2<sup>30</sup>) - 1 | | |
| (2<sup>30</sup>) - 2 | | |
@ -266,13 +266,13 @@ Rust programs use [jemalloc][jemalloc] for this purpose.
Anyway, back to our example. Since this memory is on the heap, it can stay
alive longer than the function which allocates the box. In this case, however,
it doesnt.[^moving] When the function is over, we need to free the stack frame
for `main()`. `Box<T>`, though, has a trick up its sleve: [Drop][drop]. The
for `main()`. `Box<T>`, though, has a trick up its sleeve: [Drop][drop]. The
implementation of `Drop` for `Box` deallocates the memory that was allocated
when it was created. Great! So when `x` goes away, it first frees the memory
allocated on the heap:
| Address | Name | Value |
+---------+------+--------+
|---------|------|--------|
| 1 | y | 42 |
| 0 | x | ?????? |
@ -305,7 +305,7 @@ fn main() {
When we enter `main()`, memory looks like this:
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 1 | y | 0 |
| 0 | x | 5 |
@ -315,7 +315,7 @@ memory location that `x` lives at, which in this case is `0`.
What about when we call `foo()`, passing `y` as an argument?
| Address | Name | Value |
+---------+------+-------+
|---------|------|-------|
| 3 | z | 42 |
| 2 | i | 0 |
| 1 | y | 0 |
@ -367,7 +367,7 @@ fn main() {
First, we call `main()`:
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
@ -380,7 +380,7 @@ value pointing there.
Next, at the end of `main()`, `foo()` gets called:
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
@ -397,7 +397,7 @@ since `j` points at `h`.
Next, `foo()` calls `baz()`, passing `z`:
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 7 | g | 100 |
@ -413,7 +413,7 @@ Weve allocated memory for `f` and `g`. `baz()` is very short, so when its
over, we get rid of its stack frame:
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
@ -426,11 +426,11 @@ over, we get rid of its stack frame:
Next, `foo()` calls `bar()` with `x` and `z`:
| Address | Name | Value |
+----------------------+------+----------------------+
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 4 |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
@ -449,13 +449,13 @@ case, we set up the variables as usual.
At the end of `bar()`, it calls `baz()`:
| Address | Name | Value |
+----------------------+------+----------------------+
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 12 | g | 100 |
| 11 | f | 4 |
| 10 | e | 4 |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
@ -473,11 +473,11 @@ far.
After `baz()` is over, we get rid of `f` and `g`:
| Address | Name | Value |
+----------------------+------+----------------------+
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 4 |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
@ -493,7 +493,7 @@ Next, we return from `bar()`. `d` in this case is a `Box<T>`, so it also frees
what it points to: (2<sup>30</sup>) - 1.
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
@ -506,7 +506,7 @@ what it points to: (2<sup>30</sup>) - 1.
And after that, `foo()` returns:
| Address | Name | Value |
+-----------------+------+----------------+
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | 0 |

View File

@ -1,56 +0,0 @@
% Tuple Structs
Rust has another data type that's like a hybrid between a tuple and a struct,
called a *tuple struct*. Tuple structs do have a name, but their fields don't:
```{rust}
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
```
These two will not be equal, even if they have the same values:
```{rust}
# struct Color(i32, i32, i32);
# struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
```
It is almost always better to use a struct than a tuple struct. We would write
`Color` and `Point` like this instead:
```{rust}
struct Color {
red: i32,
blue: i32,
green: i32,
}
struct Point {
x: i32,
y: i32,
z: i32,
}
```
Now, we have actual names, rather than positions. Good names are important,
and with a struct, we have actual names.
There _is_ one case when a tuple struct is very useful, though, and that's a
tuple struct with only one element. We call this the *newtype* pattern, because
it allows you to create a new type, distinct from that of its contained value
and expressing its own semantic meaning:
```{rust}
struct Inches(i32);
let length = Inches(10);
let Inches(integer_length) = length;
println!("length is {} inches", integer_length);
```
As you can see here, you can extract the inner integer type through a
destructuring `let`, as we discussed previously in 'tuples.' In this case, the
`let Inches(integer_length)` assigns `10` to `integer_length`.

View File

@ -1,183 +0,0 @@
% Unsafe Code
# Introduction
Rust aims to provide safe abstractions over the low-level details of
the CPU and operating system, but sometimes one needs to drop down and
write code at that level. This guide aims to provide an overview of
the dangers and power one gets with Rust's unsafe subset.
Rust provides an escape hatch in the form of the `unsafe { ... }`
block which allows the programmer to dodge some of the compiler's
checks and do a wide range of operations, such as:
- dereferencing [raw pointers](#raw-pointers)
- calling a function via FFI ([covered by the FFI guide](ffi.html))
- casting between types bitwise (`transmute`, aka "reinterpret cast")
- [inline assembly](#inline-assembly)
Note that an `unsafe` block does not relax the rules about lifetimes
of `&` and the freezing of borrowed data.
Any use of `unsafe` is the programmer saying "I know more than you" to
the compiler, and, as such, the programmer should be very sure that
they actually do know more about why that piece of code is valid. In
general, one should try to minimize the amount of unsafe code in a
code base; preferably by using the bare minimum `unsafe` blocks to
build safe interfaces.
> **Note**: the low-level details of the Rust language are still in
> flux, and there is no guarantee of stability or backwards
> compatibility. In particular, there may be changes that do not cause
> compilation errors, but do cause semantic changes (such as invoking
> undefined behaviour). As such, extreme care is required.
# Pointers
## References
One of Rust's biggest features is memory safety. This is achieved in
part via [the ownership system](ownership.html), which is how the
compiler can guarantee that every `&` reference is always valid, and,
for example, never pointing to freed memory.
These restrictions on `&` have huge advantages. However, they also
constrain how we can use them. For example, `&` doesn't behave
identically to C's pointers, and so cannot be used for pointers in
foreign function interfaces (FFI). Additionally, both immutable (`&`)
and mutable (`&mut`) references have some aliasing and freezing
guarantees, required for memory safety.
In particular, if you have an `&T` reference, then the `T` must not be
modified through that reference or any other reference. There are some
standard library types, e.g. `Cell` and `RefCell`, that provide inner
mutability by replacing compile time guarantees with dynamic checks at
runtime.
An `&mut` reference has a different constraint: when an object has an
`&mut T` pointing into it, then that `&mut` reference must be the only
such usable path to that object in the whole program. That is, an
`&mut` cannot alias with any other references.
Using `unsafe` code to incorrectly circumvent and violate these
restrictions is undefined behaviour. For example, the following
creates two aliasing `&mut` pointers, and is invalid.
```
use std::mem;
let mut x: u8 = 1;
let ref_1: &mut u8 = &mut x;
let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
// oops, ref_1 and ref_2 point to the same piece of data (x) and are
// both usable
*ref_1 = 10;
*ref_2 = 20;
```
## Raw pointers
Rust offers two additional pointer types (*raw pointers*), written as
`*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
respectively; indeed, one of their most common uses is for FFI,
interfacing with external C libraries.
Raw pointers have much fewer guarantees than other pointer types
offered by the Rust language and libraries. For example, they
- are not guaranteed to point to valid memory and are not even
guaranteed to be non-null (unlike both `Box` and `&`);
- do not have any automatic clean-up, unlike `Box`, and so require
manual resource management;
- are plain-old-data, that is, they don't move ownership, again unlike
`Box`, hence the Rust compiler cannot protect against bugs like
use-after-free;
- lack any form of lifetimes, unlike `&`, and so the compiler cannot
reason about dangling pointers; and
- have no guarantees about aliasing or mutability other than mutation
not being allowed directly through a `*const T`.
Fortunately, they come with a redeeming feature: the weaker guarantees
mean weaker restrictions. The missing restrictions make raw pointers
appropriate as a building block for implementing things like smart
pointers and vectors inside libraries. For example, `*` pointers are
allowed to alias, allowing them to be used to write shared-ownership
types like reference counted and garbage collected pointers, and even
thread-safe shared memory types (`Rc` and the `Arc` types are both
implemented entirely in Rust).
There are two things that you are required to be careful about
(i.e. require an `unsafe { ... }` block) with raw pointers:
- dereferencing: they can have any value: so possible results include
a crash, a read of uninitialised memory, a use-after-free, or
reading data as normal.
- pointer arithmetic via the `offset` [intrinsic](#intrinsics) (or
`.offset` method): this intrinsic uses so-called "in-bounds"
arithmetic, that is, it is only defined behaviour if the result is
inside (or one-byte-past-the-end) of the object from which the
original pointer came.
The latter assumption allows the compiler to optimize more
effectively. As can be seen, actually *creating* a raw pointer is not
unsafe, and neither is converting to an integer.
### References and raw pointers
At runtime, a raw pointer `*` and a reference pointing to the same
piece of data have an identical representation. In fact, an `&T`
reference will implicitly coerce to an `*const T` raw pointer in safe code
and similarly for the `mut` variants (both coercions can be performed
explicitly with, respectively, `value as *const T` and `value as *mut T`).
Going the opposite direction, from `*const` to a reference `&`, is not
safe. A `&T` is always valid, and so, at a minimum, the raw pointer
`*const T` has to point to a valid instance of type `T`. Furthermore,
the resulting pointer must satisfy the aliasing and mutability laws of
references. The compiler assumes these properties are true for any
references, no matter how they are created, and so any conversion from
raw pointers is asserting that they hold. The programmer *must*
guarantee this.
The recommended method for the conversion is
```
let i: u32 = 1;
// explicit cast
let p_imm: *const u32 = &i as *const u32;
let mut m: u32 = 2;
// implicit coercion
let p_mut: *mut u32 = &mut m;
unsafe {
let ref_imm: &u32 = &*p_imm;
let ref_mut: &mut u32 = &mut *p_mut;
}
```
The `&*x` dereferencing style is preferred to using a `transmute`.
The latter is far more powerful than necessary, and the more
restricted operation is harder to use incorrectly; for example, it
requires that `x` is a pointer (unlike `transmute`).
## Making the unsafe safe(r)
There are various ways to expose a safe interface around some unsafe
code:
- store pointers privately (i.e. not in public fields of public
structs), so that you can see and control all reads and writes to
the pointer in one place.
- use `assert!()` a lot: since you can't rely on the protection of the
compiler & type-system to ensure that your `unsafe` code is correct
at compile-time, use `assert!()` to verify that it is doing the
right thing at run-time.
- implement the `Drop` for resource clean-up via a destructor, and use
RAII (Resource Acquisition Is Initialization). This reduces the need
for any manual memory management by users, and automatically ensures
that clean-up is always run, even when the thread panics.
- ensure that any data stored behind a raw pointer is destroyed at the
appropriate time.

View File

@ -3,7 +3,7 @@
Rust also has a `while` loop. It looks like this:
```{rust}
let mut x = 5; // mut x: u32
let mut x = 5; // mut x: i32
let mut done = false; // mut done: bool
while !done {

View File

@ -0,0 +1,119 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rustc_private, rustdoc)]
extern crate syntax;
extern crate rustdoc;
extern crate serialize as rustc_serialize;
use std::collections::BTreeMap;
use std::fs::{read_dir, File};
use std::io::{Read, Write};
use std::path::Path;
use std::error::Error;
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap};
use rustdoc::html::markdown::Markdown;
use rustc_serialize::json;
/// Load all the metadata files from `metadata_dir` into an in-memory map.
fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
let mut all_errors = BTreeMap::new();
for entry in try!(read_dir(metadata_dir)) {
let path = try!(entry).path();
let mut metadata_str = String::new();
try!(
File::open(&path).and_then(|mut f|
f.read_to_string(&mut metadata_str))
);
let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
for (err_code, info) in some_errors {
all_errors.insert(err_code, info);
}
}
Ok(all_errors)
}
/// Output an HTML page for the errors in `err_map` to `output_path`.
fn render_error_page(err_map: &ErrorMetadataMap, output_path: &Path) -> Result<(), Box<Error>> {
let mut output_file = try!(File::create(output_path));
try!(write!(&mut output_file,
r##"<!DOCTYPE html>
<html>
<head>
<title>Rust Compiler Error Index</title>
<meta charset="utf-8">
<!-- Include rust.css after main.css so its rules take priority. -->
<link rel="stylesheet" type="text/css" href="main.css"/>
<link rel="stylesheet" type="text/css" href="rust.css"/>
<style>
.error-undescribed {{
display: none;
}}
</style>
</head>
<body>
"##
));
try!(write!(&mut output_file, "<h1>Rust Compiler Error Index</h1>\n"));
for (err_code, info) in err_map.iter() {
// Enclose each error in a div so they can be shown/hidden en masse.
let desc_desc = match info.description {
Some(_) => "error-described",
None => "error-undescribed"
};
let use_desc = match info.use_site {
Some(_) => "error-used",
None => "error-unused"
};
try!(write!(&mut output_file, "<div class=\"{} {}\">", desc_desc, use_desc));
// Error title (with self-link).
try!(write!(&mut output_file,
"<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
err_code
));
// Description rendered as markdown.
match info.description {
Some(ref desc) => try!(write!(&mut output_file, "{}", Markdown(desc))),
None => try!(write!(&mut output_file, "<p>No description.</p>\n"))
}
try!(write!(&mut output_file, "</div>\n"));
}
try!(write!(&mut output_file, "</body>\n</html>"));
Ok(())
}
fn main_with_result() -> Result<(), Box<Error>> {
let metadata_dir = get_metadata_dir();
let err_map = try!(load_all_errors(&metadata_dir));
try!(render_error_page(&err_map, Path::new("doc/error-index.html")));
Ok(())
}
fn main() {
if let Err(e) = main_with_result() {
panic!("{}", e.description());
}
}

View File

@ -1,6 +1,8 @@
# Configs
Here are some links to repos with configs which ease the use of rust:
These are some links to repos with configs which ease the use of rust.
## Officially Maintained Configs
* [rust.vim](https://github.com/rust-lang/rust.vim)
* [emacs rust-mode](https://github.com/rust-lang/rust-mode)
@ -8,3 +10,7 @@ Here are some links to repos with configs which ease the use of rust:
* [kate-config](https://github.com/rust-lang/kate-config)
* [nano-config](https://github.com/rust-lang/nano-config)
* [zsh-config](https://github.com/rust-lang/zsh-config)
## Community-maintained Configs
* [.editorconfig](https://gist.github.com/derhuerst/c9d1b9309e308d9851fa) ([what is this?](http://editorconfig.org/))

View File

@ -13,7 +13,6 @@
import os
import sys
import functools
import resource
STATUS = 0
@ -37,6 +36,7 @@ def only_on(platforms):
@only_on(('linux', 'darwin', 'freebsd', 'openbsd'))
def check_rlimit_core():
import resource
soft, hard = resource.getrlimit(resource.RLIMIT_CORE)
if soft > 0:
error_unless_permitted('ALLOW_NONZERO_RLIMIT_CORE', """\

View File

@ -1,156 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2012-2013 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.
# This script is for extracting the grammar from the rust docs.
import fileinput
collections = {"gram": [],
"keyword": [],
"reserved": [],
"binop": [],
"unop": []}
in_coll = False
coll = ""
for line in fileinput.input(openhook=fileinput.hook_encoded("utf-8")):
if in_coll:
if line.startswith("~~~~"):
in_coll = False
else:
if coll in ["keyword", "reserved", "binop", "unop"]:
for word in line.split():
if word not in collections[coll]:
collections[coll].append(word)
else:
collections[coll].append(line)
else:
if line.startswith("~~~~"):
for cname in collections:
if ("." + cname) in line:
coll = cname
in_coll = True
break
# Define operator symbol-names here
tokens = ["non_star", "non_slash", "non_eol",
"non_single_quote", "non_double_quote", "ident"]
symnames = {
".": "dot",
"+": "plus",
"-": "minus",
"/": "slash",
"*": "star",
"%": "percent",
"~": "tilde",
"@": "at",
"!": "not",
"&": "and",
"|": "or",
"^": "xor",
"<<": "lsl",
">>": "lsr",
">>>": "asr",
"&&": "andand",
"||": "oror",
"<": "lt",
"<=": "le",
"==": "eqeq",
">=": "ge",
">": "gt",
"=": "eq",
"+=": "plusequal",
"-=": "minusequal",
"/=": "divequal",
"*=": "starequal",
"%=": "percentequal",
"&=": "andequal",
"|=": "orequal",
"^=": "xorequal",
">>=": "lsrequal",
">>>=": "asrequal",
"<<=": "lslequal",
"::": "coloncolon",
"->": "rightarrow",
"<-": "leftarrow",
"<->": "swaparrow",
"//": "linecomment",
"/*": "openblockcomment",
"*/": "closeblockcomment",
"macro_rules": "macro_rules",
"=>": "eg",
"..": "dotdot",
",": "comma"
}
lines = []
for line in collections["gram"]:
line2 = ""
for word in line.split():
# replace strings with keyword-names or symbol-names from table
if word.startswith("\""):
word = word[1:-1]
if word in symnames:
word = symnames[word]
else:
for ch in word:
if not ch.isalpha():
raise Exception("non-alpha apparent keyword: "
+ word)
if word not in tokens:
if (word in collections["keyword"] or
word in collections["reserved"]):
tokens.append(word)
else:
raise Exception("unknown keyword/reserved word: "
+ word)
line2 += " " + word
lines.append(line2)
for word in collections["keyword"] + collections["reserved"]:
if word not in tokens:
tokens.append(word)
for sym in collections["unop"] + collections["binop"] + symnames.keys():
word = symnames[sym]
if word not in tokens:
tokens.append(word)
print("%start parser, token;")
print("%%token %s ;" % ("\n\t, ".join(tokens)))
for coll in ["keyword", "reserved"]:
print("%s: %s ; " % (coll, "\n\t| ".join(collections[coll])))
for coll in ["binop", "unop"]:
print("%s: %s ; " % (coll, "\n\t| ".join([symnames[x]
for x in collections[coll]])))
print("\n".join(lines))

View File

@ -46,13 +46,8 @@ def run(args):
f.write("\n")
version = run([llconfig, '--version']).strip()
# LLVM libs
if version < '3.5':
args = [llconfig, '--libs']
else:
args = [llconfig, '--libs', '--system-libs']
args = [llconfig, '--libs', '--system-libs']
args.extend(components)
out = run(args)
@ -73,11 +68,6 @@ for lib in out.strip().replace("\n", ' ').split(' '):
f.write(", kind = \"static\"")
f.write(")]\n")
# llvm-config before 3.5 didn't have a system-libs flag
if version < '3.5':
if os == 'win32':
f.write("#[link(name = \"imagehlp\")]")
# LLVM ldflags
out = run([llconfig, '--ldflags'])
for lib in out.strip().split(' '):

Binary file not shown.

View File

@ -25,7 +25,7 @@
import fileinput, re, os, sys, operator
preamble = '''// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
preamble = '''// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -207,8 +207,8 @@ def format_table_content(f, content, indent):
def load_properties(f, interestingprops):
fetch(f)
props = {}
re1 = re.compile("^([0-9A-F]+) +; (\w+)")
re2 = re.compile("^([0-9A-F]+)\.\.([0-9A-F]+) +; (\w+)")
re1 = re.compile("^ *([0-9A-F]+) *; *(\w+)")
re2 = re.compile("^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)")
for line in fileinput.input(os.path.basename(f)):
prop = None
@ -234,6 +234,11 @@ def load_properties(f, interestingprops):
if prop not in props:
props[prop] = []
props[prop].append((d_lo, d_hi))
# optimize if possible
for prop in props:
props[prop] = group_cat(ungroup_cat(props[prop]))
return props
# load all widths of want_widths, except those in except_cats
@ -518,11 +523,14 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
emit_table(f, "combining_class_table", combine, "&'static [(char, char, u8)]", is_pub=False,
pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]))
f.write(" pub fn canonical_combining_class(c: char) -> u8 {\n"
+ " bsearch_range_value_table(c, combining_class_table)\n"
+ " }\n")
f.write(""" #[deprecated(reason = "use the crates.io `unicode-normalization` lib instead",
since = "1.0.0")]
#[unstable(feature = "unicode",
reason = "this functionality will be moved to crates.io")]
pub fn canonical_combining_class(c: char) -> u8 {
bsearch_range_value_table(c, combining_class_table)
}
f.write("""
}
""")

View File

@ -1 +1 @@
0.12.0-8398-ga59de37e99060162a2674e3ff45409ac73595c0e
0.12.0-9659-g35ceea3997c79a3b7562e89b462ab76af5b86b22

View File

@ -355,7 +355,6 @@ impl<T: Clone> Arc<T> {
}
}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Arc<T> {
/// Drops the `Arc<T>`.
@ -489,7 +488,6 @@ impl<T> Clone for Weak<T> {
}
}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Weak<T> {
/// Drops the `Weak<T>`.
@ -675,7 +673,7 @@ impl<T> fmt::Pointer for Arc<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default + Sync + Send> Default for Arc<T> {
impl<T: Default> Default for Arc<T> {
#[stable(feature = "rust1", since = "1.0.0")]
fn default() -> Arc<T> { Arc::new(Default::default()) }
}

View File

@ -37,7 +37,7 @@
//! }
//! ```
//!
//! This will print `Cons(1, Box(Cons(2, Box(Nil))))`.
//! This will print `Cons(1, Cons(2, Nil))`.
//!
//! Recursive structures must be boxed, because if the definition of `Cons` looked like this:
//!
@ -62,6 +62,11 @@ use core::ops::{Deref, DerefMut};
use core::ptr::{Unique};
use core::raw::{TraitObject};
#[cfg(not(stage0))]
use core::marker::Unsize;
#[cfg(not(stage0))]
use core::ops::CoerceUnsized;
/// A value that represents the heap. This is the default place that the `box`
/// keyword allocates into when no place is supplied.
///
@ -390,3 +395,6 @@ impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
self.call_box(args)
}
}
#[cfg(not(stage0))]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}

View File

@ -8,6 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::{isize, usize};
#[inline(always)]
fn check_size_and_alignment(size: usize, align: usize) {
debug_assert!(size != 0);
debug_assert!(size <= isize::MAX as usize, "Tried to allocate too much: {} bytes", size);
debug_assert!(usize::is_power_of_two(align), "Invalid alignment of allocation: {}", align);
}
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
/// Return a pointer to `size` bytes of memory aligned to `align`.
@ -19,6 +28,7 @@
/// size on the platform.
#[inline]
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
check_size_and_alignment(size, align);
imp::allocate(size, align)
}
@ -38,6 +48,7 @@ pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
/// any value in range_inclusive(requested_size, usable_size).
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
check_size_and_alignment(size, align);
imp::reallocate(ptr, old_size, size, align)
}
@ -56,6 +67,7 @@ pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usiz
#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
align: usize) -> usize {
check_size_and_alignment(size, align);
imp::reallocate_inplace(ptr, old_size, size, align)
}
@ -95,7 +107,7 @@ pub const EMPTY: *mut () = 0x1 as *mut ();
/// The allocator for unique pointers.
#[cfg(not(test))]
#[lang="exchange_malloc"]
#[lang = "exchange_malloc"]
#[inline]
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
if size == 0 {
@ -108,7 +120,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
}
#[cfg(not(test))]
#[lang="exchange_free"]
#[lang = "exchange_free"]
#[inline]
unsafe fn exchange_free(ptr: *mut u8, old_size: usize, align: usize) {
deallocate(ptr, old_size, align);
@ -133,6 +145,7 @@ const MIN_ALIGN: usize = 16;
#[cfg(feature = "external_funcs")]
mod imp {
#[allow(improper_ctypes)]
extern {
fn rust_allocate(size: usize, align: usize) -> *mut u8;
fn rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
@ -210,7 +223,9 @@ mod imp {
}
// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough
#[cfg(all(not(windows), not(target_os = "android")))]
#[cfg(all(not(windows),
not(target_os = "android"),
not(target_env = "musl")))]
#[link(name = "pthread")]
extern {}
@ -383,7 +398,7 @@ mod imp {
}
#[cfg(test)]
mod test {
mod tests {
extern crate test;
use self::test::Bencher;
use boxed::Box;

View File

@ -73,7 +73,7 @@
#![feature(allocator)]
#![feature(custom_attribute)]
#![feature(fundamental)]
#![feature(lang_items, unsafe_destructor)]
#![feature(lang_items)]
#![feature(box_syntax)]
#![feature(optin_builtin_traits)]
#![feature(unboxed_closures)]

View File

@ -159,7 +159,7 @@ use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
use core::default::Default;
use core::fmt;
use core::hash::{Hasher, Hash};
use core::marker;
use core::marker::{self, Sized};
use core::mem::{self, min_align_of, size_of, forget};
use core::nonzero::NonZero;
use core::ops::{Deref, Drop};
@ -170,17 +170,36 @@ use core::result::Result;
use core::result::Result::{Ok, Err};
use core::intrinsics::assume;
#[cfg(not(stage0))]
use core::intrinsics::drop_in_place;
#[cfg(not(stage0))]
use core::marker::Unsize;
#[cfg(not(stage0))]
use core::mem::{min_align_of_val, size_of_val};
#[cfg(not(stage0))]
use core::ops::CoerceUnsized;
use heap::deallocate;
#[cfg(stage0)]
struct RcBox<T> {
value: T,
strong: Cell<usize>,
weak: Cell<usize>
weak: Cell<usize>,
value: T,
}
#[cfg(not(stage0))]
struct RcBox<T: ?Sized> {
strong: Cell<usize>,
weak: Cell<usize>,
value: T,
}
/// A reference-counted pointer type over an immutable value.
///
/// See the [module level documentation](./index.html) for more details.
#[cfg(stage0)]
#[unsafe_no_drop_flag]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T> {
@ -188,11 +207,30 @@ pub struct Rc<T> {
// accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
}
#[cfg(not(stage0))]
#[unsafe_no_drop_flag]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T: ?Sized> {
// FIXME #12808: strange names to try to avoid interfering with field
// accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
}
#[cfg(stage0)]
impl<T> !marker::Send for Rc<T> {}
#[cfg(not(stage0))]
impl<T: ?Sized> !marker::Send for Rc<T> {}
#[cfg(stage0)]
impl<T> !marker::Sync for Rc<T> {}
#[cfg(not(stage0))]
impl<T: ?Sized> !marker::Sync for Rc<T> {}
#[cfg(not(stage0))]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
impl<T> Rc<T> {
/// Constructs a new `Rc<T>`.
///
@ -212,14 +250,39 @@ impl<T> Rc<T> {
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
_ptr: NonZero::new(boxed::into_raw(box RcBox {
value: value,
strong: Cell::new(1),
weak: Cell::new(1)
weak: Cell::new(1),
value: value
})),
}
}
}
}
#[cfg(not(stage0))]
impl<T: ?Sized> Rc<T> {
/// Downgrades the `Rc<T>` to a `Weak<T>` reference.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// let weak_five = five.downgrade();
/// ```
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module")]
pub fn downgrade(&self) -> Weak<T> {
self.inc_weak();
Weak { _ptr: self._ptr }
}
}
#[cfg(stage0)]
impl<T> Rc<T> {
/// Downgrades the `Rc<T>` to a `Weak<T>` reference.
///
/// # Examples
@ -241,14 +304,24 @@ impl<T> Rc<T> {
}
/// Get the number of weak references to this value.
#[cfg(stage0)]
#[inline]
#[unstable(feature = "alloc")]
pub fn weak_count<T>(this: &Rc<T>) -> usize { this.weak() - 1 }
#[cfg(not(stage0))]
#[inline]
#[unstable(feature = "alloc")]
pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { this.weak() - 1 }
/// Get the number of strong references to this value.
#[cfg(stage0)]
#[inline]
#[unstable(feature = "alloc")]
pub fn strong_count<T>(this: &Rc<T>) -> usize { this.strong() }
#[cfg(not(stage0))]
#[inline]
#[unstable(feature = "alloc")]
pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() }
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the
/// same inner value.
@ -365,6 +438,7 @@ impl<T: Clone> Rc<T> {
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Deref for Rc<T> {
type Target = T;
@ -374,8 +448,18 @@ impl<T> Deref for Rc<T> {
&self.inner().value
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for Rc<T> {
type Target = T;
#[unsafe_destructor]
#[inline(always)]
fn deref(&self) -> &T {
&self.inner().value
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Rc<T> {
/// Drops the `Rc<T>`.
@ -426,6 +510,61 @@ impl<T> Drop for Rc<T> {
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for Rc<T> {
/// Drops the `Rc<T>`.
///
/// This will decrement the strong reference count. If the strong reference
/// count becomes zero and the only other references are `Weak<T>` ones,
/// `drop`s the inner value.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// {
/// let five = Rc::new(5);
///
/// // stuff
///
/// drop(five); // explicit drop
/// }
/// {
/// let five = Rc::new(5);
///
/// // stuff
///
/// } // implicit drop
/// ```
fn drop(&mut self) {
unsafe {
let ptr = *self._ptr;
if !(*(&ptr as *const _ as *const *const ())).is_null() &&
ptr as usize != mem::POST_DROP_USIZE {
self.dec_strong();
if self.strong() == 0 {
// destroy the contained object
drop_in_place(&mut (*ptr).value);
// remove the implicit "strong weak" pointer now that we've
// destroyed the contents.
self.dec_weak();
if self.weak() == 0 {
deallocate(ptr as *mut u8,
size_of_val(&*ptr),
min_align_of_val(&*ptr))
}
}
}
}
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Rc<T> {
@ -450,6 +589,31 @@ impl<T> Clone for Rc<T> {
Rc { _ptr: self._ptr }
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for Rc<T> {
/// Makes a clone of the `Rc<T>`.
///
/// When you clone an `Rc<T>`, it will create another pointer to the data and
/// increase the strong reference counter.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// five.clone();
/// ```
#[inline]
fn clone(&self) -> Rc<T> {
self.inc_strong();
Rc { _ptr: self._ptr }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Rc<T> {
@ -611,27 +775,50 @@ impl<T: Ord> Ord for Rc<T> {
fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
}
// FIXME (#18248) Make `T` `Sized?`
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Hash> Hash for Rc<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized+Hash> Hash for Rc<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Display> fmt::Display for Rc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized+fmt::Display> fmt::Display for Rc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Debug> fmt::Debug for Rc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized+fmt::Debug> fmt::Debug for Rc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Pointer for Rc<T> {
@ -646,6 +833,7 @@ impl<T> fmt::Pointer for Rc<T> {
/// dropped.
///
/// See the [module level documentation](./index.html) for more.
#[cfg(stage0)]
#[unsafe_no_drop_flag]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
@ -654,12 +842,28 @@ pub struct Weak<T> {
// field accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
}
#[cfg(not(stage0))]
#[unsafe_no_drop_flag]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
pub struct Weak<T: ?Sized> {
// FIXME #12808: strange names to try to avoid interfering with
// field accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
}
#[cfg(stage0)]
impl<T> !marker::Send for Weak<T> {}
#[cfg(not(stage0))]
impl<T: ?Sized> !marker::Send for Weak<T> {}
#[cfg(stage0)]
impl<T> !marker::Sync for Weak<T> {}
#[cfg(not(stage0))]
impl<T: ?Sized> !marker::Sync for Weak<T> {}
#[cfg(stage0)]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
impl<T> Weak<T> {
@ -692,8 +896,41 @@ impl<T> Weak<T> {
}
}
}
#[cfg(not(stage0))]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
impl<T: ?Sized> Weak<T> {
#[unsafe_destructor]
/// Upgrades a weak reference to a strong reference.
///
/// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
///
/// Returns `None` if there were no strong references and the data was
/// destroyed.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// let weak_five = five.downgrade();
///
/// let strong_five: Option<Rc<_>> = weak_five.upgrade();
/// ```
pub fn upgrade(&self) -> Option<Rc<T>> {
if self.strong() == 0 {
None
} else {
self.inc_strong();
Some(Rc { _ptr: self._ptr })
}
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Weak<T> {
/// Drops the `Weak<T>`.
@ -738,6 +975,53 @@ impl<T> Drop for Weak<T> {
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for Weak<T> {
/// Drops the `Weak<T>`.
///
/// This will decrement the weak reference count.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// {
/// let five = Rc::new(5);
/// let weak_five = five.downgrade();
///
/// // stuff
///
/// drop(weak_five); // explicit drop
/// }
/// {
/// let five = Rc::new(5);
/// let weak_five = five.downgrade();
///
/// // stuff
///
/// } // implicit drop
/// ```
fn drop(&mut self) {
unsafe {
let ptr = *self._ptr;
if !(*(&ptr as *const _ as *const *const ())).is_null() &&
ptr as usize != mem::POST_DROP_USIZE {
self.dec_weak();
// the weak count starts at 1, and will only go to zero if all
// the strong pointers have disappeared.
if self.weak() == 0 {
deallocate(ptr as *mut u8, size_of_val(&*ptr),
min_align_of_val(&*ptr))
}
}
}
}
}
#[cfg(stage0)]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
impl<T> Clone for Weak<T> {
@ -762,14 +1046,48 @@ impl<T> Clone for Weak<T> {
Weak { _ptr: self._ptr }
}
}
#[cfg(not(stage0))]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
impl<T: ?Sized> Clone for Weak<T> {
/// Makes a clone of the `Weak<T>`.
///
/// This increases the weak reference count.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let weak_five = Rc::new(5).downgrade();
///
/// weak_five.clone();
/// ```
#[inline]
fn clone(&self) -> Weak<T> {
self.inc_weak();
Weak { _ptr: self._ptr }
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Debug> fmt::Debug for Weak<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(Weak)")
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized+fmt::Debug> fmt::Debug for Weak<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(Weak)")
}
}
#[cfg(stage0)]
#[doc(hidden)]
trait RcBoxPtr<T> {
fn inner(&self) -> &RcBox<T>;
@ -792,7 +1110,31 @@ trait RcBoxPtr<T> {
#[inline]
fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
}
#[cfg(not(stage0))]
#[doc(hidden)]
trait RcBoxPtr<T: ?Sized> {
fn inner(&self) -> &RcBox<T>;
#[inline]
fn strong(&self) -> usize { self.inner().strong.get() }
#[inline]
fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
#[inline]
fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
#[inline]
fn weak(&self) -> usize { self.inner().weak.get() }
#[inline]
fn inc_weak(&self) { self.inner().weak.set(self.weak() + 1); }
#[inline]
fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
}
#[cfg(stage0)]
impl<T> RcBoxPtr<T> for Rc<T> {
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
@ -801,12 +1143,27 @@ impl<T> RcBoxPtr<T> for Rc<T> {
// the contract anyway.
// This allows the null check to be elided in the destructor if we
// manipulated the reference count in the same function.
assume(!self._ptr.is_null());
assume(!(*(&self._ptr as *const _ as *const *const ())).is_null());
&(**self._ptr)
}
}
}
#[cfg(not(stage0))]
impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
unsafe {
// Safe to assume this here, as if it weren't true, we'd be breaking
// the contract anyway.
// This allows the null check to be elided in the destructor if we
// manipulated the reference count in the same function.
assume(!(*(&self._ptr as *const _ as *const *const ())).is_null());
&(**self._ptr)
}
}
}
#[cfg(stage0)]
impl<T> RcBoxPtr<T> for Weak<T> {
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
@ -815,7 +1172,21 @@ impl<T> RcBoxPtr<T> for Weak<T> {
// the contract anyway.
// This allows the null check to be elided in the destructor if we
// manipulated the reference count in the same function.
assume(!self._ptr.is_null());
assume(!(*(&self._ptr as *const _ as *const *const ())).is_null());
&(**self._ptr)
}
}
}
#[cfg(not(stage0))]
impl<T: ?Sized> RcBoxPtr<T> for Weak<T> {
#[inline(always)]
fn inner(&self) -> &RcBox<T> {
unsafe {
// Safe to assume this here, as if it weren't true, we'd be breaking
// the contract anyway.
// This allows the null check to be elided in the destructor if we
// manipulated the reference count in the same function.
assume(!(*(&self._ptr as *const _ as *const *const ())).is_null());
&(**self._ptr)
}
}

View File

@ -35,7 +35,6 @@
#![feature(core)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unsafe_destructor)]
#![cfg_attr(test, feature(test))]
extern crate alloc;
@ -124,7 +123,6 @@ fn chunk(size: usize, is_copy: bool) -> Chunk {
}
}
#[unsafe_destructor]
impl<'longer_than_self> Drop for Arena<'longer_than_self> {
fn drop(&mut self) {
unsafe {
@ -510,7 +508,6 @@ impl<T> TypedArena<T> {
}
}
#[unsafe_destructor]
impl<T> Drop for TypedArena<T> {
fn drop(&mut self) {
unsafe {

View File

@ -153,7 +153,7 @@
use core::prelude::*;
use core::iter::{FromIterator};
use core::mem::{zeroed, replace, swap};
use core::mem::swap;
use core::ptr;
use slice;
@ -484,46 +484,42 @@ impl<T: Ord> BinaryHeap<T> {
// The implementations of sift_up and sift_down 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
// vector over the junk element. This reduces the constant factor
// compared to using swaps, which involves twice as many moves.
fn sift_up(&mut self, start: usize, mut pos: usize) {
// hole), shift along the others and move the removed element back into the
// vector at the final location of the hole.
// The `Hole` type is used to represent this, and make sure
// the hole is filled back at the end of its scope, even on panic.
// Using a hole reduces the constant factor compared to using swaps,
// which involves twice as many moves.
fn sift_up(&mut self, start: usize, pos: usize) {
unsafe {
let new = replace(&mut self.data[pos], zeroed());
// Take out the value at `pos` and create a hole.
let mut hole = Hole::new(&mut self.data, pos);
while pos > start {
let parent = (pos - 1) >> 1;
if new <= self.data[parent] { break; }
let x = replace(&mut self.data[parent], zeroed());
ptr::write(&mut self.data[pos], x);
pos = parent;
while hole.pos() > start {
let parent = (hole.pos() - 1) / 2;
if hole.removed() <= hole.get(parent) { break }
hole.move_to(parent);
}
ptr::write(&mut self.data[pos], new);
}
}
fn sift_down_range(&mut self, mut pos: usize, end: usize) {
let start = pos;
unsafe {
let start = pos;
let new = replace(&mut self.data[pos], zeroed());
let mut hole = Hole::new(&mut self.data, pos);
let mut child = 2 * pos + 1;
while child < end {
let right = child + 1;
if right < end && !(self.data[child] > self.data[right]) {
if right < end && !(hole.get(child) > hole.get(right)) {
child = right;
}
let x = replace(&mut self.data[child], zeroed());
ptr::write(&mut self.data[pos], x);
pos = child;
child = 2 * pos + 1;
hole.move_to(child);
child = 2 * hole.pos() + 1;
}
ptr::write(&mut self.data[pos], new);
self.sift_up(start, pos);
pos = hole.pos;
}
self.sift_up(start, pos);
}
fn sift_down(&mut self, pos: usize) {
@ -546,7 +542,7 @@ impl<T: Ord> BinaryHeap<T> {
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
pub fn drain(&mut self) -> Drain<T> {
Drain { iter: self.data.drain() }
Drain { iter: self.data.drain(..) }
}
/// Drops all items from the binary heap.
@ -554,6 +550,73 @@ impl<T: Ord> BinaryHeap<T> {
pub fn clear(&mut self) { self.drain(); }
}
/// Hole represents a hole in a slice i.e. an index without valid value
/// (because it was moved from or duplicated).
/// In drop, `Hole` will restore the slice by filling the hole
/// position with the value that was originally removed.
struct Hole<'a, T: 'a> {
data: &'a mut [T],
/// `elt` is always `Some` from new until drop.
elt: Option<T>,
pos: usize,
}
impl<'a, T> Hole<'a, T> {
/// Create a new Hole at index `pos`.
fn new(data: &'a mut [T], pos: usize) -> Self {
unsafe {
let elt = ptr::read(&data[pos]);
Hole {
data: data,
elt: Some(elt),
pos: pos,
}
}
}
#[inline(always)]
fn pos(&self) -> usize { self.pos }
/// Return a reference to the element removed
#[inline(always)]
fn removed(&self) -> &T {
self.elt.as_ref().unwrap()
}
/// Return a reference to the element at `index`.
///
/// Panics if the index is out of bounds.
///
/// Unsafe because index must not equal pos.
#[inline(always)]
unsafe fn get(&self, index: usize) -> &T {
debug_assert!(index != self.pos);
&self.data[index]
}
/// Move hole to new location
///
/// Unsafe because index must not equal pos.
#[inline(always)]
unsafe fn move_to(&mut self, index: usize) {
debug_assert!(index != self.pos);
let index_ptr: *const _ = &self.data[index];
let hole_ptr = &mut self.data[self.pos];
ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1);
self.pos = index;
}
}
impl<'a, T> Drop for Hole<'a, T> {
fn drop(&mut self) {
// fill the hole again
unsafe {
let pos = self.pos;
ptr::write(&mut self.data[pos], self.elt.take().unwrap());
}
}
}
/// `BinaryHeap` iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter <'a, T: 'a> {

View File

@ -89,6 +89,7 @@ use core::hash;
use core::iter::RandomAccessIterator;
use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
use core::iter::{self, FromIterator};
use core::mem::swap;
use core::ops::Index;
use core::slice;
use core::{u8, u32, usize};
@ -210,15 +211,13 @@ impl BitVec {
assert_eq!(self.len(), other.len());
// This could theoretically be a `debug_assert!`.
assert_eq!(self.storage.len(), other.storage.len());
let mut changed = false;
let mut changed_bits = 0;
for (a, b) in self.blocks_mut().zip(other.blocks()) {
let w = op(*a, b);
if *a != w {
changed = true;
*a = w;
}
changed_bits |= *a ^ w;
*a = w;
}
changed
changed_bits != 0
}
/// Iterator over mutable refs to the underlying blocks of data.
@ -604,6 +603,110 @@ impl BitVec {
Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits }
}
/// Moves all bits from `other` into `Self`, leaving `other` empty.
///
/// # Examples
///
/// ```
/// # #![feature(collections, bit_vec_append_split_off)]
/// use std::collections::BitVec;
///
/// let mut a = BitVec::from_bytes(&[0b10000000]);
/// let mut b = BitVec::from_bytes(&[0b01100001]);
///
/// a.append(&mut b);
///
/// assert_eq!(a.len(), 16);
/// assert_eq!(b.len(), 0);
/// assert!(a.eq_vec(&[true, false, false, false, false, false, false, false,
/// false, true, true, false, false, false, false, true]));
/// ```
#[unstable(feature = "bit_vec_append_split_off",
reason = "recently added as part of collections reform 2")]
pub fn append(&mut self, other: &mut Self) {
let b = self.len() % u32::BITS;
self.nbits += other.len();
other.nbits = 0;
if b == 0 {
self.storage.append(&mut other.storage);
} else {
self.storage.reserve(other.storage.len());
for block in other.storage.drain(..) {
*(self.storage.last_mut().unwrap()) |= block << b;
self.storage.push(block >> (u32::BITS - b));
}
}
}
/// Splits the `BitVec` into two at the given bit,
/// retaining the first half in-place and returning the second one.
///
/// # Panics
///
/// Panics if `at` is out of bounds.
///
/// # Examples
///
/// ```
/// # #![feature(collections, bit_vec_append_split_off)]
/// use std::collections::BitVec;
/// let mut a = BitVec::new();
/// a.push(true);
/// a.push(false);
/// a.push(false);
/// a.push(true);
///
/// let b = a.split_off(2);
///
/// assert_eq!(a.len(), 2);
/// assert_eq!(b.len(), 2);
/// assert!(a.eq_vec(&[true, false]));
/// assert!(b.eq_vec(&[false, true]));
/// ```
#[unstable(feature = "bit_vec_append_split_off",
reason = "recently added as part of collections reform 2")]
pub fn split_off(&mut self, at: usize) -> Self {
assert!(at <= self.len(), "`at` out of bounds");
let mut other = BitVec::new();
if at == 0 {
swap(self, &mut other);
return other;
} else if at == self.len() {
return other;
}
let w = at / u32::BITS;
let b = at % u32::BITS;
other.nbits = self.nbits - at;
self.nbits = at;
if b == 0 {
// Split at block boundary
other.storage = self.storage.split_off(w);
} else {
other.storage.reserve(self.storage.len() - w);
{
let mut iter = self.storage[w..].iter();
let mut last = *iter.next().unwrap();
for &cur in iter {
other.storage.push((last >> b) | (cur << (u32::BITS - b)));
last = cur;
}
other.storage.push(last >> b);
}
self.storage.truncate(w+1);
self.fix_last_block();
}
other
}
/// Returns `true` if all bits are 0.
///
/// # Examples
@ -1693,6 +1796,89 @@ impl BitSet {
self.other_op(other, |w1, w2| w1 ^ w2);
}
/// Moves all elements from `other` into `Self`, leaving `other` empty.
///
/// # Examples
///
/// ```
/// # #![feature(collections, bit_set_append_split_off)]
/// use std::collections::{BitVec, BitSet};
///
/// let mut a = BitSet::new();
/// a.insert(2);
/// a.insert(6);
///
/// let mut b = BitSet::new();
/// b.insert(1);
/// b.insert(3);
/// b.insert(6);
///
/// a.append(&mut b);
///
/// assert_eq!(a.len(), 4);
/// assert_eq!(b.len(), 0);
/// assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b01110010])));
/// ```
#[unstable(feature = "bit_set_append_split_off",
reason = "recently added as part of collections reform 2")]
pub fn append(&mut self, other: &mut Self) {
self.union_with(other);
other.clear();
}
/// Splits the `BitSet` into two at the given key including the key.
/// Retains the first part in-place while returning the second part.
///
/// # Examples
///
/// ```
/// # #![feature(collections, bit_set_append_split_off)]
/// use std::collections::{BitSet, BitVec};
/// let mut a = BitSet::new();
/// a.insert(2);
/// a.insert(6);
/// a.insert(1);
/// a.insert(3);
///
/// let b = a.split_off(3);
///
/// assert_eq!(a.len(), 2);
/// assert_eq!(b.len(), 2);
/// assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100000])));
/// assert_eq!(b, BitSet::from_bit_vec(BitVec::from_bytes(&[0b00010010])));
/// ```
#[unstable(feature = "bit_set_append_split_off",
reason = "recently added as part of collections reform 2")]
pub fn split_off(&mut self, at: usize) -> Self {
let mut other = BitSet::new();
if at == 0 {
swap(self, &mut other);
return other;
} else if at >= self.bit_vec.len() {
return other;
}
// Calculate block and bit at which to split
let w = at / u32::BITS;
let b = at % u32::BITS;
// Pad `other` with `w` zero blocks,
// append `self`'s blocks in the range from `w` to the end to `other`
other.bit_vec.storage.extend(repeat(0u32).take(w)
.chain(self.bit_vec.storage[w..].iter().cloned()));
other.bit_vec.nbits = self.bit_vec.nbits;
if b > 0 {
other.bit_vec.storage[w] &= !0 << b;
}
// Sets `bit_vec.len()` and fixes the last block as well
self.bit_vec.truncate(at);
other
}
/// Returns the number of set bits in this set.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -21,7 +21,7 @@ use core::ops::Deref;
use core::option::Option;
use fmt;
use alloc::{rc, arc};
use alloc::{boxed, rc, arc};
use self::Cow::*;
@ -37,6 +37,11 @@ use self::Cow::*;
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
///
/// `Borrow` is very similar to, but different than, `AsRef`. See
/// [the book][book] for more.
///
/// [book]: ../../book/borrow-and-asref.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
/// Immutably borrows from an owned value.
@ -111,6 +116,14 @@ impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
fn borrow_mut(&mut self) -> &mut T { &mut **self }
}
impl<T: ?Sized> Borrow<T> for boxed::Box<T> {
fn borrow(&self) -> &T { &**self }
}
impl<T: ?Sized> BorrowMut<T> for boxed::Box<T> {
fn borrow_mut(&mut self) -> &mut T { &mut **self }
}
impl<T> Borrow<T> for rc::Rc<T> {
fn borrow(&self) -> &T { &**self }
}

View File

@ -270,14 +270,12 @@ impl<T> DoubleEndedIterator for RawItems<T> {
}
}
#[unsafe_destructor]
impl<T> Drop for RawItems<T> {
fn drop(&mut self) {
for _ in self.by_ref() {}
}
}
#[unsafe_destructor]
impl<K, V> Drop for Node<K, V> {
fn drop(&mut self) {
if self.keys.is_null() ||
@ -1394,7 +1392,6 @@ impl<K, V> TraversalImpl for MoveTraversalImpl<K, V> {
}
}
#[unsafe_destructor]
impl<K, V> Drop for MoveTraversalImpl<K, V> {
fn drop(&mut self) {
// We need to cleanup the stored values manually, as the RawItems destructor would run

View File

@ -7,8 +7,6 @@
// <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.
//
// ignore-lexer-test FIXME #15679
//! Utilities for formatting and printing strings
//!
@ -262,7 +260,6 @@
//! Example usage is:
//!
//! ```
//! # #![feature(old_io)]
//! # #![allow(unused_must_use)]
//! use std::io::Write;
//! let mut w = Vec::new();
@ -290,7 +287,6 @@
//! off, some example usage is:
//!
//! ```
//! # #![feature(old_io)]
//! use std::fmt;
//! use std::io::{self, Write};
//!
@ -402,7 +398,7 @@
//! longer than this width, then it is truncated down to this many characters and only those are
//! emitted.
//!
//! For integral types, this has no meaning currently.
//! For integral types, this is ignored.
//!
//! For floating-point types, this indicates how many digits after the decimal point should be
//! printed.
@ -500,6 +496,6 @@ use string;
#[stable(feature = "rust1", since = "1.0.0")]
pub fn format(args: Arguments) -> string::String {
let mut output = string::String::new();
let _ = write!(&mut output, "{}", args);
let _ = output.write_fmt(args);
output
}

View File

@ -33,7 +33,6 @@
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(step_by)]
@ -42,7 +41,8 @@
#![feature(slice_patterns)]
#![feature(debug_builders)]
#![feature(utf8_error)]
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections,
collections_drain, collections_range))]
#![cfg_attr(test, allow(deprecated))] // rand
#![feature(no_std)]
@ -51,7 +51,7 @@
#[macro_use]
extern crate core;
extern crate unicode;
extern crate rustc_unicode;
extern crate alloc;
#[cfg(test)] #[macro_use] extern crate std;
@ -82,6 +82,7 @@ pub mod borrow;
pub mod enum_set;
pub mod fmt;
pub mod linked_list;
pub mod range;
pub mod slice;
pub mod str;
pub mod string;

View File

@ -616,7 +616,13 @@ impl<T> LinkedList<T> {
length: len - at
};
// Swap split_node.next with list_head (which is None), nulling out split_node.next,
// as it is the new tail.
mem::swap(&mut split_node.resolve().unwrap().next, &mut splitted_list.list_head);
// Null out list_head.prev. Note this `unwrap` won't fail because if at == len
// we already branched out at the top of the fn to return the empty list.
splitted_list.list_head.as_mut().unwrap().prev = Rawlink::none();
// Fix the tail ptr
self.list_tail = split_node;
self.length = at;
@ -624,7 +630,6 @@ impl<T> LinkedList<T> {
}
}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for LinkedList<T> {
fn drop(&mut self) {
@ -933,7 +938,7 @@ impl<A: Hash> Hash for LinkedList<A> {
}
#[cfg(test)]
mod test {
mod tests {
use std::clone::Clone;
use std::iter::{Iterator, IntoIterator};
use std::option::Option::{Some, None, self};
@ -1083,6 +1088,26 @@ mod test {
}
}
#[test]
fn test_26021() {
use std::iter::ExactSizeIterator;
// There was a bug in split_off that failed to null out the RHS's head's prev ptr.
// This caused the RHS's dtor to walk up into the LHS at drop and delete all of
// its nodes.
//
// https://github.com/rust-lang/rust/issues/26021
let mut v1 = LinkedList::new();
v1.push_front(1u8);
v1.push_front(1u8);
v1.push_front(1u8);
v1.push_front(1u8);
let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
assert_eq!(v1.len(), 3);
assert_eq!(v1.iter().len(), 3);
assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
}
#[cfg(test)]
fn fuzz_test(sz: i32) {
let mut m: LinkedList<_> = LinkedList::new();

View File

@ -0,0 +1,45 @@
// Copyright 2015 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.
#![unstable(feature = "collections_range", reason = "was just added")]
//! Range syntax.
use core::option::Option::{self, None, Some};
use core::ops::{RangeFull, Range, RangeTo, RangeFrom};
/// **RangeArgument** is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
pub trait RangeArgument<T> {
/// Start index (inclusive)
///
/// Return start value if present, else `None`.
fn start(&self) -> Option<&T> { None }
/// End index (exclusive)
///
/// Return end value if present, else `None`.
fn end(&self) -> Option<&T> { None }
}
impl<T> RangeArgument<T> for RangeFull {}
impl<T> RangeArgument<T> for RangeFrom<T> {
fn start(&self) -> Option<&T> { Some(&self.start) }
}
impl<T> RangeArgument<T> for RangeTo<T> {
fn end(&self) -> Option<&T> { Some(&self.end) }
}
impl<T> RangeArgument<T> for Range<T> {
fn start(&self) -> Option<&T> { Some(&self.start) }
fn end(&self) -> Option<&T> { Some(&self.end) }
}

View File

@ -995,39 +995,38 @@ impl<T> [T] {
////////////////////////////////////////////////////////////////////////////////
// Extension traits for slices over specific kinds of data
////////////////////////////////////////////////////////////////////////////////
#[unstable(feature = "collections", reason = "U should be an associated type")]
#[unstable(feature = "collections", reason = "recently changed")]
/// An extension trait for concatenating slices
pub trait SliceConcatExt<T: ?Sized, U> {
/// Flattens a slice of `T` into a single value `U`.
///
/// # Examples
///
/// ```
/// let v = vec!["hello", "world"];
///
/// let s: String = v.concat();
///
/// println!("{}", s); // prints "helloworld"
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn concat(&self) -> U;
pub trait SliceConcatExt<T: ?Sized> {
#[unstable(feature = "collections", reason = "recently changed")]
/// The resulting type after concatenation
type Output;
/// Flattens a slice of `T` into a single value `U`, placing a given separator between each.
/// Flattens a slice of `T` into a single value `Self::Output`.
///
/// # Examples
///
/// ```
/// let v = vec!["hello", "world"];
///
/// let s: String = v.connect(" ");
///
/// println!("{}", s); // prints "hello world"
/// assert_eq!(["hello", "world"].concat(), "helloworld");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn connect(&self, sep: &T) -> U;
fn concat(&self) -> Self::Output;
/// Flattens a slice of `T` into a single value `Self::Output`, placing a given separator
/// between each.
///
/// # Examples
///
/// ```
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn connect(&self, sep: &T) -> Self::Output;
}
impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T, Vec<T>> for [V] {
impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T> for [V] {
type Output = Vec<T>;
fn concat(&self) -> Vec<T> {
let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
let mut result = Vec::with_capacity(size);

View File

@ -7,8 +7,6 @@
// <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.
//
// ignore-lexer-test FIXME #15679
//! Unicode string manipulation (the `str` type).
//!
@ -59,12 +57,12 @@ use core::result::Result;
use core::str as core_str;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use unicode::str::{UnicodeStr, Utf16Encoder};
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
use vec_deque::VecDeque;
use borrow::{Borrow, ToOwned};
use string::String;
use unicode;
use rustc_unicode;
use vec::Vec;
use slice::SliceConcatExt;
@ -77,14 +75,16 @@ pub use core::str::{Matches, RMatches};
pub use core::str::{MatchIndices, RMatchIndices};
pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
pub use core::str::{from_utf8_unchecked, ParseBoolError};
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
pub use rustc_unicode::str::{SplitWhitespace, Words, Graphemes, GraphemeIndices};
pub use core::str::pattern;
/*
Section: Creating a string
*/
impl<S: Borrow<str>> SliceConcatExt<str, String> for [S] {
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
type Output = String;
fn concat(&self) -> String {
if self.is_empty() {
return String::new();
@ -160,6 +160,9 @@ enum DecompositionType {
/// External iterator for a string decomposition's characters.
///
/// For use with the `std::iter` module.
#[allow(deprecated)]
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
since = "1.0.0")]
#[derive(Clone)]
#[unstable(feature = "unicode",
reason = "this functionality may be replaced with a more generic \
@ -171,6 +174,7 @@ pub struct Decompositions<'a> {
sorted: bool
}
#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Iterator for Decompositions<'a> {
type Item = char;
@ -197,7 +201,7 @@ impl<'a> Iterator for Decompositions<'a> {
{
let callback = |d| {
let class =
unicode::char::canonical_combining_class(d);
rustc_unicode::char::canonical_combining_class(d);
if class == 0 && !*sorted {
canonical_sort(buffer);
*sorted = true;
@ -206,10 +210,10 @@ impl<'a> Iterator for Decompositions<'a> {
};
match self.kind {
Canonical => {
unicode::char::decompose_canonical(ch, callback)
rustc_unicode::char::decompose_canonical(ch, callback)
}
Compatible => {
unicode::char::decompose_compatible(ch, callback)
rustc_unicode::char::decompose_compatible(ch, callback)
}
}
}
@ -253,6 +257,9 @@ enum RecompositionState {
/// External iterator for a string recomposition's characters.
///
/// For use with the `std::iter` module.
#[allow(deprecated)]
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
since = "1.0.0")]
#[derive(Clone)]
#[unstable(feature = "unicode",
reason = "this functionality may be replaced with a more generic \
@ -265,6 +272,7 @@ pub struct Recompositions<'a> {
last_ccc: Option<u8>
}
#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Iterator for Recompositions<'a> {
type Item = char;
@ -275,7 +283,7 @@ impl<'a> Iterator for Recompositions<'a> {
match self.state {
Composing => {
for ch in self.iter.by_ref() {
let ch_class = unicode::char::canonical_combining_class(ch);
let ch_class = rustc_unicode::char::canonical_combining_class(ch);
if self.composee.is_none() {
if ch_class != 0 {
return Some(ch);
@ -287,7 +295,7 @@ impl<'a> Iterator for Recompositions<'a> {
match self.last_ccc {
None => {
match unicode::char::compose(k, ch) {
match rustc_unicode::char::compose(k, ch) {
Some(r) => {
self.composee = Some(r);
continue;
@ -315,7 +323,7 @@ impl<'a> Iterator for Recompositions<'a> {
self.last_ccc = Some(ch_class);
continue;
}
match unicode::char::compose(k, ch) {
match rustc_unicode::char::compose(k, ch) {
Some(r) => {
self.composee = Some(r);
continue;
@ -388,6 +396,7 @@ macro_rules! utf8_acc_cont_byte {
#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<str> for String {
#[inline]
fn borrow(&self) -> &str { &self[..] }
}
@ -464,6 +473,9 @@ impl str {
/// Returns an iterator over the string in Unicode Normalization Form D
/// (canonical decomposition).
#[allow(deprecated)]
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
since = "1.0.0")]
#[inline]
#[unstable(feature = "unicode",
reason = "this functionality may be replaced with a more generic \
@ -479,6 +491,9 @@ impl str {
/// Returns an iterator over the string in Unicode Normalization Form KD
/// (compatibility decomposition).
#[allow(deprecated)]
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
since = "1.0.0")]
#[inline]
#[unstable(feature = "unicode",
reason = "this functionality may be replaced with a more generic \
@ -494,6 +509,9 @@ impl str {
/// An Iterator over the string in Unicode Normalization Form C
/// (canonical decomposition followed by canonical composition).
#[allow(deprecated)]
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
since = "1.0.0")]
#[inline]
#[unstable(feature = "unicode",
reason = "this functionality may be replaced with a more generic \
@ -510,6 +528,9 @@ impl str {
/// An Iterator over the string in Unicode Normalization Form KC
/// (compatibility decomposition followed by canonical composition).
#[allow(deprecated)]
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
since = "1.0.0")]
#[inline]
#[unstable(feature = "unicode",
reason = "this functionality may be replaced with a more generic \
@ -694,7 +715,7 @@ impl str {
/// is skipped if empty.
///
/// This method can be used for string data that is _terminated_,
/// rather than _seperated_ by a pattern.
/// rather than _separated_ by a pattern.
///
/// # Iterator behavior
///
@ -741,7 +762,7 @@ impl str {
/// skipped if empty.
///
/// This method can be used for string data that is _terminated_,
/// rather than _seperated_ by a pattern.
/// rather than _separated_ by a pattern.
///
/// # Iterator behavior
///
@ -1689,6 +1710,8 @@ impl str {
///
/// assert_eq!(&gr2[..], b);
/// ```
#[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
since = "1.0.0")]
#[unstable(feature = "unicode",
reason = "this functionality may only be provided by libunicode")]
pub fn graphemes(&self, is_extended: bool) -> Graphemes {
@ -1708,33 +1731,52 @@ impl str {
///
/// assert_eq!(&gr_inds[..], b);
/// ```
#[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
since = "1.0.0")]
#[unstable(feature = "unicode",
reason = "this functionality may only be provided by libunicode")]
pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
UnicodeStr::grapheme_indices(&self[..], is_extended)
}
/// An iterator over the non-empty words of `self`.
///
/// A 'word' is a subsequence separated by any sequence of whitespace.
/// Sequences of whitespace
/// are collapsed, so empty "words" are not included.
/// An iterator over the non-empty substrings of `self` which contain no whitespace,
/// and which are separated by any amount of whitespace.
///
/// # Examples
///
/// ```
/// # #![feature(str_words)]
/// # #![allow(deprecated)]
/// let some_words = " Mary had\ta little \n\t lamb";
/// let v: Vec<&str> = some_words.words().collect();
///
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
/// ```
#[deprecated(reason = "words() will be removed. Use split_whitespace() instead",
since = "1.1.0")]
#[unstable(feature = "str_words",
reason = "the precise algorithm to use is unclear")]
#[allow(deprecated)]
pub fn words(&self) -> Words {
UnicodeStr::words(&self[..])
}
/// An iterator over the non-empty substrings of `self` which contain no whitespace,
/// and which are separated by any amount of whitespace.
///
/// # Examples
///
/// ```
/// let some_words = " Mary had\ta little \n\t lamb";
/// let v: Vec<&str> = some_words.split_whitespace().collect();
///
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
/// ```
#[stable(feature = "split_whitespace", since = "1.1.0")]
pub fn split_whitespace(&self) -> SplitWhitespace {
UnicodeStr::split_whitespace(&self[..])
}
/// Returns a string's displayed width in columns.
///
/// Control characters have zero width.
@ -1748,6 +1790,8 @@ impl str {
/// recommends that these
/// characters be treated as 1 column (i.e., `is_cjk = false`) if the
/// locale is unknown.
#[deprecated(reason = "use the crates.io `unicode-width` library instead",
since = "1.0.0")]
#[unstable(feature = "unicode",
reason = "this functionality may only be provided by libunicode")]
pub fn width(&self, is_cjk: bool) -> usize {

View File

@ -7,8 +7,6 @@
// <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.
//
// ignore-lexer-test FIXME #15679
//! An owned, growable string that enforces that its contents are valid UTF-8.
@ -24,11 +22,12 @@ use core::ops::{self, Deref, Add, Index};
use core::ptr;
use core::slice;
use core::str::pattern::Pattern;
use unicode::str as unicode_str;
use unicode::str::Utf16Item;
use rustc_unicode::str as unicode_str;
use rustc_unicode::str::Utf16Item;
use borrow::{Cow, IntoCow};
use str::{self, FromStr, Utf8Error};
use range::RangeArgument;
use str::{self, FromStr, Utf8Error, Chars};
use vec::{DerefVec, Vec, as_vec};
/// A growable string stored as a UTF-8 encoded buffer.
@ -697,6 +696,59 @@ impl String {
pub fn clear(&mut self) {
self.vec.clear()
}
/// Create a draining iterator that removes the specified range in the string
/// and yields the removed chars from start to end. The element range is
/// removed even if the iterator is not consumed until the end.
///
/// # Panics
///
/// Panics if the starting point or end point are not on character boundaries,
/// or if they are out of bounds.
///
/// # Examples
///
/// ```
/// # #![feature(collections_drain)]
///
/// let mut s = String::from("α is alpha, β is beta");
/// let beta_offset = s.find('β').unwrap_or(s.len());
///
/// // Remove the range up until the β from the string
/// let t: String = s.drain(..beta_offset).collect();
/// assert_eq!(t, "α is alpha, ");
/// assert_eq!(s, "β is beta");
///
/// // A full range clears the string
/// s.drain(..);
/// assert_eq!(s, "");
/// ```
#[unstable(feature = "collections_drain",
reason = "recently added, matches RFC")]
pub fn drain<R>(&mut self, range: R) -> Drain where R: RangeArgument<usize> {
// Memory safety
//
// The String version of Drain does not have the memory safety issues
// of the vector version. The data is just plain bytes.
// Because the range removal happens in Drop, if the Drain iterator is leaked,
// the removal will not happen.
let len = self.len();
let start = *range.start().unwrap_or(&0);
let end = *range.end().unwrap_or(&len);
// Take out two simultaneous borrows. The &mut String won't be accessed
// until iteration is over, in Drop.
let self_ptr = self as *mut _;
// slicing does the appropriate bounds checks
let chars_iter = self[start..end].chars();
Drain {
start: start,
end: end,
iter: chars_iter,
string: self_ptr,
}
}
}
impl FromUtf8Error {
@ -705,7 +757,7 @@ impl FromUtf8Error {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_bytes(self) -> Vec<u8> { self.bytes }
/// Accesss the underlying UTF8-error that was the cause of this error.
/// Access the underlying UTF8-error that was the cause of this error.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn utf8_error(&self) -> Utf8Error { self.error }
}
@ -1000,6 +1052,7 @@ impl<T: fmt::Display + ?Sized> ToString for T {
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<str> for String {
#[inline]
fn as_ref(&self) -> &str {
self
}
@ -1015,9 +1068,20 @@ impl AsRef<[u8]> for String {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for String {
#[cfg(not(test))]
#[inline]
fn from(s: &'a str) -> String {
s.to_string()
String { vec: <[_]>::to_vec(s.as_bytes()) }
}
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
// required for this method definition, is not available. Since we don't
// require this method for testing purposes, I'll just stub it
// NB see the slice::hack module in slice.rs for more information
#[inline]
#[cfg(test)]
fn from(_: &str) -> String {
panic!("not available with cfg(test)");
}
}
@ -1067,4 +1131,62 @@ impl fmt::Write for String {
self.push_str(s);
Ok(())
}
#[inline]
fn write_char(&mut self, c: char) -> fmt::Result {
self.push(c);
Ok(())
}
}
/// A draining iterator for `String`.
#[unstable(feature = "collections_drain", reason = "recently added")]
pub struct Drain<'a> {
/// Will be used as &'a mut String in the destructor
string: *mut String,
/// Start of part to remove
start: usize,
/// End of part to remove
end: usize,
/// Current remaining range to remove
iter: Chars<'a>,
}
unsafe impl<'a> Sync for Drain<'a> {}
unsafe impl<'a> Send for Drain<'a> {}
#[unstable(feature = "collections_drain", reason = "recently added")]
impl<'a> Drop for Drain<'a> {
fn drop(&mut self) {
unsafe {
// Use Vec::drain. "Reaffirm" the bounds checks to avoid
// panic code being inserted again.
let self_vec = (*self.string).as_mut_vec();
if self.start <= self.end && self.end <= self_vec.len() {
self_vec.drain(self.start..self.end);
}
}
}
}
#[unstable(feature = "collections_drain", reason = "recently added")]
impl<'a> Iterator for Drain<'a> {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[unstable(feature = "collections_drain", reason = "recently added")]
impl<'a> DoubleEndedIterator for Drain<'a> {
#[inline]
fn next_back(&mut self) -> Option<char> {
self.iter.next_back()
}
}

View File

@ -15,34 +15,44 @@
//!
//! # Examples
//!
//! Explicitly creating a `Vec<T>` with `new()`:
//! You can explicitly create a `Vec<T>` with `new()`:
//!
//! ```
//! let xs: Vec<i32> = Vec::new();
//! let v: Vec<i32> = Vec::new();
//! ```
//!
//! Using the `vec!` macro:
//! ...or by using the `vec!` macro:
//!
//! ```
//! let ys: Vec<i32> = vec![];
//! let v: Vec<i32> = vec![];
//!
//! let zs = vec![1i32, 2, 3, 4, 5];
//! let v = vec![1, 2, 3, 4, 5];
//!
//! let v = vec![0; 10]; // ten zeroes
//! ```
//!
//! Push:
//! You can `push` values onto the end of a vector (which will grow the vector as needed):
//!
//! ```
//! let mut xs = vec![1i32, 2];
//! let mut v = vec![1, 2];
//!
//! xs.push(3);
//! v.push(3);
//! ```
//!
//! And pop:
//! Popping values works in much the same way:
//!
//! ```
//! let mut xs = vec![1i32, 2];
//! let mut v = vec![1, 2];
//!
//! let two = xs.pop();
//! let two = v.pop();
//! ```
//!
//! Vectors also support indexing (through the `Index` and `IndexMut` traits):
//!
//! ```
//! let mut v = vec![1, 2, 3];
//! let three = v[2];
//! v[1] = v[1] + 5;
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
@ -69,6 +79,8 @@ use core::usize;
use borrow::{Cow, IntoCow};
use super::range::RangeArgument;
// FIXME- fix places which assume the max vector allowed has memory usize::MAX.
static MAX_MEMORY_SIZE: usize = isize::MAX as usize;
@ -714,36 +726,61 @@ impl<T> Vec<T> {
unsafe { other.set_len(0); }
}
/// Creates a draining iterator that clears the `Vec` and iterates over
/// the removed items from start to end.
/// Create a draining iterator that removes the specified range in the vector
/// and yields the removed items from start to end. The element range is
/// removed even if the iterator is not consumed until the end.
///
/// Note: It is unspecified how many elements are removed from the vector,
/// if the `Drain` value is leaked.
///
/// # Panics
///
/// Panics if the starting point is greater than the end point or if
/// the end point is greater than the length of the vector.
///
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut v = vec!["a".to_string(), "b".to_string()];
/// for s in v.drain() {
/// // s has type String, not &String
/// println!("{}", s);
/// }
/// assert!(v.is_empty());
/// # #![feature(collections_drain, collections_range)]
///
/// // Draining using `..` clears the whole vector.
/// let mut v = vec![1, 2, 3];
/// let u: Vec<_> = v.drain(..).collect();
/// assert_eq!(v, &[]);
/// assert_eq!(u, &[1, 2, 3]);
/// ```
#[inline]
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
pub fn drain(&mut self) -> Drain<T> {
#[unstable(feature = "collections_drain",
reason = "recently added, matches RFC")]
pub fn drain<R>(&mut self, range: R) -> Drain<T> where R: RangeArgument<usize> {
// Memory safety
//
// When the Drain is first created, it shortens the length of
// the source vector to make sure no uninitalized or moved-from elements
// are accessible at all if the Drain's destructor never gets to run.
//
// Drain will ptr::read out the values to remove.
// When finished, remaining tail of the vec is copied back to cover
// the hole, and the vector length is restored to the new length.
//
let len = self.len();
let start = *range.start().unwrap_or(&0);
let end = *range.end().unwrap_or(&len);
assert!(start <= end);
assert!(end <= len);
unsafe {
let begin = *self.ptr as *const T;
let end = if mem::size_of::<T>() == 0 {
(*self.ptr as usize + self.len()) as *const T
} else {
(*self.ptr).offset(self.len() as isize) as *const T
};
self.set_len(0);
// set self.vec length's to start, to be safe in case Drain is leaked
self.set_len(start);
// Use the borrow in the IterMut to indicate borrowing behavior of the
// whole Drain iterator (like &mut T).
let range_slice = slice::from_raw_parts_mut(
self.as_mut_ptr().offset(start as isize),
end - start);
Drain {
ptr: begin,
end: end,
marker: PhantomData,
tail_start: end,
tail_len: len - end,
iter: range_slice.iter_mut(),
vec: self as *mut _,
}
}
}
@ -1587,7 +1624,6 @@ impl<T: Ord> Ord for Vec<T> {
}
}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Vec<T> {
fn drop(&mut self) {
@ -1740,6 +1776,11 @@ impl<T> Iterator for IntoIter<T> {
let exact = diff / (if size == 0 {1} else {size});
(exact, Some(exact))
}
#[inline]
fn count(self) -> usize {
self.size_hint().0
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -1769,7 +1810,6 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for IntoIter<T> {
fn drop(&mut self) {
@ -1783,14 +1823,16 @@ impl<T> Drop for IntoIter<T> {
}
}
/// An iterator that drains a vector.
#[unsafe_no_drop_flag]
#[unstable(feature = "collections",
reason = "recently added as part of collections reform 2")]
pub struct Drain<'a, T:'a> {
ptr: *const T,
end: *const T,
marker: PhantomData<&'a T>,
/// A draining iterator for `Vec<T>`.
#[unstable(feature = "collections_drain", reason = "recently added")]
pub struct Drain<'a, T: 'a> {
/// Index of tail to preserve
tail_start: usize,
/// Length of tail
tail_len: usize,
/// Current remaining range to remove
iter: slice::IterMut<'a, T>,
vec: *mut Vec<T>,
}
unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
@ -1802,34 +1844,15 @@ impl<'a, T> Iterator for Drain<'a, T> {
#[inline]
fn next(&mut self) -> Option<T> {
unsafe {
if self.ptr == self.end {
None
} else {
if mem::size_of::<T>() == 0 {
// purposefully don't use 'ptr.offset' because for
// vectors with 0-size elements this would return the
// same pointer.
self.ptr = mem::transmute(self.ptr as usize + 1);
// Use a non-null pointer value
Some(ptr::read(EMPTY as *mut T))
} else {
let old = self.ptr;
self.ptr = self.ptr.offset(1);
Some(ptr::read(old))
}
self.iter.next().map(|elt|
unsafe {
ptr::read(elt as *const _)
}
}
)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let diff = (self.end as usize) - (self.ptr as usize);
let size = mem::size_of::<T>();
let exact = diff / (if size == 0 {1} else {size});
(exact, Some(exact))
self.iter.size_hint()
}
}
@ -1837,41 +1860,39 @@ impl<'a, T> Iterator for Drain<'a, T> {
impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
unsafe {
if self.end == self.ptr {
None
} else {
if mem::size_of::<T>() == 0 {
// See above for why 'ptr.offset' isn't used
self.end = mem::transmute(self.end as usize - 1);
self.iter.next_back().map(|elt|
unsafe {
ptr::read(elt as *const _)
}
)
}
}
// Use a non-null pointer value
Some(ptr::read(EMPTY as *mut T))
} else {
self.end = self.end.offset(-1);
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Drop for Drain<'a, T> {
fn drop(&mut self) {
// exhaust self first
while let Some(_) = self.next() { }
Some(ptr::read(self.end))
}
if self.tail_len > 0 {
unsafe {
let source_vec = &mut *self.vec;
// memmove back untouched tail, update to new length
let start = source_vec.len();
let tail = self.tail_start;
let src = source_vec.as_ptr().offset(tail as isize);
let dst = source_vec.as_mut_ptr().offset(start as isize);
ptr::copy(src, dst, self.tail_len);
source_vec.set_len(start + self.tail_len);
}
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Drop for Drain<'a, T> {
fn drop(&mut self) {
// self.ptr == self.end == mem::POST_DROP_USIZE if drop has already been called,
// so we can use #[unsafe_no_drop_flag].
// destroy the remaining elements
for _x in self.by_ref() {}
}
}
////////////////////////////////////////////////////////////////////////////////
// Conversion from &[T] to &Vec<T>
////////////////////////////////////////////////////////////////////////////////
@ -1893,7 +1914,6 @@ impl<'a, T> Deref for DerefVec<'a, T> {
}
// Prevent the inner `Vec<T>` from attempting to deallocate memory.
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Drop for DerefVec<'a, T> {
fn drop(&mut self) {
@ -1962,7 +1982,6 @@ struct PartialVecZeroSized<T,U> {
marker: PhantomData<::core::cell::Cell<(T,U)>>,
}
#[unsafe_destructor]
impl<T,U> Drop for PartialVecNonZeroSized<T,U> {
fn drop(&mut self) {
unsafe {
@ -1988,7 +2007,6 @@ impl<T,U> Drop for PartialVecNonZeroSized<T,U> {
}
}
#[unsafe_destructor]
impl<T,U> Drop for PartialVecZeroSized<T,U> {
fn drop(&mut self) {
unsafe {

View File

@ -59,7 +59,6 @@ impl<T: Clone> Clone for VecDeque<T> {
}
}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for VecDeque<T> {
fn drop(&mut self) {
@ -1396,6 +1395,42 @@ impl<T> VecDeque<T> {
// naive impl
self.extend(other.drain());
}
/// Retains only the elements specified by the predicate.
///
/// In other words, remove all elements `e` such that `f(&e)` returns false.
/// This method operates in place and preserves the order of the retained
/// elements.
///
/// # Examples
///
/// ```
/// # #![feature(vec_deque_retain)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
/// buf.extend(1..5);
/// buf.retain(|&x| x%2 == 0);
///
/// let v: Vec<_> = buf.into_iter().collect();
/// assert_eq!(&v[..], &[2, 4]);
/// ```
#[unstable(feature = "vec_deque_retain",
reason = "new API, waiting for dust to settle")]
pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
let len = self.len();
let mut del = 0;
for i in 0..len {
if !f(&self[i]) {
del += 1;
} else if del > 0 {
self.swap(i-del, i);
}
}
if del > 0 {
self.truncate(len - del);
}
}
}
impl<T: Clone> VecDeque<T> {
@ -1612,7 +1647,6 @@ pub struct Drain<'a, T: 'a> {
inner: &'a mut VecDeque<T>,
}
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: 'a> Drop for Drain<'a, T> {
fn drop(&mut self) {
@ -1772,7 +1806,7 @@ impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
}
#[cfg(test)]
mod test {
mod tests {
use core::iter::{Iterator, self};
use core::option::Option::Some;

View File

@ -367,7 +367,7 @@ impl<V> VecMap<V> {
// Move all elements to other
swap(self, &mut other);
return other
} else if at > self.v.len() {
} else if at >= self.v.len() {
// No elements to copy
return other;
}
@ -418,7 +418,7 @@ impl<V> VecMap<V> {
}
let filter: fn((usize, Option<V>)) -> Option<(usize, V)> = filter; // coerce to fn ptr
Drain { iter: self.v.drain().enumerate().filter_map(filter) }
Drain { iter: self.v.drain(..).enumerate().filter_map(filter) }
}
/// Returns the number of elements in the map.

View File

@ -387,6 +387,67 @@ fn test_bit_vec_clone() {
assert!(b.contains(&1000));
}
#[test]
fn test_bit_set_append() {
let mut a = BitSet::new();
a.insert(2);
a.insert(6);
let mut b = BitSet::new();
b.insert(1);
b.insert(3);
b.insert(6);
a.append(&mut b);
assert_eq!(a.len(), 4);
assert_eq!(b.len(), 0);
assert!(b.capacity() >= 6);
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b01110010])));
}
#[test]
fn test_bit_set_split_off() {
// Split at 0
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
0b00110011, 0b01101011, 0b10101101]));
let b = a.split_off(0);
assert_eq!(a.len(), 0);
assert_eq!(b.len(), 21);
assert_eq!(b, BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
0b00110011, 0b01101011, 0b10101101])));
// Split behind last element
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
0b00110011, 0b01101011, 0b10101101]));
let b = a.split_off(50);
assert_eq!(a.len(), 21);
assert_eq!(b.len(), 0);
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
0b00110011, 0b01101011, 0b10101101])));
// Split at arbitrary element
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
0b00110011, 0b01101011, 0b10101101]));
let b = a.split_off(34);
assert_eq!(a.len(), 12);
assert_eq!(b.len(), 9);
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
0b00110011, 0b01000000])));
assert_eq!(b, BitSet::from_bit_vec(BitVec::from_bytes(&[0, 0, 0, 0,
0b00101011, 0b10101101])));
}
mod bench {
use std::collections::{BitSet, BitVec};
use std::__rand::{Rng, thread_rng, ThreadRng};

View File

@ -630,6 +630,141 @@ fn test_bit_vec_extend() {
0b01001001, 0b10010010, 0b10111101]));
}
#[test]
fn test_bit_vec_append() {
// Append to BitVec that holds a multiple of u32::BITS bits
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011]);
let mut b = BitVec::new();
b.push(false);
b.push(true);
b.push(true);
a.append(&mut b);
assert_eq!(a.len(), 35);
assert_eq!(b.len(), 0);
assert!(b.capacity() >= 3);
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
false, false, false, true, false, false, true, false,
true, false, false, true, false, false, true, false,
false, false, true, true, false, false, true, true,
false, true, true]));
// Append to arbitrary BitVec
let mut a = BitVec::new();
a.push(true);
a.push(false);
let mut b = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
a.append(&mut b);
assert_eq!(a.len(), 42);
assert_eq!(b.len(), 0);
assert!(b.capacity() >= 40);
assert!(a.eq_vec(&[true, false, true, false, true, false, false, false,
false, false, false, false, false, true, false, false,
true, false, true, false, false, true, false, false,
true, false, false, false, true, true, false, false,
true, true, true, false, false, true, false, true,
false, true]));
// Append to empty BitVec
let mut a = BitVec::new();
let mut b = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
a.append(&mut b);
assert_eq!(a.len(), 40);
assert_eq!(b.len(), 0);
assert!(b.capacity() >= 40);
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
false, false, false, true, false, false, true, false,
true, false, false, true, false, false, true, false,
false, false, true, true, false, false, true, true,
true, false, false, true, false, true, false, true]));
// Append empty BitVec
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
let mut b = BitVec::new();
a.append(&mut b);
assert_eq!(a.len(), 40);
assert_eq!(b.len(), 0);
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
false, false, false, true, false, false, true, false,
true, false, false, true, false, false, true, false,
false, false, true, true, false, false, true, true,
true, false, false, true, false, true, false, true]));
}
#[test]
fn test_bit_vec_split_off() {
// Split at 0
let mut a = BitVec::new();
a.push(true);
a.push(false);
a.push(false);
a.push(true);
let b = a.split_off(0);
assert_eq!(a.len(), 0);
assert_eq!(b.len(), 4);
assert!(b.eq_vec(&[true, false, false, true]));
// Split at last bit
a.truncate(0);
a.push(true);
a.push(false);
a.push(false);
a.push(true);
let b = a.split_off(4);
assert_eq!(a.len(), 4);
assert_eq!(b.len(), 0);
assert!(a.eq_vec(&[true, false, false, true]));
// Split at block boundary
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b11110011]);
let b = a.split_off(32);
assert_eq!(a.len(), 32);
assert_eq!(b.len(), 8);
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
false, false, false, true, false, false, true, false,
true, false, false, true, false, false, true, false,
false, false, true, true, false, false, true, true]));
assert!(b.eq_vec(&[true, true, true, true, false, false, true, true]));
// Don't split at block boundary
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011,
0b01101011, 0b10101101]);
let b = a.split_off(13);
assert_eq!(a.len(), 13);
assert_eq!(b.len(), 35);
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
false, false, false, true, false]));
assert!(b.eq_vec(&[false, true, false, true, false, false, true, false,
false, true, false, false, false, true, true, false,
false, true, true, false, true, true, false, true,
false, true, true, true, false, true, false, true,
true, false, true]));
}
mod bench {
use std::collections::BitVec;
use std::u32;

View File

@ -12,6 +12,7 @@ use std::collections::BTreeMap;
use std::collections::Bound::{Excluded, Included, Unbounded, self};
use std::collections::btree_map::Entry::{Occupied, Vacant};
use std::iter::range_inclusive;
use std::rc::Rc;
#[test]
fn test_basic_large() {
@ -198,6 +199,34 @@ fn test_range() {
}
}
#[test]
fn test_borrow() {
// make sure these compile -- using the Borrow trait
{
let mut map = BTreeMap::new();
map.insert("0".to_string(), 1);
assert_eq!(map["0"], 1);
}
{
let mut map = BTreeMap::new();
map.insert(Box::new(0), 1);
assert_eq!(map[&0], 1);
}
{
let mut map = BTreeMap::new();
map.insert(Box::new([0, 1]) as Box<[i32]>, 1);
assert_eq!(map[&[0, 1][..]], 1);
}
{
let mut map = BTreeMap::new();
map.insert(Rc::new(0), 1);
assert_eq!(map[&0], 1);
}
}
#[test]
fn test_entry(){
let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];

Some files were not shown because too many files have changed in this diff Show More