From 71e50180713eaaaa3bedc827e6890cede03baa0b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 12:26:02 +0100 Subject: [PATCH 01/33] ci: replace MINGW_URL with CUSTOM_MINGW=1 This commit replaces the mirrors base URL contained in the MINGW_URL with a CUSTOM_MINGW=1 environment variable. The mirrors base URL will be fetched instead through the MIRRORS_BASE environment variable, defined in src/ci/shared.sh. --- src/ci/azure-pipelines/auto.yml | 12 ++++++------ src/ci/scripts/install-clang.sh | 2 +- src/ci/scripts/install-mingw.sh | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 836f81a781656..f69808c3702bc 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -284,7 +284,7 @@ jobs: MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-1 - MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc + CUSTOM_MINGW: 1 MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 # FIXME(#59637) @@ -294,14 +294,14 @@ jobs: MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-2 - MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc + CUSTOM_MINGW: 1 MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 x86_64-mingw-1: MSYS_BITS: 64 SCRIPT: make ci-mingw-subset-1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu - MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc + CUSTOM_MINGW: 1 MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 # FIXME(#59637) @@ -311,7 +311,7 @@ jobs: MSYS_BITS: 64 SCRIPT: make ci-mingw-subset-2 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu - MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc + CUSTOM_MINGW: 1 MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 @@ -340,7 +340,7 @@ jobs: MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler SCRIPT: python x.py dist - MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc + CUSTOM_MINGW: 1 MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 DIST_REQUIRE_ALL_TOOLS: 1 @@ -349,7 +349,7 @@ jobs: MSYS_BITS: 64 SCRIPT: python x.py dist RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler - MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc + CUSTOM_MINGW: 1 MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 DIST_REQUIRE_ALL_TOOLS: 1 diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index b1e9bf92ca5d2..f0179994e8e4c 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -17,7 +17,7 @@ if isMacOS; then # Configure `AR` specifically so rustbuild doesn't try to infer it as # `clang-ar` by accident. ciCommandSetEnv AR "ar" -elif isWindows && [[ -z ${MINGW_URL+x} ]]; then +elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then # If we're compiling for MSVC then we, like most other distribution builders, # switch to clang as the compiler. This'll allow us eventually to enable LTO # amongst LLVM and rustc. Note that we only do this on MSVC as I don't think diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index b4e8b889f520a..8b11e59fb639d 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -28,7 +28,7 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isWindows; then - if [[ -z "${MINGW_URL+x}" ]]; then + if [[ "${CUSTOM_MINGW-0}" -ne 1 ]]; then arch=i686 if [ "$MSYS_BITS" = "64" ]; then arch=x86_64 @@ -37,9 +37,9 @@ if isWindows; then mingw-w64-$arch-gcc mingw-w64-$arch-python2 ciCommandAddPath "${SYSTEM_WORKFOLDER}/msys2/mingw${MSYS_BITS}/bin" else - curl -o mingw.7z "${MINGW_URL}/${MINGW_ARCHIVE}" + curl -o mingw.7z "${MIRRORS_BASE}/${MINGW_ARCHIVE}" 7z x -y mingw.7z > /dev/null - curl -o "${MINGW_DIR}/bin/gdborig.exe" "${MINGW_URL}/2017-04-20-${MSYS_BITS}bit-gdborig.exe" + curl -o "${MINGW_DIR}/bin/gdborig.exe" "${MIRRORS_BASE}/2017-04-20-${MSYS_BITS}bit-gdborig.exe" ciCommandAddPath "$(pwd)/${MINGW_DIR}/bin" fi fi From 53c2c04d63b3c043ec5b1b4f401e04868a1139a4 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 12:35:55 +0100 Subject: [PATCH 02/33] ci: remove the MINGW_DIR and MINGW_ARCHIVE env vars --- src/ci/azure-pipelines/auto.yml | 12 ------------ src/ci/scripts/install-mingw.sh | 15 ++++++++++++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index f69808c3702bc..74fb237eebd1e 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -285,8 +285,6 @@ jobs: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-1 CUSTOM_MINGW: 1 - MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z - MINGW_DIR: mingw32 # FIXME(#59637) NO_DEBUG_ASSERTIONS: 1 NO_LLVM_ASSERTIONS: 1 @@ -295,15 +293,11 @@ jobs: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-2 CUSTOM_MINGW: 1 - MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z - MINGW_DIR: mingw32 x86_64-mingw-1: MSYS_BITS: 64 SCRIPT: make ci-mingw-subset-1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu CUSTOM_MINGW: 1 - MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z - MINGW_DIR: mingw64 # FIXME(#59637) NO_DEBUG_ASSERTIONS: 1 NO_LLVM_ASSERTIONS: 1 @@ -312,8 +306,6 @@ jobs: SCRIPT: make ci-mingw-subset-2 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu CUSTOM_MINGW: 1 - MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z - MINGW_DIR: mingw64 # 32/64 bit MSVC and GNU deployment dist-x86_64-msvc: @@ -341,8 +333,6 @@ jobs: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler SCRIPT: python x.py dist CUSTOM_MINGW: 1 - MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z - MINGW_DIR: mingw32 DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 dist-x86_64-mingw: @@ -350,8 +340,6 @@ jobs: SCRIPT: python x.py dist RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler CUSTOM_MINGW: 1 - MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z - MINGW_DIR: mingw64 DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 8b11e59fb639d..631d5e575a5dc 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -27,6 +27,9 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" +MINGW_ARCHIVE_32="i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z" +MINGW_ARCHIVE_64="x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z" + if isWindows; then if [[ "${CUSTOM_MINGW-0}" -ne 1 ]]; then arch=i686 @@ -37,9 +40,15 @@ if isWindows; then mingw-w64-$arch-gcc mingw-w64-$arch-python2 ciCommandAddPath "${SYSTEM_WORKFOLDER}/msys2/mingw${MSYS_BITS}/bin" else - curl -o mingw.7z "${MIRRORS_BASE}/${MINGW_ARCHIVE}" + mingw_archive="${MINGW_ARCHIVE_32}" + if [[ "${MSYS_BITS}" = "64" ]]; then + mingw_archive="${MINGW_ARCHIVE_64}" + fi + mingw_dir="mingw${MSYS_BITS}" + + curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}" 7z x -y mingw.7z > /dev/null - curl -o "${MINGW_DIR}/bin/gdborig.exe" "${MIRRORS_BASE}/2017-04-20-${MSYS_BITS}bit-gdborig.exe" - ciCommandAddPath "$(pwd)/${MINGW_DIR}/bin" + curl -o "${mingw_dir}/bin/gdborig.exe" "${MIRRORS_BASE}/2017-04-20-${MSYS_BITS}bit-gdborig.exe" + ciCommandAddPath "$(pwd)/${mingw_dir}/bin" fi fi From af6b26646b41e1b9614be12ae126f7033a3fa908 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 12:45:03 +0100 Subject: [PATCH 03/33] ci: remove the MSYS_BITS env var --- src/ci/azure-pipelines/auto.yml | 17 --------------- src/ci/azure-pipelines/steps/run.yml | 14 ++++++------ src/ci/azure-pipelines/try.yml | 1 - src/ci/scripts/install-mingw.sh | 32 ++++++++++++++++++---------- 4 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 74fb237eebd1e..946eb483c2946 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -223,25 +223,21 @@ jobs: matrix: # 32/64 bit MSVC tests x86_64-msvc-1: - MSYS_BITS: 64 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler SCRIPT: make ci-subset-1 # FIXME(#59637) NO_DEBUG_ASSERTIONS: 1 NO_LLVM_ASSERTIONS: 1 x86_64-msvc-2: - MSYS_BITS: 64 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler SCRIPT: make ci-subset-2 i686-msvc-1: - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc SCRIPT: make ci-subset-1 # FIXME(#59637) NO_DEBUG_ASSERTIONS: 1 NO_LLVM_ASSERTIONS: 1 i686-msvc-2: - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc SCRIPT: make ci-subset-2 # FIXME(#59637) @@ -249,11 +245,9 @@ jobs: NO_LLVM_ASSERTIONS: 1 # MSVC aux tests x86_64-msvc-aux: - MSYS_BITS: 64 RUST_CHECK_TARGET: check-aux EXCLUDE_CARGO=1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc x86_64-msvc-cargo: - MSYS_BITS: 64 SCRIPT: python x.py test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc VCVARS_BAT: vcvars64.bat @@ -262,10 +256,8 @@ jobs: NO_LLVM_ASSERTIONS: 1 # MSVC tools tests x86_64-msvc-tools: - MSYS_BITS: 64 SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstate/toolstates.json - DEPLOY_TOOLSTATES_JSON: toolstates-windows.json # 32/64-bit MinGW builds. # @@ -281,7 +273,6 @@ jobs: # came from the mingw-w64 SourceForge download site. Unfortunately # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. i686-mingw-1: - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-1 CUSTOM_MINGW: 1 @@ -289,12 +280,10 @@ jobs: NO_DEBUG_ASSERTIONS: 1 NO_LLVM_ASSERTIONS: 1 i686-mingw-2: - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-2 CUSTOM_MINGW: 1 x86_64-mingw-1: - MSYS_BITS: 64 SCRIPT: make ci-mingw-subset-1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu CUSTOM_MINGW: 1 @@ -302,14 +291,12 @@ jobs: NO_DEBUG_ASSERTIONS: 1 NO_LLVM_ASSERTIONS: 1 x86_64-mingw-2: - MSYS_BITS: 64 SCRIPT: make ci-mingw-subset-2 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu CUSTOM_MINGW: 1 # 32/64 bit MSVC and GNU deployment dist-x86_64-msvc: - MSYS_BITS: 64 RUST_CONFIGURE_ARGS: >- --build=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc @@ -319,7 +306,6 @@ jobs: DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 dist-i686-msvc: - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: >- --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc @@ -329,14 +315,12 @@ jobs: DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 dist-i686-mingw: - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler SCRIPT: python x.py dist CUSTOM_MINGW: 1 DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 dist-x86_64-mingw: - MSYS_BITS: 64 SCRIPT: python x.py dist RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler CUSTOM_MINGW: 1 @@ -345,7 +329,6 @@ jobs: # "alternate" deployment, see .travis.yml for more info dist-x86_64-msvc-alt: - MSYS_BITS: 64 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist DEPLOY_ALT: 1 diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index cef2d235602f1..4d7c68593223a 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -8,6 +8,13 @@ steps: +# Configure our CI_JOB_NAME variable which log analyzers can use for the main +# step to see what's going on. +- bash: | + builder=$(echo $AGENT_JOBNAME | cut -d ' ' -f 2) + echo "##vso[task.setvariable variable=CI_JOB_NAME]$builder" + displayName: Configure Job Name + # Disable automatic line ending conversion, which is enabled by default on # Azure's Windows image. Having the conversion enabled caused regressions both # in our test suite (it broke miri tests) and in the ecosystem, since we @@ -135,13 +142,6 @@ steps: condition: and(succeeded(), not(variables.SKIP_JOB)) displayName: Install awscli -# Configure our CI_JOB_NAME variable which log analyzers can use for the main -# step to see what's going on. -- bash: | - builder=$(echo $AGENT_JOBNAME | cut -d ' ' -f 2) - echo "##vso[task.setvariable variable=CI_JOB_NAME]$builder" - displayName: Configure Job Name - # As a quick smoke check on the otherwise very fast mingw-check linux builder # check our own internal scripts. - bash: | diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index c919b1023a0eb..fe39ce3e24116 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -72,7 +72,6 @@ jobs: # DEPLOY: 1 # # dist-x86_64-msvc-alt: -# MSYS_BITS: 64 # RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler # SCRIPT: python x.py dist # DEPLOY_ALT: 1 diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 631d5e575a5dc..8b579587b9e1f 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -31,24 +31,34 @@ MINGW_ARCHIVE_32="i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z" MINGW_ARCHIVE_64="x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z" if isWindows; then + case "${CI_JOB_NAME}" in + *i686*) + bits=32 + arch=i686 + mingw_archive="${MINGW_ARCHIVE_32}" + ;; + *x86_64*) + bits=64 + arch=x86_64 + mingw_archive="${MINGW_ARCHIVE_64}" + ;; + *) + echo "src/ci/scripts/install-mingw.sh can't detect the builder's architecture" + echo "please tweak it to recognize the builder named '${CI_JOB_NAME}'" + exit 1 + ;; + esac + if [[ "${CUSTOM_MINGW-0}" -ne 1 ]]; then - arch=i686 - if [ "$MSYS_BITS" = "64" ]; then - arch=x86_64 - fi pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake \ mingw-w64-$arch-gcc mingw-w64-$arch-python2 - ciCommandAddPath "${SYSTEM_WORKFOLDER}/msys2/mingw${MSYS_BITS}/bin" + ciCommandAddPath "${SYSTEM_WORKFOLDER}/msys2/mingw${bits}/bin" else - mingw_archive="${MINGW_ARCHIVE_32}" - if [[ "${MSYS_BITS}" = "64" ]]; then - mingw_archive="${MINGW_ARCHIVE_64}" - fi - mingw_dir="mingw${MSYS_BITS}" + mingw_dir="mingw${bits}" curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}" 7z x -y mingw.7z > /dev/null - curl -o "${mingw_dir}/bin/gdborig.exe" "${MIRRORS_BASE}/2017-04-20-${MSYS_BITS}bit-gdborig.exe" + curl -o "${mingw_dir}/bin/gdborig.exe" "${MIRRORS_BASE}/2017-04-20-${bits}bit-gdborig.exe" ciCommandAddPath "$(pwd)/${mingw_dir}/bin" fi fi From 6104aa77eb97050c3b302a0d13934040de84cda9 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 18:13:18 +0100 Subject: [PATCH 04/33] ci: extract validate-toolstate into a script --- src/ci/azure-pipelines/steps/run.yml | 13 +------------ src/ci/scripts/validate-toolstate.sh | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 12 deletions(-) create mode 100755 src/ci/scripts/validate-toolstate.sh diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index 4d7c68593223a..4df315d5d5cd3 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -144,18 +144,7 @@ steps: # As a quick smoke check on the otherwise very fast mingw-check linux builder # check our own internal scripts. -- bash: | - set -e - git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git - cd rust-toolstate - python2.7 "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" "" - # Only check maintainers if this build is supposed to publish toolstate. - # Builds that are not supposed to publish don't have the access token. - if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then - TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py" - fi - cd .. - rm -rf rust-toolstate +- bash: src/ci/scripts/validate-toolstate.sh env: TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check')) diff --git a/src/ci/scripts/validate-toolstate.sh b/src/ci/scripts/validate-toolstate.sh new file mode 100755 index 0000000000000..93e645b24a859 --- /dev/null +++ b/src/ci/scripts/validate-toolstate.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# A quick smoke test to make sure publish_tooolstate.py works. + +set -euo pipefail +IFS=$'\n\t' + +source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" + +git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git +cd rust-toolstate +python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" "" +# Only check maintainers if this build is supposed to publish toolstate. +# Builds that are not supposed to publish don't have the access token. +if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then + TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py" +fi +cd .. +rm -rf rust-toolstate From d623c56f4c2eab00a9cb5ba12e9e708430945f1a Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 18:18:49 +0100 Subject: [PATCH 05/33] ci: extract running the build into a script --- src/ci/azure-pipelines/steps/run.yml | 15 +-------------- src/ci/scripts/run-build-from-ci.sh | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 14 deletions(-) create mode 100755 src/ci/scripts/run-build-from-ci.sh diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index 4df315d5d5cd3..fe2bee507152d 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -150,22 +150,9 @@ steps: condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check')) displayName: Verify the publish_toolstate script works -- bash: | - set -e - # Remove any preexisting rustup installation since it can interfere - # with the cargotest step and its auto-detection of things like Clippy in - # the environment - rustup self uninstall -y || true - if [ "$IMAGE" = "" ]; then - src/ci/run.sh - else - src/ci/docker/run.sh $IMAGE - fi - #timeoutInMinutes: 180 +- bash: src/ci/scripts/run-build-from-ci.sh timeoutInMinutes: 600 env: - CI: true - SRC: . AWS_ACCESS_KEY_ID: $(SCCACHE_AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(SCCACHE_AWS_SECRET_ACCESS_KEY) TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) diff --git a/src/ci/scripts/run-build-from-ci.sh b/src/ci/scripts/run-build-from-ci.sh new file mode 100755 index 0000000000000..c02117f459de0 --- /dev/null +++ b/src/ci/scripts/run-build-from-ci.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Start the CI build. You shouldn't run this locally: call either src/ci/run.sh +# or src/ci/docker/run.sh instead. + +set -euo pipefail +IFS=$'\n\t' + +source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" + +export CI="true" +export SRC=. + +# Remove any preexisting rustup installation since it can interfere +# with the cargotest step and its auto-detection of things like Clippy in +# the environment +rustup self uninstall -y || true +if [ -z "${IMAGE+x}" ]; then + src/ci/run.sh +else + src/ci/docker/run.sh "${IMAGE}" +fi From e209ee42e99cd76d7fefd0c53fbd84f0d2123935 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 30 Oct 2019 18:56:40 +0100 Subject: [PATCH 06/33] ci: extract collecting cpu stats into a script --- src/ci/azure-pipelines/steps/run.yml | 7 ++----- src/ci/scripts/collect-cpu-stats.sh | 9 +++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100755 src/ci/scripts/collect-cpu-stats.sh diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index fe2bee507152d..e856207b17d49 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -31,11 +31,8 @@ steps: - bash: src/ci/scripts/should-skip-this.sh displayName: Decide whether to run this job -# Spawn a background process to collect CPU usage statistics which we'll upload -# at the end of the build. See the comments in the script here for more -# information. -- bash: python src/ci/cpu-usage-over-time.py &> cpu-usage.csv & - displayName: "Collect CPU-usage statistics in the background" +- bash: src/ci/scripts/collect-cpu-stats.sh + displayName: Collect CPU-usage statistics in the background - bash: src/ci/scripts/dump-environment.sh displayName: Show the current environment diff --git a/src/ci/scripts/collect-cpu-stats.sh b/src/ci/scripts/collect-cpu-stats.sh new file mode 100755 index 0000000000000..08065431f9816 --- /dev/null +++ b/src/ci/scripts/collect-cpu-stats.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Spawn a background process to collect CPU usage statistics which we'll upload +# at the end of the build. See the comments in the script here for more +# information. + +set -euo pipefail +IFS=$'\n\t' + +python src/ci/cpu-usage-over-time.py &> cpu-usage.csv & From c90cc12b0721cc6e80ba62041bf0b82058428580 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 31 Oct 2019 16:56:11 +0100 Subject: [PATCH 07/33] ci: move validate-toolstate.sh in the mingw-check image The task was already run just there, so this cleans things up. --- src/ci/azure-pipelines/steps/run.yml | 8 -------- src/ci/docker/mingw-check/Dockerfile | 5 ++++- .../mingw-check}/validate-toolstate.sh | 9 +++++---- 3 files changed, 9 insertions(+), 13 deletions(-) rename src/ci/{scripts => docker/mingw-check}/validate-toolstate.sh (57%) diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml index e856207b17d49..214c11fd69024 100644 --- a/src/ci/azure-pipelines/steps/run.yml +++ b/src/ci/azure-pipelines/steps/run.yml @@ -139,14 +139,6 @@ steps: condition: and(succeeded(), not(variables.SKIP_JOB)) displayName: Install awscli -# As a quick smoke check on the otherwise very fast mingw-check linux builder -# check our own internal scripts. -- bash: src/ci/scripts/validate-toolstate.sh - env: - TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN) - condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check')) - displayName: Verify the publish_toolstate script works - - bash: src/ci/scripts/run-build-from-ci.sh timeoutInMinutes: 600 env: diff --git a/src/ci/docker/mingw-check/Dockerfile b/src/ci/docker/mingw-check/Dockerfile index 24e2dea4ca773..b2d96aed2a9e8 100644 --- a/src/ci/docker/mingw-check/Dockerfile +++ b/src/ci/docker/mingw-check/Dockerfile @@ -19,7 +19,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +COPY mingw-check/validate-toolstate.sh /scripts/ + ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 ENV SCRIPT python2.7 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ python2.7 ../x.py build --stage 0 src/tools/build-manifest && \ - python2.7 ../x.py test --stage 0 src/tools/compiletest + python2.7 ../x.py test --stage 0 src/tools/compiletest && \ + /scripts/validate-toolstate.sh diff --git a/src/ci/scripts/validate-toolstate.sh b/src/ci/docker/mingw-check/validate-toolstate.sh similarity index 57% rename from src/ci/scripts/validate-toolstate.sh rename to src/ci/docker/mingw-check/validate-toolstate.sh index 93e645b24a859..2ebf1d6d5ae7f 100755 --- a/src/ci/scripts/validate-toolstate.sh +++ b/src/ci/docker/mingw-check/validate-toolstate.sh @@ -4,15 +4,16 @@ set -euo pipefail IFS=$'\n\t' -source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" - +rm -rf rust-toolstate git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git cd rust-toolstate -python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" "" +python2.7 "../../src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" \ + "$(git log --format=%s -n1 HEAD)" "" "" # Only check maintainers if this build is supposed to publish toolstate. # Builds that are not supposed to publish don't have the access token. if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then - TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py" + TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 \ + "../../src/tools/publish_toolstate.py" fi cd .. rm -rf rust-toolstate From 14da85c68e6b5cd8a64a1f2f5ba5cd50c725e38b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 4 Nov 2019 17:40:18 +0100 Subject: [PATCH 08/33] ci: move mirrors to https://ci-mirrors.rust-lang.org --- src/ci/docker/armhf-gnu/Dockerfile | 2 +- src/ci/docker/dist-armv7-linux/crosstool-ng.sh | 2 +- src/ci/docker/dist-various-1/install-mips-musl.sh | 2 +- src/ci/docker/dist-various-1/install-mipsel-musl.sh | 2 +- src/ci/docker/dist-various-2/build-wasi-toolchain.sh | 2 +- src/ci/docker/dist-x86_64-linux/build-curl.sh | 2 +- src/ci/docker/dist-x86_64-linux/build-openssl.sh | 2 +- src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh | 2 +- src/ci/docker/scripts/freebsd-toolchain.sh | 2 +- src/ci/docker/scripts/sccache.sh | 2 +- src/ci/shared.sh | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ci/docker/armhf-gnu/Dockerfile b/src/ci/docker/armhf-gnu/Dockerfile index 9493b33698708..5373612279bca 100644 --- a/src/ci/docker/armhf-gnu/Dockerfile +++ b/src/ci/docker/armhf-gnu/Dockerfile @@ -72,7 +72,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static # TODO: What is this?! # Source of the file: https://github.com/vfdev-5/qemu-rpi2-vexpress/raw/master/vexpress-v2p-ca15-tc1.dtb -RUN curl -O https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/vexpress-v2p-ca15-tc1.dtb +RUN curl -O https://ci-mirrors.rust-lang.org/rustc/vexpress-v2p-ca15-tc1.dtb COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/dist-armv7-linux/crosstool-ng.sh b/src/ci/docker/dist-armv7-linux/crosstool-ng.sh index ae737d9677d87..fb067a79a5c85 100644 --- a/src/ci/docker/dist-armv7-linux/crosstool-ng.sh +++ b/src/ci/docker/dist-armv7-linux/crosstool-ng.sh @@ -1,7 +1,7 @@ set -ex # Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz -url="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/crosstool-ng-1.24.0.tar.gz" +url="https://ci-mirrors.rust-lang.org/rustc/crosstool-ng-1.24.0.tar.gz" curl -Lf $url | tar xzf - cd crosstool-ng-crosstool-ng-1.24.0 ./bootstrap diff --git a/src/ci/docker/dist-various-1/install-mips-musl.sh b/src/ci/docker/dist-various-1/install-mips-musl.sh index 29cfb5d96083e..9584258d23403 100755 --- a/src/ci/docker/dist-various-1/install-mips-musl.sh +++ b/src/ci/docker/dist-various-1/install-mips-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mips-linux-musl # originally from # https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/ # OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" +URL="https://ci-mirrors.rust-lang.org/rustc" FILE="OpenWrt-Toolchain-ar71xx-generic_gcc-5.3.0_musl-1.1.16.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mips-linux-musl --strip-components=2 diff --git a/src/ci/docker/dist-various-1/install-mipsel-musl.sh b/src/ci/docker/dist-various-1/install-mipsel-musl.sh index de8c359d16757..50a8e554b1675 100755 --- a/src/ci/docker/dist-various-1/install-mipsel-musl.sh +++ b/src/ci/docker/dist-various-1/install-mipsel-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl # Note that this originally came from: # https://downloads.openwrt.org/snapshots/trunk/malta/generic/ # OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" +URL="https://ci-mirrors.rust-lang.org/rustc" FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2 diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh index c63ea6facca64..17aa78945cf21 100755 --- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh @@ -5,7 +5,7 @@ set -ex # Originally from https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz -curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ +curl https://ci-mirrors.rust-lang.org/rustc/clang%2Bllvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ tar xJf - export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH diff --git a/src/ci/docker/dist-x86_64-linux/build-curl.sh b/src/ci/docker/dist-x86_64-linux/build-curl.sh index 8200bbe2fdce5..a65e3de5cfc26 100755 --- a/src/ci/docker/dist-x86_64-linux/build-curl.sh +++ b/src/ci/docker/dist-x86_64-linux/build-curl.sh @@ -5,7 +5,7 @@ source shared.sh VERSION=7.66.0 -curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/curl-$VERSION.tar.xz \ +curl https://ci-mirrors.rust-lang.org/rustc/curl-$VERSION.tar.xz \ | xz --decompress \ | tar xf - diff --git a/src/ci/docker/dist-x86_64-linux/build-openssl.sh b/src/ci/docker/dist-x86_64-linux/build-openssl.sh index be8a6c93945e9..0d9bdf7a09929 100755 --- a/src/ci/docker/dist-x86_64-linux/build-openssl.sh +++ b/src/ci/docker/dist-x86_64-linux/build-openssl.sh @@ -4,7 +4,7 @@ set -ex source shared.sh VERSION=1.0.2k -URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/openssl-$VERSION.tar.gz +URL=https://ci-mirrors.rust-lang.org/rustc/openssl-$VERSION.tar.gz curl $URL | tar xzf - diff --git a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh index 797f674b954f2..f8697c698b9fb 100755 --- a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -25,7 +25,7 @@ cd netbsd mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot -URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc +URL=https://ci-mirrors.rust-lang.org/rustc # Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz curl $URL/2018-03-01-netbsd-src.tgz | tar xzf - diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh index 70155e770a960..5670e10be23cf 100755 --- a/src/ci/docker/scripts/freebsd-toolchain.sh +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -59,7 +59,7 @@ done # Originally downloaded from: # https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz -URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz +URL=https://ci-mirrors.rust-lang.org/rustc/2019-04-04-freebsd-${freebsd_arch}-${freebsd_version}-RELEASE-base.txz curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" # Fix up absolute symlinks from the system image. This can be removed diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh index efeb0ed0d72d0..552afbfee7c17 100644 --- a/src/ci/docker/scripts/sccache.sh +++ b/src/ci/docker/scripts/sccache.sh @@ -1,6 +1,6 @@ set -ex curl -fo /usr/local/bin/sccache \ - https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2018-04-02-sccache-x86_64-unknown-linux-musl + https://ci-mirrors.rust-lang.org/rustc/2018-04-02-sccache-x86_64-unknown-linux-musl chmod +x /usr/local/bin/sccache diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 718a5379ae558..862ded0d5dbf0 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -4,7 +4,7 @@ # `source shared.sh`, hence the invalid shebang and not being # marked as an executable file in git. -export MIRRORS_BASE="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" +export MIRRORS_BASE="https://ci-mirrors.rust-lang.org/rustc" # See http://unix.stackexchange.com/questions/82598 # Duplicated in docker/dist-various-2/shared.sh From 85132b20c4b3f6858ea273ec276c4ad9162603f8 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 6 Nov 2019 18:58:57 +0100 Subject: [PATCH 09/33] ci: download curl and openssl from s3 for dist-x86_64-linux CentOS 5 only supports SSLv3 without SNI, and to get newer protocols working we need to download and compile OpenSSL and cURL from our mirror. Because of that, we can't use the CDN, as CloudFront requires TLSv1 with SNI. This commit changes the dist-x86_64-linux image to bypass the CDN for OpenSSL and cURL. --- src/ci/docker/dist-x86_64-linux/build-curl.sh | 5 ++++- src/ci/docker/dist-x86_64-linux/build-openssl.sh | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-x86_64-linux/build-curl.sh b/src/ci/docker/dist-x86_64-linux/build-curl.sh index a65e3de5cfc26..0c7eb5fdac9be 100755 --- a/src/ci/docker/dist-x86_64-linux/build-curl.sh +++ b/src/ci/docker/dist-x86_64-linux/build-curl.sh @@ -5,7 +5,10 @@ source shared.sh VERSION=7.66.0 -curl https://ci-mirrors.rust-lang.org/rustc/curl-$VERSION.tar.xz \ +# This needs to be downloaded directly from S3, it can't go through the CDN. +# That's because the CDN is backed by CloudFront, which requires SNI and TLSv1 +# (without paying an absurd amount of money). +curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/curl-$VERSION.tar.xz \ | xz --decompress \ | tar xf - diff --git a/src/ci/docker/dist-x86_64-linux/build-openssl.sh b/src/ci/docker/dist-x86_64-linux/build-openssl.sh index 0d9bdf7a09929..d8f6bdb51b8d5 100755 --- a/src/ci/docker/dist-x86_64-linux/build-openssl.sh +++ b/src/ci/docker/dist-x86_64-linux/build-openssl.sh @@ -4,7 +4,11 @@ set -ex source shared.sh VERSION=1.0.2k -URL=https://ci-mirrors.rust-lang.org/rustc/openssl-$VERSION.tar.gz + +# This needs to be downloaded directly from S3, it can't go through the CDN. +# That's because the CDN is backed by CloudFront, which requires SNI and TLSv1 +# (without paying an absurd amount of money). +URL=https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/openssl-$VERSION.tar.gz curl $URL | tar xzf - From 71cf364c3cf1c6b437be0e9352fa6d3ee8191404 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Fri, 15 Nov 2019 02:02:09 +0100 Subject: [PATCH 10/33] Fix the source code highlighting on source comments --- src/librustdoc/html/static/main.js | 56 +++++++++++++++++------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 04c0a0f005b82..e992c0b62bf00 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -396,38 +396,46 @@ function getSearchElement() { document.onkeypress = handleShortcut; document.onkeydown = handleShortcut; - document.onclick = function(ev) { - if (hasClass(ev.target, "collapse-toggle")) { - collapseDocs(ev.target, "toggle"); - } else if (hasClass(ev.target.parentNode, "collapse-toggle")) { - collapseDocs(ev.target.parentNode, "toggle"); - } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) { - var prev_id = 0; - var set_fragment = function(name) { - if (browserSupportsHistoryApi()) { - history.replaceState(null, null, "#" + name); - highlightSourceLines(); - } else { - location.replace("#" + name); - } - }; + var handleSourceHighlight = (function() { + var prev_line_id = 0; + + var set_fragment = function(name) { + if (browserSupportsHistoryApi()) { + history.replaceState(null, null, "#" + name); + highlightSourceLines(); + } else { + location.replace("#" + name); + } + }; - var cur_id = parseInt(ev.target.id, 10); + return function(ev) { + var cur_line_id = parseInt(ev.target.id, 10); - if (ev.shiftKey && prev_id) { - if (prev_id > cur_id) { - var tmp = prev_id; - prev_id = cur_id; - cur_id = tmp; + if (ev.shiftKey && prev_line_id) { + // Swap selection if needed + if (prev_line_id > cur_line_id) { + var tmp = prev_line_id; + prev_line_id = cur_line_id; + cur_line_id = tmp; } - set_fragment(prev_id + "-" + cur_id); + set_fragment(prev_line_id + "-" + cur_line_id); } else { - prev_id = cur_id; + prev_line_id = cur_line_id; - set_fragment(cur_id); + set_fragment(cur_line_id); } + } + })(); + + document.onclick = function(ev) { + if (hasClass(ev.target, "collapse-toggle")) { + collapseDocs(ev.target, "toggle"); + } else if (hasClass(ev.target.parentNode, "collapse-toggle")) { + collapseDocs(ev.target.parentNode, "toggle"); + } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) { + handleSourceHighlight(ev); } else if (hasClass(getHelpElement(), "hidden") === false) { var help = getHelpElement(); var is_inside_help_popup = ev.target !== help && help.contains(ev.target); From 1bbb8168ec5aa2d03e1b49d5a38eda0300c67da4 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Fri, 15 Nov 2019 02:30:44 +0100 Subject: [PATCH 11/33] Prevent jumps when selecting one or many lines --- src/librustdoc/html/static/main.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index e992c0b62bf00..4db02d58c51ac 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -401,16 +401,21 @@ function getSearchElement() { var prev_line_id = 0; var set_fragment = function(name) { + var x = window.scrollX, + y = window.scrollY; if (browserSupportsHistoryApi()) { history.replaceState(null, null, "#" + name); highlightSourceLines(); } else { location.replace("#" + name); } + // Prevent jumps when selecting one or many lines + window.scrollTo(x, y); }; return function(ev) { var cur_line_id = parseInt(ev.target.id, 10); + ev.preventDefault(); if (ev.shiftKey && prev_line_id) { // Swap selection if needed From 405866aaa3e8057218ad482ca60e284ea0c9e350 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Nov 2019 11:44:32 +0100 Subject: [PATCH 12/33] re-add miri intrinsic ABI check --- src/librustc_mir/interpret/terminator.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 4f9e404b2c635..0134c77808b82 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -264,6 +264,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { + if caller_abi != Abi::RustIntrinsic && caller_abi != Abi::PlatformIntrinsic { + throw_ub_format!("Rust intrinsic called with an ABI other than \ + `RustIntrinsic` and `PlatformIntrinsic`."); + } + let old_stack = self.cur_frame(); let old_bb = self.frame().block; M::call_intrinsic(self, span, instance, args, dest, ret, unwind)?; From 44b68116c522ad8870f0a8627550ba1f5c8fc797 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Nov 2019 13:14:41 +0100 Subject: [PATCH 13/33] rename and move read_vector_ty --- src/librustc/ty/sty.rs | 18 ++++++++++++++---- src/librustc_mir/interpret/intrinsics.rs | 21 +++++++++++---------- src/librustc_mir/interpret/operand.rs | 11 ----------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 8f6fc02ab4b37..d1d71a4287244 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1814,20 +1814,30 @@ impl<'tcx> TyS<'tcx> { pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self.kind { - Adt(def, substs) => { - def.non_enum_variant().fields[0].ty(tcx, substs) - } + Adt(def, substs) => def.non_enum_variant().fields[0].ty(tcx, substs), _ => bug!("simd_type called on invalid type") } } - pub fn simd_size(&self, _cx: TyCtxt<'_>) -> usize { + pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> usize { + // Parameter currently unused, but probably needed in the future to + // allow `#[repr(simd)] struct Simd([T; N]);`. match self.kind { Adt(def, _) => def.non_enum_variant().fields.len(), _ => bug!("simd_size called on invalid type") } } + pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (usize, Ty<'tcx>) { + match self.kind { + Adt(def, substs) => { + let variant = def.non_enum_variant(); + (variant.fields.len(), variant.fields[0].ty(tcx, substs)) + } + _ => bug!("simd_size_and_type called on invalid type") + } + } + #[inline] pub fn is_region_ptr(&self) -> bool { match self.kind { diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 6117cf4038a24..e43e6c0e43a80 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -302,10 +302,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.copy_op_transmute(args[0], dest)?; } "simd_insert" => { - let index = self.read_scalar(args[1])?.to_u32()? as u64; - let scalar = args[2]; + let index = u64::from(self.read_scalar(args[1])?.to_u32()?); + let elem = args[2]; let input = args[0]; - let (len, e_ty) = self.read_vector_ty(input); + let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx.tcx); + let len = len as u64; assert!( index < len, "Index `{}` must be in bounds of vector type `{}`: `[0, {})`", @@ -317,15 +318,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { dest.layout.ty, input.layout.ty ); assert_eq!( - scalar.layout.ty, e_ty, - "Scalar type `{}` must match vector element type `{}`", - scalar.layout.ty, e_ty + elem.layout.ty, e_ty, + "Scalar element type `{}` must match vector element type `{}`", + elem.layout.ty, e_ty ); for i in 0..len { let place = self.place_field(dest, i)?; let value = if i == index { - scalar + elem } else { self.operand_field(input, i)? }; @@ -333,10 +334,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } "simd_extract" => { - let index = self.read_scalar(args[1])?.to_u32()? as _; - let (len, e_ty) = self.read_vector_ty(args[0]); + let index = u64::from(self.read_scalar(args[1])?.to_u32()?); + let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx.tcx); assert!( - index < len, + index < len as u64, "index `{}` is out-of-bounds of vector type `{}` with length `{}`", index, e_ty, len ); diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 4d2ccdc20da65..970f76a9d6d7c 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -315,17 +315,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - /// Read vector length and element type - pub fn read_vector_ty( - &self, op: OpTy<'tcx, M::PointerTag> - ) -> (u64, &rustc::ty::TyS<'tcx>) { - if let layout::Abi::Vector { .. } = op.layout.abi { - (op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx)) - } else { - bug!("Type `{}` is not a SIMD vector type", op.layout.ty) - } - } - /// Read a scalar from a place pub fn read_scalar( &self, From 09180d71fd382c8d0471ff342147d91def3a1595 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Nov 2019 13:31:09 +0100 Subject: [PATCH 14/33] make simd_size return a u64 --- src/librustc/ty/layout.rs | 2 +- src/librustc/ty/sty.rs | 8 ++++---- src/librustc_codegen_llvm/intrinsic.rs | 22 +++++++++++++--------- src/librustc_mir/interpret/intrinsics.rs | 3 +-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 972452601ddd5..b9fc5f59b7bbc 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -697,7 +697,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // SIMD vector types. ty::Adt(def, ..) if def.repr.simd() => { let element = self.layout_of(ty.simd_type(tcx))?; - let count = ty.simd_size(tcx) as u64; + let count = ty.simd_size(tcx); assert!(count > 0); let scalar = match element.abi { Abi::Scalar(ref scalar) => scalar.clone(), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d1d71a4287244..b7e645d55a5fc 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1819,20 +1819,20 @@ impl<'tcx> TyS<'tcx> { } } - pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> usize { + pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> u64 { // Parameter currently unused, but probably needed in the future to // allow `#[repr(simd)] struct Simd([T; N]);`. match self.kind { - Adt(def, _) => def.non_enum_variant().fields.len(), + Adt(def, _) => def.non_enum_variant().fields.len() as u64, _ => bug!("simd_size called on invalid type") } } - pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (usize, Ty<'tcx>) { + pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { match self.kind { Adt(def, substs) => { let variant = def.non_enum_variant(); - (variant.fields.len(), variant.fields[0].ty(tcx, substs)) + (variant.fields.len() as u64, variant.fields[0].ty(tcx, substs)) } _ => bug!("simd_size_and_type called on invalid type") } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index e1ce7f622e2ef..fb5f457bb3a1c 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -28,6 +28,7 @@ use syntax_pos::Span; use std::cmp::Ordering; use std::{iter, i128, u128}; +use std::convert::TryFrom; fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { let llvm_name = match name { @@ -1105,8 +1106,8 @@ fn generic_simd_intrinsic( let m_len = match in_ty.kind { // Note that this `.unwrap()` crashes for isize/usize, that's sort // of intentional as there's not currently a use case for that. - ty::Int(i) => i.bit_width().unwrap(), - ty::Uint(i) => i.bit_width().unwrap(), + ty::Int(i) => i.bit_width().unwrap() as u64, + ty::Uint(i) => i.bit_width().unwrap() as u64, _ => return_error!("`{}` is not an integral type", in_ty), }; require_simd!(arg_tys[1], "argument"); @@ -1116,7 +1117,7 @@ fn generic_simd_intrinsic( m_len, v_len ); let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, m_len as u64); + let i1xn = bx.type_vector(i1, m_len); let m_i1s = bx.bitcast(args[0].immediate(), i1xn); return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } @@ -1166,7 +1167,7 @@ fn generic_simd_intrinsic( require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); - require!(out_len == n, + require!(out_len == n as u64, "expected return type of length {}, found `{}` with length {}", n, ret_ty, out_len); require!(in_elem == ret_ty.simd_type(tcx), @@ -1251,7 +1252,7 @@ fn generic_simd_intrinsic( // trailing bits. let expected_int_bits = in_len.max(8); match ret_ty.kind { - ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => (), + ty::Uint(i) if i.bit_width() == Some(expected_int_bits as usize) => (), _ => return_error!( "bitmask `{}`, expected `u{}`", ret_ty, expected_int_bits @@ -1276,7 +1277,8 @@ fn generic_simd_intrinsic( // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. let shift_indices = vec![ - bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _); in_len + bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _); + in_len as _ ]; let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice())); // Truncate vector to an @@ -1291,7 +1293,7 @@ fn generic_simd_intrinsic( name: &str, in_elem: &::rustc::ty::TyS<'_>, in_ty: &::rustc::ty::TyS<'_>, - in_len: usize, + in_len: u64, bx: &mut Builder<'a, 'll, 'tcx>, span: Span, args: &[OperandRef<'tcx, &'ll Value>], @@ -1506,11 +1508,12 @@ fn generic_simd_intrinsic( // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, in_len as u64); + let i1xn = bx.type_vector(i1, in_len); (bx.trunc(args[2].immediate(), i1xn), i1xn) }; // Type of the vector of pointers: + let in_len = usize::try_from(in_len).unwrap(); let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count); let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count); @@ -1606,13 +1609,14 @@ fn generic_simd_intrinsic( // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, in_len as u64); + let i1xn = bx.type_vector(i1, in_len); (bx.trunc(args[2].immediate(), i1xn), i1xn) }; let ret_t = bx.type_void(); // Type of the vector of pointers: + let in_len = usize::try_from(in_len).unwrap(); let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count); let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count); diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index e43e6c0e43a80..23f7b1acb54d4 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -306,7 +306,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let elem = args[2]; let input = args[0]; let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx.tcx); - let len = len as u64; assert!( index < len, "Index `{}` must be in bounds of vector type `{}`: `[0, {})`", @@ -337,7 +336,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let index = u64::from(self.read_scalar(args[1])?.to_u32()?); let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx.tcx); assert!( - index < len as u64, + index < len, "index `{}` is out-of-bounds of vector type `{}` with length `{}`", index, e_ty, len ); From 8952c8aa42209919c2980e99f11694e36f2b6845 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Nov 2019 14:10:07 +0100 Subject: [PATCH 15/33] ICE on invalid MIR --- src/librustc_mir/interpret/terminator.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 0134c77808b82..50c4a249c63c2 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -264,10 +264,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { - if caller_abi != Abi::RustIntrinsic && caller_abi != Abi::PlatformIntrinsic { - throw_ub_format!("Rust intrinsic called with an ABI other than \ - `RustIntrinsic` and `PlatformIntrinsic`."); - } + assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic); let old_stack = self.cur_frame(); let old_bb = self.frame().block; From 5e115a25ca3799a9232f2c3712ed36626025c752 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Nov 2019 16:09:45 +0100 Subject: [PATCH 16/33] avoid some casts --- src/librustc_codegen_llvm/intrinsic.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index fb5f457bb3a1c..4277ce1d1f754 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -28,7 +28,6 @@ use syntax_pos::Span; use std::cmp::Ordering; use std::{iter, i128, u128}; -use std::convert::TryFrom; fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { let llvm_name = match name { @@ -1161,13 +1160,13 @@ fn generic_simd_intrinsic( } if name.starts_with("simd_shuffle") { - let n: usize = name["simd_shuffle".len()..].parse().unwrap_or_else(|_| + let n: u64 = name["simd_shuffle".len()..].parse().unwrap_or_else(|_| span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")); require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); - require!(out_len == n as u64, + require!(out_len == n, "expected return type of length {}, found `{}` with length {}", n, ret_ty, out_len); require!(in_elem == ret_ty.simd_type(tcx), @@ -1176,7 +1175,7 @@ fn generic_simd_intrinsic( in_elem, in_ty, ret_ty, ret_ty.simd_type(tcx)); - let total_len = in_len as u128 * 2; + let total_len = u128::from(in_len) * 2; let vector = args[2].immediate(); @@ -1402,7 +1401,7 @@ fn generic_simd_intrinsic( // FIXME: use: // https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Function.h#L182 // https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Intrinsics.h#L81 - fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: usize, no_pointers: usize) -> String { + fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: u64, no_pointers: usize) -> String { let p0s: String = "p0".repeat(no_pointers); match elem_ty.kind { ty::Int(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()), @@ -1412,7 +1411,7 @@ fn generic_simd_intrinsic( } } - fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: Ty<'_>, vec_len: usize, + fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: Ty<'_>, vec_len: u64, mut no_pointers: usize) -> &'ll Type { // FIXME: use cx.layout_of(ty).llvm_type() ? let mut elem_ty = match elem_ty.kind { @@ -1425,7 +1424,7 @@ fn generic_simd_intrinsic( elem_ty = cx.type_ptr_to(elem_ty); no_pointers -= 1; } - cx.type_vector(elem_ty, vec_len as u64) + cx.type_vector(elem_ty, vec_len) } @@ -1513,7 +1512,6 @@ fn generic_simd_intrinsic( }; // Type of the vector of pointers: - let in_len = usize::try_from(in_len).unwrap(); let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count); let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count); @@ -1616,7 +1614,6 @@ fn generic_simd_intrinsic( let ret_t = bx.type_void(); // Type of the vector of pointers: - let in_len = usize::try_from(in_len).unwrap(); let llvm_pointer_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count); let llvm_pointer_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count); From 4e1eeb9a4543c9c1bfbbac0b7813520c5b0be5ef Mon Sep 17 00:00:00 2001 From: clemencetbk Date: Sat, 16 Nov 2019 12:04:17 -0500 Subject: [PATCH 17/33] Add explanation message for E0641 --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0641.md | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/librustc_error_codes/error_codes/E0641.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index ffefe51f854f5..f886d06b96d1b 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -351,6 +351,7 @@ E0635: include_str!("./error_codes/E0635.md"), E0636: include_str!("./error_codes/E0636.md"), E0638: include_str!("./error_codes/E0638.md"), E0639: include_str!("./error_codes/E0639.md"), +E0641: include_str!("./error_codes/E0641.md"), E0642: include_str!("./error_codes/E0642.md"), E0643: include_str!("./error_codes/E0643.md"), E0644: include_str!("./error_codes/E0644.md"), @@ -585,7 +586,6 @@ E0744: include_str!("./error_codes/E0744.md"), E0634, // type has conflicting packed representaton hints E0637, // "'_" is not a valid lifetime bound E0640, // infer outlives requirements - E0641, // cannot cast to/from a pointer with an unknown kind // E0645, // trait aliases not finished E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0667, // `impl Trait` in projections diff --git a/src/librustc_error_codes/error_codes/E0641.md b/src/librustc_error_codes/error_codes/E0641.md new file mode 100644 index 0000000000000..e39bebce1fea6 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0641.md @@ -0,0 +1,19 @@ +Attempted to cast to/from a pointer with an unknown kind. + +Erroneous code examples: + +```compile_fail,E0641 +let b = 0 as *const _; // error +``` + +Must give information for type of pointer that is being cast from/to if the +type cannot be inferred. + +``` +// Creating a pointer from reference: type can be inferred +let a = &(String::from("Hello world!")) as *const _; // Ok + +let b = 0 as *const i32; // Ok + +let c: *const i32 = 0 as *const _; // Ok +``` \ No newline at end of file From dc137dd868daaa2d7821997e6a87d49fbb9e4ca8 Mon Sep 17 00:00:00 2001 From: clemencetbk Date: Sat, 16 Nov 2019 12:05:26 -0500 Subject: [PATCH 18/33] Update ui tests --- src/test/ui/issues/issue-45730.stderr | 1 + src/test/ui/order-dependent-cast-inference.stderr | 1 + 2 files changed, 2 insertions(+) diff --git a/src/test/ui/issues/issue-45730.stderr b/src/test/ui/issues/issue-45730.stderr index 4fc1e3835f7ad..3c400d6eefaa8 100644 --- a/src/test/ui/issues/issue-45730.stderr +++ b/src/test/ui/issues/issue-45730.stderr @@ -30,3 +30,4 @@ LL | let x = 0 as *const i32 as *const _ as *mut _; error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0641`. diff --git a/src/test/ui/order-dependent-cast-inference.stderr b/src/test/ui/order-dependent-cast-inference.stderr index 01e59f8f022fd..081038c573acf 100644 --- a/src/test/ui/order-dependent-cast-inference.stderr +++ b/src/test/ui/order-dependent-cast-inference.stderr @@ -10,3 +10,4 @@ LL | let mut y = 0 as *const _; error: aborting due to previous error +For more information about this error, try `rustc --explain E0641`. From 0487f0c0c38c1bae95bd786bc044307a3ff082e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 8 Nov 2019 18:04:05 -0800 Subject: [PATCH 19/33] Suggest calling async closure when needed When using an async closure as a value in a place that expects a future, suggest calling the closure. Fix #65923. --- src/librustc/traits/error_reporting.rs | 153 ++++++++++++------ ...as-arg-where-it-should-have-been-called.rs | 3 + ...rg-where-it-should-have-been-called.stderr | 21 ++- ...as-arg-where-it-should-have-been-called.rs | 2 + ...rg-where-it-should-have-been-called.stderr | 19 ++- 5 files changed, 143 insertions(+), 55 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index c7e51ff321771..4a51ce2b780df 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1238,60 +1238,109 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { points_at_arg: bool, ) { let self_ty = trait_ref.self_ty(); - match self_ty.kind { + let (def_id, output_ty, callable) = match self_ty.kind { + ty::Closure(def_id, substs) => { + (def_id, self.closure_sig(def_id, substs).output(), "closure") + } ty::FnDef(def_id, _) => { - // We tried to apply the bound to an `fn`. Check whether calling it would evaluate - // to a type that *would* satisfy the trait binding. If it would, suggest calling - // it: `bar(foo)` -> `bar(foo)`. This case is *very* likely to be hit if `foo` is - // `async`. - let output_ty = self_ty.fn_sig(self.tcx).output(); - let new_trait_ref = ty::TraitRef { - def_id: trait_ref.def_id(), - substs: self.tcx.mk_substs_trait(output_ty.skip_binder(), &[]), - }; - let obligation = Obligation::new( - obligation.cause.clone(), - obligation.param_env, - new_trait_ref.to_predicate(), - ); - match self.evaluate_obligation(&obligation) { - Ok(EvaluationResult::EvaluatedToOk) | - Ok(EvaluationResult::EvaluatedToOkModuloRegions) | - Ok(EvaluationResult::EvaluatedToAmbig) => { - if let Some(hir::Node::Item(hir::Item { - ident, - kind: hir::ItemKind::Fn(.., body_id), - .. - })) = self.tcx.hir().get_if_local(def_id) { - let body = self.tcx.hir().body(*body_id); - let msg = "use parentheses to call the function"; - let snippet = format!( - "{}({})", - ident, - body.params.iter() - .map(|arg| match &arg.pat.kind { - hir::PatKind::Binding(_, _, ident, None) - if ident.name != kw::SelfLower => ident.to_string(), - _ => "_".to_string(), - }).collect::>().join(", "), - ); - // When the obligation error has been ensured to have been caused by - // an argument, the `obligation.cause.span` points at the expression - // of the argument, so we can provide a suggestion. This is signaled - // by `points_at_arg`. Otherwise, we give a more general note. - if points_at_arg { - err.span_suggestion( - obligation.cause.span, - msg, - snippet, - Applicability::HasPlaceholders, - ); - } else { - err.help(&format!("{}: `{}`", msg, snippet)); - } - } + (def_id, self_ty.fn_sig(self.tcx).output(), "function") + } + _ => return, + }; + let msg = format!("use parentheses to call the {}", callable); + // We tried to apply the bound to an `fn` or closure. Check whether calling it would + // evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling + // it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`. + + let new_trait_ref = ty::TraitRef { + def_id: trait_ref.def_id(), + substs: self.tcx.mk_substs_trait(output_ty.skip_binder(), &[]), + }; + let obligation = Obligation::new( + obligation.cause.clone(), + obligation.param_env, + new_trait_ref.to_predicate(), + ); + let get_name = |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind| -> Option { + // Get the local name of this closure. This can be inaccurate because + // of the possibility of reassignment, but this should be good enough. + match &kind { + hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { + Some(format!("{}", name)) + } + _ => { + err.note(&msg); + None + } + } + }; + match self.evaluate_obligation(&obligation) { + Ok(EvaluationResult::EvaluatedToOk) | + Ok(EvaluationResult::EvaluatedToOkModuloRegions) | + Ok(EvaluationResult::EvaluatedToAmbig) => { + let hir = self.tcx.hir(); + // Get the name of the callable and the arguments to be used in the suggestion. + let snippet = match hir.get_if_local(def_id) { + Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_, decl, _, span, ..), + .. + })) => { + err.span_label(*span, "consider calling this closure"); + let hir_id = match hir.as_local_hir_id(def_id) { + Some(hir_id) => hir_id, + None => return, + }; + let parent_node = hir.get_parent_node(hir_id); + let name = match hir.find(parent_node) { + Some(hir::Node::Stmt(hir::Stmt { + kind: hir::StmtKind::Local(local), .. + })) => match get_name(err, &local.pat.kind) { + Some(name) => name, + None => return, + }, + // Different to previous arm because one is `&hir::Local` and the other + // is `P`. + Some(hir::Node::Local(local)) => match get_name(err, &local.pat.kind) { + Some(name) => name, + None => return, + }, + _ => return, + }; + let args = decl.inputs.iter() + .map(|_| "_") + .collect::>().join(", "); + format!("{}({})", name, args) + } + Some(hir::Node::Item(hir::Item { + ident, + kind: hir::ItemKind::Fn(.., body_id), + .. + })) => { + err.span_label(ident.span, "consider calling this function"); + let body = hir.body(*body_id); + let args = body.params.iter() + .map(|arg| match &arg.pat.kind { + hir::PatKind::Binding(_, _, ident, None) + if ident.name != kw::SelfLower => ident.to_string(), + _ => "_".to_string(), + }).collect::>().join(", "); + format!("{}({})", ident, args) } - _ => {} + _ => return, + }; + if points_at_arg { + // When the obligation error has been ensured to have been caused by + // an argument, the `obligation.cause.span` points at the expression + // of the argument, so we can provide a suggestion. This is signaled + // by `points_at_arg`. Otherwise, we give a more general note. + err.span_suggestion( + obligation.cause.span, + &msg, + snippet, + Applicability::HasPlaceholders, + ); + } else { + err.help(&format!("{}: `{}`", msg, snippet)); } } _ => {} diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs index a2d2ba145bc5e..156162c9027c3 100644 --- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs +++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs @@ -1,4 +1,5 @@ // edition:2018 +#![feature(async_closure)] use std::future::Future; async fn foo() {} @@ -7,4 +8,6 @@ fn bar(f: impl Future) {} fn main() { bar(foo); //~ERROR E0277 + let async_closure = async || (); + bar(async_closure); //~ERROR E0277 } diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr index 1cc704b443366..05583876a066c 100644 --- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr +++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr @@ -1,6 +1,9 @@ error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied - --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:9 + --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9 | +LL | async fn foo() {} + | --- consider calling this function +LL | LL | fn bar(f: impl Future) {} | --- ----------------- required by this bound in `bar` ... @@ -10,6 +13,20 @@ LL | bar(foo); | the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}` | help: use parentheses to call the function: `foo()` -error: aborting due to previous error +error[E0277]: the trait bound `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]: std::future::Future` is not satisfied + --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9 + | +LL | fn bar(f: impl Future) {} + | --- ----------------- required by this bound in `bar` +... +LL | let async_closure = async || (); + | -------- consider calling this closure +LL | bar(async_closure); + | ^^^^^^^^^^^^^ + | | + | the trait `std::future::Future` is not implemented for `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]` + | help: use parentheses to call the closure: `async_closure()` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs index acd149c5854e8..4303e5c540569 100644 --- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs +++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs @@ -15,4 +15,6 @@ fn bar(f: impl T) {} fn main() { bar(foo); //~ERROR E0277 + let closure = || S; + bar(closure); //~ERROR E0277 } diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr index 7a49031bde7c2..91f60e8f426c4 100644 --- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr +++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr @@ -1,6 +1,9 @@ error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9 | +LL | fn foo() -> impl T { S } + | --- consider calling this function +LL | LL | fn bar(f: impl T) {} | --- ------- required by this bound in `bar` ... @@ -10,6 +13,20 @@ LL | bar(foo); | the trait `T` is not implemented for `fn() -> impl T {foo}` | help: use parentheses to call the function: `foo()` -error: aborting due to previous error +error[E0277]: the trait bound `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:23]: T` is not satisfied + --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:19:9 + | +LL | fn bar(f: impl T) {} + | --- ------- required by this bound in `bar` +... +LL | let closure = || S; + | -- consider calling this closure +LL | bar(closure); + | ^^^^^^^ + | | + | the trait `T` is not implemented for `[closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:23]` + | help: use parentheses to call the closure: `closure()` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. From d7efa5bd6a22a07cf50a7abe0542a830d91aa182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 16 Nov 2019 17:10:13 -0800 Subject: [PATCH 20/33] review comments --- src/librustc/traits/error_reporting.rs | 172 +++++++++++++------------ 1 file changed, 91 insertions(+), 81 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 4a51ce2b780df..b1652f58772d0 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1230,6 +1230,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + fn mk_obligation_for_def_id( + &self, + def_id: DefId, + output_ty: Ty<'tcx>, + cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> PredicateObligation<'tcx> { + let new_trait_ref = ty::TraitRef { + def_id, + substs: self.tcx.mk_substs_trait(output_ty, &[]), + }; + Obligation::new(cause, param_env, new_trait_ref.to_predicate()) + } + + + /// We tried to apply the bound to an `fn` or closure. Check whether calling it would + /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling + /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`. fn suggest_fn_call( &self, obligation: &PredicateObligation<'tcx>, @@ -1248,19 +1266,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => return, }; let msg = format!("use parentheses to call the {}", callable); - // We tried to apply the bound to an `fn` or closure. Check whether calling it would - // evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling - // it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`. - let new_trait_ref = ty::TraitRef { - def_id: trait_ref.def_id(), - substs: self.tcx.mk_substs_trait(output_ty.skip_binder(), &[]), - }; - let obligation = Obligation::new( + let obligation = self.mk_obligation_for_def_id( + trait_ref.def_id(), + output_ty.skip_binder(), obligation.cause.clone(), obligation.param_env, - new_trait_ref.to_predicate(), ); + let get_name = |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind| -> Option { // Get the local name of this closure. This can be inaccurate because // of the possibility of reassignment, but this should be good enough. @@ -1277,73 +1290,72 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match self.evaluate_obligation(&obligation) { Ok(EvaluationResult::EvaluatedToOk) | Ok(EvaluationResult::EvaluatedToOkModuloRegions) | - Ok(EvaluationResult::EvaluatedToAmbig) => { - let hir = self.tcx.hir(); - // Get the name of the callable and the arguments to be used in the suggestion. - let snippet = match hir.get_if_local(def_id) { - Some(hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_, decl, _, span, ..), - .. - })) => { - err.span_label(*span, "consider calling this closure"); - let hir_id = match hir.as_local_hir_id(def_id) { - Some(hir_id) => hir_id, - None => return, - }; - let parent_node = hir.get_parent_node(hir_id); - let name = match hir.find(parent_node) { - Some(hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Local(local), .. - })) => match get_name(err, &local.pat.kind) { - Some(name) => name, - None => return, - }, - // Different to previous arm because one is `&hir::Local` and the other - // is `P`. - Some(hir::Node::Local(local)) => match get_name(err, &local.pat.kind) { - Some(name) => name, - None => return, - }, - _ => return, - }; - let args = decl.inputs.iter() - .map(|_| "_") - .collect::>().join(", "); - format!("{}({})", name, args) - } - Some(hir::Node::Item(hir::Item { - ident, - kind: hir::ItemKind::Fn(.., body_id), - .. - })) => { - err.span_label(ident.span, "consider calling this function"); - let body = hir.body(*body_id); - let args = body.params.iter() - .map(|arg| match &arg.pat.kind { - hir::PatKind::Binding(_, _, ident, None) - if ident.name != kw::SelfLower => ident.to_string(), - _ => "_".to_string(), - }).collect::>().join(", "); - format!("{}({})", ident, args) - } + Ok(EvaluationResult::EvaluatedToAmbig) => {} + _ => return, + } + let hir = self.tcx.hir(); + // Get the name of the callable and the arguments to be used in the suggestion. + let snippet = match hir.get_if_local(def_id) { + Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_, decl, _, span, ..), + .. + })) => { + err.span_label(*span, "consider calling this closure"); + let hir_id = match hir.as_local_hir_id(def_id) { + Some(hir_id) => hir_id, + None => return, + }; + let parent_node = hir.get_parent_node(hir_id); + let name = match hir.find(parent_node) { + Some(hir::Node::Stmt(hir::Stmt { + kind: hir::StmtKind::Local(local), .. + })) => match get_name(err, &local.pat.kind) { + Some(name) => name, + None => return, + }, + // Different to previous arm because one is `&hir::Local` and the other + // is `P`. + Some(hir::Node::Local(local)) => match get_name(err, &local.pat.kind) { + Some(name) => name, + None => return, + }, _ => return, }; - if points_at_arg { - // When the obligation error has been ensured to have been caused by - // an argument, the `obligation.cause.span` points at the expression - // of the argument, so we can provide a suggestion. This is signaled - // by `points_at_arg`. Otherwise, we give a more general note. - err.span_suggestion( - obligation.cause.span, - &msg, - snippet, - Applicability::HasPlaceholders, - ); - } else { - err.help(&format!("{}: `{}`", msg, snippet)); - } + let args = decl.inputs.iter() + .map(|_| "_") + .collect::>().join(", "); + format!("{}({})", name, args) + } + Some(hir::Node::Item(hir::Item { + ident, + kind: hir::ItemKind::Fn(.., body_id), + .. + })) => { + err.span_label(ident.span, "consider calling this function"); + let body = hir.body(*body_id); + let args = body.params.iter() + .map(|arg| match &arg.pat.kind { + hir::PatKind::Binding(_, _, ident, None) + if ident.name != kw::SelfLower => ident.to_string(), + _ => "_".to_string(), + }).collect::>().join(", "); + format!("{}({})", ident, args) } - _ => {} + _ => return, + }; + if points_at_arg { + // When the obligation error has been ensured to have been caused by + // an argument, the `obligation.cause.span` points at the expression + // of the argument, so we can provide a suggestion. This is signaled + // by `points_at_arg`. Otherwise, we give a more general note. + err.span_suggestion( + obligation.cause.span, + &msg, + snippet, + Applicability::HasPlaceholders, + ); + } else { + err.help(&format!("{}: `{}`", msg, snippet)); } } @@ -1377,12 +1389,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let ty::Ref(_, t_type, _) = trait_type.kind { trait_type = t_type; - let substs = self.tcx.mk_substs_trait(trait_type, &[]); - let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs); - let new_obligation = Obligation::new( + let new_obligation = self.mk_obligation_for_def_id( + trait_ref.def_id, + trait_type, ObligationCause::dummy(), obligation.param_env, - new_trait_ref.to_predicate(), ); if self.predicate_may_hold(&new_obligation) { @@ -1440,12 +1451,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { hir::Mutability::Immutable => self.tcx.mk_mut_ref(region, t_type), }; - let substs = self.tcx.mk_substs_trait(&trait_type, &[]); - let new_trait_ref = ty::TraitRef::new(trait_ref.skip_binder().def_id, substs); - let new_obligation = Obligation::new( + let new_obligation = self.mk_obligation_for_def_id( + trait_ref.skip_binder().def_id, + trait_type, ObligationCause::dummy(), obligation.param_env, - new_trait_ref.to_predicate(), ); if self.evaluate_obligation_no_overflow( From ce7a579cace5de621071a9e18416268e93246fdd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 16 Nov 2019 23:35:27 +0300 Subject: [PATCH 21/33] rustc_plugin: Remove the compatibility shim --- Cargo.lock | 8 -------- src/librustc_driver/Cargo.toml | 1 - src/librustc_interface/Cargo.toml | 2 +- src/librustc_interface/passes.rs | 4 ++-- src/librustc_plugin/deprecated/Cargo.toml | 14 -------------- src/librustc_plugin/deprecated/lib.rs | 8 -------- 6 files changed, 3 insertions(+), 34 deletions(-) delete mode 100644 src/librustc_plugin/deprecated/Cargo.toml delete mode 100644 src/librustc_plugin/deprecated/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2ecb38851e7bd..1923032a4dd0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3529,7 +3529,6 @@ dependencies = [ "rustc_metadata", "rustc_mir", "rustc_parse", - "rustc_plugin", "rustc_plugin_impl", "rustc_resolve", "rustc_save_analysis", @@ -3758,13 +3757,6 @@ dependencies = [ "syntax_pos", ] -[[package]] -name = "rustc_plugin" -version = "0.0.0" -dependencies = [ - "rustc_plugin_impl", -] - [[package]] name = "rustc_plugin_impl" version = "0.0.0" diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index ff673e52b60c2..f9613d1aafc69 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -22,7 +22,6 @@ errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } rustc_parse = { path = "../librustc_parse" } -rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot rustc_plugin_impl = { path = "../librustc_plugin" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index de59882bbdf95..7efcc2855bbaa 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -31,7 +31,7 @@ rustc_passes = { path = "../librustc_passes" } rustc_typeck = { path = "../librustc_typeck" } rustc_lint = { path = "../librustc_lint" } rustc_errors = { path = "../librustc_errors" } -rustc_plugin = { path = "../librustc_plugin", package = "rustc_plugin_impl" } +rustc_plugin_impl = { path = "../librustc_plugin" } rustc_privacy = { path = "../librustc_privacy" } rustc_resolve = { path = "../librustc_resolve" } tempfile = "3.0.5" diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 86d58bfe8bdac..5df814da770ad 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -29,8 +29,8 @@ use rustc_metadata::cstore; use rustc_mir as mir; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, ast_validation, hir_stats, layout_test}; -use rustc_plugin as plugin; -use rustc_plugin::registry::Registry; +use rustc_plugin_impl as plugin; +use rustc_plugin_impl::registry::Registry; use rustc_privacy; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_traits; diff --git a/src/librustc_plugin/deprecated/Cargo.toml b/src/librustc_plugin/deprecated/Cargo.toml deleted file mode 100644 index cc75f7b9ab20d..0000000000000 --- a/src/librustc_plugin/deprecated/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_plugin" -version = "0.0.0" -build = false -edition = "2018" - -[lib] -name = "rustc_plugin" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_plugin_impl = { path = ".." } diff --git a/src/librustc_plugin/deprecated/lib.rs b/src/librustc_plugin/deprecated/lib.rs deleted file mode 100644 index 1d0afe84c25a8..0000000000000 --- a/src/librustc_plugin/deprecated/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(staged_api)] -#![unstable(feature = "rustc_private", issue = "27812")] -#![rustc_deprecated(since = "1.38.0", reason = "\ - import this through `rustc_driver::plugin` instead to make TLS work correctly. \ - See https://github.com/rust-lang/rust/issues/62717")] - -pub use rustc_plugin_impl::*; From 7f49f7bcc275062ac7f77b6f58d72e8b180bf367 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 17 Nov 2019 00:54:24 +0300 Subject: [PATCH 22/33] Rename directory `rustc_plugin` -> `rustc_plugin_impl` --- src/librustc_driver/Cargo.toml | 2 +- src/librustc_interface/Cargo.toml | 2 +- src/{librustc_plugin => librustc_plugin_impl}/Cargo.toml | 0 src/{librustc_plugin => librustc_plugin_impl}/build.rs | 0 src/{librustc_plugin => librustc_plugin_impl}/lib.rs | 0 src/{librustc_plugin => librustc_plugin_impl}/load.rs | 0 src/{librustc_plugin => librustc_plugin_impl}/registry.rs | 0 7 files changed, 2 insertions(+), 2 deletions(-) rename src/{librustc_plugin => librustc_plugin_impl}/Cargo.toml (100%) rename src/{librustc_plugin => librustc_plugin_impl}/build.rs (100%) rename src/{librustc_plugin => librustc_plugin_impl}/lib.rs (100%) rename src/{librustc_plugin => librustc_plugin_impl}/load.rs (100%) rename src/{librustc_plugin => librustc_plugin_impl}/registry.rs (100%) diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index f9613d1aafc69..2b7e4d35248e6 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -22,7 +22,7 @@ errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } rustc_parse = { path = "../librustc_parse" } -rustc_plugin_impl = { path = "../librustc_plugin" } +rustc_plugin_impl = { path = "../librustc_plugin_impl" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_error_codes = { path = "../librustc_error_codes" } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index 7efcc2855bbaa..7ab5ec2b2329e 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -31,7 +31,7 @@ rustc_passes = { path = "../librustc_passes" } rustc_typeck = { path = "../librustc_typeck" } rustc_lint = { path = "../librustc_lint" } rustc_errors = { path = "../librustc_errors" } -rustc_plugin_impl = { path = "../librustc_plugin" } +rustc_plugin_impl = { path = "../librustc_plugin_impl" } rustc_privacy = { path = "../librustc_privacy" } rustc_resolve = { path = "../librustc_resolve" } tempfile = "3.0.5" diff --git a/src/librustc_plugin/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml similarity index 100% rename from src/librustc_plugin/Cargo.toml rename to src/librustc_plugin_impl/Cargo.toml diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin_impl/build.rs similarity index 100% rename from src/librustc_plugin/build.rs rename to src/librustc_plugin_impl/build.rs diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin_impl/lib.rs similarity index 100% rename from src/librustc_plugin/lib.rs rename to src/librustc_plugin_impl/lib.rs diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin_impl/load.rs similarity index 100% rename from src/librustc_plugin/load.rs rename to src/librustc_plugin_impl/load.rs diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin_impl/registry.rs similarity index 100% rename from src/librustc_plugin/registry.rs rename to src/librustc_plugin_impl/registry.rs From d8ea7866fc766c8366ff5d0fc04225270cdf11f6 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 18 Nov 2019 00:47:38 +0900 Subject: [PATCH 23/33] Add JohnTitor to rustc-guide toolstate notification list Also update org names of some books --- src/tools/publish_toolstate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 4383cd9d5be43..61762ae1d9b04 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -41,7 +41,7 @@ 'ryankurte', 'thejpster', 'therealprof', }, 'edition-guide': {'ehuss', 'Centril', 'steveklabnik'}, - 'rustc-guide': {'mark-i-m', 'spastorino', 'amanjeev'}, + 'rustc-guide': {'mark-i-m', 'spastorino', 'amanjeev', 'JohnTitor'}, } REPOS = { @@ -50,11 +50,11 @@ 'rls': 'https://github.com/rust-lang/rls', 'rustfmt': 'https://github.com/rust-lang/rustfmt', 'book': 'https://github.com/rust-lang/book', - 'nomicon': 'https://github.com/rust-lang-nursery/nomicon', - 'reference': 'https://github.com/rust-lang-nursery/reference', + 'nomicon': 'https://github.com/rust-lang/nomicon', + 'reference': 'https://github.com/rust-lang/reference', 'rust-by-example': 'https://github.com/rust-lang/rust-by-example', 'embedded-book': 'https://github.com/rust-embedded/book', - 'edition-guide': 'https://github.com/rust-lang-nursery/edition-guide', + 'edition-guide': 'https://github.com/rust-lang/edition-guide', 'rustc-guide': 'https://github.com/rust-lang/rustc-guide', } From de122e673ac06f47652a593e0895f8367e049290 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 15 Nov 2019 14:29:35 +0100 Subject: [PATCH 24/33] std::error::Chain: remove Copy remove Copy from Iterator as per comment https://github.com/rust-lang/rust/issues/58520#issuecomment-553682166 --- src/libstd/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index df24b6635f411..d1cb0862d82a8 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -791,7 +791,7 @@ impl dyn Error { /// /// [`Error`]: trait.Error.html #[unstable(feature = "error_iter", issue = "58520")] -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] pub struct Chain<'a> { current: Option<&'a (dyn Error + 'static)>, } From eda67ba05cccba4a3360fd27ffc033765a9b41d9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 18 Nov 2019 07:41:10 -0800 Subject: [PATCH 25/33] Disable gdb pretty printer global section on wasm targets The wasm targets don't support gdb anyway so there's no need for this section there. --- src/librustc_target/spec/wasm32_base.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs index 6f00245b00941..e18a9e66468c7 100644 --- a/src/librustc_target/spec/wasm32_base.rs +++ b/src/librustc_target/spec/wasm32_base.rs @@ -140,6 +140,9 @@ pub fn options() -> TargetOptions { has_elf_tls: true, tls_model: "local-exec".to_string(), + // gdb scripts don't work on wasm blobs + emit_debug_gdb_scripts: false, + .. Default::default() } } From 0e2ccaaa3e70d85d1243c07e6ac0ef3829115a8d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 14 Nov 2019 20:19:34 -0500 Subject: [PATCH 26/33] Fix 'type annotations needed' error with opaque types Related: #66426 This commit adds handling for opaque types during inference variable fallback. Type variables generated from the instantiatino of opaque types now fallback to the opque type itself. Normally, the type variable for an instantiated opaque type is either unified with the concrete type, or with the opaque type itself (e.g when a function returns an opaque type by calling another function). However, it's possible for the type variable to be left completely unconstrained. This can occur in code like this: ```rust pub type Foo = impl Copy; fn produce() -> Option { None } ``` Here, we'll instantatiate the `Foo` in `Option` to a fresh type variable, but we will never unify it with anything due to the fact that we return a `None`. This results in the error message: `type annotations needed: cannot resolve `_: std::marker::Copy`` pointing at `pub type Foo = impl Copy`. This message is not only confusing, it's incorrect. When an opaque type inference variable is completely unconstrained, we can always fall back to using the opaque type itself. This effectively turns that particular use of the opaque type into a non-defining use, even if it appears in a defining scope. --- src/librustc/infer/opaque_types/mod.rs | 5 + src/librustc_typeck/check/mod.rs | 101 +++++++++++++++++- src/test/ui/impl-trait/where-allowed-2.rs | 9 ++ src/test/ui/impl-trait/where-allowed-2.stderr | 11 ++ src/test/ui/impl-trait/where-allowed.rs | 5 - src/test/ui/type-alias-impl-trait/fallback.rs | 22 ++++ 6 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/impl-trait/where-allowed-2.rs create mode 100644 src/test/ui/impl-trait/where-allowed-2.stderr create mode 100644 src/test/ui/type-alias-impl-trait/fallback.rs diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 9ed60b1f0c112..500122ce8c49e 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -24,6 +24,10 @@ pub type OpaqueTypeMap<'tcx> = DefIdMap>; /// appear in the return type). #[derive(Copy, Clone, Debug)] pub struct OpaqueTypeDecl<'tcx> { + + /// The opaque type (`ty::Opaque`) for this declaration + pub opaque_type: Ty<'tcx>, + /// The substitutions that we apply to the opaque type that this /// `impl Trait` desugars to. e.g., if: /// @@ -1150,6 +1154,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { self.opaque_types.insert( def_id, OpaqueTypeDecl { + opaque_type: ty, substs, definition_span, concrete_ty: ty_var, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a8418c5f3499b..6c2f6e4fb3eea 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -147,7 +147,7 @@ use crate::TypeAndSubsts; use crate::lint; use crate::util::captures::Captures; use crate::util::common::{ErrorReported, indenter}; -use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashSet, HirIdMap}; +use crate::util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, HirIdMap}; pub use self::Expectation::*; use self::autoderef::Autoderef; @@ -231,6 +231,13 @@ pub struct Inherited<'a, 'tcx> { // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions. opaque_types: RefCell>>, + /// A map from inference variables created from opaque + /// type instantiations (ty::Infer) to the actual opaque + /// type (`ty::Opaque`). Used during fallback to map unconstrained + /// opaque type inference variables to their corresponding + /// opaque type. + opaque_types_vars: RefCell, Ty<'tcx>>>, + /// Each type parameter has an implicit region bound that /// indicates it must outlive at least the function body (the user /// may specify stronger requirements). This field indicates the @@ -696,6 +703,7 @@ impl Inherited<'a, 'tcx> { deferred_cast_checks: RefCell::new(Vec::new()), deferred_generator_interiors: RefCell::new(Vec::new()), opaque_types: RefCell::new(Default::default()), + opaque_types_vars: RefCell::new(Default::default()), implicit_region_bound, body_id, } @@ -937,9 +945,46 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { // All type checking constraints were added, try to fallback unsolved variables. fcx.select_obligations_where_possible(false, |_| {}); let mut fallback_has_occurred = false; + + // We do fallback in two passes, to try to generate + // better error messages. + // The first time, we do *not* replace opaque types. + for ty in &fcx.unsolved_variables() { + fallback_has_occurred |= fcx.fallback_if_possible(ty, false /* opaque_fallback */); + } + // We now see if we can make progress. This might + // cause us to unify inference variables for opaque types, + // since we may have unified some other type variables + // during the first phase of fallback. + // This means that we only replace inference variables with their underlying + // opaque types as a last resort. + // + // In code like this: + // + // ```rust + // type MyType = impl Copy; + // fn produce() -> MyType { true } + // fn bad_produce() -> MyType { panic!() } + // ``` + // + // we want to unify the opaque inference variable in `bad_produce` + // with the diverging fallback for `panic!` (e.g. `()` or `!`), + // This will produce a nice error message about conflicting concrete + // types for `MyType`. + // + // If we had tried to fallback the opaque inference variable to `MyType`, + // we will generate a confusing type-check error that does not explicitly + // refer to opaque types. + fcx.select_obligations_where_possible(fallback_has_occurred, |_| {}); + + // We now run fallback again, but this time we allow it to replace + // unconstrained opaque type variables, in addition to performing + // other kinds of fallback. for ty in &fcx.unsolved_variables() { - fallback_has_occurred |= fcx.fallback_if_possible(ty); + fallback_has_occurred |= fcx.fallback_if_possible(ty, true /* opaque_fallback */); } + + // See if we can make any more progress fcx.select_obligations_where_possible(fallback_has_occurred, |_| {}); // Even though coercion casts provide type hints, we check casts after fallback for @@ -2864,8 +2909,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let mut opaque_types = self.opaque_types.borrow_mut(); + let mut opaque_types_vars = self.opaque_types_vars.borrow_mut(); for (ty, decl) in opaque_type_map { let _ = opaque_types.insert(ty, decl); + let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type); } value @@ -3078,7 +3125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to Error. // The return value indicates whether fallback has occurred. - fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool { + fn fallback_if_possible(&self, ty: Ty<'tcx>, opaque_fallback: bool) -> bool { use rustc::ty::error::UnconstrainedNumeric::Neither; use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat}; @@ -3088,7 +3135,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { UnconstrainedInt => self.tcx.types.i32, UnconstrainedFloat => self.tcx.types.f64, Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(), - Neither => return false, + Neither => { + // This type variable was created from the instantiation of an opaque + // type. The fact that we're attempting to perform fallback for it + // means that the function neither constrained it to a concrete + // type, nor to the opaque type itself. + // + // For example, in this code: + // + //``` + // type MyType = impl Copy; + // fn defining_use() -> MyType { true } + // fn other_use() -> MyType { defining_use() } + // ``` + // + // `defining_use` will constrain the instantiated inference + // variable to `bool`, while `other_use` will constrain + // the instantiated inference variable to `MyType`. + // + // When we process opaque types during writeback, we + // will handle cases like `other_use`, and not count + // them as defining usages + // + // However, we also need to handle cases like this: + // + // ```rust + // pub type Foo = impl Copy; + // fn produce() -> Option { + // None + // } + // ``` + // + // In the above snippet, the inference varaible created by + // instantiating `Option` will be completely unconstrained. + // We treat this as a non-defining use by making the inference + // variable fall back to the opaque type itself. + if opaque_fallback { + if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) { + debug!("fallback_if_possible: falling back opaque type var {:?} to {:?}", + ty, opaque_ty); + *opaque_ty + } else { + return false; + } + } else { + return false; + } + }, }; debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback); self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback); diff --git a/src/test/ui/impl-trait/where-allowed-2.rs b/src/test/ui/impl-trait/where-allowed-2.rs new file mode 100644 index 0000000000000..f7744ef1b3eae --- /dev/null +++ b/src/test/ui/impl-trait/where-allowed-2.rs @@ -0,0 +1,9 @@ +//! Ideally, these tests would go in `where-allowed.rs`, but we bail out +//! too early to display them. +use std::fmt::Debug; + +// Disallowed +fn in_adt_in_return() -> Vec { panic!() } +//~^ ERROR opaque type expands to a recursive type + +fn main() {} diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr new file mode 100644 index 0000000000000..1de15014c1f8d --- /dev/null +++ b/src/test/ui/impl-trait/where-allowed-2.stderr @@ -0,0 +1,11 @@ +error[E0720]: opaque type expands to a recursive type + --> $DIR/where-allowed-2.rs:6:30 + | +LL | fn in_adt_in_return() -> Vec { panic!() } + | ^^^^^^^^^^ expands to a recursive type + | + = note: type resolves to itself + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs index 5ab74e02e0e40..211a14ed4dd99 100644 --- a/src/test/ui/impl-trait/where-allowed.rs +++ b/src/test/ui/impl-trait/where-allowed.rs @@ -11,10 +11,6 @@ fn in_return() -> impl Debug { panic!() } // Allowed fn in_adt_in_parameters(_: Vec) { panic!() } -// Disallowed -fn in_adt_in_return() -> Vec { panic!() } -//~^ ERROR type annotations needed - // Disallowed fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types @@ -60,7 +56,6 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types //~| ERROR nested `impl Trait` is not allowed -//~| ERROR type annotations needed // Disallowed fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } diff --git a/src/test/ui/type-alias-impl-trait/fallback.rs b/src/test/ui/type-alias-impl-trait/fallback.rs new file mode 100644 index 0000000000000..c59c1e3b7d01e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/fallback.rs @@ -0,0 +1,22 @@ +// Tests that we correctly handle the instantiated +// inference variable being completely unconstrained. +// +// check-pass +#![feature(type_alias_impl_trait)] + +type Foo = impl Copy; + +enum Wrapper { + First(T), + Second +} + +fn _make_iter() -> Foo { + true +} + +fn _produce() -> Wrapper { + Wrapper::Second +} + +fn main() {} From 61c75bdb11e782ee50ff1e4de6d29fd5ff4f0e31 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 15 Nov 2019 10:47:47 -0500 Subject: [PATCH 27/33] Add explanation of unconstrained opaque type --- src/test/ui/type-alias-impl-trait/fallback.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/test/ui/type-alias-impl-trait/fallback.rs b/src/test/ui/type-alias-impl-trait/fallback.rs index c59c1e3b7d01e..fe1ca2230daca 100644 --- a/src/test/ui/type-alias-impl-trait/fallback.rs +++ b/src/test/ui/type-alias-impl-trait/fallback.rs @@ -11,11 +11,17 @@ enum Wrapper { Second } -fn _make_iter() -> Foo { +// This method constrains `Foo` to be `bool` +fn constrained_foo() -> Foo { true } -fn _produce() -> Wrapper { + +// This method does not constrain `Foo`. +// Per RFC 2071, function bodies may either +// fully constrain an opaque type, or place no +// constraints on it. +fn unconstrained_foo() -> Wrapper { Wrapper::Second } From f87177b1c5df80d98e8f9c4645ecfc68edbae931 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 15 Nov 2019 16:24:51 -0500 Subject: [PATCH 28/33] Replace bool with new `FallbackMode` enum --- src/librustc/infer/opaque_types/mod.rs | 2 +- src/librustc_typeck/check/mod.rs | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 500122ce8c49e..9b197c1ecb140 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -25,7 +25,7 @@ pub type OpaqueTypeMap<'tcx> = DefIdMap>; #[derive(Copy, Clone, Debug)] pub struct OpaqueTypeDecl<'tcx> { - /// The opaque type (`ty::Opaque`) for this declaration + /// The opaque type (`ty::Opaque`) for this declaration. pub opaque_type: Ty<'tcx>, /// The substitutions that we apply to the opaque type that this diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6c2f6e4fb3eea..50c1a74fe911b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -232,7 +232,7 @@ pub struct Inherited<'a, 'tcx> { opaque_types: RefCell>>, /// A map from inference variables created from opaque - /// type instantiations (ty::Infer) to the actual opaque + /// type instantiations (`ty::Infer`) to the actual opaque /// type (`ty::Opaque`). Used during fallback to map unconstrained /// opaque type inference variables to their corresponding /// opaque type. @@ -950,7 +950,7 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { // better error messages. // The first time, we do *not* replace opaque types. for ty in &fcx.unsolved_variables() { - fallback_has_occurred |= fcx.fallback_if_possible(ty, false /* opaque_fallback */); + fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque); } // We now see if we can make progress. This might // cause us to unify inference variables for opaque types, @@ -968,7 +968,7 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { // ``` // // we want to unify the opaque inference variable in `bad_produce` - // with the diverging fallback for `panic!` (e.g. `()` or `!`), + // with the diverging fallback for `panic!` (e.g. `()` or `!`). // This will produce a nice error message about conflicting concrete // types for `MyType`. // @@ -981,10 +981,10 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { // unconstrained opaque type variables, in addition to performing // other kinds of fallback. for ty in &fcx.unsolved_variables() { - fallback_has_occurred |= fcx.fallback_if_possible(ty, true /* opaque_fallback */); + fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All); } - // See if we can make any more progress + // See if we can make any more progress. fcx.select_obligations_where_possible(fallback_has_occurred, |_| {}); // Even though coercion casts provide type hints, we check casts after fallback for @@ -2544,6 +2544,16 @@ enum TupleArgumentsFlag { TupleArguments, } +/// Controls how we perform fallback for unconstrained +/// type variables. +enum FallbackMode { + /// Do not fallback type variables to opaque types. + NoOpaque, + /// Perform all possible kinds of fallback, including + /// turning type variables to opaque types. + All, +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn new( inh: &'a Inherited<'a, 'tcx>, @@ -3125,7 +3135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to Error. // The return value indicates whether fallback has occurred. - fn fallback_if_possible(&self, ty: Ty<'tcx>, opaque_fallback: bool) -> bool { + fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool { use rustc::ty::error::UnconstrainedNumeric::Neither; use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat}; @@ -3170,7 +3180,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // instantiating `Option` will be completely unconstrained. // We treat this as a non-defining use by making the inference // variable fall back to the opaque type itself. - if opaque_fallback { + if let FallbackMode::All = mode { if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) { debug!("fallback_if_possible: falling back opaque type var {:?} to {:?}", ty, opaque_ty); From a11abe0d6b0f1a7a7bb4bdfde1dedfd89b357732 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 15 Nov 2019 16:50:57 -0500 Subject: [PATCH 29/33] Update test output --- src/test/ui/impl-trait/where-allowed.stderr | 102 +++++++++----------- 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index fcd4c357afdbe..e5d2feff51cc4 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -1,5 +1,5 @@ error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:51:51 + --> $DIR/where-allowed.rs:47:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | --------^^^^^^^^^^- @@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:60:57 + --> $DIR/where-allowed.rs:56:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | --------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | outer `impl Trait` error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:124:16 + --> $DIR/where-allowed.rs:119:16 | LL | type Out = impl Debug; | ^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Out = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:160:23 + --> $DIR/where-allowed.rs:155:23 | LL | type InTypeAlias = impl Debug; | ^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type InTypeAlias = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:164:39 + --> $DIR/where-allowed.rs:159:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ @@ -44,205 +44,205 @@ LL | type InReturnInTypeAlias = fn() -> impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:19:40 + --> $DIR/where-allowed.rs:15:40 | LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:23:42 + --> $DIR/where-allowed.rs:19:42 | LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:27:38 + --> $DIR/where-allowed.rs:23:38 | LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:31:40 + --> $DIR/where-allowed.rs:27:40 | LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:35:49 + --> $DIR/where-allowed.rs:31:49 | LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:39:51 + --> $DIR/where-allowed.rs:35:51 | LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:43:55 + --> $DIR/where-allowed.rs:39:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:47:57 + --> $DIR/where-allowed.rs:43:57 | LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:51:51 + --> $DIR/where-allowed.rs:47:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:56:53 + --> $DIR/where-allowed.rs:52:53 | LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:60:57 + --> $DIR/where-allowed.rs:56:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:66:59 + --> $DIR/where-allowed.rs:61:59 | LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:70:38 + --> $DIR/where-allowed.rs:65:38 | LL | fn in_Fn_parameter_in_generics (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:74:40 + --> $DIR/where-allowed.rs:69:40 | LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:87:32 + --> $DIR/where-allowed.rs:82:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:91:41 + --> $DIR/where-allowed.rs:86:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:95:27 + --> $DIR/where-allowed.rs:90:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:100:25 + --> $DIR/where-allowed.rs:95:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:102:20 + --> $DIR/where-allowed.rs:97:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:113:23 + --> $DIR/where-allowed.rs:108:23 | LL | fn in_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:131:34 + --> $DIR/where-allowed.rs:126:34 | LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:144:33 + --> $DIR/where-allowed.rs:139:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:147:31 + --> $DIR/where-allowed.rs:142:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:164:39 + --> $DIR/where-allowed.rs:159:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:169:16 + --> $DIR/where-allowed.rs:164:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:174:24 + --> $DIR/where-allowed.rs:169:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:179:6 + --> $DIR/where-allowed.rs:174:6 | LL | impl impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:185:24 + --> $DIR/where-allowed.rs:180:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:191:11 + --> $DIR/where-allowed.rs:186:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:198:15 + --> $DIR/where-allowed.rs:193:15 | LL | where Vec: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:205:24 + --> $DIR/where-allowed.rs:200:24 | LL | where T: PartialEq | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:212:17 + --> $DIR/where-allowed.rs:207:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:219:22 + --> $DIR/where-allowed.rs:214:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:225:29 + --> $DIR/where-allowed.rs:220:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ @@ -250,36 +250,24 @@ LL | let _in_local_variable: impl Fn() = || {}; = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/where-allowed.rs:227:46 + --> $DIR/where-allowed.rs:222:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ -error[E0282]: type annotations needed - --> $DIR/where-allowed.rs:15:30 - | -LL | fn in_adt_in_return() -> Vec { panic!() } - | ^^^^^^^^^^ cannot infer type - -error[E0282]: type annotations needed - --> $DIR/where-allowed.rs:60:49 - | -LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } - | ^^^^^^^^^^^^^^^^^^^ cannot infer type - error: could not find defining uses - --> $DIR/where-allowed.rs:160:1 + --> $DIR/where-allowed.rs:155:1 | LL | type InTypeAlias = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/where-allowed.rs:124:5 + --> $DIR/where-allowed.rs:119:5 | LL | type Out = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 44 previous errors +error: aborting due to 42 previous errors -Some errors have detailed explanations: E0282, E0562, E0658, E0666. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0562, E0658, E0666. +For more information about an error, try `rustc --explain E0562`. From 3de7bd28bd0a62f563ce44da9c993c0ef23a9d2b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 17 Nov 2019 22:56:13 -0800 Subject: [PATCH 30/33] Add unix::process::CommandExt::arg0 This allows argv[0] to be overridden on the executable's command-line. This also makes the program executed independent of argv[0]. Does Fuchsia have the same semantics? Addresses: #66510 --- src/libstd/sys/unix/ext/process.rs | 16 +++++++++ src/libstd/sys/unix/process/process_common.rs | 16 +++++++-- .../sys/unix/process/process_fuchsia.rs | 2 +- src/libstd/sys/unix/process/process_unix.rs | 4 +-- src/test/ui/command-argv0.rs | 33 +++++++++++++++++++ 5 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/command-argv0.rs diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 7ace95edef9fb..0e95f97486b24 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -2,6 +2,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::ffi::OsStr; use crate::io; use crate::os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd}; use crate::process; @@ -103,6 +104,14 @@ pub trait CommandExt { /// cross-platform `spawn` instead. #[stable(feature = "process_exec2", since = "1.9.0")] fn exec(&mut self) -> io::Error; + + /// Set executable argument + /// + /// Set the first process argument, `argv[0]`, to something other than the + /// default executable path. + #[unstable(feature = "process_set_argv0", issue = "66510")] + fn arg0(&mut self, arg: S) -> &mut process::Command + where S: AsRef; } #[stable(feature = "rust1", since = "1.0.0")] @@ -127,6 +136,13 @@ impl CommandExt for process::Command { fn exec(&mut self) -> io::Error { self.as_inner_mut().exec(sys::process::Stdio::Inherit) } + + fn arg0(&mut self, arg: S) -> &mut process::Command + where S: AsRef + { + self.as_inner_mut().set_arg_0(arg.as_ref()); + self + } } /// Unix-specific extensions to [`process::ExitStatus`]. diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 4edd2ebf8c598..2efb076bc2ba9 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -135,8 +135,8 @@ impl Command { let program = os2c(program, &mut saw_nul); Command { argv: Argv(vec![program.as_ptr(), ptr::null()]), + args: vec![program.clone()], program, - args: Vec::new(), env: Default::default(), cwd: None, uid: None, @@ -149,11 +149,19 @@ impl Command { } } + pub fn set_arg_0(&mut self, arg: &OsStr) { + // Set a new arg0 + let arg = os2c(arg, &mut self.saw_nul); + debug_assert!(self.argv.0.len() > 1); + self.argv.0[0] = arg.as_ptr(); + self.args[0] = arg; + } + pub fn arg(&mut self, arg: &OsStr) { // Overwrite the trailing NULL pointer in `argv` and then add a new null // pointer. let arg = os2c(arg, &mut self.saw_nul); - self.argv.0[self.args.len() + 1] = arg.as_ptr(); + self.argv.0[self.args.len()] = arg.as_ptr(); self.argv.0.push(ptr::null()); // Also make sure we keep track of the owned value to schedule a @@ -178,6 +186,10 @@ impl Command { &self.argv.0 } + pub fn get_program(&self) -> &CStr { + &*self.program + } + #[allow(dead_code)] pub fn get_cwd(&self) -> &Option { &self.cwd diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 2b1a3ecfd70f5..486c12f9bf88a 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -110,7 +110,7 @@ impl Command { ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null - self.get_argv()[0], self.get_argv().as_ptr(), envp, + self.get_program().as_ptr(), self.get_argv().as_ptr(), envp, actions.len() as size_t, actions.as_ptr(), &mut process_handle, ptr::null_mut(), diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 507dc6892613a..45e4d195f17d2 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -248,7 +248,7 @@ impl Command { *sys::os::environ() = envp.as_ptr(); } - libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); + libc::execvp(self.get_program().as_ptr(), self.get_argv().as_ptr()); Err(io::Error::last_os_error()) } @@ -373,7 +373,7 @@ impl Command { .unwrap_or_else(|| *sys::os::environ() as *const _); let ret = libc::posix_spawnp( &mut p.pid, - self.get_argv()[0], + self.get_program().as_ptr(), file_actions.0.as_ptr(), attrs.0.as_ptr(), self.get_argv().as_ptr() as *const _, diff --git a/src/test/ui/command-argv0.rs b/src/test/ui/command-argv0.rs new file mode 100644 index 0000000000000..56a9fb4d39125 --- /dev/null +++ b/src/test/ui/command-argv0.rs @@ -0,0 +1,33 @@ +// run-pass + +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +#![feature(process_set_argv0)] + +use std::env; +use std::os::unix::process::CommandExt; +use std::process::Command; + +fn main() { + let args: Vec<_> = env::args().collect(); + + if args.len() > 1 { + assert_eq!(args[1], "doing-test"); + assert_eq!(args[0], "i have a silly name"); + + println!("passed"); + return; + } + + let output = + Command::new(&args[0]).arg("doing-test").arg0("i have a silly name").output().unwrap(); + assert!( + output.stderr.is_empty(), + "Non-empty stderr: {}", + String::from_utf8_lossy(&output.stderr) + ); + assert!(output.status.success()); + assert_eq!(output.stdout, b"passed\n"); +} From 614da98454984921142eb2059db7be953d2c855c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 17 Nov 2019 11:27:48 -0800 Subject: [PATCH 31/33] review comments --- src/librustc/traits/error_reporting.rs | 78 +++++++++++++++----------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b1652f58772d0..18f083e154a86 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1244,6 +1244,42 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Obligation::new(cause, param_env, new_trait_ref.to_predicate()) } + /// Given a closure's `DefId`, return the given name of the closure. + /// + /// This doesn't account for reassignments, but it's only used for suggestions. + fn get_closure_name( + &self, + def_id: DefId, + err: &mut DiagnosticBuilder<'_>, + msg: &str, + ) -> Option { + let get_name = |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind| -> Option { + // Get the local name of this closure. This can be inaccurate because + // of the possibility of reassignment, but this should be good enough. + match &kind { + hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { + Some(format!("{}", name)) + } + _ => { + err.note(&msg); + None + } + } + }; + + let hir = self.tcx.hir(); + let hir_id = hir.as_local_hir_id(def_id)?; + let parent_node = hir.get_parent_node(hir_id); + match hir.find(parent_node) { + Some(hir::Node::Stmt(hir::Stmt { + kind: hir::StmtKind::Local(local), .. + })) => get_name(err, &local.pat.kind), + // Different to previous arm because one is `&hir::Local` and the other + // is `P`. + Some(hir::Node::Local(local)) => get_name(err, &local.pat.kind), + _ => return None, + } + } /// We tried to apply the bound to an `fn` or closure. Check whether calling it would /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling @@ -1274,19 +1310,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { obligation.param_env, ); - let get_name = |err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind| -> Option { - // Get the local name of this closure. This can be inaccurate because - // of the possibility of reassignment, but this should be good enough. - match &kind { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { - Some(format!("{}", name)) - } - _ => { - err.note(&msg); - None - } - } - }; match self.evaluate_obligation(&obligation) { Ok(EvaluationResult::EvaluatedToOk) | Ok(EvaluationResult::EvaluatedToOkModuloRegions) | @@ -1301,29 +1324,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. })) => { err.span_label(*span, "consider calling this closure"); - let hir_id = match hir.as_local_hir_id(def_id) { - Some(hir_id) => hir_id, + let name = match self.get_closure_name(def_id, err, &msg) { + Some(name) => name, None => return, }; - let parent_node = hir.get_parent_node(hir_id); - let name = match hir.find(parent_node) { - Some(hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Local(local), .. - })) => match get_name(err, &local.pat.kind) { - Some(name) => name, - None => return, - }, - // Different to previous arm because one is `&hir::Local` and the other - // is `P`. - Some(hir::Node::Local(local)) => match get_name(err, &local.pat.kind) { - Some(name) => name, - None => return, - }, - _ => return, - }; let args = decl.inputs.iter() .map(|_| "_") - .collect::>().join(", "); + .collect::>() + .join(", "); format!("{}({})", name, args) } Some(hir::Node::Item(hir::Item { @@ -1336,9 +1344,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let args = body.params.iter() .map(|arg| match &arg.pat.kind { hir::PatKind::Binding(_, _, ident, None) + // FIXME: provide a better suggestion when encountering `SelfLower`, it + // should suggest a method call. if ident.name != kw::SelfLower => ident.to_string(), _ => "_".to_string(), - }).collect::>().join(", "); + }) + .collect::>() + .join(", "); format!("{}({})", ident, args) } _ => return, From f74fe812fe802c71bd9f909cbce8a703a20ba479 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 18 Nov 2019 23:22:58 +0300 Subject: [PATCH 32/33] resolve: Give derive helpers highest priority during resolution --- src/librustc_resolve/macros.rs | 25 +++++++----- .../auxiliary/derive-helper-shadowing-2.rs | 12 ++++++ .../proc-macro/derive-helper-shadowing-2.rs | 16 ++++++++ .../ui/proc-macro/derive-helper-shadowing.rs | 4 +- .../proc-macro/derive-helper-shadowing.stderr | 38 +------------------ 5 files changed, 47 insertions(+), 48 deletions(-) create mode 100644 src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs create mode 100644 src/test/ui/proc-macro/derive-helper-shadowing-2.rs diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 4f687b5ba9200..8dc0fb9bd77f5 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -466,11 +466,12 @@ impl<'a> Resolver<'a> { ) -> Result<&'a NameBinding<'a>, Determinacy> { bitflags::bitflags! { struct Flags: u8 { - const MACRO_RULES = 1 << 0; - const MODULE = 1 << 1; - const MISC_SUGGEST_CRATE = 1 << 2; - const MISC_SUGGEST_SELF = 1 << 3; - const MISC_FROM_PRELUDE = 1 << 4; + const MACRO_RULES = 1 << 0; + const MODULE = 1 << 1; + const DERIVE_HELPER_COMPAT = 1 << 2; + const MISC_SUGGEST_CRATE = 1 << 3; + const MISC_SUGGEST_SELF = 1 << 4; + const MISC_FROM_PRELUDE = 1 << 5; } } @@ -528,8 +529,10 @@ impl<'a> Resolver<'a> { match this.resolve_macro_path(derive, Some(MacroKind::Derive), parent_scope, true, force) { Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) { - let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); - result = ok(res, derive.span, this.arenas); + let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), + ty::Visibility::Public, derive.span, ExpnId::root()) + .to_name_binding(this.arenas); + result = Ok((binding, Flags::DERIVE_HELPER_COMPAT)); break; } Ok(_) | Err(Determinacy::Determined) => {} @@ -659,13 +662,17 @@ impl<'a> Resolver<'a> { let (res, innermost_res) = (binding.res(), innermost_binding.res()); if res != innermost_res { let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin); - let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); + let is_derive_helper_compat = |res, flags: Flags| { + res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper) && + flags.contains(Flags::DERIVE_HELPER_COMPAT) + }; let ambiguity_error_kind = if is_import { Some(AmbiguityKind::Import) } else if innermost_res == builtin || res == builtin { Some(AmbiguityKind::BuiltinAttr) - } else if innermost_res == derive_helper || res == derive_helper { + } else if is_derive_helper_compat(innermost_res, innermost_flags) || + is_derive_helper_compat(res, flags) { Some(AmbiguityKind::DeriveHelper) } else if innermost_flags.contains(Flags::MACRO_RULES) && flags.contains(Flags::MODULE) && diff --git a/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs new file mode 100644 index 0000000000000..370a1a2794dcf --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs @@ -0,0 +1,12 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(same_name, attributes(same_name))] +pub fn derive_a(_: TokenStream) -> TokenStream { + TokenStream::new() +} diff --git a/src/test/ui/proc-macro/derive-helper-shadowing-2.rs b/src/test/ui/proc-macro/derive-helper-shadowing-2.rs new file mode 100644 index 0000000000000..5204d72b980c1 --- /dev/null +++ b/src/test/ui/proc-macro/derive-helper-shadowing-2.rs @@ -0,0 +1,16 @@ +// If a derive macro introduces a helper attribute with the same name as that macro, +// then make sure that it's usable without ambiguities. + +// check-pass +// aux-build:derive-helper-shadowing-2.rs + +#[macro_use] +extern crate derive_helper_shadowing_2; + +#[derive(same_name)] +struct S { + #[same_name] // OK, no ambiguity, derive helpers have highest priority + field: u8, +} + +fn main() {} diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs index f0ca34db414d4..6147e96a74bf1 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs @@ -19,11 +19,11 @@ macro_rules! gen_helper_use { #[empty_helper] //~ ERROR `empty_helper` is ambiguous #[derive(Empty)] struct S { - #[empty_helper] //~ ERROR `empty_helper` is ambiguous + #[empty_helper] // OK, no ambiguity, derive helpers have highest priority field: [u8; { use empty_helper; //~ ERROR `empty_helper` is ambiguous - #[empty_helper] //~ ERROR `empty_helper` is ambiguous + #[empty_helper] // OK, no ambiguity, derive helpers have highest priority struct U; mod inner { diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index 9048830bee24d..76434860a4956 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -61,42 +61,6 @@ LL | use test_macros::empty_attr as empty_helper; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `crate::empty_helper` to refer to this attribute macro unambiguously -error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name) - --> $DIR/derive-helper-shadowing.rs:22:7 - | -LL | #[empty_helper] - | ^^^^^^^^^^^^ ambiguous name - | -note: `empty_helper` could refer to the derive helper attribute defined here - --> $DIR/derive-helper-shadowing.rs:20:10 - | -LL | #[derive(Empty)] - | ^^^^^ -note: `empty_helper` could also refer to the attribute macro imported here - --> $DIR/derive-helper-shadowing.rs:10:5 - | -LL | use test_macros::empty_attr as empty_helper; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `crate::empty_helper` to refer to this attribute macro unambiguously - -error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name) - --> $DIR/derive-helper-shadowing.rs:26:11 - | -LL | #[empty_helper] - | ^^^^^^^^^^^^ ambiguous name - | -note: `empty_helper` could refer to the derive helper attribute defined here - --> $DIR/derive-helper-shadowing.rs:20:10 - | -LL | #[derive(Empty)] - | ^^^^^ -note: `empty_helper` could also refer to the attribute macro imported here - --> $DIR/derive-helper-shadowing.rs:10:5 - | -LL | use test_macros::empty_attr as empty_helper; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `crate::empty_helper` to refer to this attribute macro unambiguously - -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0659`. From c84fae13e5eb5a475dcb214b170aaf77a8c3783d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 1 Nov 2019 15:16:52 +1100 Subject: [PATCH 33/33] Move the definition of `QueryResult` into `plumbing.rs`. Because it's the only file that uses it, and removes the need for importing it. --- src/librustc/ty/query/job.rs | 10 ---------- src/librustc/ty/query/plumbing.rs | 14 +++++++++++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index 391ea762a083b..e5f4e793132f4 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -22,16 +22,6 @@ use { std::iter::FromIterator, }; -/// Indicates the state of a query for a given key in a query map. -pub(super) enum QueryResult<'tcx> { - /// An already executing query. The query job can be used to await for its completion. - Started(Lrc>), - - /// The query panicked. Queries trying to wait on this will raise a fatal error or - /// silently panic. - Poisoned, -} - /// Represents a span and a query key. #[derive(Clone, Debug)] pub struct QueryInfo<'tcx> { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 52a784d3fc0be..fc55b665c1d0e 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -7,7 +7,7 @@ use crate::ty::tls; use crate::ty::{self, TyCtxt}; use crate::ty::query::Query; use crate::ty::query::config::{QueryConfig, QueryDescription}; -use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo}; +use crate::ty::query::job::{QueryJob, QueryInfo}; use errors::DiagnosticBuilder; use errors::Level; @@ -52,6 +52,16 @@ impl QueryValue { } } +/// Indicates the state of a query for a given key in a query map. +pub(super) enum QueryResult<'tcx> { + /// An already executing query. The query job can be used to await for its completion. + Started(Lrc>), + + /// The query panicked. Queries trying to wait on this will raise a fatal error or + /// silently panic. + Poisoned, +} + impl<'tcx, M: QueryConfig<'tcx>> Default for QueryCache<'tcx, M> { fn default() -> QueryCache<'tcx, M> { QueryCache { @@ -676,8 +686,6 @@ macro_rules! define_queries_inner { [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => { use std::mem; - #[cfg(parallel_compiler)] - use ty::query::job::QueryResult; use rustc_data_structures::sharded::Sharded; use crate::{ rustc_data_structures::stable_hasher::HashStable,