]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #41847 - alexcrichton:less-unstable-annotations, r=eddyb
authorbors <bors@rust-lang.org>
Sat, 13 May 2017 05:22:08 +0000 (05:22 +0000)
committerbors <bors@rust-lang.org>
Sat, 13 May 2017 05:22:08 +0000 (05:22 +0000)
rustc: Add a new `-Z force-unstable-if-unmarked` flag

This commit adds a new `-Z` flag to the compiler for use when bootstrapping the
compiler itself. We want to be able to use crates.io crates, but we also want
the usage of such crates to be as ergonomic as possible! To that end compiler
crates are a little tricky in that the crates.io crates are not annotated as
unstable, nor do they expect to pull in unstable dependencies.

To cover all these situations it's intended that the compiler will forever now
bootstrap with `-Z force-unstable-if-unmarked`. This flags serves a dual purpose
of forcing crates.io crates to themselves be unstable while also allowing them
to use other "unstable" crates.io crates. This should mean that adding a
dependency to compiler no longer requires upstream modification with
unstable/staged_api attributes for inclusion!

119 files changed:
.travis.yml
appveyor.yml
src/ci/docker/android-ndk.sh [new file with mode: 0644]
src/ci/docker/arm-android/Dockerfile
src/ci/docker/arm-android/accept-licenses.sh [deleted file]
src/ci/docker/arm-android/install-ndk.sh
src/ci/docker/arm-android/install-sdk.sh
src/ci/docker/arm-android/start-emulator.sh
src/ci/docker/armhf-gnu/Dockerfile
src/ci/docker/cross/Dockerfile
src/ci/docker/disabled/dist-aarch64-android/Dockerfile [new file with mode: 0644]
src/ci/docker/disabled/dist-armv7-android/Dockerfile [new file with mode: 0644]
src/ci/docker/disabled/dist-i686-android/Dockerfile [new file with mode: 0644]
src/ci/docker/disabled/dist-x86_64-android/Dockerfile [new file with mode: 0644]
src/ci/docker/dist-aarch64-linux/Dockerfile
src/ci/docker/dist-android/Dockerfile
src/ci/docker/dist-android/install-ndk.sh
src/ci/docker/dist-arm-linux/Dockerfile
src/ci/docker/dist-armhf-linux/Dockerfile
src/ci/docker/dist-armv7-linux/Dockerfile
src/ci/docker/dist-fuchsia/Dockerfile
src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile
src/ci/docker/dist-i686-freebsd/Dockerfile
src/ci/docker/dist-i686-linux/Dockerfile
src/ci/docker/dist-mips-linux/Dockerfile
src/ci/docker/dist-mips64-linux/Dockerfile
src/ci/docker/dist-mips64el-linux/Dockerfile
src/ci/docker/dist-mipsel-linux/Dockerfile
src/ci/docker/dist-powerpc-linux/Dockerfile
src/ci/docker/dist-powerpc64-linux/Dockerfile
src/ci/docker/dist-powerpc64le-linux/Dockerfile
src/ci/docker/dist-s390x-linux/Dockerfile
src/ci/docker/dist-x86_64-freebsd/Dockerfile
src/ci/docker/dist-x86_64-linux/Dockerfile
src/ci/docker/dist-x86_64-musl/Dockerfile
src/ci/docker/dist-x86_64-netbsd/Dockerfile
src/ci/docker/emscripten/Dockerfile
src/ci/docker/i686-gnu-nopt/Dockerfile
src/ci/docker/i686-gnu/Dockerfile
src/ci/docker/run.sh
src/ci/docker/x86_64-gnu-aux/Dockerfile
src/ci/docker/x86_64-gnu-debug/Dockerfile
src/ci/docker/x86_64-gnu-distcheck/Dockerfile
src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile
src/ci/docker/x86_64-gnu-incremental/Dockerfile
src/ci/docker/x86_64-gnu-llvm-3.7/Dockerfile
src/ci/docker/x86_64-gnu-nopt/Dockerfile
src/ci/docker/x86_64-gnu/Dockerfile
src/doc/unstable-book/src/SUMMARY.md
src/doc/unstable-book/src/library-features/print-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/library-features/print.md [deleted file]
src/liballoc/arc.rs
src/libcore/ptr.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/infer/combine.rs
src/librustc/infer/equate.rs
src/librustc/infer/error_reporting/note.rs
src/librustc/middle/cstore.rs
src/librustc/middle/effect.rs
src/librustc/mir/mod.rs
src/librustc/mir/tcx.rs
src/librustc/mir/visit.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc/ty/relate.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_const_eval/eval.rs
src/librustc_driver/lib.rs
src/librustc_driver/target_features.rs
src/librustc_incremental/persist/hash.rs
src/librustc_lint/builtin.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/expr/as_operand.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/expr/stmt.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/misc.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/copy_prop.rs
src/librustc_mir/transform/deaggregator.rs
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/simplify_branches.rs
src/librustc_mir/transform/type_check.rs
src/librustc_passes/mir_stats.rs
src/librustc_trans/back/symbol_names.rs
src/librustc_trans/collector.rs
src/librustc_trans/consts.rs
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/rvalue.rs
src/librustc_typeck/variance/constraints.rs
src/librustc_typeck/variance/xform.rs
src/librustdoc/clean/mod.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/macros.rs
src/libstd/path.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/os.rs
src/libstd/thread/mod.rs
src/test/compile-fail/crt-static-gated.rs [deleted file]
src/test/compile-fail/region-invariant-static-error-reporting.rs
src/test/compile-fail/regions-trait-object-subtyping.rs
src/test/compile-fail/variance-contravariant-arg-object.rs
src/test/compile-fail/variance-covariant-arg-object.rs
src/test/compile-fail/variance-invariant-arg-object.rs
src/test/incremental/remove_source_file/auxiliary/mod.rs [new file with mode: 0644]
src/test/incremental/remove_source_file/main.rs [new file with mode: 0644]
src/test/run-pass/issue-41677.rs [new file with mode: 0644]
src/test/run-pass/issue-41849-variance-req.rs [new file with mode: 0644]
src/test/run-pass/print-stdout-eprint-stderr.rs [new file with mode: 0644]
src/test/ui/static-lifetime.rs [new file with mode: 0644]
src/test/ui/static-lifetime.stderr [new file with mode: 0644]
src/tools/compiletest/src/runtest.rs
src/tools/rls

index 4fcf6f02defc4bd4666574d5247fc6a69d16f92d..190cb3380a18c633870f6c4d0f7baf677bf3d09a 100644 (file)
@@ -63,7 +63,7 @@ matrix:
       os: osx
       osx_image: xcode8.2
       install: &osx_install_sccache >
-        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-apple-darwin &&
+        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/sccache &&
         travis_retry curl -o /usr/local/bin/stamp https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/stamp
index 8ace91c3d89e37f0d1b1006c9bf52fc5bf690940..42c6256a95a8cc04fef17140dd39e02b0d499e9f 100644 (file)
@@ -124,8 +124,8 @@ install:
   - set PATH=C:\Python27;%PATH%
 
   # Download and install sccache
-  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-pc-windows-msvc
-  - mv 2017-04-29-sccache-x86_64-pc-windows-msvc sccache.exe
+  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-pc-windows-msvc
+  - mv 2017-05-12-sccache-x86_64-pc-windows-msvc sccache.exe
   - set PATH=%PATH%;%CD%
 
   # Download and install ninja
diff --git a/src/ci/docker/android-ndk.sh b/src/ci/docker/android-ndk.sh
new file mode 100644 (file)
index 0000000..4849f84
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Copyright 2017 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.
+
+set -ex
+
+URL=https://dl.google.com/android/repository
+
+download_ndk() {
+    mkdir -p /android/ndk
+    cd /android/ndk
+    curl -O $URL/$1
+    unzip -q $1
+    rm $1
+    mv android-ndk-* ndk
+}
+
+make_standalone_toolchain() {
+    # See https://developer.android.com/ndk/guides/standalone_toolchain.htm
+    python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \
+        --install-dir /android/ndk/$1-$2 \
+        --arch $1 \
+        --api $2
+}
+
+remove_ndk() {
+    rm -rf /android/ndk/ndk
+}
index 04ca6d76c557b9086af1e91fbc3c4ca9a1e63b73..93f15baf55e7745fa912ab3d707ed75b9108269c 100644 (file)
@@ -1,7 +1,6 @@
 FROM ubuntu:16.04
 
-RUN dpkg --add-architecture i386 && \
-    apt-get update && \
+RUN apt-get update && \
     apt-get install -y --no-install-recommends \
   g++ \
   make \
@@ -12,35 +11,54 @@ RUN dpkg --add-architecture i386 && \
   git \
   cmake \
   unzip \
-  expect \
-  openjdk-9-jre-headless \
   sudo \
-  libstdc++6:i386 \
   xz-utils \
   libssl-dev \
   pkg-config
 
-WORKDIR /android/
-ENV PATH=$PATH:/android/ndk-arm-9/bin:/android/sdk/tools:/android/sdk/platform-tools
-
-COPY install-ndk.sh install-sdk.sh accept-licenses.sh /android/
-RUN sh /android/install-ndk.sh
-RUN sh /android/install-sdk.sh
-
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
     dpkg -i dumb-init_*.deb && \
     rm dumb-init_*.deb
 
-COPY start-emulator.sh /android/
+RUN curl -o /usr/local/bin/sccache \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
+    chmod +x /usr/local/bin/sccache
 
-ENTRYPOINT ["/usr/bin/dumb-init", "--", "/android/start-emulator.sh"]
+# Install NDK
+COPY install-ndk.sh /tmp
+RUN . /tmp/install-ndk.sh && \
+    download_ndk android-ndk-r13b-linux-x86_64.zip && \
+    make_standalone_toolchain arm 9 && \
+    remove_ndk
 
-RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-02-24-sccache-x86_64-unknown-linux-gnu && \
-      chmod +x /usr/local/bin/sccache
+# Install SDK
+RUN dpkg --add-architecture i386 && \
+    apt-get update && \
+    apt-get install -y --no-install-recommends \
+  openjdk-9-jre-headless \
+  tzdata \
+  libstdc++6:i386 \
+  libgl1-mesa-glx \
+  libpulse0
+
+COPY install-sdk.sh /tmp
+RUN . /tmp/install-sdk.sh && \
+    download_sdk tools_r25.2.5-linux.zip && \
+    download_sysimage armeabi-v7a 18 && \
+    create_avd armeabi-v7a 18
+
+# Setup env
+ENV PATH=$PATH:/android/sdk/tools
+ENV PATH=$PATH:/android/sdk/platform-tools
+
+ENV TARGETS=arm-linux-androideabi
 
 ENV RUST_CONFIGURE_ARGS \
-      --target=arm-linux-androideabi \
-      --arm-linux-androideabi-ndk=/android/ndk-arm-9
+      --target=$TARGETS \
+      --arm-linux-androideabi-ndk=/android/ndk/arm-9
+
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS --verbose
 
-ENV SCRIPT python2.7 ../x.py test --target arm-linux-androideabi
+# Entrypoint
+COPY start-emulator.sh /android/
+ENTRYPOINT ["/usr/bin/dumb-init", "--", "/android/start-emulator.sh"]
diff --git a/src/ci/docker/arm-android/accept-licenses.sh b/src/ci/docker/arm-android/accept-licenses.sh
deleted file mode 100755 (executable)
index 8d8f60a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/expect -f
-# ignore-license
-
-set timeout 1800
-set cmd [lindex $argv 0]
-set licenses [lindex $argv 1]
-
-spawn {*}$cmd
-expect {
-  "Do you accept the license '*'*" {
-        exp_send "y\r"
-        exp_continue
-  }
-  eof
-}
index 389ec062110e0e5681ef0d8385582e508afca44c..80818721199838adf8fa0a6b509739366098e9c5 100644 (file)
 
 set -ex
 
