]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #36862 - chamoysvoice:E0220, r=GuillaumeGomez
authorbors <bors@rust-lang.org>
Sun, 2 Oct 2016 12:01:57 +0000 (05:01 -0700)
committerGitHub <noreply@github.com>
Sun, 2 Oct 2016 12:01:57 +0000 (05:01 -0700)
Update E0220 error format

@jonathandturner
Part of #35233 .
Fixes #35385.

169 files changed:
RELEASES.md
mk/cfg/wasm32-unknown-emscripten.mk [new file with mode: 0644]
mk/main.mk
src/bootstrap/Cargo.lock
src/bootstrap/check.rs
src/bootstrap/lib.rs
src/bootstrap/native.rs
src/bootstrap/sanity.rs
src/bootstrap/step.rs
src/compiler-rt
src/doc/book/references-and-borrowing.md
src/doc/reference.md
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc_jemalloc/build.rs
src/liballoc_jemalloc/lib.rs
src/liballoc_system/lib.rs
src/libcollections/linked_list.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollectionstest/slice.rs
src/libcompiler_builtins/build.rs
src/libcore/cmp.rs
src/libcore/fmt/mod.rs
src/libcore/mem.rs
src/libcore/ops.rs
src/libcoretest/num/flt2dec/estimator.rs
src/liblibc
src/libpanic_unwind/Cargo.lock
src/libpanic_unwind/emcc.rs [new file with mode: 0644]
src/libpanic_unwind/lib.rs
src/librustc/cfg/construct.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/def_collector.rs
src/librustc/hir/mod.rs
src/librustc/hir/pat_util.rs
src/librustc/hir/print.rs
src/librustc/infer/error_reporting.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/region.rs
src/librustc/mir/repr.rs
src/librustc/mir/tcx.rs
src/librustc/mir/visit.rs
src/librustc/ty/error.rs
src/librustc/ty/fast_reject.rs
src/librustc/ty/mod.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/util.rs
src/librustc_back/target/asmjs_unknown_emscripten.rs
src/librustc_back/target/mod.rs
src/librustc_back/target/wasm32_unknown_emscripten.rs [new file with mode: 0644]
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/eval.rs
src/librustc_driver/lib.rs
src/librustc_incremental/calculate_svh/svh_visitor.rs
src/librustc_llvm/build.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/loader.rs
src/librustc_metadata/schema.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/pattern.rs
src/librustc_mir/mir_map.rs
src/librustc_passes/consts.rs
src/librustc_resolve/lib.rs
src/librustc_trans/abi.rs
src/librustc_trans/back/symbol_names.rs
src/librustc_trans/mir/constant.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render.rs
src/librustdoc/test.rs
src/libstd/env.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/net/mod.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/os/linux/raw.rs
src/libstd/process.rs
src/libstd/rand/mod.rs
src/libstd/sync/barrier.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mpsc/select.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/common/io.rs
src/libstd/sys/common/net.rs
src/libstd/sys/common/remutex.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/unix/net.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/thread.rs
src/libstd/thread/local.rs
src/libstd/thread/mod.rs
src/libstd/time/mod.rs
src/libsyntax/ast.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/build.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/test.rs
src/libsyntax/visit.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/format.rs
src/libtest/lib.rs
src/libunwind/libunwind.rs
src/llvm
src/rustllvm/llvm-auto-clean-trigger
src/test/compile-fail/E0035.rs
src/test/compile-fail/E0036.rs
src/test/compile-fail/allocator-dylib-is-system.rs
src/test/compile-fail/allocator-rust-dylib-is-jemalloc.rs
src/test/compile-fail/attr-on-generic-formals-are-visited.rs [new file with mode: 0644]
src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs [new file with mode: 0644]
src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs [new file with mode: 0644]
src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs [new file with mode: 0644]
src/test/compile-fail/attrs-with-no-formal-in-generics-3.rs [new file with mode: 0644]
src/test/compile-fail/discrim-overflow-2.rs
src/test/compile-fail/discrim-overflow.rs
src/test/compile-fail/issue-36881.rs [new file with mode: 0644]
src/test/incremental/hashes/enum_defs.rs [new file with mode: 0644]
src/test/run-fail/panic-task-name-none.rs
src/test/run-fail/panic-task-name-owned.rs
src/test/run-fail/task-spawn-barefn.rs
src/test/run-fail/test-panic.rs
src/test/run-fail/test-should-fail-bad-message.rs
src/test/run-fail/test-tasks-invalid-value.rs
src/test/run-pass/allocator-override.rs
src/test/run-pass/attr-on-generic-formals.rs [new file with mode: 0644]
src/test/run-pass/deriving-show.rs
src/test/run-pass/discriminant_value-wrapper.rs [new file with mode: 0644]
src/test/run-pass/extern-pass-empty.rs
src/test/run-pass/format-no-std.rs
src/test/run-pass/packed-struct-layout.rs
src/test/run-pass/packed-tuple-struct-layout.rs
src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs
src/test/run-pass/panic-runtime/abort.rs
src/test/run-pass/panic-runtime/lto-abort.rs
src/test/run-pass/panic-runtime/lto-unwind.rs
src/test/run-pass/process-status-inherits-stdin.rs
src/test/run-pass/simd-intrinsic-generic-cast.rs
src/test/run-pass/task-stderr.rs
src/tools/compiletest/src/common.rs
src/tools/compiletest/src/main.rs
src/tools/compiletest/src/runtest.rs
src/tools/compiletest/src/util.rs

index a747d046968211d1887d186a4ee71dbef0768a90..e6f18f9f7ba557726f9078ac320e0577a92318ae 100644 (file)
@@ -54,7 +54,7 @@ Diagnostics
   Most common editors supporting Rust have been updated to work with it. It was
   previously described [on the Rust blog]
   (https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html).
-* [In error descriptions, references are now described in plain english,
+* [In error descriptions, references are now described in plain English,
   instead of as "&-ptr"]
   (https://github.com/rust-lang/rust/pull/35611)
 * [In error type descriptions, unknown numeric types are named `{integer}` or
@@ -148,7 +148,7 @@ Libraries
   (https://github.com/rust-lang/rust/pull/34946)
 * [`hash_map::Entry`, `hash_map::VacantEntry` and `hash_map::OccupiedEntry`
   implement `Debug`]
-  (https://github.com/rust-lang/rust/pull/34946)
+  (https://github.com/rust-lang/rust/pull/34937)
 * [`btree_map::Entry`, `btree_map::VacantEntry` and `btree_map::OccupiedEntry`
   implement `Debug`]
   (https://github.com/rust-lang/rust/pull/34885)
@@ -885,7 +885,7 @@ Cargo
 Performance
 -----------
 
-* [The time complexity of comparing variables for equivalence during type 
+* [The time complexity of comparing variables for equivalence during type
   unification is reduced from _O_(_n_!) to _O_(_n_)][1.9tu]. This leads
   to major compilation time improvement in some scenarios.
 * [`ToString` is specialized for `str`, giving it the same performance
diff --git a/mk/cfg/wasm32-unknown-emscripten.mk b/mk/cfg/wasm32-unknown-emscripten.mk
new file mode 100644 (file)
index 0000000..997bdfb
--- /dev/null
@@ -0,0 +1,24 @@
+# wasm32-unknown-emscripten configuration
+CC_wasm32-unknown-emscripten=emcc
+CXX_wasm32-unknown-emscripten=em++
+CPP_wasm32-unknown-emscripten=$(CPP)
+AR_wasm32-unknown-emscripten=emar
+CFG_LIB_NAME_wasm32-unknown-emscripten=lib$(1).so
+CFG_STATIC_LIB_NAME_wasm32-unknown-emscripten=lib$(1).a
+CFG_LIB_GLOB_wasm32-unknown-emscripten=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_wasm32-unknown-emscripten=lib$(1)-*.dylib.dSYM
+CFG_JEMALLOC_CFLAGS_wasm32-unknown-emscripten := -m32 $(CFLAGS)
+CFG_GCCISH_CFLAGS_wasm32-unknown-emscripten :=  -g -fPIC -m32 -s BINARYEN=1 $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_wasm32-unknown-emscripten := -fno-rtti -s BINARYEN=1 $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_wasm32-unknown-emscripten := -shared -fPIC -ldl -pthread  -lrt -g -m32 -s BINARYEN=1
+CFG_GCCISH_DEF_FLAG_wasm32-unknown-emscripten := -Wl,--export-dynamic,--dynamic-list=
+CFG_LLC_FLAGS_wasm32-unknown-emscripten :=
+CFG_INSTALL_NAME_wasm32-unknown-emscripten =
+CFG_EXE_SUFFIX_wasm32-unknown-emscripten =
+CFG_WINDOWSY_wasm32-unknown-emscripten :=
+CFG_UNIXY_wasm32-unknown-emscripten := 1
+CFG_LDPATH_wasm32-unknown-emscripten :=
+CFG_RUN_wasm32-unknown-emscripten=$(2)
+CFG_RUN_TARG_wasm32-unknown-emscripten=$(call CFG_RUN_wasm32-unknown-emscripten,,$(2))
+CFG_GNU_TRIPLE_wasm32-unknown-emscripten := wasm32-unknown-emscripten
+CFG_DISABLE_JEMALLOC_wasm32-unknown-emscripten := 1
index cc843add50d1ba55053e5971621214775378f825..e68a8f3005561d56309527c7ac1de40c82e0ae93 100644 (file)
@@ -300,7 +300,7 @@ endif
 # LLVM macros
 ######################################################################
 
-LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc pnacl systemz
+LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc pnacl systemz jsbackend
 LLVM_REQUIRED_COMPONENTS=ipo bitreader bitwriter linker asmparser mcjit \
                 interpreter instrumentation
 
index 36b94e4ebea32d4136abc26919eb7f89f4fe0d8d..babbb6a16bae0002e1b4506e13394f6e60986e15 100644 (file)
@@ -5,16 +5,16 @@ dependencies = [
  "build_helper 0.1.0",
  "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)",
+ "gcc 0.3.35 (git+https://github.com/alexcrichton/gcc-rs)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -34,7 +34,7 @@ name = "cmake"
 version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -42,17 +42,17 @@ name = "filetime"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gcc"
-version = "0.3.31"
-source = "git+https://github.com/alexcrichton/gcc-rs#b8e2400883f1a2749b323354dad372cdd1c838c7"
+version = "0.3.35"
+source = "git+https://github.com/alexcrichton/gcc-rs#8ff5360b6e0dc4f3c9d3f71036f1ff403c68469d"
 
 [[package]]
 name = "gcc"
-version = "0.3.31"
+version = "0.3.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -65,13 +65,13 @@ name = "kernel32-sys"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libc"
-version = "0.2.10"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -84,15 +84,15 @@ name = "memchr"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num_cpus"
-version = "0.2.11"
+version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -123,7 +123,7 @@ version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -136,7 +136,7 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.1.28"
+version = "0.1.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -149,7 +149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi"
-version = "0.2.6"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -161,20 +161,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum aho-corasick 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2b3fb52b09c1710b961acb35390d514be82e4ac96a9969a8e38565a29b878dc9"
 "checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978"
 "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
-"checksum gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>"
-"checksum gcc 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)" = "cfe877476e53690ebb0ce7325d0bf43e198d9500291b54b3c65e518de5039b07"
+"checksum gcc 0.3.35 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>"
+"checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312"
 "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "55f3730be7e803cf350d32061958171731c2395831fbd67a61083782808183e0"
+"checksum libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "23e3757828fa702a20072c37ff47938e9dd331b92fac6e223d26d4b7a55f7ee2"
 "checksum md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5539a8dee9b4ae308c9c406a379838b435a8f2c84cf9fedc6d5a576be9888db"
 "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
-"checksum num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "51fedae97a05f7353612fe017ab705a37e6db8f4d67c5c6fe739a9e70d6eed09"
+"checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
 "checksum regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)" = "56b7ee9f764ecf412c6e2fff779bca4b22980517ae335a21aeaf4e32625a5df2"
 "checksum regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "31040aad7470ad9d8c46302dcffba337bb4289ca5da2e3cd6e37b64109a85199"
 "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
 "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
 "checksum thread_local 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "55dd963dbaeadc08aa7266bf7f91c3154a7805e32bb94b820b769d2ef3b4744d"
-"checksum toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "fcd27a04ca509aff336ba5eb2abc58d456f52c4ff64d9724d88acb85ead560b6"
+"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
 "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
-"checksum winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfaaa8fbdaa618fa6914b59b2769d690dd7521920a18d84b42d254678dd5fd4"
+"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
index 2b9d717cbd48dbaa3365257cb80916b32a10c393..b8417218a2231e285e3adbefc3b99ba1c01fc77d 100644 (file)
@@ -108,6 +108,10 @@ pub fn compiletest(build: &Build,
     cmd.arg("--host").arg(compiler.host);
     cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build));
 
+    if let Some(nodejs) = build.config.nodejs.as_ref() {
+        cmd.arg("--nodejs").arg(nodejs);
+    }
+
     let mut flags = vec!["-Crpath".to_string()];
     if build.config.rust_optimize_tests {
         flags.push("-O".to_string());
@@ -323,6 +327,9 @@ pub fn krate(build: &Build,
     if target.contains("android") {
         build.run(cargo.arg("--no-run"));
         krate_android(build, compiler, target, mode);
+    } else if target.contains("emscripten") {
+        build.run(cargo.arg("--no-run"));
+        krate_emscripten(build, compiler, target, mode);
     } else {
         cargo.args(&build.flags.args);
         build.run(&mut cargo);
@@ -371,6 +378,35 @@ fn krate_android(build: &Build,
     }
 }
 
+fn krate_emscripten(build: &Build,
+                    compiler: &Compiler,
+                    target: &str,
+                    mode: Mode) {
+     let mut tests = Vec::new();
+     let out_dir = build.cargo_out(compiler, mode, target);
+     find_tests(&out_dir, target, &mut tests);
+     find_tests(&out_dir.join("deps"), target, &mut tests);
+
+     for test in tests {
+         let test_file_name = test.to_string_lossy().into_owned();
+         println!("running {}", test_file_name);
+         let nodejs = build.config.nodejs.as_ref().expect("nodejs not configured");
+         let status = Command::new(nodejs)
+             .arg(&test_file_name)
+             .stderr(::std::process::Stdio::inherit())
+             .status();
+         match status {
+             Ok(status) => {
+                 if !status.success() {
+                     panic!("some tests failed");
+                 }
+             }
+             Err(e) => panic!(format!("failed to execute command: {}", e)),
+         };
+     }
+ }
+
+
 fn find_tests(dir: &Path,
               target: &str,
               dst: &mut Vec<PathBuf>) {
@@ -381,7 +417,8 @@ fn find_tests(dir: &Path,
         }
         let filename = e.file_name().into_string().unwrap();
         if (target.contains("windows") && filename.ends_with(".exe")) ||
-           (!target.contains("windows") && !filename.contains(".")) {
+           (!target.contains("windows") && !filename.contains(".")) ||
+           (target.contains("emscripten") && filename.contains(".js")){
             dst.push(e.path());
         }
     }
index 3d1cf47cb7e9037039b88ccdfea749001854801c..b4f61605d472db1f72596f99da37483513097ded 100644 (file)
@@ -557,17 +557,22 @@ enum State {
                 continue
             }
 
-            if !submodule.path.exists() {
-                t!(fs::create_dir_all(&submodule.path));
-            }
+            // `submodule.path` is the relative path to a submodule (from the repository root)
+            // `submodule_path` is the path to a submodule from the cwd
+
+            // use `submodule.path` when e.g. executing a submodule specific command from the
+            // repository root
+            // use `submodule_path` when e.g. executing a normal git command for the submodule
+            // (set via `current_dir`)
+            let submodule_path = self.src.join(submodule.path);
 
             match submodule.state {
                 State::MaybeDirty => {
                     // drop staged changes
-                    self.run(git().current_dir(submodule.path)
+                    self.run(git().current_dir(&submodule_path)
                                   .args(&["reset", "--hard"]));
                     // drops unstaged changes
-                    self.run(git().current_dir(submodule.path)
+                    self.run(git().current_dir(&submodule_path)
                                   .args(&["clean", "-fdx"]));
                 },
                 State::NotInitialized => {
@@ -577,9 +582,9 @@ enum State {
                 State::OutOfSync => {
                     // drops submodule commits that weren't reported to the (outer) git repository
                     self.run(git_submodule().arg("update").arg(submodule.path));
-                    self.run(git().current_dir(submodule.path)
+                    self.run(git().current_dir(&submodule_path)
                                   .args(&["reset", "--hard"]));
-                    self.run(git().current_dir(submodule.path)
+                    self.run(git().current_dir(&submodule_path)
                                   .args(&["clean", "-fdx"]));
                 },
             }
@@ -975,7 +980,8 @@ fn rustc_flags(&self, target: &str) -> Vec<String> {
         // than an entry here.
 
         let mut base = Vec::new();
-        if target != self.config.build && !target.contains("msvc") {
+        if target != self.config.build && !target.contains("msvc") &&
+            !target.contains("emscripten") {
             base.push(format!("-Clinker={}", self.cc(target).display()));
         }
         return base
index df6408e5fe1c8ac2010abcfdd3222a6b61b976d5..63fc59e43286e24d987de924f87b57afbf85ee01 100644 (file)
@@ -65,7 +65,7 @@ pub fn llvm(build: &Build, target: &str) {
        .out_dir(&dst)
        .profile(if build.config.llvm_optimize {"Release"} else {"Debug"})
        .define("LLVM_ENABLE_ASSERTIONS", assertions)
-       .define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC;SystemZ")
+       .define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend")
        .define("LLVM_INCLUDE_EXAMPLES", "OFF")
        .define("LLVM_INCLUDE_TESTS", "OFF")
        .define("LLVM_INCLUDE_DOCS", "OFF")
index 962d0666f69f192f8fbb8a37a54fb7ee40ccad92..c4e6399c2c36d270fc65fed47663379bf92bacff 100644 (file)
@@ -95,6 +95,13 @@ pub fn check(build: &mut Build) {
     // We're gonna build some custom C code here and there, host triples
     // also build some C++ shims for LLVM so we need a C++ compiler.
     for target in build.config.target.iter() {
+        // On emscripten we don't actually need the C compiler to just
+        // build the target artifacts, only for testing. For the sake
+        // of easier bot configuration, just skip detection.
+        if target.contains("emscripten") {
+            continue;
+        }
+
         need_cmd(build.cc(target).as_ref());
         if let Some(ar) = build.ar(target) {
             need_cmd(ar.as_ref());
@@ -104,6 +111,14 @@ pub fn check(build: &mut Build) {
         need_cmd(build.cxx(host).as_ref());
     }
 
+    // The msvc hosts don't use jemalloc, turn it off globally to
+    // avoid packaging the dummy liballoc_jemalloc on that platform.
+    for host in build.config.host.iter() {
+        if host.contains("msvc") {
+            build.config.use_jemalloc = false;
+        }
+    }
+
     // Externally configured LLVM requires FileCheck to exist
     let filecheck = build.llvm_filecheck(&build.config.build);
     if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
@@ -111,15 +126,6 @@ pub fn check(build: &mut Build) {
     }
 
     for target in build.config.target.iter() {
-        // Either can't build or don't want to run jemalloc on these targets
-        if target.contains("rumprun") ||
-           target.contains("bitrig") ||
-           target.contains("openbsd") ||
-           target.contains("msvc") ||
-           target.contains("emscripten") {
-            build.config.use_jemalloc = false;
-        }
-
         // Can't compile for iOS unless we're on OSX
         if target.contains("apple-ios") &&
            !build.config.build.contains("apple-darwin") {
index 4b5a26d205af7457f7093871145457a996e86af9..8a96cd1b4d23939f5e08e516beaa4a984e5c96fc 100644 (file)
@@ -418,7 +418,6 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
                     self.check_crate_std(compiler),
                     self.check_crate_test(compiler),
                     self.check_debuginfo(compiler),
-                    self.dist(stage),
                 ];
 
                 // If we're testing the build triple, then we know we can
@@ -463,6 +462,9 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
                         // misc
                         self.check_linkcheck(stage),
                         self.check_tidy(stage),
+
+                        // can we make the distributables?
+                        self.dist(stage),
                     ]);
                 }
                 return base
index 8598065bd965d9713bfafb6c1e766d63a7b17b89..f03ba5a4e8bf16dcf42dd742a4ce255c36321356 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8598065bd965d9713bfafb6c1e766d63a7b17b89
+Subproject commit f03ba5a4e8bf16dcf42dd742a4ce255c36321356
index 2ec3a00c0df516ab73db23926639712697c0cd50..d845ad6feb0013deb3856982f1e11a5c1d894201 100644 (file)
@@ -86,7 +86,7 @@ fn main() {
         return v.iter().fold(0, |a, &b| a + b);
     }
     // Borrow two vectors and sum them.
-    // This kind of borrowing does not allow mutation to the borrowed.
+    // This kind of borrowing does not allow mutation through the borrowed reference.
     fn foo(v1: &Vec<i32>, v2: &Vec<i32>) -> i32 {
         // do stuff with v1 and v2
         let s1 = sum_vec(v1);
index b72c3743a69ce1f34d447d7976f94b83ba62a66e..20970ab7a351254322cedef0f6efb4198e95dc75 100644 (file)
@@ -3959,6 +3959,16 @@ the top-level type for the implementation of the called method. If no such metho
 found, `.deref()` is called and the compiler continues to search for the method
 implementation in the returned type `U`.
 
+## The `Send` trait
+
+The `Send` trait indicates that a value of this type is safe to send from one 
+thread to another.
+
+## The 'Sync' trait
+
+The 'Sync' trait indicates that a value of this type is safe to share between
+multiple threads.
+
 # Memory model
 
 A Rust program's memory consists of a static set of *items* and a *heap*.
index e3c92fc1aa8301950e1f107d758050e0093ed60d..29e18781ce2a597884333e84f57f5d1938a27948 100644 (file)
@@ -1000,6 +1000,7 @@ fn drop(&mut self) {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn manually_share_arc() {
         let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
         let arc_v = Arc::new(v);
index bc9b6e805efc91ee5107229de22de8d01ec78148..28f4dda1408830264612d571a35d7f651868f988 100644 (file)
@@ -244,12 +244,14 @@ impl<T: ?Sized> Box<T> {
     /// the destructor of `T` and free the allocated memory. Since the
     /// way `Box` allocates and releases memory is unspecified, the
     /// only valid pointer to pass to this function is the one taken
-    /// from another `Box` via the `Box::into_raw` function.
+    /// from another `Box` via the [`Box::into_raw`] function.
     ///
     /// This function is unsafe because improper use may lead to
     /// memory problems. For example, a double-free may occur if the
     /// function is called twice on the same raw pointer.
     ///
+    /// [`Box::into_raw`]: struct.Box.html#method.into_raw
+    ///
     /// # Examples
     ///
     /// ```
@@ -269,12 +271,14 @@ pub unsafe fn from_raw(raw: *mut T) -> Self {
     /// memory previously managed by the `Box`. In particular, the
     /// caller should properly destroy `T` and release the memory. The
     /// proper way to do so is to convert the raw pointer back into a
-    /// `Box` with the `Box::from_raw` function.
+    /// `Box` with the [`Box::from_raw`] function.
     ///
     /// Note: this is an associated function, which means that you have
     /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
     /// is so that there is no conflict with a method on the inner type.
     ///
+    /// [`Box::from_raw`]: struct.Box.html#method.from_raw
+    ///
     /// # Examples
     ///
     /// ```
index 8b31c5a557747765fbdc09967cc9c28ad4cec700..028d742cc832ea7c0a466562075f25c787f629e3 100644 (file)
@@ -27,6 +27,24 @@ fn main() {
     let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
     let src_dir = env::current_dir().unwrap();
 
+    // FIXME: This is a hack to support building targets that don't
+    // support jemalloc alongside hosts that do. The jemalloc build is
+    // controlled by a feature of the std crate, and if that feature
+    // changes between targets, it invalidates the fingerprint of
+    // std's build script (this is a cargo bug); so we must ensure
+    // that the feature set used by std is the same across all
+    // targets, which means we have to build the alloc_jemalloc crate
+    // for targets like emscripten, even if we don't use it.
+    if target.contains("rumprun") ||
+        target.contains("bitrig") ||
+        target.contains("openbsd") ||
+        target.contains("msvc") ||
+        target.contains("emscripten")
+    {
+        println!("cargo:rustc-cfg=dummy_jemalloc");
+        return;
+    }
+
     if let Some(jemalloc) = env::var_os("JEMALLOC_OVERRIDE") {
         let jemalloc = PathBuf::from(jemalloc);
         println!("cargo:rustc-link-search=native={}",
index 5bbf1c35e0dd41f0b60e6f46d0ec3f0003b050df..21e45f9c4b20c81598c7629da18deeedc31941b4 100644 (file)
 
 extern crate libc;
 
-use libc::{c_int, c_void, size_t};
+pub use imp::*;
 
-// Linkage directives to pull in jemalloc and its dependencies.
-//
-// On some platforms we need to be sure to link in `pthread` which jemalloc
-// depends on, and specifically on android we need to also link to libgcc.
-// Currently jemalloc is compiled with gcc which will generate calls to
-// intrinsics that are libgcc specific (e.g. those intrinsics aren't present in
-// libcompiler-rt), so link that in to get that support.
-#[link(name = "jemalloc", kind = "static")]
-#[cfg_attr(target_os = "android", link(name = "gcc"))]
-#[cfg_attr(all(not(windows),
-               not(target_os = "android"),
-               not(target_env = "musl")),
-           link(name = "pthread"))]
-#[cfg(not(cargobuild))]
-extern "C" {}
-
-// Note that the symbols here are prefixed by default on OSX and Windows (we
-// don't explicitly request it), and on Android and DragonFly we explicitly
-// request it as unprefixing cause segfaults (mismatches in allocators).
-extern "C" {
-    #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                   target_os = "dragonfly", target_os = "windows"),
-               link_name = "je_mallocx")]
-    fn mallocx(size: size_t, flags: c_int) -> *mut c_void;
-    #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                   target_os = "dragonfly", target_os = "windows"),
-               link_name = "je_rallocx")]
-    fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
-    #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                   target_os = "dragonfly", target_os = "windows"),
-               link_name = "je_xallocx")]
-    fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
-    #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                   target_os = "dragonfly", target_os = "windows"),
-               link_name = "je_sdallocx")]
-    fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
-    #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                   target_os = "dragonfly", target_os = "windows"),
-               link_name = "je_nallocx")]
-    fn nallocx(size: size_t, flags: c_int) -> size_t;
-}
+// See comments in build.rs for why we sometimes build a crate that does nothing
+#[cfg(not(dummy_jemalloc))]
+mod imp {
+    use libc::{c_int, c_void, size_t};
 
-// The minimum alignment guaranteed by the architecture. This value is used to
-// add fast paths for low alignment values. In practice, the alignment is a
-// constant at the call site and the branch will be optimized out.
-#[cfg(all(any(target_arch = "arm",
-              target_arch = "mips",
-              target_arch = "powerpc")))]
-const MIN_ALIGN: usize = 8;
-#[cfg(all(any(target_arch = "x86",
-              target_arch = "x86_64",
-              target_arch = "aarch64",
-              target_arch = "powerpc64",
-              target_arch = "mips64",
-              target_arch = "s390x")))]
-const MIN_ALIGN: usize = 16;
-
-// MALLOCX_ALIGN(a) macro
-fn mallocx_align(a: usize) -> c_int {
-    a.trailing_zeros() as c_int
-}
+    // Linkage directives to pull in jemalloc and its dependencies.
+    //
+    // On some platforms we need to be sure to link in `pthread` which jemalloc
+    // depends on, and specifically on android we need to also link to libgcc.
+    // Currently jemalloc is compiled with gcc which will generate calls to
+    // intrinsics that are libgcc specific (e.g. those intrinsics aren't present in
+    // libcompiler-rt), so link that in to get that support.
+    #[link(name = "jemalloc", kind = "static")]
+    #[cfg_attr(target_os = "android", link(name = "gcc"))]
+    #[cfg_attr(all(not(windows),
+                   not(target_os = "android"),
+                   not(target_env = "musl")),
+               link(name = "pthread"))]
+    #[cfg(not(cargobuild))]
+    extern "C" {}
+
+    // Note that the symbols here are prefixed by default on OSX and Windows (we
+    // don't explicitly request it), and on Android and DragonFly we explicitly
+    // request it as unprefixing cause segfaults (mismatches in allocators).
+    extern "C" {
+        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
+                       target_os = "dragonfly", target_os = "windows"),
+                   link_name = "je_mallocx")]
+        fn mallocx(size: size_t, flags: c_int) -> *mut c_void;
+        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
+                       target_os = "dragonfly", target_os = "windows"),
+                   link_name = "je_rallocx")]
+        fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
+        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
+                       target_os = "dragonfly", target_os = "windows"),
+                   link_name = "je_xallocx")]
+        fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
+        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
+                       target_os = "dragonfly", target_os = "windows"),
+                   link_name = "je_sdallocx")]
+        fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
+        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
+                       target_os = "dragonfly", target_os = "windows"),
+                   link_name = "je_nallocx")]
+        fn nallocx(size: size_t, flags: c_int) -> size_t;
+    }
+
+    // The minimum alignment guaranteed by the architecture. This value is used to
+    // add fast paths for low alignment values. In practice, the alignment is a
+    // constant at the call site and the branch will be optimized out.
+    #[cfg(all(any(target_arch = "arm",
+                  target_arch = "mips",
+                  target_arch = "powerpc")))]
+    const MIN_ALIGN: usize = 8;
+    #[cfg(all(any(target_arch = "x86",
+                  target_arch = "x86_64",
+                  target_arch = "aarch64",
+                  target_arch = "powerpc64",
+                  target_arch = "mips64",
+                  target_arch = "s390x")))]
+    const MIN_ALIGN: usize = 16;
+
+    // MALLOCX_ALIGN(a) macro
+    fn mallocx_align(a: usize) -> c_int {
+        a.trailing_zeros() as c_int
+    }
+
+    fn align_to_flags(align: usize) -> c_int {
+        if align <= MIN_ALIGN {
+            0
+        } else {
+            mallocx_align(align)
+        }
+    }
+
+    #[no_mangle]
+    pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
+        let flags = align_to_flags(align);
+        unsafe { mallocx(size as size_t, flags) as *mut u8 }
+    }
+
+    #[no_mangle]
+    pub extern "C" fn __rust_reallocate(ptr: *mut u8,
+                                        _old_size: usize,
+                                        size: usize,
+                                        align: usize)
+                                        -> *mut u8 {
+        let flags = align_to_flags(align);
+        unsafe { rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 }
+    }
+
+    #[no_mangle]
+    pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
+                                                _old_size: usize,
+                                                size: usize,
+                                                align: usize)
+                                                -> usize {
+        let flags = align_to_flags(align);
+        unsafe { xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize }
+    }
 