-cpgdb() {
-  cp android-ndk-r11c/prebuilt/linux-x86_64/bin/gdb /android/$1/bin/$2-gdb
-  cp android-ndk-r11c/prebuilt/linux-x86_64/bin/gdb-orig /android/$1/bin/gdb-orig
-  cp -r android-ndk-r11c/prebuilt/linux-x86_64/share /android/$1/share
+URL=https://dl.google.com/android/repository
+
+download_ndk() {
+    mkdir -p /android/ndk
+    cd /android/ndk
+    curl -O $URL/$1
+    unzip -q $1
+    rm $1
+    mv android-ndk-* ndk
 }
 
-# Prep the Android NDK
-#
-# See https://github.com/servo/servo/wiki/Building-for-Android
-curl -O https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip
-unzip -q android-ndk-r11c-linux-x86_64.zip
-bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
-        --platform=android-9 \
-        --toolchain=arm-linux-androideabi-4.9 \
-        --install-dir=/android/ndk-arm-9 \
-        --ndk-dir=/android/android-ndk-r11c \
-        --arch=arm
-cpgdb ndk-arm-9 arm-linux-androideabi
+make_standalone_toolchain() {
+    # See https://developer.android.com/ndk/guides/standalone_toolchain.html
+    python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \
+        --install-dir /android/ndk/$1-$2 \
+        --arch $1 \
+        --api $2
+}
 
-rm -rf ./android-ndk-r11c-linux-x86_64.zip ./android-ndk-r11c
+remove_ndk() {
+    rm -rf /android/ndk/ndk
+}
index 2db1d46ba2273e89cfdb655ba59ef427ba0974ba..258fc47a7a6927e573ad534e26352c7c5cb7e417 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
 # file at the top-level directory of this distribution and at
 # http://rust-lang.org/COPYRIGHT.
 #
 
 set -ex
 
-# Prep the SDK and emulator
-#
-# Note that the update process requires that we accept a bunch of licenses, and
-# we can't just pipe `yes` into it for some reason, so we take the same strategy
-# located in https://github.com/appunite/docker by just wrapping it in a script
-# which apparently magically accepts the licenses.
+URL=https://dl.google.com/android/repository
+
+download_sdk() {
+    mkdir -p /android/sdk
+    cd /android/sdk
+    curl -O $URL/$1
+    unzip -q $1
+    rm -rf $1
+}
+
+download_sysimage() {
+    # See https://developer.android.com/studio/tools/help/android.html
+    abi=$1
+    api=$2
+
+    filter="platform-tools,android-$api"
+    filter="$filter,sys-img-$abi-android-$api"
 
-mkdir sdk
-curl https://dl.google.com/android/android-sdk_r24.4-linux.tgz | \
-    tar xzf - -C sdk --strip-components=1
+    # Keep printing yes to accept the licenses
+    while true; do echo yes; sleep 10; done | \
+        /android/sdk/tools/android update sdk -a --no-ui \
+            --filter "$filter"
+}
 
-filter="platform-tools,android-18"
-filter="$filter,sys-img-armeabi-v7a-android-18"
+create_avd() {
+    # See https://developer.android.com/studio/tools/help/android.html
+    abi=$1
+    api=$2
 
-./accept-licenses.sh "android - update sdk -a --no-ui --filter $filter"
+    echo no | \
+        /android/sdk/tools/android create avd \
+            --name $abi-$api \
+            --target android-$api \
+            --abi $abi
+}
 
-echo "no" | android create avd \
-                --name arm-18 \
-                --target android-18 \
-                --abi armeabi-v7a
index 4a73637e9ddbf977d987f4d62423d00c1eac6b6a..cd3369d5eaddc7da93f844b4fa3fd7ceceee021f 100755 (executable)
@@ -14,5 +14,12 @@ set -ex
 # Setting SHELL to a file instead on a symlink helps android
 # emulator identify the system
 export SHELL=/bin/bash
-nohup nohup emulator @arm-18 -no-window -partition-size 2047 0<&- &>/dev/null &
+
+# Using the default qemu2 engine makes time::tests::since_epoch fails because
+# the emulator date is set to unix epoch (in armeabi-v7a-18 image). Using
+# classic engine the emulator starts with the current date and the tests run
+# fine. If another image is used, this need to be evaluated again.
+nohup nohup emulator @armeabi-v7a-18 \
+    -engine classic -no-window -partition-size 2047 0<&- &>/dev/null &
+
 exec "$@"
index 5dfdf093081cb3ba7dd117e1ba5c9e01307dc3d3..801de69a63d544733f6be98befeab05e1dcea31e 100644 (file)
@@ -74,7 +74,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
 RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 5de00d5b02151af9255852dd3e6f645174e49882..30a699c3ba2141429b86d86cee41fa3e0d9742f6 100644 (file)
@@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
diff --git a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile
new file mode 100644 (file)
index 0000000..e15876e
--- /dev/null
@@ -0,0 +1,49 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python2.7 \
+  git \
+  cmake \
+  unzip \
+  sudo \
+  xz-utils \
+  libssl-dev \
+  pkg-config
+
+RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
+    dpkg -i dumb-init_*.deb && \
+    rm dumb-init_*.deb
+
+RUN curl -o /usr/local/bin/sccache \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
+      chmod +x /usr/local/bin/sccache
+
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
+COPY android-ndk.sh /
+RUN . /android-ndk.sh && \
+    download_ndk android-ndk-r13b-linux-x86_64.zip && \
+    make_standalone_toolchain arm64 21 && \
+    remove_ndk
+
+ENV PATH=$PATH:/android/ndk/arm64-21/bin
+
+ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/
+
+ENV HOSTS=aarch64-linux-android
+
+ENV RUST_CONFIGURE_ARGS \
+      --host=$HOSTS \
+      --target=$HOSTS \
+      --aarch64-linux-android-ndk=/android/ndk/arm64-21 \
+      --disable-rpath \
+      --enable-extended \
+      --enable-cargo-openssl-static
+
+ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
diff --git a/src/ci/docker/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/disabled/dist-armv7-android/Dockerfile
new file mode 100644 (file)
index 0000000..0d81e40
--- /dev/null
@@ -0,0 +1,65 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python2.7 \
+  git \
+  cmake \
+  unzip \
+  sudo \
+  xz-utils \
+  libssl-dev \
+  pkg-config
+
+RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
+    dpkg -i dumb-init_*.deb && \
+    rm dumb-init_*.deb
+
+RUN curl -o /usr/local/bin/sccache \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
+      chmod +x /usr/local/bin/sccache
+
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
+COPY android-ndk.sh /
+RUN . /android-ndk.sh && \
+    download_ndk android-ndk-r13b-linux-x86_64.zip && \
+    make_standalone_toolchain arm 9 && \
+    make_standalone_toolchain arm 21 && \
+    remove_ndk
+
+ENV PATH=$PATH:/android/ndk/arm-9/bin
+
+ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/
+
+ENV HOSTS=armv7-linux-androideabi
+
+ENV RUST_CONFIGURE_ARGS \
+      --host=$HOSTS \
+      --target=$HOSTS \
+      --armv7-linux-androideabi-ndk=/android/ndk/arm \
+      --disable-rpath \
+      --enable-extended \
+      --enable-cargo-openssl-static
+
+# We support api level 9, but api level 21 is required to build llvm. To
+# overcome this problem we use a ndk with api level 21 to build llvm and then
+# switch to a ndk with api level 9 to complete the build. When the linker is
+# invoked there are missing symbols (like sigsetempty, not available with api
+# level 9), the default linker behavior is to generate an error, to allow the
+# build to finish we use --warn-unresolved-symbols. Note that the missing
+# symbols does not affect std, only the compiler (llvm) and cargo (openssl).
+RUN chmod 777 /android/ndk && \
+    ln -s /android/ndk/arm-21 /android/ndk/arm
+
+ENV SCRIPT \
+  python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \
+  (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \
+    rm /android/ndk/arm && \
+    ln -s /android/ndk/arm-9 /android/ndk/arm && \
+    python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
diff --git a/src/ci/docker/disabled/dist-i686-android/Dockerfile b/src/ci/docker/disabled/dist-i686-android/Dockerfile
new file mode 100644 (file)
index 0000000..3793063
--- /dev/null
@@ -0,0 +1,65 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python2.7 \
+  git \
+  cmake \
+  unzip \
+  sudo \
+  xz-utils \
+  libssl-dev \
+  pkg-config
+
+RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
+    dpkg -i dumb-init_*.deb && \
+    rm dumb-init_*.deb
+
+RUN curl -o /usr/local/bin/sccache \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
+      chmod +x /usr/local/bin/sccache
+
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
+COPY android-ndk.sh /
+RUN . /android-ndk.sh && \
+    download_ndk android-ndk-r13b-linux-x86_64.zip && \
+    make_standalone_toolchain x86 9 && \
+    make_standalone_toolchain x86 21 && \
+    remove_ndk
+
+ENV PATH=$PATH:/android/ndk/x86-9/bin
+
+ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/
+
+ENV HOSTS=i686-linux-android
+
+ENV RUST_CONFIGURE_ARGS \
+      --host=$HOSTS \
+      --target=$HOSTS \
+      --i686-linux-android-ndk=/android/ndk/x86 \
+      --disable-rpath \
+      --enable-extended \
+      --enable-cargo-openssl-static
+
+# We support api level 9, but api level 21 is required to build llvm. To
+# overcome this problem we use a ndk with api level 21 to build llvm and then
+# switch to a ndk with api level 9 to complete the build. When the linker is
+# invoked there are missing symbols (like sigsetempty, not available with api
+# level 9), the default linker behavior is to generate an error, to allow the
+# build to finish we use --warn-unresolved-symbols. Note that the missing
+# symbols does not affect std, only the compiler (llvm) and cargo (openssl).
+RUN chmod 777 /android/ndk && \
+    ln -s /android/ndk/x86-21 /android/ndk/x86
+
+ENV SCRIPT \
+  python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \
+  (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \
+    rm /android/ndk/x86 && \
+    ln -s /android/ndk/x86-9 /android/ndk/x86 && \
+    python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
diff --git a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile
new file mode 100644 (file)
index 0000000..a642d8e
--- /dev/null
@@ -0,0 +1,49 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python2.7 \
+  git \
+  cmake \
+  unzip \
+  sudo \
+  xz-utils \
+  libssl-dev \
+  pkg-config
+
+RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
+    dpkg -i dumb-init_*.deb && \
+    rm dumb-init_*.deb
+
+RUN curl -o /usr/local/bin/sccache \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
+      chmod +x /usr/local/bin/sccache
+
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
+COPY android-ndk.sh /
+RUN . /android-ndk.sh && \
+    download_ndk android-ndk-r13b-linux-x86_64.zip && \
+    make_standalone_toolchain x86_64 21 && \
+    remove_ndk
+
+ENV PATH=$PATH:/android/ndk/x86_64-21/bin
+
+ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/
+
+ENV HOSTS=x86_64-linux-android
+
+ENV RUST_CONFIGURE_ARGS \
+      --host=$HOSTS \
+      --target=$HOSTS \
+      --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \
+      --disable-rpath \
+      --enable-extended \
+      --enable-cargo-openssl-static
+
+ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
index a694bf84b18cdbc4fbd6f1db28d90a55cb88883b..c8257c05acdd40466e2f38ecddee4a819811f227 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
index 1dd97fd4e047145223da8d449263f8c483c3b41e..711c0ee5747000f4796bf855214ccf8753560064 100644 (file)
@@ -1,7 +1,6 @@
 FROM ubuntu:16.04
 
-RUN dpkg --add-architecture i386 && \
-    apt-get update && \
+RUN apt-get update && \
     apt-get install -y --no-install-recommends \
   g++ \
   make \
@@ -12,28 +11,30 @@ RUN dpkg --add-architecture i386 && \
   git \
   cmake \
   unzip \
-  expect \
-  openjdk-9-jre \
   sudo \
-  libstdc++6:i386 \
   xz-utils \
   libssl-dev \
   pkg-config
 
-WORKDIR /android/
-ENV PATH=$PATH:/android/ndk-arm-9/bin:/android/sdk/tools:/android/sdk/platform-tools
-
-COPY install-ndk.sh /android/
-RUN sh /android/install-ndk.sh
-
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
     dpkg -i dumb-init_*.deb && \
     rm dumb-init_*.deb
-ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
-      chmod +x /usr/local/bin/sccache
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
+    chmod +x /usr/local/bin/sccache
+
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
+# Install NDK
+COPY install-ndk.sh /tmp
+RUN . /tmp/install-ndk.sh && \
+    download_ndk android-ndk-r13b-linux-x86_64.zip && \
+    make_standalone_toolchain arm 9 && \
+    make_standalone_toolchain x86 9 && \
+    make_standalone_toolchain arm64 21 && \
+    make_standalone_toolchain x86_64 21 && \
+    remove_ndk
 
 ENV TARGETS=arm-linux-androideabi
 ENV TARGETS=$TARGETS,armv7-linux-androideabi
@@ -44,10 +45,10 @@ ENV TARGETS=$TARGETS,x86_64-linux-android
 ENV RUST_CONFIGURE_ARGS \
       --target=$TARGETS \
       --enable-extended \
-      --arm-linux-androideabi-ndk=/android/ndk-arm-9 \
-      --armv7-linux-androideabi-ndk=/android/ndk-arm-9 \
-      --i686-linux-android-ndk=/android/ndk-x86-9 \
-      --aarch64-linux-android-ndk=/android/ndk-arm64-21 \
-      --x86_64-linux-android-ndk=/android/ndk-x86_64-21
+      --arm-linux-androideabi-ndk=/android/ndk/arm-9 \
+      --armv7-linux-androideabi-ndk=/android/ndk/arm-9 \
+      --i686-linux-android-ndk=/android/ndk/x86-9 \
+      --aarch64-linux-android-ndk=/android/ndk/arm64-21 \
+      --x86_64-linux-android-ndk=/android/ndk/x86_64-21
 
 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
index d3a2d31754543c0b95c64861062e4367976bb2ac..80818721199838adf8fa0a6b509739366098e9c5 100644 (file)
 
 set -ex
 
-# Prep the Android NDK
-#
-# See https://github.com/servo/servo/wiki/Building-for-Android
-curl -O https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip
-unzip -q android-ndk-r11c-linux-x86_64.zip
-bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
-        --platform=android-9 \
-        --toolchain=arm-linux-androideabi-4.9 \
-        --install-dir=/android/ndk-arm-9 \
-        --ndk-dir=/android/android-ndk-r11c \
-        --arch=arm
-bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
-        --platform=android-21 \
-        --toolchain=aarch64-linux-android-4.9 \
-        --install-dir=/android/ndk-arm64-21 \
-        --ndk-dir=/android/android-ndk-r11c \
-        --arch=arm64
-bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
-        --platform=android-9 \
-        --toolchain=x86-4.9 \
-        --install-dir=/android/ndk-x86-9 \
-        --ndk-dir=/android/android-ndk-r11c \
-        --arch=x86
-bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
-        --platform=android-21 \
-        --toolchain=x86_64-4.9 \
-        --install-dir=/android/ndk-x86_64-21 \
-        --ndk-dir=/android/android-ndk-r11c \
-        --arch=x86_64
+URL=https://dl.google.com/android/repository
+
+download_ndk() {
+    mkdir -p /android/ndk
+    cd /android/ndk
+    curl -O $URL/$1
+    unzip -q $1
+    rm $1
+    mv android-ndk-* ndk
+}
+
+make_standalone_toolchain() {
+    # See https://developer.android.com/ndk/guides/standalone_toolchain.html
+    python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \
+        --install-dir /android/ndk/$1-$2 \
+        --arch $1 \
+        --api $2
+}
 
-rm -rf ./android-ndk-r11c-linux-x86_64.zip ./android-ndk-r11c
+remove_ndk() {
+    rm -rf /android/ndk/ndk
+}
index 3ee183115724201994937c071df0540f47f64790..af2b58f7d6b7f5d5ab8d82a721e0d0259e2898d7 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
index 902e2e7e6e140265fd01f48bc516c9c055764d56..076bc50946cac66f8103260413b7cec93629b59b 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabihf/bin
index d6a66c2f4a33b5e134371e28d31966f486ba9087..9367a5a6270cf257b12b5f52ba71b5054f38a560 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/armv7-unknown-linux-gnueabihf/bin
index b079f12f7e5e8f67efbe6e6011e3ad8c707eac66..8699e0d87d7fafad7a5fa995578a2cdb8b7f001b 100644 (file)
@@ -30,7 +30,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index 6ea7db03cd51f61024e777340460f85d4c528e58..3e823339eaaf9890195627f45e592e5c7f2e42ff 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index b9e5f91b373a8da6eeefaa2d9d58754bd97599c5..a1f36257f960ab022f4a0c3a0a9b7b26bda24fac 100644 (file)
@@ -25,7 +25,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index a15d6c4e53dbac3305f50b7ea1af0a5144132cf7..8335147de60a02514181afc3cc4146dc9d9da99d 100644 (file)
@@ -82,7 +82,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=i686-unknown-linux-gnu
index dbcdf2eb9d6a5ae2a149baa6da1ce9610bc7de63..c23240f0c70f9a4475c587158781c7bae20819de 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index d0e59253a0f3edfbafb519ab77a3126de1e7e3e3..415dca99d95ee1ec427b2fc526f391929309742c 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 6645d0cbaad5b10f23d9dd3a728ea660274c7e06..2aba5f615baba476103944d4856bf80b6eb699f9 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index dae1972e49688fb441bce99e96f671a153ec8709..d15e3010863c464827b9916fbece7ea4d0b134c8 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index b43bf8beb26e1a7c94e9e736cc0f86d26d5d7e16..bff6504749e1a516e8b3e58b99f5ad59445a8c96 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
index 540415e7e272ee8cd543e57f5e8f4645b9767107..58b09fd0fa7316af8964eb4b57e8771915ac08e8 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc64-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
index 08ab0f37b62570627ad6b65f1fae73463bd88d6d..08f1d1d7ed5f7518083f0382f2807ba084e1615c 100644 (file)
@@ -63,7 +63,7 @@ COPY shared.sh build-powerpc64le-toolchain.sh /tmp/
 RUN ./build-powerpc64le-toolchain.sh
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index a758559e0c108b4d8604ce5dfd53c0412f1e2e1b..5eb238fa887b660c7fdfe5b6b439566cd6cfdcf7 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-s390x-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin
index 8c3e86fd9ad71b19731b1ed8b35d03aa90fe787e..0ac58468147d23b1f60194d6f00a8030ed8b38b2 100644 (file)
@@ -25,7 +25,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index d3db8bde0391be158c4f5f135b61dcef87b68bc5..d688bb7f8a4c4b0b60656736bac9ad29a4aded6e 100644 (file)
@@ -82,7 +82,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=x86_64-unknown-linux-gnu
index d58741132dccc905caf206acf132fa237cf06b37..87550641bc6d58528ecab2a9d9bbb9fcee0eaa60 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index 5c2fbbdf30f3618b8f0f3f7e674f9e2cb1ac3714..b6d9c221c1ce85bae3913c393ce08664c35ca92e 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-netbsd-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
index dcbf1c7396376eb6d8880dfe5b94ee606992e2ee..09657d2f89211febe8a0ddc70c629dc889bbb062 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   lib32stdc++6
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 94554111104498bf7611803fc90a9996623afbda..076be8f429116581f088eb49f1e09d4452a27c29 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 12c9cdf4a112c876d4515afeaa667702c41dd7dd..5fac05735746761982775c05d14be3758701d1fe 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 59b93b784b2f6f27db319fc06d23c2fa93a4600c..6abbf0530afa69c6ebb333823f8b3d562495bb9f 100755 (executable)
@@ -21,11 +21,27 @@ root_dir="`dirname $src_dir`"
 
 source "$ci_dir/shared.sh"
 
-retry docker \
-  build \
-  --rm \
-  -t rust-ci \
-  "`dirname "$script"`/$image"
+if [ -f "$docker_dir/$image/Dockerfile" ]; then
+    retry docker \
+      build \
+      --rm \
+      -t rust-ci \
+      "$docker_dir/$image"
+elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
+    if [ -n "$TRAVIS_OS_NAME" ]; then
+        echo Cannot run disabled images on travis!
+        exit 1
+    fi
+    retry docker \
+      build \
+      --rm \
+      -t rust-ci \
+      -f "$docker_dir/disabled/$image/Dockerfile" \
+      "$docker_dir"
+else
+    echo Invalid image: $image
+    exit 1
+fi
 
 objdir=$root_dir/obj
 
index d1f421248df5bfadb5f6c1beed987881f06af0d2..06c7c2824fd9d45b76b40d21e1f788d5a32affce 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 86704126700be4c9165b0482a5635c474bb89a93..6ea54ac4db3e7f2a8b384b2a869cbe19dff85695 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 26d1f82efcc59ba0945e308f91e0fcc019b65683..e24c660a8c36d804fe267d7a8f2ed0662e7cf660 100644 (file)
@@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 3626301d7e9a22be0db82bb6c9ca65a9de78353c..78035c7fe3d7f9410321bd7f89783b24f48cbc30 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 42b2d98d332eb1fa12822fa220b60609eb74ffd1..0aaed64e384ed486e9dcaafa5e4737c3bf29897c 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 8bff767609f415117bb86f01c53a6d46c4bc52a4..7c136fa39bc8bb2accc5b5c0d1bd6dffcdf6e978 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index c2c1ac8787903117afd29ce7bc910bbf3e2eab4c..4499736967cf49194a8c398d7b9a7b3968be804c 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 727cc84643fbec74b41c14d99930d76f8a994882..de85e1ff36af8ca3f2e5515afc1427c6fd9a216f 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 3d9e7c7fd860dd33f1b3b793f83ca3d102fc0425..8f26e4d36cda2dd52d48073160c5e3073d197c1e 100644 (file)
     - [peek](library-features/peek.md)
     - [placement_in](library-features/placement-in.md)
     - [placement_new_protocol](library-features/placement-new-protocol.md)
-    - [print](library-features/print.md)
+    - [print_internals](library-features/print-internals.md)
     - [proc_macro_internals](library-features/proc-macro-internals.md)
     - [process_try_wait](library-features/process-try-wait.md)
     - [question_mark_carrier](library-features/question-mark-carrier.md)
diff --git a/src/doc/unstable-book/src/library-features/print-internals.md b/src/doc/unstable-book/src/library-features/print-internals.md
new file mode 100644 (file)
index 0000000..a685578
--- /dev/null
@@ -0,0 +1,5 @@
+# `print_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/library-features/print.md b/src/doc/unstable-book/src/library-features/print.md
deleted file mode 100644 (file)
index dc25cb2..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# `print`
-
-This feature is internal to the Rust compiler and is not intended for general use.
-
-------------------------
index 6d85183faf75d9867b2f54d531b74e30973b9a07..27ecefe043b1e333b7788a4444c74ff519c35be3 100644 (file)
 /// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex],
 /// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types.
 ///
-/// `Arc` uses atomic operations for reference counting, so `Arc`s can be
-/// sent between threads. In other words, `Arc<T>` implements [`Send`]
-/// as long as `T` implements [`Send`] and [`Sync`][sync]. The disadvantage is
-/// that atomic operations are more expensive than ordinary memory accesses.
-/// If you are not sharing reference-counted values between threads, consider
-/// using [`rc::Rc`][`Rc`] for lower overhead. [`Rc`] is a safe default, because
-/// the compiler will catch any attempt to send an [`Rc`] between threads.
-/// However, a library might choose `Arc` in order to give library consumers
+/// ## Thread Safety
+///
+/// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference
+/// counting  This means that it is thread-safe. The disadvantage is that
+/// atomic operations are more expensive than ordinary memory accesses. If you
+/// are not sharing reference-counted values between threads, consider using
+/// [`Rc<T>`] for lower overhead. [`Rc<T>`] is a safe default, because the
+/// compiler will catch any attempt to send an [`Rc<T>`] between threads.
+/// However, a library might choose `Arc<T>` in order to give library consumers
 /// more flexibility.
 ///
+/// `Arc<T>` will implement [`Send`] and [`Sync`] as long as the `T` implements
+/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an
+/// `Arc<T>` to make it thread-safe? This may be a bit counter-intuitive at
+/// first: after all, isn't the point of `Arc<T>` thread safety? The key is
+/// this: `Arc<T>` makes it thread safe to have multiple ownership of the same
+/// data, but it  doesn't add thread safety to its data. Consider
+/// `Arc<RefCell<T>>`. `RefCell<T>` isn't [`Sync`], and if `Arc<T>` was always
+/// [`Send`], `Arc<RefCell<T>>` would be as well. But then we'd have a problem:
+/// `RefCell<T>` is not thread safe; it keeps track of the borrowing count using
+/// non-atomic operations.
+///
+/// In the end, this means that you may need to pair `Arc<T>` with some sort of
+/// `std::sync` type, usually `Mutex<T>`.
+///
+/// ## Breaking cycles with `Weak`
+///
 /// The [`downgrade`][downgrade] method can be used to create a non-owning
 /// [`Weak`][weak] pointer. A [`Weak`][weak] pointer can be [`upgrade`][upgrade]d
 /// to an `Arc`, but this will return [`None`] if the value has already been
@@ -74,6 +91,8 @@
 /// strong `Arc` pointers from parent nodes to children, and [`Weak`][weak]
 /// pointers from children back to their parents.
 ///
+/// ## `Deref` behavior
+///
 /// `Arc<T>` automatically dereferences to `T` (via the [`Deref`][deref] trait),
 /// so you can call `T`'s methods on a value of type `Arc<T>`. To avoid name
 /// clashes with `T`'s methods, the methods of `Arc<T>` itself are [associated
 ///
 /// [arc]: struct.Arc.html
 /// [weak]: struct.Weak.html
-/// [`Rc`]: ../../std/rc/struct.Rc.html
+/// [`Rc<T>`]: ../../std/rc/struct.Rc.html
 /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
 /// [mutex]: ../../std/sync/struct.Mutex.html
 /// [rwlock]: ../../std/sync/struct.RwLock.html
 /// [atomic]: ../../std/sync/atomic/index.html
 /// [`Send`]: ../../std/marker/trait.Send.html
-/// [sync]: ../../std/marker/trait.Sync.html
+/// [`Sync`]: ../../std/marker/trait.Sync.html
 /// [deref]: ../../std/ops/trait.Deref.html
 /// [downgrade]: struct.Arc.html#method.downgrade
 /// [upgrade]: struct.Weak.html#method.upgrade
index a60abefc076504027bdc99141b9add789bda7060..5f189d473be79f95c56ed2a9cc657ced02559d05 100644 (file)
@@ -1005,7 +1005,7 @@ unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
 
 #[unstable(feature = "unique", issue = "27730")]
 impl<T: Sized> Unique<T> {
-    /// Creates a new `Shared` that is dangling, but well-aligned.
+    /// Creates a new `Unique` that is dangling, but well-aligned.
     ///
     /// This is useful for initializing types which lazily allocate, like
     /// `Vec::new` does.
index af425a95fb19ccc55da7e84a3bedd435e7f0367a..25fc5b7a4f6d9f9c9ff2e9b101205a3dad18a20e 100644 (file)
@@ -159,6 +159,14 @@ pub enum DepNode<D: Clone + Debug> {
     DefSpan(D),
     Stability(D),
     Deprecation(D),
+    ItemBodyNestedBodies(D),
+    ConstIsRvaluePromotableToStatic(D),
+    ImplParent(D),
+    TraitOfItem(D),
+    IsExportedSymbol(D),
+    IsMirAvailable(D),
+    ItemAttrs(D),
+    FnArgNames(D),
     FileMap(D, Arc<String>),
 }
 
@@ -273,6 +281,14 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             DefSpan(ref d) => op(d).map(DefSpan),
             Stability(ref d) => op(d).map(Stability),
             Deprecation(ref d) => op(d).map(Deprecation),
+            ItemAttrs(ref d) => op(d).map(ItemAttrs),
+            FnArgNames(ref d) => op(d).map(FnArgNames),
+            ImplParent(ref d) => op(d).map(ImplParent),
+            TraitOfItem(ref d) => op(d).map(TraitOfItem),
+            IsExportedSymbol(ref d) => op(d).map(IsExportedSymbol),
+            ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
+            ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
+            IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
             GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
             FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())),
         }
index 1bac512e20977b087d4fdd09b35e336bbf8e8e9b..82578f6aa61d5a78ca3fb793cc582a1179c2ff87 100644 (file)
@@ -42,9 +42,8 @@
 use ty::{IntType, UintType};
 use ty::{self, Ty, TyCtxt};
 use ty::error::TypeError;
-use ty::fold::TypeFoldable;
-use ty::relate::{RelateResult, TypeRelation};
-use traits::PredicateObligations;
+use ty::relate::{self, Relate, RelateResult, TypeRelation};
+use traits::{Obligation, PredicateObligations};
 
 use syntax::ast;
 use syntax_pos::Span;
@@ -207,11 +206,16 @@ pub fn instantiate(&mut self,
         // `'?2` and `?3` are fresh region/type inference
         // variables. (Down below, we will relate `a_ty <: b_ty`,
         // adding constraints like `'x: '?2` and `?1 <: ?3`.)
-        let b_ty = self.generalize(a_ty, b_vid, dir == EqTo)?;
+        let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?;
         debug!("instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})",
                a_ty, dir, b_vid, b_ty);
         self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty);
 
+        if needs_wf {
+            self.obligations.push(Obligation::new(self.trace.cause.clone(),
+                                                  ty::Predicate::WellFormed(b_ty)));
+        }
+
         // Finally, relate `b_ty` to `a_ty`, as described in previous comment.
         //
         // FIXME(#16847): This code is non-ideal because all these subtype
@@ -230,10 +234,9 @@ pub fn instantiate(&mut self,
 
     /// Attempts to generalize `ty` for the type variable `for_vid`.
     /// This checks for cycle -- that is, whether the type `ty`
-    /// references `for_vid`. If `is_eq_relation` is false, it will
-    /// also replace all regions/unbound-type-variables with fresh
-    /// variables. Returns `TyError` in the case of a cycle, `Ok`
-    /// otherwise.
+    /// references `for_vid`. The `dir` is the "direction" for which we
+    /// a performing the generalization (i.e., are we producing a type
+    /// that can be used as a supertype etc).
     ///
     /// Preconditions:
     ///
@@ -241,22 +244,33 @@ pub fn instantiate(&mut self,
     fn generalize(&self,
                   ty: Ty<'tcx>,
                   for_vid: ty::TyVid,
-                  is_eq_relation: bool)
-                  -> RelateResult<'tcx, Ty<'tcx>>
+                  dir: RelationDir)
+                  -> RelateResult<'tcx, Generalization<'tcx>>
     {
+        // Determine the ambient variance within which `ty` appears.
+        // The surrounding equation is:
+        //
+        //     ty [op] ty2
+        //
+        // where `op` is either `==`, `<:`, or `:>`. This maps quite
+        // naturally.
+        let ambient_variance = match dir {
+            RelationDir::EqTo => ty::Invariant,
+            RelationDir::SubtypeOf => ty::Covariant,
+            RelationDir::SupertypeOf => ty::Contravariant,
+        };
+
         let mut generalize = Generalizer {
             infcx: self.infcx,
             span: self.trace.cause.span,
             for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
-            is_eq_relation: is_eq_relation,
-            cycle_detected: false
+            ambient_variance: ambient_variance,
+            needs_wf: false,
         };
-        let u = ty.fold_with(&mut generalize);
-        if generalize.cycle_detected {
-            Err(TypeError::CyclicTy)
-        } else {
-            Ok(u)
-        }
+
+        let ty = generalize.relate(&ty, &ty)?;
+        let needs_wf = generalize.needs_wf;
+        Ok(Generalization { ty, needs_wf })
     }
 }
 
@@ -264,16 +278,81 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
     infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
     span: Span,
     for_vid_sub_root: ty::TyVid,
-    is_eq_relation: bool,
-    cycle_detected: bool,
+    ambient_variance: ty::Variance,
+    needs_wf: bool, // see the field `needs_wf` in `Generalization`
 }
 
-impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
-    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
+/// Result from a generalization operation. This includes
+/// not only the generalized type, but also a bool flag
+/// indicating whether further WF checks are needed.q
+struct Generalization<'tcx> {
+    ty: Ty<'tcx>,
+
+    /// If true, then the generalized type may not be well-formed,
+    /// even if the source type is well-formed, so we should add an
+    /// additional check to enforce that it is. This arises in
+    /// particular around 'bivariant' type parameters that are only
+    /// constrained by a where-clause. As an example, imagine a type:
+    ///
+    ///     struct Foo<A, B> where A: Iterator<Item=B> {
+    ///         data: A
+    ///     }
+    ///
+    /// here, `A` will be covariant, but `B` is
+    /// unconstrained. However, whatever it is, for `Foo` to be WF, it
+    /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
+    /// then after generalization we will wind up with a type like
+    /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
+    /// ?D>` (or `>:`), we will wind up with the requirement that `?A
+    /// <: ?C`, but no particular relationship between `?B` and `?D`
+    /// (after all, we do not know the variance of the normalized form
+    /// of `A::Item` with respect to `A`). If we do nothing else, this
+    /// may mean that `?D` goes unconstrained (as in #41677).  So, in
+    /// this scenario where we create a new type variable in a
+    /// bivariant context, we set the `needs_wf` flag to true. This
+    /// will force the calling code to check that `WF(Foo<?C, ?D>)`
+    /// holds, which in turn implies that `?C::Item == ?D`. So once
+    /// `?C` is constrained, that should suffice to restrict `?D`.
+    needs_wf: bool,
+}
+
+impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
         self.infcx.tcx
     }
 
-    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+    fn tag(&self) -> &'static str {
+        "Generalizer"
+    }
+
+    fn a_is_expected(&self) -> bool {
+        true
+    }
+
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'tcx>
+    {
+        Ok(ty::Binder(self.relate(a.skip_binder(), b.skip_binder())?))
+    }
+
+    fn relate_with_variance<T: Relate<'tcx>>(&mut self,
+                                             variance: ty::Variance,
+                                             a: &T,
+                                             b: &T)
+                                             -> RelateResult<'tcx, T>
+    {
+        let old_ambient_variance = self.ambient_variance;
+        self.ambient_variance = self.ambient_variance.xform(variance);
+
+        let result = self.relate(a, b);
+        self.ambient_variance = old_ambient_variance;
+        result
+    }
+
+    fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
+
         // Check to see whether the type we are genealizing references
         // any other type variable related to `vid` via
         // subtyping. This is basically our "occurs check", preventing
@@ -286,41 +365,63 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
                 if sub_vid == self.for_vid_sub_root {
                     // If sub-roots are equal, then `for_vid` and
                     // `vid` are related via subtyping.
-                    self.cycle_detected = true;
-                    self.tcx().types.err
+                    return Err(TypeError::CyclicTy);
                 } else {
                     match variables.probe_root(vid) {
                         Some(u) => {
                             drop(variables);
-                            self.fold_ty(u)
+                            self.relate(&u, &u)
                         }
                         None => {
-                            if !self.is_eq_relation {
-                                let origin = variables.origin(vid);
-                                let new_var_id = variables.new_var(false, origin, None);
-                                let u = self.tcx().mk_var(new_var_id);
-                                debug!("generalize: replacing original vid={:?} with new={:?}",
-                                       vid, u);
-                                u
-                            } else {
-                                t
+                            match self.ambient_variance {
+                                // Invariant: no need to make a fresh type variable.
+                                ty::Invariant => return Ok(t),
+
+                                // Bivariant: make a fresh var, but we
+                                // may need a WF predicate. See
+                                // comment on `needs_wf` field for
+                                // more info.
+                                ty::Bivariant => self.needs_wf = true,
+
+                                // Co/contravariant: this will be
+                                // sufficiently constrained later on.
+                                ty::Covariant | ty::Contravariant => (),
                             }
+
+                            let origin = variables.origin(vid);
+                            let new_var_id = variables.new_var(false, origin, None);
+                            let u = self.tcx().mk_var(new_var_id);
+                            debug!("generalize: replacing original vid={:?} with new={:?}",
+                                   vid, u);
+                            return Ok(u);
                         }
                     }
                 }
             }