-fn align_to_flags(align: usize) -> c_int {
-    if align <= MIN_ALIGN {
+    #[no_mangle]
+    pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
+        let flags = align_to_flags(align);
+        unsafe { sdallocx(ptr as *mut c_void, old_size as size_t, flags) }
+    }
+
+    #[no_mangle]
+    pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
+        let flags = align_to_flags(align);
+        unsafe { nallocx(size as size_t, flags) as usize }
+    }
+
+    // These symbols are used by jemalloc on android but the really old android
+    // we're building on doesn't have them defined, so just make sure the symbols
+    // are available.
+    #[no_mangle]
+    #[cfg(target_os = "android")]
+    pub extern "C" fn pthread_atfork(_prefork: *mut u8,
+                                     _postfork_parent: *mut u8,
+                                     _postfork_child: *mut u8)
+                                     -> i32 {
         0
-    } else {
-        mallocx_align(align)
     }
 }
 
-#[no_mangle]
-pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
-    let flags = align_to_flags(align);
-    unsafe { mallocx(size as size_t, flags) as *mut u8 }
-}
+#[cfg(dummy_jemalloc)]
+mod imp {
+    fn bogus() -> ! {
+        panic!("jemalloc is not implemented for this platform");
+    }
 
-#[no_mangle]
-pub extern "C" fn __rust_reallocate(ptr: *mut u8,
-                                    _old_size: usize,
-                                    size: usize,
-                                    align: usize)
-                                    -> *mut u8 {
-    let flags = align_to_flags(align);
-    unsafe { rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 }
-}
+    #[no_mangle]
+    pub extern "C" fn __rust_allocate(_size: usize, _align: usize) -> *mut u8 {
+        bogus()
+    }
 
-#[no_mangle]
-pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
-                                            _old_size: usize,
-                                            size: usize,
-                                            align: usize)
-                                            -> usize {
-    let flags = align_to_flags(align);
-    unsafe { xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize }
-}
+    #[no_mangle]
+    pub extern "C" fn __rust_reallocate(_ptr: *mut u8,
+                                        _old_size: usize,
+                                        _size: usize,
+                                        _align: usize)
+                                        -> *mut u8 {
+        bogus()
+    }
 
-#[no_mangle]
-pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
-    let flags = align_to_flags(align);
-    unsafe { sdallocx(ptr as *mut c_void, old_size as size_t, flags) }
-}
+    #[no_mangle]
+    pub extern "C" fn __rust_reallocate_inplace(_ptr: *mut u8,
+                                                _old_size: usize,
+                                                _size: usize,
+                                                _align: usize)
+                                                -> usize {
+        bogus()
+    }
 
-#[no_mangle]
-pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
-    let flags = align_to_flags(align);
-    unsafe { nallocx(size as size_t, flags) as usize }
-}
+    #[no_mangle]
+    pub extern "C" fn __rust_deallocate(_ptr: *mut u8, _old_size: usize, _align: usize) {
+        bogus()
+    }
 
-// These symbols are used by jemalloc on android but the really old android
-// we're building on doesn't have them defined, so just make sure the symbols
-// are available.
-#[no_mangle]
-#[cfg(target_os = "android")]
-pub extern "C" fn pthread_atfork(_prefork: *mut u8,
-                                 _postfork_parent: *mut u8,
-                                 _postfork_child: *mut u8)
-                                 -> i32 {
-    0
+    #[no_mangle]
+    pub extern "C" fn __rust_usable_size(_size: usize, _align: usize) -> usize {
+        bogus()
+    }
 }
index 01407d1acd2ecda82db51af61f7f50925cc91a22..dacafe771edc2c500264e0d028fcbe6ddfbc5fbd 100644 (file)
@@ -29,7 +29,8 @@
               target_arch = "mips",
               target_arch = "powerpc",
               target_arch = "powerpc64",
-              target_arch = "asmjs")))]
+              target_arch = "asmjs",
+              target_arch = "wasm32")))]
 const MIN_ALIGN: usize = 8;
 #[cfg(all(any(target_arch = "x86_64",
               target_arch = "aarch64",