+            ty::TyInfer(ty::IntVar(_)) |
+            ty::TyInfer(ty::FloatVar(_)) => {
+                // No matter what mode we are in,
+                // integer/floating-point types must be equal to be
+                // relatable.
+                Ok(t)
+            }
             _ => {
-                t.super_fold_with(self)
+                relate::super_relate_tys(self, t, t)
             }
         }
     }
 
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+    fn regions(&mut self, r: ty::Region<'tcx>, r2: ty::Region<'tcx>)
+               -> RelateResult<'tcx, ty::Region<'tcx>> {
+        assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
+
         match *r {
             // Never make variables for regions bound within the type itself,
             // nor for erased regions.
             ty::ReLateBound(..) |
-            ty::ReErased => { return r; }
+            ty::ReErased => {
+                return Ok(r);
+            }
 
             // Early-bound regions should really have been substituted away before
             // we get to this point.
@@ -342,15 +443,16 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
             ty::ReScope(..) |
             ty::ReVar(..) |
             ty::ReFree(..) => {
-                if self.is_eq_relation {
-                    return r;
+                match self.ambient_variance {
+                    ty::Invariant => return Ok(r),
+                    ty::Bivariant | ty::Covariant | ty::Contravariant => (),
                 }
             }
         }
 
         // FIXME: This is non-ideal because we don't give a
         // very descriptive origin for this region variable.
-        self.infcx.next_region_var(MiscVariable(self.span))
+        Ok(self.infcx.next_region_var(MiscVariable(self.span)))
     }
 }
 
index f0b179fa2e4205ac2d8b5f6b1818b71e3d193308..f9ffaee81f1573de6c636e685d0418c45f0e9e33 100644 (file)
 use super::combine::{CombineFields, RelationDir};
 use super::{Subtype};
 
+use hir::def_id::DefId;
+
 use ty::{self, Ty, TyCtxt};
 use ty::TyVar;
-use ty::relate::{Relate, RelateResult, TypeRelation};
+use ty::subst::Substs;
+use ty::relate::{self, Relate, RelateResult, TypeRelation};
 
 /// Ensures `a` is made equal to `b`. Returns `a` on success.
 pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
@@ -38,6 +41,22 @@ fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
+    fn relate_item_substs(&mut self,
+                          _item_def_id: DefId,
+                          a_subst: &'tcx Substs<'tcx>,
+                          b_subst: &'tcx Substs<'tcx>)
+                          -> RelateResult<'tcx, &'tcx Substs<'tcx>>
+    {
+        // NB: Once we are equating types, we don't care about
+        // variance, so don't try to lookup the variance here. This
+        // also avoids some cycles (e.g. #41849) since looking up
+        // variance requires computing types which can require
+        // performing trait matching (which then performs equality
+        // unification).
+
+        relate::relate_substs(self, None, a_subst, b_subst)
+    }
+
     fn relate_with_variance<T: Relate<'tcx>>(&mut self,
                                              _: ty::Variance,
                                              a: &T,
index 49952d81cbb0b8918bffae54a5b2769205506924..963c14c48c82947d834ce678414af72817c5fcfc 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use infer::{self, InferCtxt, SubregionOrigin};
-use ty::Region;
+use ty::{self, Region};
 use ty::error::TypeError;
 use errors::DiagnosticBuilder;
 
@@ -262,7 +262,14 @@ pub(super) fn report_concrete_failure(&self,
                                                "the type `{}` does not fulfill the required \
                                                 lifetime",
                                                self.ty_to_string(ty));
-                self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, "");
+                match *sub {
+                    ty::ReStatic => {
+                        self.tcx.note_and_explain_region(&mut err, "type must satisfy ", sub, "")
+                    }
+                    _ => {
+                        self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, "")
+                    }
+                }
                 err
             }
             infer::RelateRegionParamBound(span) => {
index 53e684e34bde1408e602531dbe464312f01107f2..569b1aeeb09d7ca1a2e2323746295a89b24708c7 100644 (file)
@@ -210,27 +210,21 @@ pub trait CrateStore {
     fn visibility(&self, def: DefId) -> ty::Visibility;
     fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
     fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
-    fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]>;
-    fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
 
     // trait info
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
 
     // impl info
     fn impl_defaultness(&self, def: DefId) -> hir::Defaultness;
-    fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
 
     // trait/impl-item info
-    fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;
     fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
 
     // flags
     fn is_const_fn(&self, did: DefId) -> bool;
     fn is_default_impl(&self, impl_did: DefId) -> bool;
-    fn is_foreign_item(&self, did: DefId) -> bool;
     fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
-    fn is_exported_symbol(&self, def_id: DefId) -> bool;
 
     // crate metadata
     fn dylib_dependency_formats(&self, cnum: CrateNum)
@@ -336,28 +330,22 @@ fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
     }
     fn item_generics_cloned(&self, def: DefId) -> ty::Generics
         { bug!("item_generics_cloned") }
-    fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]> { bug!("item_attrs") }
-    fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
 
     // trait info
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
 
     // impl info
     fn impl_defaultness(&self, def: DefId) -> hir::Defaultness { bug!("impl_defaultness") }
-    fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
 
     // trait/impl-item info
-    fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") }
     fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
         { bug!("associated_item_cloned") }
 
     // flags
     fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
     fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
-    fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
     fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
-    fn is_exported_symbol(&self, def_id: DefId) -> bool { false }
 
     // crate metadata
     fn dylib_dependency_formats(&self, cnum: CrateNum)
index e03948db3683187e542d3fba3f4dc993a6264109..5360a86560d399235a660c877c47090fea23bf3f 100644 (file)
@@ -205,7 +205,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
                     } else if match self.tcx.hir.get_if_local(def_id) {
                         Some(hir::map::NodeForeignItem(..)) => true,
                         Some(..) => false,
-                        None => self.tcx.sess.cstore.is_foreign_item(def_id),
+                        None => self.tcx.is_foreign_item(def_id),
                     } {
                         self.require_unsafe_ext(expr.id, expr.span, "use of extern static", true);
                     }
index b517ebabbe767622e9b4ab7e1b1e099a328bf3f1..fe2ad498e99610635faf0a4889717dc7a7422904 100644 (file)
@@ -799,7 +799,7 @@ pub enum StatementKind<'tcx> {
     StorageDead(Lvalue<'tcx>),
 
     InlineAsm {
-        asm: InlineAsm,
+        asm: Box<InlineAsm>,
         outputs: Vec<Lvalue<'tcx>>,
         inputs: Vec<Operand<'tcx>>
     },
@@ -995,7 +995,7 @@ pub struct VisibilityScopeData {
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum Operand<'tcx> {
     Consume(Lvalue<'tcx>),
-    Constant(Constant<'tcx>),
+    Constant(Box<Constant<'tcx>>),
 }
 
 impl<'tcx> Debug for Operand<'tcx> {
@@ -1015,7 +1015,7 @@ pub fn function_handle<'a>(
         substs: &'tcx Substs<'tcx>,
         span: Span,
     ) -> Self {
-        Operand::Constant(Constant {
+        Operand::Constant(box Constant {
             span: span,
             ty: tcx.type_of(def_id).subst(tcx, substs),
             literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
@@ -1062,7 +1062,7 @@ pub enum Rvalue<'tcx> {
     /// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
     /// that `Foo` has a destructor. These rvalues can be optimized
     /// away after type-checking and before lowering.
-    Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),
+    Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
@@ -1185,7 +1185,7 @@ fn fmt_tuple(fmt: &mut Formatter, lvs: &[Operand]) -> fmt::Result {
                     tuple_fmt.finish()
                 }
 
-                match *kind {
+                match **kind {
                     AggregateKind::Array(_) => write!(fmt, "{:?}", lvs),
 
                     AggregateKind::Tuple => {
@@ -1603,7 +1603,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
             Discriminant(ref lval) => Discriminant(lval.fold_with(folder)),
             Box(ty) => Box(ty.fold_with(folder)),
             Aggregate(ref kind, ref fields) => {
-                let kind = match *kind {
+                let kind = box match **kind {
                     AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
                     AggregateKind::Tuple => AggregateKind::Tuple,
                     AggregateKind::Adt(def, v, substs, n) =>
@@ -1631,7 +1631,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
             Discriminant(ref lval) => lval.visit_with(visitor),
             Box(ty) => ty.visit_with(visitor),
             Aggregate(ref kind, ref fields) => {
-                (match *kind {
+                (match **kind {
                     AggregateKind::Array(ty) => ty.visit_with(visitor),
                     AggregateKind::Tuple => false,
                     AggregateKind::Adt(_, _, substs, _) => substs.visit_with(visitor),
index b6020df072853631ce43cfa14d2e01403ed8f9f4..7bc1dc58c29d298ed84a42b603973487732efef2 100644 (file)
@@ -183,7 +183,7 @@ pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'
                 tcx.mk_box(t)
             }
             Rvalue::Aggregate(ref ak, ref ops) => {
-                match *ak {
+                match **ak {
                     AggregateKind::Array(ty) => {
                         tcx.mk_array(ty, ops.len())
                     }
index 31bdd99ef32210abb0e85e91221396ab14d2e355..557fedadeba62155cb0a6cb1ce5767b68f76b35b 100644 (file)
@@ -515,6 +515,7 @@ fn super_rvalue(&mut self,
 
                     Rvalue::Aggregate(ref $($mutability)* kind,
                                       ref $($mutability)* operands) => {
+                        let kind = &$($mutability)* **kind;
                         match *kind {
                             AggregateKind::Array(ref $($mutability)* ty) => {
                                 self.visit_ty(ty);
index 82a4c1e1e626a9e45defaddbae224a31d0641d7b..3b5dc2ae164b60f90d8c6dc617c0e66a01126e76 100644 (file)
@@ -34,6 +34,7 @@
 use std::rc::Rc;
 use syntax_pos::{Span, DUMMY_SP};
 use syntax::attr;
+use syntax::ast;
 use syntax::symbol::Symbol;
 
 pub trait Key: Clone + Hash + Eq + Debug {
@@ -340,6 +341,36 @@ fn describe(_: TyCtxt, _: DefId) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::item_attrs<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("item_attrs")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::is_exported_symbol<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("is_exported_symbol")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::fn_arg_names<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("fn_arg_names")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::impl_parent<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("impl_parent")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::trait_of_item<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("trait_of_item")
+    }
+}
+
 impl<'tcx> QueryDescription for queries::item_body_nested_bodies<'tcx> {
     fn describe(tcx: TyCtxt, def_id: DefId) -> String {
         format!("nested item bodies of `{}`", tcx.item_path_str(def_id))
@@ -781,9 +812,14 @@ fn default() -> Self {
     [] def_span: DefSpan(DefId) -> Span,
     [] stability: Stability(DefId) -> Option<attr::Stability>,
     [] deprecation: Deprecation(DefId) -> Option<attr::Deprecation>,
-    [] item_body_nested_bodies: metadata_dep_node(DefId) -> Rc<BTreeMap<hir::BodyId, hir::Body>>,
-    [] const_is_rvalue_promotable_to_static: metadata_dep_node(DefId) -> bool,
-    [] is_mir_available: metadata_dep_node(DefId) -> bool,
+    [] item_attrs: ItemAttrs(DefId) -> Rc<[ast::Attribute]>,
+    [] fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
+    [] impl_parent: ImplParent(DefId) -> Option<DefId>,
+    [] trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
+    [] is_exported_symbol: IsExportedSymbol(DefId) -> bool,
+    [] item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> Rc<BTreeMap<hir::BodyId, hir::Body>>,
+    [] const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
+    [] is_mir_available: IsMirAvailable(DefId) -> bool,
 }
 
 fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -798,10 +834,6 @@ fn reachability_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::Reachability
 }
 
-fn metadata_dep_node(def_id: DefId) -> DepNode<DefId> {
-    DepNode::MetaData(def_id)
-}
-
 fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode<DefId> {
     instance.dep_node()
 }
index 99a5f6325ac7515242f3c9322af7ded3fb295b8c..f5d510c11ae9dd64d1f48b4c3d021b7f29c6e334 100644 (file)
@@ -330,6 +330,66 @@ pub struct CrateVariancesMap {
     pub empty_variance: Rc<Vec<ty::Variance>>,
 }
 
+impl Variance {
+    /// `a.xform(b)` combines the variance of a context with the
+    /// variance of a type with the following meaning.  If we are in a
+    /// context with variance `a`, and we encounter a type argument in
+    /// a position with variance `b`, then `a.xform(b)` is the new
+    /// variance with which the argument appears.
+    ///
+    /// Example 1:
+    ///
+    ///     *mut Vec<i32>
+    ///
+    /// Here, the "ambient" variance starts as covariant. `*mut T` is
+    /// invariant with respect to `T`, so the variance in which the
+    /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
+    /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
+    /// respect to its type argument `T`, and hence the variance of
+    /// the `i32` here is `Invariant.xform(Covariant)`, which results
+    /// (again) in `Invariant`.
+    ///
+    /// Example 2:
+    ///
+    ///     fn(*const Vec<i32>, *mut Vec<i32)
+    ///
+    /// The ambient variance is covariant. A `fn` type is
+    /// contravariant with respect to its parameters, so the variance
+    /// within which both pointer types appear is
+    /// `Covariant.xform(Contravariant)`, or `Contravariant`.  `*const
+    /// T` is covariant with respect to `T`, so the variance within
+    /// which the first `Vec<i32>` appears is
+    /// `Contravariant.xform(Covariant)` or `Contravariant`.  The same
+    /// is true for its `i32` argument. In the `*mut T` case, the
+    /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
+    /// and hence the outermost type is `Invariant` with respect to
+    /// `Vec<i32>` (and its `i32` argument).
+    ///
+    /// Source: Figure 1 of "Taming the Wildcards:
+    /// Combining Definition- and Use-Site Variance" published in PLDI'11.
+    pub fn xform(self, v: ty::Variance) -> ty::Variance {
+        match (self, v) {
+            // Figure 1, column 1.
+            (ty::Covariant, ty::Covariant) => ty::Covariant,
+            (ty::Covariant, ty::Contravariant) => ty::Contravariant,
+            (ty::Covariant, ty::Invariant) => ty::Invariant,
+            (ty::Covariant, ty::Bivariant) => ty::Bivariant,
+
+            // Figure 1, column 2.
+            (ty::Contravariant, ty::Covariant) => ty::Contravariant,
+            (ty::Contravariant, ty::Contravariant) => ty::Covariant,
+            (ty::Contravariant, ty::Invariant) => ty::Invariant,
+            (ty::Contravariant, ty::Bivariant) => ty::Bivariant,
+
+            // Figure 1, column 3.
+            (ty::Invariant, _) => ty::Invariant,
+
+            // Figure 1, column 4.
+            (ty::Bivariant, _) => ty::Bivariant,
+        }
+    }
+}
+
 #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
 pub struct MethodCallee<'tcx> {
     /// Impl method ID, for inherent methods, or trait method ID, otherwise.
@@ -2360,7 +2420,7 @@ pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
         if let Some(id) = self.hir.as_local_node_id(did) {
             Attributes::Borrowed(self.hir.attrs(id))
         } else {
-            Attributes::Owned(self.sess.cstore.item_attrs(did))
+            Attributes::Owned(self.item_attrs(did))
         }
     }
 
@@ -2396,7 +2456,7 @@ pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
             let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
 
             // Record the trait->implementation mapping.
-            let parent = self.sess.cstore.impl_parent(impl_def_id).unwrap_or(trait_id);
+            let parent = self.impl_parent(impl_def_id).unwrap_or(trait_id);
             def.record_remote_impl(self, impl_def_id, trait_ref, parent);
         }
 
@@ -2433,22 +2493,6 @@ pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
         }
     }
 
-    /// If the given def ID describes an item belonging to a trait,
-    /// return the ID of the trait that the trait item belongs to.
-    /// Otherwise, return `None`.
-    pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
-        if def_id.krate != LOCAL_CRATE {
-            return self.sess.cstore.trait_of_item(def_id);
-        }
-        self.opt_associated_item(def_id)
-            .and_then(|associated_item| {
-                match associated_item.container {
-                    TraitContainer(def_id) => Some(def_id),
-                    ImplContainer(_) => None
-                }
-            })
-    }
-
     /// Construct a parameter environment suitable for static contexts or other contexts where there
     /// are no free type/lifetime parameters in scope.
     pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> {
@@ -2688,6 +2732,20 @@ fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span {
     tcx.hir.span_if_local(def_id).unwrap()
 }
 
+/// If the given def ID describes an item belonging to a trait,
+/// return the ID of the trait that the trait item belongs to.
+/// Otherwise, return `None`.
+fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId> {
+    tcx.opt_associated_item(def_id)
+        .and_then(|associated_item| {
+            match associated_item.container {
+                TraitContainer(def_id) => Some(def_id),
+                ImplContainer(_) => None
+            }
+        })
+}
+
+
 pub fn provide(providers: &mut ty::maps::Providers) {
     *providers = ty::maps::Providers {
         associated_item,
@@ -2695,6 +2753,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         adt_sized_constraint,
         adt_dtorck_constraint,
         def_span,
+        trait_of_item,
         ..*providers
     };
 }
index dfa11b9c71a04c6c038621d4dc63330310fa986b..bbe682e74bc04b6dcfe920808d1faae0df10b883 100644 (file)
@@ -51,6 +51,24 @@ fn relate<T: Relate<'tcx>>(&mut self, a: &T, b: &T) -> RelateResult<'tcx, T> {
         Relate::relate(self, a, b)
     }
 
+    /// Relate the two substitutions for the given item. The default
+    /// is to look up the variance for the item and proceed
+    /// accordingly.
+    fn relate_item_substs(&mut self,
+                          item_def_id: DefId,
+                          a_subst: &'tcx Substs<'tcx>,
+                          b_subst: &'tcx Substs<'tcx>)
+                          -> RelateResult<'tcx, &'tcx Substs<'tcx>>
+    {
+        debug!("relate_item_substs(item_def_id={:?}, a_subst={:?}, b_subst={:?})",
+               item_def_id,
+               a_subst,
+               b_subst);
+
+        let opt_variances = self.tcx().variances_of(item_def_id);
+        relate_substs(self, Some(&opt_variances), a_subst, b_subst)
+    }
+
     /// Switch variance for the purpose of relating `a` and `b`.
     fn relate_with_variance<T: Relate<'tcx>>(&mut self,
                                              variance: ty::Variance,
@@ -109,25 +127,6 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
     }
 }
 
-// substitutions are not themselves relatable without more context,
-// but they is an important subroutine for things that ARE relatable,
-// like traits etc.
-fn relate_item_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
-                                         item_def_id: DefId,
-                                         a_subst: &'tcx Substs<'tcx>,
-                                         b_subst: &'tcx Substs<'tcx>)
-                                         -> RelateResult<'tcx, &'tcx Substs<'tcx>>
-    where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
-{
-    debug!("substs: item_def_id={:?} a_subst={:?} b_subst={:?}",
-           item_def_id,
-           a_subst,
-           b_subst);
-
-    let opt_variances = relation.tcx().variances_of(item_def_id);
-    relate_substs(relation, Some(&opt_variances), a_subst, b_subst)
-}
-
 pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
                                         variances: Option<&Vec<ty::Variance>>,
                                         a_subst: &'tcx Substs<'tcx>,
@@ -291,7 +290,7 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
         if a.def_id != b.def_id {
             Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
         } else {
-            let substs = relate_item_substs(relation, a.def_id, a.substs, b.substs)?;
+            let substs = relation.relate_item_substs(a.def_id, a.substs, b.substs)?;
             Ok(ty::TraitRef { def_id: a.def_id, substs: substs })
         }
     }
@@ -308,7 +307,7 @@ fn relate<'a, 'gcx, R>(relation: &mut R,
         if a.def_id != b.def_id {
             Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
         } else {
-            let substs = relate_item_substs(relation, a.def_id, a.substs, b.substs)?;
+            let substs = relation.relate_item_substs(a.def_id, a.substs, b.substs)?;
             Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs: substs })
         }
     }
@@ -372,7 +371,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
         (&ty::TyAdt(a_def, a_substs), &ty::TyAdt(b_def, b_substs))
             if a_def == b_def =>
         {
-            let substs = relate_item_substs(relation, a_def.did, a_substs, b_substs)?;
+            let substs = relation.relate_item_substs(a_def.did, a_substs, b_substs)?;
             Ok(tcx.mk_adt(a_def, substs))
         }
 
index 4ae8bdc284b226760c17ddcd924f71e715679711..4b7d52c25173a58c9640430a87cfe61a84286977 100644 (file)
@@ -517,11 +517,11 @@ fn elaborate_replace(
     }
 
     fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> {
-        Rvalue::Use(Operand::Constant(Constant {
+        Rvalue::Use(Operand::Constant(Box::new(Constant {
             span: span,
             ty: self.tcx.types.bool,
             literal: Literal::Value { value: ConstVal::Bool(val) }
-        }))
+        })))
     }
 
     fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagState) {
index 8b1aa0708807bc4284b8b7f8bad0c09840e7ec70..e79f23aee11456e2fd3f3ce35f7e72a95f45d1ca 100644 (file)
@@ -74,7 +74,7 @@ pub fn lookup_const_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 // constants, we only try to find the expression for a
                 // trait-associated const if the caller gives us the
                 // substitutions for the reference to it.
-                if tcx.sess.cstore.trait_of_item(def_id).is_some() {
+                if tcx.trait_of_item(def_id).is_some() {
                     resolve_trait_associated_const(tcx, def_id, substs)
                 } else {
                     Some((def_id, substs))
index 9cee5bc0319b7f2d723aaeff9459826ac44791c9..024fc546a158efe9d175f4ba7357be522cf1a739 100644 (file)
@@ -636,11 +636,24 @@ fn print_crate_info(sess: &Session,
                             node: ast::MetaItemKind::Word,
                             span: DUMMY_SP,
                         });
-                        if !allow_unstable_cfg && gated_cfg.is_some() {
-                            continue;
+
+                        // Note that crt-static is a specially recognized cfg
+                        // directive that's printed out here as part of
+                        // rust-lang/rust#37406, but in general the
+                        // `target_feature` cfg is gated under
+                        // rust-lang/rust#29717. For now this is just
+                        // specifically allowing the crt-static cfg and that's
+                        // it, this is intended to get into Cargo and then go
+                        // through to build scripts.
+                        let value = value.as_ref().map(|s| s.as_str());
+                        let value = value.as_ref().map(|s| s.as_ref());
+                        if name != "target_feature" || value != Some("crt-static") {
+                            if !allow_unstable_cfg && gated_cfg.is_some() {
+                                continue;
+                            }
                         }
 
-                        cfgs.push(if let &Some(ref value) = value {
+                        cfgs.push(if let Some(value) = value {
                             format!("{}=\"{}\"", name, value)
                         } else {
                             format!("{}", name)
index 718f2b515068b3415033e2cf578e2cb39fd135e5..61bc7c6eb4c714e81f7b1ab3283e3e261d28a4f3 100644 (file)
@@ -12,7 +12,6 @@
 use llvm::LLVMRustHasFeature;
 use rustc::session::Session;
 use rustc_trans::back::write::create_target_machine;
-use syntax::feature_gate::UnstableFeatures;
 use syntax::symbol::Symbol;
 use libc::c_char;
 
@@ -53,8 +52,6 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
     }
 
     let requested_features = sess.opts.cg.target_feature.split(',');
-    let unstable_options = sess.opts.debugging_opts.unstable_options;
-    let is_nightly = UnstableFeatures::from_environment().is_nightly_build();
     let found_negative = requested_features.clone().any(|r| r == "-crt-static");
     let found_positive = requested_features.clone().any(|r| r == "+crt-static");
 
@@ -68,14 +65,6 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
         found_positive
     };
 
-    // If we switched from the default then that's only allowed on nightly, so
-    // gate that here.
-    if (found_positive || found_negative) && (!is_nightly || !unstable_options) {
-        sess.fatal("specifying the `crt-static` target feature is only allowed \
-                    on the nightly channel with `-Z unstable-options` passed \
-                    as well");
-    }
-
     if crt_static {
         cfg.insert((tf, Some(Symbol::intern("crt-static"))));
     }
index 5bc442deafa2bd726524e98d6cd7f09f9d214d3d..2f727a80f016e0589ccb8069554338645c3db31d 100644 (file)
@@ -79,7 +79,11 @@ pub fn hash(&mut self, dep_node: &DepNode<DefId>) -> Option<Fingerprint> {
 
             DepNode::FileMap(def_id, ref name) => {
                 if def_id.is_local() {
-                    Some(self.incremental_hashes_map[dep_node])
+                    // We will have been able to retrace the DefId (which is
+                    // always the local CRATE_DEF_INDEX), but the file with the
+                    // given name might have been removed, so we use get() in
+                    // order to allow for that case.
+                    self.incremental_hashes_map.get(dep_node).map(|x| *x)
                 } else {
                     Some(self.metadata_hash(DepNode::FileMap(def_id, name.clone()),
                                             def_id.krate,
index 715a769158bc3fb832b0613d52f996068cb6eda6..3b6516af35a050f8e1ff29cd2e4bfd5ec91dca79 100644 (file)
@@ -718,7 +718,6 @@ fn fl_lit_check_expr(cx: &EarlyContext, expr: &ast::Expr) {
                     cx.span_lint(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
                                  l.span,
                                  "floating-point literals cannot be used in patterns");
-                    error!("span mc spanspam");
                     },
                 _ => (),
             }
index c7da535faa2946a3ab232ea82b7f59cbb087c615..dbf3e94832fc4fd724a010fe841d440243c406b0 100644 (file)
@@ -41,8 +41,6 @@
 use rustc_back::target::Target;
 use rustc::hir;
 
-use std::collections::BTreeMap;
-
 macro_rules! provide {
     (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident $($name:ident => $compute:block)*) => {
         pub fn provide<$lt>(providers: &mut Providers<$lt>) {
@@ -113,21 +111,23 @@ pub fn provide<$lt>(providers: &mut Providers<$lt>) {
     def_span => { cdata.get_span(def_id.index, &tcx.sess) }
     stability => { cdata.get_stability(def_id.index) }
     deprecation => { cdata.get_deprecation(def_id.index) }
-    item_body_nested_bodies => {
-        let map: BTreeMap<_, _> = cdata.entry(def_id.index).ast.into_iter().flat_map(|ast| {
-            ast.decode(cdata).nested_bodies.decode(cdata).map(|body| (body.id(), body))
-        }).collect();
-
-        Rc::new(map)
-    }
+    item_attrs => { cdata.get_item_attrs(def_id.index, &tcx.dep_graph) }
+    // FIXME(#38501) We've skipped a `read` on the `HirBody` of
+    // a `fn` when encoding, so the dep-tracking wouldn't work.
+    // This is only used by rustdoc anyway, which shouldn't have
+    // incremental recompilation ever enabled.
+    fn_arg_names => { cdata.get_fn_arg_names(def_id.index) }
+    impl_parent => { cdata.get_parent_impl(def_id.index) }
+    trait_of_item => { cdata.get_trait_of_item(def_id.index) }
+    is_exported_symbol => {
+        let dep_node = cdata.metadata_dep_node(GlobalMetaDataKind::ExportedSymbols);
+        cdata.exported_symbols.get(&tcx.dep_graph, dep_node).contains(&def_id.index)
+    }
+    item_body_nested_bodies => { Rc::new(cdata.item_body_nested_bodies(def_id.index)) }
     const_is_rvalue_promotable_to_static => {
-        cdata.entry(def_id.index).ast.expect("const item missing `ast`")
-            .decode(cdata).rvalue_promotable_to_static
-    }
-    is_mir_available => {
-        !cdata.is_proc_macro(def_id.index) &&
-        cdata.maybe_entry(def_id.index).and_then(|item| item.decode(cdata).mir).is_some()
+        cdata.const_is_rvalue_promotable_to_static(def_id.index)
     }
+    is_mir_available => { cdata.is_item_mir_available(def_id.index) }
 }
 
 impl CrateStore for cstore::CStore {
@@ -145,22 +145,6 @@ fn item_generics_cloned(&self, def: DefId) -> ty::Generics {
         self.get_crate_data(def.krate).get_generics(def.index)
     }
 
-    fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]>
-    {
-        self.get_crate_data(def_id.krate)
-            .get_item_attrs(def_id.index, &self.dep_graph)
-    }
-
-    fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>
-    {
-        // FIXME(#38501) We've skipped a `read` on the `HirBody` of
-        // a `fn` when encoding, so the dep-tracking wouldn't work.
-        // This is only used by rustdoc anyway, which shouldn't have
-        // incremental recompilation ever enabled.
-        assert!(!self.dep_graph.is_fully_enabled());
-        self.get_crate_data(did.krate).get_fn_arg_names(did.index)
-    }
-
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
     {
         if let Some(def_id) = filter {
@@ -179,16 +163,6 @@ fn impl_defaultness(&self, def: DefId) -> hir::Defaultness
         self.get_crate_data(def.krate).get_impl_defaultness(def.index)
     }
 
-    fn impl_parent(&self, impl_def: DefId) -> Option<DefId> {
-        self.dep_graph.read(DepNode::MetaData(impl_def));
-        self.get_crate_data(impl_def.krate).get_parent_impl(impl_def.index)
-    }
-
-    fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
-        self.dep_graph.read(DepNode::MetaData(def_id));
-        self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index)
-    }
-
     fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
     {
         self.dep_graph.read(DepNode::MetaData(def));
@@ -206,23 +180,11 @@ fn is_default_impl(&self, impl_did: DefId) -> bool {
         self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index)
     }
 
-    fn is_foreign_item(&self, did: DefId) -> bool {
-        self.get_crate_data(did.krate).is_foreign_item(did.index)
-    }
-
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool
     {
         self.do_is_statically_included_foreign_item(def_id)
     }
 
-    fn is_exported_symbol(&self, def_id: DefId) -> bool {
-        let data = self.get_crate_data(def_id.krate);
-        let dep_node = data.metadata_dep_node(GlobalMetaDataKind::ExportedSymbols);
-        data.exported_symbols
-            .get(&self.dep_graph, dep_node)
-            .contains(&def_id.index)
-    }
-
     fn is_dllimport_foreign_item(&self, def_id: DefId) -> bool {
         if def_id.krate == LOCAL_CRATE {
             self.dllimport_foreign_items.borrow().contains(&def_id.index)
index 820b5a68bcc9b51bb0781e49ecc95ae75d9c7927..ea845f722c3450b214bb7f835b16e135016c6a56 100644 (file)
@@ -30,6 +30,7 @@
 
 use std::borrow::Cow;
 use std::cell::Ref;
+use std::collections::BTreeMap;
 use std::io;
 use std::mem;
 use std::rc::Rc;
@@ -453,16 +454,16 @@ fn to_def(&self, did: DefId) -> Option<Def> {
 }
 
 impl<'a, 'tcx> CrateMetadata {
-    pub fn is_proc_macro(&self, id: DefIndex) -> bool {
+    fn is_proc_macro(&self, id: DefIndex) -> bool {
         self.proc_macros.is_some() && id != CRATE_DEF_INDEX
     }
 
-    pub fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
+    fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
         assert!(!self.is_proc_macro(item_id));
         self.root.index.lookup(self.blob.raw_bytes(), item_id)
     }
 
-    pub fn entry(&self, item_id: DefIndex) -> Entry<'tcx> {
+    fn entry(&self, item_id: DefIndex) -> Entry<'tcx> {
         match self.maybe_entry(item_id) {
             None => {
                 bug!("entry: id not found: {:?} in crate {:?} with number {}",
@@ -789,6 +790,22 @@ pub fn item_body_tables(&self,
         tcx.alloc_tables(ast.tables.decode((self, tcx)))
     }
 
+    pub fn item_body_nested_bodies(&self, id: DefIndex) -> BTreeMap<hir::BodyId, hir::Body> {
+        self.entry(id).ast.into_iter().flat_map(|ast| {
+            ast.decode(self).nested_bodies.decode(self).map(|body| (body.id(), body))
+        }).collect()
+    }
+
+    pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool {
+        self.entry(id).ast.expect("const item missing `ast`")
+            .decode(self).rvalue_promotable_to_static
+    }
+
+    pub fn is_item_mir_available(&self, id: DefIndex) -> bool {
+        !self.is_proc_macro(id) &&
+        self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some()
+    }
+
     pub fn maybe_get_optimized_mir(&self,
                                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                    id: DefIndex)
index c503b8c7fe06f7bb9c58ed0fce452203e35551e0..40a78933aad2d8e5718f28a25f0fd63f5f2def6e 100644 (file)
@@ -60,7 +60,7 @@ pub fn push_assign_constant(&mut self,
                                 temp: &Lvalue<'tcx>,
                                 constant: Constant<'tcx>) {
         self.push_assign(block, source_info, temp,
-                         Rvalue::Use(Operand::Constant(constant)));
+                         Rvalue::Use(Operand::Constant(box constant)));
     }
 
     pub fn push_assign_unit(&mut self,
@@ -68,7 +68,7 @@ pub fn push_assign_unit(&mut self,
                             source_info: SourceInfo,
                             lvalue: &Lvalue<'tcx>) {
         self.push_assign(block, source_info, lvalue, Rvalue::Aggregate(
-            AggregateKind::Tuple, vec![]
+            box AggregateKind::Tuple, vec![]
         ));
     }
 
index 22a36bb21d8753f6cafc5b285007cdf6e9a69a87..f7534737edc03cb74571bbcd517bda16dfa29a7e 100644 (file)
@@ -66,7 +66,7 @@ fn expr_as_operand(&mut self,
         match category {
             Category::Constant => {
                 let constant = this.as_constant(expr);
-                block.and(Operand::Constant(constant))
+                block.and(Operand::Constant(box constant))
             }
             Category::Lvalue |
             Category::Rvalue(..) => {
index 8dc7745cd9eb998772201cfd2d519b56fdf861ec..46e2408c38d5d6e06a90c0e2dc28cde0c6a871fa 100644 (file)
@@ -166,7 +166,7 @@ fn expr_as_rvalue(&mut self,
                           .map(|f| unpack!(block = this.as_operand(block, scope, f)))
                           .collect();
 
-                block.and(Rvalue::Aggregate(AggregateKind::Array(el_ty), fields))
+                block.and(Rvalue::Aggregate(box AggregateKind::Array(el_ty), fields))
             }
             ExprKind::Tuple { fields } => { // see (*) above
                 // first process the set of fields
@@ -175,14 +175,14 @@ fn expr_as_rvalue(&mut self,
                           .map(|f| unpack!(block = this.as_operand(block, scope, f)))
                           .collect();
 
-                block.and(Rvalue::Aggregate(AggregateKind::Tuple, fields))
+                block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
             }
             ExprKind::Closure { closure_id, substs, upvars } => { // see (*) above
                 let upvars =
                     upvars.into_iter()
                           .map(|upvar| unpack!(block = this.as_operand(block, scope, upvar)))
                           .collect();
-                block.and(Rvalue::Aggregate(AggregateKind::Closure(closure_id, substs), upvars))
+                block.and(Rvalue::Aggregate(box AggregateKind::Closure(closure_id, substs), upvars))
             }
             ExprKind::Adt {
                 adt_def, variant_index, substs, fields, base
@@ -215,7 +215,8 @@ fn expr_as_rvalue(&mut self,
                     field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect()
                 };
 
-                let adt = AggregateKind::Adt(adt_def, variant_index, substs, active_field_index);
+                let adt =
+                    box AggregateKind::Adt(adt_def, variant_index, substs, active_field_index);
                 block.and(Rvalue::Aggregate(adt, fields))
             }
             ExprKind::Assign { .. } |
index c03432312b0ab6c4adc235e2a3036603c6f3854b..3c7ab373651d2c7983eda3d1c06116d137fbc147 100644 (file)
@@ -129,7 +129,7 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
                 this.cfg.push(block, Statement {
                     source_info: source_info,
                     kind: StatementKind::InlineAsm {
-                        asm: asm.clone(),
+                        asm: box asm.clone(),
                         outputs: outputs,
                         inputs: inputs
                     },
index 0833342927fec9dbbb31bab1164aa70a44080b58..28386fa598ce6c7890ddd6762a44d3e4bb65d369 100644 (file)
@@ -308,7 +308,7 @@ pub fn perform_test(&mut self,
                     let eq_block = self.cfg.start_new_block();
                     let cleanup = self.diverge_cleanup();
                     self.cfg.terminate(block, source_info, TerminatorKind::Call {
-                        func: Operand::Constant(Constant {
+                        func: Operand::Constant(box Constant {
                             span: test.span,
                             ty: mty,
                             literal: method
index 35a8b245f2bb64203a7e19e14d8c891015e02821..6c93e073de6b1953bd56b60de2d9069409b9d390 100644 (file)
@@ -40,7 +40,7 @@ pub fn literal_operand(&mut self,
                            ty: Ty<'tcx>,
                            literal: Literal<'tcx>)
                            -> Operand<'tcx> {
-        let constant = Constant {
+        let constant = box Constant {
             span: span,
             ty: ty,
             literal: literal,
@@ -49,7 +49,7 @@ pub fn literal_operand(&mut self,
     }
 
     pub fn unit_rvalue(&mut self) -> Rvalue<'tcx> {
-        Rvalue::Aggregate(AggregateKind::Tuple, vec![])
+        Rvalue::Aggregate(box AggregateKind::Tuple, vec![])
     }
 
     // Returns a zero literal operand for the appropriate type, works for
index f9c08f34eaf3f4fde47daac87c75282d3391760b..6043a696183f26eb069171d7514db420be8e038a 100644 (file)
@@ -786,7 +786,7 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
     let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
     let substs = tcx.intern_substs(&[Kind::from(data.item_ty)]);
     TerminatorKind::Call {
-        func: Operand::Constant(Constant {
+        func: Operand::Constant(box Constant {
             span: data.span,
             ty: tcx.type_of(free_func).subst(tcx, substs),
             literal: Literal::Value {
index 1458ea7fdd6a29fcd9fb5e9b75c5ddf88bf95337..a6f9952b23ca5111d9b25286fd50ff77a3ba5d6e 100644 (file)
@@ -323,7 +323,7 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
     let (callee, mut args) = match call_kind {
         CallKind::Indirect => (rcvr, vec![]),
         CallKind::Direct(def_id) => (
-            Operand::Constant(Constant {
+            Operand::Constant(box Constant {
                 span: span,
                 ty: tcx.type_of(def_id).subst(tcx, param_env.free_substs),
                 literal: Literal::Value {
@@ -449,7 +449,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
             kind: StatementKind::Assign(
                 Lvalue::Local(RETURN_POINTER),
                 Rvalue::Aggregate(
-                    AggregateKind::Adt(adt_def, variant_no, substs, None),
+                    box AggregateKind::Adt(adt_def, variant_no, substs, None),
                     (1..sig.inputs().len()+1).map(|i| {
                         Operand::Consume(Lvalue::Local(Local::new(i)))
                     }).collect()
index fbb67161bac9d82fb7d5034ccab663d481d9819c..08a4961c6cd1ba40317605a73c95e0110a10d303 100644 (file)
@@ -316,7 +316,7 @@ fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
             _ => return,
         }
 
-        *operand = Operand::Constant(self.constant.clone());
+        *operand = Operand::Constant(box self.constant.clone());
         self.uses_replaced += 1
     }
 }
index 4309f91c635bb15bc6f733123354c0d24b733625..d21dbeafb5d0a0b269184aec28b2fcd8942ddfeb 100644 (file)
@@ -49,8 +49,8 @@ fn run_pass<'a, 'tcx>(&self,
                     &Rvalue::Aggregate(ref agg_kind, ref operands) => (agg_kind, operands),
                     _ => span_bug!(src_info.span, "expected aggregate, not {:?}", rhs),
                 };
-                let (adt_def, variant, substs) = match agg_kind {
-                    &AggregateKind::Adt(adt_def, variant, substs, None)
+                let (adt_def, variant, substs) = match **agg_kind {
+                    AggregateKind::Adt(adt_def, variant, substs, None)
                         => (adt_def, variant, substs),
                     _ => span_bug!(src_info.span, "expected struct, not {:?}", rhs),
                 };
@@ -114,8 +114,8 @@ fn get_aggregate_statement_index<'a, 'tcx, 'b>(start: usize,
             &Rvalue::Aggregate(ref kind, ref operands) => (kind, operands),
             _ => continue,
         };
-        let (adt_def, variant) = match kind {
-            &AggregateKind::Adt(adt_def, variant, _, None) => (adt_def, variant),
+        let (adt_def, variant) = match **kind {
+            AggregateKind::Adt(adt_def, variant, _, None) => (adt_def, variant),
             _ => continue,
         };
         if operands.len() == 0 {
index ed9a0d3809f245886e0aa6e41bee1c7f76ba3d7f..e1c4602b045ebab53404a86b715176f6c4a7c84e 100644 (file)
@@ -230,7 +230,7 @@ fn promote_temp(&mut self, temp: Local) -> Local {
                 (if self.keep_original {
                     rhs.clone()
                 } else {
-                    let unit = Rvalue::Aggregate(AggregateKind::Tuple, vec![]);
+                    let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
                     mem::replace(rhs, unit)
                 }, statement.source_info)
             };
@@ -288,7 +288,7 @@ fn promote_temp(&mut self, temp: Local) -> Local {
 
     fn promote_candidate(mut self, candidate: Candidate) {
         let span = self.promoted.span;
-        let new_operand = Operand::Constant(Constant {
+        let new_operand = Operand::Constant(box Constant {
             span: span,
             ty: self.promoted.return_ty,
             literal: Literal::Promoted {
index 0d592b4d72be5b11df3d9ddd232ca0fa39cb921b..df837a32133b37e252d885003c0bc83c2e778c4c 100644 (file)
@@ -730,7 +730,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
             }
 
             Rvalue::Aggregate(ref kind, _) => {
-                if let AggregateKind::Adt(def, ..) = *kind {
+                if let AggregateKind::Adt(def, ..) = **kind {
                     if def.has_dtor(self.tcx) {
                         self.add(Qualif::NEEDS_DROP);
                         self.deny_drop();
index d21a6ddfdfb970c85b57276238399370133ddeff..1dcacb29c3ecc406807630affdfd7e7209b14910 100644 (file)
@@ -37,7 +37,7 @@ fn run_pass<'a, 'tcx>(&self,
         for block in mir.basic_blocks_mut() {
             let terminator = block.terminator_mut();
             terminator.kind = match terminator.kind {
-                TerminatorKind::SwitchInt { discr: Operand::Constant(Constant {
+                TerminatorKind::SwitchInt { discr: Operand::Constant(box Constant {
                     literal: Literal::Value { ref value }, ..
                 }), ref values, ref targets, .. } => {
                     if let Some(ref constint) = value.to_const_int() {
@@ -54,7 +54,7 @@ fn run_pass<'a, 'tcx>(&self,
                         continue
                     }
                 },
-                TerminatorKind::Assert { target, cond: Operand::Constant(Constant {
+                TerminatorKind::Assert { target, cond: Operand::Constant(box Constant {
                     literal: Literal::Value {
                         value: ConstVal::Bool(cond)
                     }, ..
@@ -66,4 +66,3 @@ fn run_pass<'a, 'tcx>(&self,
         }
     }
 }
-
index b325470ec818cadcd33f6dd3309ec408400a5351..be384218a414e0a461393c54eb489d521b155eac 100644 (file)
@@ -534,7 +534,7 @@ fn check_call_inputs(&mut self,
 
     fn is_box_free(&self, operand: &Operand<'tcx>) -> bool {
         match operand {
-            &Operand::Constant(Constant {
+            &Operand::Constant(box Constant {
                 literal: Literal::Value {
                     value: ConstVal::Function(def_id, _), ..
                 }, ..
index d9921e62330b95e1fa098a7f39b60540641af3c5..24218725186624525e735628bd03a9fac3b6b07a 100644 (file)
@@ -190,7 +190,7 @@ fn visit_rvalue(&mut self,
             Rvalue::Aggregate(ref kind, ref _operands) => {
                 // AggregateKind is not distinguished by visit API, so
                 // record it. (`super_rvalue` handles `_operands`.)
-                self.record(match *kind {
+                self.record(match **kind {
                     AggregateKind::Array(_) => "AggregateKind::Array",
                     AggregateKind::Tuple => "AggregateKind::Tuple",
                     AggregateKind::Adt(..) => "AggregateKind::Adt",
index aef9140ba4556cf9b14f927daaf13d12bbadc4a7..1aed2932948020f87e990c1f675aa46c413d39f0 100644 (file)
@@ -223,7 +223,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
             _ => false
         }
     } else {
-        tcx.sess.cstore.is_foreign_item(def_id)
+        tcx.is_foreign_item(def_id)
     };
 
     if let Some(name) = weak_lang_items::link_name(&attrs) {
index 6d7d95f54872105ea12b790ee9cd1b8e656777a8..5f8b79a994a554755bbd0b93cb336c0a5f8985a7 100644 (file)
@@ -652,8 +652,8 @@ fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instan
         }
         Some(_) => true,
         None => {
-            if tcx.sess.cstore.is_exported_symbol(def_id) ||
-                tcx.sess.cstore.is_foreign_item(def_id)
+            if tcx.is_exported_symbol(def_id) ||
+                tcx.is_foreign_item(def_id)
             {
                 // We can link to the item in question, no instance needed
                 // in this crate
index 6afb340107d6661aa1c3a5ad517319757942f887..eac0a062567194cd056253b4ff0a320cae3d0a47 100644 (file)
@@ -186,7 +186,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
                 llvm::set_thread_local(g, true);
             }
         }
-        if ccx.use_dll_storage_attrs() && !ccx.sess().cstore.is_foreign_item(def_id) {
+        if ccx.use_dll_storage_attrs() && !ccx.tcx().is_foreign_item(def_id) {
             // This item is external but not foreign, i.e. it originates from an external Rust
             // crate. Since we don't know whether this crate will be linked dynamically or
             // statically in the final application, we always mark such symbols as 'dllimport'.
index 889f9dc4cded5880f85a9c2171a7b24e708d350c..96ef26d3f6f833aa87a2a56c2eef37ac01d8c74f 100644 (file)
@@ -108,7 +108,7 @@ fn visit_terminator_kind(&mut self,
                              location: Location) {
         match *kind {
             mir::TerminatorKind::Call {
-                func: mir::Operand::Constant(mir::Constant {
+                func: mir::Operand::Constant(box mir::Constant {
                     literal: Literal::Value {
                         value: ConstVal::Function(def_id, _), ..
                     }, ..
index 040194e63d07e0ec6f549244ec495d3f3951abae..6ba00c7e103317cf1afcafa0827b1353e5de9417 100644 (file)
@@ -537,7 +537,7 @@ fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>,
                 }
                 failure?;
 
-                match *kind {
+                match **kind {
                     mir::AggregateKind::Array(_) => {
                         self.const_array(dest_ty, &fields)
                     }
index b8e9a490b0e7cffa36b0ce40812131c19ebd8382..667075e6970e184c010e55ef7f9c6ab1de8f4ac8 100644 (file)
@@ -104,7 +104,7 @@ pub fn trans_rvalue(&mut self,
             }
 
             mir::Rvalue::Aggregate(ref kind, ref operands) => {
-                match *kind {
+                match **kind {
                     mir::AggregateKind::Adt(adt_def, variant_index, substs, active_field_index) => {
                         let discr = adt_def.discriminant_for_variant(bcx.tcx(), variant_index)
                            .to_u128_unchecked() as u64;
index e986a381cd963df034968e27a66fa463c2a5c2e6..cb2ee7dd1bcda5c7b89bcc4fda7a95e6d543f81c 100644 (file)
@@ -27,7 +27,6 @@
 
 use super::terms::*;
 use super::terms::VarianceTerm::*;
-use super::xform::*;
 
 pub struct ConstraintContext<'a, 'tcx: 'a> {
     pub terms_cx: TermsContext<'a, 'tcx>,
index 507734ce35e44fdcf1695911ac48b7c7190b6293..7106ca4d420a86100bebc22a21d4e64a8f98dd81 100644 (file)
 
 use rustc::ty;
 
-pub trait Xform {
-    fn xform(self, v: Self) -> Self;
-}
-
-impl Xform for ty::Variance {
-    fn xform(self, v: ty::Variance) -> ty::Variance {
-        // "Variance transformation", Figure 1 of The Paper
-        match (self, v) {
-            // Figure 1, column 1.
-            (ty::Covariant, ty::Covariant) => ty::Covariant,
-            (ty::Covariant, ty::Contravariant) => ty::Contravariant,
-            (ty::Covariant, ty::Invariant) => ty::Invariant,
-            (ty::Covariant, ty::Bivariant) => ty::Bivariant,
-
-            // Figure 1, column 2.
-            (ty::Contravariant, ty::Covariant) => ty::Contravariant,
-            (ty::Contravariant, ty::Contravariant) => ty::Covariant,
-            (ty::Contravariant, ty::Invariant) => ty::Invariant,
-            (ty::Contravariant, ty::Bivariant) => ty::Bivariant,
-
-            // Figure 1, column 3.
-            (ty::Invariant, _) => ty::Invariant,
-
-            // Figure 1, column 4.
-            (ty::Bivariant, _) => ty::Bivariant,
-        }
-    }
-}
-
 pub fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
     // Greatest lower bound of the variance lattice as
     // defined in The Paper:
index 24d056035ceec541da0eea065acee215154dbd58..2dde6d9d4ee556286fd07b7d4e9a164024a57d6f 100644 (file)
@@ -1180,7 +1180,7 @@ fn clean(&self, cx: &DocContext) -> FnDecl {
         let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() {
             vec![].into_iter()
         } else {
-            cx.tcx.sess.cstore.fn_arg_names(did).into_iter()
+            cx.tcx.fn_arg_names(did).into_iter()
         }.peekable();
         FnDecl {
             output: Return(sig.skip_binder().output().clean(cx)),
index e2832873e2e674a83d2e80d67503fd2ff83471ce..c872a8e52611408c64218569acd378e167cbc5cc 100644 (file)
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
+pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
+#[unstable(feature = "print_internals", issue = "0")]
+pub use self::stdio::{_print, _eprint};
 #[unstable(feature = "libstd_io_internals", issue = "0")]
 #[doc(no_inline, hidden)]
 pub use self::stdio::{set_panic, set_print};
index 38ad23e14b3ebc01a174787c05a06a1b94687094..a8b0bf0071a22465ddc0882d1196715ceed728b7 100644 (file)
@@ -17,7 +17,7 @@
 use sync::{Arc, Mutex, MutexGuard};
 use sys::stdio;
 use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
-use thread::LocalKeyState;
+use thread::{LocalKey, LocalKeyState};
 
 /// Stdout used by print! and println! macros
 thread_local! {
@@ -659,41 +659,56 @@ pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
     })
 }
 
-#[unstable(feature = "print",
-           reason = "implementation detail which may disappear or be replaced at any time",
-           issue = "0")]
-#[doc(hidden)]
-pub fn _print(args: fmt::Arguments) {
-    // As an implementation of the `println!` macro, we want to try our best to
-    // not panic wherever possible and get the output somewhere. There are
-    // currently two possible vectors for panics we take care of here:
-    //
-    // 1. If the TLS key for the local stdout has been destroyed, accessing it
-    //    would cause a panic. Note that we just lump in the uninitialized case
-    //    here for convenience, we're not trying to avoid a panic.
-    // 2. If the local stdout is currently in use (e.g. we're in the middle of
-    //    already printing) then accessing again would cause a panic.
-    //
-    // If, however, the actual I/O causes an error, we do indeed panic.
-    let result = match LOCAL_STDOUT.state() {
+/// Write `args` to output stream `local_s` if possible, `global_s`
+/// otherwise. `label` identifies the stream in a panic message.
+///
+/// This function is used to print error messages, so it takes extra
+/// care to avoid causing a panic when `local_stream` is unusable.
+/// For instance, if the TLS key for the local stream is uninitialized
+/// or already destroyed, or if the local stream is locked by another
+/// thread, it will just fall back to the global stream.
+///
+/// However, if the actual I/O causes an error, this function does panic.
+fn print_to<T>(args: fmt::Arguments,
+               local_s: &'static LocalKey<RefCell<Option<Box<Write+Send>>>>,
+               global_s: fn() -> T,
+               label: &str) where T: Write {
+    let result = match local_s.state() {
         LocalKeyState::Uninitialized |
-        LocalKeyState::Destroyed => stdout().write_fmt(args),
+        LocalKeyState::Destroyed => global_s().write_fmt(args),
         LocalKeyState::Valid => {
-            LOCAL_STDOUT.with(|s| {
+            local_s.with(|s| {
                 if let Ok(mut borrowed) = s.try_borrow_mut() {
                     if let Some(w) = borrowed.as_mut() {
                         return w.write_fmt(args);
                     }
                 }
-                stdout().write_fmt(args)
+                global_s().write_fmt(args)
             })
         }
     };
     if let Err(e) = result {
-        panic!("failed printing to stdout: {}", e);
+        panic!("failed printing to {}: {}", label, e);
     }
 }
 
+#[unstable(feature = "print_internals",
+           reason = "implementation detail which may disappear or be replaced at any time",
+           issue = "0")]
+#[doc(hidden)]
+pub fn _print(args: fmt::Arguments) {
+    print_to(args, &LOCAL_STDOUT, stdout, "stdout");
+}
+
+#[unstable(feature = "print_internals",
+           reason = "implementation detail which may disappear or be replaced at any time",
+           issue = "0")]
+#[doc(hidden)]
+pub fn _eprint(args: fmt::Arguments) {
+    use panicking::LOCAL_STDERR;
+    print_to(args, &LOCAL_STDERR, stderr, "stderr");
+}
+
 #[cfg(test)]
 mod tests {
     use thread;
index a1f092621cb44f506c8e8b2e360e1fe5068f3c32..ef78ea6dfe8ee72c047315f07e3b2be4e96a8739 100644 (file)
@@ -68,6 +68,9 @@ macro_rules! panic {
 /// necessary to use `io::stdout().flush()` to ensure the output is emitted
 /// immediately.
 ///
+/// Use `print!` only for the primary output of your program.  Use
+/// `eprint!` instead to print error and progress messages.
+///
 /// # Panics
 ///
 /// Panics if writing to `io::stdout()` fails.
@@ -105,9 +108,12 @@ macro_rules! print {
 /// Use the `format!` syntax to write data to the standard output.
 /// See `std::fmt` for more information.
 ///
+/// Use `println!` only for the primary output of your program.  Use
+/// `eprintln!` instead to print error and progress messages.
+///
 /// # Panics
 ///
-/// Panics if writing to `io::stdout()` fails.
+/// Panics if writing to `io::stdout` fails.
 ///
 /// # Examples
 ///
@@ -124,6 +130,45 @@ macro_rules! println {
     ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
 }
 
+/// Macro for printing to the standard error.
+///
+/// Equivalent to the `print!` macro, except that output goes to
+/// `io::stderr` instead of `io::stdout`.  See `print!` for
+/// example usage.
+///
+/// Use `eprint!` only for error and progress messages.  Use `print!`
+/// instead for the primary output of your program.
+///
+/// # Panics
+///
+/// Panics if writing to `io::stderr` fails.
+#[macro_export]
+#[stable(feature = "eprint", since="1.18.0")]
+#[allow_internal_unstable]
+macro_rules! eprint {
+    ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
+}
+
+/// Macro for printing to the standard error, with a newline.
+///
+/// Equivalent to the `println!` macro, except that output goes to
+/// `io::stderr` instead of `io::stdout`.  See `println!` for
+/// example usage.
+///
+/// Use `eprintln!` only for error and progress messages.  Use `println!`
+/// instead for the primary output of your program.
+///
+/// # Panics
+///
+/// Panics if writing to `io::stderr` fails.
+#[macro_export]
+#[stable(feature = "eprint", since="1.18.0")]
+macro_rules! eprintln {
+    () => (eprint!("\n"));
+    ($fmt:expr) => (eprint!(concat!($fmt, "\n")));
+    ($fmt:expr, $($arg:tt)*) => (eprint!(concat!($fmt, "\n"), $($arg)*));
+}
+
 /// A macro to select an event from a number of receivers.
 ///
 /// This macro is used to wait for the first event to occur on a number of
index 9d66430bc93032a59bf5953027646bd9730bc07a..f4b9a8972e3abb93f8dcfbceead1a6096d76d509 100644 (file)
 //! ```
 //! use std::path::PathBuf;
 //!
+//! // This way works...
 //! let mut path = PathBuf::from("c:\\");
+//!
 //! path.push("windows");
 //! path.push("system32");
+//!
 //! path.set_extension("dll");
+//!
+//! // ... but push is best used if you don't know everything up
+//! // front. If you do, this way is better:
+//! let path: PathBuf = ["c:\\", "windows", "system32.dll"].iter().collect();
 //! ```
 //!
 //! [`Component`]: ../../std/path/enum.Component.html
@@ -63,6 +70,7 @@
 //! [`Path`]: ../../std/path/struct.Path.html
 //! [`push`]: ../../std/path/struct.PathBuf.html#method.push
 //! [`String`]: ../../std/string/struct.String.html
+//!
 //! [`str`]: ../../std/primitive.str.html
 //! [`OsString`]: ../../std/ffi/struct.OsString.html
 //! [`OsStr`]: ../../std/ffi/struct.OsStr.html
@@ -1036,14 +1044,40 @@ fn cmp(&self, other: &Components<'a>) -> cmp::Ordering {
 ///
 /// # Examples
 ///
+/// You can use [`push`] to build up a `PathBuf` from
+/// components:
+///
 /// ```
 /// use std::path::PathBuf;
 ///
-/// let mut path = PathBuf::from("c:\\");
+/// let mut path = PathBuf::new();
+///
+/// path.push(r"C:\");
 /// path.push("windows");
 /// path.push("system32");
+///
 /// path.set_extension("dll");
 /// ```
+///
+/// However, [`push`] is best used for dynamic situations. This is a better way
+/// to do this when you know all of the components ahead of time:
+///
+/// ```
+/// use std::path::PathBuf;
+///
+/// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
+/// ```
+///
+/// We can still do better than this! Since these are all strings, we can use
+/// `From::from`:
+///
+/// ```
+/// use std::path::PathBuf;
+///
+/// let path = PathBuf::from(r"C:\windows\system32.dll");
+/// ```
+///
+/// Which method works best depends on what kind of situation you're in.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct PathBuf {
index 5e46069cf7ddfb2257eb8d4f5423cb1d153f83fb..1646f8cce72326e05c778bf88933b892479f6695 100644 (file)
@@ -199,7 +199,10 @@ fn clone(&self) -> Self { *self }
 
 pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
 
+pub const FACILITY_NT_BIT: DWORD = 0x1000_0000;
+
 pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
 pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
 
 pub const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
index 7e28dd1e259c8c1551e7f73fc97d2daaecc09501..a51b458451e8623ff3fd397956f276cf6e5e4604 100644 (file)
@@ -32,7 +32,7 @@ pub fn errno() -> i32 {
 }
 
 /// Gets a detailed string description for the given error number.
-pub fn error_string(errnum: i32) -> String {
+pub fn error_string(mut errnum: i32) -> String {
     // This value is calculated from the macro
     // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
     let langId = 0x0800 as c::DWORD;
@@ -40,9 +40,27 @@ pub fn error_string(errnum: i32) -> String {
     let mut buf = [0 as c::WCHAR; 2048];
 
     unsafe {
-        let res = c::FormatMessageW(c::FORMAT_MESSAGE_FROM_SYSTEM |
+        let mut module = ptr::null_mut();
+        let mut flags = 0;
+
+        // NTSTATUS errors may be encoded as HRESULT, which may returned from
+        // GetLastError. For more information about Windows error codes, see
+        // `[MS-ERREF]`: https://msdn.microsoft.com/en-us/library/cc231198.aspx
+        if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
+            // format according to https://support.microsoft.com/en-us/help/259693
+            const NTDLL_DLL: &'static [u16] = &['N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _,
+                                                '.' as _, 'D' as _, 'L' as _, 'L' as _, 0];
+            module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
+
+            if module != ptr::null_mut() {
+                errnum ^= c::FACILITY_NT_BIT as i32;
+                flags = c::FORMAT_MESSAGE_FROM_HMODULE;
+            }
+        }
+
+        let res = c::FormatMessageW(flags | c::FORMAT_MESSAGE_FROM_SYSTEM |
                                         c::FORMAT_MESSAGE_IGNORE_INSERTS,
-                                    ptr::null_mut(),
+                                    module,
                                     errnum as c::DWORD,
                                     langId,
                                     buf.as_mut_ptr(),
@@ -299,3 +317,17 @@ pub fn home_dir() -> Option<PathBuf> {
 pub fn exit(code: i32) -> ! {
     unsafe { c::ExitProcess(code as c::UINT) }
 }
+
+#[cfg(test)]
+mod tests {
+    use io::Error;
+    use sys::c;
+
+    // tests `error_string` above
+    #[test]
+    fn ntstatus_error() {
+        const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001;
+        assert!(!Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _)
+            .to_string().contains("FormatMessageW() returned error"));
+    }
+}
index 4432f898e04f8aa00bea7925bf7ec27b3db03be0..230c60baf8bb49a95b123d4c29b4c4a90caeb660 100644 (file)
 //! The [`thread::current`] function is available even for threads not spawned
 //! by the APIs of this module.
 //!
-//! ## Blocking support: park and unpark
-//!
-//! Every thread is equipped with some basic low-level blocking support, via the
-//! [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`]
-//! method. [`park`] blocks the current thread, which can then be resumed from
-//! another thread by calling the [`unpark`] method on the blocked thread's handle.
-//!
-//! Conceptually, each [`Thread`] handle has an associated token, which is
-//! initially not present:
-//!
-//! * The [`thread::park`][`park`] function blocks the current thread unless or until
-//!   the token is available for its thread handle, at which point it atomically
-//!   consumes the token. It may also return *spuriously*, without consuming the
-//!   token. [`thread::park_timeout`] does the same, but allows specifying a
-//!   maximum time to block the thread for.
-//!
-//! * The [`unpark`] method on a [`Thread`] atomically makes the token available
-//!   if it wasn't already.
-//!
-//! In other words, each [`Thread`] acts a bit like a semaphore with initial count
-//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
-//! and can return spuriously.
-//!
-//! The API is typically used by acquiring a handle to the current thread,
-//! placing that handle in a shared data structure so that other threads can
-//! find it, and then `park`ing. When some desired condition is met, another
-//! thread calls [`unpark`] on the handle.
-//!
-//! The motivation for this design is twofold:
-//!
-//! * It avoids the need to allocate mutexes and condvars when building new
-//!   synchronization primitives; the threads already provide basic blocking/signaling.
-//!
-//! * It can be implemented very efficiently on many platforms.
-//!
 //! ## Thread-local storage
 //!
 //! This module also provides an implementation of thread-local storage for Rust
@@ -322,6 +287,8 @@ pub fn stack_size(mut self, size: usize) -> Builder {
     /// thread finishes). The join handle can be used to block on
     /// termination of the child thread, including recovering its panics.
     ///
+    /// For a more complete documentation see [`thread::spawn`][`spawn`].
+    ///
     /// # Errors
     ///
     /// Unlike the [`spawn`] free function, this method yields an
@@ -396,19 +363,19 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
 /// panics, [`join`] will return an [`Err`] containing the argument given to
 /// [`panic`].
 ///
+/// This will create a thread using default parameters of [`Builder`], if you
+/// want to specify the stack size or the name of the thread, use this API
+/// instead.
+///
 /// # Panics
 ///
 /// Panics if the OS fails to create a thread; use [`Builder::spawn`]
 /// to recover from such errors.
 ///
-/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
-/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
-/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
-/// [`panic`]: ../../std/macro.panic.html
-/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
-///
 /// # Examples
 ///
+/// Creating a thread.
+///
 /// ```
 /// use std::thread;
 ///
@@ -418,6 +385,54 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
 ///
 /// handler.join().unwrap();
 /// ```
+///
+/// As mentioned in the module documentation, threads are usually made to
+/// communicate using [`channels`], here is how it usually looks.
+///
+/// This example also shows how to use `move`, in order to give ownership
+/// of values to a thread.
+///
+/// ```
+/// use std::thread;
+/// use std::sync::mpsc::channel;
+///
+/// let (tx, rx) = channel();
+///
+/// let sender = thread::spawn(move || {
+///     let _ = tx.send("Hello, thread".to_owned());
+/// });
+///
+/// let receiver = thread::spawn(move || {
+///     println!("{}", rx.recv().unwrap());
+/// });
+///
+/// let _ = sender.join();
+/// let _ = receiver.join();
+/// ```
+///
+/// A thread can also return a value through its [`JoinHandle`], you can use
+/// this to make asynchronous computations (futures might be more appropriate
+/// though).
+///
+/// ```
+/// use std::thread;
+///
+/// let computation = thread::spawn(|| {
+///     // Some expensive computation.
+///     42
+/// });
+///
+/// let result = computation.join().unwrap();
+/// println!("{}", result);
+/// ```
+///
+/// [`channels`]: ../../std/sync/mpsc/index.html
+/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
+/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
+/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+/// [`panic`]: ../../std/macro.panic.html
+/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
+/// [`Builder`]: ../../std/thread/struct.Builder.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
@@ -568,23 +583,72 @@ pub fn sleep(dur: Duration) {
 
 /// Blocks unless or until the current thread's token is made available.
 ///
-/// Every thread is equipped with some basic low-level blocking support, via
-/// the `park()` function and the [`unpark`][unpark] method. These can be
-/// used as a more CPU-efficient implementation of a spinlock.
+/// A call to `park` does not guarantee that the thread will remain parked
+/// forever, and callers should be prepared for this possibility.
 ///
-/// [unpark]: struct.Thread.html#method.unpark
+/// # park and unpark
+///
+/// Every thread is equipped with some basic low-level blocking support, via the
+/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`]
+/// method. [`park`] blocks the current thread, which can then be resumed from
+/// another thread by calling the [`unpark`] method on the blocked thread's
+/// handle.
+///
+/// Conceptually, each [`Thread`] handle has an associated token, which is
+/// initially not present:
+///
+/// * The [`thread::park`][`park`] function blocks the current thread unless or
+///   until the token is available for its thread handle, at which point it
+///   atomically consumes the token. It may also return *spuriously*, without
+///   consuming the token. [`thread::park_timeout`] does the same, but allows
+///   specifying a maximum time to block the thread for.
+///
+/// * The [`unpark`] method on a [`Thread`] atomically makes the token available
+///   if it wasn't already.
+///
+/// In other words, each [`Thread`] acts a bit like a spinlock that can be
+/// locked and unlocked using `park` and `unpark`.
 ///
 /// The API is typically used by acquiring a handle to the current thread,
 /// placing that handle in a shared data structure so that other threads can
-/// find it, and then parking (in a loop with a check for the token actually
-/// being acquired).
+/// find it, and then `park`ing. When some desired condition is met, another
+/// thread calls [`unpark`] on the handle.
 ///
-/// A call to `park` does not guarantee that the thread will remain parked
-/// forever, and callers should be prepared for this possibility.
+/// The motivation for this design is twofold:
 ///
-/// See the [module documentation][thread] for more detail.
+/// * It avoids the need to allocate mutexes and condvars when building new
+///   synchronization primitives; the threads already provide basic
+///   blocking/signaling.
 ///
-/// [thread]: index.html
+/// * It can be implemented very efficiently on many platforms.
+///
+/// # Examples
+///
+/// ```
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let parked_thread = thread::Builder::new()
+///     .spawn(|| {
+///         println!("Parking thread");
+///         thread::park();
+///         println!("Thread unparked");
+///     })
+///     .unwrap();
+///
+/// // Let some time pass for the thread to be spawned.
+/// thread::sleep(Duration::from_millis(10));
+///
+/// println!("Unpark the thread");
+/// parked_thread.thread().unpark();
+///
+/// parked_thread.join().unwrap();
+/// ```
+///
+/// [`Thread`]: ../../std/thread/struct.Thread.html
+/// [`park`]: ../../std/thread/fn.park.html
+/// [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
+/// [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
 //
 // The implementation currently uses the trivial strategy of a Mutex+Condvar
 // with wakeup flag, which does not actually allow spurious wakeups. In the
@@ -601,21 +665,21 @@ pub fn park() {
     *guard = false;
 }
 
-/// Use [park_timeout].
+/// Use [`park_timeout`].
 ///
 /// Blocks unless or until the current thread's token is made available or
 /// the specified duration has been reached (may wake spuriously).
 ///
-/// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than `ms`. This method
-/// should not be used for precise timing due to anomalies such as
+/// The semantics of this function are equivalent to [`park`] except
+/// that the thread will be blocked for roughly no longer than `dur`. This
+/// method should not be used for precise timing due to anomalies such as
 /// preemption or platform differences that may not cause the maximum
 /// amount of time waited to be precisely `ms` long.
 ///
-/// See the [module documentation][thread] for more detail.
+/// See the [park documentation][`park`] for more detail.
 ///
-/// [thread]: index.html
-/// [park_timeout]: fn.park_timeout.html
+/// [`park_timeout`]: fn.park_timeout.html
+/// [`park`]: ../../std/thread/fn.park.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")]
 pub fn park_timeout_ms(ms: u32) {
@@ -625,13 +689,13 @@ pub fn park_timeout_ms(ms: u32) {
 /// Blocks unless or until the current thread's token is made available or
 /// the specified duration has been reached (may wake spuriously).
 ///
-/// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than `dur`. This method
-/// should not be used for precise timing due to anomalies such as
+/// The semantics of this function are equivalent to [`park`][park] except
+/// that the thread will be blocked for roughly no longer than `dur`. This
+/// method should not be used for precise timing due to anomalies such as
 /// preemption or platform differences that may not cause the maximum
 /// amount of time waited to be precisely `dur` long.
 ///
-/// See the module doc for more detail.
+/// See the [park dococumentation][park] for more details.
 ///
 /// # Platform behavior
 ///
@@ -656,6 +720,8 @@ pub fn park_timeout_ms(ms: u32) {
 ///     park_timeout(timeout);
 /// }
 /// ```
+///
+/// [park]: fn.park.html
 #[stable(feature = "park_timeout", since = "1.4.0")]
 pub fn park_timeout(dur: Duration) {
     let thread = current();
@@ -777,22 +843,36 @@ pub(crate) fn new(name: Option<String>) -> Thread {
 
     /// Atomically makes the handle's token available if it is not already.
     ///
-    /// See the module doc for more detail.
+    /// Every thread is equipped with some basic low-level blocking support, via
+    /// the [`park`][park] function and the `unpark()` method. These can be
+    /// used as a more CPU-efficient implementation of a spinlock.
+    ///
+    /// See the [park documentation][park] for more details.
     ///
     /// # Examples
     ///
     /// ```
     /// use std::thread;
+    /// use std::time::Duration;
     ///
-    /// let handler = thread::Builder::new()
+    /// let parked_thread = thread::Builder::new()
     ///     .spawn(|| {
-    ///         let thread = thread::current();
-    ///         thread.unpark();
+    ///         println!("Parking thread");
+    ///         thread::park();
+    ///         println!("Thread unparked");
     ///     })
     ///     .unwrap();
     ///
-    /// handler.join().unwrap();
+    /// // Let some time pass for the thread to be spawned.
+    /// thread::sleep(Duration::from_millis(10));
+    ///
+    /// println!("Unpark the thread");
+    /// parked_thread.thread().unpark();
+    ///
+    /// parked_thread.join().unwrap();
     /// ```
+    ///
+    /// [park]: fn.park.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unpark(&self) {
         let mut guard = self.inner.lock.lock().unwrap();
diff --git a/src/test/compile-fail/crt-static-gated.rs b/src/test/compile-fail/crt-static-gated.rs
deleted file mode 100644 (file)
index 6c7c60b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-// compile-flags:-C target-feature=+crt-static
-// error-pattern: specifying the `crt-static` target feature is only allowed
-
-fn main() {}
index d25674a74b1d37e563adcbe82728b269e3a70626..646ae8183a20ce8c93047a4dfc4d5203162f97e6 100644 (file)
@@ -13,9 +13,8 @@
 // over time, but this test used to exhibit some pretty bogus messages
 // that were not remotely helpful.
 
-// error-pattern:cannot infer
-// error-pattern:cannot outlive the lifetime 'a
-// error-pattern:must be valid for the static lifetime
+// error-pattern:the lifetime 'a
+// error-pattern:the static lifetime
 
 struct Invariant<'a>(Option<&'a mut &'a mut ()>);
 
index e8ada6a1755719205422e74f43591b9bf8ea138f..948fb7e1ef6c29759aed6ba0ddd3ac5db4349471 100644 (file)
@@ -22,7 +22,7 @@ fn foo2<'a:'b,'b>(x: &'b mut (Dummy+'a)) -> &'b mut (Dummy+'b) {
 
 fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
     // Without knowing 'a:'b, we can't coerce
-    x //~ ERROR cannot infer an appropriate lifetime
+    x //~ ERROR lifetime bound not satisfied
      //~^ ERROR cannot infer an appropriate lifetime
 }
 
index d3bf92e85f411a5207e03786dc844487d7417dcf..1795ac95358d7c6c29c2bde494f0212b16ad6076 100644 (file)
@@ -21,7 +21,7 @@ fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
                                 -> Box<Get<&'min i32>>
     where 'max : 'min
 {
-    v //~ ERROR cannot infer an appropriate lifetime
+    v //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
@@ -29,7 +29,7 @@ fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
     where 'max : 'min
 {
     // Previously OK:
-    v //~ ERROR cannot infer an appropriate lifetime
+    v //~ ERROR mismatched types
 }
 
 fn main() { }
index 0e94e35df2839895fdc389f970eeb6396db708e0..ad059a467f570bb2d4b9e5ef872d907ff1f8522c 100644 (file)
@@ -22,14 +22,14 @@ fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
     where 'max : 'min
 {
     // Previously OK, now an error as traits are invariant.
-    v //~ ERROR cannot infer an appropriate lifetime
+    v //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
                                    -> Box<Get<&'max i32>>
     where 'max : 'min
 {
-    v //~ ERROR cannot infer an appropriate lifetime
+    v //~ ERROR mismatched types
 }
 
 fn main() { }
index aa3e06c015d503829e89c839c2beb07e52a40e4e..9edb510b826a12df92df2fe2ea40966ca9ac98fa 100644 (file)
@@ -18,14 +18,14 @@ fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
                                 -> Box<Get<&'min i32>>
     where 'max : 'min
 {
-    v //~ ERROR cannot infer an appropriate lifetime
+    v //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
                                    -> Box<Get<&'max i32>>
     where 'max : 'min
 {
-    v //~ ERROR cannot infer an appropriate lifetime
+    v //~ ERROR mismatched types
 }
 
 fn main() { }
diff --git a/src/test/incremental/remove_source_file/auxiliary/mod.rs b/src/test/incremental/remove_source_file/auxiliary/mod.rs
new file mode 100644 (file)
index 0000000..a2cea65
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2017 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.
+
+pub fn print_hello() {
+    println!("hello");
+}
diff --git a/src/test/incremental/remove_source_file/main.rs b/src/test/incremental/remove_source_file/main.rs
new file mode 100644 (file)
index 0000000..4ba33f3
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2017 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 makes sure that the compiler doesn't crash due to a failing
+// table lookup when a source file is removed.
+
+// revisions:rpass1 rpass2
+
+// Note that we specify -g so that the FileMaps actually get referenced by the
+// incr. comp. cache:
+// compile-flags: -Z query-dep-graph -g
+
+#[cfg(rpass1)]
+mod auxiliary;
+
+#[cfg(rpass1)]
+fn main() {
+    auxiliary::print_hello();
+}
+
+#[cfg(rpass2)]
+fn main() {
+    println!("hello");
+}
diff --git a/src/test/run-pass/issue-41677.rs b/src/test/run-pass/issue-41677.rs
new file mode 100644 (file)
index 0000000..d014382
--- /dev/null
@@ -0,0 +1,37 @@
+// 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.
+
+// Regression test for #41677. The local variable was winding up with
+// a type `Receiver<?T, H>` where `?T` was unconstrained, because we
+// failed to enforce the WF obligations and `?T` is a bivariant type
+// parameter position.
+
+#![allow(unused_variables, dead_code)]
+
+use std::marker::PhantomData;
+
+trait Handle {
+    type Inner;
+}
+
+struct ResizingHandle<H>(PhantomData<H>);
+impl<H> Handle for ResizingHandle<H> {
+    type Inner = H;
+}
+
+struct Receiver<T, H: Handle<Inner=T>>(PhantomData<H>);
+
+fn channel<T>(size: usize) -> Receiver<T, ResizingHandle<T>> {
+    let rx = Receiver(PhantomData);
+    rx
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/issue-41849-variance-req.rs b/src/test/run-pass/issue-41849-variance-req.rs
new file mode 100644 (file)
index 0000000..0557a6e
--- /dev/null
@@ -0,0 +1,43 @@
+// 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.
+
+// Regression test for #41849.
+
+use std::ops::Mul;
+
+const C: usize = 1;
+const CAPACITY: usize = 1 * C;
+
+struct A<X> {
+    f: [X; CAPACITY],
+}
+
+struct B<T> {
+    f: T,
+}
+
+impl<T> Mul for B<T> {
+    type Output = Self;
+    fn mul(self, _rhs: B<T>) -> Self::Output {
+        self
+    }
+}
+
+impl<T> Mul<usize> for B<T> {
+    type Output = Self;
+    fn mul(self, _rhs: usize) -> Self::Output {
+        self
+    }
+}
+
+fn main() {
+    let a = A { f: [1] };
+    let _ = B { f: a };
+}
diff --git a/src/test/run-pass/print-stdout-eprint-stderr.rs b/src/test/run-pass/print-stdout-eprint-stderr.rs
new file mode 100644 (file)
index 0000000..0a0f30a
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2017 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.
+
+// ignore-emscripten spawning processes is not supported
+
+use std::{env, process};
+
+fn child() {
+    print!("[stdout 0]");
+    print!("[stdout {}]", 1);
+    println!("[stdout {}]", 2);
+    println!();
+    eprint!("[stderr 0]");
+    eprint!("[stderr {}]", 1);
+    eprintln!("[stderr {}]", 2);
+    eprintln!();
+}
+
+fn parent() {
+    let this = env::args().next().unwrap();
+    let output = process::Command::new(this).arg("-").output().unwrap();
+    assert!(output.status.success());
+
+    let stdout = String::from_utf8(output.stdout).unwrap();
+    let stderr = String::from_utf8(output.stderr).unwrap();
+
+    assert_eq!(stdout, "[stdout 0][stdout 1][stdout 2]\n\n");
+    assert_eq!(stderr, "[stderr 0][stderr 1][stderr 2]\n\n");
+}
+
+fn main() {
+    if env::args().count() == 2 { child() } else { parent() }
+}
diff --git a/src/test/ui/static-lifetime.rs b/src/test/ui/static-lifetime.rs
new file mode 100644 (file)
index 0000000..7b1887b
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+pub trait Arbitrary: Sized + 'static {}
+
+impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {}
+
+fn main() {
+}
\ No newline at end of file
diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr
new file mode 100644 (file)
index 0000000..f73dff4
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0477]: the type `std::borrow::Cow<'a, A>` does not fulfill the required lifetime
+  --> $DIR/static-lifetime.rs:13:20
+   |
+13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {}
+   |                    ^^^^^^^^^
+   |
+   = note: type must satisfy the static lifetime
+
+error: aborting due to previous error
+
index a044282666da0a7ec100086b2927bdf097f3c3c9..911f3c51f5f6005f4181f023f67218ca72bd2111 100644 (file)
@@ -570,7 +570,7 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
                          format!("-command={}", debugger_script.to_str().unwrap())];
 
                 let mut gdb_path = tool_path;
-                gdb_path.push_str(&format!("/bin/{}-gdb", self.config.target));
+                gdb_path.push_str("/bin/gdb");
                 let procsrv::Result {
                     out,
                     err,
@@ -647,6 +647,11 @@ fn run_debuginfo_gdb_test_no_opt(&self) {
                                              exe_file.to_str().unwrap()
                                              .replace(r"\", r"\\")));
 
+                // Force GDB to print values in the Rust format.
+                if self.config.gdb_native_rust {
+                    script_str.push_str("set language rust\n");
+                }
+
                 // Add line breakpoints
                 for line in &breakpoint_lines {
                     script_str.push_str(&format!("break '{}':{}\n",
index 67babd2d63710444a3071dfd9184648fd85a6a3d..207c18da7d73faf0217fa433cce3a9d075f2fe25 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 67babd2d63710444a3071dfd9184648fd85a6a3d
+Subproject commit 207c18da7d73faf0217fa433cce3a9d075f2fe25