index 690c4f4af35896df5b24cb5be112bfbf279b34e4..67f3708a62b91dbf50e83d6bf98fcb5842f967b0 100644 (file)
@@ -1294,6 +1294,7 @@ fn test_insert_prev() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_send() {
         let n = list_from(&[1, 2, 3]);
         thread::spawn(move || {
index 54dc7ec06da16b9661bf7f9547ad6eaaf9ba49b9..6b705ca039fd881b4f1d261c764f0b78c9eb1b60 100644 (file)
@@ -168,7 +168,7 @@ pub fn len(&self) -> usize {
         core_slice::SliceExt::len(self)
     }
 
-    /// Returns true if the slice has a length of 0
+    /// Returns true if the slice has a length of 0.
     ///
     /// # Example
     ///
@@ -402,7 +402,7 @@ pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
         core_slice::SliceExt::get_unchecked_mut(self, index)
     }
 
-    /// Returns an raw pointer to the slice's buffer
+    /// Returns an raw pointer to the slice's buffer.
     ///
     /// The caller must ensure that the slice outlives the pointer this
     /// function returns, or else it will end up pointing to garbage.
@@ -468,7 +468,7 @@ pub fn as_mut_ptr(&mut self) -> *mut T {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut v = ["a", "b", "c", "d"];
     /// v.swap(1, 3);
     /// assert!(v == ["a", "d", "c", "b"]);
@@ -483,7 +483,7 @@ pub fn swap(&mut self, a: usize, b: usize) {
     ///
     /// # Example
     ///
-    /// ```rust
+    /// ```
     /// let mut v = [1, 2, 3];
     /// v.reverse();
     /// assert!(v == [3, 2, 1]);
@@ -567,9 +567,9 @@ pub fn windows(&self, size: usize) -> Windows<T> {
     }
 
     /// Returns an iterator over `size` elements of the slice at a
-    /// time. The chunks are slices and do not overlap. If `size` does not divide the
-    /// length of the slice, then the last chunk will not have length
-    /// `size`.
+    /// time. The chunks are slices and do not overlap. If `size` does
+    /// not divide the length of the slice, then the last chunk will
+    /// not have length `size`.
     ///
     /// # Panics
     ///
@@ -656,7 +656,7 @@ pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut v = [1, 2, 3, 4, 5, 6];
     ///
     /// // scoped to restrict the lifetime of the borrows
@@ -754,7 +754,7 @@ pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
     }
 
     /// Returns an iterator over subslices separated by elements that match
-    /// `pred`, limited to returning at most `n` items.  The matched element is
+    /// `pred`, limited to returning at most `n` items. The matched element is
     /// not contained in the subslices.
     ///
     /// The last element returned, if any, will contain the remainder of the
@@ -781,7 +781,7 @@ pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
     }
 
     /// Returns an iterator over subslices separated by elements that match
-    /// `pred`, limited to returning at most `n` items.  The matched element is
+    /// `pred`, limited to returning at most `n` items. The matched element is
     /// not contained in the subslices.
     ///
     /// The last element returned, if any, will contain the remainder of the
@@ -835,7 +835,7 @@ pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to returning at most `n` items. This starts at the end of
-    /// the slice and works backwards.  The matched element is not contained in
+    /// the slice and works backwards. The matched element is not contained in
     /// the subslices.
     ///
     /// The last element returned, if any, will contain the remainder of the
@@ -922,9 +922,9 @@ pub fn ends_with(&self, needle: &[T]) -> bool
     ///
     /// Looks up a series of four elements. The first is found, with a
     /// uniquely determined position; the second and third are not
-    /// found; the fourth could match any position in `[1,4]`.
+    /// found; the fourth could match any position in `[1, 4]`.
     ///
-    /// ```rust
+    /// ```
     /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
     ///
     /// assert_eq!(s.binary_search(&13),  Ok(9));
@@ -956,9 +956,9 @@ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
     ///
     /// Looks up a series of four elements. The first is found, with a
     /// uniquely determined position; the second and third are not
-    /// found; the fourth could match any position in `[1,4]`.
+    /// found; the fourth could match any position in `[1, 4]`.
     ///
-    /// ```rust
+    /// ```
     /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
     ///
     /// let seek = 13;
@@ -982,21 +982,23 @@ pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
     /// Binary search a sorted slice with a key extraction function.
     ///
     /// Assumes that the slice is sorted by the key, for instance with
-    /// `sort_by_key` using the same key extraction function.
+    /// [`sort_by_key`] using the same key extraction function.
     ///
     /// If a matching value is found then returns `Ok`, containing the
     /// index for the matched element; if no match is found then `Err`
     /// is returned, containing the index where a matching element could
     /// be inserted while maintaining sorted order.
     ///
+    /// [`sort_by_key`]: #method.sort_by_key
+    ///
     /// # Examples
     ///
     /// Looks up a series of four elements in a slice of pairs sorted by
     /// their second elements. The first is found, with a uniquely
     /// determined position; the second and third are not found; the
-    /// fourth could match any position in `[1,4]`.
+    /// fourth could match any position in `[1, 4]`.
     ///
-    /// ```rust
+    /// ```
     /// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
     ///          (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
     ///          (1, 21), (2, 34), (4, 55)];
@@ -1023,7 +1025,7 @@ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, us
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut v = [-5, 4, 1, -3, 2];
     ///
     /// v.sort();
@@ -1045,7 +1047,7 @@ pub fn sort(&mut self)
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut v = [-5i32, 4, 1, -3, 2];
     ///
     /// v.sort_by_key(|k| k.abs());
@@ -1067,7 +1069,7 @@ pub fn sort_by_key<B, F>(&mut self, mut f: F)
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut v = [5, 4, 1, 3, 2];
     /// v.sort_by(|a, b| a.cmp(b));
     /// assert!(v == [1, 2, 3, 4, 5]);
@@ -1094,7 +1096,7 @@ pub fn sort_by<F>(&mut self, compare: F)
     ///
     /// # Example
     ///
-    /// ```rust
+    /// ```
     /// let mut dst = [0, 0, 0];
     /// let src = [1, 2, 3];
     ///
@@ -1116,7 +1118,7 @@ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
     ///
     /// # Example
     ///
-    /// ```rust
+    /// ```
     /// let mut dst = [0, 0, 0];
     /// let src = [1, 2, 3];
     ///
index 6a6b450e518632ff0b0666e594290d239bf077f7..96efe1a03e351095898bbead31653ec78ae5f13f 100644 (file)
@@ -697,7 +697,7 @@ pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
     ///
     /// Basic usage:
     ///
-    /// ```rust
+    /// ```
     /// let bananas = "bananas";
     ///
     /// assert!(bananas.ends_with("anas"));
@@ -900,7 +900,7 @@ pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
     ///
     /// It does _not_ give you:
     ///
-    /// ```rust,ignore
+    /// ```,ignore
     /// assert_eq!(d, &["a", "b", "c"]);
     /// ```
     ///
index e4930ae3572085169ecb0cec30ad4dec55636470..119828ea43c61c31ce419b1c173ae0fd795f542b 100644 (file)
@@ -21,7 +21,7 @@
 //!
 //! There are multiple ways to create a new `String` from a string literal:
 //!
-//! ```rust
+//! ```
 //! let s = "Hello".to_string();
 //!
 //! let s = String::from("world");
@@ -31,7 +31,7 @@
 //! You can create a new `String` from an existing one by concatenating with
 //! `+`:
 //!
-//! ```rust
+//! ```
 //! let s = "Hello".to_string();
 //!
 //! let message = s + " world!";
@@ -40,7 +40,7 @@
 //! If you have a vector of valid UTF-8 bytes, you can make a `String` out of
 //! it. You can do the reverse too.
 //!
-//! ```rust
+//! ```
 //! let sparkle_heart = vec![240, 159, 146, 150];
 //!
 //! // We know these bytes are valid, so we'll use `unwrap()`.
index e868a542d55fde2c8c05c8c6bb3d5b5601c1d56f..ed6eb62c9677ebdc5bafd47aba8dc359724f2728 100644 (file)
@@ -1769,7 +1769,7 @@ impl<T> IntoIter<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// # #![feature(vec_into_iter_as_slice)]
     /// let vec = vec!['a', 'b', 'c'];
     /// let mut into_iter = vec.into_iter();
@@ -1788,7 +1788,7 @@ pub fn as_slice(&self) -> &[T] {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// # #![feature(vec_into_iter_as_slice)]
     /// let vec = vec!['a', 'b', 'c'];
     /// let mut into_iter = vec.into_iter();
index 5b341ab62d097dd3de59d4ed5150a93e93df8e2b..9580714075ad78260e8c68e50354d8af085319ea 100644 (file)
@@ -1116,6 +1116,7 @@ fn test_box_slice_clone() {
 }
 
 #[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
 fn test_box_slice_clone_panics() {
     use std::sync::Arc;
     use std::sync::atomic::{AtomicUsize, Ordering};
index 66c683333b9854812767fc92e16b790c296f391d..acbd39bb1630c483c3a25064c8780eb95c118728 100644 (file)
@@ -73,6 +73,12 @@ fn extend(&mut self, sources: &[&'static str]) {
 
 fn main() {
     let target = env::var("TARGET").expect("TARGET was not set");
+
+    // Emscripten's runtime includes all the builtins
+    if target.contains("emscripten") {
+        return;
+    }
+
     let cfg = &mut gcc::Config::new();
 
     if target.contains("msvc") {
index f990a27e52b3190b8a00fd6840b7ad75ee546f62..036633fe89dc67d514c7e27dd84fbe68610149c0 100644 (file)
 
 //! Functionality for ordering and comparison.
 //!
-//! This module defines both `PartialOrd` and `PartialEq` traits which are used
+//! This module defines both [`PartialOrd`] and [`PartialEq`] traits which are used
 //! by the compiler to implement comparison operators. Rust programs may
-//! implement `PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators,
-//! and may implement `PartialEq` to overload the `==` and `!=` operators.
+//! implement [`PartialOrd`] to overload the `<`, `<=`, `>`, and `>=` operators,
+//! and may implement [`PartialEq`] to overload the `==` and `!=` operators.
+//!
+//! [`PartialOrd`]: trait.PartialOrd.html
+//! [`PartialEq`]: trait.PartialEq.html
 //!
 //! # Examples
 //!
index 5d7f41556c25f6ec9e52e70e4f35a4847bc9f605..9aba6703386a2ec2c04e6c245a13d04c4fbbe6df 100644 (file)
@@ -794,7 +794,7 @@ pub trait UpperExp {
 /// assert_eq!(output, "Hello world!");
 /// ```
 ///
-/// Please note that using [`write!`][write_macro] might be preferrable. Example:
+/// Please note that using [`write!`] might be preferrable. Example:
 ///
 /// ```
 /// use std::fmt::Write;
@@ -805,7 +805,7 @@ pub trait UpperExp {
 /// assert_eq!(output, "Hello world!");
 /// ```
 ///
-/// [write_macro]: ../../std/macro.write!.html
+/// [`write!`]: ../../std/macro.write.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn write(output: &mut Write, args: Arguments) -> Result {
     let mut formatter = Formatter {
@@ -1566,11 +1566,11 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
 // Implementation of Display/Debug for various core types
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Debug for *const T {
+impl<T: ?Sized> Debug for *const T {
     fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Debug for *mut T {
+impl<T: ?Sized> Debug for *mut T {
     fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
 }
 
index d3b8a60b79776c3f00a304e3430f006b1a4abc59..e0aa25724c1f93924ce901139295d840355328af 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use clone;
+use cmp;
+use fmt;
+use hash;
 use intrinsics;
+use marker::{Copy, PhantomData, Sized};
 use ptr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -647,3 +652,80 @@ pub fn drop<T>(_x: T) { }
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     ptr::read(src as *const T as *const U)
 }
+
+/// Opaque type representing the discriminant of an enum.
+///
+/// See the `discriminant` function in this module for more information.
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+pub struct Discriminant<T>(u64, PhantomData<*const T>);
+
+// N.B. These trait implementations cannot be derived because we don't want any bounds on T.
+
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+impl<T> Copy for Discriminant<T> {}
+
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+impl<T> clone::Clone for Discriminant<T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+impl<T> cmp::PartialEq for Discriminant<T> {
+    fn eq(&self, rhs: &Self) -> bool {
+        self.0 == rhs.0
+    }
+}
+
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+impl<T> cmp::Eq for Discriminant<T> {}
+
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+impl<T> hash::Hash for Discriminant<T> {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.0.hash(state);
+    }
+}
+
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+impl<T> fmt::Debug for Discriminant<T> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_tuple("Discriminant")
+           .field(&self.0)
+           .finish()
+    }
+}
+
+/// Returns a value uniquely identifying the enum variant in `v`.
+///
+/// If `T` is not an enum, calling this function will not result in undefined behavior, but the
+/// return value is unspecified.
+///
+/// # Stability
+///
+/// The discriminant of an enum variant may change if the enum definition changes. A discriminant
+/// of some variant will not change between compilations with the same compiler.
+///
+/// # Examples
+///
+/// This can be used to compare enums that carry data, while disregarding
+/// the actual data:
+///
+/// ```
+/// #![feature(discriminant_value)]
+/// use std::mem;
+///
+/// enum Foo { A(&'static str), B(i32), C(i32) }
+///
+/// assert!(mem::discriminant(&Foo::A("bar")) == mem::discriminant(&Foo::A("baz")));
+/// assert!(mem::discriminant(&Foo::B(1))     == mem::discriminant(&Foo::B(2)));
+/// assert!(mem::discriminant(&Foo::B(3))     != mem::discriminant(&Foo::C(3)));
+/// ```
+#[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")]
+pub fn discriminant<T>(v: &T) -> Discriminant<T> {
+    unsafe {
+        Discriminant(intrinsics::discriminant_value(v), PhantomData)
+    }
+}
+
index 85a52da332db53a8842a803ee14b83dd70fbf2d8..72e951a7c347c1f2c73f76c06d78e880c84472c2 100644 (file)
@@ -14,7 +14,7 @@
 //!
 //! Some of these traits are imported by the prelude, so they are available in
 //! every Rust program. Only operators backed by traits can be overloaded. For
-//! example, the addition operator (`+`) can be overloaded through the `Add`
+//! example, the addition operator (`+`) can be overloaded through the [`Add`]
 //! trait, but since the assignment operator (`=`) has no backing trait, there
 //! is no way of overloading its semantics. Additionally, this module does not
 //! provide any mechanism to create new operators. If traitless overloading or
 //! contexts involving built-in types, this is usually not a problem.
 //! However, using these operators in generic code, requires some
 //! attention if values have to be reused as opposed to letting the operators
-//! consume them. One option is to occasionally use `clone()`.
+//! consume them. One option is to occasionally use [`clone()`].
 //! Another option is to rely on the types involved providing additional
 //! operator implementations for references. For example, for a user-defined
 //! type `T` which is supposed to support addition, it is probably a good
-//! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>`
-//! so that generic code can be written without unnecessary cloning.
+//! idea to have both `T` and `&T` implement the traits [`Add<T>`][`Add`] and
+//! [`Add<&T>`][`Add`] so that generic code can be written without unnecessary
+//! cloning.
 //!
 //! # Examples
 //!
-//! This example creates a `Point` struct that implements `Add` and `Sub`, and
-//! then demonstrates adding and subtracting two `Point`s.
+//! This example creates a `Point` struct that implements [`Add`] and [`Sub`],
+//! and then demonstrates adding and subtracting two `Point`s.
 //!
 //! ```rust
 //! use std::ops::{Add, Sub};
 //! See the documentation for each trait for an example implementation.
 //!
 //! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be
-//! invoked like functions. Note that `Fn` takes `&self`, `FnMut` takes `&mut
-//! self` and `FnOnce` takes `self`. These correspond to the three kinds of
+//! invoked like functions. Note that [`Fn`] takes `&self`, [`FnMut`] takes `&mut
+//! self` and [`FnOnce`] takes `self`. These correspond to the three kinds of
 //! methods that can be invoked on an instance: call-by-reference,
 //! call-by-mutable-reference, and call-by-value. The most common use of these
 //! traits is to act as bounds to higher-level functions that take functions or
 //! closures as arguments.
 //!
-//! [`Fn`]: trait.Fn.html
-//! [`FnMut`]: trait.FnMut.html
-//! [`FnOnce`]: trait.FnOnce.html
-//!
-//! Taking a `Fn` as a parameter:
+//! Taking a [`Fn`] as a parameter:
 //!
 //! ```rust
 //! fn call_with_one<F>(func: F) -> usize
@@ -99,7 +96,7 @@
 //! assert_eq!(call_with_one(double), 2);
 //! ```
 //!
-//! Taking a `FnMut` as a parameter:
+//! Taking a [`FnMut`] as a parameter:
 //!
 //! ```rust
 //! fn do_twice<F>(mut func: F)
 //! assert_eq!(x, 5);
 //! ```
 //!
-//! Taking a `FnOnce` as a parameter:
+//! Taking a [`FnOnce`] as a parameter:
 //!
 //! ```rust
 //! fn consume_with_relish<F>(func: F)
 //!
 //! // `consume_and_return_x` can no longer be invoked at this point
 //! ```
+//!
+//! [`Fn`]: trait.Fn.html
+//! [`FnMut`]: trait.FnMut.html
+//! [`FnOnce`]: trait.FnOnce.html
+//! [`Add`]: trait.Add.html
+//! [`Sub`]: trait.Sub.html
+//! [`clone()`]: ../clone/trait.Clone.html#tymethod.clone
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -1873,7 +1877,7 @@ macro_rules! shr_assign_impl_all {
 shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 
 /// The `Index` trait is used to specify the functionality of indexing operations
-/// like `arr[idx]` when used in an immutable context.
+/// like `container[index]` when used in an immutable context.
 ///
 /// # Examples
 ///
@@ -1924,50 +1928,50 @@ pub trait Index<Idx: ?Sized> {
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output: ?Sized;
 
-    /// The method for the indexing (`Foo[Bar]`) operation
+    /// The method for the indexing (`container[index]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
     fn index(&self, index: Idx) -> &Self::Output;
 }
 
 /// The `IndexMut` trait is used to specify the functionality of indexing
-/// operations like `arr[idx]`, when used in a mutable context.
+/// operations like `container[index]`, when used in a mutable context.
 ///
 /// # Examples
 ///
-/// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
-/// calling `index_mut`, and therefore, `main` prints `Indexing!`.
+/// A trivial implementation of `IndexMut` for a type `Foo`. When `&mut Foo[2]`
+/// happens, it ends up calling `index_mut`, and therefore, `main` prints
+/// `Mutable indexing with 2!`.
 ///
 /// ```
 /// use std::ops::{Index, IndexMut};
 ///
 /// #[derive(Copy, Clone)]
 /// struct Foo;
-/// struct Bar;
 ///
-/// impl Index<Bar> for Foo {
+/// impl Index<usize> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
+///     fn index(&self, _index: usize) -> &Foo {
 ///         self
 ///     }
 /// }
 ///
-/// impl IndexMut<Bar> for Foo {
-///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
-///         println!("Indexing!");
+/// impl IndexMut<usize> for Foo {
+///     fn index_mut(&mut self, index: usize) -> &mut Foo {
+///         println!("Mutable indexing with {}!", index);
 ///         self
 ///     }
 /// }
 ///
 /// fn main() {
-///     &mut Foo[Bar];
+///     &mut Foo[2];
 /// }
 /// ```
 #[lang = "index_mut"]
 #[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
-    /// The method for the indexing (`Foo[Bar]`) operation
+    /// The method for the mutable indexing (`container[index]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
     fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
 }
index 857aae72c8a5bd5d92a0088a36bbe3c37fc58b37..0bca616ea9abcc99e5fc604ee4d91f2472b2985d 100644 (file)
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// FIXME https://github.com/kripken/emscripten/issues/4563
+// NB we have to actually not compile this test to avoid
+// an undefined symbol error
+#![cfg(not(target_os = "emscripten"))]
+
 use core::num::flt2dec::estimator::*;
 
 #[test]
index eb708c020826a8d792a5a5275be147aabe47fe24..b474785561d58efbd27add9d22339dcabad742ad 160000 (submodule)
@@ -1 +1 @@
-Subproject commit eb708c020826a8d792a5a5275be147aabe47fe24
+Subproject commit b474785561d58efbd27add9d22339dcabad742ad
index 20d826d4a470ee7c7c14d85b6760caade6f26eef..0cf75c941508b7b378ceeb86cb3105e0c593df5b 100644 (file)
@@ -5,6 +5,7 @@ dependencies = [
  "alloc 0.0.0",
  "core 0.0.0",
  "libc 0.0.0",
+ "unwind 0.0.0",
 ]
 
 [[package]]
@@ -25,3 +26,11 @@ dependencies = [
  "core 0.0.0",
 ]
 
+[[package]]
+name = "unwind"
+version = "0.0.0"
+dependencies = [
+ "core 0.0.0",
+ "libc 0.0.0",
+]
+
diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs
new file mode 100644 (file)
index 0000000..b3ab111
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unwinding for emscripten
+//!
+//! Whereas Rust's usual unwinding implementation for Unix platforms
+//! calls into the libunwind APIs directly, on emscripten we instead
+//! call into the C++ unwinding APIs. This is just an expedience since
+//! emscripten's runtime always implements those APIs and does not
+//! implement libunwind.
+
+#![allow(private_no_mangle_fns)]
+
+use core::any::Any;
+use core::ptr;
+use alloc::boxed::Box;
+use libc::{self, c_int};
+use unwind as uw;
+use core::mem;
+
+pub fn payload() -> *mut u8 {
+    ptr::null_mut()
+}
+
+pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
+    assert!(!ptr.is_null());
+    let ex = ptr::read(ptr as *mut _);
+    __cxa_free_exception(ptr as *mut _);
+    ex
+}
+
+pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
+    let sz = mem::size_of_val(&data);
+    let exception = __cxa_allocate_exception(sz);
+    if exception == ptr::null_mut() {
+        return uw::_URC_FATAL_PHASE1_ERROR as u32;
+    }
+    let exception = exception as *mut Box<Any + Send>;
+    ptr::write(exception, data);
+    __cxa_throw(exception as *mut _, ptr::null_mut(), ptr::null_mut());
+
+    unreachable!()
+}
+
+#[lang = "eh_personality"]
+#[no_mangle]
+unsafe extern "C" fn rust_eh_personality(version: c_int,
+                                         actions: uw::_Unwind_Action,
+                                         exception_class: uw::_Unwind_Exception_Class,
+                                         exception_object: *mut uw::_Unwind_Exception,
+                                         context: *mut uw::_Unwind_Context)
+                                         -> uw::_Unwind_Reason_Code {
+    __gxx_personality_v0(version, actions,
+                         exception_class,
+                         exception_object,
+                         context)
+}
+
+extern {
+    fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void;
+    fn __cxa_free_exception(thrown_exception: *mut libc::c_void);
+    fn __cxa_throw(thrown_exception: *mut libc::c_void,
+                   tinfo: *mut libc::c_void,
+                   dest: *mut libc::c_void);
+    fn __gxx_personality_v0(version: c_int,
+                            actions: uw::_Unwind_Action,
+                            exception_class: uw::_Unwind_Exception_Class,
+                            exception_object: *mut uw::_Unwind_Exception,
+                            context: *mut uw::_Unwind_Context)
+                            -> uw::_Unwind_Reason_Code;
+}
index 11dd9befe0a82e940da630f68317591ef960187b..ff483fa823e0cc0c86d7b224474b0ad5ae7266d7 100644 (file)
 mod imp;
 
 // i686-pc-windows-gnu and all others
-#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))]
+#[cfg(any(all(unix, not(target_os = "emscripten")),
+          all(windows, target_arch = "x86", target_env = "gnu")))]
 #[path = "gcc.rs"]
 mod imp;
 
+// emscripten
+#[cfg(target_os = "emscripten")]
+#[path = "emcc.rs"]
+mod imp;
+
 mod dwarf;
 mod windows;
 
index 25a73226473b7556e3179a7ca77108cf98db7b15..50d4cbc982e97b2be8633d71090024b430f76ddb 100644 (file)
@@ -126,7 +126,7 @@ fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
                 self.add_ast_node(pat.id, &[pats_exit])
             }
 
-            PatKind::Vec(ref pre, ref vec, ref post) => {
+            PatKind::Slice(ref pre, ref vec, ref post) => {
                 let pre_exit = self.pats_all(pre.iter(), pred);
                 let vec_exit = self.pats_all(vec.iter(), pre_exit);
                 let post_exit = self.pats_all(post.iter(), vec_exit);
@@ -298,7 +298,7 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
                 self.add_unreachable_node()
             }
 
-            hir::ExprVec(ref elems) => {
+            hir::ExprArray(ref elems) => {
                 self.straightline(expr, pred, elems.iter().map(|e| &**e))
             }
 
index 726e4e53e231c1fc5c592ac4e80b9be80f7c3524..b1771f52da2c6fef8b4fa31ade542c9ea393c380 100644 (file)
@@ -394,7 +394,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
     visitor.visit_id(typ.id);
 
     match typ.node {
-        TyVec(ref ty) => {
+        TySlice(ref ty) => {
             visitor.visit_ty(ty)
         }
         TyPtr(ref mutable_type) => {
@@ -422,7 +422,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             visitor.visit_ty(ty);
             walk_list!(visitor, visit_ty_param_bound, bounds);
         }
-        TyFixedLengthVec(ref ty, ref expression) => {
+        TyArray(ref ty, ref expression) => {
             visitor.visit_ty(ty);
             visitor.visit_expr(expression)
         }
@@ -520,7 +520,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
             visitor.visit_expr(upper_bound)
         }
         PatKind::Wild => (),
-        PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
+        PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => {
             walk_list!(visitor, visit_pat, prepatterns);
             walk_list!(visitor, visit_pat, slice_pattern);
             walk_list!(visitor, visit_pat, postpatterns);
@@ -749,7 +749,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
         ExprBox(ref subexpression) => {
             visitor.visit_expr(subexpression)
         }
-        ExprVec(ref subexpressions) => {
+        ExprArray(ref subexpressions) => {
             walk_list!(visitor, visit_expr, subexpressions);
         }
         ExprRepeat(ref element, ref count) => {
index 29dedeeeb03e646414b730635837fac25bd2414c..dace486b277db7e5360287fe876610486994a6a8 100644 (file)
@@ -222,17 +222,16 @@ fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
     }
 
     fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
-        use syntax::ast::TyKind::*;
         P(hir::Ty {
             id: t.id,
             node: match t.node {
-                Infer | ImplicitSelf => hir::TyInfer,
-                Vec(ref ty) => hir::TyVec(self.lower_ty(ty)),
-                Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
-                Rptr(ref region, ref mt) => {
+                TyKind::Infer | TyKind::ImplicitSelf => hir::TyInfer,
+                TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty)),
+                TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
+                TyKind::Rptr(ref region, ref mt) => {
                     hir::TyRptr(self.lower_opt_lifetime(region), self.lower_mt(mt))
                 }
-                BareFn(ref f) => {
+                TyKind::BareFn(ref f) => {
                     hir::TyBareFn(P(hir::BareFnTy {
                         lifetimes: self.lower_lifetime_defs(&f.lifetimes),
                         unsafety: self.lower_unsafety(f.unsafety),
@@ -240,12 +239,14 @@ fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
                         decl: self.lower_fn_decl(&f.decl),
                     }))
                 }
-                Never => hir::TyNever,
-                Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()),
-                Paren(ref ty) => {
+                TyKind::Never => hir::TyNever,
+                TyKind::Tup(ref tys) => {
+                    hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect())
+                }
+                TyKind::Paren(ref ty) => {
                     return self.lower_ty(ty);
                 }
-                Path(ref qself, ref path) => {
+                TyKind::Path(ref qself, ref path) => {
                     let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
                         hir::QSelf {
                             ty: self.lower_ty(ty),
@@ -254,22 +255,22 @@ fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
                     });
                     hir::TyPath(qself, self.lower_path(path))
                 }
-                ObjectSum(ref ty, ref bounds) => {
+                TyKind::ObjectSum(ref ty, ref bounds) => {
                     hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
                 }
-                FixedLengthVec(ref ty, ref e) => {
-                    hir::TyFixedLengthVec(self.lower_ty(ty), self.lower_expr(e))
+                TyKind::Array(ref ty, ref e) => {
+                    hir::TyArray(self.lower_ty(ty), self.lower_expr(e))
                 }
-                Typeof(ref expr) => {
+                TyKind::Typeof(ref expr) => {
                     hir::TyTypeof(self.lower_expr(expr))
                 }
-                PolyTraitRef(ref bounds) => {
+                TyKind::PolyTraitRef(ref bounds) => {
                     hir::TyPolyTraitRef(self.lower_bounds(bounds))
                 }
-                ImplTrait(ref bounds) => {
+                TyKind::ImplTrait(ref bounds) => {
                     hir::TyImplTrait(self.lower_bounds(bounds))
                 }
-                Mac(_) => panic!("TyMac should have been expanded by now."),
+                TyKind::Mac(_) => panic!("TyMac should have been expanded by now."),
             },
             span: t.span,
         })
@@ -891,8 +892,8 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                 PatKind::Range(ref e1, ref e2) => {
                     hir::PatKind::Range(self.lower_expr(e1), self.lower_expr(e2))
                 }
-                PatKind::Vec(ref before, ref slice, ref after) => {
-                    hir::PatKind::Vec(before.iter().map(|x| self.lower_pat(x)).collect(),
+                PatKind::Slice(ref before, ref slice, ref after) => {
+                    hir::PatKind::Slice(before.iter().map(|x| self.lower_pat(x)).collect(),
                                 slice.as_ref().map(|x| self.lower_pat(x)),
                                 after.iter().map(|x| self.lower_pat(x)).collect())
                 }
@@ -1031,7 +1032,7 @@ fn lower_expr(&mut self, e: &Expr) -> P<hir::Expr> {
                 }
 
                 ExprKind::Vec(ref exprs) => {
-                    hir::ExprVec(exprs.iter().map(|x| self.lower_expr(x)).collect())
+                    hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
                 }
                 ExprKind::Repeat(ref expr, ref count) => {
                     let expr = self.lower_expr(expr);
index c0f38061a0d6dac2681a1a6fb47a68db53986594..49d889ff08dec6a5aab1436be986bdad355d7322 100644 (file)
@@ -286,7 +286,7 @@ fn visit_expr(&mut self, expr: &Expr) {
     fn visit_ty(&mut self, ty: &Ty) {
         match ty.node {
             TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
-            TyKind::FixedLengthVec(_, ref length) => self.visit_ast_const_integer(length),
+            TyKind::Array(_, ref length) => self.visit_ast_const_integer(length),
             TyKind::ImplTrait(..) => {
                 self.create_def(ty.id, DefPathData::ImplTrait);
             }
@@ -448,7 +448,7 @@ fn visit_expr(&mut self, expr: &'ast hir::Expr) {
     }
 
     fn visit_ty(&mut self, ty: &'ast hir::Ty) {
-        if let hir::TyFixedLengthVec(_, ref length) = ty.node {
+        if let hir::TyArray(_, ref length) = ty.node {
             self.visit_hir_const_integer(length);
         }
         if let hir::TyImplTrait(..) = ty.node {
index 0cfdbae1a50b0a53d7bd1f9e1392620dc45eb391..f64b0e9c7342cf994cfc8624b8261ea66443b500 100644 (file)
@@ -478,7 +478,7 @@ fn walk_<G>(&self, it: &mut G) -> bool
             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
                 s.walk_(it)
             }
-            PatKind::Vec(ref before, ref slice, ref after) => {
+            PatKind::Slice(ref before, ref slice, ref after) => {
                 before.iter().all(|p| p.walk_(it)) &&
                 slice.iter().all(|p| p.walk_(it)) &&
                 after.iter().all(|p| p.walk_(it))
@@ -554,8 +554,8 @@ pub enum PatKind {
     /// A range pattern, e.g. `1...2`
     Range(P<Expr>, P<Expr>),
     /// `[a, b, ..i, y, z]` is represented as:
-    ///     `PatKind::Vec(box [a, b], Some(i), box [y, z])`
-    Vec(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
+    ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
+    Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -826,7 +826,7 @@ pub enum Expr_ {
     /// A `box x` expression.
     ExprBox(P<Expr>),
     /// An array (`[a, b, c, d]`)
-    ExprVec(HirVec<P<Expr>>),
+    ExprArray(HirVec<P<Expr>>),
     /// A function call
     ///
     /// The first field resolves to the function itself (usually an `ExprPath`),
@@ -1080,10 +1080,10 @@ pub struct BareFnTy {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 /// The different kinds of types recognized by the compiler
 pub enum Ty_ {
-    /// A variable length array (`[T]`)
-    TyVec(P<Ty>),
+    /// A variable length slice (`[T]`)
+    TySlice(P<Ty>),
     /// A fixed length array (`[T; n]`)
-    TyFixedLengthVec(P<Ty>, P<Expr>),
+    TyArray(P<Ty>, P<Expr>),
     /// A raw pointer (`*const T` or `*mut T`)
     TyPtr(MutTy),
     /// A reference (`&'a T` or `&'a mut T`)
index dec41fdfc3b50c35a4693339c61948d6488a3407..505d126db7f4fb9f6b848d58ec2d468c5de1ebfd 100644 (file)
@@ -62,7 +62,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
                 _ => false
             }
         }
-        PatKind::Vec(..) => true,
+        PatKind::Slice(..) => true,
         _ => false
     }
 }
index eebc8fa9e5d5dfd6aadc0cd48cca061f0e427418..90b92beb7a7fbf0eb17e332c6bed942b181e1ab8 100644 (file)
@@ -486,7 +486,7 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
         self.maybe_print_comment(ty.span.lo)?;
         self.ibox(0)?;
         match ty.node {
-            hir::TyVec(ref ty) => {
+            hir::TySlice(ref ty) => {
                 word(&mut self.s, "[")?;
                 self.print_type(&ty)?;
                 word(&mut self.s, "]")?;
@@ -543,7 +543,7 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
             hir::TyImplTrait(ref bounds) => {
                 self.print_bounds("impl ", &bounds[..])?;
             }
-            hir::TyFixedLengthVec(ref ty, ref v) => {
+            hir::TyArray(ref ty, ref v) => {
                 word(&mut self.s, "[")?;
                 self.print_type(&ty)?;
                 word(&mut self.s, "; ")?;
@@ -1319,7 +1319,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                 self.word_space("box")?;
                 self.print_expr(expr)?;
             }
-            hir::ExprVec(ref exprs) => {
+            hir::ExprArray(ref exprs) => {
                 self.print_expr_vec(&exprs[..])?;
             }
             hir::ExprRepeat(ref element, ref count) => {
@@ -1829,7 +1829,7 @@ pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
                 word(&mut self.s, "...")?;
                 self.print_expr(&end)?;
             }
-            PatKind::Vec(ref before, ref slice, ref after) => {
+            PatKind::Slice(ref before, ref slice, ref after) => {
                 word(&mut self.s, "[")?;
                 self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?;
                 if let Some(ref p) = *slice {
index 2792968d427aa95d39b99bf2e6e2202bd6800153..3f216d6916851a15867247edc15111a336d78c51 100644 (file)
@@ -1433,8 +1433,8 @@ fn rebuild_arg_ty_or_output(&self,
                 hir::TyPtr(ref mut_ty) => {
                     ty_queue.push(&mut_ty.ty);
                 }
-                hir::TyVec(ref ty) |
-                hir::TyFixedLengthVec(ref ty, _) => {
+                hir::TySlice(ref ty) |
+                hir::TyArray(ref ty, _) => {
                     ty_queue.push(&ty);
                 }
                 hir::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)),
@@ -1469,9 +1469,9 @@ fn build_to(from: P<hir::Ty>,
                             ty: build_to(mut_ty.ty, to),
                         })
                     }
-                    hir::TyVec(ty) => hir::TyVec(build_to(ty, to)),
-                    hir::TyFixedLengthVec(ty, e) => {
-                        hir::TyFixedLengthVec(build_to(ty, to), e)
+                    hir::TySlice(ty) => hir::TySlice(build_to(ty, to)),
+                    hir::TyArray(ty, e) => {
+                        hir::TyArray(build_to(ty, to), e)
                     }
                     hir::TyTup(tys) => {
                         hir::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect())
index 5b5c3da8f05b2eae0334c60879f5a8d7e0f2933d..d7392338d5ed9539af80d2c660f5e75af5c870f7 100644 (file)
@@ -442,7 +442,7 @@ pub fn walk_expr(&mut self, expr: &hir::Expr) {
                 }
             }
 
-            hir::ExprVec(ref exprs) => {
+            hir::ExprArray(ref exprs) => {
                 self.consume_exprs(exprs);
             }
 
index db9dd82d492d3193650fd464a0248bd63991511a..79396b9ca4dab155cda150de99f7af64395c3a90 100644 (file)
@@ -490,7 +490,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
 
       // otherwise, live nodes are not required:
       hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
-      hir::ExprVec(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
+      hir::ExprArray(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
       hir::ExprTup(..) | hir::ExprBinary(..) | hir::ExprAddrOf(..) |
       hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(_) |
       hir::ExprAgain(_) | hir::ExprLit(_) | hir::ExprRet(..) |
@@ -1095,7 +1095,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
 
           // Uninteresting cases: just propagate in rev exec order
 
-          hir::ExprVec(ref exprs) => {
+          hir::ExprArray(ref exprs) => {
             self.propagate_through_exprs(&exprs[..], succ)
           }
 
@@ -1436,7 +1436,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       hir::ExprCall(..) | hir::ExprMethodCall(..) | hir::ExprIf(..) |
       hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) |
       hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
-      hir::ExprVec(..) | hir::ExprTup(..) | hir::ExprBinary(..) |
+      hir::ExprArray(..) | hir::ExprTup(..) | hir::ExprBinary(..) |
       hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprRet(..) |
       hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprLit(_) |
       hir::ExprBlock(..) | hir::ExprAddrOf(..) |
index 340a5ac8f87b73a03f6a06adb8360006ece44cfd..c50e668a417946c59d12bc377ab43dce9c2bb88d 100644 (file)
@@ -503,7 +503,7 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
           hir::ExprClosure(..) | hir::ExprRet(..) |
           hir::ExprUnary(..) |
           hir::ExprMethodCall(..) | hir::ExprCast(..) |
-          hir::ExprVec(..) | hir::ExprTup(..) | hir::ExprIf(..) |
+          hir::ExprArray(..) | hir::ExprTup(..) | hir::ExprIf(..) |
           hir::ExprBinary(..) | hir::ExprWhile(..) |
           hir::ExprBlock(..) | hir::ExprLoop(..) | hir::ExprMatch(..) |
           hir::ExprLit(..) | hir::ExprBreak(..) |
@@ -1155,7 +1155,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResul
             self.cat_pattern_(subcmt, &subpat, op)?;
           }
 
-          PatKind::Vec(ref before, ref slice, ref after) => {
+          PatKind::Slice(ref before, ref slice, ref after) => {
             let context = InteriorOffsetKind::Pattern;
             let elt_cmt = self.cat_index(pat, cmt, context)?;
             for before_pat in before {
index 33110c61e8f8b1f0cf95c30f319c600f599a545d..90b6cbad3d9aea54849a66893debd7e0279bcae0 100644 (file)
@@ -961,7 +961,7 @@ fn is_binding_pat(pat: &hir::Pat) -> bool {
                 field_pats.iter().any(|fp| is_binding_pat(&fp.node.pat))
             }
 
-            PatKind::Vec(ref pats1, ref pats2, ref pats3) => {
+            PatKind::Slice(ref pats1, ref pats2, ref pats3) => {
                 pats1.iter().any(|p| is_binding_pat(&p)) ||
                 pats2.iter().any(|p| is_binding_pat(&p)) ||
                 pats3.iter().any(|p| is_binding_pat(&p))
@@ -1012,7 +1012,7 @@ fn record_rvalue_scope_if_borrow_expr(visitor: &mut RegionResolutionVisitor,
                         visitor, &field.expr, blk_id);
                 }
             }
-            hir::ExprVec(ref subexprs) |
+            hir::ExprArray(ref subexprs) |
             hir::ExprTup(ref subexprs) => {
                 for subexpr in subexprs {
                     record_rvalue_scope_if_borrow_expr(
index 5da2e2f6fda5444d763ad1c1ffe515fa033d4a00..f11dc3740da666a2bd53b6474d0fc12a2134eed5 100644 (file)
@@ -1024,7 +1024,7 @@ pub enum CastKind {
 
 #[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum AggregateKind<'tcx> {
-    Vec,
+    Array,
     Tuple,
     /// The second field is variant number (discriminant), it's equal to 0
     /// for struct and union expressions. The fourth field is active field
@@ -1115,8 +1115,6 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
             }
 
             Aggregate(ref kind, ref lvs) => {
-                use self::AggregateKind::*;
-
                 fn fmt_tuple(fmt: &mut Formatter, lvs: &[Operand]) -> fmt::Result {
                     let mut tuple_fmt = fmt.debug_tuple("");
                     for lv in lvs {
@@ -1126,9 +1124,9 @@ fn fmt_tuple(fmt: &mut Formatter, lvs: &[Operand]) -> fmt::Result {
                 }
 
                 match *kind {
-                    Vec => write!(fmt, "{:?}", lvs),
+                    AggregateKind::Array => write!(fmt, "{:?}", lvs),
 
-                    Tuple => {
+                    AggregateKind::Tuple => {
                         match lvs.len() {
                             0 => write!(fmt, "()"),
                             1 => write!(fmt, "({:?},)", lvs[0]),
@@ -1136,7 +1134,7 @@ fn fmt_tuple(fmt: &mut Formatter, lvs: &[Operand]) -> fmt::Result {
                         }
                     }
 
-                    Adt(adt_def, variant, substs, _) => {
+                    AggregateKind::Adt(adt_def, variant, substs, _) => {
                         let variant_def = &adt_def.variants[variant];
 
                         ppaux::parameterized(fmt, substs, variant_def.did,
@@ -1155,7 +1153,7 @@ fn fmt_tuple(fmt: &mut Formatter, lvs: &[Operand]) -> fmt::Result {
                         }
                     }
 
-                    Closure(def_id, _) => ty::tls::with(|tcx| {
+                    AggregateKind::Closure(def_id, _) => ty::tls::with(|tcx| {
                         if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
                             let name = format!("[closure@{:?}]", tcx.map.span(node_id));
                             let mut struct_fmt = fmt.debug_struct(&name);
index 19e980ec73eb148464f492cd0553ef9333fc8515..960d61adba72c3b7c8b4878505f6f73a0b0cea04 100644 (file)
@@ -174,7 +174,7 @@ pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Opti
             }
             &Rvalue::Aggregate(ref ak, ref ops) => {
                 match *ak {
-                    AggregateKind::Vec => {
+                    AggregateKind::Array => {
                         if let Some(operand) = ops.get(0) {
                             let ty = operand.ty(mir, tcx);
                             Some(tcx.mk_array(ty, ops.len()))
index 9e0bafa4e310f22bafe9244c0c3dfff26c979840..cb8d3f97f7b2963fc8541c8f73d274d82bb45e8c 100644 (file)
@@ -513,7 +513,7 @@ fn super_rvalue(&mut self,
                     Rvalue::Aggregate(ref $($mutability)* kind,
                                       ref $($mutability)* operands) => {
                         match *kind {
-                            AggregateKind::Vec => {
+                            AggregateKind::Array => {
                             }
                             AggregateKind::Tuple => {
                             }
index 001f47af68c3bf67b0727f6425a2040eb5c0ef32..9b345c2d02329b5f1f6ca1e7a3a7da130cdb01b8 100644 (file)
@@ -33,13 +33,8 @@ pub enum TypeError<'tcx> {
     UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
     AbiMismatch(ExpectedFound<abi::Abi>),
     Mutability,
-    BoxMutability,
-    PtrMutability,
-    RefMutability,
-    VecMutability,
     TupleSize(ExpectedFound<usize>),
     FixedArraySize(ExpectedFound<usize>),
-    TyParamSize(ExpectedFound<usize>),
     ArgCount,
     RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
     RegionsNotSame(&'tcx Region, &'tcx Region),
@@ -47,14 +42,12 @@ pub enum TypeError<'tcx> {
     RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region),
     RegionsOverlyPolymorphic(BoundRegion, &'tcx Region),
     Sorts(ExpectedFound<Ty<'tcx>>),
-    IntegerAsChar,
     IntMismatch(ExpectedFound<ty::IntVarValue>),
     FloatMismatch(ExpectedFound<ast::FloatTy>),
     Traits(ExpectedFound<DefId>),
     BuiltinBoundsMismatch(ExpectedFound<ty::BuiltinBounds>),
     VariadicMismatch(ExpectedFound<bool>),
     CyclicTy,
-    ConvergenceMismatch(ExpectedFound<bool>),
     ProjectionNameMismatched(ExpectedFound<Name>),
     ProjectionBoundsLength(ExpectedFound<usize>),
     TyParamDefaultMismatch(ExpectedFound<type_variable::Default<'tcx>>)
@@ -99,18 +92,6 @@ fn report_maybe_different(f: &mut fmt::Formatter,
                        values.found)
             }
             Mutability => write!(f, "types differ in mutability"),
-            BoxMutability => {
-                write!(f, "boxed types differ in mutability")
-            }
-            VecMutability => write!(f, "vectors differ in mutability"),
-            PtrMutability => write!(f, "pointers differ in mutability"),
-            RefMutability => write!(f, "references differ in mutability"),
-            TyParamSize(values) => {
-                write!(f, "expected a type with {} type params, \
-                           found one with {} type params",
-                       values.expected,
-                       values.found)
-            }
             FixedArraySize(values) => {
                 write!(f, "expected an array with a fixed size of {} elements, \
                            found one with {} elements",
@@ -167,9 +148,6 @@ fn report_maybe_different(f: &mut fmt::Formatter,
                            values.found)
                 }
             }
-            IntegerAsChar => {
-                write!(f, "expected an integral type, found `char`")
-            }
             IntMismatch(ref values) => {
                 write!(f, "expected `{:?}`, found `{:?}`",
                        values.expected,
@@ -185,11 +163,6 @@ fn report_maybe_different(f: &mut fmt::Formatter,
                        if values.expected { "variadic" } else { "non-variadic" },
                        if values.found { "variadic" } else { "non-variadic" })
             }
-            ConvergenceMismatch(ref values) => {
-                write!(f, "expected {} fn, found {} function",
-                       if values.expected { "converging" } else { "diverging" },
-                       if values.found { "converging" } else { "diverging" })
-            }
             ProjectionNameMismatched(ref values) => {
                 write!(f, "expected {}, found {}",
                        values.expected,
index ee1544d2d996d3df5905d29c6838ec2b4439e6e5..befc9533c387b338747e386c4e876ab0ff19ec44 100644 (file)
@@ -24,7 +24,7 @@ pub enum SimplifiedType {
     FloatSimplifiedType(ast::FloatTy),
     AdtSimplifiedType(DefId),
     StrSimplifiedType,
-    VecSimplifiedType,
+    ArraySimplifiedType,
     PtrSimplifiedType,
     NeverSimplifiedType,
     TupleSimplifiedType(usize),
@@ -57,7 +57,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         ty::TyFloat(float_type) => Some(FloatSimplifiedType(float_type)),
         ty::TyAdt(def, _) => Some(AdtSimplifiedType(def.did)),
         ty::TyStr => Some(StrSimplifiedType),
-        ty::TyArray(..) | ty::TySlice(_) => Some(VecSimplifiedType),
+        ty::TyArray(..) | ty::TySlice(_) => Some(ArraySimplifiedType),
         ty::TyRawPtr(_) => Some(PtrSimplifiedType),
         ty::TyTrait(ref trait_info) => {
             Some(TraitSimplifiedType(trait_info.principal.def_id()))
index 717b8923a16358a5edcccdcfc421f90bf64615d5..cc13299d4347585a8ce6f480e0951c1be6c963e6 100644 (file)
@@ -2228,7 +2228,7 @@ pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
             hir::ExprClosure(..) |
             hir::ExprBlock(..) |
             hir::ExprRepeat(..) |
-            hir::ExprVec(..) |
+            hir::ExprArray(..) |
             hir::ExprBreak(..) |
             hir::ExprAgain(..) |
             hir::ExprRet(..) |
index 5a87ea1473d982fbda294e9dc4f5e13566aa2faf..abd5cb51f39baa795d2a4cb2d265ce80926a96d2 100644 (file)
@@ -296,13 +296,8 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             UnsafetyMismatch(x) => UnsafetyMismatch(x),
             AbiMismatch(x) => AbiMismatch(x),
             Mutability => Mutability,
-            BoxMutability => BoxMutability,
-            PtrMutability => PtrMutability,
-            RefMutability => RefMutability,
-            VecMutability => VecMutability,
             TupleSize(x) => TupleSize(x),
             FixedArraySize(x) => FixedArraySize(x),
-            TyParamSize(x) => TyParamSize(x),
             ArgCount => ArgCount,
             RegionsDoesNotOutlive(a, b) => {
                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
@@ -319,14 +314,12 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             RegionsOverlyPolymorphic(a, b) => {
                 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
             }
-            IntegerAsChar => IntegerAsChar,
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
             Traits(x) => Traits(x),
             BuiltinBoundsMismatch(x) => BuiltinBoundsMismatch(x),
             VariadicMismatch(x) => VariadicMismatch(x),
             CyclicTy => CyclicTy,
-            ConvergenceMismatch(x) => ConvergenceMismatch(x),
             ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
             ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
 
index 8fe5756a60ecb5cc2358758c3b769bef0004153a..c209503e90e7d50c83b88a412b409ed1b5ca3ba8 100644 (file)
@@ -12,6 +12,7 @@
 
 use hir::def_id::DefId;
 use infer::InferCtxt;
+use hir::map as ast_map;
 use hir::pat_util;
 use traits::{self, Reveal};
 use ty::{self, Ty, AdtKind, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
@@ -388,16 +389,77 @@ pub fn is_adt_dtorck(self, adt: ty::AdtDef) -> bool {
     }
 }
 
+// When hashing a type this ends up affecting properties like symbol names. We
+// want these symbol names to be calculated independent of other factors like
+// what architecture you're compiling *from*.
+//
+// The hashing just uses the standard `Hash` trait, but the implementations of
+// `Hash` for the `usize` and `isize` types are *not* architecture independent
+// (e.g. they has 4 or 8 bytes). As a result we want to avoid `usize` and
+// `isize` completely when hashing. To ensure that these don't leak in we use a
+// custom hasher implementation here which inflates the size of these to a `u64`
+// and `i64`.
+struct WidenUsizeHasher<H> {
+    inner: H,
+}
+
+impl<H> WidenUsizeHasher<H> {
+    fn new(inner: H) -> WidenUsizeHasher<H> {
+        WidenUsizeHasher { inner: inner }
+    }
+}
+
+impl<H: Hasher> Hasher for WidenUsizeHasher<H> {
+    fn write(&mut self, bytes: &[u8]) {
+        self.inner.write(bytes)
+    }
+
+    fn finish(&self) -> u64 {
+        self.inner.finish()
+    }
+
+    fn write_u8(&mut self, i: u8) {
+        self.inner.write_u8(i)
+    }
+    fn write_u16(&mut self, i: u16) {
+        self.inner.write_u16(i)
+    }
+    fn write_u32(&mut self, i: u32) {
+        self.inner.write_u32(i)
+    }
+    fn write_u64(&mut self, i: u64) {
+        self.inner.write_u64(i)
+    }
+    fn write_usize(&mut self, i: usize) {
+        self.inner.write_u64(i as u64)
+    }
+    fn write_i8(&mut self, i: i8) {
+        self.inner.write_i8(i)
+    }
+    fn write_i16(&mut self, i: i16) {
+        self.inner.write_i16(i)
+    }
+    fn write_i32(&mut self, i: i32) {
+        self.inner.write_i32(i)
+    }
+    fn write_i64(&mut self, i: i64) {
+        self.inner.write_i64(i)
+    }
+    fn write_isize(&mut self, i: isize) {
+        self.inner.write_i64(i as i64)
+    }
+}
+
 pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, H> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    state: H
+    state: WidenUsizeHasher<H>,
 }
 
 impl<'a, 'gcx, 'tcx, H: Hasher> TypeIdHasher<'a, 'gcx, 'tcx, H> {
     pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, state: H) -> Self {
         TypeIdHasher {
             tcx: tcx,
-            state: state
+            state: WidenUsizeHasher::new(state),
         }
     }
 
@@ -421,9 +483,12 @@ fn hash_discriminant_u8<T>(&mut self, x: &T) {
     fn def_id(&mut self, did: DefId) {
         // Hash the DefPath corresponding to the DefId, which is independent
         // of compiler internal state.
-        let tcx = self.tcx;
-        let def_path = tcx.def_path(did);
-        def_path.deterministic_hash_to(tcx, &mut self.state);
+        let path = self.tcx.def_path(did);
+        self.def_path(&path)
+    }
+
+    pub fn def_path(&mut self, def_path: &ast_map::DefPath) {
+        def_path.deterministic_hash_to(self.tcx, &mut self.state);
     }
 }
 
@@ -436,7 +501,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
             TyInt(i) => self.hash(i),
             TyUint(u) => self.hash(u),
             TyFloat(f) => self.hash(f),
-            TyArray(_, n) => self.hash(n as u64),
+            TyArray(_, n) => self.hash(n),
             TyRawPtr(m) |
             TyRef(_, m) => self.hash(m.mutbl),
             TyClosure(def_id, _) |
@@ -447,14 +512,14 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
                 self.hash(f.unsafety);
                 self.hash(f.abi);
                 self.hash(f.sig.variadic());
-                self.hash(f.sig.inputs().skip_binder().len() as u64);
+                self.hash(f.sig.inputs().skip_binder().len());
             }
             TyTrait(ref data) => {
                 self.def_id(data.principal.def_id());
                 self.hash(data.builtin_bounds);
             }
             TyTuple(tys) => {
-                self.hash(tys.len() as u64);
+                self.hash(tys.len());
             }
             TyParam(p) => {
                 self.hash(p.idx);
index 9ccfdbb129c7352bceab72900939f340660c7512..667f7cf2c214a9defc7c7b01c0d0f60addf59e91 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Result<Target, String> {
         allow_asm: false,
         obj_is_bitcode: true,
         max_atomic_width: 32,
+        post_link_args: vec!["-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()],
         .. Default::default()
     };
     Ok(Target {
index 3eddd911749e5251b13818b7fb64c58f5af85e3c..4404af1970e77857423c39d13a864fb503a36a54 100644 (file)
@@ -168,8 +168,8 @@ fn $module() {
     ("x86_64-unknown-netbsd", x86_64_unknown_netbsd),
     ("x86_64-rumprun-netbsd", x86_64_rumprun_netbsd),
 
-    ("i686_unknown_haiku", i686_unknown_haiku),
-    ("x86_64_unknown_haiku", x86_64_unknown_haiku),
+    ("i686-unknown-haiku", i686_unknown_haiku),
+    ("x86_64-unknown-haiku", x86_64_unknown_haiku),
 
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
@@ -190,7 +190,8 @@ fn $module() {
     ("i586-pc-windows-msvc", i586_pc_windows_msvc),
 
     ("le32-unknown-nacl", le32_unknown_nacl),
-    ("asmjs-unknown-emscripten", asmjs_unknown_emscripten)
+    ("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
+    ("wasm32-unknown-emscripten", wasm32_unknown_emscripten)
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
diff --git a/src/librustc_back/target/wasm32_unknown_emscripten.rs b/src/librustc_back/target/wasm32_unknown_emscripten.rs
new file mode 100644 (file)
index 0000000..2923f2e
--- /dev/null
@@ -0,0 +1,42 @@
+// 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.
+
+use super::{Target, TargetOptions};
+
+pub fn target() -> Result<Target, String> {
+    let opts = TargetOptions {
+        linker: "emcc".to_string(),
+        ar: "emar".to_string(),
+
+        dynamic_linking: false,
+        executables: true,
+        // Today emcc emits two files - a .js file to bootstrap and
+        // possibly interpret the wasm, and a .wasm file
+        exe_suffix: ".js".to_string(),
+        linker_is_gnu: true,
+        allow_asm: false,
+        obj_is_bitcode: true,
+        max_atomic_width: 32,
+        post_link_args: vec!["-s".to_string(), "BINARYEN=1".to_string(),
+                             "-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()],
+        .. Default::default()
+    };
+    Ok(Target {
+        llvm_target: "asmjs-unknown-emscripten".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_os: "emscripten".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(),
+        arch: "wasm32".to_string(),
+        options: opts,
+    })
+}
index eb74936d8c905380625a63e630a06f6a24934631..5178ef65cf6a46ef356ff767996872483973688c 100644 (file)
@@ -536,10 +536,10 @@ fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
                 }
                 PatKind::Box(inner) => PatKind::Box(self.fold_pat(inner)),
                 PatKind::Ref(inner, mutbl) => PatKind::Ref(self.fold_pat(inner), mutbl),
-                PatKind::Vec(before, slice, after) => {
-                    PatKind::Vec(before.move_map(|x| self.fold_pat(x)),
-                                 slice.map(|x| self.fold_pat(x)),
-                                 after.move_map(|x| self.fold_pat(x)))
+                PatKind::Slice(before, slice, after) => {
+                    PatKind::Slice(before.move_map(|x| self.fold_pat(x)),
+                                   slice.map(|x| self.fold_pat(x)),
+                                   after.move_map(|x| self.fold_pat(x)))
                 }
                 PatKind::Wild |
                 PatKind::Lit(_) |
@@ -610,14 +610,14 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
         ty::TySlice(_) => match ctor {
             &Slice(n) => {
                 assert_eq!(pats_len, n);
-                PatKind::Vec(pats.collect(), None, hir::HirVec::new())
+                PatKind::Slice(pats.collect(), None, hir::HirVec::new())
             },
             _ => unreachable!()
         },
 
         ty::TyArray(_, len) => {
             assert_eq!(pats_len, len);
-            PatKind::Vec(pats.collect(), None, hir::HirVec::new())
+            PatKind::Slice(pats.collect(), None, hir::HirVec::new())
         }
 
         _ => {
@@ -713,7 +713,7 @@ fn is_useful<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>,
     };
 
     let max_slice_length = rows.iter().filter_map(|row| match row[0].0.node {
-        PatKind::Vec(ref before, _, ref after) => Some(before.len() + after.len()),
+        PatKind::Slice(ref before, _, ref after) => Some(before.len() + after.len()),
         _ => None
     }).max().map_or(0, |v| v + 1);
 
@@ -812,7 +812,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
             vec![ConstantValue(eval_const_expr(cx.tcx, &expr))],
         PatKind::Range(ref lo, ref hi) =>
             vec![ConstantRange(eval_const_expr(cx.tcx, &lo), eval_const_expr(cx.tcx, &hi))],
-        PatKind::Vec(ref before, ref slice, ref after) =>
+        PatKind::Slice(ref before, ref slice, ref after) =>
             match left_ty.sty {
                 ty::TyArray(..) => vec![Single],
                 ty::TySlice(_) if slice.is_some() => {
@@ -1001,7 +1001,7 @@ pub fn specialize<'a, 'b, 'tcx>(
             }
         }
 
-        PatKind::Vec(ref before, ref slice, ref after) => {
+        PatKind::Slice(ref before, ref slice, ref after) => {
             let pat_len = before.len() + after.len();
             match *constructor {
                 Single => {
index 4ae3c7d37db8dec202f82f0bf9f34cf2c3b49930..3bf936dc9960c26e206a5bcbc9e1320f98107008 100644 (file)
@@ -317,11 +317,11 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             PatKind::Struct(path.clone(), field_pats, false)
         }
 
-        hir::ExprVec(ref exprs) => {
+        hir::ExprArray(ref exprs) => {
             let pats = exprs.iter()
                             .map(|expr| const_expr_to_pat(tcx, &expr, pat_id, span))
                             .collect::<Result<_, _>>()?;
-            PatKind::Vec(pats, None, hir::HirVec::new())
+            PatKind::Slice(pats, None, hir::HirVec::new())
         }
 
         hir::ExprPath(_, ref path) => {
@@ -898,7 +898,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             Array(_, n) if idx >= n => {
                 signal!(e, IndexOutOfBounds { len: n, index: idx })
             }
-            Array(v, n) => if let hir::ExprVec(ref v) = tcx.map.expect_expr(v).node {
+            Array(v, n) => if let hir::ExprArray(ref v) = tcx.map.expect_expr(v).node {
                 assert_eq!(n as usize as u64, n);
                 eval_const_expr_partial(tcx, &v[idx as usize], ty_hint, fn_args)?
             } else {
@@ -925,7 +925,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             _ => signal!(e, IndexedNonVec),
         }
       }
-      hir::ExprVec(ref v) => Array(e.id, v.len() as u64),
+      hir::ExprArray(ref v) => Array(e.id, v.len() as u64),
       hir::ExprRepeat(_, ref n) => {
           let len_hint = ty_hint.checked_or(tcx.types.usize);
           Repeat(
index 5ac4512fe39004d72386822c36351e960b1d8800..492165e2f2a8e081290d8af025ea390352c5b330 100644 (file)
@@ -1075,7 +1075,7 @@ fn flush(&mut self) -> io::Result<()> {
     }
 
     let thread = cfg.spawn(move || {
-         io::set_panic(box err);
+         io::set_panic(Some(box err));
          f()
      });
 
@@ -1121,7 +1121,7 @@ fn exit_on_err() -> ! {
     // Panic so the process returns a failure code, but don't pollute the
     // output with some unnecessary panic messages, we've already
     // printed everything that we needed to.
-    io::set_panic(box io::sink());
+    io::set_panic(Some(box io::sink()));
     panic!();
 }
 
index 55fe5fc1e349a21aa69278692053a484b22781f7..d0ae83a9826c25fbe35b2447011c1da2ed9e419f 100644 (file)
@@ -207,7 +207,7 @@ enum SawExprComponent<'a> {
     SawExprAgain(Option<token::InternedString>),
 
     SawExprBox,
-    SawExprVec,
+    SawExprArray,
     SawExprCall,
     SawExprMethodCall,
     SawExprTup,
@@ -235,7 +235,7 @@ enum SawExprComponent<'a> {
 fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
     match *node {
         ExprBox(..)              => SawExprBox,
-        ExprVec(..)              => SawExprVec,
+        ExprArray(..)            => SawExprArray,
         ExprCall(..)             => SawExprCall,
         ExprMethodCall(..)       => SawExprMethodCall,
         ExprTup(..)              => SawExprTup,
index 3f551476e2b46b87a6529075e55bd2c6b124f5e5..5257575a94e8b1322a87ce3e0986adc1fa16afb7 100644 (file)
@@ -66,7 +66,8 @@ fn main() {
     let host = env::var("HOST").expect("HOST was not set");
     let is_crossed = target != host;
 
-    let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "systemz"];
+    let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "systemz",
+                               "jsbackend"];
 
     // FIXME: surely we don't need all these components, right? Stuff like mcjit
     //        or interpreter the compiler itself never uses.
index eb45d3d25c5c05f5ff71a713d57c039626cac426..3946b44ead5787c69b5e925359cef91f8aed5943 100644 (file)
@@ -434,6 +434,10 @@ fn init() { }
                  LLVMInitializeSystemZTargetMC,
                  LLVMInitializeSystemZAsmPrinter,
                  LLVMInitializeSystemZAsmParser);
+    init_target!(llvm_component = "jsbackend",
+                 LLVMInitializeJSBackendTargetInfo,
+                 LLVMInitializeJSBackendTarget,
+                 LLVMInitializeJSBackendTargetMC);
 }
 
 pub fn last_error() -> Option<String> {
index ca4fb77d95ad62dd8941a2641096df7747185e2d..4d18462848e5d84c6f1b5ea608b43fd3c6fb1f70 100644 (file)
@@ -1288,7 +1288,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
         let link_meta = self.link_meta;
         let is_rustc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeRustcMacro);
         let root = self.lazy(&CrateRoot {
-            rustc_version: RUSTC_VERSION.to_string(),
+            rustc_version: rustc_version(),
             name: link_meta.crate_name.clone(),
             triple: tcx.sess.opts.target_triple.clone(),
             hash: link_meta.crate_hash,
index fc94cec916aad146be7f830c77cc64040aa7912b..75242fc36db762bf592c4fc4ce2084049cb077cb 100644 (file)
 //! metadata::loader or metadata::creader for all the juicy details!
 
 use cstore::MetadataBlob;
-use schema::{METADATA_HEADER, RUSTC_VERSION};
+use schema::{METADATA_HEADER, rustc_version};
 
 use rustc::hir::svh::Svh;
 use rustc::session::Session;
@@ -382,7 +382,7 @@ pub fn report_load_errs(&mut self) -> ! {
         }
         if !self.rejected_via_version.is_empty() {
             err.help(&format!("please recompile that crate using this compiler ({})",
-                              RUSTC_VERSION));
+                              rustc_version()));
             let mismatches = self.rejected_via_version.iter();
             for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() {
                 err.note(&format!("crate `{}` path #{}: {} compiled by {:?}",
@@ -597,9 +597,10 @@ fn extract_one(&mut self, m: FnvHashMap<PathBuf, PathKind>, flavor: CrateFlavor,
 
     fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
         let root = metadata.get_root();
-        if root.rustc_version != RUSTC_VERSION {
+        let rustc_version = rustc_version();
+        if root.rustc_version != rustc_version {
             info!("Rejecting via version: expected {} got {}",
-                  RUSTC_VERSION, root.rustc_version);
+                  rustc_version, root.rustc_version);
             self.rejected_via_version.push(CrateMismatch {
                 path: libpath.to_path_buf(),
                 got: root.rustc_version
index 58e18bc709e3c41a5dd2cfdb1be6d7227fcbc202..1a46315e9cd7ac7a2da4395412568520b19c97ff 100644 (file)
 
 use std::marker::PhantomData;
 
-#[cfg(not(test))]
-pub const RUSTC_VERSION: &'static str = concat!("rustc ", env!("CFG_VERSION"));
-
-#[cfg(test)]
-pub const RUSTC_VERSION: &'static str = "rustc 0.0.0-unit-test";
+pub fn rustc_version() -> String {
+    format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
+}
 
 /// Metadata encoding version.
 /// NB: increment this if you change the format of metadata such that
index a40571c5d859784125c247ea19cf785b6e8d1622..2123235ddc1d887f7417d8f26e32c8aebe64ea0f 100644 (file)
@@ -160,7 +160,7 @@ fn expr_as_rvalue(&mut self,
                           .map(|f| unpack!(block = this.as_operand(block, f)))
                           .collect();
 
-                block.and(Rvalue::Aggregate(AggregateKind::Vec, fields))
+                block.and(Rvalue::Aggregate(AggregateKind::Array, fields))
             }
             ExprKind::Tuple { fields } => { // see (*) above
                 // first process the set of fields
index 6283ff2187ab8bbed00b8ff395d367627f26a409..2840538ae5b4f473feca3ec31e11bccb692b3cbd 100644 (file)
@@ -613,7 +613,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 value: value.to_ref(),
                 value_extents: cx.tcx.region_maps.node_extent(value.id)
             },
-        hir::ExprVec(ref fields) =>
+        hir::ExprArray(ref fields) =>
             ExprKind::Vec { fields: fields.to_ref() },
         hir::ExprTup(ref fields) =>
             ExprKind::Tuple { fields: fields.to_ref() },
index 7b8446b184fb3725f4fd8fc2170c25a23a9cbe62..8751b1dc03aabd7780d2baf08b2a0a3641529c68 100644 (file)
@@ -113,7 +113,7 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
                 PatternKind::Deref { subpattern: self.to_pattern(subpattern) }
             }
 
-            PatKind::Vec(ref prefix, ref slice, ref suffix) => {
+            PatKind::Slice(ref prefix, ref slice, ref suffix) => {
                 let ty = self.cx.tcx.node_id_to_type(pat.id);
                 match ty.sty {
                     ty::TyRef(_, mt) =>
index 5e92a057da38280a46c8ca1ef21353e1bad1ef64..2dcefcc12f6e5e3b3374773f561309f30c4ca9a7 100644 (file)
@@ -202,7 +202,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
 
     // Array lengths, i.e. [T; constant].
     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-        if let hir::TyFixedLengthVec(_, ref length) = ty.node {
+        if let hir::TyArray(_, ref length) = ty.node {
             self.build_const_integer(length);
         }
         intravisit::walk_ty(self, ty);
index f919e42b6bd7d38d6de6f483f002192ee80ae70f..1b86c84a057026f324769d04ee6405a3d06962a3 100644 (file)
@@ -602,7 +602,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
         hir::ExprIndex(..) |
         hir::ExprField(..) |
         hir::ExprTupField(..) |
-        hir::ExprVec(_) |
+        hir::ExprArray(_) |
         hir::ExprType(..) |
         hir::ExprTup(..) => {}
 
index 0694edd235777dee30e653cb40cbc7d9bdad0c3a..d1bfb7d786eb3192c5a58d2380bc34d0cc01a33c 100644 (file)
@@ -3534,7 +3534,7 @@ fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
         } else {
             // danger, shouldn't be ident?
             names.push(token::intern("<opaque>"));
-            collect_mod(names, module);
+            collect_mod(names, module.parent.unwrap());
         }
     }
     collect_mod(&mut names, module);
index b82c5629f9da1dcea0d5510caac0f30ce60aa64f..0a5b013c79ac21fbdc979244a6a11a98b8a922c7 100644 (file)
@@ -519,6 +519,7 @@ pub fn adjust_for_abi<'a, 'tcx>(&mut self,
             "powerpc64" => cabi_powerpc64::compute_abi_info(ccx, self),
             "s390x" => cabi_s390x::compute_abi_info(ccx, self),
             "asmjs" => cabi_asmjs::compute_abi_info(ccx, self),
+            "wasm32" => cabi_asmjs::compute_abi_info(ccx, self),
             a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a))
         }
 
index 0a668db06908090b8a7689380bdf37ffc5da243b..f0661e03bc8153f0f38a09a4dae47b1de386bbfd 100644 (file)
@@ -152,17 +152,17 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
     let mut hash_state = scx.symbol_hasher().borrow_mut();
     record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
         hash_state.reset();
-        let mut hasher = Sha256Hasher(&mut hash_state);
+        let hasher = Sha256Hasher(&mut hash_state);
+        let mut hasher = ty::util::TypeIdHasher::new(tcx, hasher);
 
         // the main symbol name is not necessarily unique; hash in the
         // compiler's internal def-path, guaranteeing each symbol has a
         // truly unique path
-        def_path.deterministic_hash_to(tcx, &mut hasher);
+        hasher.def_path(def_path);
 
         // Include the main item-type. Note that, in this case, the
         // assertions about `needs_subst` may not hold, but this item-type
         // ought to be the same for every reference anyway.
-        let mut hasher = ty::util::TypeIdHasher::new(tcx, hasher);
         assert!(!item_type.has_erasable_regions());
         hasher.visit_ty(item_type);
 
index c0e7af845ec4f5c4b9d71902410bf3df9e1e6aa7..76b63512bdbd02870f1de5db2d0e2ae8ee7bffed 100644 (file)
@@ -569,7 +569,7 @@ fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>,
                 }
 
                 match *kind {
-                    mir::AggregateKind::Vec => {
+                    mir::AggregateKind::Array => {
                         self.const_array(dest_ty, &fields)
                     }
                     mir::AggregateKind::Adt(..) |
index e28a4566e0ea6d01e9f503c0492bf0ffc6511889..568e44a95191d947ce48dc0700ad48e72b53a2a7 100644 (file)
@@ -1625,7 +1625,7 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
         }
 
         let result_ty = match ast_ty.node {
-            hir::TyVec(ref ty) => {
+            hir::TySlice(ref ty) => {
                 tcx.mk_slice(self.ast_ty_to_ty(rscope, &ty))
             }
             hir::TyObjectSum(ref ty, ref bounds) => {
@@ -1760,7 +1760,7 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
 
                 ty
             }
-            hir::TyFixedLengthVec(ref ty, ref e) => {
+            hir::TyArray(ref ty, ref e) => {
                 if let Ok(length) = eval_length(tcx.global_tcx(), &e, "array length") {
                     tcx.mk_array(self.ast_ty_to_ty(rscope, &ty), length)
                 } else {
index 5d6d21bb6f8c8bb41402c435990a9d58719c9cc0..99d1da77018ad26ecec59cdc6713fce19d4309e4 100644 (file)
@@ -227,7 +227,7 @@ pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
                     tcx.types.err
                 }
             }
-            PatKind::Vec(ref before, ref slice, ref after) => {
+            PatKind::Slice(ref before, ref slice, ref after) => {
                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
                 let (inner_ty, slice_ty) = match expected_ty.sty {
                     ty::TyArray(inner_ty, size) => {
index ab59fafb652099087028a0406a6202802c200523..e81bca3c171839b2e67e671abeedb34716d829ab 100644 (file)
@@ -312,13 +312,25 @@ fn instantiate_method_substs(&mut self,
 
         if num_supplied_types > 0 && num_supplied_types != num_method_types {
             if num_method_types == 0 {
-                span_err!(self.tcx.sess, self.span, E0035,
-                    "does not take type parameters");
+                struct_span_err!(self.tcx.sess, self.span, E0035,
+                                 "does not take type parameters")
+                    .span_label(self.span, &"called with unneeded type parameters")
+                    .emit();
             } else {
-                span_err!(self.tcx.sess, self.span, E0036,
+                struct_span_err!(self.tcx.sess, self.span, E0036,
                     "incorrect number of type parameters given for this method: \
                      expected {}, found {}",
-                    num_method_types, num_supplied_types);
+                    num_method_types, num_supplied_types)
+                    .span_label(self.span,
+                                &format!("Passed {} type argument{}, expected {}",
+                                         num_supplied_types,
+                                         if num_supplied_types != 1 {
+                                            "s"
+                                         } else {
+                                            ""
+                                         },
+                                         num_method_types))
+                    .emit();
             }
             supplied_method_types = vec![self.tcx.types.err; num_method_types];
         }
index ee00cb2f5a3e4797b8fdb4f8022880dcd59d321d..2ac2dab999bb0470d0ee7111a76a87d6b82ebd7a 100644 (file)
@@ -450,7 +450,7 @@ fn visit_item(&mut self, i: &'tcx hir::Item) {
 
     fn visit_ty(&mut self, t: &'tcx hir::Ty) {
         match t.node {
-            hir::TyFixedLengthVec(_, ref expr) => {
+            hir::TyArray(_, ref expr) => {
                 check_const_with_type(self.ccx, &expr, self.ccx.tcx.types.usize, expr.id);
             }
             _ => {}
@@ -626,7 +626,7 @@ fn visit_block(&mut self, b: &'gcx hir::Block) {
     // need to record the type for that node
     fn visit_ty(&mut self, t: &'gcx hir::Ty) {
         match t.node {
-            hir::TyFixedLengthVec(ref ty, ref count_expr) => {
+            hir::TyArray(ref ty, ref count_expr) => {
                 self.visit_ty(&ty);
                 self.fcx.check_expr_with_hint(&count_expr, self.fcx.tcx.types.usize);
             }
@@ -3590,7 +3590,7 @@ fn check_expr_kind(&self,
               self.check_method_call(expr, name, &args[..], &tps[..], expected, lvalue_pref)
           }
           hir::ExprCast(ref e, ref t) => {
-            if let hir::TyFixedLengthVec(_, ref count_expr) = t.node {
+            if let hir::TyArray(_, ref count_expr) = t.node {
                 self.check_expr_with_hint(&count_expr, tcx.types.usize);
             }
 
@@ -3623,7 +3623,7 @@ fn check_expr_kind(&self,
             self.check_expr_eq_type(&e, typ);
             typ
           }
-          hir::ExprVec(ref args) => {
+          hir::ExprArray(ref args) => {
             let uty = expected.to_option(self).and_then(|uty| {
                 match uty.sty {
                     ty::TyArray(ty, _) | ty::TySlice(ty) => Some(ty),
index 0b70d904c26549830c9a3326afb669ccfa736a93..8685f703a599c8888f7becf687f9091f53d364e8 100644 (file)
@@ -247,7 +247,7 @@ fn visit_local(&mut self, l: &hir::Local) {
 
     fn visit_ty(&mut self, t: &hir::Ty) {
         match t.node {
-            hir::TyFixedLengthVec(ref ty, ref count_expr) => {
+            hir::TyArray(ref ty, ref count_expr) => {
                 self.visit_ty(&ty);
                 write_ty_to_tcx(self.fcx.ccx, count_expr.id, self.tcx().types.usize);
             }
index e5d4d4a9dae2ccaaf83b754206204c4f66fd5407..cdd7bef2c7fb92c6325194f76f297044dee47dea 100644 (file)
@@ -1164,10 +1164,12 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         } else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) {
             Some(disr)
         } else {
-            span_err!(tcx.sess, v.span, E0370,
-                      "enum discriminant overflowed on value after {}; \
-                       set explicitly via {} = {} if that is desired outcome",
-                      prev_disr.unwrap(), v.node.name, wrapped_disr);
+            struct_span_err!(tcx.sess, v.span, E0370,
+                             "enum discriminant overflowed")
+                .span_label(v.span, &format!("overflowed on value after {}", prev_disr.unwrap()))
+                .note(&format!("explicitly set `{} = {}` if that is desired outcome",
+                               v.node.name, wrapped_disr))
+                .emit();
             None
         }.unwrap_or(wrapped_disr);
         prev_disr = Some(disr);
index 0ae059509bd1057a6ba16d3b4d5c1f1d9a7f9353..c1ee4e61c5c72b45bf8d827c6f4def8a2ea0f56e 100644 (file)
@@ -283,34 +283,34 @@ pub fn is_crate(&self) -> bool {
         }
     }
     pub fn is_mod(&self) -> bool {
-        ItemType::from(self) == ItemType::Module
+        self.type_() == ItemType::Module
     }
     pub fn is_trait(&self) -> bool {
-        ItemType::from(self) == ItemType::Trait
+        self.type_() == ItemType::Trait
     }
     pub fn is_struct(&self) -> bool {
-        ItemType::from(self) == ItemType::Struct
+        self.type_() == ItemType::Struct
     }
     pub fn is_enum(&self) -> bool {
-        ItemType::from(self) == ItemType::Module
+        self.type_() == ItemType::Module
     }
     pub fn is_fn(&self) -> bool {
-        ItemType::from(self) == ItemType::Function
+        self.type_() == ItemType::Function
     }
     pub fn is_associated_type(&self) -> bool {
-        ItemType::from(self) == ItemType::AssociatedType
+        self.type_() == ItemType::AssociatedType
     }
     pub fn is_associated_const(&self) -> bool {
-        ItemType::from(self) == ItemType::AssociatedConst
+        self.type_() == ItemType::AssociatedConst
     }
     pub fn is_method(&self) -> bool {
-        ItemType::from(self) == ItemType::Method
+        self.type_() == ItemType::Method
     }
     pub fn is_ty_method(&self) -> bool {
-        ItemType::from(self) == ItemType::TyMethod
+        self.type_() == ItemType::TyMethod
     }
     pub fn is_primitive(&self) -> bool {
-        ItemType::from(self) == ItemType::Primitive
+        self.type_() == ItemType::Primitive
     }
     pub fn is_stripped(&self) -> bool {
         match self.inner { StrippedItem(..) => true, _ => false }
@@ -342,6 +342,11 @@ pub fn stability_class(&self) -> String {
     pub fn stable_since(&self) -> Option<&str> {
         self.stability.as_ref().map(|s| &s.since[..])
     }
+
+    /// Returns a documentation-level item type from the item.
+    pub fn type_(&self) -> ItemType {
+        ItemType::from(self)
+    }
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -1646,8 +1651,8 @@ fn clean(&self, cx: &DocContext) -> Type {
             TyRptr(ref l, ref m) =>
                 BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
                              type_: box m.ty.clean(cx)},
-            TyVec(ref ty) => Vector(box ty.clean(cx)),
-            TyFixedLengthVec(ref ty, ref e) => {
+            TySlice(ref ty) => Vector(box ty.clean(cx)),
+            TyArray(ref ty, ref e) => {
                 let n = if let Some(tcx) = cx.tcx_opt() {
                     use rustc_const_math::{ConstInt, ConstUsize};
                     use rustc_const_eval::eval_const_expr;
@@ -2699,7 +2704,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
         },
         PatKind::Range(..) => panic!("tried to get argument name from PatKind::Range, \
                               which is not allowed in function arguments"),
-        PatKind::Vec(ref begin, ref mid, ref end) => {
+        PatKind::Slice(ref begin, ref mid, ref end) => {
             let begin = begin.iter().map(|p| name_from_pat(&**p));
             let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter();
             let end = end.iter().map(|p| name_from_pat(&**p));
index 9c80f6e98c39c31d494dc2e940311c667a2f76fd..46461226381a3e04b5fb314f94fdc9a92d7d45ea 100644 (file)
@@ -89,9 +89,6 @@ pub struct Context {
     /// Current hierarchy of components leading down to what's currently being
     /// rendered
     pub current: Vec<String>,
-    /// String representation of how to get back to the root path of the 'doc/'
-    /// folder in terms of a relative URL.
-    pub root_path: String,
     /// The current destination folder of where HTML artifacts should be placed.
     /// This changes as the context descends into the module hierarchy.
     pub dst: PathBuf,
@@ -496,7 +493,6 @@ pub fn run(mut krate: clean::Crate,
     krate = render_sources(&dst, &mut scx, krate)?;
     let cx = Context {
         current: Vec::new(),
-        root_path: String::new(),
         dst: dst,
         render_redirect_pages: false,
         shared: Arc::new(scx),
@@ -591,7 +587,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     for &(did, ref item) in orphan_impl_items {
         if let Some(&(ref fqp, _)) = paths.get(&did) {
             search_index.push(IndexItem {
-                ty: item_type(item),
+                ty: item.type_(),
                 name: item.name.clone().unwrap(),
                 path: fqp[..fqp.len() - 1].join("::"),
                 desc: Escape(&shorter(item.doc_value())).to_string(),
@@ -835,11 +831,6 @@ fn mkdir(path: &Path) -> io::Result<()> {
     }
 }
 
-/// Returns a documentation-level item type from the item.
-fn item_type(item: &clean::Item) -> ItemType {
-    ItemType::from(item)
-}
-
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
 /// things like ".." to components which preserve the "top down" hierarchy of a
 /// static HTML tree. Each component in the cleaned path will be passed as an
@@ -1075,7 +1066,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                     // inserted later on when serializing the search-index.
                     if item.def_id.index != CRATE_DEF_INDEX {
                         self.search_index.push(IndexItem {
-                            ty: item_type(&item),
+                            ty: item.type_(),
                             name: s.to_string(),
                             path: path.join("::").to_string(),
                             desc: Escape(&shorter(item.doc_value())).to_string(),
@@ -1122,7 +1113,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                     self.access_levels.is_public(item.def_id)
                 {
                     self.paths.insert(item.def_id,
-                                      (self.stack.clone(), item_type(&item)));
+                                      (self.stack.clone(), item.type_()));
                 }
             }
             // link variants to their parent enum because pages aren't emitted
@@ -1135,7 +1126,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
 
             clean::PrimitiveItem(..) if item.visibility.is_some() => {
                 self.paths.insert(item.def_id, (self.stack.clone(),
-                                                item_type(&item)));
+                                                item.type_()));
             }
 
             _ => {}
@@ -1230,6 +1221,12 @@ fn generics(&mut self, generics: &clean::Generics) {
 }
 
 impl Context {
+    /// String representation of how to get back to the root path of the 'doc/'
+    /// folder in terms of a relative URL.
+    fn root_path(&self) -> String {
+        repeat("../").take(self.current.len()).collect::<String>()
+    }
+
     /// Recurse in the directory structure and change the "root path" to make
     /// sure it always points to the top (relatively)
     fn recurse<T, F>(&mut self, s: String, f: F) -> T where
@@ -1240,7 +1237,6 @@ fn recurse<T, F>(&mut self, s: String, f: F) -> T where
         }
         let prev = self.dst.clone();
         self.dst.push(&s);
-        self.root_path.push_str("../");
         self.current.push(s);
 
         info!("Recursing into {}", self.dst.display());
@@ -1251,8 +1247,6 @@ fn recurse<T, F>(&mut self, s: String, f: F) -> T where
 
         // Go back to where we were at
         self.dst = prev;
-        let len = self.root_path.len();
-        self.root_path.truncate(len - 3);
         self.current.pop().unwrap();
 
         return ret;
@@ -1304,7 +1298,7 @@ fn render_item(&self,
             title.push_str(it.name.as_ref().unwrap());
         }
         title.push_str(" - Rust");
-        let tyname = item_type(it).css_class();
+        let tyname = it.type_().css_class();
         let desc = if it.is_crate() {
             format!("API documentation for the Rust `{}` crate.",
                     self.shared.layout.krate)
@@ -1315,7 +1309,7 @@ fn render_item(&self,
         let keywords = make_item_keywords(it);
         let page = layout::Page {
             css_class: tyname,
-            root_path: &self.root_path,
+            root_path: &self.root_path(),
             title: &title,
             description: &desc,
             keywords: &keywords,
@@ -1329,8 +1323,7 @@ fn render_item(&self,
                            &Item{ cx: self, item: it },
                            self.shared.css_file_extension.is_some())?;
         } else {
-            let mut url = repeat("../").take(self.current.len())
-                                       .collect::<String>();
+            let mut url = self.root_path();
             if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
                 for name in &names[..names.len() - 1] {
                     url.push_str(name);
@@ -1407,7 +1400,7 @@ fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
             // buf will be empty if the item is stripped and there is no redirect for it
             if !buf.is_empty() {
                 let name = item.name.as_ref().unwrap();
-                let item_type = item_type(&item);
+                let item_type = item.type_();
                 let file_name = &item_path(item_type, name);
                 let joint_dst = self.dst.join(file_name);
                 try_err!(fs::create_dir_all(&self.dst), &self.dst);
@@ -1444,7 +1437,7 @@ fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc
         for item in &m.items {
             if maybe_ignore_item(item) { continue }
 
-            let short = item_type(item).css_class();
+            let short = item.type_().css_class();
             let myname = match item.name {
                 None => continue,
                 Some(ref s) => s.to_string(),
@@ -1492,7 +1485,7 @@ fn href(&self) -> Option<String> {
             }).map(|l| &l.1);
             let root = match root {
                 Some(&Remote(ref s)) => s.to_string(),
-                Some(&Local) => self.cx.root_path.clone(),
+                Some(&Local) => self.cx.root_path(),
                 None | Some(&Unknown) => return None,
             };
             Some(format!("{root}/{krate}/macro.{name}.html?gotomacrosrc=1",
@@ -1507,7 +1500,7 @@ fn href(&self) -> Option<String> {
             let path = PathBuf::from(&self.item.source.filename);
             self.cx.shared.local_sources.get(&path).map(|path| {
                 format!("{root}src/{krate}/{path}#{href}",
-                        root = self.cx.root_path,
+                        root = self.cx.root_path(),
                         krate = self.cx.shared.layout.krate,
                         path = path,
                         href = href)
@@ -1531,7 +1524,7 @@ fn href(&self) -> Option<String> {
             };
             let mut path = match cache.extern_locations.get(&self.item.def_id.krate) {
                 Some(&(_, Remote(ref s))) => s.to_string(),
-                Some(&(_, Local)) => self.cx.root_path.clone(),
+                Some(&(_, Local)) => self.cx.root_path(),
                 Some(&(_, Unknown)) => return None,
                 None => return None,
             };
@@ -1541,7 +1534,7 @@ fn href(&self) -> Option<String> {
             }
             Some(format!("{path}{file}?gotosrc={goto}",
                          path = path,
-                         file = item_path(item_type(self.item), external_path.last().unwrap()),
+                         file = item_path(self.item.type_(), external_path.last().unwrap()),
                          goto = self.item.def_id.index.as_usize()))
         }
     }
@@ -1586,7 +1579,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             }
         }
         write!(fmt, "<a class='{}' href=''>{}</a>",
-               item_type(self.item), self.item.name.as_ref().unwrap())?;
+               self.item.type_(), self.item.name.as_ref().unwrap())?;
 
         write!(fmt, "</span>")?; // in-band
         write!(fmt, "<span class='out-of-band'>")?;
@@ -1739,8 +1732,8 @@ fn reorder(ty: ItemType) -> u8 {
     }
 
     fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering {
-        let ty1 = item_type(i1);
-        let ty2 = item_type(i2);
+        let ty1 = i1.type_();
+        let ty2 = i2.type_();
         if ty1 != ty2 {
             return (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
         }
@@ -1764,7 +1757,7 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
             continue;
         }
 
-        let myty = Some(item_type(myitem));
+        let myty = Some(myitem.type_());
         if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) {
             // Put `extern crate` and `use` re-exports in the same section.
             curty = myty;
@@ -1851,9 +1844,9 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
                        name = *myitem.name.as_ref().unwrap(),
                        stab_docs = stab_docs,
                        docs = shorter(Some(&Markdown(doc_value).to_string())),
-                       class = item_type(myitem),
+                       class = myitem.type_(),
                        stab = myitem.stability_class(),
-                       href = item_path(item_type(myitem), myitem.name.as_ref().unwrap()),
+                       href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
                        title = full_path(cx, myitem))?;
             }
         }
@@ -2059,7 +2052,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::Item)
                   -> fmt::Result {
         let name = m.name.as_ref().unwrap();
-        let item_type = item_type(m);
+        let item_type = m.type_();
         let id = derive_id(format!("{}.{}", item_type, name));
         let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
         write!(w, "<h3 id='{id}' class='method stab {stab}'>\
@@ -2145,7 +2138,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
                let (ref path, _) = cache.external_paths[&it.def_id];
                path[..path.len() - 1].join("/")
            },
-           ty = item_type(it).css_class(),
+           ty = it.type_().css_class(),
            name = *it.name.as_ref().unwrap())?;
     Ok(())
 }
@@ -2154,7 +2147,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink) -> String {
     use html::item_type::ItemType::*;
 
     let name = it.name.as_ref().unwrap();
-    let ty = match item_type(it) {
+    let ty = match it.type_() {
         Typedef | AssociatedType => AssociatedType,
         s@_ => s,
     };
@@ -2232,7 +2225,7 @@ fn method(w: &mut fmt::Formatter,
               link: AssocItemLink)
               -> fmt::Result {
         let name = meth.name.as_ref().unwrap();
-        let anchor = format!("#{}.{}", item_type(meth), name);
+        let anchor = format!("#{}.{}", meth.type_(), name);
         let href = match link {
             AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
             AssocItemLink::Anchor(None) => anchor,
@@ -2740,7 +2733,7 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                      link: AssocItemLink, render_mode: RenderMode,
                      is_default_item: bool, outer_version: Option<&str>,
                      trait_: Option<&clean::Trait>) -> fmt::Result {
-        let item_type = item_type(item);
+        let item_type = item.type_();
         let name = item.name.as_ref().unwrap();
 
         let render_method_item: bool = match render_mode {
@@ -2918,7 +2911,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                 write!(fmt, "::<wbr>")?;
             }
             write!(fmt, "<a href='{}index.html'>{}</a>",
-                   &cx.root_path[..(cx.current.len() - i - 1) * 3],
+                   &cx.root_path()[..(cx.current.len() - i - 1) * 3],
                    *name)?;
         }
         write!(fmt, "</p>")?;
@@ -2932,7 +2925,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                    relpath: '{path}'\
                 }};</script>",
                name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
-               ty = item_type(it).css_class(),
+               ty = it.type_().css_class(),
                path = relpath)?;
         if parentlen == 0 {
             // there is no sidebar-items.js beyond the crate root path
index 1ab86cf7e8920fc4fe9cef6db4aedab43cd769bc..02f0916de0ef3a970e0cd95c11ba4f0823912912 100644 (file)
@@ -228,7 +228,7 @@ fn drop(&mut self) {
     let codemap = Rc::new(CodeMap::new());
     let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()),
                                                       Some(codemap.clone()));
-    let old = io::set_panic(box Sink(data.clone()));
+    let old = io::set_panic(Some(box Sink(data.clone())));
     let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
 
     // Compile the code
index 5171fbdf03e80702f3b44fda48151af5ba5dba1d..76a2f93c162e7a3f9579fd69388dbc450aa9a109 100644 (file)
@@ -892,7 +892,18 @@ mod os {
     pub const EXE_EXTENSION: &'static str = "pexe";
 }
 
-#[cfg(target_os = "emscripten")]
+#[cfg(all(target_os = "emscripten", target_arch = "asmjs"))]
+mod os {
+    pub const FAMILY: &'static str = "unix";
+    pub const OS: &'static str = "emscripten";
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".so";
+    pub const DLL_EXTENSION: &'static str = "so";
+    pub const EXE_SUFFIX: &'static str = ".js";
+    pub const EXE_EXTENSION: &'static str = "js";
+}
+
+#[cfg(all(target_os = "emscripten", target_arch = "wasm32"))]
 mod os {
     pub const FAMILY: &'static str = "unix";
     pub const OS: &'static str = "emscripten";
@@ -969,6 +980,11 @@ mod arch {
     pub const ARCH: &'static str = "asmjs";
 }
 
+#[cfg(target_arch = "wasm32")]
+mod arch {
+    pub const ARCH: &'static str = "wasm32";
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -1017,6 +1033,7 @@ fn test_set_var_overwrite() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_var_big() {
         let mut s = "".to_string();
         let mut i = 0;
@@ -1030,6 +1047,7 @@ fn test_var_big() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_self_exe_path() {
         let path = current_exe();
         assert!(path.is_ok());
@@ -1040,6 +1058,7 @@ fn test_self_exe_path() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_env_set_get_huge() {
         let n = make_rand_name();
         let s = repeat("x").take(10000).collect::<String>();
index 576198564dbd43f7393335460a51c07d06c74195..2f2969b110db17a7687b81802ce6409013526277 100644 (file)
@@ -1686,7 +1686,7 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use io::prelude::*;
 
index 4ff8c6ac128bd9872fdc8b546914d2327cc252be..21a0cc1fb3b13e0028014fc916973a9f06ef7775 100644 (file)
@@ -1107,6 +1107,7 @@ fn flush(&mut self) -> io::Result<()> {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn panic_in_write_doesnt_flush_in_drop() {
         static WRITES: AtomicUsize = AtomicUsize::new(0);
 
index 0de02cbf19c9f4f952339a67ede5f9a79ef51b0f..3becc0a0c9ee17ca1886823e0ad87c0cb2c02ce0 100644 (file)
@@ -1264,15 +1264,13 @@ pub trait BufRead: Read {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
-    /// Read all bytes into `buf` until the delimiter `byte` is reached.
+    /// Read all bytes into `buf` until the delimiter `byte` or EOF is reached.
     ///
     /// This function will read bytes from the underlying stream until the
     /// delimiter or EOF is found. Once found, all bytes up to, and including,
     /// the delimiter (if found) will be appended to `buf`.
     ///
-    /// If this reader is currently at EOF then this function will not modify
-    /// `buf` and will return `Ok(n)` where `n` is the number of bytes which
-    /// were read.
+    /// If successful, this function will return the total number of bytes read.
     ///
     /// # Errors
     ///
@@ -1315,9 +1313,7 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
     /// up to, and including, the delimiter (if found) will be appended to
     /// `buf`.
     ///
-    /// If this reader is currently at EOF then this function will not modify
-    /// `buf` and will return `Ok(n)` where `n` is the number of bytes which
-    /// were read.
+    /// If successful, this function will return the total number of bytes read.
     ///
     /// # Errors
     ///
@@ -1761,6 +1757,7 @@ mod tests {
     use super::repeat;
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn read_until() {
         let mut buf = Cursor::new(&b"12"[..]);
         let mut v = Vec::new();
@@ -1971,6 +1968,7 @@ fn chain_zero_length_read_is_not_eof() {
     }
 
     #[bench]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn bench_read_to_end(b: &mut test::Bencher) {
         b.iter(|| {
             let mut lr = repeat(1).take(10000000);
index 9a782e95f6e5f994fd2cabe77cd59512a99ef90f..6421595a009a7124e5635abf580f271b111c5719 100644 (file)
@@ -593,11 +593,11 @@ fn flush(&mut self) -> io::Result<()> {
                      with a more general mechanism",
            issue = "0")]
 #[doc(hidden)]
-pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
+pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
     use panicking::LOCAL_STDERR;
     use mem;
     LOCAL_STDERR.with(move |slot| {
-        mem::replace(&mut *slot.borrow_mut(), Some(sink))
+        mem::replace(&mut *slot.borrow_mut(), sink)
     }).and_then(|mut s| {
         let _ = s.flush();
         Some(s)
@@ -617,10 +617,10 @@ pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
                      with a more general mechanism",
            issue = "0")]
 #[doc(hidden)]
-pub fn set_print(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
+pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
     use mem;
     LOCAL_STDOUT.with(move |slot| {
-        mem::replace(&mut *slot.borrow_mut(), Some(sink))
+        mem::replace(&mut *slot.borrow_mut(), sink)
     }).and_then(|mut s| {
         let _ = s.flush();
         Some(s)
@@ -668,6 +668,7 @@ mod tests {
     use super::*;
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn panic_doesnt_poison() {
         thread::spawn(|| {
             let _a = stdin();
index d0b59b42c1798a73a2ca56e75d553849ea5a9672..58daa7dbf8dc4d843b9b5e49f2da0f860d0e85f8 100644 (file)
@@ -519,7 +519,7 @@ fn to_socket_addrs(&self) -> io::Result<T::Iter> {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use net::*;
     use net::test::{tsa, sa6, sa4};
index 05ef559422f33187707e1894c56eef67800945cf..ba2cd70e0d7776a77f0b553b2006eeb95c38d850 100644 (file)
@@ -669,7 +669,7 @@ fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
 }
 
 // Tests for this module
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use net::*;
     use net::Ipv6MulticastScope::*;
index ad2fe3c1c0dbc8874e093328a1c530d6bec47aab..7dd0e30df0368cf5abd3b3dd42facc610096ddf2 100644 (file)
@@ -31,7 +31,8 @@
 mod tcp;
 mod udp;
 mod parser;
-#[cfg(test)] mod test;
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod test;
 
 /// Possible values which can be passed to the [`shutdown`] method of
 /// [`TcpStream`].
index 3c5f07c3e33a6db25ef7fd9f033d9f3825d080be..0e7c5b06713fb31a58d3977a85f7f4f1aa5e27ac 100644 (file)
@@ -428,7 +428,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use io::ErrorKind;
     use io::prelude::*;
index 781f026c12c7795e1b2c82fae0506c5b40d8b566..c03ac496adbb27b6f9c4ecef20e412a7f833764e 100644 (file)
@@ -353,7 +353,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use io::ErrorKind;
     use net::*;
index 1c19e58818d743e5fb67c2da76c45e8c2dbf48e4..e6a95bc831ffbafdbea5df3a14e5610d2c8cb32f 100644 (file)
@@ -34,7 +34,8 @@
           target_arch = "le32",
           target_arch = "powerpc",
           target_arch = "arm",
-          target_arch = "asmjs"))]
+          target_arch = "asmjs",
+          target_arch = "wasm32"))]
 mod arch {
     use os::raw::{c_long, c_short, c_uint};
 
index f0c4443070074aa3318f11605b11ba8abebf8b97..9d21a76e81b9e41f4e39ebe1af7fba669e002aa2 100644 (file)
@@ -8,7 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Working with processes.
+//! A module for working with processes.
+//!
+//! # Examples
+//!
+//! Basic usage where we try to execute the `cat` shell command:
+//!
+//! ```should_panic
+//! use std::process::Command;
+//!
+//! let mut child = Command::new("/bin/cat")
+//!                         .arg("file.txt")
+//!                         .spawn()
+//!                         .expect("failed to execute child");
+//!
+//! let ecode = child.wait()
+//!                  .expect("failed to wait on child");
+//!
+//! assert!(ecode.success());
+//! ```
 
 #![stable(feature = "process", since = "1.0.0")]
 
@@ -807,7 +825,7 @@ pub fn exit(code: i32) -> ! {
     ::sys::os::exit(code)
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use io::prelude::*;
 
index 3f14fcd239f1d0ceb2d6d36f32da74a3a845c345..69cd37651d5c28bde1bc9d5427975abea94e0133 100644 (file)
@@ -242,6 +242,7 @@ fn test_os_rng() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_os_rng_tasks() {
 
         let mut txs = vec!();
index ac0f400379e3cabf3504a10b496426774e2c0659..f46eab684846384a9b5245657d11f20bd450d867 100644 (file)
@@ -118,6 +118,7 @@ mod tests {
     use thread;
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_barrier() {
         const N: usize = 10;
 
index 3db8b05b954c3dacf4b157a8edc73f9d83118613..a983ae716a4816d387c75659c4dedafc3a5007e3 100644 (file)
@@ -270,6 +270,7 @@ fn smoke() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn notify_one() {
         let m = Arc::new(Mutex::new(()));
         let m2 = m.clone();
@@ -286,6 +287,7 @@ fn notify_one() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn notify_all() {
         const N: usize = 10;
 
@@ -322,6 +324,7 @@ fn notify_all() {
     }
 
     #[test]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn wait_timeout_ms() {
         let m = Arc::new(Mutex::new(()));
         let m2 = m.clone();
@@ -343,6 +346,7 @@ fn wait_timeout_ms() {
 
     #[test]
     #[should_panic]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn two_mutexes() {
         let m = Arc::new(Mutex::new(()));
         let m2 = m.clone();
index 3d9f81413dc734202b1e8a6df174ed35703b2d2b..d9c14ef2f771eb83a81cdb8ea9130704449d66d9 100644 (file)
@@ -1268,7 +1268,7 @@ fn cause(&self) -> Option<&error::Error> {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use env;
     use super::*;
@@ -1942,7 +1942,7 @@ fn destroy_upgraded_shared_port_when_sender_still_active() {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod sync_tests {
     use env;
     use thread;
index d926043fbbcd074e37fae9807f07b6a34cbfcce8..8d80f942ff75cb9f50c29919c75d7beaf6a21466 100644 (file)
@@ -146,7 +146,7 @@ fn drop(&mut self) {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use sync::mpsc::channel;
     use super::{Queue, Data, Empty, Inconsistent};
index 51b08bd75c4bc3475548171cf9dd1ec018619629..91896e1ab85dca7ccadbfb4f3d980949a4330ec5 100644 (file)
@@ -366,7 +366,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 #[allow(unused_imports)]
 mod tests {
     use thread;
index 724d7b1be730d59953620950ffa5ca20f55b5172..5858e4b6ddb1f2ab35312aaa4a5406baa84ca29c 100644 (file)
@@ -231,7 +231,7 @@ fn drop(&mut self) {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use sync::Arc;
     use super::Queue;
index 098a3e44258c77f2d116826b5dffe71560d355e5..812724c7a167eaf13e61801d079dd421222c9315 100644 (file)
@@ -352,7 +352,7 @@ pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Fla
     &guard.__lock.poison
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use sync::mpsc::channel;
     use sync::{Arc, Mutex, Condvar};
index 86d2986959c999abee5e10c3761f16f4fa0253fc..ad9d0b375442200be9ecf0cf59fb04d64dcfdd44 100644 (file)
@@ -367,7 +367,7 @@ pub fn poisoned(&self) -> bool {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use panic;
     use sync::mpsc::channel;
index 7f053c6704b56dffb09b5b32bf135fbc07345ef9..48ecae185f95c37e9e9a54a3e24c121587bb5fcc 100644 (file)
@@ -380,7 +380,7 @@ fn drop(&mut self) {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     #![allow(deprecated)] // rand
 
index 3cd70eddb858c1d0f8566855ff2fb0aca5fa478c..47cec4ef5c2762a7c6e2601e28f88c84bb728974 100644 (file)
@@ -50,7 +50,7 @@ pub unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> io::
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 pub mod test {
     use path::{Path, PathBuf};
     use env;
@@ -165,6 +165,7 @@ fn read_to_end_uninit_good() {
     }
 
     #[bench]
+    #[cfg_attr(target_os = "emscripten", ignore)]
     fn bench_uninitialized(b: &mut ::test::Bencher) {
         b.iter(|| {
             let mut lr = repeat(1).take(10000000);
index 18280e497db1d949092cb1f6697909f1762e978f..2599bb660e813de607551694d513973217fedef4 100644 (file)
               target_os = "solaris", target_os = "haiku")))]
 use sys::net::netc::IPV6_DROP_MEMBERSHIP;
 
+#[cfg(target_os = "linux")]
+use libc::MSG_NOSIGNAL;
+#[cfg(not(target_os = "linux"))]
+const MSG_NOSIGNAL: c_int = 0x0; // unused dummy value
+
 ////////////////////////////////////////////////////////////////////////////////
 // sockaddr and misc bindings
 ////////////////////////////////////////////////////////////////////////////////
@@ -225,7 +230,7 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
             c::send(*self.inner.as_inner(),
                     buf.as_ptr() as *const c_void,
                     len,
-                    0)
+                    MSG_NOSIGNAL)
         })?;
         Ok(ret as usize)
     }
@@ -449,7 +454,7 @@ pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
         let ret = cvt(unsafe {
             c::sendto(*self.inner.as_inner(),
                       buf.as_ptr() as *const c_void, len,
-                      0, dstp, dstlen)
+                      MSG_NOSIGNAL, dstp, dstlen)
         })?;
         Ok(ret as usize)
     }
@@ -573,7 +578,7 @@ pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
             c::send(*self.inner.as_inner(),
                     buf.as_ptr() as *const c_void,
                     len,
-                    0)
+                    MSG_NOSIGNAL)
         })?;
         Ok(ret as usize)
     }
index cbdeaad7f6bd3acfbff16c2cb7fa25ab688f904a..4d0407ccf6c8903bb20eee0059b492319a94d81f 100644 (file)
@@ -156,7 +156,7 @@ fn drop(&mut self) {
 }
 
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
     use cell::RefCell;
index 3f93fce1935611f236f611d3eb5ed9652617d851..622fd4b85a59afe2a9fedad389c4d93443374a4e 100644 (file)
 use sys::net::Socket;
 use sys_common::{AsInner, FromInner, IntoInner};
 
+#[cfg(target_os = "linux")]
+use libc::MSG_NOSIGNAL;
+#[cfg(not(target_os = "linux"))]
+const MSG_NOSIGNAL: libc::c_int = 0x0; // unused dummy value
+
 fn sun_path_offset() -> usize {
     unsafe {
         // Work with an actual instance of the type since using a null pointer is UB
@@ -690,7 +695,7 @@ fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
                 let count = cvt(libc::sendto(*d.0.as_inner(),
                                              buf.as_ptr() as *const _,
                                              buf.len(),
-                                             0,
+                                             MSG_NOSIGNAL,
                                              &addr as *const _ as *const _,
                                              len))?;
                 Ok(count as usize)
@@ -786,7 +791,7 @@ fn into_raw_fd(self) -> RawFd {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod test {
     use thread;
     use io;
index ec7ccdf5894fd01b17568bc7e314f4179ad79453..ad287bbec3889b276c5292c7fa6efa082600b472 100644 (file)
 #[cfg(not(target_os = "linux"))]
 const SOCK_CLOEXEC: c_int = 0;
 
+// Another conditional contant for name resolution: Macos et iOS use
+// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
+// Other platforms do otherwise.
+#[cfg(target_vendor = "apple")]
+use libc::SO_NOSIGPIPE;
+#[cfg(not(target_vendor = "apple"))]
+const SO_NOSIGPIPE: c_int = 0;
+
 pub struct Socket(FileDesc);
 
 pub fn init() {}
@@ -81,7 +89,11 @@ pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
             let fd = cvt(libc::socket(fam, ty, 0))?;
             let fd = FileDesc::new(fd);
             fd.set_cloexec()?;
-            Ok(Socket(fd))
+            let socket = Socket(fd);
+            if cfg!(target_vendor = "apple") {
+                setsockopt(&socket, libc::SOL_SOCKET, SO_NOSIGPIPE, 1)?;
+            }
+            Ok(socket)
         }
     }
 
index 50014f51f6cf46420fbaaa2a3e2e68db15933f3e..dafc11d9cc8e9c7b01b01f1aeb0968d1254b9a3c 100644 (file)
@@ -369,7 +369,7 @@ macro_rules! t {
         }
 
         // NaCl has no signal support.
-        if cfg!(not(target_os = "nacl")) {
+        if cfg!(not(any(target_os = "nacl", target_os = "emscripten"))) {
             // Reset signal handling so the child process starts in a
             // standardized state. libstd ignores SIGPIPE, and signal-handling
             // libraries often set a mask. Child processes inherit ignored
@@ -589,7 +589,7 @@ pub fn wait(&mut self) -> io::Result<ExitStatus> {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use super::*;
 
index 980ef01f549c36b9d10f0a1a49d738f8035c8a7d..1e879117f73abf2e185c0d7b57a05ad38aaed1f3 100644 (file)
@@ -29,6 +29,20 @@ pub struct Thread {
 unsafe impl Send for Thread {}
 unsafe impl Sync for Thread {}
 
+// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc,
+// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
+#[cfg(not(target_os = "emscripten"))]
+unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
+                                    stack_size: libc::size_t) -> libc::c_int {
+    libc::pthread_attr_setstacksize(attr, stack_size)
+}
+
+#[cfg(target_os = "emscripten")]
+unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
+                                    _stack_size: libc::size_t) -> libc::c_int {
+    panic!()
+}
+
 impl Thread {
     pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
                           -> io::Result<Thread> {
@@ -38,8 +52,8 @@ pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
 
         let stack_size = cmp::max(stack, min_stack_size(&attr));
-        match libc::pthread_attr_setstacksize(&mut attr,
-                                              stack_size as libc::size_t) {
+        match pthread_attr_setstacksize(&mut attr,
+                                        stack_size as libc::size_t) {
             0 => {}
             n => {
                 assert_eq!(n, libc::EINVAL);
index c44dee49f14a69373eed7cbcf6952358b701f8e5..a333a7d967d240fa11f757543fe50f068c529cad 100644 (file)
@@ -524,7 +524,7 @@ pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
     }
 }
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use sync::mpsc::{channel, Sender};
     use cell::{Cell, UnsafeCell};
index d8e021bb04ff9d9aeaead09365b762e20c7401cf..901ff98fcb3c5fa51e23b52a83e42042cbb9d0ca 100644 (file)
 //!
 //! [`Cell`]: ../cell/struct.Cell.html
 //! [`RefCell`]: ../cell/struct.RefCell.html
-//! [`thread_local!`]: ../macro.thread_local!.html
+//! [`thread_local!`]: ../macro.thread_local.html
 //! [`with`]: struct.LocalKey.html#method.with
 
 #![stable(feature = "rust1", since = "1.0.0")]
@@ -741,7 +741,7 @@ fn _assert_both<T: Send + Sync>() {}
 // Tests
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(test)]
+#[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use any::Any;
     use sync::mpsc::{channel, Sender};
index 154f603c84f162f591c7fd75b8b8541676ca6024..6854f1e14fa137e3f3fa2ef99d98705b3bb5d271 100644 (file)
 pub struct SystemTime(time::SystemTime);
 
 /// An error returned from the `duration_since` method on `SystemTime`,
-/// used to learn about why how far in the opposite direction a timestamp lies.
+/// used to learn how far in the opposite direction a system time lies.
 #[derive(Clone, Debug)]
 #[stable(feature = "time2", since = "1.8.0")]
 pub struct SystemTimeError(Duration);
index c18b36161dfcf3a190d3c3e4b71324912d5828d8..fcf2d32ded960aab2c61ccf47baf3ce785a8f91d 100644 (file)
@@ -121,6 +121,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// A lifetime definition, e.g. `'a: 'b+'c+'d`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct LifetimeDef {
+    pub attrs: ThinVec<Attribute>,
     pub lifetime: Lifetime,
     pub bounds: Vec<Lifetime>
 }
@@ -370,6 +371,7 @@ pub enum TraitBoundModifier {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct TyParam {
+    pub attrs: ThinVec<Attribute>,
     pub ident: Ident,
     pub id: NodeId,
     pub bounds: TyParamBounds,
@@ -593,7 +595,7 @@ pub fn walk<F>(&self, it: &mut F) -> bool
             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
                 s.walk(it)
             }
-            PatKind::Vec(ref before, ref slice, ref after) => {
+            PatKind::Slice(ref before, ref slice, ref after) => {
                 before.iter().all(|p| p.walk(it)) &&
                 slice.iter().all(|p| p.walk(it)) &&
                 after.iter().all(|p| p.walk(it))
@@ -669,8 +671,8 @@ pub enum PatKind {
     /// A range pattern, e.g. `1...2`
     Range(P<Expr>, P<Expr>),
     /// `[a, b, ..i, y, z]` is represented as:
-    ///     `PatKind::Vec(box [a, b], Some(i), box [y, z])`
-    Vec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
+    ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
+    Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
     /// A macro pattern; pre-expansion
     Mac(Mac),
 }
@@ -1431,10 +1433,10 @@ pub struct BareFnTy {
 /// The different kinds of types recognized by the compiler
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum TyKind {
-    /// A variable-length array (`[T]`)
-    Vec(P<Ty>),
+    /// A variable-length slice (`[T]`)
+    Slice(P<Ty>),
     /// A fixed length array (`[T; n]`)
-    FixedLengthVec(P<Ty>, P<Expr>),
+    Array(P<Ty>, P<Expr>),
     /// A raw pointer (`*const T` or `*mut T`)
     Ptr(MutTy),
     /// A reference (`&'a T` or `&'a mut T`)
index 4e50299e836b3b71ef58be94ef9175bb342dc868..81c8e0bdb8262c082835f9713470b87eebd880e4 100644 (file)
@@ -215,7 +215,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
 
     let ty = ecx.ty(
         span,
-        ast::TyKind::FixedLengthVec(
+        ast::TyKind::Array(
             ecx.ty(
                 span,
                 ast::TyKind::Tup(vec![ty_str.clone(), ty_str])
index b81d95a6998c310e01006df4c6733d0f81d28684..bdbc45471bba29c115693a563cb9c29db8da5294 100644 (file)
@@ -73,6 +73,7 @@ fn ty_ptr(&self, span: Span,
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
+               attrs: Vec<ast::Attribute>,
                bounds: ast::TyParamBounds,
                default: Option<P<ast::Ty>>) -> ast::TyParam;
 
@@ -83,6 +84,7 @@ fn typaram(&self,
     fn lifetime_def(&self,
                     span: Span,
                     name: ast::Name,
+                    attrs: Vec<ast::Attribute>,
                     bounds: Vec<ast::Lifetime>)
                     -> ast::LifetimeDef;
 
@@ -96,7 +98,7 @@ fn stmt_let_typed(&self,
                       ident: ast::Ident,
                       typ: P<ast::Ty>,
                       ex: P<ast::Expr>)
-                      -> P<ast::Stmt>;
+                      -> ast::Stmt;
     fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt;
     fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt;
 
@@ -452,11 +454,13 @@ fn ty_infer(&self, span: Span) -> P<ast::Ty> {
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
+               attrs: Vec<ast::Attribute>,
                bounds: ast::TyParamBounds,
                default: Option<P<ast::Ty>>) -> ast::TyParam {
         ast::TyParam {
             ident: id,
             id: ast::DUMMY_NODE_ID,
+            attrs: attrs.into(),
             bounds: bounds,
             default: default,
             span: span
@@ -503,9 +507,11 @@ fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
     fn lifetime_def(&self,
                     span: Span,
                     name: ast::Name,
+                    attrs: Vec<ast::Attribute>,
                     bounds: Vec<ast::Lifetime>)
                     -> ast::LifetimeDef {
         ast::LifetimeDef {
+            attrs: attrs.into(),
             lifetime: self.lifetime(span, name),
             bounds: bounds
         }
@@ -556,7 +562,7 @@ fn stmt_let_typed(&self,
                       ident: ast::Ident,
                       typ: P<ast::Ty>,
                       ex: P<ast::Expr>)
-                      -> P<ast::Stmt> {
+                      -> ast::Stmt {
         let pat = if mutbl {
             let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mutable);
             self.pat_ident_binding_mode(sp, ident, binding_mode)
@@ -571,11 +577,11 @@ fn stmt_let_typed(&self,
             span: sp,
             attrs: ast::ThinVec::new(),
         });
-        P(ast::Stmt {
+        ast::Stmt {
             id: ast::DUMMY_NODE_ID,
             node: ast::StmtKind::Local(local),
             span: sp,
-        })
+        }
     }
 
     // Generate `let _: Type;`, usually used for type assertions.
index b687e4f92be739805b8ce05800bca81b2862b4cd..079d7175822cc9f7d4afc401d50ac84fc36faba8 100644 (file)
@@ -303,6 +303,9 @@ pub fn new() -> Features {
     // Used to identify the `compiler_builtins` crate
     // rustc internal
     (active, compiler_builtins, "1.13.0", None),
+
+    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
+    (active, generic_param_attrs, "1.11.0", Some(34761)),
 );
 
 declare_features! (
@@ -1082,14 +1085,14 @@ fn visit_expr(&mut self, e: &ast::Expr) {
 
     fn visit_pat(&mut self, pattern: &ast::Pat) {
         match pattern.node {
-            PatKind::Vec(_, Some(_), ref last) if !last.is_empty() => {
+            PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => {
                 gate_feature_post!(&self, advanced_slice_patterns,
                                   pattern.span,
                                   "multiple-element slice matches anywhere \
                                    but at the end of a slice (e.g. \
                                    `[0, ..xs, 0]`) are experimental")
             }
-            PatKind::Vec(..) => {
+            PatKind::Slice(..) => {
                 gate_feature_post!(&self, slice_patterns,
                                   pattern.span,
                                   "slice pattern syntax is experimental");
@@ -1220,6 +1223,24 @@ fn visit_vis(&mut self, vis: &ast::Visibility) {
 
         visit::walk_vis(self, vis)
     }
+
+    fn visit_generics(&mut self, g: &ast::Generics) {
+        for t in &g.ty_params {
+            if !t.attrs.is_empty() {
+                gate_feature_post!(&self, generic_param_attrs, t.attrs[0].span,
+                                   "attributes on type parameter bindings are experimental");
+            }
+        }
+        visit::walk_generics(self, g)
+    }
+
+    fn visit_lifetime_def(&mut self, lifetime_def: &ast::LifetimeDef) {
+        if !lifetime_def.attrs.is_empty() {
+            gate_feature_post!(&self, generic_param_attrs, lifetime_def.attrs[0].span,
+                               "attributes on lifetime bindings are experimental");
+        }
+        visit::walk_lifetime_def(self, lifetime_def)
+    }
 }
 
 pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> Features {
index 36f273e1dbc299f3c6c31773578ee050307f6649..08c0637b2d90255f666d7d0293966ff7c6c5e660 100644 (file)
@@ -356,7 +356,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
         id: fld.new_id(id),
         node: match node {
             TyKind::Infer | TyKind::ImplicitSelf => node,
-            TyKind::Vec(ty) => TyKind::Vec(fld.fold_ty(ty)),
+            TyKind::Slice(ty) => TyKind::Slice(fld.fold_ty(ty)),
             TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)),
             TyKind::Rptr(region, mt) => {
                 TyKind::Rptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt))
@@ -385,8 +385,8 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
                 TyKind::ObjectSum(fld.fold_ty(ty),
                             fld.fold_bounds(bounds))
             }
-            TyKind::FixedLengthVec(ty, e) => {
-                TyKind::FixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e))
+            TyKind::Array(ty, e) => {
+                TyKind::Array(fld.fold_ty(ty), fld.fold_expr(e))
             }
             TyKind::Typeof(expr) => {
                 TyKind::Typeof(fld.fold_expr(expr))
@@ -662,8 +662,13 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
 }
 
 pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
-    let TyParam {id, ident, bounds, default, span} = tp;
+    let TyParam {attrs, id, ident, bounds, default, span} = tp;
+    let attrs: Vec<_> = attrs.into();
     TyParam {
+        attrs: attrs.into_iter()
+            .flat_map(|x| fld.fold_attribute(x).into_iter())
+            .collect::<Vec<_>>()
+            .into(),
         id: fld.new_id(id),
         ident: ident,
         bounds: fld.fold_bounds(bounds),
@@ -687,7 +692,12 @@ pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
 
 pub fn noop_fold_lifetime_def<T: Folder>(l: LifetimeDef, fld: &mut T)
                                          -> LifetimeDef {
+    let attrs: Vec<_> = l.attrs.into();
     LifetimeDef {
+        attrs: attrs.into_iter()
+            .flat_map(|x| fld.fold_attribute(x).into_iter())
+            .collect::<Vec<_>>()
+            .into(),
         lifetime: fld.fold_lifetime(l.lifetime),
         bounds: fld.fold_lifetimes(l.bounds),
     }
@@ -1092,8 +1102,8 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
             PatKind::Range(e1, e2) => {
                 PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2))
             },
-            PatKind::Vec(before, slice, after) => {
-                PatKind::Vec(before.move_map(|x| folder.fold_pat(x)),
+            PatKind::Slice(before, slice, after) => {
+                PatKind::Slice(before.move_map(|x| folder.fold_pat(x)),
                        slice.map(|x| folder.fold_pat(x)),
                        after.move_map(|x| folder.fold_pat(x)))
             }
index 5476166932d32fced7400c13717f82970c9d6b5f..9b6002b2469f2991411f4457295bf10aa79c70cc 100644 (file)
@@ -1179,7 +1179,7 @@ pub fn parse_trait_item(&mut self) -> PResult<'a, TraitItem> {
         let lo = self.span.lo;
 
         let (name, node) = if self.eat_keyword(keywords::Type) {
-            let TyParam {ident, bounds, default, ..} = self.parse_ty_param()?;
+            let TyParam {ident, bounds, default, ..} = self.parse_ty_param(vec![])?;
             self.expect(&token::Semi)?;
             (ident, TraitItemKind::Type(bounds, default))
         } else if self.is_const_item() {
@@ -1386,8 +1386,8 @@ pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
             // Parse the `; e` in `[ i32; e ]`
             // where `e` is a const expression
             let t = match self.maybe_parse_fixed_length_of_vec()? {
-                None => TyKind::Vec(t),
-                Some(suffix) => TyKind::FixedLengthVec(t, suffix)
+                None => TyKind::Slice(t),
+                Some(suffix) => TyKind::Array(t, suffix)
             };
             self.expect(&token::CloseDelim(token::Bracket))?;
             t
@@ -1910,10 +1910,22 @@ pub fn parse_lifetime(&mut self) -> PResult<'a, ast::Lifetime> {
 
     /// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def  =
     /// lifetime [':' lifetimes]`
-    pub fn parse_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
-
+    ///
+    /// If `followed_by_ty_params` is None, then we are in a context
+    /// where only lifetime parameters are allowed, and thus we should
+    /// error if we encounter attributes after the bound lifetimes.
+    ///
+    /// If `followed_by_ty_params` is Some(r), then there may be type
+    /// parameter bindings after the lifetimes, so we should pass
+    /// along the parsed attributes to be attached to the first such
+    /// type parmeter.
+    pub fn parse_lifetime_defs(&mut self,
+                               followed_by_ty_params: Option<&mut Vec<ast::Attribute>>)
+                               -> PResult<'a, Vec<ast::LifetimeDef>>
+    {
         let mut res = Vec::new();
         loop {
+            let attrs = self.parse_outer_attributes()?;
             match self.token {
                 token::Lifetime(_) => {
                     let lifetime = self.parse_lifetime()?;
@@ -1923,11 +1935,20 @@ pub fn parse_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
                         } else {
                             Vec::new()
                         };
-                    res.push(ast::LifetimeDef { lifetime: lifetime,
+                    res.push(ast::LifetimeDef { attrs: attrs.into(),
+                                                lifetime: lifetime,
                                                 bounds: bounds });
                 }
 
                 _ => {
+                    if let Some(recv) = followed_by_ty_params {
+                        assert!(recv.is_empty());
+                        *recv = attrs;
+                    } else {
+                        let msg = "trailing attribute after lifetime parameters";
+                        return Err(self.fatal(msg));
+                    }
+                    debug!("parse_lifetime_defs ret {:?}", res);
                     return Ok(res);
                 }
             }
@@ -3587,7 +3608,7 @@ pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
                 self.bump();
                 let (before, slice, after) = self.parse_pat_vec_elements()?;
                 self.expect(&token::CloseDelim(token::Bracket))?;
-                pat = PatKind::Vec(before, slice, after);
+                pat = PatKind::Slice(before, slice, after);
             }
             // At this point, token != _, &, &&, (, [
             _ => if self.eat_keyword(keywords::Mut) {
@@ -4228,7 +4249,7 @@ fn parse_ty_param_bounds(&mut self,
     }
 
     /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
-    fn parse_ty_param(&mut self) -> PResult<'a, TyParam> {
+    fn parse_ty_param(&mut self, preceding_attrs: Vec<ast::Attribute>) -> PResult<'a, TyParam> {
         let span = self.span;
         let ident = self.parse_ident()?;
 
@@ -4242,6 +4263,7 @@ fn parse_ty_param(&mut self) -> PResult<'a, TyParam> {
         };
 
         Ok(TyParam {
+            attrs: preceding_attrs.into(),
             ident: ident,
             id: ast::DUMMY_NODE_ID,
             bounds: bounds,
@@ -4262,11 +4284,27 @@ pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
         let span_lo = self.span.lo;
 
         if self.eat(&token::Lt) {
-            let lifetime_defs = self.parse_lifetime_defs()?;
+            // Upon encountering attribute in generics list, we do not
+            // know if it is attached to lifetime or to type param.
+            //
+            // Solution: 1. eagerly parse attributes in tandem with
+            // lifetime defs, 2. store last set of parsed (and unused)
+            // attributes in `attrs`, and 3. pass in those attributes
+            // when parsing formal type param after lifetime defs.
+            let mut attrs = vec![];
+            let lifetime_defs = self.parse_lifetime_defs(Some(&mut attrs))?;
             let mut seen_default = false;
+            let mut post_lifetime_attrs = Some(attrs);
             let ty_params = self.parse_seq_to_gt(Some(token::Comma), |p| {
                 p.forbid_lifetime()?;
-                let ty_param = p.parse_ty_param()?;
+                // Move out of `post_lifetime_attrs` if present. O/w
+                // not first type param: parse attributes anew.
+                let attrs = match post_lifetime_attrs.as_mut() {
+                    None => p.parse_outer_attributes()?,
+                    Some(attrs) => mem::replace(attrs, vec![]),
+                };
+                post_lifetime_attrs = None;
+                let ty_param = p.parse_ty_param(attrs)?;
                 if ty_param.default.is_some() {
                     seen_default = true;
                 } else if seen_default {
@@ -4276,6 +4314,12 @@ pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
                 }
                 Ok(ty_param)
             })?;
+            if let Some(attrs) = post_lifetime_attrs {
+                if !attrs.is_empty() {
+                    self.span_err(attrs[0].span,
+                                  "trailing attribute after lifetime parameters");
+                }
+            }
             Ok(ast::Generics {
                 lifetimes: lifetime_defs,
                 ty_params: ty_params,
@@ -4423,7 +4467,7 @@ pub fn parse_where_clause(&mut self) -> PResult<'a, ast::WhereClause> {
                     let bound_lifetimes = if self.eat_keyword(keywords::For) {
                         // Higher ranked constraint.
                         self.expect(&token::Lt)?;
-                        let lifetime_defs = self.parse_lifetime_defs()?;
+                        let lifetime_defs = self.parse_lifetime_defs(None)?;
                         self.expect_gt()?;
                         lifetime_defs
                     } else {
@@ -4991,7 +5035,7 @@ fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> {
     fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
         if self.eat_keyword(keywords::For) {
             self.expect(&token::Lt)?;
-            let lifetime_defs = self.parse_lifetime_defs()?;
+            let lifetime_defs = self.parse_lifetime_defs(None)?;
             self.expect_gt()?;
             Ok(lifetime_defs)
         } else {
index 8563d27908db61428405892616fa437fc5948e77..3c106970232cdb4dbf39e516d9db32544fbd5dec 100644 (file)
@@ -972,7 +972,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
         try!(self.maybe_print_comment(ty.span.lo));
         try!(self.ibox(0));
         match ty.node {
-            ast::TyKind::Vec(ref ty) => {
+            ast::TyKind::Slice(ref ty) => {
                 try!(word(&mut self.s, "["));
                 try!(self.print_type(&ty));
                 try!(word(&mut self.s, "]"));
@@ -1039,7 +1039,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
             ast::TyKind::ImplTrait(ref bounds) => {
                 try!(self.print_bounds("impl ", &bounds[..]));
             }
-            ast::TyKind::FixedLengthVec(ref ty, ref v) => {
+            ast::TyKind::Array(ref ty, ref v) => {
                 try!(word(&mut self.s, "["));
                 try!(self.print_type(&ty));
                 try!(word(&mut self.s, "; "));
@@ -2573,7 +2573,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
                 try!(word(&mut self.s, "..."));
                 try!(self.print_expr(&end));
             }
-            PatKind::Vec(ref before, ref slice, ref after) => {
+            PatKind::Slice(ref before, ref slice, ref after) => {
                 try!(word(&mut self.s, "["));
                 try!(self.commasep(Inconsistent,
                                    &before[..],
index 6ccf9848c6df901e9844351bb4d06bb110b2cc92..8faad77859e18d7cd1d5a4688ae91850b33ef670 100644 (file)
@@ -572,7 +572,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
     let static_lt = ecx.lifetime(sp, keywords::StaticLifetime.name());
     // &'static [self::test::TestDescAndFn]
     let static_type = ecx.ty_rptr(sp,
-                                  ecx.ty(sp, ast::TyKind::Vec(struct_type)),
+                                  ecx.ty(sp, ast::TyKind::Slice(struct_type)),
                                   Some(static_lt),
                                   ast::Mutability::Immutable);
     // static TESTS: $static_type = &[...];
index 57b06c40878fe9dcea3adc3c7486a9a0f4c6a018..7fb3e5c6bee1d719d5b68267d25aa9f693afbff2 100644 (file)
@@ -201,6 +201,7 @@ pub fn walk_lifetime<V: Visitor>(visitor: &mut V, lifetime: &Lifetime) {
 pub fn walk_lifetime_def<V: Visitor>(visitor: &mut V, lifetime_def: &LifetimeDef) {
     visitor.visit_lifetime(&lifetime_def.lifetime);
     walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
+    walk_list!(visitor, visit_attribute, &*lifetime_def.attrs);
 }
 
 pub fn walk_poly_trait_ref<V>(visitor: &mut V, trait_ref: &PolyTraitRef, _: &TraitBoundModifier)
@@ -313,7 +314,7 @@ pub fn walk_variant<V>(visitor: &mut V, variant: &Variant, generics: &Generics,
 
 pub fn walk_ty<V: Visitor>(visitor: &mut V, typ: &Ty) {
     match typ.node {
-        TyKind::Vec(ref ty) | TyKind::Paren(ref ty) => {
+        TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => {
             visitor.visit_ty(ty)
         }
         TyKind::Ptr(ref mutable_type) => {
@@ -341,7 +342,7 @@ pub fn walk_ty<V: Visitor>(visitor: &mut V, typ: &Ty) {
             visitor.visit_ty(ty);
             walk_list!(visitor, visit_ty_param_bound, bounds);
         }
-        TyKind::FixedLengthVec(ref ty, ref expression) => {
+        TyKind::Array(ref ty, ref expression) => {
             visitor.visit_ty(ty);
             visitor.visit_expr(expression)
         }
@@ -434,7 +435,7 @@ pub fn walk_pat<V: Visitor>(visitor: &mut V, pattern: &Pat) {
             visitor.visit_expr(upper_bound)
         }
         PatKind::Wild => (),
-        PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
+        PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => {
             walk_list!(visitor, visit_pat, prepatterns);
             walk_list!(visitor, visit_pat, slice_pattern);
             walk_list!(visitor, visit_pat, postpatterns);
@@ -474,6 +475,7 @@ pub fn walk_generics<V: Visitor>(visitor: &mut V, generics: &Generics) {
         visitor.visit_ident(param.span, param.ident);
         walk_list!(visitor, visit_ty_param_bound, &param.bounds);
         walk_list!(visitor, visit_ty, &param.default);
+        walk_list!(visitor, visit_attribute, &*param.attrs);
     }
     walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
     for predicate in &generics.where_clause.predicates {
index e307925a6ed83907b03de79f5b25d2b13188b4f2..bc47d8f4e613741977ac0dc0a52c3b78acd40aed 100644 (file)
@@ -536,7 +536,7 @@ fn create_derived_impl(&self,
                 bounds.push((*declared_bound).clone());
             }
 
-            cx.typaram(self.span, ty_param.ident, P::from_vec(bounds), None)
+            cx.typaram(self.span, ty_param.ident, vec![], P::from_vec(bounds), None)
         }));
 
         // and similarly for where clauses
index 210878b7c9f0e09d3d62d1052cc967514bcece27..4749d082bc0ec3dcd0723e57a000862ed3e866f7 100644 (file)
@@ -194,6 +194,7 @@ pub fn to_path(&self,
 fn mk_ty_param(cx: &ExtCtxt,
                span: Span,
                name: &str,
+               attrs: &[ast::Attribute],
                bounds: &[Path],
                self_ident: Ident,
                self_generics: &Generics)
@@ -204,7 +205,7 @@ fn mk_ty_param(cx: &ExtCtxt,
             cx.typarambound(path)
         })
         .collect();
-    cx.typaram(span, cx.ident_of(name), bounds, None)
+    cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
 }
 
 fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>, span: Span)
@@ -246,7 +247,7 @@ pub fn to_generics(&self,
                 let bounds = bounds.iter()
                     .map(|b| cx.lifetime(span, cx.ident_of(*b).name))
                     .collect();
-                cx.lifetime_def(span, cx.ident_of(*lt).name, bounds)
+                cx.lifetime_def(span, cx.ident_of(*lt).name, vec![], bounds)
             })
             .collect();
         let ty_params = self.bounds
@@ -254,7 +255,7 @@ pub fn to_generics(&self,
             .map(|t| {
                 match *t {
                     (ref name, ref bounds) => {
-                        mk_ty_param(cx, span, *name, bounds, self_ty, self_generics)
+                        mk_ty_param(cx, span, *name, &[], bounds, self_ty, self_generics)
                     }
                 }
             })
index 892ebcfa76129ee468188419c22db46ebf7b81ec..de78f859f0f616d7f155df7e5e42a4d6d58c2e74 100644 (file)
@@ -506,7 +506,7 @@ fn static_array(ecx: &mut ExtCtxt,
                     -> P<ast::Expr> {
         let sp = piece_ty.span;
         let ty = ecx.ty_rptr(sp,
-                             ecx.ty(sp, ast::TyKind::Vec(piece_ty)),
+                             ecx.ty(sp, ast::TyKind::Slice(piece_ty)),
                              Some(ecx.lifetime(sp, keywords::StaticLifetime.name())),
                              ast::Mutability::Immutable);
         let slice = ecx.expr_vec_slice(sp, pieces);
index dcfd3f754c7203b2860a09e080f6f40b79e61bc3..5949afe0ff167c070710d903c126450d693da163 100644 (file)
@@ -1182,26 +1182,59 @@ fn flush(&mut self) -> io::Result<()> {
             }
         }
 
-        thread::spawn(move || {
-            let data = Arc::new(Mutex::new(Vec::new()));
-            let data2 = data.clone();
-            let cfg = thread::Builder::new().name(match desc.name {
-                DynTestName(ref name) => name.clone(),
-                StaticTestName(name) => name.to_owned(),
+        // If the platform is single-threaded we're just going to run
+        // the test synchronously, regardless of the concurrency
+        // level.
+        let supports_threads = !cfg!(target_os = "emscripten");
+
+        // Buffer for capturing standard I/O
+        let data = Arc::new(Mutex::new(Vec::new()));
+        let data2 = data.clone();
+
+        if supports_threads {
+            thread::spawn(move || {
+                let cfg = thread::Builder::new().name(match desc.name {
+                    DynTestName(ref name) => name.clone(),
+                    StaticTestName(name) => name.to_owned(),
+                });
+
+                let result_guard = cfg.spawn(move || {
+                    if !nocapture {
+                        io::set_print(Some(box Sink(data2.clone())));
+                        io::set_panic(Some(box Sink(data2)));
+                    }
+                    testfn()
+                })
+                    .unwrap();
+                let test_result = calc_result(&desc, result_guard.join());
+                let stdout = data.lock().unwrap().to_vec();
+                monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
             });
+        } else {
+            let oldio = if !nocapture {
+                Some((
+                    io::set_print(Some(box Sink(data2.clone()))),
+                    io::set_panic(Some(box Sink(data2)))
+                ))
+            } else {
+                None
+            };
 
-            let result_guard = cfg.spawn(move || {
-                                      if !nocapture {
-                                          io::set_print(box Sink(data2.clone()));
-                                          io::set_panic(box Sink(data2));
-                                      }
-                                      testfn()
-                                  })
-                                  .unwrap();
-            let test_result = calc_result(&desc, result_guard.join());
+            use std::panic::{catch_unwind, AssertUnwindSafe};
+
+            let result = catch_unwind(AssertUnwindSafe(|| {
+                testfn()
+            }));
+
+            if let Some((printio, panicio)) = oldio {
+                io::set_print(printio);
+                io::set_panic(panicio);
+            };
+
+            let test_result = calc_result(&desc, result);
             let stdout = data.lock().unwrap().to_vec();
             monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
-        });
+        }
     }
 
     match testfn {
@@ -1291,7 +1324,7 @@ pub fn fmt_metrics(&self) -> String {
 ///
 /// This function is a no-op, and does not even read from `dummy`.
 #[cfg(not(any(all(target_os = "nacl", target_arch = "le32"),
-              target_arch = "asmjs")))]
+              target_arch = "asmjs", target_arch = "wasm32")))]
 pub fn black_box<T>(dummy: T) -> T {
     // we need to "use" the argument in some way LLVM can't
     // introspect.
@@ -1299,7 +1332,7 @@ pub fn black_box<T>(dummy: T) -> T {
     dummy
 }
 #[cfg(any(all(target_os = "nacl", target_arch = "le32"),
-          target_arch = "asmjs"))]
+          target_arch = "asmjs", target_arch = "wasm32"))]
 #[inline(never)]
 pub fn black_box<T>(dummy: T) -> T {
     dummy
index 30de859f1501aeee01176cba6daca382bbca09d5..c2edf754e49c18ef38c97ac9fbb1d8b25f8658c6 100644 (file)
@@ -65,7 +65,7 @@ pub enum _Unwind_Reason_Code {
 #[cfg(target_arch = "s390x")]
 pub const unwinder_private_data_size: usize = 2;
 
-#[cfg(target_arch = "asmjs")]
+#[cfg(target_os = "emscripten")]
 pub const unwinder_private_data_size: usize = 20;
 
 #[repr(C)]
index 7801978ec1f3637fcda1b564048ebc732bf586af..3e03f7374169cd41547d75e62ac2ab8a103a913c 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 7801978ec1f3637fcda1b564048ebc732bf586af
+Subproject commit 3e03f7374169cd41547d75e62ac2ab8a103a913c
index ea8d59290df2e23415bbe18db4b4ac7f04dfb594..979f5f07abea129a351a1e5e27a26547d0e56fe2 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2016-09-17
+2016-09-25
index 43f46e3578c20fc6867b0821015114b45c0eed9e..9322d21d2a88d325d5913cd989aa93eae3fe4223 100644 (file)
@@ -17,4 +17,5 @@ fn method(&self) {}
 fn main() {
     let x = Test;
     x.method::<i32>(); //~ ERROR E0035
+                       //~| NOTE called with unneeded type parameters
 }
index 35fd6e8942fe7286129df10e40d62be568d46985..ecb6dac66f218f138ec68d2d1029091438669ffe 100644 (file)
@@ -20,4 +20,5 @@ fn main() {
     let x = Test;
     let v = &[0];
     x.method::<i32, i32>(v); //~ ERROR E0036
+                             //~| NOTE Passed 2 type arguments, expected 1
 }
index db7f304227f01acc9df0d1df50744ac82e3e08c4..4c576de22021ccedf276bec0859bbe85e04f55c1 100644 (file)
@@ -18,6 +18,8 @@
 // system allocator. Do this by linking in jemalloc and making sure that we get
 // an error.
 
+// ignore-emscripten FIXME: What "other allocator" should we use for emcc?
+
 #![feature(alloc_jemalloc)]
 
 extern crate allocator_dylib;
index 46ad226d255645a0df21d8ac19f5179aa6905fe0..02c271ab24da3185a550c14d08775e1aadcba06a 100644 (file)
@@ -16,6 +16,8 @@
 // Ensure that rust dynamic libraries use jemalloc as their allocator, verifying
 // by linking in the system allocator here and ensuring that we get a complaint.
 
+// ignore-emscripten FIXME: What "other allocator" is correct for emscripten?
+
 #![feature(alloc_system)]
 
 extern crate allocator_dylib2;
diff --git a/src/test/compile-fail/attr-on-generic-formals-are-visited.rs b/src/test/compile-fail/attr-on-generic-formals-are-visited.rs
new file mode 100644 (file)
index 0000000..c902cfd
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test ensures that attributes on formals in generic parameter
+// lists are included when we are checking for unstable attributes.
+//
+// Note that feature(generic_param_attrs) *is* enabled here. We are
+// checking feature-gating of the attributes themselves, not the
+// capability to parse such attributes in that context.
+
+#![feature(generic_param_attrs)]
+#![allow(dead_code)]
+
+struct StLt<#[lt_struct] 'a>(&'a u32);
+//~^ ERROR The attribute `lt_struct` is currently unknown to the compiler
+struct StTy<#[ty_struct] I>(I);
+//~^ ERROR The attribute `ty_struct` is currently unknown to the compiler
+
+enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
+//~^ ERROR The attribute `lt_enum` is currently unknown to the compiler
+enum EnTy<#[ty_enum] J> { A(J), B }
+//~^ ERROR The attribute `ty_enum` is currently unknown to the compiler
+
+trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
+//~^ ERROR The attribute `lt_trait` is currently unknown to the compiler
+trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
+//~^ ERROR The attribute `ty_trait` is currently unknown to the compiler
+
+type TyLt<#[lt_type] 'd> = &'d u32;
+//~^ ERROR The attribute `lt_type` is currently unknown to the compiler
+type TyTy<#[ty_type] L> = (L, );
+//~^ ERROR The attribute `ty_type` is currently unknown to the compiler
+
+impl<#[lt_inherent] 'e> StLt<'e> { }
+//~^ ERROR The attribute `lt_inherent` is currently unknown to the compiler
+impl<#[ty_inherent] M> StTy<M> { }
+//~^ ERROR The attribute `ty_inherent` is currently unknown to the compiler
+
+impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
+    //~^ ERROR The attribute `lt_impl_for` is currently unknown to the compiler
+    fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
+}
+impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
+    //~^ ERROR The attribute `ty_impl_for` is currently unknown to the compiler
+    fn foo(&self, _: N) { }
+}
+
+fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
+//~^ ERROR The attribute `lt_fn` is currently unknown to the compiler
+fn f_ty<#[ty_fn] O>(_: O) { }
+//~^ ERROR The attribute `ty_fn` is currently unknown to the compiler
+
+impl<I> StTy<I> {
+    fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
+    //~^ ERROR The attribute `lt_meth` is currently unknown to the compiler
+    fn m_ty<#[ty_meth] P>(_: P) { }
+    //~^ ERROR The attribute `ty_meth` is currently unknown to the compiler
+}
+
+fn hof_lt<Q>(_: Q)
+    where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
+    //~^ ERROR The attribute `lt_hof` is currently unknown to the compiler
+{
+}
+
+fn main() {
+
+}
diff --git a/src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs b/src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs
new file mode 100644 (file)
index 0000000..944802f
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test ensures that attributes on formals in generic parameter
+// lists are rejected if feature(generic_param_attrs) is not enabled.
+//
+// (We are prefixing all tested features with `rustc_`, to ensure that
+// the attributes themselves won't be rejected by the compiler when
+// using `rustc_attrs` feature. There is a separate compile-fail/ test
+// ensuring that the attribute feature-gating works in this context.)
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+struct StLt<#[rustc_lt_struct] 'a>(&'a u32);
+//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+struct StTy<#[rustc_ty_struct] I>(I);
+//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+
+enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B }
+//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+enum EnTy<#[rustc_ty_enum] J> { A(J), B }
+//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+
+trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
+//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); }
+//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+
+type TyLt<#[rustc_lt_type] 'd> = &'d u32;
+//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+type TyTy<#[rustc_ty_type] L> = (L, );
+//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+
+impl<#[rustc_lt_inherent] 'e> StLt<'e> { }
+//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+impl<#[rustc_ty_inherent] M> StTy<M> { }
+//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+
+impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
+    //~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+    fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
+}
+impl<#[rustc_ty_impl_for] N> TrTy<N> for StTy<N> {
+    //~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+    fn foo(&self, _: N) { }
+}
+
+fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
+//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+fn f_ty<#[rustc_ty_fn] O>(_: O) { }
+//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+
+impl<I> StTy<I> {
+    fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
+    //~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+    fn m_ty<#[rustc_ty_meth] P>(_: P) { }
+    //~^ ERROR attributes on type parameter bindings are experimental (see issue #34761)
+}
+
+fn hof_lt<Q>(_: Q)
+    where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
+    //~^ ERROR attributes on lifetime bindings are experimental (see issue #34761)
+{
+}
+
+fn main() {
+
+}
diff --git a/src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs b/src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs
new file mode 100644 (file)
index 0000000..53e287c
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test checks variations on `<#[attr] 'a, #[oops]>`, where
+// `#[oops]` is left dangling (that is, it is unattached, with no
+// formal binding following it).
+
+#![feature(generic_param_attrs, rustc_attrs)]
+#![allow(dead_code)]
+
+struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
+
+impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
+    //~^ ERROR trailing attribute after lifetime parameters
+}
+
+fn main() {
+
+}
diff --git a/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs b/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs
new file mode 100644 (file)
index 0000000..a38a7bf
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test checks variations on `<#[attr] 'a, #[oops]>`, where
+// `#[oops]` is left dangling (that is, it is unattached, with no
+// formal binding following it).
+
+#![feature(generic_param_attrs, rustc_attrs)]
+#![allow(dead_code)]
+
+struct RefAny<'a, T>(&'a T);
+
+impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {
+    //~^ ERROR expected identifier, found `>`
+}
+
+fn main() {
+
+}
diff --git a/src/test/compile-fail/attrs-with-no-formal-in-generics-3.rs b/src/test/compile-fail/attrs-with-no-formal-in-generics-3.rs
new file mode 100644 (file)
index 0000000..e7d5b94
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test checks variations on `<#[attr] 'a, #[oops]>`, where
+// `#[oops]` is left dangling (that is, it is unattached, with no
+// formal binding following it).
+
+struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
+
+fn hof_lt<Q>(_: Q)
+    where Q: for <#[rustc_1] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32
+    //~^ ERROR trailing attribute after lifetime parameters
+{
+
+}
+
+fn main() {
+
+}
index 0ff740212e8fa46cec39e66a28c8b00de66ce70b..213683b5808838f2fdd50d497fa0bbd13fbd4a9d 100644 (file)
@@ -24,7 +24,9 @@ fn f_i8() {
     enum A {
         Ok = i8::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed on value after 127i8; set explicitly via OhNo = -128i8 if that is desired outcome
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 127i8
+              //~| NOTE explicitly set `OhNo = -128i8` if that is desired outcome
     }
 }
 
@@ -33,7 +35,9 @@ fn f_u8() {
     enum A {
         Ok = u8::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed on value after 255u8; set explicitly via OhNo = 0u8 if that is desired outcome
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 255u8
+              //~| NOTE explicitly set `OhNo = 0u8` if that is desired outcome
     }
 }
 
@@ -42,7 +46,9 @@ fn f_i16() {
     enum A {
         Ok = i16::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 32767i16
+              //~| NOTE explicitly set `OhNo = -32768i16` if that is desired outcome
     }
 }
 
@@ -51,7 +57,9 @@ fn f_u16() {
     enum A {
         Ok = u16::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 65535u16
+              //~| NOTE explicitly set `OhNo = 0u16` if that is desired outcome
     }
 }
 
@@ -60,7 +68,9 @@ fn f_i32() {
     enum A {
         Ok = i32::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 2147483647i32
+              //~| NOTE explicitly set `OhNo = -2147483648i32` if that is desired outcome
     }
 }
 
@@ -69,7 +79,9 @@ fn f_u32() {
     enum A {
         Ok = u32::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 4294967295u32
+              //~| NOTE explicitly set `OhNo = 0u32` if that is desired outcome
     }
 }
 
@@ -78,7 +90,9 @@ fn f_i64() {
     enum A {
         Ok = i64::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 9223372036854775807i64
+              //~| NOTE explicitly set `OhNo = -9223372036854775808i64` if that is desired outcome
     }
 }
 
@@ -87,7 +101,9 @@ fn f_u64() {
     enum A {
         Ok = u64::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 18446744073709551615u64
+              //~| NOTE explicitly set `OhNo = 0u64` if that is desired outcome
     }
 }
 
index 7316e737b6da8680379b2c617430e54b2703b4ad..a3039b8d9573adafb1093d06efc0fb058e4f308c 100644 (file)
@@ -22,7 +22,9 @@ fn f_i8() {
     enum A {
         Ok = i8::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed on value after 127i8; set explicitly via OhNo = -128i8 if that is desired outcome
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 127i8
+              //~| NOTE explicitly set `OhNo = -128i8` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -33,7 +35,9 @@ fn f_u8() {
     enum A {
         Ok = u8::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed on value after 255u8; set explicitly via OhNo = 0u8 if that is desired outcome
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 255u8
+              //~| NOTE explicitly set `OhNo = 0u8` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -44,7 +48,9 @@ fn f_i16() {
     enum A {
         Ok = i16::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| NOTE overflowed on value after 32767i16
+              //~| NOTE explicitly set `OhNo = -32768i16` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -55,7 +61,9 @@ fn f_u16() {
     enum A {
         Ok = u16::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| overflowed on value after 65535u16
+              //~| NOTE explicitly set `OhNo = 0u16` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -66,7 +74,9 @@ fn f_i32() {
     enum A {
         Ok = i32::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| overflowed on value after 2147483647i32
+              //~| NOTE explicitly set `OhNo = -2147483648i32` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -77,7 +87,9 @@ fn f_u32() {
     enum A {
         Ok = u32::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| overflowed on value after 4294967295u32
+              //~| NOTE explicitly set `OhNo = 0u32` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -88,7 +100,9 @@ fn f_i64() {
     enum A {
         Ok = i64::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| overflowed on value after 9223372036854775807i64
+              //~| NOTE explicitly set `OhNo = -9223372036854775808i64` if that is desired outcome
     }
 
     let x = A::Ok;
@@ -99,7 +113,9 @@ fn f_u64() {
     enum A {
         Ok = u64::MAX - 1,
         Ok2,
-        OhNo, //~ ERROR enum discriminant overflowed
+        OhNo, //~ ERROR enum discriminant overflowed [E0370]
+              //~| overflowed on value after 18446744073709551615u64
+              //~| NOTE explicitly set `OhNo = 0u64` if that is desired outcome
     }
 
     let x = A::Ok;
diff --git a/src/test/compile-fail/issue-36881.rs b/src/test/compile-fail/issue-36881.rs
new file mode 100644 (file)
index 0000000..cca20e9
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    extern crate rand;
+    use rand::Rng; //~ ERROR unresolved import
+}
diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs
new file mode 100644 (file)
index 0000000..aa17a24
--- /dev/null
@@ -0,0 +1,715 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+// This test case tests the incremental compilation hash (ICH) implementation
+// for enum definitions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// We also test the ICH for enum definitions exported in metadata. Same as
+// above, we want to make sure that the change between rev1 and rev2 also
+// results in a change of the ICH for the enum's metadata, and that it stays
+// the same between rev2 and rev3.
+
+// must-compile-successfully
+// revisions: cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+
+// Change enum visibility -----------------------------------------------------
+#[cfg(cfail1)]
+enum EnumVisibility { A }
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail3")]
+pub enum EnumVisibility { A }
+
+
+
+// Change name of a c-style variant -------------------------------------------
+#[cfg(cfail1)]
+enum EnumChangeNameCStyleVariant {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeNameCStyleVariant {
+    Variant1,
+    Variant2Changed,
+}
+
+
+
+// Change name of a tuple-style variant ---------------------------------------
+#[cfg(cfail1)]
+enum EnumChangeNameTupleStyleVariant {
+    Variant1,
+    Variant2(u32, f32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeNameTupleStyleVariant {
+    Variant1,
+    Variant2Changed(u32, f32),
+}
+
+
+
+// Change name of a struct-style variant --------------------------------------
+#[cfg(cfail1)]
+enum EnumChangeNameStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: f32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeNameStructStyleVariant {
+    Variant1,
+    Variant2Changed { a: u32, b: f32 },
+}
+
+
+
+// Change the value of a c-style variant --------------------------------------
+#[cfg(cfail1)]
+enum EnumChangeValueCStyleVariant0 {
+    Variant1,
+    Variant2 = 11,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeValueCStyleVariant0 {
+    Variant1,
+    Variant2 = 22,
+}
+
+#[cfg(cfail1)]
+enum EnumChangeValueCStyleVariant1 {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeValueCStyleVariant1 {
+    Variant1,
+    Variant2 = 11,
+}
+
+
+
+// Add a c-style variant ------------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddCStyleVariant {
+    Variant1,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumAddCStyleVariant {
+    Variant1,
+    Variant2,
+}
+
+
+
+// Remove a c-style variant ---------------------------------------------------
+#[cfg(cfail1)]
+enum EnumRemoveCStyleVariant {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumRemoveCStyleVariant {
+    Variant1,
+}
+
+
+
+// Add a tuple-style variant --------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddTupleStyleVariant {
+    Variant1,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumAddTupleStyleVariant {
+    Variant1,
+    Variant2(u32, f32),
+}
+
+
+
+// Remove a tuple-style variant -----------------------------------------------
+#[cfg(cfail1)]
+enum EnumRemoveTupleStyleVariant {
+    Variant1,
+    Variant2(u32, f32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumRemoveTupleStyleVariant {
+    Variant1,
+}
+
+
+
+// Add a struct-style variant -------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddStructStyleVariant {
+    Variant1,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumAddStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: f32 },
+}
+
+
+
+// Remove a struct-style variant ----------------------------------------------
+#[cfg(cfail1)]
+enum EnumRemoveStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: f32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumRemoveStructStyleVariant {
+    Variant1,
+}
+
+
+
+// Change the type of a field in a tuple-style variant ------------------------
+#[cfg(cfail1)]
+enum EnumChangeFieldTypeTupleStyleVariant {
+    Variant1(u32, u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeFieldTypeTupleStyleVariant {
+    Variant1(u32, u64),
+}
+
+
+
+// Change the type of a field in a struct-style variant -----------------------
+#[cfg(cfail1)]
+enum EnumChangeFieldTypeStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: u32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeFieldTypeStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: u64 },
+}
+
+
+
+// Change the name of a field in a struct-style variant -----------------------
+#[cfg(cfail1)]
+enum EnumChangeFieldNameStructStyleVariant {
+    Variant1 { a: u32, b: u32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeFieldNameStructStyleVariant {
+    Variant1 { a: u32, c: u32 },
+}
+
+
+
+// Change order of fields in a tuple-style variant ----------------------------
+#[cfg(cfail1)]
+enum EnumChangeOrderTupleStyleVariant {
+    Variant1(u32, u64),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeOrderTupleStyleVariant {
+    Variant1(u64, u32),
+}
+
+
+
+// Change order of fields in a struct-style variant ---------------------------
+#[cfg(cfail1)]
+enum EnumChangeFieldOrderStructStyleVariant {
+    Variant1 { a: u32, b: f32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumChangeFieldOrderStructStyleVariant {
+    Variant1 { b: f32, a: u32 },
+}
+
+
+
+// Add a field to a tuple-style variant ---------------------------------------
+#[cfg(cfail1)]
+enum EnumAddFieldTupleStyleVariant {
+    Variant1(u32, u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumAddFieldTupleStyleVariant {
+    Variant1(u32, u32, u32),
+}
+
+
+
+// Add a field to a struct-style variant --------------------------------------
+#[cfg(cfail1)]
+enum EnumAddFieldStructStyleVariant {
+    Variant1 { a: u32, b: u32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumAddFieldStructStyleVariant {
+    Variant1 { a: u32, b: u32, c: u32 },
+}
+
+
+
+// Add #[must_use] to the enum ------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddMustUse {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[must_use]
+enum EnumAddMustUse {
+    Variant1,
+    Variant2,
+}
+
+
+
+// Add #[repr(C)] to the enum -------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddReprC {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddReprC {
+    Variant1,
+    Variant2,
+}
+
+
+
+// Change the name of a type parameter ----------------------------------------
+#[cfg(cfail1)]
+enum EnumChangeNameOfTypeParameter<S> {
+    Variant1(S),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumChangeNameOfTypeParameter<T> {
+    Variant1(T),
+}
+
+
+
+// Add a type parameter ------------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddTypeParameter<S> {
+    Variant1(S),
+    Variant2(S),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddTypeParameter<S, T> {
+    Variant1(S),
+    Variant2(T),
+}
+
+
+
+// Change the name of a lifetime parameter ------------------------------------
+#[cfg(cfail1)]
+enum EnumChangeNameOfLifetimeParameter<'a> {
+    Variant1(&'a u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumChangeNameOfLifetimeParameter<'b> {
+    Variant1(&'b u32),
+}
+
+
+
+// Add a lifetime parameter ---------------------------------------------------
+#[cfg(cfail1)]
+enum EnumAddLifetimeParameter<'a> {
+    Variant1(&'a u32),
+    Variant2(&'a u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddLifetimeParameter<'a, 'b> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+
+
+// Add a lifetime bound to a lifetime parameter -------------------------------
+#[cfg(cfail1)]
+enum EnumAddLifetimeParameterBound<'a, 'b> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddLifetimeParameterBound<'a, 'b: 'a> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+// Add a lifetime bound to a type parameter -----------------------------------
+#[cfg(cfail1)]
+enum EnumAddLifetimeBoundToParameter<'a, T> {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+
+
+// Add a trait bound to a type parameter --------------------------------------
+#[cfg(cfail1)]
+enum EnumAddTraitBound<S> {
+    Variant1(S),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddTraitBound<T: Sync> {
+    Variant1(T),
+}
+
+
+
+// Add a lifetime bound to a lifetime parameter in where clause ---------------
+#[cfg(cfail1)]
+enum EnumAddLifetimeParameterBoundWhere<'a, 'b> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddLifetimeParameterBoundWhere<'a, 'b> where 'b: 'a {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+
+
+// Add a lifetime bound to a type parameter in where clause -------------------
+#[cfg(cfail1)]
+enum EnumAddLifetimeBoundToParameterWhere<'a, T> {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+
+
+// Add a trait bound to a type parameter in where clause ----------------------
+#[cfg(cfail1)]
+enum EnumAddTraitBoundWhere<S> {
+    Variant1(S),
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[repr(C)]
+enum EnumAddTraitBoundWhere<T> where T: Sync {
+    Variant1(T),
+}
+
+
+
+// In an enum with two variants, swap usage of type parameters ----------------
+#[cfg(cfail1)]
+enum EnumSwapUsageTypeParameters<A, B> {
+    Variant1 { a: A },
+    Variant2 { a: B },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumSwapUsageTypeParameters<A, B> {
+    Variant1 { a: B },
+    Variant2 { a: A },
+}
+
+
+
+// In an enum with two variants, swap usage of lifetime parameters ------------
+#[cfg(cfail1)]
+enum EnumSwapUsageLifetimeParameters<'a, 'b> {
+    Variant1 { a: &'a u32 },
+    Variant2 { b: &'b u32 },
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+enum EnumSwapUsageLifetimeParameters<'a, 'b> {
+    Variant1 { a: &'b u32 },
+    Variant2 { b: &'a u32 },
+}
+
+
+
+struct ReferencedType1;
+struct ReferencedType2;
+
+
+
+// Change field type in tuple-style variant indirectly by modifying a use statement
+mod change_field_type_indirectly_tuple_style {
+    #[cfg(cfail1)]
+    use super::ReferencedType1 as FieldType;
+    #[cfg(not(cfail1))]
+    use super::ReferencedType2 as FieldType;
+
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    enum TupleStyle {
+        Variant1(FieldType)
+    }
+}
+
+
+
+// Change field type in record-style variant indirectly by modifying a use statement
+mod change_field_type_indirectly_struct_style {
+    #[cfg(cfail1)]
+    use super::ReferencedType1 as FieldType;
+    #[cfg(not(cfail1))]
+    use super::ReferencedType2 as FieldType;
+
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    enum StructStyle {
+        Variant1 { a: FieldType }
+    }
+}
+
+
+
+trait ReferencedTrait1 {}
+trait ReferencedTrait2 {}
+
+
+
+// Change trait bound of type parameter indirectly by modifying a use statement
+mod change_trait_bound_indirectly {
+    #[cfg(cfail1)]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(cfail1))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    enum Enum<T: Trait> {
+        Variant1(T)
+    }
+}
+
+
+
+// Change trait bound of type parameter in where clause indirectly by modifying a use statement
+mod change_trait_bound_indirectly_where {
+    #[cfg(cfail1)]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(cfail1))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    enum Enum<T> where T: Trait {
+        Variant1(T)
+    }
+}
+
+
index ab50503830534e7546ba0e89dd58807c8e7be3fd..36e2a4b86aa3965fa7d6ade6835e392162e58a55 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // error-pattern:thread '<unnamed>' panicked at 'test'
+// ignore-emscripten Needs threads
 
 use std::thread;
 
index 2d2371f5ce77c6d05fc58e85249b9442bdb580ea..4da40c3158b84c22ef955e8e243d3224b1e1a5cd 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // error-pattern:thread 'owned name' panicked at 'test'
+// ignore-emscripten Needs threads.
 
 use std::thread::Builder;
 
index ede055acd61ffcb7a20a3ff54461b366a2633a12..108430848b9b29673efe9b569fae95650be2bc3b 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // error-pattern:Ensure that the child thread runs by panicking
+// ignore-emscripten Needs threads.
 
 use std::thread;
 
index fa360570253b0f0e947eaaf1b2fe669d40704f21..21ced01d9d69efe619f8e23d79a72411bdf72b41 100644 (file)
@@ -12,6 +12,7 @@
 // error-pattern:thread 'test_foo' panicked at
 // compile-flags: --test
 // ignore-pretty: does not work well with `--test`
+// ignore-emscripten
 
 #[test]
 fn test_foo() {
index e18c5d9631a702358a6964b918fe8b2db3bb3267..74b5f17bcf9bad053905f6d917fb3498f63d7b87 100644 (file)
@@ -12,6 +12,7 @@
 // error-pattern:thread 'test_foo' panicked at
 // compile-flags: --test
 // ignore-pretty: does not work well with `--test`
+// ignore-emscripten
 
 #[test]
 #[should_panic(expected = "foobar")]
index 94ed641c79c9372cabcf34a107356b5e2bc780cc..b5c222764d243ea33060ff3826da71884f908c42 100644 (file)
@@ -15,6 +15,7 @@
 // compile-flags: --test
 // exec-env:RUST_TEST_THREADS=foo
 // ignore-pretty: does not work well with `--test`
+// ignore-emscripten
 
 #[test]
 fn do_nothing() {}
index d7a8e79bfbee84f5951461887676e2370f5ebc65..ca2dbdf2b3de30a4a3672ecd389dc075889ca29c 100644 (file)
@@ -10,6 +10,7 @@
 
 // no-prefer-dynamic
 // aux-build:allocator-dummy.rs
+// ignore-emscripten
 
 #![feature(test)]
 
diff --git a/src/test/run-pass/attr-on-generic-formals.rs b/src/test/run-pass/attr-on-generic-formals.rs
new file mode 100644 (file)
index 0000000..5985284
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test ensures we can attach attributes to the formals in all
+// places where generic parameter lists occur, assuming appropriate
+// feature gates are enabled.
+//
+// (We are prefixing all tested features with `rustc_`, to ensure that
+// the attributes themselves won't be rejected by the compiler when
+// using `rustc_attrs` feature. There is a separate compile-fail/ test
+// ensuring that the attribute feature-gating works in this context.)
+
+#![feature(generic_param_attrs, rustc_attrs)]
+#![allow(dead_code)]
+
+struct StLt<#[rustc_lt_struct] 'a>(&'a u32);
+struct StTy<#[rustc_ty_struct] I>(I);
+
+enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B }
+enum EnTy<#[rustc_ty_enum] J> { A(J), B }
+
+trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
+trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); }
+
+type TyLt<#[rustc_lt_type] 'd> = &'d u32;
+type TyTy<#[rustc_ty_type] L> = (L, );
+
+impl<#[rustc_lt_inherent] 'e> StLt<'e> { }
+impl<#[rustc_ty_inherent] M> StTy<M> { }
+
+impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
+    fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
+}
+impl<#[rustc_ty_impl_for] N> TrTy<N> for StTy<N> {
+    fn foo(&self, _: N) { }
+}
+
+fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
+fn f_ty<#[rustc_ty_fn] O>(_: O) { }
+
+impl<I> StTy<I> {
+    fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
+    fn m_ty<#[rustc_ty_meth] P>(_: P) { }
+}
+
+fn hof_lt<Q>(_: Q)
+    where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
+{
+}
+
+fn main() {
+
+}
index 1f30f3ecedc9682394888654c043a56183794520..e858ba8c823b8537d0d26d71b8cc3e8c50cce10f 100644 (file)
@@ -24,6 +24,9 @@ enum Enum {
     StructVariant { x: isize, y : usize }
 }
 
+#[derive(Debug)]
+struct Pointers(*const Send, *mut Sync);
+
 macro_rules! t {
     ($x:expr, $expected:expr) => {
         assert_eq!(format!("{:?}", $x), $expected.to_string())
diff --git a/src/test/run-pass/discriminant_value-wrapper.rs b/src/test/run-pass/discriminant_value-wrapper.rs
new file mode 100644 (file)
index 0000000..2dbda0b
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(discriminant_value)]
+
+use std::mem;
+
+enum ADT {
+    First(u32, u32),
+    Second(u64)
+}
+
+pub fn main() {
+    assert!(mem::discriminant(&ADT::First(0,0)) == mem::discriminant(&ADT::First(1,1)));
+    assert!(mem::discriminant(&ADT::Second(5))  == mem::discriminant(&ADT::Second(6)));
+    assert!(mem::discriminant(&ADT::First(2,2)) != mem::discriminant(&ADT::Second(2)));
+
+    let _ = mem::discriminant(&10);
+    let _ = mem::discriminant(&"test");
+}
+
index 21948d2e5ad23c04bf3dad6312652456f48ea5bb..801a3c40ab47ddb9a2d0dd73248e521da5f0ab07 100644 (file)
@@ -12,6 +12,7 @@
 
 // pretty-expanded FIXME #23616
 // ignore-msvc
+// ignore-emscripten
 
 struct TwoU8s {
     one: u8,
index 62d54da56b2ec95279eb421f8083b3d9222b1c93..1b9b4ab32ca40cb1cb1f767ef4cf565721470b7e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-emscripten missing rust_begin_unwind
+
 #![feature(lang_items, start, collections)]
 #![no_std]
 
index 92308c9fc3e4e0eddebe36707b3cf215c32144fc..d1e05e5a0184c3d1c8cac004726b958bf3b0c5c2 100644 (file)
@@ -7,6 +7,7 @@
 // <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-emscripten Not sure what's happening here.
 
 
 use std::mem;
index 411c1807a16b71491410c7c4bfedf810985dcd2f..ee4eb86ed0de3d04a6c30d4552810aac53646e26 100644 (file)
@@ -7,6 +7,7 @@
 // <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-emscripten
 
 
 use std::mem;
index 71c1a61062d1085a24bb2e02a065a68731bb07af..1c273fcba02daf77b148b7c9f44dd9779b4d416e 100644 (file)
@@ -11,6 +11,7 @@
 // compile-flags:-C panic=abort
 // aux-build:exit-success-if-unwind.rs
 // no-prefer-dynamic
+// ignore-emscripten Function not implemented
 
 extern crate exit_success_if_unwind;
 
index 2fc9d6cfd04a13ead3a726200646f7ff118650e9..be38f6ea3643a8857c7c553af3e2df34aa8ac59d 100644 (file)
@@ -10,6 +10,7 @@
 
 // compile-flags:-C panic=abort
 // no-prefer-dynamic
+// ignore-emscripten Function not implemented.
 
 use std::process::Command;
 use std::env;
index 09e33b88189fe8fb691ed1934bea768f41733016..e4cd4e809a4c6bf7684b9346ea325dbca9335c39 100644 (file)
@@ -10,6 +10,7 @@
 
 // compile-flags:-C lto -C panic=abort
 // no-prefer-dynamic
+// ignore-emscripten Function not implemented.
 
 use std::process::Command;
 use std::env;
index 10e633b3775b3530f88d325a4ed703bca6f148fa..768b88fd09e0b3fad9c8aaa33c2b3db88e2fca0e 100644 (file)
@@ -10,6 +10,7 @@
 
 // compile-flags:-C lto -C panic=unwind
 // no-prefer-dynamic
+// ignore-emscripten Function not implemented.
 
 use std::process::Command;
 use std::env;
index 2ad47c4f116ae9a34d6dbd22c145ed65391b280c..ff389bec899efba23026791c97f3aaad210e03f6 100644 (file)
@@ -7,6 +7,7 @@
 // <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-emscripten Function not implemented.
 
 use std::env;
 use std::io;
index 2efd9333999b24ca0f83834b7be300b849cb7f19..d32fa01c7b9453fb2e3c1d52705b6d070eb108c5 100644 (file)
@@ -7,6 +7,7 @@
 // <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-emscripten linking with emcc failed
 
 #![feature(repr_simd, platform_intrinsics, concat_idents, test)]
 #![allow(non_camel_case_types)]
index 1f64f40c5255baead14e2e11b8488ffe4f305466..13d5cc989e94dac4a8dfd332bc55e2abcea5d87b 100644 (file)
@@ -30,7 +30,7 @@ fn main() {
     let data = Arc::new(Mutex::new(Vec::new()));
     let sink = Sink(data.clone());
     let res = thread::Builder::new().spawn(move|| -> () {
-        io::set_panic(Box::new(sink));
+        io::set_panic(Some(Box::new(sink)));
         panic!("Hello, world!")
     }).unwrap().join();
     assert!(res.is_err());
index 5d522736089ea4d2acf1340b99bf5a6cd6c23583..81cb927f26b0210d33ff07695a281f424ba70142 100644 (file)
@@ -183,4 +183,5 @@ pub struct Config {
     pub cflags: String,
     pub llvm_components: String,
     pub llvm_cxxflags: String,
+    pub nodejs: Option<String>,
 }
index 114cfaf7972ea51481a176ebd1800a1bca13185c..ff91ab7c70b3ee97a05f96c7e93e3033c3554b51 100644 (file)
@@ -109,6 +109,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           reqopt("", "cflags", "flags for the C compiler", "FLAGS"),
           reqopt("", "llvm-components", "list of LLVM components built in", "LIST"),
           reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS"),
+          optopt("", "nodejs", "the name of nodejs", "PATH"),
           optflag("h", "help", "show this message"));
 
     let (argv0, args_) = args.split_first().unwrap();
@@ -190,6 +191,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
         cflags: matches.opt_str("cflags").unwrap(),
         llvm_components: matches.opt_str("llvm-components").unwrap(),
         llvm_cxxflags: matches.opt_str("llvm-cxxflags").unwrap(),
+        nodejs: matches.opt_str("nodejs"),
     }
 }
 
@@ -431,10 +433,17 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
         }
     };
 
+    // Debugging emscripten code doesn't make sense today
+    let mut ignore = early_props.ignore;
+    if (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb) &&
+        config.target.contains("emscripten") {
+        ignore = true;
+    }
+
     test::TestDescAndFn {
         desc: test::TestDesc {
             name: make_test_name(config, testpaths),
-            ignore: early_props.ignore,
+            ignore: ignore,
             should_panic: should_panic,
         },
         testfn: make_test_closure(config, testpaths),
index 8fdb882164af8517d793bb0c6e885e1277fb2751..35b93392baf2c4c96110e961a7a871f714394a01 100644 (file)
@@ -1168,7 +1168,6 @@ fn exec_compiled_test(&self) -> ProcRes {
             "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
                 self._arm_exec_compiled_test(env)
             }
-
             _=> {
                 let aux_dir = self.aux_output_dir_name();
                 self.compose_and_run(self.make_run_args(),
@@ -1421,7 +1420,7 @@ fn make_lib_name(&self, auxfile: &Path) -> PathBuf {
     fn make_exe_name(&self) -> PathBuf {
         let mut f = self.output_base_name();
         // FIXME: This is using the host architecture exe suffix, not target!
-        if self.config.target == "asmjs-unknown-emscripten" {
+        if self.config.target.contains("emscripten") {
             let mut fname = f.file_name().unwrap().to_os_string();
             fname.push(".js");
             f.set_file_name(&fname);
@@ -1439,8 +1438,9 @@ fn make_run_args(&self) -> ProcArgs {
         let mut args = self.split_maybe_args(&self.config.runtool);
 
         // If this is emscripten, then run tests under nodejs
-        if self.config.target == "asmjs-unknown-emscripten" {
-            args.push("nodejs".to_owned());
+        if self.config.target.contains("emscripten") {
+            let nodejs = self.config.nodejs.clone().unwrap_or("nodejs".to_string());
+            args.push(nodejs);
         }
 
         let exe_file = self.make_exe_name();
index 428bbcfe5761d6d00acadc632fea0f7c0c5685ef..cad71c59f0a4aef93ccd10d3d75b1022b0bafdc9 100644 (file)
@@ -43,7 +43,8 @@
                                                               ("sparc", "sparc"),
                                                               ("x86_64", "x86_64"),
                                                               ("xcore", "xcore"),
-                                                              ("asmjs", "asmjs")];
+                                                              ("asmjs", "asmjs"),
+                                                              ("wasm32", "wasm32")];
 
 pub fn get_os(triple: &str) -> &'static str {
     for &(triple_os, os) in OS_TABLE {