diff --git a/.azure-pipelines/auto.yml b/.azure-pipelines/auto.yml index 8035feeeefb97..2e6c3b7a992af 100644 --- a/.azure-pipelines/auto.yml +++ b/.azure-pipelines/auto.yml @@ -138,9 +138,8 @@ jobs: IMAGE: x86_64-gnu-full-bootstrap x86_64-gnu-aux: IMAGE: x86_64-gnu-aux - # FIXME: needs reenabling here rather than Travis - # x86_64-gnu-tools: - # IMAGE: x86_64-gnu-tools + x86_64-gnu-tools: + IMAGE: x86_64-gnu-tools x86_64-gnu-debug: IMAGE: x86_64-gnu-debug x86_64-gnu-nopt: @@ -252,12 +251,10 @@ jobs: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc VCVARS_BAT: vcvars64.bat # MSVC tools tests - # FIXME: broken on azure right now, need to figure out a cause and - # reenable - # x86_64-msvc-tools: - # MSYS_BITS: 64 - # SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows - # RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri + x86_64-msvc-tools: + MSYS_BITS: 64 + SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri # 32/64-bit MinGW builds. # diff --git a/.azure-pipelines/steps/run.yml b/.azure-pipelines/steps/run.yml index 271f9d382ff64..1ece3ceb088a0 100644 --- a/.azure-pipelines/steps/run.yml +++ b/.azure-pipelines/steps/run.yml @@ -8,6 +8,13 @@ steps: +# 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 +# started shipping install scripts with CRLF endings instead of the old LF. +- bash: git config --global core.autocrlf false + displayName: "Disable git automatic line ending conversion" + - checkout: self fetchDepth: 2 diff --git a/.mailmap b/.mailmap index 5673cc5cfbc9d..c5ecfb54fca52 100644 --- a/.mailmap +++ b/.mailmap @@ -167,6 +167,8 @@ Matthijs Hofstra Melody Horn Michael Williams Michael Woerister +Michael Woerister +Michael Woerister Mickaël Raybaud-Roig m-r-r Ms2ger Mukilan Thiagarajan diff --git a/.travis.yml b/.travis.yml index ec90dd3c8fbcc..1d35ea0efacc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,164 +1,10 @@ language: shell -sudo: required -dist: xenial -services: - - docker -addons: - apt: - packages: - - gdb +script: echo Travis CI is not used anymore -git: - depth: 2 - submodules: false - -env: - global: - - CI_JOB_NAME=$TRAVIS_JOB_NAME - -matrix: - fast_finish: true - include: - - env: IMAGE=x86_64-gnu-tools - name: x86_64-gnu-tools - if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/) - -before_install: - # We'll use the AWS cli to download/upload cached docker layers as well as - # push our deployments, so download that here. - - pip install --user awscli; export PATH=$PATH:$HOME/.local/bin:$HOME/Library/Python/2.7/bin/ - - mkdir -p $HOME/rustsrc - # FIXME(#46924): these two commands are required to enable IPv6, - # they shouldn't exist, please revert once more official solutions appeared. - # see https://github.com/travis-ci/travis-ci/issues/8891#issuecomment-353403729 - - if [ "$TRAVIS_OS_NAME" = linux ]; then - echo '{"ipv6":true,"fixed-cidr-v6":"fd9a:8454:6789:13f7::/64"}' | sudo tee /etc/docker/daemon.json; - sudo service docker restart; - fi - -install: - - case "$TRAVIS_OS_NAME" in - linux) - travis_retry curl -fo $HOME/stamp https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-03-17-stamp-x86_64-unknown-linux-musl && - chmod +x $HOME/stamp && - export PATH=$PATH:$HOME - ;; - osx) - if [[ "$SCRIPT" == "./x.py dist" ]]; then - travis_retry brew update && - travis_retry brew install xz && - travis_retry brew install swig@3 && - brew link --force swig@3; - fi && - travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin && - chmod +x /usr/local/bin/sccache && - travis_retry curl -fo /usr/local/bin/stamp https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin && - chmod +x /usr/local/bin/stamp && - travis_retry curl -f http://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz | tar xJf - && - export CC=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang && - export CXX=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang++ && - export AR=ar - ;; - esac - -before_script: - - > - echo "#### Disk usage before running script:"; - df -h; - du . | sort -nr | head -n100 - - > - RUN_SCRIPT="src/ci/init_repo.sh . $HOME/rustsrc"; - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - export RUN_SCRIPT="$RUN_SCRIPT && src/ci/run.sh"; - else - export RUN_SCRIPT="$RUN_SCRIPT && src/ci/docker/run.sh $IMAGE"; - # Enable core dump on Linux. - sudo sh -c 'echo "/checkout/obj/cores/core.%p.%E" > /proc/sys/kernel/core_pattern'; - fi - - > - if [ "$IMAGE" = mingw-check ]; then - # verify the publish_toolstate script works. - git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git; - cd rust-toolstate; - python2.7 "$TRAVIS_BUILD_DIR/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" ""; - cd ..; - rm -rf rust-toolstate; - fi - -# Log time information from this machine and an external machine for insight into possible -# clock drift. Timezones don't matter since relative deltas give all the necessary info. -script: - - > - date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true) - - stamp sh -x -c "$RUN_SCRIPT" - - > - date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true) - -after_success: - - > - echo "#### Build successful; Disk usage after running script:"; - df -h; - du . | sort -nr | head -n100 - - > - if [ "$DEPLOY$DEPLOY_ALT" == "1" ]; then - mkdir -p deploy/$TRAVIS_COMMIT; - if [ "$TRAVIS_OS_NAME" == "osx" ]; then - rm -rf build/dist/doc && - cp -r build/dist/* deploy/$TRAVIS_COMMIT; - else - rm -rf obj/build/dist/doc && - cp -r obj/build/dist/* deploy/$TRAVIS_COMMIT; - fi; - ls -la deploy/$TRAVIS_COMMIT; - deploy_dir=rustc-builds; - if [ "$DEPLOY_ALT" == "1" ]; then - deploy_dir=rustc-builds-alt; - fi; - travis_retry aws s3 cp --no-progress --recursive --acl public-read ./deploy s3://rust-lang-ci2/$deploy_dir - fi - -after_failure: - - > - echo "#### Build failed; Disk usage after running script:"; - df -h; - du . | sort -nr | head -n100 - - # Random attempt at debugging currently. Just poking around in here to see if - # anything shows up. - - # Dump backtrace for macOS - - ls -lat $HOME/Library/Logs/DiagnosticReports/ - - find $HOME/Library/Logs/DiagnosticReports - -type f - -name '*.crash' - -not -name '*.stage2-*.crash' - -not -name 'com.apple.CoreSimulator.CoreSimulatorService-*.crash' - -exec printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" {} \; - -exec head -750 {} \; - -exec echo travis_fold":"end:crashlog \; || true - - # Dump backtrace for Linux - - ln -s . checkout && - for CORE in obj/cores/core.*; do - EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); - if [ -f "$EXE" ]; then - printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; - gdb --batch -q -c "$CORE" "$EXE" - -iex 'set auto-load off' - -iex 'dir src/' - -iex 'set sysroot .' - -ex bt - -ex q; - echo travis_fold":"end:crashlog; - fi; - done || true - - # see #50887 - - cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true - - # attempt to debug anything killed by the oom killer on linux, just to see if - # it happened - - dmesg | grep -i kill +branches: + only: + - auto + - try notifications: email: false diff --git a/Cargo.lock b/Cargo.lock index eaec52a7a150c..98dd10955d57d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1030,7 +1030,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1760,11 +1760,8 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "nodrop" @@ -3450,7 +3447,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4038,14 +4035,6 @@ name = "unicode_categories" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unreachable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "unstable-book-gen" version = "0.1.0" @@ -4124,11 +4113,6 @@ name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "vte" version = "0.3.3" @@ -4388,7 +4372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4" +"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" @@ -4552,7 +4536,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" @@ -4562,7 +4545,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f42f536e22f7fcbb407639765c8fd78707a33109301f834a594758bedd6e8cf" "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/RELEASES.md b/RELEASES.md index b6e2171f6eef9..5ceeea8d037cb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -309,9 +309,9 @@ Misc Compatibility Notes ------------------- -- [`Command::before_exec` is now deprecated in favor of the - unsafe method `Command::pre_exec`.][58059] -- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you +- [`Command::before_exec` is being replaced by the unsafe method + `Command::pre_exec`][58059] and will be deprecated with Rust 1.37.0. +- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated][57425] as you can now use `const` functions in `static` variables. [58370]: https://github.com/rust-lang/rust/pull/58370/ diff --git a/appveyor.yml b/appveyor.yml index ee1511a0394d4..003de85184c32 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,113 +1,8 @@ -environment: - # This is required for at least an AArch64 compiler in one image, and is also - # going to soon be required for compiling LLVM. - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview - - # By default schannel checks revocation of certificates unlike some other SSL - # backends, but we've historically had problems on CI where a revocation - # server goes down presumably. See #43333 for more info - CARGO_HTTP_CHECK_REVOKE: false - - matrix: - # MSVC tools tests - - CI_JOB_NAME: x86_64-msvc-tools - MSYS_BITS: 64 - SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri - -matrix: - fast_finish: true - -clone_depth: 2 +clone_depth: 1 build: false -install: - # Print which AppVeyor agent version we're running on. - - appveyor version - # If we need to download a custom MinGW, do so here and set the path - # appropriately. - # - # Note that this *also* means that we're not using what is typically - # /mingw32/bin/python2.7.exe, which is a "correct" python interpreter where - # /usr/bin/python2.7.exe is not. To ensure we use the right interpreter we - # move `C:\Python27` ahead in PATH and then also make sure the `python2.7.exe` - # file exists in there (which it doesn't by default). - - if defined MINGW_URL appveyor-retry appveyor DownloadFile %MINGW_URL%/%MINGW_ARCHIVE% - - if defined MINGW_URL 7z x -y %MINGW_ARCHIVE% > nul - - if defined MINGW_URL set PATH=%CD%\%MINGW_DIR%\bin;C:\msys64\usr\bin;%PATH% - - # 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 - # clang has an output mode compatible with MinGW that we need. If it does we - # should switch to clang for MinGW as well! - # - # Note that the LLVM installer is an NSIS installer - # - # Original downloaded here came from - # http://releases.llvm.org/8.0.0/LLVM-8.0.0-win64.exe - - if NOT defined MINGW_URL appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-8.0.0-win64.exe - - if NOT defined MINGW_URL .\LLVM-8.0.0-win64.exe /S /NCRC /D=C:\clang-rust - - if NOT defined MINGW_URL set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --set llvm.clang-cl=C:\clang-rust\bin\clang-cl.exe - - # Here we do a pretty heinous thing which is to mangle the MinGW installation - # we just had above. Currently, as of this writing, we're using MinGW-w64 - # builds of gcc, and that's currently at 6.3.0. We use 6.3.0 as it appears to - # be the first version which contains a fix for #40546, builds randomly - # failing during LLVM due to ar.exe/ranlib.exe failures. - # - # Unfortunately, though, 6.3.0 *also* is the first version of MinGW-w64 builds - # to contain a regression in gdb (#40184). As a result if we were to use the - # gdb provided (7.11.1) then we would fail all debuginfo tests. - # - # In order to fix spurious failures (pretty high priority) we use 6.3.0. To - # avoid disabling gdb tests we download an *old* version of gdb, specifically - # that found inside the 6.2.0 distribution. We then overwrite the 6.3.0 gdb - # with the 6.2.0 gdb to get tests passing. - # - # Note that we don't literally overwrite the gdb.exe binary because it appears - # to just use gdborig.exe, so that's the binary we deal with instead. - - if defined MINGW_URL appveyor-retry appveyor DownloadFile %MINGW_URL%/2017-04-20-%MSYS_BITS%bit-gdborig.exe - - if defined MINGW_URL mv 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_DIR%\bin\gdborig.exe - - # Otherwise pull in the MinGW installed on appveyor - - if NOT defined MINGW_URL set PATH=C:\msys64\mingw%MSYS_BITS%\bin;C:\msys64\usr\bin;%PATH% - - # Prefer the "native" Python as LLVM has trouble building with MSYS sometimes - - copy C:\Python27\python.exe C:\Python27\python2.7.exe - - set PATH=C:\Python27;%PATH% - - # Download and install sccache - - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-26-sccache-x86_64-pc-windows-msvc - - mv 2018-04-26-sccache-x86_64-pc-windows-msvc sccache.exe - - set PATH=%PATH%;%CD% - - # Download and install ninja - # - # Note that this is originally from the github releases patch of Ninja - - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-03-15-ninja-win.zip - - 7z x 2017-03-15-ninja-win.zip - - set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja - # - set PATH=%PATH%;%CD% -- this already happens above for sccache - - # Install InnoSetup to get `iscc` used to produce installers - - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-08-22-is.exe - - 2017-08-22-is.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- - - set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH% - - # Help debug some handle issues on AppVeyor - - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-05-15-Handle.zip - - mkdir handle - - 7z x -ohandle 2017-05-15-Handle.zip - - set PATH=%PATH%;%CD%\handle - - handle.exe -accepteula -help - test_script: - - if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc - - sh src/ci/init_repo.sh . /c/cache/rustsrc - - set SRC=. - - set NO_CCACHE=1 - - sh src/ci/run.sh + - echo AppVeyor is not used anymore branches: only: diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 46c58d118f743..cab7443bf3fe8 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -598,6 +598,7 @@ fn test_with_no_doc_stage0() { bless: false, compare_mode: None, rustfix_coverage: false, + pass: None, }; let build = Build::new(config); @@ -640,6 +641,7 @@ fn test_exclude() { bless: false, compare_mode: None, rustfix_coverage: false, + pass: None, }; let build = Build::new(config); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 4774c0a51c09a..179accda0c8b2 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -58,6 +58,7 @@ pub enum Subcommand { /// Whether to automatically update stderr/stdout files bless: bool, compare_mode: Option, + pass: Option, test_args: Vec, rustc_args: Vec, fail_fast: bool, @@ -199,6 +200,12 @@ To learn more about a subcommand, run `./x.py -h`" "mode describing what file the actual ui output will be compared to", "COMPARE MODE", ); + opts.optopt( + "", + "pass", + "force {check,build,run}-pass tests to this mode.", + "check | build | run" + ); opts.optflag( "", "rustfix-coverage", @@ -401,6 +408,7 @@ Arguments: paths, bless: matches.opt_present("bless"), compare_mode: matches.opt_str("compare-mode"), + pass: matches.opt_str("pass"), test_args: matches.opt_strs("test-args"), rustc_args: matches.opt_strs("rustc-args"), fail_fast: !matches.opt_present("no-fail-fast"), @@ -524,6 +532,15 @@ impl Subcommand { _ => None, } } + + pub fn pass(&self) -> Option<&str> { + match *self { + Subcommand::Test { + ref pass, .. + } => pass.as_ref().map(|s| &s[..]), + _ => None, + } + } } fn split(s: &[String]) -> Vec { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2f9bd067c3115..1d54ca16a315b 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1065,6 +1065,11 @@ impl Step for Compiletest { } }); + if let Some(ref pass) = builder.config.cmd.pass() { + cmd.arg("--pass"); + cmd.arg(pass); + } + if let Some(ref nodejs) = builder.config.nodejs { cmd.arg("--nodejs").arg(nodejs); } diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index 116c16b2f35cd..c2cf77d56cb3b 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -22,7 +22,7 @@ shift export CFLAGS="-fPIC $CFLAGS" -MUSL=musl-1.1.20 +MUSL=musl-1.1.22 # may have been downloaded in a previous run if [ ! -d $MUSL ]; then diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 34708d1847f6b..3cda8d927973c 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -13,5 +13,6 @@ - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) +- [Profile-guided Optimization](profile-guided-optimization.md) - [Linker-plugin based LTO](linker-plugin-lto.md) - [Contributing to `rustc`](contributing.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index a616409d9a400..3773a7783020f 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -214,3 +214,20 @@ This option lets you control what happens when the code panics. ## incremental This flag allows you to enable incremental compilation. + +## profile-generate + +This flag allows for creating instrumented binaries that will collect +profiling data for use with profile-guided optimization (PGO). The flag takes +an optional argument which is the path to a directory into which the +instrumented binary will emit the collected data. See the chapter on +[profile-guided optimization](profile-guided-optimization.html) for more +information. + +## profile-use + +This flag specifies the profiling data file to be used for profile-guided +optimization (PGO). The flag takes a mandatory argument which is the path +to a valid `.profdata` file. See the chapter on +[profile-guided optimization](profile-guided-optimization.html) for more +information. diff --git a/src/doc/rustc/src/profile-guided-optimization.md b/src/doc/rustc/src/profile-guided-optimization.md new file mode 100644 index 0000000000000..38be07a6440da --- /dev/null +++ b/src/doc/rustc/src/profile-guided-optimization.md @@ -0,0 +1,136 @@ +# Profile Guided Optimization + +`rustc` supports doing profile-guided optimization (PGO). +This chapter describes what PGO is, what it is good for, and how it can be used. + +## What Is Profiled-Guided Optimization? + +The basic concept of PGO is to collect data about the typical execution of +a program (e.g. which branches it is likely to take) and then use this data +to inform optimizations such as inlining, machine-code layout, +register allocation, etc. + +There are different ways of collecting data about a program's execution. +One is to run the program inside a profiler (such as `perf`) and another +is to create an instrumented binary, that is, a binary that has data +collection built into it, and run that. +The latter usually provides more accurate data and it is also what is +supported by `rustc`. + +## Usage + +Generating a PGO-optimized program involves following a workflow with four steps: + +1. Compile the program with instrumentation enabled + (e.g. `rustc -Cprofile-generate=/tmp/pgo-data main.rs`) +2. Run the instrumented program (e.g. `./main`) which generates a + `default_.profraw` file +3. Convert the `.profraw` file into a `.profdata` file using + LLVM's `llvm-profdata` tool +4. Compile the program again, this time making use of the profiling data + (for example `rustc -Cprofile-use=merged.profdata main.rs`) + +An instrumented program will create one or more `.profraw` files, one for each +instrumented binary. E.g. an instrumented executable that loads two instrumented +dynamic libraries at runtime will generate three `.profraw` files. Running an +instrumented binary multiple times, on the other hand, will re-use the +respective `.profraw` files, updating them in place. + +These `.profraw` files have to be post-processed before they can be fed back +into the compiler. This is done by the `llvm-profdata` tool. This tool +is most easily installed via + +```bash +rustup component add llvm-tools-preview +``` + +Note that installing the `llvm-tools-preview` component won't add +`llvm-profdata` to the `PATH`. Rather, the tool can be found in: + +```bash +~/.rustup/toolchains//lib/rustlib//bin/ +``` + +Alternatively, an `llvm-profdata` coming with a recent LLVM or Clang +version usually works too. + +The `llvm-profdata` tool merges multiple `.profraw` files into a single +`.profdata` file that can then be fed back into the compiler via +`-Cprofile-use`: + +```bash +# STEP 1: Compile the binary with instrumentation +rustc -Cprofile-generate=/tmp/pgo-data -O ./main.rs + +# STEP 2: Run the binary a few times, maybe with common sets of args. +# Each run will create or update `.profraw` files in /tmp/pgo-data +./main mydata1.csv +./main mydata2.csv +./main mydata3.csv + +# STEP 3: Merge and post-process all the `.profraw` files in /tmp/pgo-data +llvm-profdata merge -o ./merged.profdata /tmp/pgo-data + +# STEP 4: Use the merged `.profdata` file during optimization. All `rustc` +# flags have to be the same. +rustc -Cprofile-use=./merged.profdata -O ./main.rs +``` + +### A Complete Cargo Workflow + +Using this feature with Cargo works very similar to using it with `rustc` +directly. Again, we generate an instrumented binary, run it to produce data, +merge the data, and feed it back into the compiler. Some things of note: + +- We use the `RUSTFLAGS` environment variable in order to pass the PGO compiler + flags to the compilation of all crates in the program. + +- We pass the `--target` flag to Cargo, which prevents the `RUSTFLAGS` + arguments to be passed to Cargo build scripts. We don't want the build + scripts to generate a bunch of `.profraw` files. + +- We pass `--release` to Cargo because that's where PGO makes the most sense. + In theory, PGO can also be done on debug builds but there is little reason + to do so. + +- It is recommended to use *absolute paths* for the argument of + `-Cprofile-generate` and `-Cprofile-use`. Cargo can invoke `rustc` with + varying working directories, meaning that `rustc` will not be able to find + the supplied `.profdata` file. With absolute paths this is not an issue. + +- It is good practice to make sure that there is no left-over profiling data + from previous compilation sessions. Just deleting the directory is a simple + way of doing so (see `STEP 0` below). + +This is what the entire workflow looks like: + +```bash +# STEP 0: Make sure there is no left-over profiling data from previous runs +rm -rf /tmp/pgo-data + +# STEP 1: Build the instrumented binaries +RUSTFLAGS="-Cprofile-generate=/tmp/pgo-data" \ + cargo build --release --target=x86_64-unknown-linux-gnu + +# STEP 2: Run the instrumented binaries with some typical data +./target/x86_64-unknown-linux-gnu/release/myprogram mydata1.csv +./target/x86_64-unknown-linux-gnu/release/myprogram mydata2.csv +./target/x86_64-unknown-linux-gnu/release/myprogram mydata3.csv + +# STEP 3: Merge the `.profraw` files into a `.profdata` file +llvm-profdata merge -o /tmp/pgo-data/merged.profdata /tmp/pgo-data + +# STEP 4: Use the `.profdata` file for guiding optimizations +RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" \ + cargo build --release --target=x86_64-unknown-linux-gnu +``` + +## Further Reading + +`rustc`'s PGO support relies entirely on LLVM's implementation of the feature +and is equivalent to what Clang offers via the `-fprofile-generate` / +`-fprofile-use` flags. The [Profile Guided Optimization][clang-pgo] section +in Clang's documentation is therefore an interesting read for anyone who wants +to use PGO with Rust. + +[clang-pgo]: https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index a896ce819aeb7..c9acd3c307b54 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -253,19 +253,6 @@ conversion, so type inference fails because the type is not unique. Please note that you must write the `(())` in one sequence without intermediate whitespace so that rustdoc understands you want an implicit `Result`-returning function. -As of version 1.37.0, this simplification also works with `Option`s, which can -be handy to test e.g. iterators or checked arithmetic, for example: - -```ignore -/// ``` -/// let _ = &[].iter().next()?; -///# Some(()) -/// ``` -``` - -Note that the result must be a `Some(())` and this has to be written in one go. -In this case disambiguating the result isn't required. - ## Documenting macros Here’s an example of documenting a macro: diff --git a/src/doc/unstable-book/src/language-features/member-constraints.md b/src/doc/unstable-book/src/language-features/member-constraints.md new file mode 100644 index 0000000000000..0d11c31aca6e9 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/member-constraints.md @@ -0,0 +1,29 @@ +# `member_constraints` + +The tracking issue for this feature is: [#61977] + +[#61977]: https://github.com/rust-lang/rust/issues/61977 + +------------------------ + +The `member_constraints` feature gate lets you use `impl Trait` syntax with +multiple unrelated lifetime parameters. + +A simple example is: + +```rust +#![feature(member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T {} + +fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { + (x, y) +} + +fn main() { } +``` + +Without the `member_constraints` feature gate, the above example is an +error because both `'a` and `'b` appear in the impl Trait bounds, but +neither outlives the other. diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md index 133174268ef93..00c81f03ba173 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -1,8 +1,8 @@ # `slice_patterns` -The tracking issue for this feature is: [#23121] +The tracking issue for this feature is: [#62254] -[#23121]: https://github.com/rust-lang/rust/issues/23121 +[#62254]: https://github.com/rust-lang/rust/issues/62254 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md b/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md deleted file mode 100644 index bcdeafc4b1137..0000000000000 --- a/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md +++ /dev/null @@ -1,36 +0,0 @@ -# `type_alias_enum_variants` - -The tracking issue for this feature is: [#49683] - -[#49683]: https://github.com/rust-lang/rust/issues/49683 - ------------------------- - -The `type_alias_enum_variants` feature enables the use of variants on type -aliases that refer to enums, as both a constructor and a pattern. That is, -it allows for the syntax `EnumAlias::Variant`, which behaves exactly the same -as `Enum::Variant` (assuming that `EnumAlias` is an alias for some enum type -`Enum`). - -Note that since `Self` exists as a type alias, this feature also enables the -use of the syntax `Self::Variant` within an impl block for an enum type. - -```rust -#![feature(type_alias_enum_variants)] - -enum Foo { - Bar(i32), - Baz { i: i32 }, -} - -type Alias = Foo; - -fn main() { - let t = Alias::Bar(0); - let t = Alias::Baz { i: 0 }; - match t { - Alias::Bar(_i) => {} - Alias::Baz { i: _i } => {} - } -} -``` diff --git a/src/etc/cpu-usage-over-time-plot.sh b/src/etc/cpu-usage-over-time-plot.sh index 724a21c3fc269..0905789079a3e 100755 --- a/src/etc/cpu-usage-over-time-plot.sh +++ b/src/etc/cpu-usage-over-time-plot.sh @@ -16,7 +16,7 @@ set -ex -bucket=rust-lang-ci-evalazure +bucket=rust-lang-ci2 commit=$1 builder=$2 diff --git a/src/etc/gdb_load_rust_pretty_printers.py b/src/etc/gdb_load_rust_pretty_printers.py index c551346bb00bf..fe38c49d2707d 100644 --- a/src/etc/gdb_load_rust_pretty_printers.py +++ b/src/etc/gdb_load_rust_pretty_printers.py @@ -1,2 +1,3 @@ +import gdb import gdb_rust_pretty_printing gdb_rust_pretty_printing.register_printers(gdb.current_objfile()) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9109a730cce2d..41966360377b3 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -367,12 +367,19 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let y = x.clone(); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // But they are unique objects + /// assert_ne!(&*x as *const i32, &*y as *const i32); /// ``` #[rustfmt::skip] #[inline] fn clone(&self) -> Box { box { (**self).clone() } } + /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples @@ -380,10 +387,15 @@ impl Clone for Box { /// ``` /// let x = Box::new(5); /// let mut y = Box::new(10); + /// let yp: *const i32 = &*y; /// /// y.clone_from(&x); /// - /// assert_eq!(*y, 5); + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no allocation occurred + /// assert_eq!(yp, &*y); /// ``` #[inline] fn clone_from(&mut self, source: &Box) { @@ -716,6 +728,14 @@ impl Iterator for Box { (**self).nth(n) } } + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Box { + fn last(self) -> Option where I: Sized { + (*self).last() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for Box { fn next_back(&mut self) -> Option { diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index c898f064fd09f..9f531f5b83c75 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1035,6 +1035,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(self) -> Option<&'a T> { + self.iter.last() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc78..ca35600e85792 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -770,8 +770,8 @@ impl BTreeMap { } // First, we merge `self` and `other` into a sorted sequence in linear time. - let self_iter = mem::replace(self, BTreeMap::new()).into_iter(); - let other_iter = mem::replace(other, BTreeMap::new()).into_iter(); + let self_iter = mem::take(self).into_iter(); + let other_iter = mem::take(other).into_iter(); let iter = MergeIter { left: self_iter.peekable(), right: other_iter.peekable(), @@ -1193,6 +1193,10 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1253,6 +1257,10 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { (self.length, Some(self.length)) } + + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1421,6 +1429,10 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a K> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1458,6 +1470,10 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a V> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1495,6 +1511,10 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + fn last(mut self) -> Option<(&'a K, &'a V)> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1508,6 +1528,10 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + fn last(mut self) -> Option<&'a mut V> { + self.next_back() + } } #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1626,6 +1650,10 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { unsafe { Some(self.next_unchecked()) } } } + + fn last(mut self) -> Option<(&'a K, &'a mut V)> { + self.next_back() + } } impl<'a, K, V> RangeMut<'a, K, V> { diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 16a96ca19b824..d3af910a82c27 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -1019,6 +1019,9 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { @@ -1073,6 +1076,10 @@ impl<'a, T> Iterator for Range<'a, T> { fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(k, _)| k) } + + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "btree_range", since = "1.17.0")] diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 40a82d6feaa98..db0d6e2f9b9d4 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -708,7 +708,7 @@ impl LinkedList { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::replace(self, Self::new()); + return mem::take(self); } else if at == len { return Self::new(); } @@ -832,6 +832,11 @@ impl<'a, T> Iterator for Iter<'a, T> { fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -881,6 +886,11 @@ impl<'a, T> Iterator for IterMut<'a, T> { fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } + + #[inline] + fn last(mut self) -> Option<&'a mut T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 71faf672962b3..573dd86b23aeb 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2206,6 +2206,11 @@ impl<'a, T> Iterator for Iter<'a, T> { self.tail = self.head - iter.len(); final_res } + + #[inline] + fn last(mut self) -> Option<&'a T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2319,6 +2324,11 @@ impl<'a, T> Iterator for IterMut<'a, T> { accum = front.iter_mut().fold(accum, &mut f); back.iter_mut().fold(accum, &mut f) } + + #[inline] + fn last(mut self) -> Option<&'a mut T> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5fc58c8ab5a7b..bfe7d12d9d0ba 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -112,6 +112,7 @@ #![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)] #![feature(alloc_layout_extra)] #![feature(try_trait)] +#![feature(mem_take)] // Allow testing this library diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 40104554fe574..70a93157c9ee2 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -203,7 +203,7 @@ impl ToOwned for str { } fn clone_into(&self, target: &mut String) { - let mut b = mem::replace(target, String::new()).into_bytes(); + let mut b = mem::take(target).into_bytes(); self.as_bytes().clone_into(&mut b); *target = unsafe { String::from_utf8_unchecked(b) } } diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 7f7722548f581..1b0d3c1969274 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2385,6 +2385,11 @@ impl Iterator for Drain<'_> { fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } } #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 5ddac673c9ff1..e0c724f557b9d 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -761,7 +761,6 @@ fn from_into_inner() { it.next().unwrap(); let vec = it.collect::>(); assert_eq!(vec, [2, 3]); - #[cfg(not(miri))] // Miri does not support comparing dangling pointers assert!(ptr != vec.as_ptr()); } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 92fe0834dd029..c0544d7469ca7 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1367,6 +1367,40 @@ impl Vec { self.truncate(new_len); } } + + /// Consumes and leaks the `Vec`, returning a mutable reference to the contents, + /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime + /// `'a`. If the type has only static references, or none at all, then this + /// may be chosen to be `'static`. + /// + /// This function is similar to the `leak` function on `Box`. + /// + /// This function is mainly useful for data that lives for the remainder of + /// the program's life. Dropping the returned reference will cause a memory + /// leak. + /// + /// # Examples + /// + /// Simple usage: + /// + /// ``` + /// #![feature(vec_leak)] + /// + /// fn main() { + /// let x = vec![1, 2, 3]; + /// let static_ref: &'static mut [usize] = Vec::leak(x); + /// static_ref[0] += 1; + /// assert_eq!(static_ref, &[2, 2, 3]); + /// } + /// ``` + #[unstable(feature = "vec_leak", issue = "62195")] + #[inline] + pub fn leak<'a>(vec: Vec) -> &'a mut [T] + where + T: 'a // Technically not needed, but kept to be explicit. + { + Box::leak(vec.into_boxed_slice()) + } } impl Vec { diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index c0ab364380fbd..e6a6fdde54042 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -117,6 +117,7 @@ impl Iterator for EscapeDefault { type Item = u8; fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } + fn last(mut self) -> Option { self.next_back() } } #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for EscapeDefault { diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs index 722c4c805168f..e843303380ad0 100644 --- a/src/libcore/char/methods.rs +++ b/src/libcore/char/methods.rs @@ -337,16 +337,16 @@ impl char { /// ``` /// // as chars /// let eastern = '東'; - /// let capitol = '京'; + /// let capital = '京'; /// /// // both can be represented as three bytes /// assert_eq!(3, eastern.len_utf8()); - /// assert_eq!(3, capitol.len_utf8()); + /// assert_eq!(3, capital.len_utf8()); /// /// // as a &str, these two are encoded in UTF-8 /// let tokyo = "東京"; /// - /// let len = eastern.len_utf8() + capitol.len_utf8(); + /// let len = eastern.len_utf8() + capital.len_utf8(); /// /// // we can see that they take six bytes total... /// assert_eq!(6, tokyo.len()); diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index a697b7bd6e589..c0de8e2ceb3f3 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -251,12 +251,12 @@ pub trait AsMut { /// /// # Examples /// -/// [`String`] implements `Into>`: +/// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`: /// /// In order to express that we want a generic function to take all arguments that can be /// converted to a specified type `T`, we can use a trait bound of [`Into`]``. /// For example: The function `is_hello` takes all arguments that can be converted into a -/// `Vec`. +/// [`Vec`]`<`[`u8`]`>`. /// /// ``` /// fn is_hello>>(s: T) { @@ -274,6 +274,7 @@ pub trait AsMut { /// [`String`]: ../../std/string/struct.String.html /// [`From`]: trait.From.html /// [`Into`]: trait.Into.html +/// [`Vec`]: ../../std/vec/struct.Vec.html #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { /// Performs the conversion. @@ -410,12 +411,12 @@ pub trait TryInto: Sized { /// /// This is useful when you are doing a type conversion that may /// trivially succeed but may also need special handling. -/// For example, there is no way to convert an `i64` into an `i32` -/// using the [`From`] trait, because an `i64` may contain a value -/// that an `i32` cannot represent and so the conversion would lose data. -/// This might be handled by truncating the `i64` to an `i32` (essentially -/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning -/// `i32::MAX`, or by some other method. The `From` trait is intended +/// For example, there is no way to convert an [`i64`] into an [`i32`] +/// using the [`From`] trait, because an [`i64`] may contain a value +/// that an [`i32`] cannot represent and so the conversion would lose data. +/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially +/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning +/// [`i32::MAX`], or by some other method. The [`From`] trait is intended /// for perfect conversions, so the `TryFrom` trait informs the /// programmer when a type conversion could go bad and lets them /// decide how to handle it. @@ -425,8 +426,8 @@ pub trait TryInto: Sized { /// - `TryFrom for U` implies [`TryInto`]` for T` /// - [`try_from`] is reflexive, which means that `TryFrom for T` /// is implemented and cannot fail -- the associated `Error` type for -/// calling `T::try_from()` on a value of type `T` is `Infallible`. -/// When the `!` type is stablized `Infallible` and `!` will be +/// calling `T::try_from()` on a value of type `T` is [`Infallible`]. +/// When the [`!`] type is stablized [`Infallible`] and [`!`] will be /// equivalent. /// /// `TryFrom` can be implemented as follows: @@ -451,7 +452,7 @@ pub trait TryInto: Sized { /// /// # Examples /// -/// As described, [`i32`] implements `TryFrom`: +/// As described, [`i32`] implements `TryFrom<`[`i64`]`>`: /// /// ``` /// use std::convert::TryFrom; @@ -474,6 +475,8 @@ pub trait TryInto: Sized { /// /// [`try_from`]: trait.TryFrom.html#tymethod.try_from /// [`TryInto`]: trait.TryInto.html +/// [`i32::MAX`]: ../../std/i32/constant.MAX.html +/// [`!`]: ../../std/primitive.never.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs index cd61ab5c552b6..1865160bc3cf4 100644 --- a/src/libcore/iter/traits/collect.rs +++ b/src/libcore/iter/traits/collect.rs @@ -196,7 +196,7 @@ pub trait FromIterator: Sized { /// ```rust /// fn collect_as_strings(collection: T) -> Vec /// where T: IntoIterator, -/// T::Item : std::fmt::Debug, +/// T::Item: std::fmt::Debug, /// { /// collection /// .into_iter() diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 04c50329de3d0..d2d08a075b92c 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -126,6 +126,7 @@ #![feature(adx_target_feature)] #![feature(maybe_uninit_slice, maybe_uninit_array)] #![feature(external_doc)] +#![feature(mem_take)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 3f4ff7c2f437e..d9757d78dcebb 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -73,9 +73,9 @@ impl !Send for *mut T { } /// impl Foo for Impl { } /// impl Bar for Impl { } /// -/// let x: &Foo = &Impl; // OK -/// // let y: &Bar = &Impl; // error: the trait `Bar` cannot -/// // be made into an object +/// let x: &dyn Foo = &Impl; // OK +/// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot +/// // be made into an object /// ``` /// /// [trait object]: ../../book/ch17-02-trait-objects.html diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index 770d1ca8e7501..b31522db474b7 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -510,6 +510,8 @@ pub fn swap(x: &mut T, y: &mut T) { /// A simple example: /// /// ``` +/// #![feature(mem_take)] +/// /// use std::mem; /// /// let mut v: Vec = vec![1, 2]; @@ -540,7 +542,8 @@ pub fn swap(x: &mut T, y: &mut T) { /// `self`, allowing it to be returned: /// /// ``` -/// # #![allow(dead_code)] +/// #![feature(mem_take)] +/// /// use std::mem; /// /// # struct Buffer { buf: Vec } @@ -549,6 +552,12 @@ pub fn swap(x: &mut T, y: &mut T) { /// mem::take(&mut self.buf) /// } /// } +/// +/// let mut buffer = Buffer { buf: vec![0, 1] }; +/// assert_eq!(buffer.buf.len(), 2); +/// +/// assert_eq!(buffer.get_and_reset(), vec![0, 1]); +/// assert_eq!(buffer.buf.len(), 0); /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html @@ -583,17 +592,17 @@ pub fn take(dest: &mut T) -> T { /// struct Buffer { buf: Vec } /// /// impl Buffer { -/// fn get_and_reset(&mut self) -> Vec { +/// fn replace_index(&mut self, i: usize, v: T) -> T { /// // error: cannot move out of dereference of `&mut`-pointer -/// let buf = self.buf; -/// self.buf = Vec::new(); -/// buf +/// let t = self.buf[i]; +/// self.buf[i] = v; +/// t /// } /// } /// ``` /// -/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset -/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from +/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to +/// avoid the move. But `replace` can be used to disassociate the original value at that index from /// `self`, allowing it to be returned: /// /// ``` @@ -602,10 +611,16 @@ pub fn take(dest: &mut T) -> T { /// /// # struct Buffer { buf: Vec } /// impl Buffer { -/// fn get_and_reset(&mut self) -> Vec { -/// mem::replace(&mut self.buf, Vec::new()) +/// fn replace_index(&mut self, i: usize, v: T) -> T { +/// mem::replace(&mut self.buf[i], v) /// } /// } +/// +/// let mut buffer = Buffer { buf: vec![0, 1] }; +/// assert_eq!(buffer.buf[0], 0); +/// +/// assert_eq!(buffer.replace_index(0, 2), 0); +/// assert_eq!(buffer.buf[0], 2); /// ``` /// /// [`Clone`]: ../../std/clone/trait.Clone.html diff --git a/src/libcore/option.rs b/src/libcore/option.rs index eec4b149ddc78..b27fd4098e167 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -777,15 +777,7 @@ impl Option { #[inline] #[stable(feature = "option_entry", since = "1.20.0")] pub fn get_or_insert(&mut self, v: T) -> &mut T { - match *self { - None => *self = Some(v), - _ => (), - } - - match *self { - Some(ref mut v) => v, - None => unsafe { hint::unreachable_unchecked() }, - } + self.get_or_insert_with(|| v) } /// Inserts a value computed from `f` into the option if it is [`None`], then @@ -845,7 +837,7 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn take(&mut self) -> Option { - mem::replace(self, None) + mem::take(self) } /// Replaces the actual value in the option by the value given in parameter, diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index fccb00d768cd8..da781d7e9feee 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -100,7 +100,11 @@ pub use unique::Unique; /// as the compiler doesn't need to prove that it's sound to elide the /// copy. /// +/// Unaligned values cannot be dropped in place, they must be copied to an aligned +/// location first using [`ptr::read_unaligned`]. +/// /// [`ptr::read`]: ../ptr/fn.read.html +/// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html /// /// # Safety /// @@ -108,8 +112,7 @@ pub use unique::Unique; /// /// * `to_drop` must be [valid] for reads. /// -/// * `to_drop` must be properly aligned. See the example below for how to drop -/// an unaligned pointer. +/// * `to_drop` must be properly aligned. /// /// Additionally, if `T` is not [`Copy`], using the pointed-to value after /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop = @@ -153,31 +156,6 @@ pub use unique::Unique; /// assert!(weak.upgrade().is_none()); /// ``` /// -/// Unaligned values cannot be dropped in place, they must be copied to an aligned -/// location first: -/// ``` -/// use std::ptr; -/// use std::mem::{self, MaybeUninit}; -/// -/// unsafe fn drop_after_copy(to_drop: *mut T) { -/// let mut copy: MaybeUninit = MaybeUninit::uninit(); -/// ptr::copy(to_drop, copy.as_mut_ptr(), 1); -/// drop(copy.assume_init()); -/// } -/// -/// #[repr(packed, C)] -/// struct Packed { -/// _padding: u8, -/// unaligned: Vec, -/// } -/// -/// let mut p = Packed { _padding: 0, unaligned: vec![42] }; -/// unsafe { -/// drop_after_copy(&mut p.unaligned as *mut _); -/// mem::forget(p); -/// } -/// ``` -/// /// Notice that the compiler performs this copy automatically when dropping packed structs, /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually. diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 155429b0e4f54..75c329a7d6c10 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -53,7 +53,7 @@ /// let value: i32 = 123; /// /// // let the compiler make a trait object -/// let object: &Foo = &value; +/// let object: &dyn Foo = &value; /// /// // look at the raw representation /// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) }; @@ -65,7 +65,7 @@ /// /// // construct a new object, pointing to a different `i32`, being /// // careful to use the `i32` vtable from `object` -/// let synthesized: &Foo = unsafe { +/// let synthesized: &dyn Foo = unsafe { /// mem::transmute(raw::TraitObject { /// data: &other_value as *const _ as *mut (), /// vtable: raw_object.vtable, diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index c6d44324ef5ee..fe48e2458cd16 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4453,6 +4453,21 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> { Some(snd) } } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + let len = self.len(); + if n >= len { + self.v = &[]; + None + } else { + let start = (len - 1 - n) * self.chunk_size; + let end = start + self.chunk_size; + let nth_back = &self.v[start..end]; + self.v = &self.v[..start]; + Some(nth_back) + } + } } #[stable(feature = "chunks_exact", since = "1.31.0")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 34f2d8917ea47..b027e6bc051b3 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1333,6 +1333,11 @@ impl<'a> Iterator for Lines<'a> { fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -3716,10 +3721,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. 'Left' in this context means the first - /// position of that byte string; for a language like Arabic or Hebrew - /// which are 'right to left' rather than 'left to right', this will be - /// the _right_ side, not the left. + /// A string is a sequence of bytes. `start` in this context means the first + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be left side, and for right-to-left languages like + /// like Arabic or Hebrew, this will be the right side. /// /// # Examples /// @@ -3755,10 +3760,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. 'Right' in this context means the last - /// position of that byte string; for a language like Arabic or Hebrew - /// which are 'right to left' rather than 'left to right', this will be - /// the _left_ side, not the right. + /// A string is a sequence of bytes. `end` in this context means the last + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be right side, and for right-to-left languages like + /// like Arabic or Hebrew, this will be the left side. /// /// # Examples /// @@ -3804,10 +3809,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. `start` in this context means the first - /// position of that byte string; for a left-to-right language like English or - /// Russian, this will be left side, and for right-to-left languages like - /// like Arabic or Hebrew, this will be the right side. + /// A string is a sequence of bytes. 'Left' in this context means the first + /// position of that byte string; for a language like Arabic or Hebrew + /// which are 'right to left' rather than 'left to right', this will be + /// the _right_ side, not the left. /// /// # Examples /// @@ -3840,10 +3845,10 @@ impl str { /// /// # Text directionality /// - /// A string is a sequence of bytes. `end` in this context means the last - /// position of that byte string; for a left-to-right language like English or - /// Russian, this will be right side, and for right-to-left languages like - /// like Arabic or Hebrew, this will be the left side. + /// A string is a sequence of bytes. 'Right' in this context means the last + /// position of that byte string; for a language like Arabic or Hebrew + /// which are 'right to left' rather than 'left to right', this will be + /// the _left_ side, not the right. /// /// # Examples /// @@ -4241,6 +4246,11 @@ impl<'a> Iterator for SplitWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "split_whitespace", since = "1.1.0")] @@ -4267,6 +4277,11 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> { fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } + + #[inline] + fn last(mut self) -> Option<&'a str> { + self.next_back() + } } #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs index ec98e0464c9e6..439ed0c81c8b6 100644 --- a/src/libcore/tests/ascii.rs +++ b/src/libcore/tests/ascii.rs @@ -151,7 +151,7 @@ macro_rules! assert_none { stringify!($what), b); } } - )* + )+ }}; ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+)) } diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs index df1deeaeb97b7..d86e21cf40b6e 100644 --- a/src/libcore/tests/fmt/mod.rs +++ b/src/libcore/tests/fmt/mod.rs @@ -3,7 +3,6 @@ mod float; mod num; #[test] -#[cfg(not(miri))] // Miri cannot print pointers fn test_format_flags() { // No residual flags left by pointer formatting let p = "".as_ptr(); @@ -13,7 +12,6 @@ fn test_format_flags() { } #[test] -#[cfg(not(miri))] // Miri cannot print pointers fn test_pointer_formats_data_pointer() { let b: &[u8] = b""; let s: &str = ""; diff --git a/src/libcore/tests/pattern.rs b/src/libcore/tests/pattern.rs index b78ed0210770f..06c3a78c1698a 100644 --- a/src/libcore/tests/pattern.rs +++ b/src/libcore/tests/pattern.rs @@ -5,7 +5,7 @@ use std::str::pattern::*; macro_rules! search_asserts { ($haystack:expr, $needle:expr, $testname:expr, [$($func:ident),*], $result:expr) => { let mut searcher = $needle.into_searcher($haystack); - let arr = [$( Step::from(searcher.$func()) ),+]; + let arr = [$( Step::from(searcher.$func()) ),*]; assert_eq!(&arr[..], &$result, $testname); } } diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 03fe1fe5a7cf8..569b3197d09bd 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -253,7 +253,6 @@ fn test_unsized_nonnull() { #[test] #[allow(warnings)] -#[cfg(not(miri))] // Miri cannot hash pointers // Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the // ABI, or even point to an actual executable code, because the function itself is never invoked. #[no_mangle] @@ -293,7 +292,7 @@ fn write_unaligned_drop() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn align_offset_zst() { // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at // all, because no amount of elements will align the pointer. @@ -308,7 +307,7 @@ fn align_offset_zst() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn align_offset_stride1() { // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to // number of bytes. diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 03e65d2fe0b81..42ec9d451f790 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -275,6 +275,25 @@ fn test_chunks_exact_nth() { assert_eq!(c2.next(), None); } +#[test] +fn test_chunks_exact_nth_back() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.chunks_exact(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); + + let v2: &[i32] = &[0, 1, 2, 3, 4]; + let mut c2 = v2.chunks_exact(3); + assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]); + assert_eq!(c2.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &[i32] = &[0, 1, 2, 3, 4]; + let mut c3 = v3.chunks_exact(10); + assert_eq!(c3.nth_back(0), None); +} + #[test] fn test_chunks_exact_last() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; @@ -1396,7 +1415,7 @@ pub mod memchr { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn test_align_to_simple() { let bytes = [1u8, 2, 3, 4, 5, 6, 7]; let (prefix, aligned, suffix) = unsafe { bytes.align_to::() }; @@ -1420,7 +1439,7 @@ fn test_align_to_zst() { } #[test] -#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation +#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset` fn test_align_to_non_trivial() { #[repr(align(8))] struct U64(u64, u64); #[repr(align(8))] struct U64U64U32(u64, u64, u32); diff --git a/src/libproc_macro/bridge/buffer.rs b/src/libproc_macro/bridge/buffer.rs index 0d8cc552d61ab..a51e3a9a33d7b 100644 --- a/src/libproc_macro/bridge/buffer.rs +++ b/src/libproc_macro/bridge/buffer.rs @@ -78,7 +78,7 @@ impl Buffer { } pub(super) fn take(&mut self) -> Self { - mem::replace(self, Self::default()) + mem::take(self) } pub(super) fn extend_from_slice(&mut self, xs: &[T]) { diff --git a/src/libproc_macro/bridge/scoped_cell.rs b/src/libproc_macro/bridge/scoped_cell.rs index 6f7965095b638..89fb707001589 100644 --- a/src/libproc_macro/bridge/scoped_cell.rs +++ b/src/libproc_macro/bridge/scoped_cell.rs @@ -74,7 +74,7 @@ impl ScopedCell { } /// Sets the value in `self` to `value` while running `f`. - pub fn set<'a, R>(&self, value: >::Out, f: impl FnOnce() -> R) -> R { + pub fn set(&self, value: >::Out, f: impl FnOnce() -> R) -> R { self.replace(value, |_| f()) } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 1e0f1ed578aae..2c097238b95b2 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -25,6 +25,7 @@ #![feature(extern_types)] #![feature(in_band_lifetimes)] #![feature(optin_builtin_traits)] +#![feature(mem_take)] #![feature(non_exhaustive)] #![feature(specialization)] diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index a7750edbb6f48..a132575b0c673 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -1,11 +1,11 @@ use crate::cfg::*; use crate::middle::region; use rustc_data_structures::graph::implementation as graph; -use syntax::ptr::P; use crate::ty::{self, TyCtxt}; use crate::hir::{self, PatKind}; use crate::hir::def_id::DefId; +use crate::hir::ptr::P; struct CFGBuilder<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -30,7 +30,7 @@ struct LoopScope { break_index: CFGIndex, // where to go on a `break` } -pub fn construct<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG { +pub fn construct(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG { let mut graph = graph::Graph::new(); let entry = graph.add_node(CFGNodeData::Entry); diff --git a/src/librustc/cfg/mod.rs b/src/librustc/cfg/mod.rs index db168d99a0801..88fc7fbfad51f 100644 --- a/src/librustc/cfg/mod.rs +++ b/src/librustc/cfg/mod.rs @@ -49,7 +49,7 @@ pub type CFGNode = graph::Node; pub type CFGEdge = graph::Edge; impl CFG { - pub fn new<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG { + pub fn new(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG { construct::construct(tcx, body) } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 82b0e50b50c48..3d5e7dd0af121 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -142,9 +142,6 @@ macro_rules! define_dep_nodes { } } - // FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties - // of queries - #[inline(always)] pub fn is_anon(&self) -> bool { match *self { $( @@ -163,7 +160,6 @@ macro_rules! define_dep_nodes { } #[allow(unreachable_code)] - #[inline(always)] pub fn has_params(&self) -> bool { match *self { $( diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index c2e3c12cea8ed..b8c6c1e372382 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -841,32 +841,21 @@ impl DepGraph { // // This method will only load queries that will end up in the disk cache. // Other queries will not be executed. - pub fn exec_cache_promotions<'tcx>(&self, tcx: TyCtxt<'tcx>) { - let green_nodes: Vec = { - let data = self.data.as_ref().unwrap(); - data.colors.values.indices().filter_map(|prev_index| { - match data.colors.get(prev_index) { - Some(DepNodeColor::Green(_)) => { - let dep_node = data.previous.index_to_node(prev_index); - if dep_node.cache_on_disk(tcx) { - Some(dep_node) - } else { - None - } - } - None | - Some(DepNodeColor::Red) => { - // We can skip red nodes because a node can only be marked - // as red if the query result was recomputed and thus is - // already in memory. - None - } + pub fn exec_cache_promotions(&self, tcx: TyCtxt<'_>) { + let data = self.data.as_ref().unwrap(); + for prev_index in data.colors.values.indices() { + match data.colors.get(prev_index) { + Some(DepNodeColor::Green(_)) => { + let dep_node = data.previous.index_to_node(prev_index); + dep_node.try_load_from_on_disk_cache(tcx); } - }).collect() - }; - - for dep_node in green_nodes { - dep_node.load_from_on_disk_cache(tcx); + None | + Some(DepNodeColor::Red) => { + // We can skip red nodes because a node can only be marked + // as red if the query result was recomputed and thus is + // already in memory. + } + } } } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 4b84d56858cca..9160b8024ee45 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -347,7 +347,7 @@ fn is_c_like_enum(item: &hir::Item) -> bool { } } -fn check_mod_attrs<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor() diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 9c4a208f0f9fc..ef05b57fb8f7d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -39,6 +39,7 @@ use crate::hir::map::{DefKey, DefPathData, Definitions}; use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; use crate::hir::def::{Res, DefKind, PartialRes, PerNS}; use crate::hir::{GenericArg, ConstArg}; +use crate::hir::ptr::P; use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, ELIDED_LIFETIMES_IN_PATHS}; use crate::middle::cstore::CrateStore; @@ -61,7 +62,6 @@ use syntax::ast::*; use syntax::errors; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::print::pprust; -use syntax::ptr::P; use syntax::source_map::{self, respan, ExpnInfo, CompilerDesugaringKind, Spanned}; use syntax::source_map::CompilerDesugaringKind::IfTemporary; use syntax::std_inject; @@ -1111,7 +1111,7 @@ impl<'a> LoweringContext<'a> { }, ); - lowered_generics.params = lowered_generics + let mut lowered_params: Vec<_> = lowered_generics .params .into_iter() .chain(in_band_defs) @@ -1121,7 +1121,7 @@ impl<'a> LoweringContext<'a> { // unsorted generic parameters at the moment, so we make sure // that they're ordered correctly here for now. (When we chain // the `in_band_defs`, we might make the order unsorted.) - lowered_generics.params.sort_by_key(|param| { + lowered_params.sort_by_key(|param| { match param.kind { hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime, hir::GenericParamKind::Type { .. } => ParamKindOrd::Type, @@ -1129,6 +1129,8 @@ impl<'a> LoweringContext<'a> { } }); + lowered_generics.params = lowered_params.into(); + (lowered_generics, res) } @@ -1155,13 +1157,13 @@ impl<'a> LoweringContext<'a> { &mut self, capture_clause: CaptureBy, closure_node_id: NodeId, - ret_ty: Option<&Ty>, + ret_ty: Option>, span: Span, body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr, ) -> hir::ExprKind { let capture_clause = self.lower_capture_clause(capture_clause); let output = match ret_ty { - Some(ty) => FunctionRetTy::Ty(P(ty.clone())), + Some(ty) => FunctionRetTy::Ty(ty), None => FunctionRetTy::Default(span), }; let ast_decl = FnDecl { @@ -1278,8 +1280,8 @@ impl<'a> LoweringContext<'a> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new()); - let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new()); + let catch_scopes = mem::take(&mut self.catch_scopes); + let loop_scopes = mem::take(&mut self.loop_scopes); let ret = f(self); self.catch_scopes = catch_scopes; self.loop_scopes = loop_scopes; @@ -2725,7 +2727,7 @@ impl<'a> LoweringContext<'a> { // ::std::future::Future let future_path = - self.std_path(span, &[sym::future, sym::Future], Some(future_params), false); + P(self.std_path(span, &[sym::future, sym::Future], Some(future_params), false)); hir::GenericBound::Trait( hir::PolyTraitRef { @@ -3094,7 +3096,7 @@ impl<'a> LoweringContext<'a> { fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext<'_>) -> hir::TraitRef { let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { - hir::QPath::Resolved(None, path) => path.and_then(|path| path), + hir::QPath::Resolved(None, path) => path, qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath), }; hir::TraitRef { @@ -3620,7 +3622,7 @@ impl<'a> LoweringContext<'a> { hir::Item { hir_id: new_id, ident, - attrs: attrs.clone(), + attrs: attrs.into_iter().cloned().collect(), node: item, vis, span, @@ -3705,7 +3707,7 @@ impl<'a> LoweringContext<'a> { hir::Item { hir_id: new_hir_id, ident, - attrs: attrs.clone(), + attrs: attrs.into_iter().cloned().collect(), node: item, vis, span: use_tree.span, @@ -4567,7 +4569,7 @@ impl<'a> LoweringContext<'a> { // `|x: u8| future_from_generator(|| -> X { ... })`. let body_id = this.lower_fn_body(&outer_decl, |this| { let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output { - Some(&**ty) + Some(ty.clone()) } else { None }; let async_body = this.make_async_expr( capture_clause, closure_id, async_ret_ty, body.span, @@ -5577,7 +5579,7 @@ impl<'a> LoweringContext<'a> { let principal = hir::PolyTraitRef { bound_generic_params: hir::HirVec::new(), trait_ref: hir::TraitRef { - path: path.and_then(|path| path), + path, hir_ref_id: hir_id, }, span, diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 60465c04ec62f..891a1956bc971 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -4,7 +4,7 @@ use crate::hir::itemlikevisit::ItemLikeVisitor; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter}; -pub fn check_crate<'hir>(hir_map: &hir::map::Map<'hir>) { +pub fn check_crate(hir_map: &hir::map::Map<'_>) { hir_map.dep_graph.assert_ignored(); let errors = Lock::new(Vec::new()); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 3d591c9a1c6bd..037d04a5d8ed3 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -147,7 +147,7 @@ impl Forest { } } - pub fn krate<'hir>(&'hir self) -> &'hir Crate { + pub fn krate(&self) -> &Crate { self.dep_graph.read(DepNode::new_no_params(DepKind::Krate)); &self.krate } @@ -155,7 +155,7 @@ impl Forest { /// This is used internally in the dependency tracking system. /// Use the `krate` method to ensure your dependency on the /// crate is tracked. - pub fn untracked_krate<'hir>(&'hir self) -> &'hir Crate { + pub fn untracked_krate(&self) -> &Crate { &self.krate } } @@ -1085,7 +1085,7 @@ impl<'a> NodesMatchingSuffix<'a> { // If `id` itself is a mod named `m` with parent `p`, then // returns `Some(id, m, p)`. If `id` has no mod in its parent // chain, then returns `None`. - fn find_first_mod_parent<'a>(map: &'a Map<'_>, mut id: HirId) -> Option<(HirId, Name)> { + fn find_first_mod_parent(map: &Map<'_>, mut id: HirId) -> Option<(HirId, Name)> { loop { if let Node::Item(item) = map.find(id)? { if item_is_mod(&item) { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 6df1c2d8c77e5..bfbd8398f99f3 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -12,6 +12,7 @@ pub use self::UnsafeSource::*; use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; +use crate::hir::ptr::P; use crate::util::nodemap::{NodeMap, FxHashSet}; use crate::mir::mono::Linkage; @@ -23,7 +24,6 @@ use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect}; use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy}; use syntax::attr::{InlineAttr, OptimizeAttr}; use syntax::ext::hygiene::SyntaxContext; -use syntax::ptr::P; use syntax::symbol::{Symbol, kw}; use syntax::tokenstream::TokenStream; use syntax::util::parser::ExprPrecedence; @@ -63,6 +63,7 @@ pub mod lowering; pub mod map; pub mod pat_util; pub mod print; +pub mod ptr; pub mod upvars; /// Uniquely identifies a node in the HIR of the current crate. It is @@ -1979,13 +1980,15 @@ pub struct InlineAsmOutput { pub span: Span, } +// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR, +// it needs to be `Clone` and use plain `Vec` instead of `HirVec`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct InlineAsm { pub asm: Symbol, pub asm_str_style: StrStyle, - pub outputs: HirVec, - pub inputs: HirVec, - pub clobbers: HirVec, + pub outputs: Vec, + pub inputs: Vec, + pub clobbers: Vec, pub volatile: bool, pub alignstack: bool, pub dialect: AsmDialect, @@ -2217,7 +2220,7 @@ pub enum UseKind { /// within the resolution map. #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TraitRef { - pub path: Path, + pub path: P, // Don't hash the ref_id. It is tracked via the thing it is used to access #[stable_hasher(ignore)] pub hir_ref_id: HirId, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 8b1984e04f55b..3b33de1a17926 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -6,7 +6,6 @@ use syntax::parse::lexer::comments; use syntax::print::pp::{self, Breaks}; use syntax::print::pp::Breaks::{Consistent, Inconsistent}; use syntax::print::pprust::{self, PrintState}; -use syntax::ptr::P; use syntax::symbol::kw; use syntax::util::parser::{self, AssocOp, Fixity}; use syntax_pos::{self, BytePos, FileName}; @@ -14,6 +13,7 @@ use syntax_pos::{self, BytePos, FileName}; use crate::hir; use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; use crate::hir::{GenericParam, GenericParamKind, GenericArg}; +use crate::hir::ptr::P; use std::borrow::Cow; use std::cell::Cell; diff --git a/src/librustc/hir/ptr.rs b/src/librustc/hir/ptr.rs new file mode 100644 index 0000000000000..3a87b36a1b434 --- /dev/null +++ b/src/librustc/hir/ptr.rs @@ -0,0 +1,141 @@ +// HACK(eddyb) this is a copy of `syntax::ptr`, minus the mutation (the HIR is +// frozen anyway). The only reason for doing this instead of replacing `P` +// with `Box` in HIR, is that `&Box<[T]>` doesn't implement `IntoIterator`. + +use std::fmt::{self, Display, Debug}; +use std::iter::FromIterator; +use std::ops::Deref; +use std::{slice, vec}; + +use serialize::{Encodable, Decodable, Encoder, Decoder}; + +use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, + HashStable}; +/// An owned smart pointer. +#[derive(Hash, PartialEq, Eq)] +pub struct P { + ptr: Box +} + +/// Construct a `P` from a `T` value. +#[allow(non_snake_case)] +pub fn P(value: T) -> P { + P { + ptr: box value + } +} + +impl P { + // HACK(eddyb) used by HIR lowering in a few places still. + // NOTE: do not make this more public than `pub(super)`. + pub(super) fn into_inner(self) -> T { + *self.ptr + } +} + +impl Deref for P { + type Target = T; + + fn deref(&self) -> &T { + &self.ptr + } +} + +impl Debug for P { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Debug::fmt(&self.ptr, f) + } +} + +impl Display for P { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Display::fmt(&**self, f) + } +} + +impl Decodable for P { + fn decode(d: &mut D) -> Result, D::Error> { + Decodable::decode(d).map(P) + } +} + +impl Encodable for P { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + (**self).encode(s) + } +} + +impl P<[T]> { + pub const fn new() -> P<[T]> { + // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>` + // (as trait methods, `default` in this case, can't be `const fn` yet). + P { + ptr: unsafe { + use std::ptr::NonNull; + std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>) + }, + } + } + + #[inline(never)] + pub fn from_vec(v: Vec) -> P<[T]> { + P { ptr: v.into_boxed_slice() } + } + + // HACK(eddyb) used by HIR lowering in a few places still. + // NOTE: do not make this more public than `pub(super)`, + // and do not make this into an `IntoIterator` impl. + pub(super) fn into_iter(self) -> vec::IntoIter { + self.ptr.into_vec().into_iter() + } +} + + +impl Default for P<[T]> { + /// Creates an empty `P<[T]>`. + fn default() -> P<[T]> { + P::new() + } +} + +impl From> for P<[T]> { + fn from(v: Vec) -> Self { + P::from_vec(v) + } +} + +impl FromIterator for P<[T]> { + fn from_iter>(iter: I) -> P<[T]> { + P::from_vec(iter.into_iter().collect()) + } +} + +impl<'a, T> IntoIterator for &'a P<[T]> { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.ptr.into_iter() + } +} + +impl Encodable for P<[T]> { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&**self, s) + } +} + +impl Decodable for P<[T]> { + fn decode(d: &mut D) -> Result, D::Error> { + Ok(P::from_vec(Decodable::decode(d)?)) + } +} + +impl HashStable for P + where T: ?Sized + HashStable +{ + fn hash_stable(&self, + hcx: &mut CTX, + hasher: &mut StableHasher) { + (**self).hash_stable(hcx, hasher); + } +} diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index b2c7bd73b6812..b508f91e01ebb 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -23,6 +23,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; +use crate::infer::region_constraints::MemberConstraint; use crate::mir::interpret::ConstValue; use rustc_data_structures::indexed_vec::IndexVec; use rustc_macros::HashStable; @@ -189,11 +190,25 @@ pub enum CanonicalTyVarKind { #[derive(Clone, Debug, HashStable)] pub struct QueryResponse<'tcx, R> { pub var_values: CanonicalVarValues<'tcx>, - pub region_constraints: Vec>, + pub region_constraints: QueryRegionConstraints<'tcx>, pub certainty: Certainty, pub value: R, } +#[derive(Clone, Debug, Default, HashStable)] +pub struct QueryRegionConstraints<'tcx> { + pub outlives: Vec>, + pub member_constraints: Vec>, +} + +impl QueryRegionConstraints<'_> { + /// Represents an empty (trivially true) set of region + /// constraints. + pub fn is_empty(&self) -> bool { + self.outlives.is_empty() && self.member_constraints.is_empty() + } +} + pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>; pub type CanonicalizedQueryResponse<'tcx, T> = @@ -292,7 +307,8 @@ impl<'tcx, V> Canonical<'tcx, V> { } } -pub type QueryRegionConstraint<'tcx> = ty::Binder, Region<'tcx>>>; +pub type QueryOutlivesConstraint<'tcx> = + ty::Binder, Region<'tcx>>>; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Creates a substitution S for the canonical value with fresh @@ -540,6 +556,19 @@ BraceStructLiftImpl! { } where R: Lift<'tcx> } +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> { + outlives, member_constraints + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> { + type Lifted = QueryRegionConstraints<'tcx>; + outlives, member_constraints + } +} + impl<'tcx> Index for CanonicalVarValues<'tcx> { type Output = Kind<'tcx>; diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 3e92fed005cd1..79c5538626be1 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -11,7 +11,7 @@ use crate::arena::ArenaAllocatable; use crate::infer::canonical::substitute::substitute_value; use crate::infer::canonical::{ Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty, - OriginalQueryValues, QueryRegionConstraint, QueryResponse, + OriginalQueryValues, QueryRegionConstraints, QueryOutlivesConstraint, QueryResponse, }; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::InferCtxtBuilder; @@ -132,7 +132,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { { self.canonicalize_response(&QueryResponse { var_values: inference_vars, - region_constraints: vec![], + region_constraints: QueryRegionConstraints::default(), certainty: Certainty::Proven, // Ambiguities are OK! value: answer, }) @@ -174,7 +174,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let region_obligations = self.take_registered_region_obligations(); let region_constraints = self.with_region_constraints(|region_constraints| { - make_query_outlives( + make_query_region_constraints( tcx, region_obligations .iter() @@ -222,10 +222,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { mut obligations, } = self.query_response_substitution(cause, param_env, original_values, query_response)?; - obligations.extend(self.query_region_constraints_into_obligations( + obligations.extend(self.query_outlives_constraints_into_obligations( cause, param_env, - &query_response.value.region_constraints, + &query_response.value.region_constraints.outlives, &result_subst, )); @@ -248,9 +248,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// that come out of these queries, which it wants to convert into /// MIR-based constraints and solve. Therefore, it is most /// convenient for the NLL Type Checker to **directly consume** - /// the `QueryRegionConstraint` values that arise from doing a + /// the `QueryOutlivesConstraint` values that arise from doing a /// query. This is contrast to other parts of the compiler, which - /// would prefer for those `QueryRegionConstraint` to be converted + /// would prefer for those `QueryOutlivesConstraint` to be converted /// into the older infcx-style constraints (e.g., calls to /// `sub_regions` or `register_region_obligation`). /// @@ -263,7 +263,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// result. If any errors arise, they are propagated back as an /// `Err` result. /// - In the case of a successful substitution, we will append - /// `QueryRegionConstraint` values onto the + /// `QueryOutlivesConstraint` values onto the /// `output_query_region_constraints` vector for the solver to /// use (if an error arises, some values may also be pushed, but /// they should be ignored). @@ -279,7 +279,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { param_env: ty::ParamEnv<'tcx>, original_values: &OriginalQueryValues<'tcx>, query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, - output_query_region_constraints: &mut Vec>, + output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> InferResult<'tcx, R> where R: Debug + TypeFoldable<'tcx>, @@ -287,7 +287,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let result_subst = self.query_response_substitution_guess(cause, original_values, query_response); - // Compute `QueryRegionConstraint` values that unify each of + // Compute `QueryOutlivesConstraint` values that unify each of // the original values `v_o` that was canonicalized into a // variable... let mut obligations = vec![]; @@ -306,8 +306,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`. if v_o != v_r { output_query_region_constraints + .outlives .push(ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r))); output_query_region_constraints + .outlives .push(ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o))); } } @@ -333,12 +335,12 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { } // ...also include the other query region constraints from the query. - output_query_region_constraints.extend( - query_response.value.region_constraints.iter().filter_map(|r_c| { + output_query_region_constraints.outlives.extend( + query_response.value.region_constraints.outlives.iter().filter_map(|r_c| { let r_c = substitute_value(self.tcx, &result_subst, r_c); // Screen out `'a: 'a` cases -- we skip the binder here but - // only care the inner values to one another, so they are still at + // only compare the inner values to one another, so they are still at // consistent binding levels. let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); if k1 != r2.into() { @@ -349,6 +351,13 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { }) ); + // ...also include the query member constraints. + output_query_region_constraints.member_constraints.extend( + query_response.value.region_constraints.member_constraints.iter().map(|p_c| { + substitute_value(self.tcx, &result_subst, p_c) + }) + ); + let user_result: R = query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value); @@ -560,11 +569,11 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Converts the region constraints resulting from a query into an /// iterator of obligations. - fn query_region_constraints_into_obligations<'a>( + fn query_outlives_constraints_into_obligations<'a>( &'a self, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>], + unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], result_subst: &'a CanonicalVarValues<'tcx>, ) -> impl Iterator> + 'a + Captures<'tcx> { unsubstituted_region_constraints @@ -645,15 +654,16 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Given the region obligations and constraints scraped from the infcx, /// creates query region constraints. -pub fn make_query_outlives<'tcx>( +pub fn make_query_region_constraints<'tcx>( tcx: TyCtxt<'tcx>, outlives_obligations: impl Iterator, ty::Region<'tcx>)>, region_constraints: &RegionConstraintData<'tcx>, -) -> Vec> { +) -> QueryRegionConstraints<'tcx> { let RegionConstraintData { constraints, verifys, givens, + member_constraints, } = region_constraints; assert!(verifys.is_empty()); @@ -684,5 +694,5 @@ pub fn make_query_outlives<'tcx>( ) .collect(); - outlives + QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() } } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 65225163a25a4..cbfb048c064a2 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -53,6 +53,7 @@ use crate::infer::{self, SuppressRegionErrors}; use crate::hir; use crate::hir::def_id::DefId; use crate::hir::Node; +use crate::infer::opaque_types; use crate::middle::region; use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::error::TypeError; @@ -375,6 +376,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } } + + RegionResolutionError::MemberConstraintFailure { + opaque_type_def_id, + hidden_ty, + member_region, + span: _, + choice_regions: _, + } => { + let hidden_ty = self.resolve_vars_if_possible(&hidden_ty); + opaque_types::unexpected_hidden_region_diagnostic( + self.tcx, + Some(region_scope_tree), + opaque_type_def_id, + hidden_ty, + member_region, + ).emit(); + } } } } @@ -411,7 +429,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e { RegionResolutionError::GenericBoundFailure(..) => true, RegionResolutionError::ConcreteFailure(..) - | RegionResolutionError::SubSupConflict(..) => false, + | RegionResolutionError::SubSupConflict(..) + | RegionResolutionError::MemberConstraintFailure { .. } => false, }; let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { @@ -429,6 +448,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _) => rvo.span(), + RegionResolutionError::MemberConstraintFailure { span, .. } => span, }); errors } diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 2613f4c7c2ae3..d06c4434b3aaf 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -1,13 +1,20 @@ //! Lexical region resolution. +use crate::hir::def_id::DefId; use crate::infer::region_constraints::Constraint; use crate::infer::region_constraints::GenericKind; +use crate::infer::region_constraints::MemberConstraint; use crate::infer::region_constraints::RegionConstraintData; use crate::infer::region_constraints::VarInfos; use crate::infer::region_constraints::VerifyBound; use crate::infer::RegionVariableOrigin; use crate::infer::SubregionOrigin; use crate::middle::free_region::RegionRelations; +use crate::ty::fold::TypeFoldable; +use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; +use crate::ty::{ReLateBound, RePlaceholder, ReScope, ReVar}; +use crate::ty::{Region, RegionVid}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, @@ -15,12 +22,7 @@ use rustc_data_structures::graph::implementation::{ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; -use std::u32; -use crate::ty::fold::TypeFoldable; -use crate::ty::{self, Ty, TyCtxt}; -use crate::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; -use crate::ty::{ReLateBound, ReScope, RePlaceholder, ReVar}; -use crate::ty::{Region, RegionVid}; +use syntax_pos::Span; mod graphviz; @@ -36,11 +38,7 @@ pub fn resolve<'tcx>( ) -> (LexicalRegionResolutions<'tcx>, Vec>) { debug!("RegionConstraintData: resolve_regions()"); let mut errors = vec![]; - let mut resolver = LexicalResolver { - region_rels, - var_infos, - data, - }; + let mut resolver = LexicalResolver { region_rels, var_infos, data }; let values = resolver.infer_variable_values(&mut errors); (values, errors) } @@ -84,6 +82,17 @@ pub enum RegionResolutionError<'tcx> { SubregionOrigin<'tcx>, Region<'tcx>, ), + + /// Indicates a failure of a `MemberConstraint`. These arise during + /// impl trait processing explicitly -- basically, the impl trait's hidden type + /// included some region that it was not supposed to. + MemberConstraintFailure { + span: Span, + opaque_type_def_id: DefId, + hidden_ty: Ty<'tcx>, + member_region: Region<'tcx>, + choice_regions: Vec>, + }, } struct RegionAndOrigin<'tcx> { @@ -121,7 +130,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let graph = self.construct_graph(); self.expand_givens(&graph); - self.expansion(&mut var_data); + loop { + self.expansion(&mut var_data); + if !self.enforce_member_constraints(&graph, &mut var_data) { + break; + } + } self.collect_errors(&mut var_data, errors); self.collect_var_errors(&var_data, &graph, errors); var_data @@ -136,7 +150,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> { LexicalRegionResolutions { error_region: tcx.lifetimes.re_static, - values: IndexVec::from_elem_n(VarValue::Value(tcx.lifetimes.re_empty), self.num_vars()) + values: IndexVec::from_elem_n(VarValue::Value(tcx.lifetimes.re_empty), self.num_vars()), } } @@ -182,6 +196,113 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + /// Enforce all member constraints and return true if anything + /// changed. See `enforce_member_constraint` for more details. + fn enforce_member_constraints( + &self, + graph: &RegionGraph<'tcx>, + var_values: &mut LexicalRegionResolutions<'tcx>, + ) -> bool { + // Note: we don't use the `any` combinator because we don't + // want to stop at the first constraint that makes a change. + let mut any_changed = false; + for member_constraint in &self.data.member_constraints { + if self.enforce_member_constraint(graph, member_constraint, var_values) { + any_changed = true; + } + } + any_changed + } + + /// Enforce a constraint like + /// + /// ``` + /// 'r member of ['c...] + /// ``` + /// + /// We look for all choice regions from the list `'c...` that: + /// + /// (a) are greater than the current value of `'r` (which is a lower bound) + /// + /// and + /// + /// (b) are compatible with the upper bounds of `'r` that we can + /// find by traversing the graph. + /// + /// From that list, we look for a *minimal* option `'c_min`. If we + /// find one, then we can enforce that `'r: 'c_min`. + fn enforce_member_constraint( + &self, + graph: &RegionGraph<'tcx>, + member_constraint: &MemberConstraint<'tcx>, + var_values: &mut LexicalRegionResolutions<'tcx>, + ) -> bool { + debug!("enforce_member_constraint(member_constraint={:#?})", member_constraint); + + // The constraint is some inference variable (`vid`) which + // must be equal to one of the options. + let member_vid = match member_constraint.member_region { + ty::ReVar(vid) => *vid, + _ => return false, + }; + + // The current value of `vid` is a lower bound LB -- i.e., we + // know that `LB <= vid` must be true. + let member_lower_bound: ty::Region<'tcx> = match var_values.value(member_vid) { + VarValue::ErrorValue => return false, + VarValue::Value(r) => r, + }; + + // Find all the "upper bounds" -- that is, each region `b` such that + // `r0 <= b` must hold. + let (member_upper_bounds, _) = self.collect_concrete_regions( + graph, + member_vid, + OUTGOING, + None, + ); + + // Get an iterator over the *available choice* -- that is, + // each choice region `c` where `lb <= c` and `c <= ub` for all the + // upper bounds `ub`. + debug!("enforce_member_constraint: upper_bounds={:#?}", member_upper_bounds); + let mut options = member_constraint.choice_regions.iter().filter(|option| { + self.sub_concrete_regions(member_lower_bound, option) + && member_upper_bounds + .iter() + .all(|upper_bound| self.sub_concrete_regions(option, upper_bound.region)) + }); + + // If there is more than one option, we only make a choice if + // there is a single *least* choice -- i.e., some available + // region that is `<=` all the others. + let mut least_choice: ty::Region<'tcx> = match options.next() { + Some(&r) => r, + None => return false, + }; + debug!("enforce_member_constraint: least_choice={:?}", least_choice); + for &option in options { + debug!("enforce_member_constraint: option={:?}", option); + if !self.sub_concrete_regions(least_choice, option) { + if self.sub_concrete_regions(option, least_choice) { + debug!("enforce_member_constraint: new least choice"); + least_choice = option; + } else { + debug!("enforce_member_constraint: no least choice"); + return false; + } + } + } + + debug!("enforce_member_constraint: final least choice = {:?}", least_choice); + if least_choice != member_lower_bound { + *var_values.value_mut(member_vid) = VarValue::Value(least_choice); + true + } else { + false + } + } + fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { self.iterate_until_fixed_point("Expansion", |constraint| { debug!("expansion: constraint={:?}", constraint); @@ -196,7 +317,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let b_data = var_values.value_mut(b_vid); let retain = match *b_data { VarValue::Value(ReStatic) | VarValue::ErrorValue => false, - _ => true + _ => true, }; (a_region, b_vid, b_data, retain) } @@ -204,7 +325,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { // These constraints are checked after expansion // is done, in `collect_errors`. - return (false, false) + return (false, false); } }; @@ -226,16 +347,16 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { match *a_region { // Check if this relationship is implied by a given. - ty::ReEarlyBound(_) | ty::ReFree(_) => if self.data.givens.contains(&(a_region, b_vid)) - { - debug!("given"); - return false; - }, + ty::ReEarlyBound(_) | ty::ReFree(_) => { + if self.data.givens.contains(&(a_region, b_vid)) { + debug!("given"); + return false; + } + } _ => {} } - match *b_data { VarValue::Value(cur_region) => { // Identical scopes can show up quite often, if the fixed point @@ -267,10 +388,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - debug!( - "Expanding value of {:?} from {:?} to {:?}", - b_vid, cur_region, lub - ); + debug!("Expanding value of {:?} from {:?} to {:?}", b_vid, cur_region, lub); *b_data = VarValue::Value(lub); return true; @@ -282,6 +400,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + /// True if `a <= b`, but not defined over inference variables. + fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool { + self.lub_concrete_regions(a, b) == b + } + + /// Returns the smallest region `c` such that `a <= c` and `b <= c`. fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { let tcx = self.tcx(); @@ -321,17 +445,16 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // at least as big as fr.scope". So, we can // reasonably compare free regions and scopes: let fr_scope = match (a, b) { - (&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => self.region_rels - .region_scope_tree - .early_free_scope(self.tcx(), br), - (&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => self.region_rels - .region_scope_tree - .free_scope(self.tcx(), fr), + (&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => { + self.region_rels.region_scope_tree.early_free_scope(self.tcx(), br) + } + (&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => { + self.region_rels.region_scope_tree.free_scope(self.tcx(), fr) + } _ => bug!(), }; - let r_id = self.region_rels - .region_scope_tree - .nearest_common_ancestor(fr_scope, s_id); + let r_id = + self.region_rels.region_scope_tree.nearest_common_ancestor(fr_scope, s_id); if r_id == fr_scope { // if the free region's scope `fr.scope` is bigger than // the scope region `s_id`, then the LUB is the free @@ -352,9 +475,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // The region corresponding to an outer block is a // subtype of the region corresponding to an inner // block. - let lub = self.region_rels - .region_scope_tree - .nearest_common_ancestor(a_id, b_id); + let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id); tcx.mk_region(ReScope(lub)) } @@ -365,11 +486,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // For these types, we cannot define any additional // relationship: - (&RePlaceholder(..), _) | (_, &RePlaceholder(..)) => if a == b { - a - } else { - tcx.lifetimes.re_static - }, + (&RePlaceholder(..), _) | (_, &RePlaceholder(..)) => { + if a == b { + a + } else { + tcx.lifetimes.re_static + } + } } } @@ -382,10 +505,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { errors: &mut Vec>, ) { for (constraint, origin) in &self.data.constraints { - debug!( - "collect_errors: constraint={:?} origin={:?}", - constraint, origin - ); + debug!("collect_errors: constraint={:?} origin={:?}", constraint, origin); match *constraint { Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => { // Expansion will ensure that these constraints hold. Ignore. @@ -433,6 +553,25 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } + // Check that all member constraints are satisfied. + for member_constraint in &self.data.member_constraints { + let member_region = var_data.normalize(self.tcx(), member_constraint.member_region); + let choice_regions = member_constraint + .choice_regions + .iter() + .map(|&choice_region| var_data.normalize(self.tcx(), choice_region)); + if !choice_regions.clone().any(|choice_region| member_region == choice_region) { + let span = self.tcx().def_span(member_constraint.opaque_type_def_id); + errors.push(RegionResolutionError::MemberConstraintFailure { + span, + opaque_type_def_id: member_constraint.opaque_type_def_id, + hidden_ty: member_constraint.hidden_ty, + member_region, + choice_regions: choice_regions.collect(), + }); + } + } + for verify in &self.data.verifys { debug!("collect_errors: verify={:?}", verify); let sub = var_data.normalize(self.tcx(), verify.region); @@ -483,34 +622,35 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // idea is to report errors that derive from independent // regions of the graph, but not those that derive from // overlapping locations. - let mut dup_vec = vec![u32::MAX; self.num_vars()]; + let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars()); for (node_vid, value) in var_data.values.iter_enumerated() { match *value { VarValue::Value(_) => { /* Inference successful */ } VarValue::ErrorValue => { - /* Inference impossible: this value contains - inconsistent constraints. - - I think that in this case we should report an - error now -- unlike the case above, we can't - wait to see whether the user needs the result - of this variable. The reason is that the mere - existence of this variable implies that the - region graph is inconsistent, whether or not it - is used. - - For example, we may have created a region - variable that is the GLB of two other regions - which do not have a GLB. Even if that variable - is not used, it implies that those two regions - *should* have a GLB. - - At least I think this is true. It may be that - the mere existence of a conflict in a region variable - that is not used is not a problem, so if this rule - starts to create problems we'll have to revisit - this portion of the code and think hard about it. =) */ + // Inference impossible: this value contains + // inconsistent constraints. + // + // I think that in this case we should report an + // error now -- unlike the case above, we can't + // wait to see whether the user needs the result + // of this variable. The reason is that the mere + // existence of this variable implies that the + // region graph is inconsistent, whether or not it + // is used. + // + // For example, we may have created a region + // variable that is the GLB of two other regions + // which do not have a GLB. Even if that variable + // is not used, it implies that those two regions + // *should* have a GLB. + // + // At least I think this is true. It may be that + // the mere existence of a conflict in a region + // variable that is not used is not a problem, so + // if this rule starts to create problems we'll + // have to revisit this portion of the code and + // think hard about it. =) -- nikomatsakis self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors); } } @@ -562,16 +702,16 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn collect_error_for_expanding_node( &self, graph: &RegionGraph<'tcx>, - dup_vec: &mut [u32], + dup_vec: &mut IndexVec>, node_idx: RegionVid, errors: &mut Vec>, ) { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. let (mut lower_bounds, lower_dup) = - self.collect_concrete_regions(graph, node_idx, INCOMING, dup_vec); + self.collect_concrete_regions(graph, node_idx, INCOMING, Some(dup_vec)); let (mut upper_bounds, upper_dup) = - self.collect_concrete_regions(graph, node_idx, OUTGOING, dup_vec); + self.collect_concrete_regions(graph, node_idx, OUTGOING, Some(dup_vec)); if lower_dup || upper_dup { return; @@ -604,9 +744,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { }; for upper_bound in &upper_bounds { - if !self.region_rels - .is_subregion_of(effective_lower_bound, upper_bound.region) - { + if !self.region_rels.is_subregion_of(effective_lower_bound, upper_bound.region) { let origin = self.var_infos[node_idx].origin.clone(); debug!( "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \ @@ -643,7 +781,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { graph: &RegionGraph<'tcx>, orig_node_idx: RegionVid, dir: Direction, - dup_vec: &mut [u32], + mut dup_vec: Option<&mut IndexVec>>, ) -> (Vec>, bool) { struct WalkState<'tcx> { set: FxHashSet, @@ -667,23 +805,23 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let node_idx = state.stack.pop().unwrap(); // check whether we've visited this node on some previous walk - if dup_vec[node_idx.index() as usize] == u32::MAX { - dup_vec[node_idx.index() as usize] = orig_node_idx.index() as u32; - } else if dup_vec[node_idx.index() as usize] != orig_node_idx.index() as u32 { - state.dup_found = true; - } + if let Some(dup_vec) = &mut dup_vec { + if dup_vec[node_idx].is_none() { + dup_vec[node_idx] = Some(orig_node_idx); + } else if dup_vec[node_idx] != Some(orig_node_idx) { + state.dup_found = true; + } - debug!( - "collect_concrete_regions(orig_node_idx={:?}, node_idx={:?})", - orig_node_idx, node_idx - ); + debug!( + "collect_concrete_regions(orig_node_idx={:?}, node_idx={:?})", + orig_node_idx, node_idx + ); + } process_edges(&self.data, &mut state, graph, node_idx, dir); } - let WalkState { - result, dup_found, .. - } = state; + let WalkState { result, dup_found, .. } = state; return (result, dup_found); fn process_edges<'tcx>( @@ -699,11 +837,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { for (_, edge) in graph.adjacent_edges(source_node_index, dir) { match edge.data { Constraint::VarSubVar(from_vid, to_vid) => { - let opp_vid = if from_vid == source_vid { - to_vid - } else { - from_vid - }; + let opp_vid = if from_vid == source_vid { to_vid } else { from_vid }; if state.set.insert(opp_vid) { state.stack.push(opp_vid); } @@ -726,7 +860,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn iterate_until_fixed_point(&self, tag: &str, mut body: F) - where F: FnMut(&Constraint<'tcx>) -> (bool, bool), + where + F: FnMut(&Constraint<'tcx>) -> (bool, bool), { let mut constraints: SmallVec<[_; 16]> = self.data.constraints.keys().collect(); let mut iteration = 0; @@ -760,17 +895,17 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { && self.bound_is_met(b, var_values, generic_ty, min) } - VerifyBound::OutlivedBy(r) => - self.region_rels.is_subregion_of( - min, - var_values.normalize(self.tcx(), r), - ), + VerifyBound::OutlivedBy(r) => { + self.region_rels.is_subregion_of(min, var_values.normalize(self.tcx(), r)) + } - VerifyBound::AnyBound(bs) => bs.iter() - .any(|b| self.bound_is_met(b, var_values, generic_ty, min)), + VerifyBound::AnyBound(bs) => { + bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min)) + } - VerifyBound::AllBounds(bs) => bs.iter() - .all(|b| self.bound_is_met(b, var_values, generic_ty, min)), + VerifyBound::AllBounds(bs) => { + bs.iter().all(|b| self.bound_is_met(b, var_values, generic_ty, min)) + } } } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 9a5c726901fe8..663acd67dcd83 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -26,6 +26,7 @@ use crate::ty::{FloatVid, IntVid, TyVid, ConstVid}; use crate::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; +use rustc_data_structures::sync::Lrc; use rustc_data_structures::unify as ut; use std::cell::{Cell, Ref, RefCell, RefMut}; use std::collections::BTreeMap; @@ -904,6 +905,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .make_subregion(origin, a, b); } + /// Require that the region `r` be equal to one of the regions in + /// the set `regions`. + pub fn member_constraint( + &self, + opaque_type_def_id: DefId, + definition_span: Span, + hidden_ty: Ty<'tcx>, + region: ty::Region<'tcx>, + in_regions: &Lrc>>, + ) { + debug!("member_constraint({:?} <: {:?})", region, in_regions); + self.borrow_region_constraints() + .member_constraint(opaque_type_def_id, definition_span, hidden_ty, region, in_regions); + } + pub fn subtype_predicate( &self, cause: &ObligationCause<'tcx>, @@ -1456,7 +1472,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Even if the type may have no inference variables, during // type-checking closure types are in local tables only. if !self.in_progress_tables.is_some() || !ty.has_closure_types() { - if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) { + if !(param_env, ty).has_local_value() { return ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span); } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index a1a93eb552138..a0621af053783 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -364,7 +364,7 @@ where // been fully instantiated and hence the set of scopes we have // doesn't matter -- just to be sure, put an empty vector // in there. - let old_a_scopes = ::std::mem::replace(pair.vid_scopes(self), vec![]); + let old_a_scopes = ::std::mem::take(pair.vid_scopes(self)); // Relate the generalized kind to the original one. let result = pair.relate_generalized_ty(self, generalized_ty); diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 6b6dbd43167fa..f43e3fa0b7787 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -1,16 +1,19 @@ -use rustc_data_structures::fx::FxHashMap; -use syntax_pos::Span; - -use crate::hir::def_id::DefId; use crate::hir; +use crate::hir::def_id::DefId; use crate::hir::Node; -use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::outlives::free_region_map::FreeRegionRelations; +use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind}; +use crate::middle::region; use crate::traits::{self, PredicateObligation}; -use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind}; use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; -use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind}; +use crate::ty::subst::{InternalSubsts, Kind, SubstsRef, UnpackedKind}; +use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt}; use crate::util::nodemap::DefIdMap; +use errors::DiagnosticBuilder; +use rustc::session::config::nightly_options; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lrc; +use syntax_pos::Span; pub type OpaqueTypeMap<'tcx> = DefIdMap>; @@ -32,6 +35,20 @@ pub struct OpaqueTypeDecl<'tcx> { /// then `substs` would be `['a, T]`. pub substs: SubstsRef<'tcx>, + /// The span of this particular definition of the opaque type. So + /// for example: + /// + /// ``` + /// existential type Foo; + /// fn bar() -> Foo { + /// ^^^ This is the span we are looking for! + /// ``` + /// + /// In cases where the fn returns `(impl Trait, impl Trait)` or + /// other such combinations, the result is currently + /// over-approximated, but better than nothing. + pub definition_span: Span, + /// The type variable that represents the value of the abstract type /// that we require. In other words, after we compile this function, /// we will be created a constraint like: @@ -98,30 +115,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// - `param_env` -- the in-scope parameter environment to be used for /// obligations /// - `value` -- the value within which we are instantiating opaque types + /// - `value_span` -- the span where the value came from, used in error reporting pub fn instantiate_opaque_types>( &self, parent_def_id: DefId, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, value: &T, + value_span: Span, ) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)> { - debug!("instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \ - param_env={:?})", - value, parent_def_id, body_id, param_env, + debug!( + "instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \ + param_env={:?})", + value, parent_def_id, body_id, param_env, ); let mut instantiator = Instantiator { infcx: self, parent_def_id, body_id, param_env, + value_span, opaque_types: Default::default(), obligations: vec![], }; let value = instantiator.instantiate_opaque_types_in_map(value); - InferOk { - value: (value, instantiator.opaque_types), - obligations: instantiator.obligations, - } + InferOk { value: (value, instantiator.opaque_types), obligations: instantiator.obligations } } /// Given the map `opaque_types` containing the existential `impl @@ -216,13 +234,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// /// # The Solution /// - /// We make use of the constraint that we *do* have in the `<=` - /// relation. To do that, we find the "minimum" of all the - /// arguments that appear in the substs: that is, some region - /// which is less than all the others. In the case of `Foo1<'a>`, - /// that would be `'a` (it's the only choice, after all). Then we - /// apply that as a least bound to the variables (e.g., `'a <= - /// '0`). + /// We generally prefer to make `<=` constraints, since they + /// integrate best into the region solver. To do that, we find the + /// "minimum" of all the arguments that appear in the substs: that + /// is, some region which is less than all the others. In the case + /// of `Foo1<'a>`, that would be `'a` (it's the only choice, after + /// all). Then we apply that as a least bound to the variables + /// (e.g., `'a <= '0`). /// /// In some cases, there is no minimum. Consider this example: /// @@ -230,8 +248,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// fn baz<'a, 'b>() -> impl Trait<'a, 'b> { ... } /// ``` /// - /// Here we would report an error, because `'a` and `'b` have no - /// relation to one another. + /// Here we would report a more complex "in constraint", like `'r + /// in ['a, 'b, 'static]` (where `'r` is some regon appearing in + /// the hidden type). + /// + /// # Constrain regions, not the hidden concrete type + /// + /// Note that generating constraints on each region `Rc` is *not* + /// the same as generating an outlives constraint on `Tc` iself. + /// For example, if we had a function like this: + /// + /// ```rust + /// fn foo<'a, T>(x: &'a u32, y: T) -> impl Foo<'a> { + /// (x, y) + /// } + /// + /// // Equivalent to: + /// existential type FooReturn<'a, T>: Foo<'a>; + /// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. } + /// ``` + /// + /// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0` + /// is an inference variable). If we generated a constraint that + /// `Tc: 'a`, then this would incorrectly require that `T: 'a` -- + /// but this is not necessary, because the existential type we + /// create will be allowed to reference `T`. So we only generate a + /// constraint that `'0: 'a`. /// /// # The `free_region_relations` parameter /// @@ -274,6 +316,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + /// See `constrain_opaque_types` for documentation. pub fn constrain_opaque_type>( &self, def_id: DefId, @@ -290,32 +333,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); - let abstract_type_generics = tcx.generics_of(def_id); + let opaque_type_generics = tcx.generics_of(def_id); let span = tcx.def_span(def_id); // If there are required region bounds, we can use them. if opaque_defn.has_required_region_bounds { let predicates_of = tcx.predicates_of(def_id); - debug!( - "constrain_opaque_type: predicates: {:#?}", - predicates_of, - ); + debug!("constrain_opaque_type: predicates: {:#?}", predicates_of,); let bounds = predicates_of.instantiate(tcx, opaque_defn.substs); debug!("constrain_opaque_type: bounds={:#?}", bounds); let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs); - let required_region_bounds = tcx.required_region_bounds( - opaque_type, - bounds.predicates, - ); + let required_region_bounds = tcx.required_region_bounds(opaque_type, bounds.predicates); debug_assert!(!required_region_bounds.is_empty()); - for region in required_region_bounds { - concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor { - infcx: self, - least_region: region, - span, + for required_region in required_region_bounds { + concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, + op: |r| self.sub_regions(infer::CallReturn(span), required_region, r), }); } return; @@ -329,11 +365,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // `['a]` for the first impl trait and `'b` for the // second. let mut least_region = None; - for param in &abstract_type_generics.params { + for param in &opaque_type_generics.params { match param.kind { GenericParamDefKind::Lifetime => {} - _ => continue + _ => continue, } + // Get the value supplied for this region from the substs. let subst_arg = opaque_defn.substs.region_at(param.index as usize); @@ -350,44 +387,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { least_region = Some(subst_arg); } else { // There are two regions (`lr` and - // `subst_arg`) which are not relatable. We can't - // find a best choice. - let context_name = match opaque_defn.origin { - hir::ExistTyOrigin::ExistentialType => "existential type", - hir::ExistTyOrigin::ReturnImplTrait => "impl Trait", - hir::ExistTyOrigin::AsyncFn => "async fn", - }; - let msg = format!("ambiguous lifetime bound in `{}`", context_name); - let mut err = self.tcx - .sess - .struct_span_err(span, &msg); - - let lr_name = lr.to_string(); - let subst_arg_name = subst_arg.to_string(); - let label_owned; - let label = match (&*lr_name, &*subst_arg_name) { - ("'_", "'_") => "the elided lifetimes here do not outlive one another", - _ => { - label_owned = format!( - "neither `{}` nor `{}` outlives the other", - lr_name, - subst_arg_name, - ); - &label_owned - } - }; - err.span_label(span, label); - - if let hir::ExistTyOrigin::AsyncFn = opaque_defn.origin { - err.note("multiple unrelated lifetimes are not allowed in \ - `async fn`."); - err.note("if you're using argument-position elided lifetimes, consider \ - switching to a single named lifetime."); - } - err.emit(); - - least_region = Some(self.tcx.mk_region(ty::ReEmpty)); - break; + // `subst_arg`) which are not relatable. We + // can't find a best choice. Therefore, + // instead of creating a single bound like + // `'r: 'a` (which is our preferred choice), + // we will create a "in bound" like `'r in + // ['a, 'b, 'c]`, where `'a..'c` are the + // regions that appear in the impl trait. + return self.generate_member_constraint( + concrete_ty, + opaque_type_generics, + opaque_defn, + def_id, + lr, + subst_arg, + ); } } } @@ -396,13 +410,121 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let least_region = least_region.unwrap_or(tcx.lifetimes.re_static); debug!("constrain_opaque_types: least_region={:?}", least_region); - concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor { - infcx: self, - least_region, - span, + concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, + op: |r| self.sub_regions(infer::CallReturn(span), least_region, r), }); } + /// As a fallback, we sometimes generate an "in constraint". For + /// a case like `impl Foo<'a, 'b>`, where `'a` and `'b` cannot be + /// related, we would generate a constraint `'r in ['a, 'b, + /// 'static]` for each region `'r` that appears in the hidden type + /// (i.e., it must be equal to `'a`, `'b`, or `'static`). + /// + /// `conflict1` and `conflict2` are the two region bounds that we + /// detected which were unrelated. They are used for diagnostics. + fn generate_member_constraint( + &self, + concrete_ty: Ty<'tcx>, + opaque_type_generics: &ty::Generics, + opaque_defn: &OpaqueTypeDecl<'tcx>, + opaque_type_def_id: DefId, + conflict1: ty::Region<'tcx>, + conflict2: ty::Region<'tcx>, + ) { + // For now, enforce a feature gate outside of async functions. + if self.member_constraint_feature_gate( + opaque_defn, + opaque_type_def_id, + conflict1, + conflict2, + ) { + return; + } + + // Create the set of choice regions: each region in the hidden + // type can be equal to any of the region parameters of the + // opaque type definition. + let choice_regions: Lrc>> = Lrc::new( + opaque_type_generics + .params + .iter() + .filter(|param| match param.kind { + GenericParamDefKind::Lifetime => true, + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => false, + }) + .map(|param| opaque_defn.substs.region_at(param.index as usize)) + .chain(std::iter::once(self.tcx.lifetimes.re_static)) + .collect(), + ); + + concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, + op: |r| self.member_constraint( + opaque_type_def_id, + opaque_defn.definition_span, + concrete_ty, + r, + &choice_regions, + ), + }); + } + + /// Member constraints are presently feature-gated except for + /// async-await. We expect to lift this once we've had a bit more + /// time. + fn member_constraint_feature_gate( + &self, + opaque_defn: &OpaqueTypeDecl<'tcx>, + opaque_type_def_id: DefId, + conflict1: ty::Region<'tcx>, + conflict2: ty::Region<'tcx>, + ) -> bool { + // If we have `#![feature(member_constraints)]`, no problems. + if self.tcx.features().member_constraints { + return false; + } + + let span = self.tcx.def_span(opaque_type_def_id); + + // Without a feature-gate, we only generate member-constraints for async-await. + let context_name = match opaque_defn.origin { + // No feature-gate required for `async fn`. + hir::ExistTyOrigin::AsyncFn => return false, + + // Otherwise, generate the label we'll use in the error message. + hir::ExistTyOrigin::ExistentialType => "existential type", + hir::ExistTyOrigin::ReturnImplTrait => "impl Trait", + }; + let msg = format!("ambiguous lifetime bound in `{}`", context_name); + let mut err = self.tcx.sess.struct_span_err(span, &msg); + + let conflict1_name = conflict1.to_string(); + let conflict2_name = conflict2.to_string(); + let label_owned; + let label = match (&*conflict1_name, &*conflict2_name) { + ("'_", "'_") => "the elided lifetimes here do not outlive one another", + _ => { + label_owned = format!( + "neither `{}` nor `{}` outlives the other", + conflict1_name, conflict2_name, + ); + &label_owned + } + }; + err.span_label(span, label); + + if nightly_options::is_nightly_build() { + help!(err, + "add #![feature(member_constraints)] to the crate attributes \ + to enable"); + } + + err.emit(); + true + } + /// Given the fully resolved, instantiated type for an opaque /// type, i.e., the value of an inference variable like C1 or C2 /// (*), computes the "definition type" for an abstract type @@ -456,23 +578,98 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - let definition_ty = - instantiated_ty.fold_with(&mut ReverseMapper::new( - self.tcx, - self.is_tainted_by_errors(), - def_id, - map, - instantiated_ty, - )); - debug!( - "infer_opaque_definition_from_instantiation: definition_ty={:?}", - definition_ty - ); + let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new( + self.tcx, + self.is_tainted_by_errors(), + def_id, + map, + instantiated_ty, + )); + debug!("infer_opaque_definition_from_instantiation: definition_ty={:?}", definition_ty); definition_ty } } +pub fn unexpected_hidden_region_diagnostic( + tcx: TyCtxt<'tcx>, + region_scope_tree: Option<®ion::ScopeTree>, + opaque_type_def_id: DefId, + hidden_ty: Ty<'tcx>, + hidden_region: ty::Region<'tcx>, +) -> DiagnosticBuilder<'tcx> { + let span = tcx.def_span(opaque_type_def_id); + let mut err = struct_span_err!( + tcx.sess, + span, + E0700, + "hidden type for `impl Trait` captures lifetime that does not appear in bounds", + ); + + // Explain the region we are capturing. + if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty = hidden_region { + // Assuming regionck succeeded (*), we ought to always be + // capturing *some* region from the fn header, and hence it + // ought to be free. So under normal circumstances, we will go + // down this path which gives a decent human readable + // explanation. + // + // (*) if not, the `tainted_by_errors` flag would be set to + // true in any case, so we wouldn't be here at all. + tcx.note_and_explain_free_region( + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", + ); + } else { + // Ugh. This is a painful case: the hidden region is not one + // that we can easily summarize or explain. This can happen + // in a case like + // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`: + // + // ``` + // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> { + // if condition() { a } else { b } + // } + // ``` + // + // Here the captured lifetime is the intersection of `'a` and + // `'b`, which we can't quite express. + + if let Some(region_scope_tree) = region_scope_tree { + // If the `region_scope_tree` is available, this is being + // invoked from the "region inferencer error". We can at + // least report a really cryptic error for now. + tcx.note_and_explain_region( + region_scope_tree, + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", + ); + } else { + // If the `region_scope_tree` is *unavailable*, this is + // being invoked by the code that comes *after* region + // inferencing. This is a bug, as the region inferencer + // ought to have noticed the failed constraint and invoked + // error reporting, which in turn should have prevented us + // from getting trying to infer the hidden type + // completely. + tcx.sess.delay_span_bug( + span, + &format!( + "hidden type captures unexpected lifetime `{:?}` \ + but no region inference failure", + hidden_region, + ), + ); + } + } + + err +} + // Visitor that requires that (almost) all regions in the type visited outlive // `least_region`. We cannot use `push_outlives_components` because regions in // closure signatures are not included in their outlives components. We need to @@ -486,13 +683,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // // We ignore any type parameters because impl trait values are assumed to // capture all the in-scope type parameters. -struct OpaqueTypeOutlivesVisitor<'a, 'tcx> { - infcx: &'a InferCtxt<'a, 'tcx>, - least_region: ty::Region<'tcx>, - span: Span, +struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP> +where + OP: FnMut(ty::Region<'tcx>), +{ + tcx: TyCtxt<'tcx>, + op: OP, } -impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, 'tcx> { +impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> +where + OP: FnMut(ty::Region<'tcx>), +{ fn visit_binder>(&mut self, t: &ty::Binder) -> bool { t.skip_binder().visit_with(self); false // keep visiting @@ -503,7 +705,7 @@ impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, 'tcx> { // ignore bound regions, keep visiting ty::ReLateBound(_, _) => false, _ => { - self.infcx.sub_regions(infer::CallReturn(self.span), self.least_region, r); + (self.op)(r); false } } @@ -519,23 +721,23 @@ impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, 'tcx> { ty::Closure(def_id, ref substs) => { // Skip lifetime parameters of the enclosing item(s) - for upvar_ty in substs.upvar_tys(def_id, self.infcx.tcx) { + for upvar_ty in substs.upvar_tys(def_id, self.tcx) { upvar_ty.visit_with(self); } - substs.closure_sig_ty(def_id, self.infcx.tcx).visit_with(self); + substs.closure_sig_ty(def_id, self.tcx).visit_with(self); } ty::Generator(def_id, ref substs, _) => { // Skip lifetime parameters of the enclosing item(s) // Also skip the witness type, because that has no free regions. - for upvar_ty in substs.upvar_tys(def_id, self.infcx.tcx) { + for upvar_ty in substs.upvar_tys(def_id, self.tcx) { upvar_ty.visit_with(self); } - substs.return_ty(def_id, self.infcx.tcx).visit_with(self); - substs.yield_ty(def_id, self.infcx.tcx).visit_with(self); + substs.return_ty(def_id, self.tcx).visit_with(self); + substs.yield_ty(def_id, self.tcx).visit_with(self); } _ => { ty.super_visit_with(self); @@ -616,40 +818,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { None => { if !self.map_missing_regions_to_empty && !self.tainted_by_errors { if let Some(hidden_ty) = self.hidden_ty.take() { - let span = self.tcx.def_span(self.opaque_type_def_id); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0700, - "hidden type for `impl Trait` captures lifetime that \ - does not appear in bounds", - ); - - // Assuming regionck succeeded, then we must - // be capturing *some* region from the fn - // header, and hence it must be free, so it's - // ok to invoke this fn (which doesn't accept - // all regions, and would ICE if an - // inappropriate region is given). We check - // `is_tainted_by_errors` by errors above, so - // we don't get in here unless regionck - // succeeded. (Note also that if regionck - // failed, then the regions we are attempting - // to map here may well be giving errors - // *because* the constraints were not - // satisfiable.) - self.tcx.note_and_explain_free_region( - &mut err, - &format!("hidden type `{}` captures ", hidden_ty), + unexpected_hidden_region_diagnostic( + self.tcx, + None, + self.opaque_type_def_id, + hidden_ty, r, - "" - ); - - err.emit(); + ).emit(); } } self.tcx.lifetimes.re_empty - }, + } } } @@ -681,8 +860,8 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { // during codegen. let generics = self.tcx.generics_of(def_id); - let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map( - |(index, &kind)| { + let substs = + self.tcx.mk_substs(substs.substs.iter().enumerate().map(|(index, &kind)| { if index < generics.parent_count { // Accommodate missing regions in the parent kinds... self.fold_kind_mapping_missing_regions_to_empty(kind) @@ -690,16 +869,15 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { // ...but not elsewhere. self.fold_kind_normally(kind) } - }, - )); + })); self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs }) } ty::Generator(def_id, substs, movability) => { let generics = self.tcx.generics_of(def_id); - let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map( - |(index, &kind)| { + let substs = + self.tcx.mk_substs(substs.substs.iter().enumerate().map(|(index, &kind)| { if index < generics.parent_count { // Accommodate missing regions in the parent kinds... self.fold_kind_mapping_missing_regions_to_empty(kind) @@ -707,8 +885,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { // ...but not elsewhere. self.fold_kind_normally(kind) } - }, - )); + })); self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability) } @@ -723,6 +900,7 @@ struct Instantiator<'a, 'tcx> { parent_def_id: DefId, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, + value_span: Span, opaque_types: OpaqueTypeMap<'tcx>, obligations: Vec>, } @@ -773,12 +951,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let parent_def_id = self.parent_def_id; let def_scope_default = || { let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); - parent_def_id == tcx.hir() - .local_def_id_from_hir_id(opaque_parent_hir_id) + parent_def_id + == tcx.hir().local_def_id_from_hir_id(opaque_parent_hir_id) }; - let (in_definition_scope, origin) = - match tcx.hir().find(opaque_hir_id) - { + let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) { Some(Node::Item(item)) => match item.node { // Anonymous `impl Trait` hir::ItemKind::Existential(hir::ExistTy { @@ -847,10 +1023,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let infcx = self.infcx; let tcx = infcx.tcx; - debug!( - "instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", - def_id, substs - ); + debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs); // Use the same type variable if the exact same opaque type appears more // than once in the return type (e.g., if it's passed to a type alias). @@ -858,41 +1031,35 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { return opaque_defn.concrete_ty; } let span = tcx.def_span(def_id); - let ty_var = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - }); + let ty_var = infcx + .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }); let predicates_of = tcx.predicates_of(def_id); - debug!( - "instantiate_opaque_types: predicates={:#?}", - predicates_of, - ); + debug!("instantiate_opaque_types: predicates={:#?}", predicates_of,); let bounds = predicates_of.instantiate(tcx, substs); debug!("instantiate_opaque_types: bounds={:?}", bounds); let required_region_bounds = tcx.required_region_bounds(ty, bounds.predicates.clone()); - debug!( - "instantiate_opaque_types: required_region_bounds={:?}", - required_region_bounds - ); + debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds); // Make sure that we are in fact defining the *entire* type // (e.g., `existential type Foo: Bar;` needs to be // defined by a function like `fn foo() -> Foo`). - debug!( - "instantiate_opaque_types: param_env={:#?}", - self.param_env, - ); - debug!( - "instantiate_opaque_types: generics={:#?}", - tcx.generics_of(def_id), - ); + debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,); + debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),); + + // Ideally, we'd get the span where *this specific `ty` came + // from*, but right now we just use the span from the overall + // value being folded. In simple cases like `-> impl Foo`, + // these are the same span, but not in cases like `-> (impl + // Foo, impl Bar)`. + let definition_span = self.value_span; self.opaque_types.insert( def_id, OpaqueTypeDecl { substs, + definition_span, concrete_ty: ty_var, has_required_region_bounds: !required_region_bounds.is_empty(), origin, @@ -911,8 +1078,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { // Require that the predicate holds for the concrete type. debug!("instantiate_opaque_types: predicate={:?}", predicate); - self.obligations - .push(traits::Obligation::new(cause, self.param_env, predicate)); + self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate)); } ty_var @@ -950,9 +1116,7 @@ pub fn may_define_existential_type( ); // Named existential types can be defined by any siblings or children of siblings. - let scope = tcx.hir() - .get_defining_scope(opaque_hir_id) - .expect("could not get defining scope"); + let scope = tcx.hir().get_defining_scope(opaque_hir_id).expect("could not get defining scope"); // We walk up the node tree until we hit the root or the scope of the opaque type. while hir_id != scope && hir_id != hir::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id); diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index 1250995a59c10..c085df6a6e7ab 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -11,6 +11,10 @@ pub struct FreeRegionMap<'tcx> { } impl<'tcx> FreeRegionMap<'tcx> { + pub fn elements(&self) -> impl Iterator> { + self.relation.elements() + } + pub fn is_empty(&self) -> bool { self.relation.is_empty() } diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 0ae4446ee63fa..e1470e4ef0232 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -112,7 +112,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Trait queries just want to pass back type obligations "as is" pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> { - ::std::mem::replace(&mut *self.region_obligations.borrow_mut(), vec![]) + ::std::mem::take(&mut *self.region_obligations.borrow_mut()) } /// Process the region obligations that must be proven (during diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index f2235fe8d6d12..21904edb309cb 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -8,11 +8,14 @@ use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; +use rustc_data_structures::sync::Lrc; use rustc_data_structures::unify as ut; +use crate::hir::def_id::DefId; use crate::ty::ReStatic; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{ReLateBound, ReVar}; use crate::ty::{Region, RegionVid}; +use syntax_pos::Span; use std::collections::BTreeMap; use std::{cmp, fmt, mem}; @@ -78,6 +81,11 @@ pub struct RegionConstraintData<'tcx> { /// be a region variable (or neither, as it happens). pub constraints: BTreeMap, SubregionOrigin<'tcx>>, + /// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that + /// `R0` must be equal to one of the regions `R1..Rn`. These occur + /// with `impl Trait` quite frequently. + pub member_constraints: Vec>, + /// A "verify" is something that we need to verify after inference /// is done, but which does not directly affect inference in any /// way. @@ -137,6 +145,43 @@ impl Constraint<'_> { } } +/// Requires that `region` must be equal to one of the regions in `choice_regions`. +/// We often denote this using the syntax: +/// +/// ``` +/// R0 member of [O1..On] +/// ``` +#[derive(Debug, Clone, HashStable)] +pub struct MemberConstraint<'tcx> { + /// The `DefId` of the opaque type causing this constraint: used for error reporting. + pub opaque_type_def_id: DefId, + + /// The span where the hidden type was instantiated. + pub definition_span: Span, + + /// The hidden type in which `member_region` appears: used for error reporting. + pub hidden_ty: Ty<'tcx>, + + /// The region `R0`. + pub member_region: Region<'tcx>, + + /// The options `O1..On`. + pub choice_regions: Lrc>>, +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for MemberConstraint<'tcx> { + opaque_type_def_id, definition_span, hidden_ty, member_region, choice_regions + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for MemberConstraint<'a> { + type Lifted = MemberConstraint<'tcx>; + opaque_type_def_id, definition_span, hidden_ty, member_region, choice_regions + } +} + /// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or /// associated type) must outlive the region `R`. `T` is known to /// outlive `RS`. Therefore, verify that `R <= RS[i]` for some @@ -410,7 +455,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { *any_unifications = false; } - mem::replace(data, RegionConstraintData::default()) + mem::take(data) } pub fn data(&self) -> &RegionConstraintData<'tcx> { @@ -643,6 +688,30 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } } + pub fn member_constraint( + &mut self, + opaque_type_def_id: DefId, + definition_span: Span, + hidden_ty: Ty<'tcx>, + member_region: ty::Region<'tcx>, + choice_regions: &Lrc>>, + ) { + debug!("member_constraint({:?} in {:#?})", member_region, choice_regions); + + if choice_regions.iter().any(|&r| r == member_region) { + return; + } + + self.data.member_constraints.push(MemberConstraint { + opaque_type_def_id, + definition_span, + hidden_ty, + member_region, + choice_regions: choice_regions.clone() + }); + + } + pub fn make_subregion( &mut self, origin: SubregionOrigin<'tcx>, @@ -906,9 +975,13 @@ impl<'tcx> RegionConstraintData<'tcx> { pub fn is_empty(&self) -> bool { let RegionConstraintData { constraints, + member_constraints, verifys, givens, } = self; - constraints.is_empty() && verifys.is_empty() && givens.is_empty() + constraints.is_empty() && + member_constraints.is_empty() && + verifys.is_empty() && + givens.is_empty() } } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index dcafb0f3976ff..e30e86998a8c6 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -115,7 +115,7 @@ impl<'tcx> TypeVariableTable<'tcx> { /// /// Note that this function does not return care whether /// `vid` has been unified with something else or not. - pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool { + pub fn var_diverges(&self, vid: ty::TyVid) -> bool { self.values.get(vid.index as usize).diverging } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 257d5159f1131..c4c23428002e6 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -35,6 +35,8 @@ #![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(const_fn)] +#![feature(const_transmute)] #![feature(core_intrinsics)] #![feature(drain_filter)] #![feature(inner_deref)] @@ -65,6 +67,7 @@ #![feature(crate_visibility_modifier)] #![feature(proc_macro_hygiene)] #![feature(log_syntax)] +#![feature(mem_take)] #![recursion_limit="512"] diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 309af4b72c127..59b08b832d272 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -765,7 +765,7 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) } -fn lint_levels<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx LintLevelMap { +fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); let mut builder = LintLevelMapBuilder { levels: LintLevelSets::builder(tcx.sess), diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 2e9e1ac582f81..5a580dfa420b3 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -211,7 +211,7 @@ pub trait CrateStore { fn crates_untracked(&self) -> Vec; // utility functions - fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata; + fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata; fn metadata_encoding_version(&self) -> &[u8]; } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index e02ee8943603a..e1889aa555f86 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -26,7 +26,7 @@ use syntax_pos; // explored. For example, if it's a live Node::Item that is a // function, then we should explore its block to check for codes that // may need to be marked as live. -fn should_explore<'tcx>(tcx: TyCtxt<'tcx>, hir_id: hir::HirId) -> bool { +fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { match tcx.hir().find(hir_id) { Some(Node::Item(..)) | Some(Node::ImplItem(..)) | @@ -662,7 +662,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } } -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_crate(tcx: TyCtxt<'_>) { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); let krate = tcx.hir().krate(); let live_symbols = find_live(tcx, access_levels, krate); diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 879da6413e28a..96b99fe4cdce2 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -81,7 +81,7 @@ pub enum Linkage { Dynamic, } -pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn calculate(tcx: TyCtxt<'_>) { let sess = &tcx.sess; let fmts = sess.crate_types.borrow().iter().map(|&ty| { let linkage = calculate_type(tcx, ty); @@ -92,7 +92,7 @@ pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) { sess.dependency_formats.set(fmts); } -fn calculate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: config::CrateType) -> DependencyList { +fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { let sess = &tcx.sess; if !sess.opts.output_types.should_codegen() { @@ -267,7 +267,7 @@ fn add_library( } } -fn attempt_static<'tcx>(tcx: TyCtxt<'tcx>) -> Option { +fn attempt_static(tcx: TyCtxt<'_>) -> Option { let sess = &tcx.sess; let crates = cstore::used_crates(tcx, RequireStatic); if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) { @@ -324,7 +324,7 @@ fn activate_injected_dep(injected: Option, // After the linkage for a crate has been determined we need to verify that // there's only going to be one allocator in the output. -fn verify_ok<'tcx>(tcx: TyCtxt<'tcx>, list: &[Linkage]) { +fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { let sess = &tcx.sess; if list.len() == 0 { return diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 086ddfd7e33bf..c93cc847adff2 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -11,6 +11,7 @@ use self::OverloadedCallType::*; use crate::hir::def::{CtorOf, Res, DefKind}; use crate::hir::def_id::DefId; +use crate::hir::ptr::P; use crate::infer::InferCtxt; use crate::middle::mem_categorization as mc; use crate::middle::region; @@ -18,7 +19,6 @@ use crate::ty::{self, DefIdTree, TyCtxt, adjustment}; use crate::hir::{self, PatKind}; use std::rc::Rc; -use syntax::ptr::P; use syntax_pos::Span; use crate::util::nodemap::ItemLocalSet; diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index e8d68e0b7a7aa..1cc96c549e724 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -10,7 +10,7 @@ use syntax_pos::{Span, sym}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::hir; -fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut ItemVisitor { tcx }.as_deep_visitor() diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 9c131ce63428b..694b0a9862960 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -142,7 +142,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> { } } -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LibFeatures { +pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures { let mut collector = LibFeatureCollector::new(tcx); intravisit::walk_crate(&mut collector, tcx.hir().krate()); collector.lib_features diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 7b69fe394fb2c..30ff835bdcc43 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -99,6 +99,7 @@ use self::VarKind::*; use crate::hir::def::*; use crate::hir::Node; +use crate::hir::ptr::P; use crate::ty::{self, TyCtxt}; use crate::ty::query::Providers; use crate::lint; @@ -111,7 +112,6 @@ use std::io::prelude::*; use std::io; use std::rc::Rc; use syntax::ast; -use syntax::ptr::P; use syntax::symbol::{kw, sym}; use syntax_pos::Span; @@ -181,7 +181,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); } } -fn check_mod_liveness<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut IrMaps::new(tcx, module_def_id).as_deep_visitor(), diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index e7253a73bd418..088c862dcb879 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -465,9 +465,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { ) -> bool { self.infcx.map(|infcx| infcx.type_is_copy_modulo_regions(param_env, ty, span)) .or_else(|| { - self.tcx.lift_to_global(&(param_env, ty)).map(|(param_env, ty)| { - ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span) - }) + if (param_env, ty).has_local_value() { + None + } else { + Some(ty.is_copy_modulo_regions(self.tcx, param_env, span)) + } }) .unwrap_or(true) } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index d607c35f8762b..6b26be34d7520 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -42,8 +42,8 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item, attrs: CodegenFnAt } } -fn method_might_be_inlined<'tcx>( - tcx: TyCtxt<'tcx>, +fn method_might_be_inlined( + tcx: TyCtxt<'_>, impl_item: &hir::ImplItem, impl_src: DefId, ) -> bool { @@ -391,7 +391,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx #[derive(Clone, HashStable)] pub struct ReachableSet(pub Lrc); -fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> ReachableSet { +fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { debug_assert!(crate_num == LOCAL_CRATE); let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 114684b152402..f859e835425c4 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1375,7 +1375,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0); let outer_cx = self.cx; - let outer_ts = mem::replace(&mut self.terminating_scopes, FxHashSet::default()); + let outer_ts = mem::take(&mut self.terminating_scopes); self.terminating_scopes.insert(body.value.hir_id.local_id); if let Some(root_id) = self.cx.root_id { @@ -1446,7 +1446,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { } } -fn region_scope_tree<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ScopeTree { +fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { let closure_base_def_id = tcx.closure_base_def_id(def_id); if closure_base_def_id != def_id { return tcx.region_scope_tree(closure_base_def_id); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 412346bab257e..758f14ebf99a6 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -8,6 +8,7 @@ use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use crate::hir::map::Map; +use crate::hir::ptr::P; use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName}; use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; @@ -18,10 +19,9 @@ use errors::{Applicability, DiagnosticBuilder}; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; -use std::mem::replace; +use std::mem::{replace, take}; use syntax::ast; use syntax::attr; -use syntax::ptr::P; use syntax::symbol::{kw, sym}; use syntax_pos::Span; @@ -368,7 +368,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// entire crate. You should not read the result of this query /// directly, but rather use `named_region_map`, `is_late_bound_map`, /// etc. -fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx ResolveLifetimes { +fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> &ResolveLifetimes { assert_eq!(for_krate, LOCAL_CRATE); let named_region_map = krate(tcx); @@ -395,7 +395,7 @@ fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx Reso tcx.arena.alloc(rl) } -fn krate<'tcx>(tcx: TyCtxt<'tcx>) -> NamedRegionMap { +fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap { let krate = tcx.hir().krate(); let mut map = NamedRegionMap { defs: Default::default(), @@ -441,7 +441,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { // Each body has their own set of labels, save labels. - let saved = replace(&mut self.labels_in_fn, vec![]); + let saved = take(&mut self.labels_in_fn); let body = self.tcx.hir().body(body); extract_labels(self, body); self.with( @@ -1405,9 +1405,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_uses, .. } = self; - let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); - let xcrate_object_lifetime_defaults = - replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default()); + let labels_in_fn = take(&mut self.labels_in_fn); + let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let mut this = LifetimeContext { tcx: *tcx, map: map, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 38df4060652b7..101563d2d99ef 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -466,7 +466,7 @@ impl<'tcx> Index<'tcx> { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. -fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }.as_deep_visitor()); } @@ -836,7 +836,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the list of enabled features that were not language features (i.e., that /// were expected to be library features), and the list of features used from /// libraries, identify activated features that don't exist and error about them. -pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); if tcx.stability().staged_api[&LOCAL_CRATE] { @@ -920,8 +920,8 @@ pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) { // don't lint about unused features. We should reenable this one day! } -fn unnecessary_stable_feature_lint<'tcx>( - tcx: TyCtxt<'tcx>, +fn unnecessary_stable_feature_lint( + tcx: TyCtxt<'_>, span: Span, feature: Symbol, since: Symbol, diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index e8113b4516cda..c8f42b1c604a5 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -18,7 +18,7 @@ use errors::DiagnosticBuilder; use syntax_pos::{Pos, Span}; use syntax::symbol::Symbol; -#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)] pub enum ErrorHandled { /// Already reported a lint or an error for this evaluation. Reported, @@ -37,6 +37,10 @@ impl ErrorHandled { } } +CloneTypeFoldableImpls! { + ErrorHandled, +} + pub type ConstEvalRawResult<'tcx> = Result, ErrorHandled>; pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>; @@ -178,7 +182,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<' /// up with a Rust-level backtrace of where the error occured. /// Thsese should always be constructed by calling `.into()` on /// a `InterpError`. In `librustc_mir::interpret`, we have the `err!` -/// macro for this +/// macro for this. #[derive(Debug, Clone)] pub struct InterpErrorInfo<'tcx> { pub kind: InterpError<'tcx, u64>, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9b1808c585ce7..59a032d53cfd6 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2867,19 +2867,19 @@ impl<'tcx> graph::WithStartNode for Body<'tcx> { } impl<'tcx> graph::WithPredecessors for Body<'tcx> { - fn predecessors<'graph>( - &'graph self, + fn predecessors( + &self, node: Self::Node, - ) -> >::Iter { + ) -> >::Iter { self.predecessors_for(node).clone().into_iter() } } impl<'tcx> graph::WithSuccessors for Body<'tcx> { - fn successors<'graph>( - &'graph self, + fn successors( + &self, node: Self::Node, - ) -> >::Iter { + ) -> >::Iter { self.basic_blocks[node].terminator().successors().cloned() } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 10efef54526a6..d2082ab87e738 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -2,7 +2,7 @@ use crate::ty::query::QueryDescription; use crate::ty::query::queries; use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use crate::ty::subst::SubstsRef; -use crate::dep_graph::SerializedDepNodeIndex; +use crate::dep_graph::{RecoverKey,DepKind, DepNode, SerializedDepNodeIndex}; use crate::hir::def_id::{CrateNum, DefId, DefIndex}; use crate::mir; use crate::mir::interpret::GlobalId; @@ -33,13 +33,13 @@ rustc_queries! { Other { /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { - cache { key.is_local() } + cache_on_disk_if { key.is_local() } } /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its /// associated generics. query generics_of(key: DefId) -> &'tcx ty::Generics { - cache { key.is_local() } + cache_on_disk_if { key.is_local() } load_cached(tcx, id) { let generics: Option = tcx.queries.on_disk_cache .try_load_query_result(tcx, id); @@ -62,7 +62,9 @@ rustc_queries! { /// predicate gets in the way of some checks, which are intended /// to operate over only the actual where-clauses written by the /// user.) - query predicates_of(_: DefId) -> &'tcx ty::GenericPredicates<'tcx> {} + query predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> { + cache_on_disk_if { key.is_local() } + } query native_libraries(_: CrateNum) -> Lrc> { desc { "looking up the native libraries of a linked crate" } @@ -93,7 +95,7 @@ rustc_queries! { /// of the MIR qualify_consts pass. The actual meaning of /// the value isn't known except to the pass itself. query mir_const_qualif(key: DefId) -> (u8, &'tcx BitSet) { - cache { key.is_local() } + cache_on_disk_if { key.is_local() } } /// Fetch the MIR for a given `DefId` right after it's built - this includes @@ -115,7 +117,7 @@ rustc_queries! { /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { - cache { key.is_local() } + cache_on_disk_if { key.is_local() } load_cached(tcx, id) { let mir: Option> = tcx.queries.on_disk_cache .try_load_query_result(tcx, id); @@ -285,7 +287,9 @@ rustc_queries! { TypeChecking { /// The result of unsafety-checking this `DefId`. - query unsafety_check_result(_: DefId) -> mir::UnsafetyCheckResult {} + query unsafety_check_result(key: DefId) -> mir::UnsafetyCheckResult { + cache_on_disk_if { key.is_local() } + } /// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error query unsafe_derive_on_repr_packed(_: DefId) -> () {} @@ -348,7 +352,7 @@ rustc_queries! { } query typeck_tables_of(key: DefId) -> &'tcx ty::TypeckTables<'tcx> { - cache { key.is_local() } + cache_on_disk_if { key.is_local() } load_cached(tcx, id) { let typeck_tables: Option> = tcx .queries.on_disk_cache @@ -360,7 +364,9 @@ rustc_queries! { } Other { - query used_trait_imports(_: DefId) -> &'tcx DefIdSet {} + query used_trait_imports(key: DefId) -> &'tcx DefIdSet { + cache_on_disk_if { key.is_local() } + } } TypeChecking { @@ -372,11 +378,15 @@ rustc_queries! { } BorrowChecking { - query borrowck(_: DefId) -> &'tcx BorrowCheckResult {} + query borrowck(key: DefId) -> &'tcx BorrowCheckResult { + cache_on_disk_if { key.is_local() } + } /// Borrow-checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. - query mir_borrowck(_: DefId) -> mir::BorrowCheckResult<'tcx> {} + query mir_borrowck(key: DefId) -> mir::BorrowCheckResult<'tcx> { + cache_on_disk_if(tcx, _) { key.is_local() && tcx.is_closure(key) } + } } TypeChecking { @@ -412,9 +422,10 @@ rustc_queries! { "const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id()) } - cache { true } - load_cached(tcx, id) { - tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok) + cache_on_disk_if(_, opt_result) { + // Only store results without errors + // FIXME: We never store these + opt_result.map_or(true, |r| r.is_ok()) } } @@ -427,9 +438,9 @@ rustc_queries! { "const-evaluating + checking `{}`", tcx.def_path_str(key.value.instance.def.def_id()) } - cache { true } - load_cached(tcx, id) { - tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok) + cache_on_disk_if(_, opt_result) { + // Only store results without errors + opt_result.map_or(true, |r| r.is_ok()) } } @@ -453,7 +464,9 @@ rustc_queries! { } TypeChecking { - query check_match(_: DefId) -> () {} + query check_match(key: DefId) -> () { + cache_on_disk_if { key.is_local() } + } /// Performs part of the privacy check and computes "access levels". query privacy_access_levels(_: CrateNum) -> &'tcx AccessLevels { @@ -483,7 +496,7 @@ rustc_queries! { query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName { no_force desc { "computing the symbol for `{}`", key } - cache { true } + cache_on_disk_if { true } } query def_kind(_: DefId) -> Option {} @@ -501,7 +514,9 @@ rustc_queries! { } Codegen { - query codegen_fn_attrs(_: DefId) -> CodegenFnAttrs {} + query codegen_fn_attrs(_: DefId) -> CodegenFnAttrs { + cache_on_disk_if { true } + } } Other { @@ -519,7 +534,7 @@ rustc_queries! { "const checking if rvalue is promotable to static `{}`", tcx.def_path_str(key) } - cache { true } + cache_on_disk_if { true } } query rvalue_promotable_map(key: DefId) -> &'tcx ItemLocalSet { desc { |tcx| @@ -548,7 +563,7 @@ rustc_queries! { key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) ) -> Vtable<'tcx, ()> { no_force - cache { true } + cache_on_disk_if { true } desc { |tcx| "checking if `{}` fulfills its obligations", tcx.def_path_str(key.1.def_id()) @@ -560,7 +575,9 @@ rustc_queries! { query trait_impls_of(key: DefId) -> &'tcx ty::trait_def::TraitImpls { desc { |tcx| "trait impls of `{}`", tcx.def_path_str(key) } } - query specialization_graph_of(_: DefId) -> &'tcx specialization_graph::Graph {} + query specialization_graph_of(_: DefId) -> &'tcx specialization_graph::Graph { + cache_on_disk_if { true } + } query is_object_safe(key: DefId) -> bool { desc { |tcx| "determine object safety of trait `{}`", tcx.def_path_str(key) } } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 895f9c6d8fb85..82c53be3ec70f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -269,11 +269,11 @@ impl OutputTypes { self.0.contains_key(key) } - pub fn keys<'a>(&'a self) -> BTreeMapKeysIter<'a, OutputType, Option> { + pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option> { self.0.keys() } - pub fn values<'a>(&'a self) -> BTreeMapValuesIter<'a, OutputType, Option> { + pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option> { self.0.values() } @@ -316,7 +316,7 @@ impl Externs { self.0.get(key) } - pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, ExternEntry> { + pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> { self.0.iter() } } @@ -1207,7 +1207,11 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, parse_linker_plugin_lto, [TRACKED], "generate build artifacts that are compatible with linker-based LTO."), - + profile_generate: SwitchWithOptPath = (SwitchWithOptPath::Disabled, + parse_switch_with_opt_path, [TRACKED], + "compile the program with profiling instrumentation"), + profile_use: Option = (None, parse_opt_pathbuf, [TRACKED], + "use the given `.profdata` file for profile-guided optimization"), } options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, @@ -1379,11 +1383,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "extra arguments to prepend to the linker invocation (space separated)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code"), - pgo_gen: SwitchWithOptPath = (SwitchWithOptPath::Disabled, - parse_switch_with_opt_path, [TRACKED], - "Generate PGO profile data, to a given file, or to the default location if it's empty."), - pgo_use: Option = (None, parse_opt_pathbuf, [TRACKED], - "Use PGO profile data from the given profile file."), disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED], "Disable the instrumentation pre-inliner, useful for profiling / PGO."), relro_level: Option = (None, parse_relro_level, [TRACKED], @@ -2036,13 +2035,6 @@ pub fn build_session_options_and_crate_config( } } - if debugging_opts.pgo_gen.enabled() && debugging_opts.pgo_use.is_some() { - early_error( - error_format, - "options `-Z pgo-gen` and `-Z pgo-use` are exclusive", - ); - } - let mut output_types = BTreeMap::new(); if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { @@ -2154,6 +2146,13 @@ pub fn build_session_options_and_crate_config( ); } + if cg.profile_generate.enabled() && cg.profile_use.is_some() { + early_error( + error_format, + "options `-C profile-generate` and `-C profile-use` are exclusive", + ); + } + let mut prints = Vec::::new(); if cg.target_cpu.as_ref().map_or(false, |s| s == "help") { prints.push(PrintRequest::TargetCPUs); diff --git a/src/librustc/session/config/tests.rs b/src/librustc/session/config/tests.rs index b8477f8dd1789..3d6312548a47b 100644 --- a/src/librustc/session/config/tests.rs +++ b/src/librustc/session/config/tests.rs @@ -519,11 +519,11 @@ fn test_codegen_options_tracking_hash() { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.pgo_gen = SwitchWithOptPath::Enabled(None); + opts.cg.profile_generate = SwitchWithOptPath::Enabled(None); assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.pgo_use = Some(PathBuf::from("abc")); + opts.cg.profile_use = Some(PathBuf::from("abc")); assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts = reference.clone(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index bb4ef2d7bd426..3cbf0ee213ae3 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -215,66 +215,66 @@ impl Session { *self.crate_disambiguator.get() } - pub fn struct_span_warn<'a, S: Into>( - &'a self, + pub fn struct_span_warn>( + &self, sp: S, msg: &str, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn(sp, msg) } - pub fn struct_span_warn_with_code<'a, S: Into>( - &'a self, + pub fn struct_span_warn_with_code>( + &self, sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } - pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_warn(msg) } - pub fn struct_span_err<'a, S: Into>( - &'a self, + pub fn struct_span_err>( + &self, sp: S, msg: &str, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_err(sp, msg) } - pub fn struct_span_err_with_code<'a, S: Into>( - &'a self, + pub fn struct_span_err_with_code>( + &self, sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_err_with_code(sp, msg, code) } // FIXME: This method should be removed (every error should have an associated error code). - pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_err(msg) } - pub fn struct_err_with_code<'a>( - &'a self, + pub fn struct_err_with_code( + &self, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_err_with_code(msg, code) } - pub fn struct_span_fatal<'a, S: Into>( - &'a self, + pub fn struct_span_fatal>( + &self, sp: S, msg: &str, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_fatal(sp, msg) } - pub fn struct_span_fatal_with_code<'a, S: Into>( - &'a self, + pub fn struct_span_fatal_with_code>( + &self, sp: S, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } - pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { self.diagnostic().struct_fatal(msg) } @@ -416,7 +416,7 @@ impl Session { pub fn next_node_id(&self) -> NodeId { self.reserve_node_ids(1) } - pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler { + pub fn diagnostic(&self) -> &errors::Handler { &self.parse_sess.span_diagnostic } @@ -504,7 +504,7 @@ impl Session { ); } - pub fn source_map<'a>(&'a self) -> &'a source_map::SourceMap { + pub fn source_map(&self) -> &source_map::SourceMap { self.parse_sess.source_map() } pub fn verbose(&self) -> bool { @@ -1295,9 +1295,9 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // Make sure that any given profiling data actually exists so LLVM can't // decide to silently skip PGO. - if let Some(ref path) = sess.opts.debugging_opts.pgo_use { + if let Some(ref path) = sess.opts.cg.profile_use { if !path.exists() { - sess.err(&format!("File `{}` passed to `-Zpgo-use` does not exist.", + sess.err(&format!("File `{}` passed to `-C profile-use` does not exist.", path.display())); } } @@ -1306,7 +1306,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // an error to combine the two for now. It always runs into an assertions // if LLVM is built with assertions, but without assertions it sometimes // does not crash and will probably generate a corrupted binary. - if sess.opts.debugging_opts.pgo_gen.enabled() && + if sess.opts.cg.profile_generate.enabled() && sess.target.target.options.is_like_msvc && sess.panic_strategy() == PanicStrategy::Unwind { sess.err("Profile-guided optimization does not yet work in conjunction \ diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index d8087af60acdf..b6f0addd77107 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -48,8 +48,8 @@ pub fn add_placeholder_note(err: &mut errors::DiagnosticBuilder<'_>) { /// If there are types that satisfy both impls, invokes `on_overlap` /// with a suitably-freshened `ImplHeader` with those types /// substituted. Otherwise, invokes `no_overlap`. -pub fn overlapping_impls<'tcx, F1, F2, R>( - tcx: TyCtxt<'tcx>, +pub fn overlapping_impls( + tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId, intercrate_mode: IntercrateMode, @@ -247,10 +247,10 @@ pub enum OrphanCheckErr<'tcx> { /// /// 1. All type parameters in `Self` must be "covered" by some local type constructor. /// 2. Some local type must appear in `Self`. -pub fn orphan_check<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn orphan_check( + tcx: TyCtxt<'_>, impl_def_id: DefId, -) -> Result<(), OrphanCheckErr<'tcx>> { +) -> Result<(), OrphanCheckErr<'_>> { debug!("orphan_check({:?})", impl_def_id); // We only except this routine to be invoked on implementations diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f54575ff8fc1d..d6cc68bcdab46 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -247,7 +247,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { /// returns the fuzzy category of a given type, or None /// if the type can be equated to any type. - fn type_category<'tcx>(t: Ty<'tcx>) -> Option { + fn type_category(t: Ty<'_>) -> Option { match t.sty { ty::Bool => Some(0), ty::Char => Some(1), diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index f106458c7676a..99b5ef3894b9c 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -461,41 +461,35 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } ty::Predicate::ConstEvaluatable(def_id, substs) => { - match self.selcx.tcx().lift_to_global(&obligation.param_env) { - None => { + if obligation.param_env.has_local_value() { ProcessResult::Unchanged - } - Some(param_env) => { - match self.selcx.tcx().lift_to_global(&substs) { - Some(substs) => { - let instance = ty::Instance::resolve( - self.selcx.tcx().global_tcx(), - param_env, - def_id, - substs, - ); - if let Some(instance) = instance { - let cid = GlobalId { - instance, - promoted: None, - }; - match self.selcx.tcx().at(obligation.cause.span) - .const_eval(param_env.and(cid)) { - Ok(_) => ProcessResult::Changed(vec![]), - Err(err) => ProcessResult::Error( - CodeSelectionError(ConstEvalFailure(err))) - } - } else { - ProcessResult::Error(CodeSelectionError( - ConstEvalFailure(ErrorHandled::TooGeneric) - )) - } - }, - None => { - pending_obligation.stalled_on = substs.types().collect(); - ProcessResult::Unchanged + } else { + if !substs.has_local_value() { + let instance = ty::Instance::resolve( + self.selcx.tcx().global_tcx(), + obligation.param_env, + def_id, + substs, + ); + if let Some(instance) = instance { + let cid = GlobalId { + instance, + promoted: None, + }; + match self.selcx.tcx().at(obligation.cause.span) + .const_eval(obligation.param_env.and(cid)) { + Ok(_) => ProcessResult::Changed(vec![]), + Err(err) => ProcessResult::Error( + CodeSelectionError(ConstEvalFailure(err))) } + } else { + ProcessResult::Error(CodeSelectionError( + ConstEvalFailure(ErrorHandled::TooGeneric) + )) } + } else { + pending_obligation.stalled_on = substs.types().collect(); + ProcessResult::Unchanged } } } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 8d17df1e61055..1ca92d79fa5f6 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -457,6 +457,16 @@ pub enum SelectionError<'tcx> { Overflow, } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for SelectionError<'tcx> { + (SelectionError::Unimplemented), + (SelectionError::OutputTypeParameterMismatch)(a, b, c), + (SelectionError::TraitNotObjectSafe)(a), + (SelectionError::ConstEvalFailure)(a), + (SelectionError::Overflow), + } +} + pub struct FulfillmentError<'tcx> { pub obligation: PredicateObligation<'tcx>, pub code: FulfillmentErrorCode<'tcx> @@ -782,13 +792,11 @@ fn do_normalize_predicates<'tcx>( return Err(ErrorReported) } }; - - match tcx.lift_to_global(&predicates) { - Some(predicates) => Ok(predicates), - None => { - // FIXME: shouldn't we, you know, actually report an error here? or an ICE? - Err(ErrorReported) - } + if predicates.has_local_value() { + // FIXME: shouldn't we, you know, actually report an error here? or an ICE? + Err(ErrorReported) + } else { + Ok(predicates) } }) } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index cfd5cfa897daf..37eff852abd01 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -702,6 +702,6 @@ impl<'tcx> TyCtxt<'tcx> { } } -pub(super) fn is_object_safe_provider<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> bool { +pub(super) fn is_object_safe_provider(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { tcx.object_safety_violations(trait_def_id).is_empty() } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 0f4b7aff82bce..20acf44340690 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -399,7 +399,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ConstValue::Unevaluated(def_id, substs) = constant.val { let tcx = self.selcx.tcx().global_tcx(); - if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { + let param_env = self.param_env; + if !param_env.has_local_value() { if substs.needs_infer() || substs.has_placeholders() { let identity_substs = InternalSubsts::identity_for_item(tcx, def_id); let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs); @@ -414,7 +415,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } } } else { - if let Some(substs) = self.tcx().lift_to_global(&substs) { + if !substs.has_local_value() { let instance = ty::Instance::resolve(tcx, param_env, def_id, substs); if let Some(instance) = instance { let cid = GlobalId { @@ -1508,8 +1509,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( /// /// Based on the "projection mode", this lookup may in fact only examine the /// topmost impl. See the comments for `Reveal` for more details. -fn assoc_ty_def<'cx, 'tcx>( - selcx: &SelectionContext<'cx, 'tcx>, +fn assoc_ty_def( + selcx: &SelectionContext<'_, '_>, impl_def_id: DefId, assoc_ty_def_id: DefId, ) -> specialization_graph::NodeItem { diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 5dd1b9e3d53f3..55e622e46b966 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -193,7 +193,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ConstValue::Unevaluated(def_id, substs) = constant.val { let tcx = self.infcx.tcx.global_tcx(); - if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { + let param_env = self.param_env; + if !param_env.has_local_value() { if substs.needs_infer() || substs.has_placeholders() { let identity_substs = InternalSubsts::identity_for_item(tcx, def_id); let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs); @@ -208,7 +209,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { } } } else { - if let Some(substs) = self.tcx().lift_to_global(&substs) { + if !substs.has_local_value() { let instance = ty::Instance::resolve(tcx, param_env, def_id, substs); if let Some(instance) = instance { let cid = GlobalId { diff --git a/src/librustc/traits/query/type_op/custom.rs b/src/librustc/traits/query/type_op/custom.rs index 72550e23460e6..a2a5f3f950c7a 100644 --- a/src/librustc/traits/query/type_op/custom.rs +++ b/src/librustc/traits/query/type_op/custom.rs @@ -3,7 +3,7 @@ use std::fmt; use crate::traits::query::Fallible; use crate::infer::canonical::query_response; -use crate::infer::canonical::QueryRegionConstraint; +use crate::infer::canonical::QueryRegionConstraints; use std::rc::Rc; use syntax::source_map::DUMMY_SP; use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt}; @@ -39,7 +39,7 @@ where fn fully_perform( self, infcx: &InferCtxt<'_, 'tcx>, - ) -> Fallible<(Self::Output, Option>>>)> { + ) -> Fallible<(Self::Output, Option>>)> { if cfg!(debug_assertions) { info!("fully_perform({:?})", self); } @@ -62,7 +62,7 @@ where fn scrape_region_constraints<'tcx, R>( infcx: &InferCtxt<'_, 'tcx>, op: impl FnOnce() -> Fallible>, -) -> Fallible<(R, Option>>>)> { +) -> Fallible<(R, Option>>)> { let mut fulfill_cx = TraitEngine::new(infcx.tcx); let dummy_body_id = ObligationCause::dummy().body_id; @@ -92,7 +92,7 @@ fn scrape_region_constraints<'tcx, R>( let region_constraint_data = infcx.take_and_reset_region_constraints(); - let outlives = query_response::make_query_outlives( + let region_constraints = query_response::make_query_region_constraints( infcx.tcx, region_obligations .iter() @@ -101,9 +101,9 @@ fn scrape_region_constraints<'tcx, R>( ®ion_constraint_data, ); - if outlives.is_empty() { + if region_constraints.is_empty() { Ok((value, None)) } else { - Ok((value, Some(Rc::new(outlives)))) + Ok((value, Some(Rc::new(region_constraints)))) } } diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index 4a07a3120f3e8..e2a5cd9670e0c 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -1,6 +1,6 @@ use crate::infer::canonical::{ Canonical, Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues, - QueryRegionConstraint, QueryResponse, + QueryRegionConstraints, QueryResponse, }; use crate::infer::{InferCtxt, InferOk}; use std::fmt; @@ -32,7 +32,7 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug { fn fully_perform( self, infcx: &InferCtxt<'_, 'tcx>, - ) -> Fallible<(Self::Output, Option>>>)>; + ) -> Fallible<(Self::Output, Option>>)>; } /// "Query type ops" are type ops that are implemented using a @@ -85,7 +85,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx { fn fully_perform_into( query_key: ParamEnvAnd<'tcx, Self>, infcx: &InferCtxt<'_, 'tcx>, - output_query_region_constraints: &mut Vec>, + output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> Fallible { if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) { return Ok(result); @@ -140,16 +140,16 @@ where fn fully_perform( self, infcx: &InferCtxt<'_, 'tcx>, - ) -> Fallible<(Self::Output, Option>>>)> { - let mut qrc = vec![]; - let r = Q::fully_perform_into(self, infcx, &mut qrc)?; + ) -> Fallible<(Self::Output, Option>>)> { + let mut region_constraints = QueryRegionConstraints::default(); + let r = Q::fully_perform_into(self, infcx, &mut region_constraints)?; // Promote the final query-region-constraints into a // (optional) ref-counted vector: - let opt_qrc = if qrc.is_empty() { + let opt_qrc = if region_constraints.is_empty() { None } else { - Some(Rc::new(qrc)) + Some(Rc::new(region_constraints)) }; Ok((r, opt_qrc)) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7c4742259ac16..798a25fe7b1bc 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -328,6 +328,23 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> { } } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for SelectionCandidate<'tcx> { + (SelectionCandidate::BuiltinCandidate) { has_nested }, + (SelectionCandidate::ParamCandidate)(poly_trait_ref), + (SelectionCandidate::ImplCandidate)(def_id), + (SelectionCandidate::AutoImplCandidate)(def_id), + (SelectionCandidate::ProjectionCandidate), + (SelectionCandidate::ClosureCandidate), + (SelectionCandidate::GeneratorCandidate), + (SelectionCandidate::FnPointerCandidate), + (SelectionCandidate::TraitAliasCandidate)(def_id), + (SelectionCandidate::ObjectCandidate), + (SelectionCandidate::BuiltinObjectCandidate), + (SelectionCandidate::BuiltinUnsizeCandidate), + } +} + struct SelectionCandidateSet<'tcx> { // a list of candidates that definitely apply to the current // obligation (meaning: types unify). @@ -818,27 +835,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Predicate::ConstEvaluatable(def_id, substs) => { let tcx = self.tcx(); - match tcx.lift_to_global(&(obligation.param_env, substs)) { - Some((param_env, substs)) => { - let instance = - ty::Instance::resolve(tcx.global_tcx(), param_env, def_id, substs); - if let Some(instance) = instance { - let cid = GlobalId { - instance, - promoted: None, - }; - match self.tcx().const_eval(param_env.and(cid)) { - Ok(_) => Ok(EvaluatedToOk), - Err(_) => Ok(EvaluatedToErr), - } - } else { - Ok(EvaluatedToErr) + if !(obligation.param_env, substs).has_local_value() { + let param_env = obligation.param_env; + let instance = + ty::Instance::resolve(tcx, param_env, def_id, substs); + if let Some(instance) = instance { + let cid = GlobalId { + instance, + promoted: None, + }; + match self.tcx().const_eval(param_env.and(cid)) { + Ok(_) => Ok(EvaluatedToOk), + Err(_) => Ok(EvaluatedToErr), } + } else { + Ok(EvaluatedToErr) } - None => { - // Inference variables still left in param_env or substs. - Ok(EvaluatedToAmbig) - } + } else { + // Inference variables still left in param_env or substs. + Ok(EvaluatedToAmbig) } } } @@ -1172,7 +1187,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if self.can_use_global_caches(param_env) { - if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) { + if !trait_ref.has_local_value() { debug!( "insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global", trait_ref, result, @@ -1645,8 +1660,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let Err(Overflow) = candidate { // Don't cache overflow globally; we only produce this // in certain modes. - } else if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) { - if let Some(candidate) = tcx.lift_to_global(&candidate) { + } else if !trait_ref.has_local_value() { + if !candidate.has_local_value() { debug!( "insert_candidate_cache(trait_ref={:?}, candidate={:?}) global", trait_ref, candidate, diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 43bb4edd9b27d..f0389bb037ac5 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -145,8 +145,8 @@ pub fn find_associated_item<'tcx>( /// Specialization is determined by the sets of types to which the impls apply; /// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies /// to. -pub(super) fn specializes<'tcx>( - tcx: TyCtxt<'tcx>, +pub(super) fn specializes( + tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId), ) -> bool { debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id); @@ -282,10 +282,10 @@ fn fulfill_implication<'a, 'tcx>( } // Query provider for `specialization_graph_of`. -pub(super) fn specialization_graph_provider<'tcx>( - tcx: TyCtxt<'tcx>, +pub(super) fn specialization_graph_provider( + tcx: TyCtxt<'_>, trait_id: DefId, -) -> &'tcx specialization_graph::Graph { +) -> &specialization_graph::Graph { let mut sg = specialization_graph::Graph::new(); let mut trait_impls = tcx.all_impls(trait_id); diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 2d295679be324..07d6f633143a2 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -417,7 +417,7 @@ pub struct SupertraitDefIds<'tcx> { visited: FxHashSet, } -pub fn supertrait_def_ids<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> SupertraitDefIds<'tcx> { +pub fn supertrait_def_ids(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SupertraitDefIds<'_> { SupertraitDefIds { tcx, stack: vec![trait_def_id], diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs index 999b4eff85697..3dd1fd100f2a4 100644 --- a/src/librustc/ty/erase_regions.rs +++ b/src/librustc/ty/erase_regions.rs @@ -42,10 +42,10 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let Some(ty_lifted) = self.tcx.lift_to_global(&ty) { - self.tcx.erase_regions_ty(ty_lifted) - } else { + if ty.has_local_value() { ty.super_fold_with(self) + } else { + self.tcx.erase_regions_ty(ty) } } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 8b98a2916a766..ab7df8e4e845b 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -91,6 +91,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn has_infer_types(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_INFER) } + fn has_local_value(&self) -> bool { + self.has_type_flags(TypeFlags::KEEP_IN_LOCAL_TCX) + } fn needs_infer(&self) -> bool { self.has_type_flags( TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER @@ -922,6 +925,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { } } +// FIXME: Optimize for checking for infer flags struct HasTypeFlagsVisitor { flags: ty::TypeFlags, } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 13d93f173e845..b921272856e28 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -1,5 +1,5 @@ use crate::dep_graph::SerializedDepNodeIndex; -use crate::dep_graph::DepNode; +use crate::dep_graph::{DepKind, DepNode}; use crate::hir::def_id::{CrateNum, DefId}; use crate::ty::TyCtxt; use crate::ty::query::queries; @@ -28,6 +28,9 @@ pub trait QueryConfig<'tcx> { } pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { + const ANON: bool; + const EVAL_ALWAYS: bool; + fn query(key: Self::Key) -> Query<'tcx>; // Don't use this method to access query results, instead use the methods on TyCtxt @@ -35,6 +38,8 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode; + fn dep_kind() -> DepKind; + // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value; @@ -50,7 +55,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { fn describe(tcx: TyCtxt<'_>, key: Self::Key) -> Cow<'static, str>; #[inline] - fn cache_on_disk(_: TyCtxt<'tcx>, _: Self::Key) -> bool { + fn cache_on_disk(_: TyCtxt<'tcx>, _: Self::Key, _: Option<&Self::Value>) -> bool { false } @@ -75,33 +80,3 @@ impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> { "running analysis passes on this crate".into() } } - -macro_rules! impl_disk_cacheable_query( - ($query_name:ident, |$tcx:tt, $key:tt| $cond:expr) => { - impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { - #[inline] - fn cache_on_disk($tcx: TyCtxt<'tcx>, $key: Self::Key) -> bool { - $cond - } - - #[inline] - fn try_load_from_disk(tcx: TyCtxt<'tcx>, - id: SerializedDepNodeIndex) - -> Option { - tcx.queries.on_disk_cache.try_load_query_result(tcx, id) - } - } - } -); - -impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| { - def_id.is_local() && tcx.is_closure(def_id) -}); - -impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true); -impl_disk_cacheable_query!(specialization_graph_of, |_, _| true); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index e595b52876f4c..e788628bc58e2 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -101,6 +101,6 @@ pub use self::on_disk_cache::OnDiskCache; rustc_query_append! { [define_queries!][ <'tcx> Other { /// Runs analysis passes on the crate. - [] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>, + [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>, }, ]} diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 982886f0f1573..85153f99b1917 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -221,26 +221,8 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; - - // const eval is special, it only encodes successfully evaluated constants - use crate::ty::query::QueryAccessors; - let cache = const_eval::query_cache(tcx).borrow(); - assert!(cache.active.is_empty()); - for (key, entry) in cache.results.iter() { - use crate::ty::query::config::QueryDescription; - if const_eval::cache_on_disk(tcx, key.clone()) { - if let Ok(ref value) = entry.value { - let dep_node = SerializedDepNodeIndex::new(entry.index.index()); - - // Record position of the cache entry - qri.push((dep_node, AbsoluteBytePos::new(enc.position()))); - - // Encode the type check tables with the SerializedDepNodeIndex - // as tag. - enc.encode_tagged(dep_node, value)?; - } - } - } + encode_query_results::, _>(tcx, enc, qri)?; + // FIXME: Include const_eval_raw? Ok(()) })?; @@ -324,9 +306,9 @@ impl<'sess> OnDiskCache<'sess> { } /// Loads a diagnostic emitted during the previous compilation session. - pub fn load_diagnostics<'tcx>( + pub fn load_diagnostics( &self, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, ) -> Vec { let diagnostics: Option = self.load_indexed( @@ -353,9 +335,9 @@ impl<'sess> OnDiskCache<'sess> { /// Returns the cached query result if there is something in the cache for /// the given `SerializedDepNodeIndex`; otherwise returns `None`. - pub fn try_load_query_result<'tcx, T>( + pub fn try_load_query_result( &self, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, ) -> Option where @@ -1090,7 +1072,7 @@ where let map = Q::query_cache(tcx).borrow(); assert!(map.active.is_empty()); for (key, entry) in map.results.iter() { - if Q::cache_on_disk(tcx, key.clone()) { + if Q::cache_on_disk(tcx, key.clone(), Some(&entry.value)) { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); // Record position of the cache entry diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 7d5f984c1b6f2..0c9e31e1ff28e 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -376,15 +376,13 @@ impl<'tcx> TyCtxt<'tcx> { return self.force_query_with_job::(key, job, null_dep_node).0; } - let dep_node = Q::to_dep_node(self, &key); - - if dep_node.kind.is_anon() { + if Q::ANON { profq_msg!(self, ProfileQueriesMsg::ProviderBegin); self.sess.profiler(|p| p.start_query(Q::NAME)); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { - tcx.dep_graph.with_anon_task(dep_node.kind, || { + tcx.dep_graph.with_anon_task(Q::dep_kind(), || { Q::compute(tcx.global_tcx(), key) }) }) @@ -405,7 +403,9 @@ impl<'tcx> TyCtxt<'tcx> { return result; } - if !dep_node.kind.is_eval_always() { + let dep_node = Q::to_dep_node(self, &key); + + if !Q::EVAL_ALWAYS { // The diagnostics for this query will be // promoted to the current session during // try_mark_green(), so we can ignore them here. @@ -444,7 +444,7 @@ impl<'tcx> TyCtxt<'tcx> { debug_assert!(self.dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache - let result = if Q::cache_on_disk(self.global_tcx(), key.clone()) && + let result = if Q::cache_on_disk(self.global_tcx(), key.clone(), None) && self.sess.opts.debugging_opts.incremental_queries { self.sess.profiler(|p| p.incremental_load_result_start(Q::NAME)); let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index); @@ -546,7 +546,7 @@ impl<'tcx> TyCtxt<'tcx> { let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { - if dep_node.kind.is_eval_always() { + if Q::EVAL_ALWAYS { tcx.dep_graph.with_eval_always_task(dep_node, tcx, key, @@ -569,8 +569,8 @@ impl<'tcx> TyCtxt<'tcx> { self.dep_graph.mark_loaded_from_cache(dep_node_index, false); } - if dep_node.kind != crate::dep_graph::DepKind::Null { - if unlikely!(!diagnostics.is_empty()) { + if unlikely!(!diagnostics.is_empty()) { + if dep_node.kind != crate::dep_graph::DepKind::Null { self.queries.on_disk_cache .store_diagnostics(dep_node_index, diagnostics); } @@ -589,15 +589,16 @@ impl<'tcx> TyCtxt<'tcx> { /// /// Note: The optimization is only available during incr. comp. pub(super) fn ensure_query>(self, key: Q::Key) -> () { - let dep_node = Q::to_dep_node(self, &key); - - if dep_node.kind.is_eval_always() { + if Q::EVAL_ALWAYS { let _ = self.get_query::(DUMMY_SP, key); return; } // Ensuring an anonymous query makes no sense - assert!(!dep_node.kind.is_anon()); + assert!(!Q::ANON); + + let dep_node = Q::to_dep_node(self, &key); + if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() { // A None return from `try_mark_green_and_read` means that this is either // a new dep node or that the dep node has already been marked red. @@ -653,6 +654,30 @@ macro_rules! handle_cycle_error { }; } +macro_rules! is_anon { + ([]) => {{ + false + }}; + ([anon$(, $modifiers:ident)*]) => {{ + true + }}; + ([$other:ident$(, $modifiers:ident)*]) => { + is_anon!([$($modifiers),*]) + }; +} + +macro_rules! is_eval_always { + ([]) => {{ + false + }}; + ([eval_always$(, $modifiers:ident)*]) => {{ + true + }}; + ([$other:ident$(, $modifiers:ident)*]) => { + is_eval_always!([$($modifiers),*]) + }; +} + macro_rules! hash_result { ([][$hcx:expr, $result:expr]) => {{ dep_graph::hash_result($hcx, &$result) @@ -933,6 +958,9 @@ macro_rules! define_queries_inner { } impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> { + const ANON: bool = is_anon!([$($modifiers)*]); + const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]); + #[inline(always)] fn query(key: Self::Key) -> Query<'tcx> { Query::$name(key) @@ -951,6 +979,11 @@ macro_rules! define_queries_inner { DepNode::new(tcx, $node(*key)) } + #[inline(always)] + fn dep_kind() -> dep_graph::DepKind { + dep_graph::DepKind::$node + } + #[inline] fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { __query_compute::$name(move || { @@ -1133,7 +1166,7 @@ macro_rules! define_provider_struct { /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just /// add it to the "We don't have enough information to reconstruct..." group in /// the match below. -pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool { +pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { use crate::dep_graph::RecoverKey; // We must avoid ever having to call force_from_dep_node() for a @@ -1210,66 +1243,3 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool true } - - -// FIXME(#45015): Another piece of boilerplate code that could be generated in -// a combined define_dep_nodes!()/define_queries!() macro. -macro_rules! impl_load_from_cache { - ($($dep_kind:ident => $query_name:ident,)*) => { - impl DepNode { - // Check whether the query invocation corresponding to the given - // DepNode is eligible for on-disk-caching. - pub fn cache_on_disk(&self, tcx: TyCtxt<'_>) -> bool { - use crate::ty::query::queries; - use crate::ty::query::QueryDescription; - - match self.kind { - $(DepKind::$dep_kind => { - let def_id = self.extract_def_id(tcx).unwrap(); - queries::$query_name::cache_on_disk(tcx.global_tcx(), def_id) - })* - _ => false - } - } - - // This is method will execute the query corresponding to the given - // DepNode. It is only expected to work for DepNodes where the - // above `cache_on_disk` methods returns true. - // Also, as a sanity check, it expects that the corresponding query - // invocation has been marked as green already. - pub fn load_from_on_disk_cache(&self, tcx: TyCtxt<'_>) { - match self.kind { - $(DepKind::$dep_kind => { - debug_assert!(tcx.dep_graph - .node_color(self) - .map(|c| c.is_green()) - .unwrap_or(false)); - - let def_id = self.extract_def_id(tcx).unwrap(); - let _ = tcx.$query_name(def_id); - })* - _ => { - bug!() - } - } - } - } - } -} - -impl_load_from_cache!( - typeck_tables_of => typeck_tables_of, - optimized_mir => optimized_mir, - unsafety_check_result => unsafety_check_result, - borrowck => borrowck, - mir_borrowck => mir_borrowck, - mir_const_qualif => mir_const_qualif, - const_is_rvalue_promotable_to_static => const_is_rvalue_promotable_to_static, - check_match => check_match, - type_of => type_of, - generics_of => generics_of, - predicates_of => predicates_of, - used_trait_imports => used_trait_imports, - codegen_fn_attrs => codegen_fn_attrs, - specialization_graph_of => specialization_graph_of, -); diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 46adb7eb2a476..a6bfc2dee613b 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -550,7 +550,7 @@ pub fn super_relate_consts>( if let ConstValue::Unevaluated(def_id, substs) = x.val { // FIXME(eddyb) get the right param_env. let param_env = ty::ParamEnv::empty(); - if let Some(substs) = tcx.lift_to_global(&substs) { + if !substs.has_local_value() { let instance = ty::Instance::resolve( tcx.global_tcx(), param_env, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 3d8170586c47f..28b52dcea80f1 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -15,6 +15,7 @@ use crate::mir::interpret; use std::fmt; use std::rc::Rc; +use std::sync::Arc; impl fmt::Debug for ty::GenericParamDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -348,7 +349,7 @@ impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) tcx.lift(&self.0).and_then(|a| { tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c))) }) - } + } } impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option { @@ -378,6 +379,20 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box { } } +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc { + type Lifted = Rc; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(&**self).map(Rc::new) + } +} + +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Arc { + type Lifted = Arc; + fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(&**self).map(Arc::new) + } +} + impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] { type Lifted = Vec; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { @@ -821,6 +836,13 @@ EnumTypeFoldableImpl! { } where T: TypeFoldable<'tcx> } +EnumTypeFoldableImpl! { + impl<'tcx, T, E> TypeFoldable<'tcx> for Result { + (Ok)(a), + (Err)(a), + } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>, +} + impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { fn super_fold_with>(&self, folder: &mut F) -> Self { Rc::new((**self).fold_with(folder)) @@ -831,6 +853,16 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { } } +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { + fn super_fold_with>(&self, folder: &mut F) -> Self { + Arc::new((**self).fold_with(folder)) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + (**self).visit_with(visitor) + } +} + impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { fn super_fold_with>(&self, folder: &mut F) -> Self { let content: T = (**self).fold_with(folder); diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 714b7c27200e3..a098cd1761236 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -354,7 +354,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { cmt: &mc::cmt_<'tcx>, loan_region: ty::Region<'tcx>, borrow_span: Span) { - pub fn borrow_of_local_data<'tcx>(cmt: &mc::cmt_<'tcx>) -> bool { + pub fn borrow_of_local_data(cmt: &mc::cmt_<'_>) -> bool { match cmt.cat { // Borrows of static items is allowed Categorization::StaticItem => false, diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 3c7f19f7fbf4f..8763a6bc066b3 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -53,7 +53,7 @@ pub struct LoanDataFlowOperator; pub type LoanDataFlow<'tcx> = DataFlowContext<'tcx, LoanDataFlowOperator>; -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_crate(tcx: TyCtxt<'_>) { tcx.par_body_owners(|body_owner_def_id| { tcx.ensure().borrowck(body_owner_def_id); }); @@ -73,7 +73,7 @@ pub struct AnalysisData<'tcx> { pub move_data: move_data::FlowedMoveData<'tcx>, } -fn borrowck<'tcx>(tcx: TyCtxt<'tcx>, owner_def_id: DefId) -> &'tcx BorrowCheckResult { +fn borrowck(tcx: TyCtxt<'_>, owner_def_id: DefId) -> &BorrowCheckResult { assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck()); debug!("borrowck(body_owner_def_id={:?})", owner_def_id); diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs index f5d311b35d738..dc7014d22ec4d 100644 --- a/src/librustc_borrowck/dataflow.rs +++ b/src/librustc_borrowck/dataflow.rs @@ -84,9 +84,9 @@ struct PropagationContext<'a, 'tcx, O> { changed: bool, } -fn get_cfg_indices<'a>(id: hir::ItemLocalId, - index: &'a FxHashMap>) - -> &'a [CFGIndex] { +fn get_cfg_indices(id: hir::ItemLocalId, + index: &FxHashMap>) + -> &[CFGIndex] { index.get(&id).map_or(&[], |v| &v[..]) } diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 4735588f29a02..94abf1796d366 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -102,8 +102,8 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { return } - // probestack doesn't play nice either with pgo-gen. - if cx.sess().opts.debugging_opts.pgo_gen.enabled() { + // probestack doesn't play nice either with `-C profile-generate`. + if cx.sess().opts.cg.profile_generate.enabled() { return; } diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index e0e26e9af2537..ca3b2b84655e2 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -205,8 +205,8 @@ impl<'a> LlvmArchiveBuilder<'a> { } fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> { - let removals = mem::replace(&mut self.removals, Vec::new()); - let mut additions = mem::replace(&mut self.additions, Vec::new()); + let removals = mem::take(&mut self.removals); + let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); let mut members = Vec::new(); diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 3638730707f3f..b135605cf02d7 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -239,9 +239,9 @@ impl<'a> Drop for DiagnosticHandlers<'a> { } } -unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext, - msg: &'b str, - cookie: c_uint) { +unsafe extern "C" fn report_inline_asm(cgcx: &CodegenContext, + msg: &str, + cookie: c_uint) { cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned()); } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 04645dacfec58..21c19e167cfbe 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -123,8 +123,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'tcx>, cgu_name: InternedString) { submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tcx, module, cost); - fn module_codegen<'tcx>( - tcx: TyCtxt<'tcx>, + fn module_codegen( + tcx: TyCtxt<'_>, cgu_name: InternedString, ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 0709368ad860e..f67c740b77748 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -144,7 +144,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn build_sibling_block<'b>(&self, name: &'b str) -> Self { + fn build_sibling_block(&self, name: &str) -> Self { Builder::new_block(self.cx, self.llfn(), name) } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7283aa95b3027..ca63e589a6f95 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -21,6 +21,7 @@ #![feature(link_args)] #![feature(static_nobundle)] #![feature(trusted_len)] +#![feature(mem_take)] #![deny(rust_2018_idioms)] #![deny(internal)] #![deny(unused_lifetimes)] @@ -124,7 +125,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend { ) { unsafe { allocator::codegen(tcx, mods, kind) } } - fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: InternedString) { + fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: InternedString) { base::compile_codegen_unit(tcx, cgu_name); } fn target_machine_factory( diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs index 78570cce57dd9..d610805b5bbd0 100644 --- a/src/librustc_codegen_ssa/back/command.rs +++ b/src/librustc_codegen_ssa/back/command.rs @@ -110,7 +110,7 @@ impl Command { } pub fn take_args(&mut self) -> Vec { - mem::replace(&mut self.args, Vec::new()) + mem::take(&mut self.args) } /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits, diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 618e8b8699fcc..707b7cae16ce7 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -653,10 +653,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, linker_error.emit(); if sess.target.target.options.is_like_msvc && linker_not_found { - sess.note_without_error("the msvc targets depend on the msvc linker \ - but `link.exe` was not found"); - sess.note_without_error("please ensure that VS 2013, VS 2015 or VS 2017 \ - was installed with the Visual C++ option"); + sess.note_without_error( + "the msvc targets depend on the msvc linker \ + but `link.exe` was not found", + ); + sess.note_without_error( + "please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 \ + was installed with the Visual C++ option", + ); } sess.abort_if_errors(); } @@ -1179,7 +1183,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, cmd.build_static_executable(); } - if sess.opts.debugging_opts.pgo_gen.enabled() { + if sess.opts.cg.profile_generate.enabled() { cmd.pgo_gen(); } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index b9ee82f108ae3..b64c9a60d9713 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -46,10 +46,10 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExpor } } -fn reachable_non_generics_provider<'tcx>( - tcx: TyCtxt<'tcx>, +fn reachable_non_generics_provider( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> &'tcx DefIdMap { +) -> &DefIdMap { assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { @@ -157,7 +157,7 @@ fn reachable_non_generics_provider<'tcx>( tcx.arena.alloc(reachable_non_generics) } -fn is_reachable_non_generic_provider_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_reachable_non_generic_provider_local(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let export_threshold = threshold(tcx); if let Some(&level) = tcx.reachable_non_generics(def_id.krate).get(&def_id) { @@ -167,14 +167,14 @@ fn is_reachable_non_generic_provider_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefI } } -fn is_reachable_non_generic_provider_extern<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.reachable_non_generics(def_id.krate).contains_key(&def_id) } -fn exported_symbols_provider_local<'tcx>( - tcx: TyCtxt<'tcx>, +fn exported_symbols_provider_local( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> Arc, SymbolExportLevel)>> { +) -> Arc, SymbolExportLevel)>> { assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { @@ -203,7 +203,7 @@ fn exported_symbols_provider_local<'tcx>( } } - if tcx.sess.opts.debugging_opts.pgo_gen.enabled() { + if tcx.sess.opts.cg.profile_generate.enabled() { // These are weak symbols that point to the profile version and the // profile name, which need to be treated as exported so LTO doesn't nix // them. @@ -273,10 +273,10 @@ fn exported_symbols_provider_local<'tcx>( Arc::new(symbols) } -fn upstream_monomorphizations_provider<'tcx>( - tcx: TyCtxt<'tcx>, +fn upstream_monomorphizations_provider( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> &'tcx DefIdMap, CrateNum>> { +) -> &DefIdMap, CrateNum>> { debug_assert!(cnum == LOCAL_CRATE); let cnums = tcx.all_crate_nums(LOCAL_CRATE); @@ -322,10 +322,10 @@ fn upstream_monomorphizations_provider<'tcx>( tcx.arena.alloc(instances) } -fn upstream_monomorphizations_for_provider<'tcx>( - tcx: TyCtxt<'tcx>, +fn upstream_monomorphizations_for_provider( + tcx: TyCtxt<'_>, def_id: DefId, -) -> Option<&'tcx FxHashMap, CrateNum>> { +) -> Option<&FxHashMap, CrateNum>> { debug_assert!(!def_id.is_local()); tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id) } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 309187ca2eaa3..fbf57701c5a95 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -423,8 +423,8 @@ pub fn start_async_codegen( modules_config.passes.push("insert-gcov-profiling".to_owned()) } - modules_config.pgo_gen = sess.opts.debugging_opts.pgo_gen.clone(); - modules_config.pgo_use = sess.opts.debugging_opts.pgo_use.clone(); + modules_config.pgo_gen = sess.opts.cg.profile_generate.clone(); + modules_config.pgo_use = sess.opts.cg.profile_use.clone(); modules_config.opt_level = Some(sess.opts.optimize); modules_config.opt_size = Some(sess.opts.optimize); @@ -1345,12 +1345,9 @@ fn start_executing_work( assert!(!started_lto); started_lto = true; - let needs_fat_lto = - mem::replace(&mut needs_fat_lto, Vec::new()); - let needs_thin_lto = - mem::replace(&mut needs_thin_lto, Vec::new()); - let import_only_modules = - mem::replace(&mut lto_import_only_modules, Vec::new()); + let needs_fat_lto = mem::take(&mut needs_fat_lto); + let needs_thin_lto = mem::take(&mut needs_thin_lto); + let import_only_modules = mem::take(&mut lto_import_only_modules); for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) { diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 47b383fddbc31..d06460fc85696 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -700,7 +700,7 @@ impl Drop for AbortCodegenOnDrop { } } -fn assert_and_save_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) { +fn assert_and_save_dep_graph(tcx: TyCtxt<'_>) { time(tcx.sess, "assert dep graph", || ::rustc_incremental::assert_dep_graph(tcx)); diff --git a/src/librustc_codegen_ssa/debuginfo/mod.rs b/src/librustc_codegen_ssa/debuginfo/mod.rs index d60a2e0cb1358..c9b1c0260e8c3 100644 --- a/src/librustc_codegen_ssa/debuginfo/mod.rs +++ b/src/librustc_codegen_ssa/debuginfo/mod.rs @@ -10,7 +10,7 @@ pub enum FunctionDebugContext { } impl FunctionDebugContext { - pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData { + pub fn get_ref(&self, span: Span) -> &FunctionDebugContextData { match *self { FunctionDebugContext::RegularContext(ref data) => data, FunctionDebugContext::DebugInfoDisabled => { diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index b76f098773f0b..3c1ab600040a1 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -10,6 +10,7 @@ #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(trusted_len)] +#![feature(mem_take)] #![allow(unused_attributes)] #![allow(dead_code)] #![deny(rust_2018_idioms)] diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 0289150a5e42a..2af9b448ef1eb 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -273,7 +273,7 @@ impl CleanupKind { } } -pub fn cleanup_kinds<'tcx>(mir: &mir::Body<'tcx>) -> IndexVec { +pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec { fn discover_masters<'tcx>(result: &mut IndexVec, mir: &mir::Body<'tcx>) { for (bb, data) in mir.basic_blocks().iter_enumerated() { diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 414871be6116e..9d5aaa7655db8 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -44,7 +44,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se mods: &mut Self::Module, kind: AllocatorKind, ); - fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: InternedString); + fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: InternedString); // If find_features is true this won't access `sess.crate_types` by assuming // that `is_pie_binary` is false. When we discover LLVM target features // `sess.crate_types` is uninitialized so we cannot access it. diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 1c80e614db8d5..3a144f0b0e0aa 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -36,7 +36,7 @@ pub trait BuilderMethods<'a, 'tcx>: { fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self; - fn build_sibling_block<'b>(&self, name: &'b str) -> Self; + fn build_sibling_block(&self, name: &str) -> Self; fn cx(&self) -> &Self::CodegenCx; fn llbb(&self) -> Self::BasicBlock; diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index f48d1f2853c52..7ab29c5c4c3d0 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -11,7 +11,7 @@ use syntax::symbol::{Symbol, sym}; const SYMBOL_NAME: Symbol = sym::rustc_symbol_name; const DEF_PATH: Symbol = sym::rustc_def_path; -pub fn report_symbol_names<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn report_symbol_names(tcx: TyCtxt<'_>) { // if the `rustc_attrs` feature is not enabled, then the // attributes we are interested in cannot be present anyway, so // skip the walk. diff --git a/src/librustc_data_structures/binary_search_util/mod.rs b/src/librustc_data_structures/binary_search_util/mod.rs new file mode 100644 index 0000000000000..32aa1cb6b1d36 --- /dev/null +++ b/src/librustc_data_structures/binary_search_util/mod.rs @@ -0,0 +1,49 @@ +#[cfg(test)] +mod test; + +/// Uses a sorted slice `data: &[E]` as a kind of "multi-map". The +/// `key_fn` extracts a key of type `K` from the data, and this +/// function finds the range of elements that match the key. `data` +/// must have been sorted as if by a call to `sort_by_key` for this to +/// work. +pub fn binary_search_slice(data: &'d [E], key_fn: impl Fn(&E) -> K, key: &K) -> &'d [E] +where + K: Ord, +{ + let mid = match data.binary_search_by_key(key, &key_fn) { + Ok(mid) => mid, + Err(_) => return &[], + }; + + // We get back *some* element with the given key -- so + // search backwards to find the *first* one. + // + // (It'd be more efficient to use a "galloping" search + // here, but it's not really worth it for small-ish + // amounts of data.) + let mut start = mid; + while start > 0 { + if key_fn(&data[start - 1]) == *key { + start -= 1; + } else { + break; + } + } + + // Now search forward to find the *last* one. + // + // (It'd be more efficient to use a "galloping" search + // here, but it's not really worth it for small-ish + // amounts of data.) + let mut end = mid + 1; + let max = data.len(); + while end < max { + if key_fn(&data[end]) == *key { + end += 1; + } else { + break; + } + } + + &data[start..end] +} diff --git a/src/librustc_data_structures/binary_search_util/test.rs b/src/librustc_data_structures/binary_search_util/test.rs new file mode 100644 index 0000000000000..d74febb5c0fc4 --- /dev/null +++ b/src/librustc_data_structures/binary_search_util/test.rs @@ -0,0 +1,23 @@ +use super::*; + +type Element = (usize, &'static str); + +fn test_map() -> Vec { + let mut data = vec![(3, "three-a"), (0, "zero"), (3, "three-b"), (22, "twenty-two")]; + data.sort_by_key(get_key); + data +} + +fn get_key(data: &Element) -> usize { + data.0 +} + +#[test] +fn binary_search_slice_test() { + let map = test_map(); + assert_eq!(binary_search_slice(&map, get_key, &0), &[(0, "zero")]); + assert_eq!(binary_search_slice(&map, get_key, &1), &[]); + assert_eq!(binary_search_slice(&map, get_key, &3), &[(3, "three-a"), (3, "three-b")]); + assert_eq!(binary_search_slice(&map, get_key, &22), &[(22, "twenty-two")]); + assert_eq!(binary_search_slice(&map, get_key, &23), &[]); +} diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index 5d8388d89f5b3..1eb28bccbe382 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -168,7 +168,7 @@ impl BitSet { /// Iterates over the indices of set bits in a sorted order. #[inline] - pub fn iter<'a>(&'a self) -> BitIter<'a, T> { + pub fn iter(&self) -> BitIter<'_, T> { BitIter { cur: None, iter: self.words.iter().enumerate(), @@ -849,7 +849,7 @@ impl BitMatrix { /// Iterates through all the columns set to true in a given row of /// the matrix. - pub fn iter<'a>(&'a self, row: R) -> BitIter<'a, C> { + pub fn iter(&self, row: R) -> BitIter<'_, C> { assert!(row.index() < self.num_rows); let (start, end) = self.range(row); BitIter { diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index 7975c62b90fb6..3bea965ef3041 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -58,7 +58,7 @@ impl Fingerprint { Ok(()) } - pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result { + pub fn decode_opaque(decoder: &mut Decoder<'_>) -> Result { let mut bytes = [0; 16]; decoder.read_raw_bytes(&mut bytes)?; diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/src/librustc_data_structures/graph/implementation/mod.rs index de4b1bcd0c2a1..d2699004c81d8 100644 --- a/src/librustc_data_structures/graph/implementation/mod.rs +++ b/src/librustc_data_structures/graph/implementation/mod.rs @@ -247,11 +247,11 @@ impl Graph { self.incoming_edges(target).sources() } - pub fn depth_traverse<'a>( - &'a self, + pub fn depth_traverse( + &self, start: NodeIndex, direction: Direction, - ) -> DepthFirstTraversal<'a, N, E> { + ) -> DepthFirstTraversal<'_, N, E> { DepthFirstTraversal::with_start_node(self, start, direction) } diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs index c09364b0a5395..5612778ce07ed 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/src/librustc_data_structures/graph/iterate/mod.rs @@ -1,5 +1,6 @@ use super::super::indexed_vec::IndexVec; -use super::{DirectedGraph, WithSuccessors, WithNumNodes}; +use super::{DirectedGraph, WithNumNodes, WithSuccessors}; +use crate::bit_set::BitSet; #[cfg(test)] mod test; @@ -51,3 +52,36 @@ pub fn reverse_post_order( vec.reverse(); vec } + +/// A "depth-first search" iterator for a directed graph. +pub struct DepthFirstSearch<'graph, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, +{ + graph: &'graph G, + stack: Vec, + visited: BitSet, +} + +impl DepthFirstSearch<'graph, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, +{ + pub fn new(graph: &'graph G, start_node: G::Node) -> Self { + Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) } + } +} + +impl Iterator for DepthFirstSearch<'_, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, +{ + type Item = G::Node; + + fn next(&mut self) -> Option { + let DepthFirstSearch { stack, visited, graph } = self; + let n = stack.pop()?; + stack.extend(graph.successors(n).filter(|&m| visited.insert(m))); + Some(n) + } +} diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 3d47b7d49fb96..e59085a9e3a95 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -5,6 +5,7 @@ pub mod implementation; pub mod iterate; mod reference; pub mod scc; +pub mod vec_graph; #[cfg(test)] mod test; @@ -17,14 +18,25 @@ pub trait WithNumNodes: DirectedGraph { fn num_nodes(&self) -> usize; } +pub trait WithNumEdges: DirectedGraph { + fn num_edges(&self) -> usize; +} + pub trait WithSuccessors: DirectedGraph where Self: for<'graph> GraphSuccessors<'graph, Item = ::Node>, { - fn successors<'graph>( - &'graph self, + fn successors( + &self, node: Self::Node, - ) -> >::Iter; + ) -> >::Iter; + + fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_, Self> + where + Self: WithNumNodes, + { + iterate::DepthFirstSearch::new(self, from) + } } pub trait GraphSuccessors<'graph> { @@ -36,10 +48,10 @@ pub trait WithPredecessors: DirectedGraph where Self: for<'graph> GraphPredecessors<'graph, Item = ::Node>, { - fn predecessors<'graph>( - &'graph self, + fn predecessors( + &self, node: Self::Node, - ) -> >::Iter; + ) -> >::Iter; } pub trait GraphPredecessors<'graph> { diff --git a/src/librustc_data_structures/graph/reference.rs b/src/librustc_data_structures/graph/reference.rs index 5ad2a71e1d732..9442bb3cdec3b 100644 --- a/src/librustc_data_structures/graph/reference.rs +++ b/src/librustc_data_structures/graph/reference.rs @@ -17,15 +17,15 @@ impl<'graph, G: WithStartNode> WithStartNode for &'graph G { } impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G { - fn successors<'iter>(&'iter self, node: Self::Node) -> >::Iter { + fn successors(&self, node: Self::Node) -> >::Iter { (**self).successors(node) } } impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G { - fn predecessors<'iter>(&'iter self, - node: Self::Node) - -> >::Iter { + fn predecessors(&self, + node: Self::Node) + -> >::Iter { (**self).predecessors(node) } } diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs index 24c5448639e7d..78554cda77b44 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/src/librustc_data_structures/graph/scc/mod.rs @@ -4,7 +4,8 @@ //! O(n) time. use crate::fx::FxHashSet; -use crate::graph::{DirectedGraph, WithNumNodes, WithSuccessors}; +use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; +use crate::graph::vec_graph::VecGraph; use crate::indexed_vec::{Idx, IndexVec}; use std::ops::Range; @@ -58,6 +59,49 @@ impl Sccs { pub fn successors(&self, scc: S) -> &[S] { self.scc_data.successors(scc) } + + /// Construct the reverse graph of the SCC graph. + pub fn reverse(&self) -> VecGraph { + VecGraph::new( + self.num_sccs(), + self.all_sccs() + .flat_map(|source| self.successors(source).iter().map(move |&target| { + (target, source) + })) + .collect(), + ) + } +} + +impl DirectedGraph for Sccs { + type Node = S; +} + +impl WithNumNodes for Sccs { + fn num_nodes(&self) -> usize { + self.num_sccs() + } +} + +impl WithNumEdges for Sccs { + fn num_edges(&self) -> usize { + self.scc_data.all_successors.len() + } +} + +impl GraphSuccessors<'graph> for Sccs { + type Item = S; + + type Iter = std::iter::Cloned>; +} + +impl WithSuccessors for Sccs { + fn successors<'graph>( + &'graph self, + node: S + ) -> >::Iter { + self.successors(node).iter().cloned() + } } impl SccData { diff --git a/src/librustc_data_structures/graph/test.rs b/src/librustc_data_structures/graph/test.rs index b390c41957294..bc142144e930f 100644 --- a/src/librustc_data_structures/graph/test.rs +++ b/src/librustc_data_structures/graph/test.rs @@ -51,15 +51,15 @@ impl WithNumNodes for TestGraph { } impl WithPredecessors for TestGraph { - fn predecessors<'graph>(&'graph self, - node: usize) - -> >::Iter { + fn predecessors(&self, + node: usize) + -> >::Iter { self.predecessors[&node].iter().cloned() } } impl WithSuccessors for TestGraph { - fn successors<'graph>(&'graph self, node: usize) -> >::Iter { + fn successors(&self, node: usize) -> >::Iter { self.successors[&node].iter().cloned() } } diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/src/librustc_data_structures/graph/vec_graph/mod.rs new file mode 100644 index 0000000000000..6fb1bb42d2cfd --- /dev/null +++ b/src/librustc_data_structures/graph/vec_graph/mod.rs @@ -0,0 +1,113 @@ +use crate::indexed_vec::{Idx, IndexVec}; +use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; + +#[cfg(test)] +mod test; + +pub struct VecGraph { + /// Maps from a given node to an index where the set of successors + /// for that node starts. The index indexes into the `edges` + /// vector. To find the range for a given node, we look up the + /// start for that node and then the start for the next node + /// (i.e., with an index 1 higher) and get the range between the + /// two. This vector always has an extra entry so that this works + /// even for the max element. + node_starts: IndexVec, + + edge_targets: Vec, +} + +impl VecGraph { + pub fn new( + num_nodes: usize, + mut edge_pairs: Vec<(N, N)>, + ) -> Self { + // Sort the edges by the source -- this is important. + edge_pairs.sort(); + + let num_edges = edge_pairs.len(); + + // Store the *target* of each edge into `edge_targets`. + let edge_targets: Vec = edge_pairs.iter().map(|&(_, target)| target).collect(); + + // Create the *edge starts* array. We are iterating over over + // the (sorted) edge pairs. We maintain the invariant that the + // length of the `node_starts` arary is enough to store the + // current source node -- so when we see that the source node + // for an edge is greater than the current length, we grow the + // edge-starts array by just enough. + let mut node_starts = IndexVec::with_capacity(num_edges); + for (index, &(source, _)) in edge_pairs.iter().enumerate() { + // If we have a list like `[(0, x), (2, y)]`: + // + // - Start out with `node_starts` of `[]` + // - Iterate to `(0, x)` at index 0: + // - Push one entry because `node_starts.len()` (0) is <= the source (0) + // - Leaving us with `node_starts` of `[0]` + // - Iterate to `(2, y)` at index 1: + // - Push one entry because `node_starts.len()` (1) is <= the source (2) + // - Push one entry because `node_starts.len()` (2) is <= the source (2) + // - Leaving us with `node_starts` of `[0, 1, 1]` + // - Loop terminates + while node_starts.len() <= source.index() { + node_starts.push(index); + } + } + + // Pad out the `node_starts` array so that it has `num_nodes + + // 1` entries. Continuing our example above, if `num_nodes` is + // be `3`, we would push one more index: `[0, 1, 1, 2]`. + // + // Interpretation of that vector: + // + // [0, 1, 1, 2] + // ---- range for N=2 + // ---- range for N=1 + // ---- range for N=0 + while node_starts.len() <= num_nodes { + node_starts.push(edge_targets.len()); + } + + assert_eq!(node_starts.len(), num_nodes + 1); + + Self { node_starts, edge_targets } + } + + /// Gets the successors for `source` as a slice. + pub fn successors(&self, source: N) -> &[N] { + let start_index = self.node_starts[source]; + let end_index = self.node_starts[source.plus(1)]; + &self.edge_targets[start_index..end_index] + } +} + +impl DirectedGraph for VecGraph { + type Node = N; +} + +impl WithNumNodes for VecGraph { + fn num_nodes(&self) -> usize { + self.node_starts.len() - 1 + } +} + +impl WithNumEdges for VecGraph { + fn num_edges(&self) -> usize { + self.edge_targets.len() + } +} + +impl GraphSuccessors<'graph> for VecGraph { + type Item = N; + + type Iter = std::iter::Cloned>; +} + +impl WithSuccessors for VecGraph { + fn successors<'graph>( + &'graph self, + node: N + ) -> >::Iter { + self.successors(node).iter().cloned() + } +} diff --git a/src/librustc_data_structures/graph/vec_graph/test.rs b/src/librustc_data_structures/graph/vec_graph/test.rs new file mode 100644 index 0000000000000..97a9bd2ad0b08 --- /dev/null +++ b/src/librustc_data_structures/graph/vec_graph/test.rs @@ -0,0 +1,51 @@ +use super::*; + +fn create_graph() -> VecGraph { + // Create a simple graph + // + // 5 + // | + // V + // 0 --> 1 --> 2 + // | + // v + // 3 --> 4 + // + // 6 + + VecGraph::new( + 7, + vec![ + (0, 1), + (1, 2), + (1, 3), + (3, 4), + (5, 1), + ], + ) +} + +#[test] +fn num_nodes() { + let graph = create_graph(); + assert_eq!(graph.num_nodes(), 7); +} + +#[test] +fn succesors() { + let graph = create_graph(); + assert_eq!(graph.successors(0), &[1]); + assert_eq!(graph.successors(1), &[2, 3]); + assert_eq!(graph.successors(2), &[]); + assert_eq!(graph.successors(3), &[4]); + assert_eq!(graph.successors(4), &[]); + assert_eq!(graph.successors(5), &[1]); + assert_eq!(graph.successors(6), &[]); +} + +#[test] +fn dfs() { + let graph = create_graph(); + let dfs: Vec<_> = graph.depth_first_search(0).collect(); + assert_eq!(dfs, vec![0, 1, 3, 4, 2]); +} diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 635edbb927e5c..b3a810a622d03 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -19,8 +19,11 @@ pub trait Idx: Copy + 'static + Ord + Debug + Hash { fn index(self) -> usize; fn increment_by(&mut self, amount: usize) { - let v = self.index() + amount; - *self = Self::new(v); + *self = self.plus(amount); + } + + fn plus(self, amount: usize) -> Self { + Self::new(self.index() + amount) } } @@ -167,6 +170,14 @@ macro_rules! newtype_index { } } + impl std::ops::Add for $type { + type Output = Self; + + fn add(self, other: usize) -> Self { + Self::new(self.index() + other) + } + } + impl Idx for $type { #[inline] fn new(value: usize) -> Self { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index a1d7ab8856daa..98c809f7e2595 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -72,6 +72,7 @@ macro_rules! unlikely { pub mod macros; pub mod svh; pub mod base_n; +pub mod binary_search_util; pub mod bit_set; pub mod box_region; pub mod const_cstr; diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index 0974607fabea8..d7cbd1e2e4b47 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -58,6 +58,10 @@ impl TransitiveRelation { self.edges.is_empty() } + pub fn elements(&self) -> impl Iterator { + self.elements.iter() + } + fn index(&self, a: &T) -> Option { self.map.get(a).cloned() } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index d92f3aafa1c7e..ff0c4ff548b71 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -188,7 +188,7 @@ impl PpSourceMode { _ => panic!("Should use call_with_pp_support_hir"), } } - fn call_with_pp_support_hir<'tcx, A, F>(&self, tcx: TyCtxt<'tcx>, f: F) -> A + fn call_with_pp_support_hir(&self, tcx: TyCtxt<'_>, f: F) -> A where F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A, { @@ -228,7 +228,7 @@ impl PpSourceMode { trait PrinterSupport: pprust::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. - fn sess<'a>(&'a self) -> &'a Session; + fn sess(&self) -> &Session; /// Produces the pretty-print annotation object. /// @@ -240,7 +240,7 @@ trait PrinterSupport: pprust::PpAnn { trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. - fn sess<'a>(&'a self) -> &'a Session; + fn sess(&self) -> &Session; /// Provides a uniform interface for re-extracting a reference to an /// `hir_map::Map` from a value that now owns it. @@ -272,7 +272,7 @@ struct NoAnn<'hir> { } impl<'hir> PrinterSupport for NoAnn<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -282,7 +282,7 @@ impl<'hir> PrinterSupport for NoAnn<'hir> { } impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -313,7 +313,7 @@ struct IdentifiedAnnotation<'hir> { } impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -360,7 +360,7 @@ impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { } impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { self.sess } @@ -458,7 +458,7 @@ struct TypedAnnotation<'a, 'tcx> { } impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { - fn sess<'a>(&'a self) -> &'a Session { + fn sess(&self) -> &Session { &self.tcx.sess } @@ -866,8 +866,8 @@ pub fn print_after_hir_lowering<'tcx>( // analysis is performed. However, we want to call `phase_3_run_analysis_passes` // with a different callback than the standard driver, so that isn't easy. // Instead, we call that function ourselves. -fn print_with_analysis<'tcx>( - tcx: TyCtxt<'tcx>, +fn print_with_analysis( + tcx: TyCtxt<'_>, ppm: PpMode, uii: Option, ofile: Option<&Path>, diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index a2717ab7ad8a9..83a0fb486fd9a 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1635,7 +1635,7 @@ impl Destination { } } - fn writable<'a>(&'a mut self) -> WritableDst<'a> { + fn writable(&mut self) -> WritableDst<'_> { match *self { Destination::Terminal(ref mut t) => WritableDst::Terminal(t), Destination::Buffered(ref mut t) => { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 70bd25a9d5772..1ffee1cdf691f 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -438,14 +438,14 @@ impl Handler { self.err_count.store(0, SeqCst); } - pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> { + pub fn struct_dummy(&self) -> DiagnosticBuilder<'_> { DiagnosticBuilder::new(self, Level::Cancelled, "") } - pub fn struct_span_warn<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); result.set_span(sp); if !self.flags.can_emit_warnings { @@ -453,11 +453,11 @@ impl Handler { } result } - pub fn struct_span_warn_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn_with_code>(&self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); result.set_span(sp); result.code(code); @@ -466,63 +466,63 @@ impl Handler { } result } - pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Warning, msg); if !self.flags.can_emit_warnings { result.cancel(); } result } - pub fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.set_span(sp); result } - pub fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err_with_code>(&self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.set_span(sp); result.code(code); result } // FIXME: This method should be removed (every error should have an associated error code). - pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> { DiagnosticBuilder::new(self, Level::Error, msg) } - pub fn struct_err_with_code<'a>( - &'a self, + pub fn struct_err_with_code( + &self, msg: &str, code: DiagnosticId, - ) -> DiagnosticBuilder<'a> { + ) -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.code(code); result } - pub fn struct_span_fatal<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg); result.set_span(sp); result } - pub fn struct_span_fatal_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal_with_code>(&self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg); result.set_span(sp); result.code(code); result } - pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> { DiagnosticBuilder::new(self, Level::Fatal, msg) } @@ -563,10 +563,10 @@ impl Handler { pub fn span_err>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Error); } - pub fn mut_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn mut_span_err>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'_> { let mut result = DiagnosticBuilder::new(self, Level::Error, msg); result.set_span(sp); result @@ -605,10 +605,10 @@ impl Handler { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Note); } - pub fn span_note_diag<'a>(&'a self, - sp: Span, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn span_note_diag(&self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'_> { let mut db = DiagnosticBuilder::new(self, Note, msg); db.set_span(sp); db diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index a43347a2197c3..38dc6edaf6325 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -51,7 +51,7 @@ use std::io::Write; use syntax::ast; use syntax_pos::Span; -pub fn assert_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.debugging_opts.dump_dep_graph { dump_graph(tcx); diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index f502d0475460e..046fdc72270db 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -35,7 +35,7 @@ const MODULE: Symbol = sym::module; const CFG: Symbol = sym::cfg; const KIND: Symbol = sym::kind; -pub fn assert_module_sources<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn assert_module_sources(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.incremental.is_none() { return; diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 5296ed0ffd0b8..1d83aa112a837 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -206,7 +206,7 @@ impl Assertion { } } -pub fn check_dirty_clean_annotations<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { // can't add `#[rustc_dirty]` etc without opting in to this feature if !tcx.features().rustc_attrs { return; diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index d9bcc0b2a83c7..90aefb0f32416 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -15,7 +15,7 @@ use super::fs::*; use super::file_format; use super::work_product; -pub fn dep_graph_tcx_init<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn dep_graph_tcx_init(tcx: TyCtxt<'_>) { if !tcx.dep_graph.is_fully_enabled() { return } @@ -192,7 +192,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { })) } -pub fn load_query_result_cache<'sess>(sess: &'sess Session) -> OnDiskCache<'sess> { +pub fn load_query_result_cache(sess: &Session) -> OnDiskCache<'_> { if sess.opts.incremental.is_none() || !sess.opts.debugging_opts.incremental_queries { return OnDiskCache::new_empty(sess.source_map()); diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 49c79ec09f5e2..13e2c5d1c574d 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -15,7 +15,7 @@ use super::dirty_clean; use super::file_format; use super::work_product; -pub fn save_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { let sess = tcx.sess; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index c1b6e3409c915..d698728198130 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -878,7 +878,7 @@ pub fn create_global_ctxt( /// Runs the resolution, type-checking, region checking and other /// miscellaneous analysis passes on the crate. -fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { +fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { assert_eq!(cnum, LOCAL_CRATE); let sess = tcx.sess; @@ -995,8 +995,8 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> { Ok(()) } -fn encode_and_write_metadata<'tcx>( - tcx: TyCtxt<'tcx>, +fn encode_and_write_metadata( + tcx: TyCtxt<'_>, outputs: &OutputFilenames, ) -> (middle::cstore::EncodedMetadata, bool) { #[derive(PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs index 9e1ef6b022d9b..d888c9e57d326 100644 --- a/src/librustc_interface/proc_macro_decls.rs +++ b/src/librustc_interface/proc_macro_decls.rs @@ -6,11 +6,11 @@ use rustc::ty::query::Providers; use syntax::attr; use syntax::symbol::sym; -pub fn find<'tcx>(tcx: TyCtxt<'tcx>) -> Option { +pub fn find(tcx: TyCtxt<'_>) -> Option { tcx.proc_macro_decls_static(LOCAL_CRATE) } -fn proc_macro_decls_static<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option { +fn proc_macro_decls_static(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option { assert_eq!(cnum, LOCAL_CRATE); let mut finder = Finder { decls: None }; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index a86d3cc43948d..6ae5e94b11af3 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -642,14 +642,14 @@ pub fn build_output_filenames( ); None } else { + if !sess.opts.cg.extra_filename.is_empty() { + sess.warn("ignoring -C extra-filename flag due to -o flag"); + } Some(out_file.clone()) }; if *odir != None { sess.warn("ignoring --out-dir flag due to -o flag"); } - if !sess.opts.cg.extra_filename.is_empty() { - sess.warn("ignoring -C extra-filename flag due to -o flag"); - } OutputFilenames { out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d808a15982e37..4c6ceb14ca42a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -74,7 +74,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn lint_mod<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) { lint::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new()); } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index b5c5fc0608b95..2db2e0bc0da96 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } let ty = cx.tables.expr_ty(&expr); - let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, ""); + let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false); let mut fn_warned = false; let mut op_warned = false; @@ -133,7 +133,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { ty: Ty<'tcx>, expr: &hir::Expr, span: Span, - descr_post_path: &str, + descr_pre: &str, + descr_post: &str, + plural: bool, ) -> bool { if ty.is_unit() || cx.tcx.is_ty_uninhabited_from( cx.tcx.hir().get_module_parent(expr.hir_id), ty) @@ -141,15 +143,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { return true; } + let plural_suffix = if plural { "s" } else { "" }; + match ty.sty { - ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path), + ty::Adt(..) if ty.is_box() => { + let boxed_ty = ty.boxed_ty(); + let descr_pre = &format!("{}boxed ", descr_pre); + check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural) + } + ty::Adt(def, _) => { + check_must_use_def(cx, def.did, span, descr_pre, descr_post) + } ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in &cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let def_id = trait_ref.def_id; - if check_must_use_def(cx, def_id, span, "implementer of ", "") { + let descr_pre = &format!( + "{}implementer{} of ", + descr_pre, + plural_suffix, + ); + if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { has_emitted = true; break; } @@ -162,7 +178,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for predicate in binder.skip_binder().iter() { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { let def_id = trait_ref.def_id; - if check_must_use_def(cx, def_id, span, "", " trait object") { + let descr_post = &format!( + " trait object{}{}", + plural_suffix, + descr_post, + ); + if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { has_emitted = true; break; } @@ -179,14 +200,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { vec![] }; for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { - let descr_post_path = &format!(" in tuple element {}", i); + let descr_post = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&span); - if check_must_use_ty(cx, ty, expr, span, descr_post_path) { + if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) { has_emitted = true; } } has_emitted } + ty::Array(ty, len) => match len.assert_usize(cx.tcx) { + // If the array is definitely non-empty, we can do `#[must_use]` checking. + Some(n) if n != 0 => { + let descr_pre = &format!( + "{}array{} of ", + descr_pre, + plural_suffix, + ); + check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true) + } + // Otherwise, we don't lint, to avoid false positives. + _ => false, + } _ => false, } } diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index 98fba55218f9b..e9cf7bca25c4b 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -1,6 +1,8 @@ #![feature(proc_macro_hygiene)] #![deny(rust_2018_idioms)] +#![recursion_limit="128"] + extern crate proc_macro; use synstructure::decl_derive; diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 0474d2a2e3b3a..d47bd0580d6ca 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -1,4 +1,5 @@ use proc_macro::TokenStream; +use proc_macro2::{TokenTree, Delimiter}; use syn::{ Token, Ident, Type, Attribute, ReturnType, Expr, Block, Error, braced, parenthesized, parse_macro_input, @@ -35,7 +36,7 @@ enum QueryModifier { Desc(Option, Punctuated), /// Cache the query to disk if the `Expr` returns true. - Cache(Option, Expr), + Cache(Option<(IdentOrWild, IdentOrWild)>, Block), /// Custom code to load the query from disk. LoadCached(Ident, Ident, Block), @@ -77,21 +78,26 @@ impl Parse for QueryModifier { }; let desc = attr_content.parse_terminated(Expr::parse)?; Ok(QueryModifier::Desc(tcx, desc)) - } else if modifier == "cache" { + } else if modifier == "cache_on_disk_if" { // Parse a cache modifier like: - // `cache { |tcx| key.is_local() }` - let attr_content; - braced!(attr_content in input); - let tcx = if attr_content.peek(Token![|]) { - attr_content.parse::()?; - let tcx = attr_content.parse()?; - attr_content.parse::()?; - Some(tcx) + // `cache(tcx, value) { |tcx| key.is_local() }` + let has_args = if let TokenTree::Group(group) = input.fork().parse()? { + group.delimiter() == Delimiter::Parenthesis + } else { + false + }; + let args = if has_args { + let args; + parenthesized!(args in input); + let tcx = args.parse()?; + args.parse::()?; + let value = args.parse()?; + Some((tcx, value)) } else { None }; - let expr = attr_content.parse()?; - Ok(QueryModifier::Cache(tcx, expr)) + let block = input.parse()?; + Ok(QueryModifier::Cache(args, block)) } else if modifier == "load_cached" { // Parse a load_cached modifier like: // `load_cached(tcx, id) { tcx.queries.on_disk_cache.try_load_query_result(tcx, id) }` @@ -203,8 +209,8 @@ struct QueryModifiers { /// The description of the query. desc: Option<(Option, Punctuated)>, - /// Cache the query to disk if the `Expr` returns true. - cache: Option<(Option, Expr)>, + /// Cache the query to disk if the `Block` returns true. + cache: Option<(Option<(IdentOrWild, IdentOrWild)>, Block)>, /// Custom code to load the query from disk. load_cached: Option<(Ident, Ident, Block)>, @@ -247,11 +253,11 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } load_cached = Some((tcx, id, block)); } - QueryModifier::Cache(tcx, expr) => { + QueryModifier::Cache(args, expr) => { if cache.is_some() { panic!("duplicate modifier `cache` for query `{}`", query.name); } - cache = Some((tcx, expr)); + cache = Some((args, expr)); } QueryModifier::Desc(tcx, list) => { if desc.is_some() { @@ -321,7 +327,7 @@ fn add_query_description_impl( let key = &query.key.0; // Find out if we should cache the query on disk - let cache = modifiers.cache.as_ref().map(|(tcx, expr)| { + let cache = modifiers.cache.as_ref().map(|(args, expr)| { let try_load_from_disk = if let Some((tcx, id, block)) = modifiers.load_cached.as_ref() { // Use custom code to load the query from disk quote! { @@ -346,11 +352,22 @@ fn add_query_description_impl( } }; - let tcx = tcx.as_ref().map(|t| quote! { #t }).unwrap_or(quote! { _ }); + let tcx = args.as_ref().map(|t| { + let t = &(t.0).0; + quote! { #t } + }).unwrap_or(quote! { _ }); + let value = args.as_ref().map(|t| { + let t = &(t.1).0; + quote! { #t } + }).unwrap_or(quote! { _ }); quote! { #[inline] #[allow(unused_variables)] - fn cache_on_disk(#tcx: TyCtxt<'tcx>, #key: Self::Key) -> bool { + fn cache_on_disk( + #tcx: TyCtxt<'tcx>, + #key: Self::Key, + #value: Option<&Self::Value> + ) -> bool { #expr } @@ -395,6 +412,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { let mut query_description_stream = quote! {}; let mut dep_node_def_stream = quote! {}; let mut dep_node_force_stream = quote! {}; + let mut try_load_from_on_disk_cache_stream = quote! {}; let mut no_force_queries = Vec::new(); for group in groups.0 { @@ -409,6 +427,22 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { _ => quote! { #result_full }, }; + if modifiers.cache.is_some() && !modifiers.no_force { + try_load_from_on_disk_cache_stream.extend(quote! { + DepKind::#name => { + debug_assert!(tcx.dep_graph + .node_color(self) + .map(|c| c.is_green()) + .unwrap_or(false)); + + let key = RecoverKey::recover(tcx.global_tcx(), self).unwrap(); + if queries::#name::cache_on_disk(tcx.global_tcx(), key, None) { + let _ = tcx.#name(key); + } + } + }); + } + let mut attributes = Vec::new(); // Pass on the fatal_cycle modifier @@ -423,20 +457,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { if modifiers.no_hash { attributes.push(quote! { no_hash }); }; - - let mut attribute_stream = quote! {}; - - for e in attributes.into_iter().intersperse(quote! {,}) { - attribute_stream.extend(e); - } - - // Add the query to the group - group_stream.extend(quote! { - [#attribute_stream] fn #name: #name(#arg) #result, - }); - - let mut attributes = Vec::new(); - // Pass on the anon modifier if modifiers.anon { attributes.push(quote! { anon }); @@ -450,6 +470,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { for e in attributes.into_iter().intersperse(quote! {,}) { attribute_stream.extend(e); } + + // Add the query to the group + group_stream.extend(quote! { + [#attribute_stream] fn #name: #name(#arg) #result, + }); + // Create a dep node for the query dep_node_def_stream.extend(quote! { [#attribute_stream] #name(#arg), @@ -470,7 +496,11 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { }); } - add_query_description_impl(&query, modifiers, &mut query_description_stream); + add_query_description_impl( + &query, + modifiers, + &mut query_description_stream, + ); } let name = &group.name; query_stream.extend(quote! { @@ -520,5 +550,19 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { } } #query_description_stream + + impl DepNode { + /// Check whether the query invocation corresponding to the given + /// DepNode is eligible for on-disk-caching. If so, this is method + /// will execute the query corresponding to the given DepNode. + /// Also, as a sanity check, it expects that the corresponding query + /// invocation has been marked as green already. + pub fn try_load_from_on_disk_cache(&self, tcx: TyCtxt<'_>) { + match self.kind { + #try_load_from_on_disk_cache_stream + _ => (), + } + } + } }) } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index df0957254cc09..2073b317939d7 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -868,7 +868,7 @@ impl<'a> CrateLoader<'a> { fn inject_profiler_runtime(&mut self) { if self.sess.opts.debugging_opts.profile || - self.sess.opts.debugging_opts.pgo_gen.enabled() + self.sess.opts.cg.profile_generate.enabled() { info!("loading profiler"); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 04a9c4e9a1a11..914084d7e9ece 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -250,7 +250,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, exported_symbols => { Arc::new(cdata.exported_symbols(tcx)) } } -pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { +pub fn provide(providers: &mut Providers<'_>) { // FIXME(#44234) - almost all of these queries have no sub-queries and // therefore no actual inputs, they're just reading tables calculated in // resolve! Does this work? Unsure! That's what the issue is about @@ -550,7 +550,7 @@ impl CrateStore for cstore::CStore { self.do_postorder_cnums_untracked() } - fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata { + fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata { encoder::encode_metadata(tcx) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index b52b6dfbb5e12..73c20ccad5abf 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1863,7 +1863,7 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { // will allow us to slice the metadata to the precise length that we just // generated regardless of trailing bytes that end up in it. -pub fn encode_metadata<'tcx>(tcx: TyCtxt<'tcx>) -> EncodedMetadata { +pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { let mut encoder = opaque::Encoder::new(vec![]); encoder.emit_raw_bytes(METADATA_HEADER); @@ -1905,7 +1905,7 @@ pub fn encode_metadata<'tcx>(tcx: TyCtxt<'tcx>) -> EncodedMetadata { EncodedMetadata { raw_data: result } } -pub fn get_repr_options<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> ReprOptions { +pub fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { let ty = tcx.type_of(did); match ty.sty { ty::Adt(ref def, _) => return def.repr, diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs index 0ce103cfa40dc..b1f4dfffc7898 100644 --- a/src/librustc_metadata/foreign_modules.rs +++ b/src/librustc_metadata/foreign_modules.rs @@ -3,7 +3,7 @@ use rustc::hir; use rustc::middle::cstore::ForeignModule; use rustc::ty::TyCtxt; -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, modules: Vec::new(), diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index cd6270046faab..728fd004fcb69 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -4,7 +4,7 @@ use rustc::ty::TyCtxt; use rustc_target::spec::abi::Abi; use syntax::symbol::sym; -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { args: Vec::new(), }; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 7b335b3b4832d..4a01d0e559af4 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -11,7 +11,7 @@ use syntax::feature_gate::{self, GateIssue}; use syntax::symbol::{Symbol, sym}; use syntax::{span_err, struct_span_err}; -pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, libs: Vec::new(), diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4872440f5bd4a..25ac93cc2422c 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -87,7 +87,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> { +fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> { let input_body = tcx.mir_validated(def_id); debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id)); @@ -275,7 +275,7 @@ fn do_mir_borrowck<'a, 'tcx>( mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer // Convert any reservation warnings into lints. - let reservation_warnings = mem::replace(&mut mbcx.reservation_warnings, Default::default()); + let reservation_warnings = mem::take(&mut mbcx.reservation_warnings); for (_, (place, span, location, bk, borrow)) in reservation_warnings { let mut initial_diag = mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs index c4b2a5daef89a..b5630251e5830 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs @@ -1,6 +1,6 @@ use crate::borrow_check::nll::type_check::Locations; -use crate::borrow_check::nll::constraints::ConstraintIndex; -use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::constraints::OutlivesConstraintIndex; +use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConstraint}; use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph; @@ -12,8 +12,8 @@ use syntax_pos::DUMMY_SP; /// -> R2` or `R2 -> R1` depending on the direction type `D`. crate struct ConstraintGraph { _direction: D, - first_constraints: IndexVec>, - next_constraints: IndexVec>, + first_constraints: IndexVec>, + next_constraints: IndexVec>, } crate type NormalConstraintGraph = ConstraintGraph; @@ -77,13 +77,13 @@ impl ConstraintGraph { /// reporting. crate fn new( direction: D, - set: &ConstraintSet, + set: &OutlivesConstraintSet, num_region_vars: usize, ) -> Self { let mut first_constraints = IndexVec::from_elem_n(None, num_region_vars); - let mut next_constraints = IndexVec::from_elem(None, &set.constraints); + let mut next_constraints = IndexVec::from_elem(None, &set.outlives); - for (idx, constraint) in set.constraints.iter_enumerated().rev() { + for (idx, constraint) in set.outlives.iter_enumerated().rev() { let head = &mut first_constraints[D::start_region(constraint)]; let next = &mut next_constraints[idx]; debug_assert!(next.is_none()); @@ -103,7 +103,7 @@ impl ConstraintGraph { /// and not constraints. crate fn region_graph<'rg>( &'rg self, - set: &'rg ConstraintSet, + set: &'rg OutlivesConstraintSet, static_region: RegionVid, ) -> RegionGraph<'rg, D> { RegionGraph::new(set, self, static_region) @@ -113,7 +113,7 @@ impl ConstraintGraph { crate fn outgoing_edges<'a>( &'a self, region_sup: RegionVid, - constraints: &'a ConstraintSet, + constraints: &'a OutlivesConstraintSet, static_region: RegionVid, ) -> Edges<'a, D> { //if this is the `'static` region and the graph's direction is normal, @@ -142,8 +142,8 @@ impl ConstraintGraph { crate struct Edges<'s, D: ConstraintGraphDirecton> { graph: &'s ConstraintGraph, - constraints: &'s ConstraintSet, - pointer: Option, + constraints: &'s OutlivesConstraintSet, + pointer: Option, next_static_idx: Option, static_region: RegionVid, } @@ -180,7 +180,7 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> { /// reverse) constraint graph. It implements the graph traits and is /// usd for doing the SCC computation. crate struct RegionGraph<'s, D: ConstraintGraphDirecton> { - set: &'s ConstraintSet, + set: &'s OutlivesConstraintSet, constraint_graph: &'s ConstraintGraph, static_region: RegionVid, } @@ -191,7 +191,7 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> { /// construct SCCs for region inference but also for error /// reporting. crate fn new( - set: &'s ConstraintSet, + set: &'s OutlivesConstraintSet, constraint_graph: &'s ConstraintGraph, static_region: RegionVid, ) -> Self { @@ -234,10 +234,10 @@ impl<'s, D: ConstraintGraphDirecton> graph::WithNumNodes for RegionGraph<'s, D> } impl<'s, D: ConstraintGraphDirecton> graph::WithSuccessors for RegionGraph<'s, D> { - fn successors<'graph>( - &'graph self, + fn successors( + &self, node: Self::Node, - ) -> >::Iter { + ) -> >::Iter { self.outgoing_regions(node) } } diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs index b1091eb5ac81f..6121ed0cf0d1c 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs @@ -1,37 +1,40 @@ +use crate::borrow_check::nll::type_check::Locations; use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use crate::borrow_check::nll::type_check::Locations; - use std::fmt; -use std::ops::Deref; +use std::ops::Index; crate mod graph; +/// A set of NLL region constraints. These include "outlives" +/// constraints of the form `R1: R2`. Each constraint is identified by +/// a unique `OutlivesConstraintIndex` and you can index into the set +/// (`constraint_set[i]`) to access the constraint details. #[derive(Clone, Default)] -crate struct ConstraintSet { - constraints: IndexVec, +crate struct OutlivesConstraintSet { + outlives: IndexVec, } -impl ConstraintSet { +impl OutlivesConstraintSet { crate fn push(&mut self, constraint: OutlivesConstraint) { debug!( - "ConstraintSet::push({:?}: {:?} @ {:?}", + "OutlivesConstraintSet::push({:?}: {:?} @ {:?}", constraint.sup, constraint.sub, constraint.locations ); if constraint.sup == constraint.sub { // 'a: 'a is pretty uninteresting return; } - self.constraints.push(constraint); + self.outlives.push(constraint); } /// Constructs a "normal" graph from the constraint set; the graph makes it /// easy to find the constraints affecting a particular region. /// /// N.B., this graph contains a "frozen" view of the current - /// constraints. Any new constraints added to the `ConstraintSet` + /// constraints. Any new constraints added to the `OutlivesConstraintSet` /// after the graph is built will not be present in the graph. crate fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph { graph::ConstraintGraph::new(graph::Normal, self, num_region_vars) @@ -54,13 +57,17 @@ impl ConstraintSet { let region_graph = &constraint_graph.region_graph(self, static_region); Sccs::new(region_graph) } + + crate fn outlives(&self) -> &IndexVec { + &self.outlives + } } -impl Deref for ConstraintSet { - type Target = IndexVec; +impl Index for OutlivesConstraintSet { + type Output = OutlivesConstraint; - fn deref(&self) -> &Self::Target { - &self.constraints + fn index(&self, i: OutlivesConstraintIndex) -> &Self::Output { + &self.outlives[i] } } @@ -94,8 +101,8 @@ impl fmt::Debug for OutlivesConstraint { } newtype_index! { - pub struct ConstraintIndex { - DEBUG_FORMAT = "ConstraintIndex({})" + pub struct OutlivesConstraintIndex { + DEBUG_FORMAT = "OutlivesConstraintIndex({})" } } diff --git a/src/librustc_mir/borrow_check/nll/member_constraints.rs b/src/librustc_mir/borrow_check/nll/member_constraints.rs new file mode 100644 index 0000000000000..b5e2e111f38e5 --- /dev/null +++ b/src/librustc_mir/borrow_check/nll/member_constraints.rs @@ -0,0 +1,235 @@ +use crate::rustc::ty::{self, Ty}; +use rustc::hir::def_id::DefId; +use rustc::infer::region_constraints::MemberConstraint; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use std::hash::Hash; +use std::ops::Index; +use syntax_pos::Span; + +/// Compactly stores a set of `R0 member of [R1...Rn]` constraints, +/// indexed by the region `R0`. +crate struct MemberConstraintSet<'tcx, R> +where + R: Copy + Hash + Eq, +{ + /// Stores the first "member" constraint for a given `R0`. This is an + /// index into the `constraints` vector below. + first_constraints: FxHashMap, + + /// Stores the data about each `R0 member of [R1..Rn]` constraint. + /// These are organized into a linked list, so each constraint + /// contains the index of the next constraint with the same `R0`. + constraints: IndexVec>, + + /// Stores the `R1..Rn` regions for *all* sets. For any given + /// constraint, we keep two indices so that we can pull out a + /// slice. + choice_regions: Vec, +} + +/// Represents a `R0 member of [R1..Rn]` constraint +crate struct NllMemberConstraint<'tcx> { + next_constraint: Option, + + /// The opaque type whose hidden type is being inferred. (Used in error reporting.) + crate opaque_type_def_id: DefId, + + /// The span where the hidden type was instantiated. + crate definition_span: Span, + + /// The hidden type in which `R0` appears. (Used in error reporting.) + crate hidden_ty: Ty<'tcx>, + + /// The region `R0`. + crate member_region_vid: ty::RegionVid, + + /// Index of `R1` in `choice_regions` vector from `MemberConstraintSet`. + start_index: usize, + + /// Index of `Rn` in `choice_regions` vector from `MemberConstraintSet`. + end_index: usize, +} + +newtype_index! { + crate struct NllMemberConstraintIndex { + DEBUG_FORMAT = "MemberConstraintIndex({})" + } +} + +impl Default for MemberConstraintSet<'tcx, ty::RegionVid> { + fn default() -> Self { + Self { + first_constraints: Default::default(), + constraints: Default::default(), + choice_regions: Default::default(), + } + } +} + +impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> { + /// Pushes a member constraint into the set. + /// + /// The input member constraint `m_c` is in the form produced by + /// the the `rustc::infer` code. + /// + /// The `to_region_vid` callback fn is used to convert the regions + /// within into `RegionVid` format -- it typically consults the + /// `UniversalRegions` data structure that is known to the caller + /// (but which this code is unaware of). + crate fn push_constraint( + &mut self, + m_c: &MemberConstraint<'tcx>, + mut to_region_vid: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid, + ) { + debug!("push_constraint(m_c={:?})", m_c); + let member_region_vid: ty::RegionVid = to_region_vid(m_c.member_region); + let next_constraint = self.first_constraints.get(&member_region_vid).cloned(); + let start_index = self.choice_regions.len(); + let end_index = start_index + m_c.choice_regions.len(); + debug!("push_constraint: member_region_vid={:?}", member_region_vid); + let constraint_index = self.constraints.push(NllMemberConstraint { + next_constraint, + member_region_vid, + opaque_type_def_id: m_c.opaque_type_def_id, + definition_span: m_c.definition_span, + hidden_ty: m_c.hidden_ty, + start_index, + end_index, + }); + self.first_constraints.insert(member_region_vid, constraint_index); + self.choice_regions.extend(m_c.choice_regions.iter().map(|&r| to_region_vid(r))); + } +} + +impl MemberConstraintSet<'tcx, R1> +where + R1: Copy + Hash + Eq, +{ + /// Remap the "member region" key using `map_fn`, producing a new + /// member constraint set. This is used in the NLL code to map from + /// the original `RegionVid` to an scc index. In some cases, we + /// may have multiple `R1` values mapping to the same `R2` key -- that + /// is ok, the two sets will be merged. + crate fn into_mapped( + self, + mut map_fn: impl FnMut(R1) -> R2, + ) -> MemberConstraintSet<'tcx, R2> + where + R2: Copy + Hash + Eq, + { + // We can re-use most of the original data, just tweaking the + // linked list links a bit. + // + // For example if we had two keys `Ra` and `Rb` that both now + // wind up mapped to the same key `S`, we would append the + // linked list for `Ra` onto the end of the linked list for + // `Rb` (or vice versa) -- this basically just requires + // rewriting the final link from one list to point at the othe + // other (see `append_list`). + + let MemberConstraintSet { first_constraints, mut constraints, choice_regions } = self; + + let mut first_constraints2 = FxHashMap::default(); + first_constraints2.reserve(first_constraints.len()); + + for (r1, start1) in first_constraints { + let r2 = map_fn(r1); + if let Some(&start2) = first_constraints2.get(&r2) { + append_list(&mut constraints, start1, start2); + } + first_constraints2.insert(r2, start1); + } + + MemberConstraintSet { + first_constraints: first_constraints2, + constraints, + choice_regions, + } + } +} + +impl MemberConstraintSet<'tcx, R> +where + R: Copy + Hash + Eq, +{ + crate fn all_indices( + &self, + ) -> impl Iterator { + self.constraints.indices() + } + + /// Iterate down the constraint indices associated with a given + /// peek-region. You can then use `choice_regions` and other + /// methods to access data. + crate fn indices( + &self, + member_region_vid: R, + ) -> impl Iterator + '_ { + let mut next = self.first_constraints.get(&member_region_vid).cloned(); + std::iter::from_fn(move || -> Option { + if let Some(current) = next { + next = self.constraints[current].next_constraint; + Some(current) + } else { + None + } + }) + } + + /// Returns the "choice regions" for a given member + /// constraint. This is the `R1..Rn` from a constraint like: + /// + /// ``` + /// R0 member of [R1..Rn] + /// ``` + crate fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] { + let NllMemberConstraint { start_index, end_index, .. } = &self.constraints[pci]; + &self.choice_regions[*start_index..*end_index] + } +} + +impl<'tcx, R> Index for MemberConstraintSet<'tcx, R> +where + R: Copy + Hash + Eq, +{ + type Output = NllMemberConstraint<'tcx>; + + fn index(&self, i: NllMemberConstraintIndex) -> &NllMemberConstraint<'tcx> { + &self.constraints[i] + } +} + +/// Given a linked list starting at `source_list` and another linked +/// list starting at `target_list`, modify `target_list` so that it is +/// followed by `source_list`. +/// +/// Before: +/// +/// ``` +/// target_list: A -> B -> C -> (None) +/// source_list: D -> E -> F -> (None) +/// ``` +/// +/// After: +/// +/// ``` +/// target_list: A -> B -> C -> D -> E -> F -> (None) +/// ``` +fn append_list( + constraints: &mut IndexVec>, + target_list: NllMemberConstraintIndex, + source_list: NllMemberConstraintIndex, +) { + let mut p = target_list; + loop { + let mut r = &mut constraints[p]; + match r.next_constraint { + Some(q) => p = q, + None => { + r.next_constraint = Some(source_list); + return; + } + } + } +} diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 5dd7b7452733c..eb63e0de195e5 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -37,6 +37,7 @@ crate mod type_check; mod universal_regions; mod constraints; +mod member_constraints; use self::facts::AllFacts; use self::region_infer::RegionInferenceContext; @@ -129,6 +130,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( placeholder_index_to_region: _, mut liveness_constraints, outlives_constraints, + member_constraints, closure_bounds_mapping, type_tests, } = constraints; @@ -150,6 +152,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( universal_region_relations, body, outlives_constraints, + member_constraints, closure_bounds_mapping, type_tests, liveness_constraints, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs index 4931005a4547a..d4f6ce8801e63 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs @@ -71,7 +71,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - let mut constraints: Vec<_> = self.constraints.iter().collect(); + let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); constraints.sort(); for constraint in &constraints { let OutlivesConstraint { diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 04ff54e9a5e45..9e08961f440f2 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -1,4 +1,5 @@ use crate::borrow_check::nll::constraints::OutlivesConstraint; +use crate::borrow_check::nll::region_infer::AppliedMemberConstraint; use crate::borrow_check::nll::region_infer::RegionInferenceContext; use crate::borrow_check::nll::type_check::Locations; use crate::borrow_check::nll::universal_regions::DefiningTy; @@ -195,6 +196,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { Trace::NotVisited => { bug!("found unvisited region {:?} on path to {:?}", p, r) } + Trace::FromOutlivesConstraint(c) => { result.push(c); p = c.sup; @@ -211,10 +213,30 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Otherwise, walk over the outgoing constraints and // enqueue any regions we find, keeping track of how we // reached them. + + // A constraint like `'r: 'x` can come from our constraint + // graph. let fr_static = self.universal_regions.fr_static; - for constraint in self.constraint_graph - .outgoing_edges(r, &self.constraints, fr_static) - { + let outgoing_edges_from_graph = self.constraint_graph + .outgoing_edges(r, &self.constraints, fr_static); + + + // But member constraints can also give rise to `'r: 'x` + // edges that were not part of the graph initially, so + // watch out for those. + let outgoing_edges_from_picks = self.applied_member_constraints(r) + .iter() + .map(|&AppliedMemberConstraint { min_choice, member_constraint_index, .. }| { + let p_c = &self.member_constraints[member_constraint_index]; + OutlivesConstraint { + sup: r, + sub: min_choice, + locations: Locations::All(p_c.definition_span), + category: ConstraintCategory::OpaqueType, + } + }); + + for constraint in outgoing_edges_from_graph.chain(outgoing_edges_from_picks) { debug_assert_eq!(constraint.sup, r); let sub_region = constraint.sub; if let Trace::NotVisited = context[sub_region] { @@ -687,7 +709,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Finds some region R such that `fr1: R` and `R` is live at // `elem`. - crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { + crate fn find_sub_region_live_at( + &self, + fr1: RegionVid, + elem: Location, + ) -> RegionVid { debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem); self.find_constraint_paths_between_regions(fr1, |r| { // First look for some `r` such that `fr1: r` and `r` is live at `elem` @@ -729,8 +755,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr1: RegionVid, fr2: RegionVid, ) -> (ConstraintCategory, Span) { - let (category, _, span) = - self.best_blame_constraint(body, fr1, |r| self.provides_universal_region(r, fr1, fr2)); + let (category, _, span) = self.best_blame_constraint( + body, + fr1, + |r| self.provides_universal_region(r, fr1, fr2), + ); (category, span) } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs index 0cf8a0d16f622..fdf2af9f44ebc 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs @@ -63,7 +63,7 @@ impl<'a, 'this, 'tcx> dot::GraphWalk<'this> for RawConstraints<'a, 'tcx> { vids.into() } fn edges(&'this self) -> dot::Edges<'this, OutlivesConstraint> { - (&self.regioncx.constraints.raw[..]).into() + (&self.regioncx.constraints.outlives().raw[..]).into() } // Render `a: b` as `a -> b`, indicating the flow diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 41ed564d0f0e1..4e609460c1f70 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -1,25 +1,32 @@ use super::universal_regions::UniversalRegions; use crate::borrow_check::nll::constraints::graph::NormalConstraintGraph; -use crate::borrow_check::nll::constraints::{ConstraintSccIndex, ConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::constraints::{ + ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet, +}; +use crate::borrow_check::nll::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}; use crate::borrow_check::nll::region_infer::values::{ - PlaceholderIndices, RegionElement, ToElementIndex + PlaceholderIndices, RegionElement, ToElementIndex, }; -use crate::borrow_check::Upvar; use crate::borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations; use crate::borrow_check::nll::type_check::Locations; +use crate::borrow_check::Upvar; use rustc::hir::def_id::DefId; -use rustc::infer::canonical::QueryRegionConstraint; +use rustc::infer::canonical::QueryOutlivesConstraint; +use rustc::infer::opaque_types; use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin, RegionVariableOrigin}; use rustc::mir::{ - ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, - ConstraintCategory, Local, Location, Body, + Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, + ConstraintCategory, Local, Location, }; use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::{self, ErrorReported}; +use rustc_data_structures::binary_search_util; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::graph::WithSuccessors; use rustc_data_structures::graph::scc::Sccs; +use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::indexed_vec::IndexVec; use rustc_errors::{Diagnostic, DiagnosticBuilder}; use syntax_pos::Span; @@ -49,17 +56,31 @@ pub struct RegionInferenceContext<'tcx> { liveness_constraints: LivenessValues, /// The outlives constraints computed by the type-check. - constraints: Rc, + constraints: Rc, /// The constraint-set, but in graph form, making it easy to traverse /// the constraints adjacent to a particular region. Used to construct /// the SCC (see `constraint_sccs`) and for error reporting. constraint_graph: Rc, - /// The SCC computed from `constraints` and the constraint graph. Used to + /// The SCC computed from `constraints` and the constraint + /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to /// compute the values of each region. constraint_sccs: Rc>, + /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` + /// exists if `B: A`. Computed lazilly. + rev_constraint_graph: Option>>, + + /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. + member_constraints: Rc>, + + /// Records the member constraints that we applied to each scc. + /// This is useful for error reporting. Once constraint + /// propagation is done, this vector is sorted according to + /// `member_region_scc`. + member_constraints_applied: Vec, + /// Map closure bounds to a `Span` that should be used for error reporting. closure_bounds_mapping: FxHashMap>, @@ -95,6 +116,32 @@ pub struct RegionInferenceContext<'tcx> { universal_region_relations: Rc>, } +/// Each time that `apply_member_constraint` is successful, it appends +/// one of these structs to the `member_constraints_applied` field. +/// This is used in error reporting to trace out what happened. +/// +/// The way that `apply_member_constraint` works is that it effectively +/// adds a new lower bound to the SCC it is analyzing: so you wind up +/// with `'R: 'O` where `'R` is the pick-region and `'O` is the +/// minimal viable option. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +struct AppliedMemberConstraint { + /// The SCC that was affected. (The "member region".) + /// + /// The vector if `AppliedMemberConstraint` elements is kept sorted + /// by this field. + member_region_scc: ConstraintSccIndex, + + /// The "best option" that `apply_member_constraint` found -- this was + /// added as an "ad-hoc" lower-bound to `member_region_scc`. + min_choice: ty::RegionVid, + + /// The "member constraint index" -- we can find out details about + /// the constraint from + /// `set.member_constraints[member_constraint_index]`. + member_constraint_index: NllMemberConstraintIndex, +} + struct RegionDefinition<'tcx> { /// What kind of variable is this -- a free region? existential /// variable? etc. (See the `NLLRegionVariableOrigin` for more @@ -186,7 +233,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { placeholder_indices: Rc, universal_region_relations: Rc>, _body: &Body<'tcx>, - outlives_constraints: ConstraintSet, + outlives_constraints: OutlivesConstraintSet, + member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, closure_bounds_mapping: FxHashMap< Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, @@ -218,12 +266,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { let scc_representatives = Self::compute_scc_representatives(&constraint_sccs, &definitions); + let member_constraints = + Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r))); + let mut result = Self { definitions, liveness_constraints, constraints, constraint_graph, constraint_sccs, + rev_constraint_graph: None, + member_constraints, + member_constraints_applied: Vec::new(), closure_bounds_mapping, scc_universes, scc_representatives, @@ -341,9 +395,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!( "init_free_and_bound_regions: placeholder {:?} is \ not compatible with universe {:?} of its SCC {:?}", - placeholder, - scc_universe, - scc, + placeholder, scc_universe, scc, ); self.add_incompatible_universe(scc); } @@ -394,6 +446,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_universes[scc] } + /// Once region solving has completed, this function will return + /// the member constraints that were applied to the value of a given + /// region `r`. See `AppliedMemberConstraint`. + fn applied_member_constraints(&self, r: impl ToRegionVid) -> &[AppliedMemberConstraint] { + let scc = self.constraint_sccs.scc(r.to_region_vid()); + binary_search_util::binary_search_slice( + &self.member_constraints_applied, + |applied| applied.member_region_scc, + &scc, + ) + } + /// Performs region inference and report errors if we see any /// unsatisfiable constraints. If this is a closure, returns the /// region requirements to propagate to our creator, if any. @@ -428,11 +492,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // to store those. Otherwise, we'll pass in `None` to the // functions below, which will trigger them to report errors // eagerly. - let mut outlives_requirements = if infcx.tcx.is_closure(mir_def_id) { - Some(vec![]) - } else { - None - }; + let mut outlives_requirements = + if infcx.tcx.is_closure(mir_def_id) { Some(vec![]) } else { None }; self.check_type_tests( infcx, @@ -451,16 +512,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { errors_buffer, ); + self.check_member_constraints(infcx, mir_def_id, errors_buffer); + let outlives_requirements = outlives_requirements.unwrap_or(vec![]); if outlives_requirements.is_empty() { None } else { let num_external_vids = self.universal_regions.num_global_and_external_regions(); - Some(ClosureRegionRequirements { - num_external_vids, - outlives_requirements, - }) + Some(ClosureRegionRequirements { num_external_vids, outlives_requirements }) } } @@ -472,7 +532,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("propagate_constraints()"); debug!("propagate_constraints: constraints={:#?}", { - let mut constraints: Vec<_> = self.constraints.iter().collect(); + let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); constraints.sort(); constraints .into_iter() @@ -488,8 +548,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { for scc_index in self.constraint_sccs.all_sccs() { self.propagate_constraint_sccs_if_new(scc_index, visited); } + + // Sort the applied member constraints so we can binary search + // through them later. + self.member_constraints_applied.sort_by_key(|applied| applied.member_region_scc); } + /// Computes the value of the SCC `scc_a` if it has not already + /// been computed. The `visited` parameter is a bitset #[inline] fn propagate_constraint_sccs_if_new( &mut self, @@ -501,6 +567,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + /// Computes the value of the SCC `scc_a`, which has not yet been + /// computed. This works by first computing all successors of the + /// SCC (if they haven't been computed already) and then unioning + /// together their elements. fn propagate_constraint_sccs_new( &mut self, scc_a: ConstraintSccIndex, @@ -510,10 +580,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Walk each SCC `B` such that `A: B`... for &scc_b in constraint_sccs.successors(scc_a) { - debug!( - "propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}", - scc_a, scc_b - ); + debug!("propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}", scc_a, scc_b); // ...compute the value of `B`... self.propagate_constraint_sccs_if_new(scc_b, visited); @@ -531,6 +598,16 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + // Now take member constraints into account. + let member_constraints = self.member_constraints.clone(); + for m_c_i in member_constraints.indices(scc_a) { + self.apply_member_constraint( + scc_a, + m_c_i, + member_constraints.choice_regions(m_c_i), + ); + } + debug!( "propagate_constraint_sccs: scc_a = {:?} has value {:?}", scc_a, @@ -538,6 +615,167 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); } + /// Invoked for each `R0 member of [R1..Rn]` constraint. + /// + /// `scc` is the SCC containing R0, and `choice_regions` are the + /// `R1..Rn` regions -- they are always known to be universal + /// regions (and if that's not true, we just don't attempt to + /// enforce the constraint). + /// + /// The current value of `scc` at the time the method is invoked + /// is considered a *lower bound*. If possible, we will modify + /// the constraint to set it equal to one of the option regions. + /// If we make any changes, returns true, else false. + fn apply_member_constraint( + &mut self, + scc: ConstraintSccIndex, + member_constraint_index: NllMemberConstraintIndex, + choice_regions: &[ty::RegionVid], + ) -> bool { + debug!("apply_member_constraint(scc={:?}, choice_regions={:#?})", scc, choice_regions,); + + if let Some(uh_oh) = + choice_regions.iter().find(|&&r| !self.universal_regions.is_universal_region(r)) + { + // FIXME(#61773): This case can only occur with + // `impl_trait_in_bindings`, I believe, and we are just + // opting not to handle it for now. See #61773 for + // details. + bug!( + "member constraint for `{:?}` has an option region `{:?}` \ + that is not a universal region", + self.member_constraints[member_constraint_index].opaque_type_def_id, + uh_oh, + ); + } + + // Create a mutable vector of the options. We'll try to winnow + // them down. + let mut choice_regions: Vec = choice_regions.to_vec(); + + // The 'member region' in a member constraint is part of the + // hidden type, which must be in the root universe. Therefore, + // it cannot have any placeholders in its value. + assert!(self.scc_universes[scc] == ty::UniverseIndex::ROOT); + debug_assert!( + self.scc_values.placeholders_contained_in(scc).next().is_none(), + "scc {:?} in a member constraint has placeholder value: {:?}", + scc, + self.scc_values.region_value_str(scc), + ); + + // The existing value for `scc` is a lower-bound. This will + // consist of some set `{P} + {LB}` of points `{P}` and + // lower-bound free regions `{LB}`. As each choice region `O` + // is a free region, it will outlive the points. But we can + // only consider the option `O` if `O: LB`. + choice_regions.retain(|&o_r| { + self.scc_values + .universal_regions_outlived_by(scc) + .all(|lb| self.universal_region_relations.outlives(o_r, lb)) + }); + debug!("apply_member_constraint: after lb, choice_regions={:?}", choice_regions); + + // Now find all the *upper bounds* -- that is, each UB is a + // free region that must outlive the member region `R0` (`UB: + // R0`). Therefore, we need only keep an option `O` if `UB: O` + // for all UB. + if choice_regions.len() > 1 { + let universal_region_relations = self.universal_region_relations.clone(); + let rev_constraint_graph = self.rev_constraint_graph(); + for ub in self.upper_bounds(scc, &rev_constraint_graph) { + debug!("apply_member_constraint: ub={:?}", ub); + choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r)); + } + debug!("apply_member_constraint: after ub, choice_regions={:?}", choice_regions); + } + + // If we ruled everything out, we're done. + if choice_regions.is_empty() { + return false; + } + + // Otherwise, we need to find the minimum remaining choice, if + // any, and take that. + debug!("apply_member_constraint: choice_regions remaining are {:#?}", choice_regions); + let min = |r1: ty::RegionVid, r2: ty::RegionVid| -> Option { + let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2); + let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1); + if r1_outlives_r2 && r2_outlives_r1 { + Some(r1.min(r2)) + } else if r1_outlives_r2 { + Some(r2) + } else if r2_outlives_r1 { + Some(r1) + } else { + None + } + }; + let mut min_choice = choice_regions[0]; + for &other_option in &choice_regions[1..] { + debug!( + "apply_member_constraint: min_choice={:?} other_option={:?}", + min_choice, other_option, + ); + match min(min_choice, other_option) { + Some(m) => min_choice = m, + None => { + debug!( + "apply_member_constraint: {:?} and {:?} are incomparable; no min choice", + min_choice, other_option, + ); + return false; + } + } + } + + let min_choice_scc = self.constraint_sccs.scc(min_choice); + debug!( + "apply_member_constraint: min_choice={:?} best_choice_scc={:?}", + min_choice, + min_choice_scc, + ); + if self.scc_values.add_region(scc, min_choice_scc) { + self.member_constraints_applied.push(AppliedMemberConstraint { + member_region_scc: scc, + min_choice, + member_constraint_index, + }); + + true + } else { + false + } + } + + /// Compute and return the reverse SCC-based constraint graph (lazilly). + fn upper_bounds( + &'a mut self, + scc0: ConstraintSccIndex, + rev_constraint_graph: &'a VecGraph, + ) -> impl Iterator + 'a { + let scc_values = &self.scc_values; + let mut duplicates = FxHashSet::default(); + rev_constraint_graph + .depth_first_search(scc0) + .skip(1) + .flat_map(move |scc1| scc_values.universal_regions_outlived_by(scc1)) + .filter(move |&r| duplicates.insert(r)) + } + + /// Compute and return the reverse SCC-based constraint graph (lazilly). + fn rev_constraint_graph( + &mut self, + ) -> Rc> { + if let Some(g) = &self.rev_constraint_graph { + return g.clone(); + } + + let rev_graph = Rc::new(self.constraint_sccs.reverse()); + self.rev_constraint_graph = Some(rev_graph.clone()); + rev_graph + } + /// Returns `true` if all the elements in the value of `scc_b` are nameable /// in `scc_a`. Used during constraint propagation, and only once /// the value of `scc_b` has been computed. @@ -554,9 +792,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Otherwise, we have to iterate over the universe elements in // B's value, and check whether all of them are nameable // from universe_a - self.scc_values - .placeholders_contained_in(scc_b) - .all(|p| universe_a.can_name(p.universe)) + self.scc_values.placeholders_contained_in(scc_b).all(|p| universe_a.can_name(p.universe)) } /// Extend `scc` so that it can outlive some placeholder region @@ -731,12 +967,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) -> bool { let tcx = infcx.tcx; - let TypeTest { - generic_kind, - lower_bound, - locations, - verify_bound: _, - } = type_test; + let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test; let generic_ty = generic_kind.to_ty(tcx); let subject = match self.try_promote_type_test_subject(infcx, generic_ty) { @@ -809,7 +1040,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { ty: Ty<'tcx>, ) -> Option> { let tcx = infcx.tcx; - let gcx = tcx.global_tcx(); debug!("try_promote_type_test_subject(ty = {:?})", ty); @@ -863,8 +1093,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); debug!("try_promote_type_test_subject: folded ty = {:?}", ty); - // `lift_to_global` will only fail if we failed to promote some region. - gcx.lift_to_global(&ty)?; + // `has_local_value` will only be true if we failed to promote some region. + if ty.has_local_value() { + return None; + } Some(ClosureOutlivesSubject::Ty(ty)) } @@ -885,11 +1117,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// except that it converts further takes the non-local upper /// bound of `'y`, so that the final result is non-local. fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid { - debug!( - "non_local_universal_upper_bound(r={:?}={})", - r, - self.region_value_str(r) - ); + debug!("non_local_universal_upper_bound(r={:?}={})", r, self.region_value_str(r)); let lub = self.universal_upper_bound(r); @@ -897,10 +1125,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // creator. let non_local_lub = self.universal_region_relations.non_local_upper_bound(lub); - debug!( - "non_local_universal_upper_bound: non_local_lub={:?}", - non_local_lub - ); + debug!("non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub); non_local_lub } @@ -920,11 +1145,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding /// a result `'y`. fn universal_upper_bound(&self, r: RegionVid) -> RegionVid { - debug!( - "universal_upper_bound(r={:?}={})", - r, - self.region_value_str(r) - ); + debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r)); // Find the smallest universal region that contains all other // universal regions within `region`. @@ -949,10 +1170,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { lower_bound: RegionVid, verify_bound: &VerifyBound<'tcx>, ) -> bool { - debug!( - "eval_verify_bound(lower_bound={:?}, verify_bound={:?})", - lower_bound, verify_bound - ); + debug!("eval_verify_bound(lower_bound={:?}, verify_bound={:?})", lower_bound, verify_bound); match verify_bound { VerifyBound::IfEq(test_ty, verify_bound1) => { @@ -961,7 +1179,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { VerifyBound::OutlivedBy(r) => { let r_vid = self.to_region_vid(r); - self.eval_outlives(body, r_vid, lower_bound) + self.eval_outlives(r_vid, lower_bound) } VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| { @@ -1034,22 +1252,24 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) } - // Evaluate whether `sup_region: sub_region @ point`. - fn eval_outlives( - &self, - _body: &Body<'tcx>, - sup_region: RegionVid, - sub_region: RegionVid, - ) -> bool { + // Evaluate whether `sup_region == sub_region`. + fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool { + self.eval_outlives(r1, r2) && self.eval_outlives(r2, r1) + } + + // Evaluate whether `sup_region: sub_region`. + fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool { debug!("eval_outlives({:?}: {:?})", sup_region, sub_region); debug!( - "eval_outlives: sup_region's value = {:?}", + "eval_outlives: sup_region's value = {:?} universal={:?}", self.region_value_str(sup_region), + self.universal_regions.is_universal_region(sup_region), ); debug!( - "eval_outlives: sub_region's value = {:?}", + "eval_outlives: sub_region's value = {:?} universal={:?}", self.region_value_str(sub_region), + self.universal_regions.is_universal_region(sub_region), ); let sub_region_scc = self.constraint_sccs.scc(sub_region); @@ -1061,9 +1281,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // now). Therefore, the sup-region outlives the sub-region if, // for each universal region R1 in the sub-region, there // exists some region R2 in the sup-region that outlives R1. - let universal_outlives = self.scc_values - .universal_regions_outlived_by(sub_region_scc) - .all(|r1| { + let universal_outlives = + self.scc_values.universal_regions_outlived_by(sub_region_scc).all(|r1| { self.scc_values .universal_regions_outlived_by(sup_region_scc) .any(|r2| self.universal_region_relations.outlives(r2, r1)) @@ -1081,8 +1300,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { return true; } - self.scc_values - .contains_points(sup_region_scc, sub_region_scc) + self.scc_values.contains_points(sup_region_scc, sub_region_scc) } /// Once regions have been propagated, this method is used to see @@ -1164,12 +1382,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Because this free region must be in the ROOT universe, we // know it cannot contain any bound universes. assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT); - debug_assert!( - self.scc_values - .placeholders_contained_in(longer_fr_scc) - .next() - .is_none() - ); + debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none()); // Only check all of the relations for the main representative of each // SCC, otherwise just check that we outlive said representative. This @@ -1223,9 +1436,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { errors_buffer: &mut Vec, ) -> Option { // If it is known that `fr: o`, carry on. - if self.universal_region_relations - .outlives(longer_fr, shorter_fr) - { + if self.universal_region_relations.outlives(longer_fr, shorter_fr) { return None; } @@ -1239,9 +1450,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // We'll call it `fr-` -- it's ever so slightly smaller than // `longer_fr`. - if let Some(fr_minus) = self - .universal_region_relations - .non_local_lower_bound(longer_fr) + if let Some(fr_minus) = self.universal_region_relations.non_local_lower_bound(longer_fr) { debug!("check_universal_region: fr_minus={:?}", fr_minus); @@ -1251,12 +1460,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Grow `shorter_fr` until we find some non-local regions. (We // always will.) We'll call them `shorter_fr+` -- they're ever // so slightly larger than `shorter_fr`. - let shorter_fr_plus = self.universal_region_relations - .non_local_upper_bounds(&shorter_fr); - debug!( - "check_universal_region: shorter_fr_plus={:?}", - shorter_fr_plus - ); + let shorter_fr_plus = + self.universal_region_relations.non_local_upper_bounds(&shorter_fr); + debug!("check_universal_region: shorter_fr_plus={:?}", shorter_fr_plus); for &&fr in &shorter_fr_plus { // Push the constraint `fr-: shorter_fr+` propagated_outlives_requirements.push(ClosureOutlivesRequirement { @@ -1288,28 +1494,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { longer_fr: RegionVid, placeholder: ty::PlaceholderRegion, ) { - debug!( - "check_bound_universal_region(fr={:?}, placeholder={:?})", - longer_fr, placeholder, - ); + debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,); let longer_fr_scc = self.constraint_sccs.scc(longer_fr); - debug!( - "check_bound_universal_region: longer_fr_scc={:?}", - longer_fr_scc, - ); + debug!("check_bound_universal_region: longer_fr_scc={:?}", longer_fr_scc,); // If we have some bound universal region `'a`, then the only // elements it can contain is itself -- we don't know anything // else about it! let error_element = match { - self.scc_values - .elements_contained_in(longer_fr_scc) - .find(|element| match element { - RegionElement::Location(_) => true, - RegionElement::RootUniversalRegion(_) => true, - RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1, - }) + self.scc_values.elements_contained_in(longer_fr_scc).find(|element| match element { + RegionElement::Location(_) => true, + RegionElement::RootUniversalRegion(_) => true, + RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1, + }) } { Some(v) => v, None => return, @@ -1320,7 +1518,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { let error_region = match error_element { RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), RegionElement::RootUniversalRegion(r) => r, - RegionElement::PlaceholderRegion(error_placeholder) => self.definitions + RegionElement::PlaceholderRegion(error_placeholder) => self + .definitions .iter_enumerated() .filter_map(|(r, definition)| match definition.origin { NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), @@ -1338,12 +1537,50 @@ impl<'tcx> RegionInferenceContext<'tcx> { // the AST-based checker uses a more conservative check, // so to even see this error, one must pass in a special // flag. - let mut diag = infcx - .tcx - .sess - .struct_span_err(span, "higher-ranked subtype error"); + let mut diag = infcx.tcx.sess.struct_span_err(span, "higher-ranked subtype error"); diag.emit(); } + + fn check_member_constraints( + &self, + infcx: &InferCtxt<'_, 'tcx>, + mir_def_id: DefId, + errors_buffer: &mut Vec, + ) { + let member_constraints = self.member_constraints.clone(); + for m_c_i in member_constraints.all_indices() { + debug!("check_member_constraint(m_c_i={:?})", m_c_i); + let m_c = &member_constraints[m_c_i]; + let member_region_vid = m_c.member_region_vid; + debug!( + "check_member_constraint: member_region_vid={:?} with value {}", + member_region_vid, + self.region_value_str(member_region_vid), + ); + let choice_regions = member_constraints.choice_regions(m_c_i); + debug!("check_member_constraint: choice_regions={:?}", choice_regions); + + // Did the member region wind up equal to any of the option regions? + if let Some(o) = choice_regions.iter().find(|&&o_r| { + self.eval_equal(o_r, m_c.member_region_vid) + }) { + debug!("check_member_constraint: evaluated as equal to {:?}", o); + continue; + } + + // If not, report an error. + let region_scope_tree = &infcx.tcx.region_scope_tree(mir_def_id); + let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid)); + opaque_types::unexpected_hidden_region_diagnostic( + infcx.tcx, + Some(region_scope_tree), + m_c.opaque_type_def_id, + m_c.hidden_ty, + member_region, + ) + .buffer(errors_buffer); + } + } } impl<'tcx> RegionDefinition<'tcx> { @@ -1357,11 +1594,7 @@ impl<'tcx> RegionDefinition<'tcx> { _ => NLLRegionVariableOrigin::Existential, }; - Self { - origin, - universe, - external_name: None, - } + Self { origin, universe, external_name: None } } } @@ -1371,7 +1604,7 @@ pub trait ClosureRegionRequirementsExt<'tcx> { tcx: TyCtxt<'tcx>, closure_def_id: DefId, closure_substs: SubstsRef<'tcx>, - ) -> Vec>; + ) -> Vec>; fn subst_closure_mapping( &self, @@ -1401,7 +1634,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx tcx: TyCtxt<'tcx>, closure_def_id: DefId, closure_substs: SubstsRef<'tcx>, - ) -> Vec> { + ) -> Vec> { debug!( "apply_requirements(closure_def_id={:?}, closure_substs={:?})", closure_def_id, closure_substs @@ -1464,10 +1697,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx if let ty::ReClosureBound(vid) = r { closure_mapping[*vid] } else { - bug!( - "subst_closure_mapping: encountered non-closure bound free region {:?}", - r - ) + bug!("subst_closure_mapping: encountered non-closure bound free region {:?}", r) } }) } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index cfd80cecca510..6f9f5707935ba 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -162,7 +162,7 @@ impl LivenessValues { } /// Iterate through each region that has a value in this set. - crate fn rows<'a>(&'a self) -> impl Iterator { + crate fn rows(&self) -> impl Iterator { self.points.rows() } diff --git a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs index 77a4d2699fff7..8de014522dea7 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs @@ -3,7 +3,8 @@ use crate::borrow_check::nll::region_infer::TypeTest; use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; use crate::borrow_check::nll::universal_regions::UniversalRegions; use crate::borrow_check::nll::ToRegionVid; -use rustc::infer::canonical::QueryRegionConstraint; +use rustc::infer::canonical::QueryRegionConstraints; +use rustc::infer::canonical::QueryOutlivesConstraint; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc::infer::region_constraints::{GenericKind, VerifyBound}; @@ -49,13 +50,33 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } } - pub(super) fn convert_all(&mut self, query_constraints: &[QueryRegionConstraint<'tcx>]) { - for query_constraint in query_constraints { + pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) { + debug!("convert_all(query_constraints={:#?})", query_constraints); + + let QueryRegionConstraints { outlives, member_constraints } = query_constraints; + + // Annoying: to invoke `self.to_region_vid`, we need access to + // `self.constraints`, but we also want to be mutating + // `self.member_constraints`. For now, just swap out the value + // we want and replace at the end. + let mut tmp = std::mem::replace( + &mut self.constraints.member_constraints, + Default::default(), + ); + for member_constraint in member_constraints { + tmp.push_constraint( + member_constraint, + |r| self.to_region_vid(r), + ); + } + self.constraints.member_constraints = tmp; + + for query_constraint in outlives { self.convert(query_constraint); } } - pub(super) fn convert(&mut self, query_constraint: &QueryRegionConstraint<'tcx>) { + pub(super) fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) { debug!("generate: constraints at: {:#?}", self.locations); // Extract out various useful fields we'll need below. diff --git a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs index 1bb3acc28f0c8..d18a8e87453a5 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs @@ -2,7 +2,7 @@ use crate::borrow_check::nll::type_check::constraint_conversion; use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; use crate::borrow_check::nll::universal_regions::UniversalRegions; use crate::borrow_check::nll::ToRegionVid; -use rustc::infer::canonical::QueryRegionConstraint; +use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::outlives::free_region_map::FreeRegionRelations; use rustc::infer::region_constraints::GenericKind; use rustc::infer::InferCtxt; @@ -287,7 +287,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { self.relations.relate_universal_regions(fr, fr_fn_body); } - for data in constraint_sets { + for data in &constraint_sets { constraint_conversion::ConstraintConversion::new( self.infcx, &self.universal_regions, @@ -297,7 +297,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { Locations::All(DUMMY_SP), ConstraintCategory::Internal, &mut self.constraints, - ).convert_all(&data); + ).convert_all(data); } CreateResult { @@ -311,7 +311,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { /// either the return type of the MIR or one of its arguments. At /// the same time, compute and add any implied bounds that come /// from this local. - fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option>>> { + fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option>> { debug!("add_implied_bounds(ty={:?})", ty); let (bounds, constraints) = self.param_env diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs index 3b138bc126257..4af78fa5e0f42 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs @@ -1,5 +1,5 @@ use crate::borrow_check::location::LocationTable; -use crate::borrow_check::nll::constraints::ConstraintSet; +use crate::borrow_check::nll::constraints::OutlivesConstraintSet; use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt}; use crate::borrow_check::nll::region_infer::values::RegionValueElements; use crate::borrow_check::nll::universal_regions::UniversalRegions; @@ -107,7 +107,7 @@ fn compute_live_locals( fn regions_that_outlive_free_regions( num_region_vars: usize, universal_regions: &UniversalRegions<'tcx>, - constraint_set: &ConstraintSet, + constraint_set: &OutlivesConstraintSet, ) -> FxHashSet { // Build a graph of the outlives constraints thus far. This is // a reverse graph, so for each constraint `R1: R2` we have an diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index f1d568f0cf24c..f160f658f5576 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -6,7 +6,7 @@ use crate::borrow_check::nll::type_check::TypeChecker; use crate::dataflow::indexes::MovePathIndex; use crate::dataflow::move_paths::MoveData; use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces}; -use rustc::infer::canonical::QueryRegionConstraint; +use rustc::infer::canonical::QueryRegionConstraints; use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Body}; use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; @@ -88,7 +88,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { struct DropData<'tcx> { dropck_result: DropckOutlivesResult<'tcx>, - region_constraint_data: Option>>>, + region_constraint_data: Option>>, } struct LivenessResults<'me, 'typeck, 'flow, 'tcx> { diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 9409fefb6bde7..cdbbe1d02bd92 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -4,7 +4,8 @@ use crate::borrow_check::borrow_set::BorrowSet; use crate::borrow_check::location::LocationTable; -use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConstraint}; +use crate::borrow_check::nll::member_constraints::MemberConstraintSet; use crate::borrow_check::nll::facts::AllFacts; use crate::borrow_check::nll::region_infer::values::LivenessValues; use crate::borrow_check::nll::region_infer::values::PlaceholderIndex; @@ -23,7 +24,7 @@ use crate::dataflow::MaybeInitializedPlaces; use either::Either; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::infer::canonical::QueryRegionConstraint; +use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -127,7 +128,8 @@ pub(crate) fn type_check<'tcx>( placeholder_indices: PlaceholderIndices::default(), placeholder_index_to_region: IndexVec::default(), liveness_constraints: LivenessValues::new(elements.clone()), - outlives_constraints: ConstraintSet::default(), + outlives_constraints: OutlivesConstraintSet::default(), + member_constraints: MemberConstraintSet::default(), closure_bounds_mapping: Default::default(), type_tests: Vec::default(), }; @@ -215,7 +217,7 @@ fn translate_outlives_facts(cx: &mut BorrowCheckContext<'_, '_>) { let location_table = cx.location_table; facts .outlives - .extend(cx.constraints.outlives_constraints.iter().flat_map( + .extend(cx.constraints.outlives_constraints.outlives().iter().flat_map( |constraint: &OutlivesConstraint| { if let Some(from_location) = constraint.locations.from_location() { Either::Left(iter::once(( @@ -582,7 +584,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { ); let locations = location.to_locations(); - for constraint in constraints.iter() { + for constraint in constraints.outlives().iter() { let mut constraint = *constraint; constraint.locations = locations; if let ConstraintCategory::Return @@ -834,6 +836,7 @@ struct TypeChecker<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, last_span: Span, + body: &'a Body<'tcx>, /// User type annotations are shared between the main MIR and the MIR of /// all of the promoted items. user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, @@ -884,7 +887,9 @@ crate struct MirTypeckRegionConstraints<'tcx> { /// hence it must report on their liveness constraints. crate liveness_constraints: LivenessValues, - crate outlives_constraints: ConstraintSet, + crate outlives_constraints: OutlivesConstraintSet, + + crate member_constraints: MemberConstraintSet<'tcx, RegionVid>, crate closure_bounds_mapping: FxHashMap>, @@ -992,6 +997,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { infcx, last_span: DUMMY_SP, mir_def_id, + body, user_type_annotations: &body.user_type_annotations, param_env, region_bound_pairs, @@ -1093,7 +1099,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, locations: Locations, category: ConstraintCategory, - data: &[QueryRegionConstraint<'tcx>], + data: &QueryRegionConstraints<'tcx>, ) { debug!( "push_region_constraints: constraints generated at {:?} are {:#?}", @@ -1109,7 +1115,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations, category, &mut self.borrowck_context.constraints, - ).convert_all(&data); + ).convert_all(data); } /// Convenient wrapper around `relate_tys::relate_types` -- see @@ -1229,6 +1235,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let infcx = self.infcx; let tcx = infcx.tcx; let param_env = self.param_env; + let body = self.body; debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id); let opaque_type_map = self.fully_perform_op( locations, @@ -1244,6 +1251,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { dummy_body_id, param_env, &anon_ty, + locations.span(body), )); debug!( "eq_opaque_type_and_type: \ @@ -2508,10 +2516,20 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { location: Location, ) -> ty::InstantiatedPredicates<'tcx> { if let Some(closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements { - let closure_constraints = - closure_region_requirements.apply_requirements(tcx, def_id, substs); + let closure_constraints = QueryRegionConstraints { + outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs), + + // Presently, closures never propagate member + // constraints to their parents -- they are enforced + // locally. This is largely a non-issue as member + // constraints only come from `-> impl Trait` and + // friends which don't appear (thus far...) in + // closures. + member_constraints: vec![], + }; let bounds_mapping = closure_constraints + .outlives .iter() .enumerate() .filter_map(|(idx, constraint)| { diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index aa2b177e54ed8..538ac6881d90a 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -130,7 +130,7 @@ pub(super) fn is_active<'tcx>( /// Determines if a given borrow is borrowing local data /// This is called for all Yield statements on movable generators -pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool { +pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { place.iterate(|place_base, place_projection| { match place_base { PlaceBase::Static(..) => return false, diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 222ce6d1c968e..f679a00035d76 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -31,7 +31,7 @@ pub enum RvalueFunc { /// Determines the category for a given expression. Note that scope /// and paren expressions have no category. impl Category { - pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option { + pub fn of(ek: &ExprKind<'_>) -> Option { match *ek { ExprKind::Scope { .. } => None, diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index b1b5233fbc875..7125eb6850bb6 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'pat, 'tcx>) { // repeatedly simplify match pairs until fixed point is reached loop { - let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]); + let match_pairs = mem::take(&mut candidate.match_pairs); let mut changed = false; for match_pair in match_pairs { match self.simplify_match_pair(match_pair, candidate) { diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 95e2e52092a91..528dfbef6946a 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -826,6 +826,6 @@ impl Test<'_> { } } -fn is_switch_ty<'tcx>(ty: Ty<'tcx>) -> bool { +fn is_switch_ty(ty: Ty<'_>) -> bool { ty.is_integral() || ty.is_char() || ty.is_bool() } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index ad970de466cfd..80a035d8287f4 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -22,7 +22,7 @@ use syntax_pos::Span; use super::lints; /// Construct the MIR for a given `DefId`. -pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> { +pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); // Figure out what primary body this item has. @@ -171,11 +171,11 @@ pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> { /////////////////////////////////////////////////////////////////////////// // BuildMir -- walks a crate, looking for fn items and methods to build MIR from -fn liberated_closure_env_ty<'tcx>( - tcx: TyCtxt<'tcx>, +fn liberated_closure_env_ty( + tcx: TyCtxt<'_>, closure_expr_id: hir::HirId, body_id: hir::BodyId, -) -> Ty<'tcx> { +) -> Ty<'_> { let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_id); let (closure_def_id, closure_substs) = match closure_ty.sty { @@ -485,7 +485,7 @@ macro_rules! unpack { }; } -fn should_abort_on_panic<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: DefId, abi: Abi) -> bool { +fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool { // Not callable from C, so we can safely unwind through these if abi == Abi::Rust || abi == Abi::RustCall { return false; } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 4d5a2ccf659bb..e95ef0caaafaf 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -22,7 +22,7 @@ use syntax::source_map::{Span, DUMMY_SP}; use crate::interpret::{self, PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, RawConst, ConstValue, - InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpretCx, StackPopCleanup, + InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup, Allocation, AllocId, MemoryKind, Memory, snapshot, RefTracking, intern_const_alloc_recursive, }; @@ -34,7 +34,7 @@ const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000; /// Should be a power of two for performance reasons. const DETECTOR_SNAPSHOT_PERIOD: isize = 256; -/// The `InterpretCx` is only meant to be used to do field and index projections into constants for +/// The `InterpCx` is only meant to be used to do field and index projections into constants for /// `simd_shuffle` and const patterns in match arms. /// /// The function containing the `match` that is currently being analyzed may have generic bounds @@ -47,7 +47,7 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> CompileTimeEvalContext<'mir, 'tcx> { debug!("mk_eval_cx: {:?}", param_env); - InterpretCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default()) + InterpCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default()) } pub(crate) fn eval_promoted<'mir, 'tcx>( @@ -303,7 +303,7 @@ impl interpret::AllocMap for FxHashMap { } crate type CompileTimeEvalContext<'mir, 'tcx> = - InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; + InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; impl interpret::MayLeak for ! { #[inline(always)] @@ -326,12 +326,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, const STATIC_KIND: Option = None; // no copying of statics allowed #[inline(always)] - fn enforce_validity(_ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool { + fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { false // for now, we don't enforce validity } fn find_fn( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], dest: Option>, @@ -371,7 +371,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn call_intrinsic( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], dest: PlaceTy<'tcx>, @@ -387,7 +387,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn ptr_op( - _ecx: &InterpretCx<'mir, 'tcx, Self>, + _ecx: &InterpCx<'mir, 'tcx, Self>, _bin_op: mir::BinOp, _left: ImmTy<'tcx>, _right: ImmTy<'tcx>, @@ -424,7 +424,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn box_alloc( - _ecx: &mut InterpretCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'mir, 'tcx, Self>, _dest: PlaceTy<'tcx>, ) -> InterpResult<'tcx> { Err( @@ -432,7 +432,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) } - fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { { let steps = &mut ecx.machine.steps_since_detector_enabled; @@ -457,13 +457,13 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } #[inline(always)] - fn stack_push(_ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { Ok(()) } /// Called immediately before a stack frame gets popped. #[inline(always)] - fn stack_pop(_ecx: &mut InterpretCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> { + fn stack_pop(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> { Ok(()) } } @@ -508,7 +508,7 @@ pub fn const_variant_index<'tcx>( } pub fn error_to_const_error<'mir, 'tcx>( - ecx: &InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, mut error: InterpErrorInfo<'tcx>, ) -> ConstEvalErr<'tcx> { error.print_backtrace(); @@ -632,7 +632,7 @@ pub fn const_eval_raw_provider<'tcx>( } let span = tcx.def_span(cid.instance.def_id()); - let mut ecx = InterpretCx::new( + let mut ecx = InterpCx::new( tcx.at(span), key.param_env, CompileTimeInterpreter::new(), diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index 7735528d8f8e0..f0014602e2d6b 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -8,6 +8,7 @@ use crate::dataflow::{BitDenotation, DataflowResults, GenKillSet}; use crate::dataflow::move_paths::{HasMoveData, MovePathIndex}; use std::iter; +use std::borrow::Borrow; /// A trait for "cartesian products" of multiple FlowAtLocation. /// @@ -60,18 +61,20 @@ pub trait FlowsAtLocation { /// (e.g., via `reconstruct_statement_effect` and /// `reconstruct_terminator_effect`; don't forget to call /// `apply_local_effect`). -pub struct FlowAtLocation<'tcx, BD> +pub struct FlowAtLocation<'tcx, BD, DR = DataflowResults<'tcx, BD>> where BD: BitDenotation<'tcx>, + DR: Borrow>, { - base_results: DataflowResults<'tcx, BD>, + base_results: DR, curr_state: BitSet, stmt_trans: GenKillSet, } -impl<'tcx, BD> FlowAtLocation<'tcx, BD> +impl<'tcx, BD, DR> FlowAtLocation<'tcx, BD, DR> where BD: BitDenotation<'tcx>, + DR: Borrow>, { /// Iterate over each bit set in the current state. pub fn each_state_bit(&self, f: F) @@ -91,8 +94,8 @@ where self.stmt_trans.gen_set.iter().for_each(f) } - pub fn new(results: DataflowResults<'tcx, BD>) -> Self { - let bits_per_block = results.sets().bits_per_block(); + pub fn new(results: DR) -> Self { + let bits_per_block = results.borrow().sets().bits_per_block(); let curr_state = BitSet::new_empty(bits_per_block); let stmt_trans = GenKillSet::from_elem(HybridBitSet::new_empty(bits_per_block)); FlowAtLocation { @@ -104,7 +107,7 @@ where /// Access the underlying operator. pub fn operator(&self) -> &BD { - self.base_results.operator() + self.base_results.borrow().operator() } pub fn contains(&self, x: BD::Idx) -> bool { @@ -134,27 +137,31 @@ where } } -impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> - where BD: BitDenotation<'tcx> +impl<'tcx, BD, DR> FlowsAtLocation for FlowAtLocation<'tcx, BD, DR> +where + BD: BitDenotation<'tcx>, + DR: Borrow>, { fn reset_to_entry_of(&mut self, bb: BasicBlock) { - self.curr_state.overwrite(self.base_results.sets().entry_set_for(bb.index())); + self.curr_state.overwrite(self.base_results.borrow().sets().entry_set_for(bb.index())); } fn reset_to_exit_of(&mut self, bb: BasicBlock) { self.reset_to_entry_of(bb); - let trans = self.base_results.sets().trans_for(bb.index()); + let trans = self.base_results.borrow().sets().trans_for(bb.index()); trans.apply(&mut self.curr_state) } fn reconstruct_statement_effect(&mut self, loc: Location) { self.stmt_trans.clear(); self.base_results + .borrow() .operator() .before_statement_effect(&mut self.stmt_trans, loc); self.stmt_trans.apply(&mut self.curr_state); self.base_results + .borrow() .operator() .statement_effect(&mut self.stmt_trans, loc); } @@ -162,11 +169,13 @@ impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> fn reconstruct_terminator_effect(&mut self, loc: Location) { self.stmt_trans.clear(); self.base_results + .borrow() .operator() .before_terminator_effect(&mut self.stmt_trans, loc); self.stmt_trans.apply(&mut self.curr_state); self.base_results + .borrow() .operator() .terminator_effect(&mut self.stmt_trans, loc); } @@ -177,9 +186,10 @@ impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> } -impl<'tcx, T> FlowAtLocation<'tcx, T> +impl<'tcx, T, DR> FlowAtLocation<'tcx, T, DR> where T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>, + DR: Borrow>, { pub fn has_any_child_of(&self, mpi: T::Idx) -> Option { // We process `mpi` before the loop below, for two reasons: diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 0f7f37f2db8b4..d94ebdbae24ae 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -92,7 +92,7 @@ struct BorrowedLocalsVisitor<'gk> { trans: &'gk mut GenKillSet, } -fn find_local<'tcx>(place: &Place<'tcx>) -> Option { +fn find_local(place: &Place<'_>) -> Option { place.iterate(|place_base, place_projection| { for proj in place_projection { if proj.elem == ProjectionElem::Deref { diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index d2003993d4506..7fa950cb98d34 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -1,7 +1,13 @@ pub use super::*; use rustc::mir::*; +use rustc::mir::visit::{ + PlaceContext, Visitor, NonMutatingUseContext, +}; +use std::cell::RefCell; use crate::dataflow::BitDenotation; +use crate::dataflow::HaveBeenBorrowedLocals; +use crate::dataflow::{DataflowResults, DataflowResultsCursor, DataflowResultsRefCursor}; #[derive(Copy, Clone)] pub struct MaybeStorageLive<'a, 'tcx> { @@ -27,7 +33,9 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { } fn start_block_effect(&self, _on_entry: &mut BitSet) { - // Nothing is live on function entry + // Nothing is live on function entry (generators only have a self + // argument, and we don't care about that) + assert_eq!(1, self.body.arg_count); } fn statement_effect(&self, @@ -63,3 +71,123 @@ impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> { /// bottom = dead const BOTTOM_VALUE: bool = false; } + +/// Dataflow analysis that determines whether each local requires storage at a +/// given location; i.e. whether its storage can go away without being observed. +pub struct RequiresStorage<'mir, 'tcx> { + body: &'mir Body<'tcx>, + borrowed_locals: + RefCell>>, +} + +impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> { + pub fn new( + body: &'mir Body<'tcx>, + borrowed_locals: &'mir DataflowResults<'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>, + ) -> Self { + RequiresStorage { + body, + borrowed_locals: RefCell::new(DataflowResultsCursor::new(borrowed_locals, body)), + } + } + + pub fn body(&self) -> &Body<'tcx> { + self.body + } +} + +impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { + type Idx = Local; + fn name() -> &'static str { "requires_storage" } + fn bits_per_block(&self) -> usize { + self.body.local_decls.len() + } + + fn start_block_effect(&self, _sets: &mut BitSet) { + // Nothing is live on function entry (generators only have a self + // argument, and we don't care about that) + assert_eq!(1, self.body.arg_count); + } + + fn statement_effect(&self, + sets: &mut GenKillSet, + loc: Location) { + self.check_for_move(sets, loc); + self.check_for_borrow(sets, loc); + + let stmt = &self.body[loc.block].statements[loc.statement_index]; + match stmt.kind { + StatementKind::StorageLive(l) => sets.gen(l), + StatementKind::StorageDead(l) => sets.kill(l), + StatementKind::Assign(ref place, _) + | StatementKind::SetDiscriminant { ref place, .. } => { + place.base_local().map(|l| sets.gen(l)); + } + StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => { + for p in &**outputs { + p.base_local().map(|l| sets.gen(l)); + } + } + _ => (), + } + } + + fn terminator_effect(&self, + sets: &mut GenKillSet, + loc: Location) { + self.check_for_move(sets, loc); + self.check_for_borrow(sets, loc); + } + + fn propagate_call_return( + &self, + in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_place: &mir::Place<'tcx>, + ) { + dest_place.base_local().map(|l| in_out.insert(l)); + } +} + +impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> { + /// Kill locals that are fully moved and have not been borrowed. + fn check_for_move(&self, sets: &mut GenKillSet, loc: Location) { + let mut visitor = MoveVisitor { + sets, + borrowed_locals: &self.borrowed_locals, + }; + visitor.visit_location(self.body, loc); + } + + /// Gen locals that are newly borrowed. This includes borrowing any part of + /// a local (we rely on this behavior of `HaveBeenBorrowedLocals`). + fn check_for_borrow(&self, sets: &mut GenKillSet, loc: Location) { + let mut borrowed_locals = self.borrowed_locals.borrow_mut(); + borrowed_locals.seek(loc); + borrowed_locals.each_gen_bit(|l| sets.gen(l)); + } +} + +impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> { + /// bottom = dead + const BOTTOM_VALUE: bool = false; +} + +struct MoveVisitor<'a, 'mir, 'tcx> { + borrowed_locals: + &'a RefCell>>, + sets: &'a mut GenKillSet, +} + +impl<'a, 'mir: 'a, 'tcx> Visitor<'tcx> for MoveVisitor<'a, 'mir, 'tcx> { + fn visit_local(&mut self, local: &Local, context: PlaceContext, loc: Location) { + if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context { + let mut borrowed_locals = self.borrowed_locals.borrow_mut(); + borrowed_locals.seek(loc); + if !borrowed_locals.contains(*local) { + self.sets.kill(*local); + } + } + } +} diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 80f65a9c8d04e..5433a9013aa85 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -17,7 +17,7 @@ use std::io; use std::path::PathBuf; use std::usize; -pub use self::impls::{MaybeStorageLive}; +pub use self::impls::{MaybeStorageLive, RequiresStorage}; pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; pub use self::impls::DefinitelyInitializedPlaces; pub use self::impls::EverInitializedPlaces; @@ -228,9 +228,25 @@ where BD: BitDenotation<'tcx>, { fn walk_cfg(&mut self, in_out: &mut BitSet) { - let mut dirty_queue: WorkQueue = - WorkQueue::with_all(self.builder.body.basic_blocks().len()); let body = self.builder.body; + + // Initialize the dirty queue in reverse post-order. This makes it more likely that the + // entry state for each basic block will have the effects of its predecessors applied + // before it is processed. In fact, for CFGs without back edges, this guarantees that + // dataflow will converge in exactly `N` iterations, where `N` is the number of basic + // blocks. + let mut dirty_queue: WorkQueue = + WorkQueue::with_none(body.basic_blocks().len()); + for (bb, _) in traversal::reverse_postorder(body) { + dirty_queue.insert(bb); + } + + // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will + // be processed after the ones added above. + for bb in body.basic_blocks().indices() { + dirty_queue.insert(bb); + } + while let Some(bb) = dirty_queue.pop() { let (on_entry, trans) = self.builder.flow_state.sets.get_mut(bb.index()); debug_assert!(in_out.words().len() == on_entry.words().len()); @@ -344,6 +360,99 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> { fn body(&self) -> &'a Body<'tcx>; } +/// Allows iterating dataflow results in a flexible and reasonably fast way. +pub struct DataflowResultsCursor<'mir, 'tcx, BD, DR = DataflowResults<'tcx, BD>> +where + BD: BitDenotation<'tcx>, + DR: Borrow>, +{ + flow_state: FlowAtLocation<'tcx, BD, DR>, + + // The statement (or terminator) whose effect has been reconstructed in + // flow_state. + curr_loc: Option, + + body: &'mir Body<'tcx>, +} + +pub type DataflowResultsRefCursor<'mir, 'tcx, BD> = + DataflowResultsCursor<'mir, 'tcx, BD, &'mir DataflowResults<'tcx, BD>>; + +impl<'mir, 'tcx, BD, DR> DataflowResultsCursor<'mir, 'tcx, BD, DR> +where + BD: BitDenotation<'tcx>, + DR: Borrow>, +{ + pub fn new(result: DR, body: &'mir Body<'tcx>) -> Self { + DataflowResultsCursor { + flow_state: FlowAtLocation::new(result), + curr_loc: None, + body, + } + } + + /// Seek to the given location in MIR. This method is fast if you are + /// traversing your MIR statements in order. + /// + /// After calling `seek`, the current state will reflect all effects up to + /// and including the `before_statement_effect` of the statement at location + /// `loc`. The `statement_effect` of the statement at `loc` will be + /// available as the current effect (see e.g. `each_gen_bit`). + /// + /// If `loc.statement_index` equals the number of statements in the block, + /// we will reconstruct the terminator effect in the same way as described + /// above. + pub fn seek(&mut self, loc: Location) { + if self.curr_loc.map(|cur| loc == cur).unwrap_or(false) { + return; + } + + let start_index; + let should_reset = match self.curr_loc { + None => true, + Some(cur) + if loc.block != cur.block || loc.statement_index < cur.statement_index => true, + _ => false, + }; + if should_reset { + self.flow_state.reset_to_entry_of(loc.block); + start_index = 0; + } else { + let curr_loc = self.curr_loc.unwrap(); + start_index = curr_loc.statement_index; + // Apply the effect from the last seek to the current state. + self.flow_state.apply_local_effect(curr_loc); + } + + for stmt in start_index..loc.statement_index { + let mut stmt_loc = loc; + stmt_loc.statement_index = stmt; + self.flow_state.reconstruct_statement_effect(stmt_loc); + self.flow_state.apply_local_effect(stmt_loc); + } + + if loc.statement_index == self.body[loc.block].statements.len() { + self.flow_state.reconstruct_terminator_effect(loc); + } else { + self.flow_state.reconstruct_statement_effect(loc); + } + self.curr_loc = Some(loc); + } + + /// Return whether the current state contains bit `x`. + pub fn contains(&self, x: BD::Idx) -> bool { + self.flow_state.contains(x) + } + + /// Iterate over each `gen` bit in the current effect (invoke `seek` first). + pub fn each_gen_bit(&self, f: F) + where + F: FnMut(BD::Idx), + { + self.flow_state.each_gen_bit(f) + } +} + pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location, analysis: &T, result: &DataflowResults<'tcx, T>, diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs index 946d66fc91d7d..c365cc2ad8544 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir/hair/cx/to_ref.rs @@ -1,7 +1,7 @@ use crate::hair::*; use rustc::hir; -use syntax::ptr::P; +use rustc::hir::ptr::P; pub trait ToRef { type Output; diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index fc2951895f3fe..d356194c00343 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -835,7 +835,7 @@ impl<'tcx> IntRange<'tcx> { fn from_ctor(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) -> Option> { // Floating-point ranges are permitted and we don't want // to consider them when constructing integer ranges. - fn is_integral<'tcx>(ty: Ty<'tcx>) -> bool { + fn is_integral(ty: Ty<'_>) -> bool { match ty.sty { ty::Char | ty::Int(_) | ty::Uint(_) => true, _ => false, diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index ed850379af60b..915ce9f20d07d 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -18,15 +18,15 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc::hir::def::*; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use rustc::hir::ptr::P; use rustc::hir::{self, Pat, PatKind}; use smallvec::smallvec; use std::slice; -use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -pub(crate) fn check_match<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: DefId) { let body_id = if let Some(id) = tcx.hir().as_local_hir_id(def_id) { tcx.hir().body_owned_by(id) } else { @@ -43,7 +43,7 @@ pub(crate) fn check_match<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { }.visit_body(tcx.hir().body(body_id)); } -fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> DiagnosticBuilder<'a> { +fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> { struct_span_err!(sess, sp, E0004, "{}", &error_message) } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index cf597ce0b6319..6ba2f58776849 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -20,13 +20,13 @@ use rustc::ty::layout::{VariantIdx, Size}; use rustc::hir::{self, PatKind, RangeEnd}; use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; +use rustc::hir::ptr::P; use rustc_data_structures::indexed_vec::Idx; use std::cmp::Ordering; use std::fmt; use syntax::ast; -use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::Span; diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index fbacdf6cd93bb..d61fb87336ccf 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -1,7 +1,7 @@ use rustc::ty::{self, Ty, TypeAndMut}; use rustc::ty::layout::{self, TyLayout, Size}; use rustc::ty::adjustment::{PointerCast}; -use syntax::ast::{FloatTy, IntTy, UintTy}; +use syntax::ast::FloatTy; use syntax::symbol::sym; use rustc_apfloat::ieee::{Single, Double}; @@ -11,9 +11,9 @@ use rustc::mir::interpret::{ }; use rustc::mir::CastKind; -use super::{InterpretCx, Machine, PlaceTy, OpTy, Immediate}; +use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate}; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { match ty.sty { ty::RawPtr(ty::TypeAndMut { ty, .. }) | @@ -151,7 +151,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { "Unexpected cast from type {:?}", src_layout.ty ); match val.to_bits_or_ptr(src_layout.size, self) { - Err(ptr) => self.cast_from_ptr(ptr, dest_layout.ty), + Err(ptr) => self.cast_from_ptr(ptr, src_layout, dest_layout), Ok(data) => self.cast_from_int(data, src_layout, dest_layout), } } @@ -239,17 +239,25 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { fn cast_from_ptr( &self, ptr: Pointer, - ty: Ty<'tcx> + src_layout: TyLayout<'tcx>, + dest_layout: TyLayout<'tcx>, ) -> InterpResult<'tcx, Scalar> { use rustc::ty::TyKind::*; - match ty.sty { + + match dest_layout.ty.sty { // Casting to a reference or fn pointer is not permitted by rustc, // no need to support it here. - RawPtr(_) | - Int(IntTy::Isize) | - Uint(UintTy::Usize) => Ok(ptr.into()), - Int(_) | Uint(_) => err!(ReadPointerAsBytes), - _ => err!(Unimplemented(format!("ptr to {:?} cast", ty))), + RawPtr(_) => Ok(ptr.into()), + Int(_) | Uint(_) => { + let size = self.memory.pointer_size(); + + match self.force_bits(Scalar::Ptr(ptr), size) { + Ok(bits) => self.cast_from_int(bits, src_layout, dest_layout), + Err(_) if dest_layout.size == size => Ok(ptr.into()), + Err(e) => Err(e), + } + } + _ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty) } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 4c4330ffb261d..fd5290ee0400c 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -26,7 +26,7 @@ use super::{ Memory, Machine }; -pub struct InterpretCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { +pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { /// Stores the `Machine` instance. pub machine: M, @@ -158,14 +158,14 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> { #[inline] fn data_layout(&self) -> &layout::TargetDataLayout { &self.tcx.data_layout } } -impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpretCx<'mir, 'tcx, M> +impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'mir, 'tcx, M> where M: Machine<'mir, 'tcx>, { @@ -175,7 +175,7 @@ where } } -impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpretCx<'mir, 'tcx, M> +impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'mir, 'tcx, M> where M: Machine<'mir, 'tcx>, { @@ -184,7 +184,7 @@ where } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { type Ty = Ty<'tcx>; type TyLayout = InterpResult<'tcx, TyLayout<'tcx>>; @@ -195,14 +195,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpretCx<'mir, 'tcx, M> } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn new( tcx: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>, machine: M, memory_extra: M::MemoryExtra, ) -> Self { - InterpretCx { + InterpCx { machine, tcx, param_env, diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index beb5049307117..cf36c10a614e5 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ }; use super::{ - Machine, PlaceTy, OpTy, InterpretCx, Immediate, + Machine, PlaceTy, OpTy, InterpCx, Immediate, }; mod type_name; @@ -39,7 +39,7 @@ fn numeric_intrinsic<'tcx, Tag>( Ok(Scalar::from_uint(bits_out, size)) } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Returns `true` if emulation happened. pub fn emulate_intrinsic( &mut self, diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index a3956e12300f1..ff560360f0ad1 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -11,7 +11,7 @@ use rustc::ty::{self, query::TyCtxtAt}; use super::{ Allocation, AllocId, InterpResult, Scalar, AllocationExtra, - InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory + InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory }; /// Whether this kind of memory is allowed to leak @@ -95,11 +95,11 @@ pub trait Machine<'mir, 'tcx>: Sized { const STATIC_KIND: Option; /// Whether to enforce the validity invariant - fn enforce_validity(ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool; + fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; /// Called before a basic block terminator is executed. /// You can use this to detect endlessly running programs. - fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>; + fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>; /// Entry point to all function calls. /// @@ -112,7 +112,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them /// was used. fn find_fn( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], dest: Option>, @@ -122,7 +122,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Directly process an intrinsic without pushing a stack frame. /// If this returns successfully, the engine will take care of jumping to the next block. fn call_intrinsic( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], dest: PlaceTy<'tcx, Self::PointerTag>, @@ -145,7 +145,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// /// Returns a (value, overflowed) pair if the operation succeeded fn ptr_op( - ecx: &InterpretCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'mir, 'tcx, Self>, bin_op: mir::BinOp, left: ImmTy<'tcx, Self::PointerTag>, right: ImmTy<'tcx, Self::PointerTag>, @@ -153,7 +153,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Heap allocations via the `box` keyword. fn box_alloc( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, dest: PlaceTy<'tcx, Self::PointerTag>, ) -> InterpResult<'tcx>; @@ -193,7 +193,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Executes a retagging operation #[inline] fn retag( - _ecx: &mut InterpretCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'mir, 'tcx, Self>, _kind: mir::RetagKind, _place: PlaceTy<'tcx, Self::PointerTag>, ) -> InterpResult<'tcx> { @@ -201,11 +201,11 @@ pub trait Machine<'mir, 'tcx>: Sized { } /// Called immediately before a new stack frame got pushed - fn stack_push(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>; + fn stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>; /// Called immediately after a stack frame gets popped fn stack_pop( - ecx: &mut InterpretCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'mir, 'tcx, Self>, extra: Self::FrameExtra, ) -> InterpResult<'tcx>; diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index c06fdccf6cac6..f5d912595337b 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -158,8 +158,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn reallocate( &mut self, ptr: Pointer, - old_size: Size, - old_align: Align, + old_size_and_align: Option<(Size, Align)>, new_size: Size, new_align: Align, kind: MemoryKind, @@ -171,15 +170,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". // This happens so rarely, the perf advantage is outweighed by the maintenance cost. let new_ptr = self.allocate(new_size, new_align, kind); + let old_size = match old_size_and_align { + Some((size, _align)) => size, + None => Size::from_bytes(self.get(ptr.alloc_id)?.bytes.len() as u64), + }; self.copy( ptr.into(), - old_align, + Align::from_bytes(1).unwrap(), // old_align anyway gets checked below by `deallocate` new_ptr.into(), new_align, old_size.min(new_size), /*nonoverlapping*/ true, )?; - self.deallocate(ptr, Some((old_size, old_align)), kind)?; + self.deallocate(ptr, old_size_and_align, kind)?; Ok(new_ptr) } @@ -198,7 +201,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn deallocate( &mut self, ptr: Pointer, - size_and_align: Option<(Size, Align)>, + old_size_and_align: Option<(Size, Align)>, kind: MemoryKind, ) -> InterpResult<'tcx> { trace!("deallocating: {}", ptr.alloc_id); @@ -232,7 +235,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { format!("{:?}", kind), )); } - if let Some((size, align)) = size_and_align { + if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); return err!(IncorrectAllocationInformation(size, diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 259bd6af0d5d4..2b20f9df53837 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -19,7 +19,7 @@ mod intern; pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here pub use self::eval_context::{ - InterpretCx, Frame, StackPopCleanup, LocalState, LocalValue, + InterpCx, Frame, StackPopCleanup, LocalState, LocalValue, }; pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy}; diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c72078fa89cd2..68c9047f7b708 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -15,7 +15,7 @@ use rustc::mir::interpret::{ sign_extend, truncate, }; use super::{ - InterpretCx, Machine, + InterpCx, Machine, MemPlace, MPlaceTy, PlaceTy, Place, }; pub use rustc::mir::interpret::ScalarMaybeUndef; @@ -213,7 +213,7 @@ pub(super) fn from_known_layout<'tcx>( } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`. /// Returns `None` if the layout does not permit loading this as a value. fn try_read_immediate_from_mplace( diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 029a440f34e72..20180c9cba542 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -4,10 +4,10 @@ use syntax::ast::FloatTy; use rustc_apfloat::Float; use rustc::mir::interpret::{InterpResult, Scalar}; -use super::{InterpretCx, PlaceTy, Immediate, Machine, ImmTy}; +use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy}; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Applies the binary operation `op` to the two operands and writes a tuple of the result /// and a boolean signifying the potential overflow to the destination. pub fn binop_with_overflow( @@ -36,7 +36,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn binary_char_op( &self, bin_op: mir::BinOp, diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 1351b5bb8bd88..4f3727fbd8d9a 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -13,7 +13,7 @@ use rustc::ty::TypeFoldable; use super::{ GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, - InterpretCx, Machine, AllocMap, AllocationExtra, + InterpCx, Machine, AllocMap, AllocationExtra, RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue }; @@ -290,7 +290,7 @@ impl<'tcx, Tag: ::std::fmt::Debug> PlaceTy<'tcx, Tag> { } // separating the pointer tag for `impl Trait`, see https://github.com/rust-lang/rust/issues/54385 -impl<'mir, 'tcx, Tag, M> InterpretCx<'mir, 'tcx, M> +impl<'mir, 'tcx, Tag, M> InterpCx<'mir, 'tcx, M> where // FIXME: Working around https://github.com/rust-lang/rust/issues/54385 Tag: ::std::fmt::Debug + Copy + Eq + Hash + 'static, @@ -583,7 +583,7 @@ where // global table but not in its local memory: It calls back into tcx through // a query, triggering the CTFE machinery to actually turn this lazy reference // into a bunch of bytes. IOW, statics are evaluated with CTFE even when - // this InterpretCx uses another Machine (e.g., in miri). This is what we + // this InterpCx uses another Machine (e.g., in miri). This is what we // want! This way, computing statics works consistently between codegen // and miri: They use the same query to eventually obtain a `ty::Const` // and use that for further computation. diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 2f99973b90d4a..dc5302eb18fc4 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -1,4 +1,4 @@ -//! This module contains the `InterpretCx` methods for executing a single step of the interpreter. +//! This module contains the `InterpCx` methods for executing a single step of the interpreter. //! //! The main entry point is the `step` method. @@ -6,7 +6,7 @@ use rustc::mir; use rustc::ty::layout::LayoutOf; use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic}; -use super::{InterpretCx, Machine}; +use super::{InterpCx, Machine}; /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the /// same type as the result. @@ -35,7 +35,7 @@ fn binop_right_homogeneous(op: mir::BinOp) -> bool { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn run(&mut self) -> InterpResult<'tcx> { while self.step()? {} Ok(()) diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 13baf245d10fb..d6f3de02ec918 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -8,10 +8,10 @@ use rustc_target::spec::abi::Abi; use rustc::mir::interpret::{InterpResult, PointerArithmetic, InterpError, Scalar}; use super::{ - InterpretCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup + InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup }; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline] pub fn goto_block(&mut self, target: Option) -> InterpResult<'tcx> { if let Some(target) = target { diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 5d2f268d26639..27d127514229c 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -2,9 +2,9 @@ use rustc::ty::{self, Ty, Instance}; use rustc::ty::layout::{Size, Align, LayoutOf}; use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic}; -use super::{InterpretCx, InterpError, Machine, MemoryKind}; +use super::{InterpCx, InterpError, Machine, MemoryKind}; -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for /// objects. /// diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index b2a159fef59c6..374f42261bf62 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -13,7 +13,7 @@ use rustc::mir::interpret::{ use std::hash::Hash; use super::{ - OpTy, Machine, InterpretCx, ValueVisitor, MPlaceTy, + OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, }; macro_rules! validation_failure { @@ -174,7 +174,7 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { MPlaceTy<'tcx, M::PointerTag>, Vec, >>, - ecx: &'rt InterpretCx<'mir, 'tcx, M>, + ecx: &'rt InterpCx<'mir, 'tcx, M>, } impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> { @@ -259,7 +259,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> type V = OpTy<'tcx, M::PointerTag>; #[inline(always)] - fn ecx(&self) -> &InterpretCx<'mir, 'tcx, M> { + fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> { &self.ecx } @@ -628,7 +628,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { +impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// This function checks the data at `op`. `op` is assumed to cover valid memory if it /// is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index d04dc3ab37ed3..783d252263735 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -8,7 +8,7 @@ use rustc::mir::interpret::{ }; use super::{ - Machine, InterpretCx, MPlaceTy, OpTy, + Machine, InterpCx, MPlaceTy, OpTy, }; // A thing that we can project into, and that has a layout. @@ -21,7 +21,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy { /// Makes this into an `OpTy`. fn to_op( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>>; /// Creates this from an `MPlaceTy`. @@ -30,14 +30,14 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy { /// Projects to the given enum variant. fn project_downcast( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, variant: VariantIdx, ) -> InterpResult<'tcx, Self>; /// Projects to the n-th field. fn project_field( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, field: u64, ) -> InterpResult<'tcx, Self>; } @@ -53,7 +53,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: #[inline(always)] fn to_op( self, - _ecx: &InterpretCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { Ok(self) } @@ -66,7 +66,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: #[inline(always)] fn project_downcast( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, variant: VariantIdx, ) -> InterpResult<'tcx, Self> { ecx.operand_downcast(self, variant) @@ -75,7 +75,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: #[inline(always)] fn project_field( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, field: u64, ) -> InterpResult<'tcx, Self> { ecx.operand_field(self, field) @@ -91,7 +91,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, #[inline(always)] fn to_op( self, - _ecx: &InterpretCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'mir, 'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { Ok(self.into()) } @@ -104,7 +104,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, #[inline(always)] fn project_downcast( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, variant: VariantIdx, ) -> InterpResult<'tcx, Self> { ecx.mplace_downcast(self, variant) @@ -113,7 +113,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, #[inline(always)] fn project_field( self, - ecx: &InterpretCx<'mir, 'tcx, M>, + ecx: &InterpCx<'mir, 'tcx, M>, field: u64, ) -> InterpResult<'tcx, Self> { ecx.mplace_field(self, field) @@ -126,9 +126,9 @@ macro_rules! make_value_visitor { pub trait $visitor_trait_name<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { type V: Value<'mir, 'tcx, M>; - /// The visitor must have an `InterpretCx` in it. + /// The visitor must have an `InterpCx` in it. fn ecx(&$($mutability)? self) - -> &$($mutability)? InterpretCx<'mir, 'tcx, M>; + -> &$($mutability)? InterpCx<'mir, 'tcx, M>; // Recursive actions, ready to be overloaded. /// Visits the given value, dispatching as appropriate to more specialized visitors. diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index cb02e1a778c93..b85149cf55676 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(slice_concat_ext)] #![feature(trusted_len)] #![feature(try_blocks)] +#![feature(mem_take)] #![recursion_limit="256"] diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index bb2738d5aa4a3..097d76925c8eb 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -281,10 +281,10 @@ impl<'tcx> InliningMap<'tcx> { } } -pub fn collect_crate_mono_items<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn collect_crate_mono_items( + tcx: TyCtxt<'_>, mode: MonoItemCollectionMode, -) -> (FxHashSet>, InliningMap<'tcx>) { +) -> (FxHashSet>, InliningMap<'_>) { let roots = time(tcx.sess, "collecting roots", || { collect_roots(tcx, mode) }); @@ -315,7 +315,7 @@ pub fn collect_crate_mono_items<'tcx>( // Find all non-generic items by walking the HIR. These items serve as roots to // start monomorphizing from. -fn collect_roots<'tcx>(tcx: TyCtxt<'tcx>, mode: MonoItemCollectionMode) -> Vec> { +fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec> { debug!("Collecting roots"); let mut roots = Vec::new(); @@ -912,7 +912,7 @@ fn find_vtable_types_for_unsizing<'tcx>( } } -fn create_fn_mono_item<'tcx>(instance: Instance<'tcx>) -> MonoItem<'tcx> { +fn create_fn_mono_item(instance: Instance<'_>) -> MonoItem<'_> { debug!("create_fn_mono_item(instance={})", instance); MonoItem::Fn(instance) } @@ -1114,7 +1114,7 @@ impl RootCollector<'_, 'v> { } } -fn item_requires_monomorphization<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let generics = tcx.generics_of(def_id); generics.requires_monomorphization(tcx) } @@ -1243,7 +1243,7 @@ fn collect_neighbours<'tcx>( } } -fn def_id_to_string<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> String { +fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String { let mut output = String::new(); let printer = DefPathBasedNames::new(tcx, false, false); printer.push_def_path(def_id, &mut output); diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 32e4d4f437a78..a934c921d9257 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -839,10 +839,10 @@ where } } -fn collect_and_partition_mono_items<'tcx>( - tcx: TyCtxt<'tcx>, +fn collect_and_partition_mono_items( + tcx: TyCtxt<'_>, cnum: CrateNum, -) -> (Arc, Arc>>>) { +) -> (Arc, Arc>>>) { assert_eq!(cnum, LOCAL_CRATE); let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 7987095a33401..32b964dbadfa9 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -829,7 +829,7 @@ fn build_call_shim<'tcx>( body } -pub fn build_adt_ctor<'tcx>(tcx: TyCtxt<'tcx>, ctor_id: DefId) -> &'tcx Body<'tcx> { +pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); let span = tcx.hir().span_if_local(ctor_id) diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index e01017d7c9bdb..de5af0a46b534 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -14,8 +14,8 @@ pub struct AddRetag; /// after the assignment, we can be sure to obtain the same place value. /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic /// copies. Data races are UB.) -fn is_stable<'tcx>( - place: &Place<'tcx>, +fn is_stable( + place: &Place<'_>, ) -> bool { use rustc::mir::Place::*; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 24df3549be481..9898ba897734d 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -480,11 +480,11 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'a> { } } -fn check_unused_unsafe<'a, 'tcx>( - tcx: TyCtxt<'tcx>, +fn check_unused_unsafe( + tcx: TyCtxt<'_>, def_id: DefId, used_unsafe: &FxHashSet, - unsafe_blocks: &'a mut Vec<(hir::HirId, bool)>, + unsafe_blocks: &mut Vec<(hir::HirId, bool)>, ) { let body_id = tcx.hir().as_local_hir_id(def_id).and_then(|hir_id| { @@ -506,7 +506,7 @@ fn check_unused_unsafe<'a, 'tcx>( hir::intravisit::Visitor::visit_body(&mut visitor, body); } -fn unsafety_check_result<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> UnsafetyCheckResult { +fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult { debug!("unsafety_violations({:?})", def_id); // N.B., this borrow is valid because all the consumers of @@ -545,7 +545,7 @@ fn unsafety_check_result<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> UnsafetyChec } } -fn unsafe_derive_on_repr_packed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: DefId) { let lint_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(|| bug!("checking unsafety for non-local def id {:?}", def_id)); @@ -602,7 +602,7 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id db.emit(); } -fn builtin_derive_def_id<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { +fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { debug!("builtin_derive_def_id({:?})", def_id); if let Some(impl_def_id) = tcx.impl_of_method(def_id) { if tcx.has_attr(impl_def_id, sym::automatically_derived) { @@ -618,7 +618,7 @@ fn builtin_derive_def_id<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option(tcx: TyCtxt<'tcx>, def_id: DefId) { +pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { debug!("check_unsafety({:?})", def_id); // closures are handled by their parent fn. diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index c7a2fdd93830f..29480f88fcedc 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -23,7 +23,7 @@ use rustc::ty::layout::{ }; use crate::interpret::{ - self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, + self, InterpCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind, StackPopCleanup, LocalValue, LocalState, }; use crate::const_eval::{ @@ -117,7 +117,7 @@ type Const<'tcx> = OpTy<'tcx>; /// Finds optimization opportunities on the MIR. struct ConstPropagator<'mir, 'tcx> { - ecx: InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, can_const_prop: IndexVec, @@ -202,7 +202,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // If the local is `Unitialized` or `Dead` then we haven't propagated a value into it. // - // `InterpretCx::access_local()` mostly takes care of this for us however, for ZSTs, + // `InterpCx::access_local()` mostly takes care of this for us however, for ZSTs, // it will synthesize a value for us. In doing so, that will cause the // `get_const(l).is_empty()` assert right before we call `set_const()` in `visit_statement` // to fail. diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 243820ba7d027..a6fb555f20bd0 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -14,7 +14,7 @@ use crate::util as mir_util; pub struct Marker(pub &'static str); impl MirPass for Marker { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { Cow::Borrowed(self.0) } @@ -52,7 +52,7 @@ pub fn on_mir_pass<'tcx>( } } -pub fn emit_mir<'tcx>(tcx: TyCtxt<'tcx>, outputs: &OutputFilenames) -> io::Result<()> { +pub fn emit_mir(tcx: TyCtxt<'_>, outputs: &OutputFilenames) -> io::Result<()> { let path = outputs.path(OutputType::Mir); let mut f = File::create(&path)?; mir_util::write_mir_pretty(tcx, None, &mut f)?; diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 7b961e97a10de..2ed3f7d5c26e2 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -68,7 +68,7 @@ use crate::transform::simplify; use crate::transform::no_landing_pads::no_landing_pads; use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation}; use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location}; -use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals}; +use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals, RequiresStorage}; use crate::util::dump_mir; use crate::util::liveness; @@ -437,16 +437,18 @@ fn locals_live_across_suspend_points( // Calculate the MIR locals which have been previously // borrowed (even if they are still active). - // This is only used for immovable generators. - let borrowed_locals = if !movable { - let analysis = HaveBeenBorrowedLocals::new(body); - let result = - do_dataflow(tcx, body, def_id, &[], &dead_unwinds, analysis, - |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); - Some((analysis, result)) - } else { - None - }; + let borrowed_locals_analysis = HaveBeenBorrowedLocals::new(body); + let borrowed_locals_result = + do_dataflow(tcx, body, def_id, &[], &dead_unwinds, borrowed_locals_analysis, + |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); + + // Calculate the MIR locals that we actually need to keep storage around + // for. + let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result); + let requires_storage = + do_dataflow(tcx, body, def_id, &[], &dead_unwinds, requires_storage_analysis, + |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); + let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result); // Calculate the liveness of MIR locals ignoring borrows. let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len()); @@ -471,10 +473,10 @@ fn locals_live_across_suspend_points( statement_index: data.statements.len(), }; - if let Some((ref analysis, ref result)) = borrowed_locals { + if !movable { let borrowed_locals = state_for_location(loc, - analysis, - result, + &borrowed_locals_analysis, + &borrowed_locals_result, body); // The `liveness` variable contains the liveness of MIR locals ignoring borrows. // This is correct for movable generators since borrows cannot live across @@ -489,27 +491,34 @@ fn locals_live_across_suspend_points( liveness.outs[block].union(&borrowed_locals); } - let mut storage_liveness = state_for_location(loc, - &storage_live_analysis, - &storage_live, - body); + let storage_liveness = state_for_location(loc, + &storage_live_analysis, + &storage_live, + body); // Store the storage liveness for later use so we can restore the state // after a suspension point storage_liveness_map.insert(block, storage_liveness.clone()); - // Mark locals without storage statements as always having live storage - storage_liveness.union(&ignored.0); + let mut storage_required = state_for_location(loc, + &requires_storage_analysis, + &requires_storage, + body); + + // Mark locals without storage statements as always requiring storage + storage_required.union(&ignored.0); // Locals live are live at this point only if they are used across // suspension points (the `liveness` variable) - // and their storage is live (the `storage_liveness` variable) - let mut live_locals_here = storage_liveness; + // and their storage is required (the `storage_required` variable) + let mut live_locals_here = storage_required; live_locals_here.intersect(&liveness.outs[block]); // The generator argument is ignored live_locals_here.remove(self_arg()); + debug!("loc = {:?}, live_locals_here = {:?}", loc, live_locals_here); + // Add the locals live at this suspension point to the set of locals which live across // any suspension points live_locals.union(&live_locals_here); @@ -517,6 +526,7 @@ fn locals_live_across_suspend_points( live_locals_at_suspension_points.push(live_locals_here); } } + debug!("live_locals = {:?}", live_locals); // Renumber our liveness_map bitsets to include only the locals we are // saving. @@ -529,8 +539,8 @@ fn locals_live_across_suspend_points( body, &live_locals, &ignored, - storage_live, - storage_live_analysis); + requires_storage, + requires_storage_analysis); LivenessInfo { live_locals, @@ -567,8 +577,8 @@ fn compute_storage_conflicts( body: &'mir Body<'tcx>, stored_locals: &liveness::LiveVarSet, ignored: &StorageIgnored, - storage_live: DataflowResults<'tcx, MaybeStorageLive<'mir, 'tcx>>, - _storage_live_analysis: MaybeStorageLive<'mir, 'tcx>, + requires_storage: DataflowResults<'tcx, RequiresStorage<'mir, 'tcx>>, + _requires_storage_analysis: RequiresStorage<'mir, 'tcx>, ) -> BitMatrix { assert_eq!(body.local_decls.len(), ignored.0.domain_size()); assert_eq!(body.local_decls.len(), stored_locals.domain_size()); @@ -584,9 +594,9 @@ fn compute_storage_conflicts( let mut visitor = StorageConflictVisitor { body, stored_locals: &stored_locals, - local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len()) + local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len()), }; - let mut state = FlowAtLocation::new(storage_live); + let mut state = FlowAtLocation::new(requires_storage); visitor.analyze_results(&mut state); let local_conflicts = visitor.local_conflicts; @@ -627,7 +637,7 @@ struct StorageConflictVisitor<'body, 'tcx, 's> { impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx> for StorageConflictVisitor<'body, 'tcx, 's> { - type FlowState = FlowAtLocation<'tcx, MaybeStorageLive<'body, 'tcx>>; + type FlowState = FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>; fn body(&self) -> &'body Body<'tcx> { self.body @@ -657,7 +667,7 @@ impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx> impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> { fn apply_state(&mut self, - flow_state: &FlowAtLocation<'tcx, MaybeStorageLive<'body, 'tcx>>, + flow_state: &FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>, loc: Location) { // Ignore unreachable blocks. match self.body.basic_blocks()[loc.block].terminator().kind { @@ -1018,14 +1028,14 @@ fn create_generator_resume_function<'tcx>( dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(()) ); } -fn source_info<'tcx>(body: &Body<'tcx>) -> SourceInfo { +fn source_info(body: &Body<'_>) -> SourceInfo { SourceInfo { span: body.span, scope: OUTERMOST_SOURCE_SCOPE, } } -fn insert_clean_drop<'tcx>(body: &mut Body<'tcx>) -> BasicBlock { +fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { let return_block = insert_term_block(body, TerminatorKind::Return); // Create a block to destroy an unresumed generators. This can only destroy upvars. diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 81d91dcd0a95f..7f43c4a3e89a1 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -50,13 +50,13 @@ pub(crate) fn provide(providers: &mut Providers<'_>) { }; } -fn is_mir_available<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_mir_available(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.mir_keys(def_id.krate).contains(&def_id) } /// Finds the full set of `DefId`s within the current crate that have /// MIR associated with them. -fn mir_keys<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx DefIdSet { +fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet { assert_eq!(krate, LOCAL_CRATE); let mut set = DefIdSet::default(); @@ -94,7 +94,7 @@ fn mir_keys<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx DefIdSet { tcx.arena.alloc(set) } -fn mir_built<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal> { +fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { let mir = build::mir_build(tcx, def_id); tcx.alloc_steal_mir(mir) } @@ -137,7 +137,7 @@ pub fn default_name() -> Cow<'static, str> { /// pass will be named after the type, and it will consist of a main /// loop that goes over each available MIR and applies `run_pass`. pub trait MirPass { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { default_name::() } @@ -192,7 +192,7 @@ pub fn run_passes( } } -fn mir_const<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal> { +fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { // Unsafety check uses the raw mir, so make sure it is run let _ = tcx.unsafety_check_result(def_id); @@ -223,7 +223,7 @@ fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal> { tcx.alloc_steal_mir(body) } -fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Body<'tcx> { +fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { if tcx.is_constructor(def_id) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index f082b5e5a046c..3e52d3ee9bbdf 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1473,7 +1473,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn mir_const_qualif<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> (u8, &'tcx BitSet) { +fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet) { // N.B., this `borrow()` is guaranteed to be valid (i.e., the value // cannot yet be stolen), because `mir_validated()`, which steals // from `mir_const(), forces this query to execute before diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index f226f15c0096f..2eed9d453f233 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -53,7 +53,7 @@ pub fn simplify_cfg(body: &mut Body<'_>) { } impl MirPass for SimplifyCfg { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { Cow::Borrowed(&self.label) } diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 0c63a8d9c96b1..f39c71ef42d71 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -15,7 +15,7 @@ impl SimplifyBranches { } impl MirPass for SimplifyBranches { - fn name<'a>(&'a self) -> Cow<'a, str> { + fn name(&self) -> Cow<'_, str> { Cow::Borrowed(&self.label) } diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index fac752dbf023e..59821440c6619 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -31,7 +31,7 @@ impl DefUseAnalysis { self.clear(); let mut finder = DefUseFinder { - info: mem::replace(&mut self.info, IndexVec::new()), + info: mem::take(&mut self.info), }; finder.visit_body(body); self.info = finder.info diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 1d876d7bddb53..9d142d9b700b6 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -8,8 +8,8 @@ use std::io::{self, Write}; use super::pretty::dump_mir_def_ids; /// Write a graphviz DOT graph of a list of MIRs. -pub fn write_mir_graphviz<'tcx, W>( - tcx: TyCtxt<'tcx>, +pub fn write_mir_graphviz( + tcx: TyCtxt<'_>, single: Option, w: &mut W, ) -> io::Result<()> diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index cf0fc09472b6c..b42eebc7ee3be 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -56,8 +56,8 @@ pub struct LivenessResult { /// Computes which local variables are live within the given function /// `mir`, including drops. -pub fn liveness_of_locals<'tcx>( - body: &Body<'tcx>, +pub fn liveness_of_locals( + body: &Body<'_>, ) -> LivenessResult { let num_live_vars = body.local_decls.len(); @@ -75,9 +75,24 @@ pub fn liveness_of_locals<'tcx>( let mut bits = LiveVarSet::new_empty(num_live_vars); - // queue of things that need to be re-processed, and a set containing - // the things currently in the queue - let mut dirty_queue: WorkQueue = WorkQueue::with_all(body.basic_blocks().len()); + // The dirty queue contains the set of basic blocks whose entry sets have changed since they + // were last processed. At the start of the analysis, we initialize the queue in post-order to + // make it more likely that the entry set for a given basic block will have the effects of all + // its successors in the CFG applied before it is processed. + // + // FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration + // order when cycles are present, but the overhead of computing the reverse CFG may outweigh + // any benefits. Benchmark this and find out. + let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks().len()); + for (bb, _) in traversal::postorder(body) { + dirty_queue.insert(bb); + } + + // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will + // be processed after the ones added above. + for bb in body.basic_blocks().indices() { + dirty_queue.insert(bb); + } let predecessors = body.predecessors(); @@ -228,8 +243,8 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor } } -fn block<'tcx>( - b: &BasicBlockData<'tcx>, +fn block( + b: &BasicBlockData<'_>, locals: usize, ) -> DefsUses { let mut visitor = DefsUsesVisitor { diff --git a/src/librustc_mir/util/mod.rs b/src/librustc_mir/util/mod.rs index 719029dbaac77..fd2a5e452ce4b 100644 --- a/src/librustc_mir/util/mod.rs +++ b/src/librustc_mir/util/mod.rs @@ -21,7 +21,7 @@ pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz}; pub use self::graphviz::write_node_label as write_graphviz_node_label; /// If possible, suggest replacing `ref` with `ref mut`. -pub fn suggest_ref_mut<'tcx>(tcx: TyCtxt<'tcx>, binding_span: Span) -> Option<(String)> { +pub fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<(String)> { let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).unwrap(); if hi_src.starts_with("ref") && hi_src["ref".len()..].starts_with(Pattern_White_Space) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 2da9c5adf9baf..560635962995c 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -837,13 +837,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { the relevant `fold_*()` method in `PlaceholderExpander`?"); } - fn visit_fn_header(&mut self, header: &'a FnHeader) { - if header.asyncness.node.is_async() && self.session.rust_2015() { - struct_span_err!(self.session, header.asyncness.span, E0670, - "`async fn` is not permitted in the 2015 edition").emit(); - } - } - fn visit_impl_item(&mut self, ii: &'a ImplItem) { match ii.node { ImplItemKind::Method(ref sig, _) => { diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 6936aedb9de80..e7f6abc410a32 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -38,7 +38,7 @@ pub fn print_hir_stats(krate: &hir::Crate) { collector.print("HIR STATS"); } -pub fn print_ast_stats<'v>(krate: &'v ast::Crate, title: &str) { +pub fn print_ast_stats(krate: &ast::Crate, title: &str) { let mut collector = StatCollector { krate: None, data: FxHashMap::default(), diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 8f790d1328572..6b1ce578240e4 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -14,7 +14,7 @@ use rustc::ty::TyCtxt; use syntax::ast::Attribute; use syntax::symbol::sym; -pub fn test_layout<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn test_layout(tcx: TyCtxt<'_>) { if tcx.features().rustc_attrs { // if the `rustc_attrs` feature is not enabled, don't bother testing layout tcx.hir() diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index ed0a78b465276..616e6974110e6 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -45,7 +45,7 @@ struct CheckLoopVisitor<'a, 'hir> { cx: Context, } -fn check_mod_loops<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckLoopVisitor { sess: &tcx.sess, hir_map: &tcx.hir(), diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index bc1151974bb70..e14fa07fbbfe4 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -39,7 +39,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn const_is_rvalue_promotable_to_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn const_is_rvalue_promotable_to_static(tcx: TyCtxt<'_>, def_id: DefId) -> bool { assert!(def_id.is_local()); let hir_id = tcx.hir().as_local_hir_id(def_id) @@ -48,7 +48,7 @@ fn const_is_rvalue_promotable_to_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) tcx.rvalue_promotable_map(def_id).contains(&body_id.hir_id.local_id) } -fn rvalue_promotable_map<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ItemLocalSet { +fn rvalue_promotable_map(tcx: TyCtxt<'_>, def_id: DefId) -> &ItemLocalSet { let outer_def_id = tcx.closure_base_def_id(def_id); if outer_def_id != def_id { return tcx.rvalue_promotable_map(outer_def_id); diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs index d3ac597160fd6..816e283a10460 100644 --- a/src/librustc_plugin/build.rs +++ b/src/librustc_plugin/build.rs @@ -30,11 +30,11 @@ impl<'v> ItemLikeVisitor<'v> for RegistrarFinder { } /// Finds the function marked with `#[plugin_registrar]`, if any. -pub fn find_plugin_registrar<'tcx>(tcx: TyCtxt<'tcx>) -> Option { +pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option { tcx.plugin_registrar_fn(LOCAL_CRATE) } -fn plugin_registrar_fn<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option { +fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option { assert_eq!(cnum, LOCAL_CRATE); let mut finder = RegistrarFinder { registrars: Vec::new() }; diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 16d484e2a98f2..ec2855f826a46 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -6,7 +6,7 @@ use rustc::util::nodemap::FxHashMap; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension}; use syntax::ext::base::MacroExpanderFn; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::Symbol; use syntax::ast; use syntax::feature_gate::AttributeType; use syntax_pos::Span; @@ -77,7 +77,7 @@ impl<'a> Registry<'a> { /// /// Returns empty slice in case the plugin was loaded /// with `--extra-plugins` - pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] { + pub fn args(&self) -> &[ast::NestedMetaItem] { self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[]) } @@ -85,9 +85,6 @@ impl<'a> Registry<'a> { /// /// This is the most general hook into `libsyntax`'s expansion behavior. pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { - if name == sym::macro_rules { - panic!("user-defined macros may not be named `macro_rules`"); - } if extension.def_info.is_none() { extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 3e98200e53274..339021f511afd 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -337,7 +337,7 @@ fn item_tables<'a, 'tcx>( if tcx.has_typeck_tables(def_id) { tcx.typeck_tables_of(def_id) } else { empty_tables } } -fn min<'tcx>(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'tcx>) -> ty::Visibility { +fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visibility { if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 } } @@ -384,14 +384,14 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> trait VisibilityLike: Sized { const MAX: Self; const SHALLOW: bool = false; - fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self; + fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self; // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // associated types for which we can't determine visibility precisely. - fn of_impl<'a, 'tcx>( + fn of_impl( hir_id: hir::HirId, - tcx: TyCtxt<'tcx>, - access_levels: &'a AccessLevels, + tcx: TyCtxt<'_>, + access_levels: &AccessLevels, ) -> Self { let mut find = FindMin { tcx, access_levels, min: Self::MAX }; let def_id = tcx.hir().local_def_id_from_hir_id(hir_id); @@ -404,7 +404,7 @@ trait VisibilityLike: Sized { } impl VisibilityLike for ty::Visibility { const MAX: Self = ty::Visibility::Public; - fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self { + fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { min(def_id_visibility(find.tcx, def_id).0, find.min, find.tcx) } } @@ -420,7 +420,7 @@ impl VisibilityLike for Option { // both "shallow" version of its self type and "shallow" version of its trait if it exists // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; - fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self { + fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self { cmp::min(if let Some(hir_id) = find.tcx.hir().as_local_hir_id(def_id) { find.access_levels.map.get(&hir_id).cloned() } else { @@ -1828,7 +1828,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn check_mod_privacy<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); // Check privacy of names not checked in previous compilation stages. @@ -1855,7 +1855,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { intravisit::walk_mod(&mut visitor, module, hir_id); } -fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx AccessLevels { +fn privacy_access_levels(tcx: TyCtxt<'_>, krate: CrateNum) -> &AccessLevels { assert_eq!(krate, LOCAL_CRATE); // Build up a set of all exported items in the AST. This is a set of all @@ -1879,7 +1879,7 @@ fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx Acce tcx.arena.alloc(visitor.access_levels) } -fn check_private_in_public<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) { +fn check_private_in_public(tcx: TyCtxt<'_>, krate: CrateNum) { assert_eq!(krate, LOCAL_CRATE); let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 81adfac0a291a..05247600a4ded 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4,9 +4,10 @@ #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(mem_take)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] -#![feature(type_alias_enum_variants)] +#![cfg_attr(bootstrap, feature(type_alias_enum_variants))] #![recursion_limit="256"] @@ -198,9 +199,9 @@ enum ResolutionError<'a> { /// /// This takes the error provided, combines it with the span and any additional spans inside the /// error and emits it. -fn resolve_error<'sess, 'a>(resolver: &'sess Resolver<'_>, - span: Span, - resolution_error: ResolutionError<'a>) { +fn resolve_error(resolver: &Resolver<'_>, + span: Span, + resolution_error: ResolutionError<'_>) { resolve_struct_error(resolver, span, resolution_error).emit(); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 392a46a262f50..d8d08107b826a 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -946,7 +946,7 @@ impl<'a> Resolver<'a> { }; let macro_resolutions = - mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new()); + mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut()); for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions { // FIXME: Path resolution will ICE if segment IDs present. for seg in &mut path { seg.id = None; } @@ -973,7 +973,7 @@ impl<'a> Resolver<'a> { } let macro_resolutions = - mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new()); + mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut()); for (ident, kind, parent_scope, initial_binding) in macro_resolutions { match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind), &parent_scope, true, true, ident.span) { @@ -998,7 +998,7 @@ impl<'a> Resolver<'a> { } } - let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new()); + let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut()); for (ident, parent_scope) in builtin_attrs { let _ = self.early_resolve_ident_in_lexical_scope( ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span @@ -1109,9 +1109,6 @@ impl<'a> Resolver<'a> { current_legacy_scope: &mut LegacyScope<'a>) { self.local_macro_def_scopes.insert(item.id, self.current_module); let ident = item.ident; - if ident.name == sym::macro_rules { - self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`"); - } let def_id = self.definitions.local_def_id(item.id); let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f69849bb4a9ee..404d728d8808c 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -682,7 +682,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; while self.indeterminate_imports.len() < prev_num_indeterminates { prev_num_indeterminates = self.indeterminate_imports.len(); - for import in mem::replace(&mut self.indeterminate_imports, Vec::new()) { + for import in mem::take(&mut self.indeterminate_imports) { match self.resolve_import(&import) { true => self.determined_imports.push(import), false => self.indeterminate_imports.push(import), diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index fdd747cdb865a..b139083e99fc1 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -19,6 +19,10 @@ pub fn opts() -> TargetOptions { target_family: Some("windows".to_string()), is_like_windows: true, is_like_msvc: true, + // set VSLANG to 1033 can prevent link.exe from using + // language packs, and avoid generating Non-UTF-8 error + // messages if a link error occurred. + link_env: vec![("VSLANG".to_string(), "1033".to_string())], pre_link_args: args, crt_static_allows_dylibs: true, crt_static_respected: true, diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index bbb0825ee082a..5c23ad4a4edfb 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -17,6 +17,7 @@ use rustc::infer::canonical::{ CanonicalVarValues, OriginalQueryValues, QueryResponse, + QueryRegionConstraints, Certainty, }; use rustc::traits::{ @@ -151,14 +152,14 @@ impl context::AggregateOps> for ChalkContext<'tcx> { let solution = constrained_subst.unchecked_map(|cs| match ambiguous { true => QueryResponse { var_values: cs.subst.make_identity(self.tcx), - region_constraints: Vec::new(), + region_constraints: QueryRegionConstraints::default(), certainty: Certainty::Ambiguous, value: (), }, false => QueryResponse { var_values: cs.subst, - region_constraints: Vec::new(), + region_constraints: QueryRegionConstraints::default(), // FIXME: restore this later once we get better at handling regions // region_constraints: cs.constraints diff --git a/src/librustc_traits/chalk_context/program_clauses/primitive.rs b/src/librustc_traits/chalk_context/program_clauses/primitive.rs index 8e4b9da6de268..6e8eed0f90725 100644 --- a/src/librustc_traits/chalk_context/program_clauses/primitive.rs +++ b/src/librustc_traits/chalk_context/program_clauses/primitive.rs @@ -15,7 +15,7 @@ use crate::lowering::Lower; use crate::generic_types; use std::iter; -crate fn wf_clause_for_raw_ptr<'tcx>(tcx: TyCtxt<'tcx>, mutbl: hir::Mutability) -> Clauses<'tcx> { +crate fn wf_clause_for_raw_ptr(tcx: TyCtxt<'_>, mutbl: hir::Mutability) -> Clauses<'_> { let ptr_ty = generic_types::raw_ptr(tcx, mutbl); let wf_clause = ProgramClause { @@ -29,13 +29,13 @@ crate fn wf_clause_for_raw_ptr<'tcx>(tcx: TyCtxt<'tcx>, mutbl: hir::Mutability) tcx.mk_clauses(iter::once(wf_clause)) } -crate fn wf_clause_for_fn_ptr<'tcx>( - tcx: TyCtxt<'tcx>, +crate fn wf_clause_for_fn_ptr( + tcx: TyCtxt<'_>, arity_and_output: usize, variadic: bool, unsafety: hir::Unsafety, abi: abi::Abi, -) -> Clauses<'tcx> { +) -> Clauses<'_> { let fn_ptr = generic_types::fn_ptr(tcx, arity_and_output, variadic, unsafety, abi); let wf_clause = ProgramClause { @@ -50,7 +50,7 @@ crate fn wf_clause_for_fn_ptr<'tcx>( tcx.mk_clauses(iter::once(wf_clause)) } -crate fn wf_clause_for_slice<'tcx>(tcx: TyCtxt<'tcx>) -> Clauses<'tcx> { +crate fn wf_clause_for_slice(tcx: TyCtxt<'_>) -> Clauses<'_> { let ty = generic_types::bound(tcx, 0); let slice_ty = tcx.mk_slice(ty); @@ -111,7 +111,7 @@ crate fn wf_clause_for_array<'tcx>( tcx.mk_clauses(iter::once(wf_clause)) } -crate fn wf_clause_for_tuple<'tcx>(tcx: TyCtxt<'tcx>, arity: usize) -> Clauses<'tcx> { +crate fn wf_clause_for_tuple(tcx: TyCtxt<'_>, arity: usize) -> Clauses<'_> { let type_list = generic_types::type_list(tcx, arity); let tuple_ty = tcx.mk_ty(ty::Tuple(type_list)); @@ -152,7 +152,7 @@ crate fn wf_clause_for_tuple<'tcx>(tcx: TyCtxt<'tcx>, arity: usize) -> Clauses<' tcx.mk_clauses(iter::once(wf_clause)) } -crate fn wf_clause_for_ref<'tcx>(tcx: TyCtxt<'tcx>, mutbl: hir::Mutability) -> Clauses<'tcx> { +crate fn wf_clause_for_ref(tcx: TyCtxt<'_>, mutbl: hir::Mutability) -> Clauses<'_> { let region = tcx.mk_region( ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0)) ); @@ -176,7 +176,7 @@ crate fn wf_clause_for_ref<'tcx>(tcx: TyCtxt<'tcx>, mutbl: hir::Mutability) -> C tcx.mk_clauses(iter::once(wf_clause)) } -crate fn wf_clause_for_fn_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> { +crate fn wf_clause_for_fn_def(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { let fn_def = generic_types::fn_def(tcx, def_id); let wf_clause = ProgramClause { diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 3abd7e90cf10f..ecd888b606981 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -279,10 +279,10 @@ fn dtorck_constraint_for_ty<'tcx>( } /// Calculates the dtorck constraint for a type. -crate fn adt_dtorck_constraint<'tcx>( - tcx: TyCtxt<'tcx>, +crate fn adt_dtorck_constraint( + tcx: TyCtxt<'_>, def_id: DefId, -) -> Result, NoSolution> { +) -> Result, NoSolution> { let def = tcx.adt_def(def_id); let span = tcx.def_span(def_id); debug!("dtorck_constraint: {:?}", def); @@ -313,7 +313,7 @@ crate fn adt_dtorck_constraint<'tcx>( Ok(result) } -fn dedup_dtorck_constraint<'tcx>(c: &mut DtorckConstraint<'tcx>) { +fn dedup_dtorck_constraint(c: &mut DtorckConstraint<'_>) { let mut outlives = FxHashSet::default(); let mut dtorck_types = FxHashSet::default(); diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 0173685583148..9ff685bb4ee8a 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -160,7 +160,7 @@ crate fn program_clauses_for_env<'tcx>( ); } -crate fn environment<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Environment<'tcx> { +crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> { use super::{Lower, IntoFromEnvGoal}; use rustc::hir::{Node, TraitItemKind, ImplItemKind, ItemKind, ForeignItemKind}; diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 2a6613101614d..b0d9134c834d6 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -155,7 +155,7 @@ impl<'tcx> IntoWellFormedGoal for DomainGoal<'tcx> { } } -crate fn program_clauses_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> { +crate fn program_clauses_for(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { // FIXME(eddyb) this should only be using `def_kind`. match tcx.def_key(def_id).disambiguated_data.data { DefPathData::TypeNs(..) => match tcx.def_kind(def_id) { @@ -181,7 +181,7 @@ crate fn program_clauses_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses< } } -fn program_clauses_for_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> { +fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { // `trait Trait where WC { .. } // P0 == Self` // Rule Implemented-From-Env (see rustc guide) @@ -337,7 +337,7 @@ fn program_clauses_for_impl(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> { tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::bind(clause)))) } -pub fn program_clauses_for_type_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> { +pub fn program_clauses_for_type_def(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { // Rule WellFormed-Type // // `struct Ty where WC1, ..., WCm` @@ -411,10 +411,10 @@ pub fn program_clauses_for_type_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> C tcx.mk_clauses(iter::once(well_formed_clause).chain(from_env_clauses)) } -pub fn program_clauses_for_associated_type_def<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn program_clauses_for_associated_type_def( + tcx: TyCtxt<'_>, item_id: DefId, -) -> Clauses<'tcx> { +) -> Clauses<'_> { // Rule ProjectionEq-Placeholder // // ``` @@ -549,10 +549,10 @@ pub fn program_clauses_for_associated_type_def<'tcx>( tcx.mk_clauses(clauses) } -pub fn program_clauses_for_associated_type_value<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn program_clauses_for_associated_type_value( + tcx: TyCtxt<'_>, item_id: DefId, -) -> Clauses<'tcx> { +) -> Clauses<'_> { // Rule Normalize-From-Impl (see rustc guide) // // ``` @@ -611,7 +611,7 @@ pub fn program_clauses_for_associated_type_value<'tcx>( tcx.mk_clauses(iter::once(normalize_clause)) } -pub fn dump_program_clauses<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn dump_program_clauses(tcx: TyCtxt<'_>) { if !tcx.features().rustc_attrs { return; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0375ad4a08f26..1792716d1fb35 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -7,6 +7,7 @@ use crate::hir::{self, GenericArg, GenericArgs, ExprKind}; use crate::hir::def::{CtorOf, Res, DefKind}; use crate::hir::def_id::DefId; use crate::hir::HirVec; +use crate::hir::ptr::P; use crate::lint; use crate::middle::lang_items::SizedTraitLangItem; use crate::middle::resolve_lifetime as rl; @@ -23,7 +24,6 @@ use crate::require_c_abi_if_c_variadic; use smallvec::SmallVec; use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; use syntax::symbol::sym; use syntax_pos::{DUMMY_SP, Span, MultiSpan}; @@ -34,7 +34,6 @@ use std::collections::BTreeSet; use std::iter; use std::slice; -use super::{check_type_alias_enum_variants_enabled}; use rustc_data_structures::fx::FxHashSet; #[derive(Debug)] @@ -1595,7 +1594,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }); if let Some(variant_def) = variant_def { if permit_variants { - check_type_alias_enum_variants_enabled(tcx, span); tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span); return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); } else { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index b435c99ad01f5..eeed5be867807 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -5,6 +5,7 @@ use errors::{Applicability, DiagnosticBuilder}; use rustc::hir::{self, PatKind, Pat, ExprKind}; use rustc::hir::def::{Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; +use rustc::hir::ptr::P; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::traits::{ObligationCause, ObligationCauseCode}; @@ -12,7 +13,6 @@ use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::subst::Kind; use syntax::ast; use syntax::source_map::Spanned; -use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::Span; use syntax_pos::hygiene::CompilerDesugaringKind; @@ -458,7 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match ty.sty { ty::Array(..) | ty::Slice(..) => { err.help("the semantics of slice patterns changed \ - recently; see issue #23121"); + recently; see issue #62254"); } _ => {} } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 4bd2f216224a5..94c76deade279 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -54,6 +54,7 @@ use crate::check::{FnCtxt, Needs}; use errors::DiagnosticBuilder; use rustc::hir; use rustc::hir::def_id::DefId; +use rustc::hir::ptr::P; use rustc::infer::{Coercion, InferResult, InferOk}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; @@ -67,7 +68,6 @@ use rustc::ty::relate::RelateResult; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; use syntax::feature_gate; -use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index a2621abf44d8d..c4c4e10a14cc0 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -29,7 +29,7 @@ use syntax_pos::Span; /// struct/enum definition for the nominal type itself (i.e. /// cannot do `struct S; impl Drop for S { ... }`). /// -pub fn check_drop_impl<'tcx>(tcx: TyCtxt<'tcx>, drop_impl_did: DefId) -> Result<(), ErrorReported> { +pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorReported> { let dtor_self_type = tcx.type_of(drop_impl_did); let dtor_predicates = tcx.predicates_of(drop_impl_did); match dtor_self_type.sty { diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 21fa219a1cab2..ccc20bd9585c9 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -20,13 +20,13 @@ use crate::astconv::AstConv as _; use errors::{Applicability, DiagnosticBuilder}; use syntax::ast; -use syntax::ptr::P; use syntax::symbol::{Symbol, LocalInternedString, kw, sym}; use syntax::source_map::Span; use syntax::util::lev_distance::find_best_match_for_name; use rustc::hir; use rustc::hir::{ExprKind, QPath}; use rustc::hir::def::{CtorKind, Res, DefKind}; +use rustc::hir::ptr::P; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::mir::interpret::GlobalId; diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 8c2b8d1565f2f..9b1a891382209 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -79,7 +79,7 @@ pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { /// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs, /// and in libcore/intrinsics.rs -pub fn check_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) { +pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { let param = |n| tcx.mk_ty_param(n, InternedString::intern(&format!("P{}", n))); let name = it.ident.as_str(); @@ -385,7 +385,7 @@ pub fn check_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) { } /// Type-check `extern "platform-intrinsic" { ... }` functions. -pub fn check_platform_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) { +pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { let param = |n| { let name = InternedString::intern(&format!("P{}", n)); tcx.mk_ty_param(n, name) diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index b492197870b75..b8b65279fe767 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -26,7 +26,6 @@ use rustc::infer::{self, InferOk}; use syntax::ast; use syntax_pos::Span; -use crate::{check_type_alias_enum_variants_enabled}; use self::probe::{IsSuggestion, ProbeScope}; pub fn provide(providers: &mut ty::query::Providers<'_>) { @@ -417,8 +416,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.hygienic_eq(method_name, vd.ident, adt_def.did) }); if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - // Braced variants generate unusable names in value namespace (reserved for // possible future use), so variants resolved as associated items may refer to // them as well. It's ok to use the variant's id as a ctor id since an diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 661883f2ac11d..bd4cf9d208684 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -970,9 +970,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("pick: actual search failed, assemble diagnotics"); - let static_candidates = mem::replace(&mut self.static_candidates, vec![]); + let static_candidates = mem::take(&mut self.static_candidates); let private_candidate = self.private_candidate.take(); - let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]); + let unsatisfied_predicates = mem::take(&mut self.unsatisfied_predicates); // things failed, so lets look at all traits, for diagnostic purposes now: self.reset(); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index fa1b07d2dcfcd..be00a6efe55ed 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -775,12 +775,12 @@ impl Ord for TraitInfo { } /// Retrieves all traits in this crate and any dependent crates. -pub fn all_traits<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +pub fn all_traits(tcx: TyCtxt<'_>) -> Vec { tcx.all_traits(LOCAL_CRATE).iter().map(|&def_id| TraitInfo { def_id }).collect() } /// Computes all traits in this crate and any dependent crates. -fn compute_all_traits<'tcx>(tcx: TyCtxt<'tcx>) -> Vec { +fn compute_all_traits(tcx: TyCtxt<'_>) -> Vec { use hir::itemlikevisit; let mut traits = vec![]; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 37866bab9009d..fb7d681a72da7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -93,6 +93,7 @@ use rustc::hir::def::{CtorOf, Res, DefKind}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::ptr::P; use crate::middle::lang_items; use crate::namespace::Namespace; use rustc::infer::{self, InferCtxt, InferOk, InferResult}; @@ -122,7 +123,6 @@ use syntax_pos::hygiene::CompilerDesugaringKind; use syntax::ast; use syntax::attr; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax::ptr::P; use syntax::source_map::{DUMMY_SP, original_sp}; use syntax::symbol::{kw, sym}; @@ -698,31 +698,31 @@ impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> { fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { } } -pub fn check_wf_new<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_wf_new(tcx: TyCtxt<'_>) { let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); tcx.hir().krate().par_visit_all_item_likes(&mut visit); } -fn check_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx }); } -fn typeck_item_bodies<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) { +fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) { debug_assert!(crate_num == LOCAL_CRATE); tcx.par_body_owners(|body_owner_def_id| { tcx.ensure().typeck_tables_of(body_owner_def_id); }); } -fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { wfcheck::check_item_well_formed(tcx, def_id); } -fn check_trait_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { wfcheck::check_trait_item(tcx, def_id); } -fn check_impl_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { wfcheck::check_impl_item(tcx, def_id); } @@ -742,7 +742,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn adt_destructor<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { +fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option { tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl) } @@ -755,10 +755,10 @@ fn adt_destructor<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option( - tcx: TyCtxt<'tcx>, +fn primary_body_of( + tcx: TyCtxt<'_>, id: hir::HirId, -) -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)> { +) -> Option<(hir::BodyId, Option<&hir::FnDecl>)> { match tcx.hir().get(id) { Node::Item(item) => { match item.node { @@ -796,7 +796,7 @@ fn primary_body_of<'tcx>( } } -fn has_typeck_tables<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // Closures' tables come from their outermost function, // as they are part of the same "inference environment". let outer_def_id = tcx.closure_base_def_id(def_id); @@ -808,11 +808,11 @@ fn has_typeck_tables<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { primary_body_of(tcx, id).is_some() } -fn used_trait_imports<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx DefIdSet { +fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet { &*tcx.typeck_tables_of(def_id).used_trait_imports } -fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckTables<'tcx> { +fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { // Closures' tables come from their outermost function, // as they are part of the same "inference environment". let outer_def_id = tcx.closure_base_def_id(def_id); @@ -856,7 +856,8 @@ fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckT let revealed_ty = if tcx.features().impl_trait_in_bindings { fcx.instantiate_opaque_types_from_value( id, - &expected_type + &expected_type, + body.value.span, ) } else { expected_type @@ -912,7 +913,7 @@ fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckT tables } -fn check_abi<'tcx>(tcx: TyCtxt<'tcx>, span: Span, abi: Abi) { +fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) { if !tcx.sess.target.target.is_abi_supported(abi) { struct_span_err!(tcx.sess, span, E0570, "The ABI `{}` is not supported for the current target", abi).emit() @@ -962,7 +963,8 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings { self.fcx.instantiate_opaque_types_from_value( self.parent_id, - &o_ty + &o_ty, + ty.span, ) } else { o_ty @@ -1058,7 +1060,11 @@ fn check_fn<'a, 'tcx>( let declared_ret_ty = fn_sig.output(); fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); - let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty); + let revealed_ret_ty = fcx.instantiate_opaque_types_from_value( + fn_id, + &declared_ret_ty, + decl.output.span(), + ); fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty))); fn_sig = fcx.tcx.mk_fn_sig( fn_sig.inputs().iter().cloned(), @@ -1285,7 +1291,7 @@ fn check_fn<'a, 'tcx>( (fcx, gen_ty) } -fn check_struct<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) { +fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) { let def_id = tcx.hir().local_def_id_from_hir_id(id); let def = tcx.adt_def(def_id); def.destructor(tcx); // force the destructor to be evaluated @@ -1299,7 +1305,7 @@ fn check_struct<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) { check_packed(tcx, span, def_id); } -fn check_union<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) { +fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) { let def_id = tcx.hir().local_def_id_from_hir_id(id); let def = tcx.adt_def(def_id); def.destructor(tcx); // force the destructor to be evaluated @@ -1461,14 +1467,14 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) } } -fn check_on_unimplemented<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, item: &hir::Item) { +fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) { let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id); // an error would be reported if this fails. let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id); } -fn report_forbidden_specialization<'tcx>( - tcx: TyCtxt<'tcx>, +fn report_forbidden_specialization( + tcx: TyCtxt<'_>, impl_item: &hir::ImplItem, parent_impl: DefId, ) { @@ -1684,7 +1690,7 @@ fn check_impl_items_against_trait<'tcx>( /// Checks whether a type can be represented in memory. In particular, it /// identifies types that contain themselves without indirection through a /// pointer, which would mean their size is unbounded. -fn check_representable<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, item_def_id: DefId) -> bool { +fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool { let rty = tcx.type_of(item_def_id); // Check that it is possible to represent this type. This call identifies @@ -1706,7 +1712,7 @@ fn check_representable<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, item_def_id: DefId) -> return true; } -pub fn check_simd<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) { +pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { let t = tcx.type_of(def_id); if let ty::Adt(def, substs) = t.sty { if def.is_struct() { @@ -1735,7 +1741,7 @@ pub fn check_simd<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) { } } -fn check_packed<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) { +fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { let repr = tcx.adt_def(def_id).repr; if repr.packed() { for attr in tcx.get_attrs(def_id).iter() { @@ -1759,7 +1765,7 @@ fn check_packed<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) { } } -fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec) -> bool { +fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec) -> bool { let t = tcx.type_of(def_id); if stack.contains(&def_id) { debug!("check_packed_inner: {:?} is recursive", t); @@ -1833,7 +1839,7 @@ fn bad_non_zero_sized_fields<'tcx>( err.emit(); } -fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) { +fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { let adt = tcx.adt_def(def_id); if !adt.repr.transparent() { return; @@ -1982,7 +1988,7 @@ pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], i check_transparent(tcx, sp, def_id); } -fn report_unexpected_variant_res<'tcx>(tcx: TyCtxt<'tcx>, res: Res, span: Span, qpath: &QPath) { +fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) { span_err!(tcx.sess, span, E0533, "expected unit struct/variant or constant, found {} `{}`", res.descr(), @@ -2445,6 +2451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, parent_id: hir::HirId, value: &T, + value_span: Span, ) -> T { let parent_def_id = self.tcx.hir().local_def_id_from_hir_id(parent_id); debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})", @@ -2457,6 +2464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.body_id, self.param_env, value, + value_span, ) ); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 034ff5f834767..3aa144ca35282 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -3,7 +3,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par use crate::hir::def_id::DefId; use rustc::traits::{self, ObligationCauseCode}; -use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate}; +use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate}; use rustc::ty::subst::{Subst, InternalSubsts}; use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::mir::interpret::ConstValue; @@ -68,7 +68,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> { /// We do this check as a pre-pass before checking fn bodies because if these constraints are /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. -pub fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item = tcx.hir().expect_item(hir_id); @@ -156,7 +156,7 @@ pub fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { } } -pub fn check_trait_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let trait_item = tcx.hir().expect_trait_item(hir_id); @@ -167,7 +167,7 @@ pub fn check_trait_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig); } -pub fn check_impl_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let impl_item = tcx.hir().expect_impl_item(hir_id); @@ -178,8 +178,8 @@ pub fn check_impl_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { check_associated_item(tcx, impl_item.hir_id, impl_item.span, method_sig); } -fn check_associated_item<'tcx>( - tcx: TyCtxt<'tcx>, +fn check_associated_item( + tcx: TyCtxt<'_>, item_id: hir::HirId, span: Span, sig_if_method: Option<&hir::MethodSig>, @@ -231,7 +231,7 @@ fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) -> CheckWfFcxBuilder<'tcx for_id(tcx, item.hir_id, item.span) } -fn for_id<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'tcx> { +fn for_id(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'_> { let def_id = tcx.hir().local_def_id_from_hir_id(id); CheckWfFcxBuilder { inherited: Inherited::build(tcx, def_id), @@ -261,14 +261,15 @@ fn check_type_defn<'tcx, F>( let needs_drop_copy = || { packed && { let ty = variant.fields.last().unwrap().ty; - fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx) - .map(|ty| ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))) - .unwrap_or_else(|| { + let ty = fcx.tcx.erase_regions(&ty); + if ty.has_local_value() { fcx_tcx.sess.delay_span_bug( item.span, &format!("inference variables in {:?}", ty)); // Just treat unresolved type expression as if it needs drop. true - }) + } else { + ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)) + } } }; let all_sized = @@ -316,7 +317,7 @@ fn check_type_defn<'tcx, F>( }); } -fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) { +fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item) { debug!("check_trait: {:?}", item.hir_id); let trait_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id); @@ -339,7 +340,7 @@ fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) { }); } -fn check_item_fn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) { +fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item) { for_item(tcx, item).with_fcx(|fcx, tcx| { let def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id); let sig = fcx.tcx.fn_sig(def_id); @@ -351,8 +352,8 @@ fn check_item_fn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) { }) } -fn check_item_type<'tcx>( - tcx: TyCtxt<'tcx>, +fn check_item_type( + tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_foreign_ty: bool, @@ -979,7 +980,7 @@ fn check_variances_for_type_defn<'tcx>( } } -fn report_bivariance<'tcx>(tcx: TyCtxt<'tcx>, span: Span, param_name: ast::Name) { +fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) { let mut err = error_392(tcx, span, param_name); let suggested_marker_id = tcx.lang_items().phantom_data(); @@ -1022,7 +1023,7 @@ fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) { /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that /// aren't true. -fn check_false_global_bounds<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span: Span, id: hir::HirId) { +fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) { let empty_env = ty::ParamEnv::empty(); let def_id = fcx.tcx.hir().local_def_id_from_hir_id(id); @@ -1103,6 +1104,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id)); let field_ty = self.normalize_associated_types_in(field.span, &field_ty); + let field_ty = self.resolve_vars_if_possible(&field_ty); + debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty); AdtField { ty: field_ty, span: field.span } }) .collect(); @@ -1134,11 +1137,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -fn error_392<'tcx>( - tcx: TyCtxt<'tcx>, +fn error_392( + tcx: TyCtxt<'_>, span: Span, param_name: ast::Name, -) -> DiagnosticBuilder<'tcx> { +) -> DiagnosticBuilder<'_> { let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name); err.span_label(span, "unused parameter"); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 6a95dec1c81bc..28711e32a4c51 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -363,10 +363,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } fn visit_free_region_map(&mut self) { - let free_region_map = self.tcx() - .lift_to_global(&self.fcx.tables.borrow().free_region_map); - let free_region_map = free_region_map.expect("all regions in free-region-map are global"); - self.tables.free_region_map = free_region_map; + self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone(); + debug_assert!(!self.tables.free_region_map.elements().any(|r| r.has_local_value())); } fn visit_user_provided_tys(&mut self) { @@ -381,12 +379,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { local_id, }; - let c_ty = if let Some(c_ty) = self.tcx().lift_to_global(c_ty) { - c_ty - } else { + if cfg!(debug_assertions) && c_ty.has_local_value() { span_bug!( hir_id.to_span(self.fcx.tcx), - "writeback: `{:?}` missing from the global type context", + "writeback: `{:?}` is a local value", c_ty ); }; @@ -423,12 +419,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); for (&def_id, c_sig) in fcx_tables.user_provided_sigs.iter() { - let c_sig = if let Some(c_sig) = self.tcx().lift_to_global(c_sig) { - c_sig - } else { + if cfg!(debug_assertions) && c_sig.has_local_value() { span_bug!( self.fcx.tcx.hir().span_if_local(def_id).unwrap(), - "writeback: `{:?}` missing from the global type context", + "writeback: `{:?}` is a local value", c_sig ); }; @@ -592,10 +586,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - if let Some(substs) = self.tcx().lift_to_global(&opaque_defn.substs) { + if !opaque_defn.substs.has_local_value() { let new = ty::ResolvedOpaqueTy { concrete_type: definition_ty, - substs, + substs: opaque_defn.substs, }; let old = self.tables @@ -617,7 +611,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } else { self.tcx().sess.delay_span_bug( span, - "cannot lift `opaque_defn` substs to global type context", + "`opaque_defn` is a local value", ); } } @@ -743,20 +737,19 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - fn resolve(&self, x: &T, span: &dyn Locatable) -> T::Lifted + fn resolve(&self, x: &T, span: &dyn Locatable) -> T where - T: TypeFoldable<'tcx> + ty::Lift<'tcx>, + T: TypeFoldable<'tcx>, { let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body)); - if let Some(lifted) = self.tcx().lift_to_global(&x) { - lifted - } else { + if cfg!(debug_assertions) && x.has_local_value() { span_bug!( span.to_span(self.fcx.tcx), - "writeback: `{:?}` missing from the global type context", + "writeback: `{:?}` is a local value", x ); } + x } } diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 7e781eeec56a9..8614de1977085 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -13,7 +13,7 @@ use rustc::util::nodemap::DefIdSet; use rustc_data_structures::fx::FxHashMap; -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_crate(tcx: TyCtxt<'_>) { let mut used_trait_imports = DefIdSet::default(); for &body_id in tcx.hir().krate().bodies.keys() { let item_def_id = tcx.hir().body_owner_def_id(body_id); @@ -70,7 +70,7 @@ impl CheckVisitor<'tcx> { } } -fn unused_crates_lint<'tcx>(tcx: TyCtxt<'tcx>) { +fn unused_crates_lint(tcx: TyCtxt<'_>) { let lint = lint::builtin::UNUSED_EXTERN_CRATES; // Collect first the crates that are completely unused. These we diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 42deeaf31f427..68bdcbfe3fd95 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -17,7 +17,7 @@ use rustc::hir::def_id::DefId; use hir::Node; use rustc::hir::{self, ItemKind}; -pub fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) { +pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) { Checker { tcx, trait_def_id } .check(tcx.lang_items().drop_trait(), visit_implementation_of_drop) .check(tcx.lang_items().copy_trait(), visit_implementation_of_copy) @@ -46,7 +46,7 @@ impl<'tcx> Checker<'tcx> { } } -fn visit_implementation_of_drop<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { +fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) { if let ty::Adt(..) = tcx.type_of(impl_did).sty { /* do nothing */ } else { @@ -74,7 +74,7 @@ fn visit_implementation_of_drop<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { } } -fn visit_implementation_of_copy<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { +fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); let impl_hir_id = if let Some(n) = tcx.hir().as_local_hir_id(impl_did) { @@ -154,7 +154,7 @@ fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'tcx>, impl_did: DefId) { } } -fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) { +fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) { debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); if impl_did.is_local() { diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 6088c03fc0681..9efe1273ac044 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -7,7 +7,6 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. -use rustc::dep_graph::DepKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -17,10 +16,10 @@ use syntax::ast; use syntax_pos::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. -pub fn crate_inherent_impls<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn crate_inherent_impls( + tcx: TyCtxt<'_>, crate_num: CrateNum, -) -> &'tcx CrateInherentImpls { +) -> &CrateInherentImpls { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); @@ -33,38 +32,14 @@ pub fn crate_inherent_impls<'tcx>( } /// On-demand query: yields a vector of the inherent impls for a specific type. -pub fn inherent_impls<'tcx>(tcx: TyCtxt<'tcx>, ty_def_id: DefId) -> &'tcx [DefId] { +pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: DefId) -> &[DefId] { assert!(ty_def_id.is_local()); - // NB. Until we adopt the red-green dep-tracking algorithm (see - // [the plan] for details on that), we do some hackery here to get - // the dependencies correct. Basically, we use a `with_ignore` to - // read the result we want. If we didn't have the `with_ignore`, - // we would wind up with a dependency on the entire crate, which - // we don't want. Then we go and add dependencies on all the impls - // in the result (which is what we wanted). - // - // The result is a graph with an edge from `Hir(I)` for every impl - // `I` defined on some type `T` to `CoherentInherentImpls(T)`, - // thus ensuring that if any of those impls change, the set of - // inherent impls is considered dirty. - // - // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 - - let result = tcx.dep_graph.with_ignore(|| { - let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); - match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => &v[..], - None => &[], - } - }); - - for &impl_def_id in &result[..] { - let def_path_hash = tcx.def_path_hash(impl_def_id); - tcx.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir)); + let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); + match crate_map.inherent_impls.get(&ty_def_id) { + Some(v) => &v[..], + None => &[], } - - result } struct InherentCollect<'tcx> { diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index aae1b1777a30f..1785304fb1d48 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -5,7 +5,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::traits::{self, IntercrateMode}; use rustc::ty::TyCtxt; -pub fn crate_inherent_impls_overlap_check<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) { +pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx }); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 4336e861ce216..9b9789139b70f 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -18,7 +18,7 @@ mod inherent_impls_overlap; mod orphan; mod unsafety; -fn check_impl<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) { +fn check_impl(tcx: TyCtxt<'_>, hir_id: HirId) { let impl_def_id = tcx.hir().local_def_id_from_hir_id(hir_id); // If there are no traits, then this implementation must have a @@ -124,7 +124,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn coherent_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { +fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { let impls = tcx.hir().trait_impls(def_id); for &impl_id in impls { check_impl(tcx, impl_id); @@ -135,7 +135,7 @@ fn coherent_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) { builtin::check_trait(tcx, def_id); } -pub fn check_coherence<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check_coherence(tcx: TyCtxt<'_>) { for &trait_def_id in tcx.hir().krate().trait_impls.keys() { tcx.ensure().coherent_trait(trait_def_id); } @@ -151,7 +151,7 @@ pub fn check_coherence<'tcx>(tcx: TyCtxt<'tcx>) { /// Overlap: no two impls for the same trait are implemented for the /// same type. Likewise, no two inherent impls for a given type /// constructor provide a method with the same name. -fn check_impl_overlap<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) { +fn check_impl_overlap(tcx: TyCtxt<'_>, hir_id: HirId) { let impl_def_id = tcx.hir().local_def_id_from_hir_id(hir_id); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 4e6fcfe0593e2..2d0faecd8ee71 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -6,7 +6,7 @@ use rustc::ty::{self, TyCtxt}; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; -pub fn check<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check(tcx: TyCtxt<'_>) { let mut orphan = OrphanChecker { tcx }; tcx.hir().krate().visit_all_item_likes(&mut orphan); } diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index c41a0e1514e68..123d7c6123b89 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -5,7 +5,7 @@ use rustc::ty::TyCtxt; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::{self, Unsafety}; -pub fn check<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn check(tcx: TyCtxt<'_>) { let mut unsafety = UnsafetyChecker { tcx }; tcx.hir().krate().visit_all_item_likes(&mut unsafety); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 87e1166b7c041..e5802179ec479 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -56,7 +56,7 @@ struct OnlySelfBounds(bool); /////////////////////////////////////////////////////////////////////////// // Main entry point -fn collect_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut CollectItemTypesVisitor { tcx }.as_deep_visitor() @@ -253,10 +253,10 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } } -fn type_param_predicates<'tcx>( - tcx: TyCtxt<'tcx>, +fn type_param_predicates( + tcx: TyCtxt<'_>, (item_def_id, def_id): (DefId, DefId), -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { use rustc::hir::*; // In the AST, bounds can derive from two places. Either @@ -381,7 +381,7 @@ impl ItemCtxt<'tcx> { /// parameter with ID `param_id`. We use this so as to avoid running /// `ast_ty_to_ty`, because we want to avoid triggering an all-out /// conversion of the type to avoid inducing unnecessary cycles. -fn is_param<'tcx>(tcx: TyCtxt<'tcx>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool { +fn is_param(tcx: TyCtxt<'_>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool { if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node { match path.res { Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => { @@ -394,7 +394,7 @@ fn is_param<'tcx>(tcx: TyCtxt<'tcx>, ast_ty: &hir::Ty, param_id: hir::HirId) -> } } -fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { +fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) { let it = tcx.hir().expect_item(item_id); debug!("convert: item {} with id {}", it.ident, it.hir_id); let def_id = tcx.hir().local_def_id_from_hir_id(item_id); @@ -476,7 +476,7 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) { } } -fn convert_trait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_id: hir::HirId) { +fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { let trait_item = tcx.hir().expect_trait_item(trait_item_id); let def_id = tcx.hir().local_def_id_from_hir_id(trait_item.hir_id); tcx.generics_of(def_id); @@ -497,7 +497,7 @@ fn convert_trait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_id: hir::HirId) { tcx.predicates_of(def_id); } -fn convert_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item_id: hir::HirId) { +fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { let def_id = tcx.hir().local_def_id_from_hir_id(impl_item_id); tcx.generics_of(def_id); tcx.type_of(def_id); @@ -507,7 +507,7 @@ fn convert_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item_id: hir::HirId) { } } -fn convert_variant_ctor<'tcx>(tcx: TyCtxt<'tcx>, ctor_id: hir::HirId) { +fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) { let def_id = tcx.hir().local_def_id_from_hir_id(ctor_id); tcx.generics_of(def_id); tcx.type_of(def_id); @@ -562,8 +562,8 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants: } } -fn convert_variant<'tcx>( - tcx: TyCtxt<'tcx>, +fn convert_variant( + tcx: TyCtxt<'_>, variant_did: Option, ctor_did: Option, ident: Ident, @@ -619,7 +619,7 @@ fn convert_variant<'tcx>( ) } -fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { +fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef { use rustc::hir::*; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -686,10 +686,10 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { /// Ensures that the super-predicates of the trait with a `DefId` /// of `trait_def_id` are converted and stored. This also ensures that /// the transitive super-predicates are converted. -fn super_predicates_of<'tcx>( - tcx: TyCtxt<'tcx>, +fn super_predicates_of( + tcx: TyCtxt<'_>, trait_def_id: DefId, -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { debug!("super_predicates(trait_def_id={:?})", trait_def_id); let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap(); @@ -740,7 +740,7 @@ fn super_predicates_of<'tcx>( }) } -fn trait_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TraitDef { +fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item = tcx.hir().expect_item(hir_id); @@ -879,7 +879,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { +fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { use rustc::hir::*; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -1122,7 +1122,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics { }) } -fn report_assoc_ty_on_inherent_impl<'tcx>(tcx: TyCtxt<'tcx>, span: Span) { +fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) { span_err!( tcx.sess, span, @@ -1131,7 +1131,7 @@ fn report_assoc_ty_on_inherent_impl<'tcx>(tcx: TyCtxt<'tcx>, span: Span) { ); } -fn type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { +fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { checked_type_of(tcx, def_id, true).unwrap() } @@ -1139,7 +1139,7 @@ fn type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { /// /// If you want to fail anyway, you can set the `fail` parameter to true, but in this case, /// you'd better just call [`type_of`] directly. -pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Option> { +pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option> { use rustc::hir::*; let hir_id = match tcx.hir().as_local_hir_id(def_id) { @@ -1353,7 +1353,7 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op None } } - Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(path), + Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(&**path), _ => None, }; @@ -1464,7 +1464,7 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op }) } -fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { +fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { use rustc::hir::{ImplItem, Item, TraitItem}; debug!("find_existential_constraints({:?})", def_id); @@ -1682,7 +1682,7 @@ fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'t } } -fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> { +fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { use rustc::hir::*; use rustc::hir::Node::*; @@ -1758,7 +1758,7 @@ fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> { } } -fn impl_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option> { +fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let icx = ItemCtxt::new(tcx, def_id); let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -1773,7 +1773,7 @@ fn impl_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option(tcx: TyCtxt<'tcx>, def_id: DefId) -> hir::ImplPolarity { +fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> hir::ImplPolarity { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); match tcx.hir().expect_item(hir_id).node { hir::ItemKind::Impl(_, polarity, ..) => polarity, @@ -1804,10 +1804,10 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>( /// Returns a list of type predicates for the definition with ID `def_id`, including inferred /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus /// inferred constraints concerning which regions outlive other regions. -fn predicates_defined_on<'tcx>( - tcx: TyCtxt<'tcx>, +fn predicates_defined_on( + tcx: TyCtxt<'_>, def_id: DefId, -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); debug!( @@ -1834,7 +1834,7 @@ fn predicates_defined_on<'tcx>( /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus /// `Self: Trait` predicates for traits. -fn predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::GenericPredicates<'tcx> { +fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> { let mut result = tcx.predicates_defined_on(def_id); if tcx.is_trait(def_id) { @@ -1861,10 +1861,10 @@ fn predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::GenericPre /// Returns a list of user-specified type predicates for the definition with ID `def_id`. /// N.B., this does not include any implied/inferred constraints. -fn explicit_predicates_of<'tcx>( - tcx: TyCtxt<'tcx>, +fn explicit_predicates_of( + tcx: TyCtxt<'_>, def_id: DefId, -) -> &'tcx ty::GenericPredicates<'tcx> { +) -> &ty::GenericPredicates<'_> { use rustc::hir::*; use rustc_data_structures::fx::FxHashSet; @@ -2271,7 +2271,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( fty } -fn is_foreign_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { +fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool { match tcx.hir().get_if_local(def_id) { Some(Node::ForeignItem(..)) => true, Some(_) => false, @@ -2279,7 +2279,7 @@ fn is_foreign_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { } } -fn static_mutability<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option { +fn static_mutability(tcx: TyCtxt<'_>, def_id: DefId) -> Option { match tcx.hir().get_if_local(def_id) { Some(Node::Item(&hir::Item { node: hir::ItemKind::Static(_, mutbl, _), .. @@ -2387,7 +2387,7 @@ fn from_target_feature( } } -fn linkage_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Linkage { +fn linkage_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Linkage { use rustc::mir::mono::Linkage::*; // Use the names from src/llvm/docs/LangRef.rst here. Most types are only @@ -2422,7 +2422,7 @@ fn linkage_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Linkag } } -fn codegen_fn_attrs<'tcx>(tcx: TyCtxt<'tcx>, id: DefId) -> CodegenFnAttrs { +fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { let attrs = tcx.get_attrs(id); let mut codegen_fn_attrs = CodegenFnAttrs::new(); diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index b833d8555ee0a..08c7cbc389a67 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -49,7 +49,7 @@ use syntax_pos::Span; /// impl<'a> Trait for Bar { type X = &'a i32; } /// // ^ 'a is unused and appears in assoc type, error /// ``` -pub fn impl_wf_check<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn impl_wf_check(tcx: TyCtxt<'_>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. @@ -58,7 +58,7 @@ pub fn impl_wf_check<'tcx>(tcx: TyCtxt<'tcx>) { } } -fn check_mod_impl_wf<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) { +fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: DefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut ImplWfCheck { tcx } @@ -92,8 +92,8 @@ impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { } } -fn enforce_impl_params_are_constrained<'tcx>( - tcx: TyCtxt<'tcx>, +fn enforce_impl_params_are_constrained( + tcx: TyCtxt<'_>, impl_def_id: DefId, impl_item_refs: &[hir::ImplItemRef], ) { @@ -183,7 +183,7 @@ fn report_unused_parameter(tcx: TyCtxt<'_>, span: Span, kind: &str, name: &str) } /// Enforce that we do not have two items in an impl with the same name. -fn enforce_impl_items_are_distinct<'tcx>(tcx: TyCtxt<'tcx>, impl_item_refs: &[hir::ImplItemRef]) { +fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) { let mut seen_type_items = FxHashMap::default(); let mut seen_value_items = FxHashMap::default(); for impl_item_ref in impl_item_refs { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 182594e768468..88e6c0f579efa 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -69,6 +69,7 @@ This API is completely unstable and subject to change. #![feature(slice_patterns)] #![feature(never_type)] #![feature(inner_deref)] +#![feature(mem_take)] #![recursion_limit="256"] @@ -105,7 +106,7 @@ use rustc::lint; use rustc::middle; use rustc::session; use rustc::util::common::ErrorReported; -use rustc::session::config::{EntryFnType, nightly_options}; +use rustc::session::config::EntryFnType; use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt}; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt}; @@ -124,21 +125,6 @@ pub struct TypeAndSubsts<'tcx> { ty: Ty<'tcx>, } -fn check_type_alias_enum_variants_enabled<'tcx>(tcx: TyCtxt<'tcx>, span: Span) { - if !tcx.features().type_alias_enum_variants { - let mut err = tcx.sess.struct_span_err( - span, - "enum variants on type aliases are experimental" - ); - if nightly_options::is_nightly_build() { - help!(&mut err, - "add `#![feature(type_alias_enum_variants)]` to the \ - crate attributes to enable"); - } - err.emit(); - } -} - fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl, abi: Abi, span: Span) { if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) { let mut err = struct_span_err!(tcx.sess, span, E0045, @@ -176,7 +162,7 @@ fn require_same_types<'tcx>( }) } -fn check_main_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, main_def_id: DefId) { +fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { let main_id = tcx.hir().as_local_hir_id(main_def_id).unwrap(); let main_span = tcx.def_span(main_def_id); let main_t = tcx.type_of(main_def_id); @@ -241,7 +227,7 @@ fn check_main_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, main_def_id: DefId) { } } -fn check_start_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, start_def_id: DefId) { +fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { let start_id = tcx.hir().as_local_hir_id(start_def_id).unwrap(); let start_span = tcx.def_span(start_def_id); let start_t = tcx.type_of(start_def_id); @@ -298,7 +284,7 @@ fn check_start_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, start_def_id: DefId) { } } -fn check_for_entry_fn<'tcx>(tcx: TyCtxt<'tcx>) { +fn check_for_entry_fn(tcx: TyCtxt<'_>) { match tcx.entry_fn(LOCAL_CRATE) { Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id), Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), @@ -315,7 +301,7 @@ pub fn provide(providers: &mut Providers<'_>) { impl_wf_check::provide(providers); } -pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> { +pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { tcx.sess.profiler(|p| p.start_activity("type-check crate")); // this ensures that later parts of type checking can assume that items diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index 63e41e01fbff5..6b8f6fccd40d7 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -20,10 +20,10 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn inferred_outlives_of<'tcx>( - tcx: TyCtxt<'tcx>, +fn inferred_outlives_of( + tcx: TyCtxt<'_>, item_def_id: DefId, -) -> &'tcx [ty::Predicate<'tcx>] { +) -> &[ty::Predicate<'_>] { let id = tcx .hir() .as_local_hir_id(item_def_id) @@ -70,10 +70,10 @@ fn inferred_outlives_of<'tcx>( } } -fn inferred_outlives_crate<'tcx>( - tcx: TyCtxt<'tcx>, +fn inferred_outlives_crate( + tcx: TyCtxt<'_>, crate_num: CrateNum, -) -> &'tcx CratePredicatesMap<'tcx> { +) -> &CratePredicatesMap<'_> { assert_eq!(crate_num, LOCAL_CRATE); // Compute a map from each struct/enum/union S to the **explicit** diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs index 4690cb9eada2e..5ddf95b0f80c2 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/src/librustc_typeck/outlives/test.rs @@ -3,7 +3,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; use syntax::symbol::sym; -pub fn test_inferred_outlives<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn test_inferred_outlives(tcx: TyCtxt<'_>) { tcx.hir() .krate() .visit_all_item_likes(&mut OutlivesTest { tcx }); diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs index c6b0da3fe474c..783890da639f4 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/src/librustc_typeck/outlives/utils.rs @@ -125,7 +125,7 @@ pub fn insert_outlives_predicate<'tcx>( } } -fn is_free_region<'tcx>(tcx: TyCtxt<'tcx>, region: Region<'_>) -> bool { +fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool { // First, screen for regions that might appear in a type header. match region { // These correspond to `T: 'a` relationships: diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 1a8871a3da9da..343d7ea656fbb 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -34,7 +34,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn crate_variances<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx CrateVariancesMap<'tcx> { +fn crate_variances(tcx: TyCtxt<'_>, crate_num: CrateNum) -> &CrateVariancesMap<'_> { assert_eq!(crate_num, LOCAL_CRATE); let mut arena = arena::TypedArena::default(); let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena); @@ -42,7 +42,7 @@ fn crate_variances<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx CrateV tcx.arena.alloc(solve::solve_constraints(constraints_cx)) } -fn variances_of<'tcx>(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> &'tcx [ty::Variance] { +fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id"); let unsupported = || { // Variance not relevant. diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs index cefc200f5cba8..0c7ebc34e8f6d 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/src/librustc_typeck/variance/test.rs @@ -3,7 +3,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; use syntax::symbol::sym; -pub fn test_variance<'tcx>(tcx: TyCtxt<'tcx>) { +pub fn test_variance(tcx: TyCtxt<'_>) { tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx }); } diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 67113787915a3..ad211763a6c46 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -16,7 +16,7 @@ use syntax_pos::Span; use crate::html::escape::Escape; -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum Cfg { /// Accepts all configurations. True, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 41a56756a1480..8ae96d8665718 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,6 +20,7 @@ use rustc::mir::interpret::{GlobalId, ConstValue}; use rustc::hir; use rustc::hir::def::{CtorKind, DefKind, Res}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::ptr::P; use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind}; use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::fold::TypeFolder; @@ -29,7 +30,6 @@ use syntax::ast::{self, AttrStyle, Ident}; use syntax::attr; use syntax::ext::base::MacroKind; use syntax::source_map::{dummy_spanned, Spanned}; -use syntax::ptr::P; use syntax::symbol::{Symbol, kw, sym}; use syntax::symbol::InternedString; use syntax_pos::{self, Pos, FileName}; @@ -223,7 +223,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct ExternalCrate { pub name: String, pub src: FileName, @@ -355,7 +355,7 @@ impl Clean for CrateNum { /// Anything with a source location and set of attributes and, optionally, a /// name. That is, anything that can be documented. This doesn't correspond /// directly to the AST's concept of an item; it's a strict superset. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone)] pub struct Item { /// Stringified span pub source: Span, @@ -528,7 +528,7 @@ impl Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub enum ItemEnum { ExternCrateItem(String, Option), ImportItem(Import), @@ -594,7 +594,7 @@ impl ItemEnum { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Module { pub items: Vec, pub is_crate: bool, @@ -731,7 +731,7 @@ impl> NestedAttributesExt for I { /// Included files are kept separate from inline doc comments so that proper line-number /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are /// kept separate because of issue #42760. -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum DocFragment { /// A doc fragment created from a `///` or `//!` doc comment. SugaredDoc(usize, syntax_pos::Span, String), @@ -781,7 +781,7 @@ impl<'a> FromIterator<&'a DocFragment> for String { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] +#[derive(Clone, Debug, Default)] pub struct Attributes { pub doc_strings: Vec, pub other_attrs: Vec, @@ -1048,7 +1048,7 @@ impl Clean for [ast::Attribute] { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericBound { TraitBound(PolyTrait, hir::TraitBoundModifier), Outlives(Lifetime), @@ -1231,7 +1231,7 @@ impl<'tcx> Clean>> for InternalSubsts<'tcx> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Lifetime(String); impl Lifetime { @@ -1326,7 +1326,7 @@ impl Clean> for ty::RegionKind { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, @@ -1464,7 +1464,7 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericParamDefKind { Lifetime, Type { @@ -1498,7 +1498,7 @@ impl GenericParamDefKind { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct GenericParamDef { pub name: String, @@ -1610,7 +1610,7 @@ impl Clean for hir::GenericParam { } // maybe use a Generic enum and use Vec? -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Default, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)] pub struct Generics { pub params: Vec, pub where_predicates: Vec, @@ -1874,7 +1874,7 @@ pub fn get_all_types( (all_types.into_iter().collect(), ret_types) } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Method { pub generics: Generics, pub decl: FnDecl, @@ -1902,7 +1902,7 @@ impl<'a> Clean for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId, } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct TyMethod { pub header: hir::FnHeader, pub decl: FnDecl, @@ -1911,7 +1911,7 @@ pub struct TyMethod { pub ret_types: Vec, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Function { pub decl: FnDecl, pub generics: Generics, @@ -1952,7 +1952,7 @@ impl Clean for doctree::Function<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct FnDecl { pub inputs: Arguments, pub output: FunctionRetTy, @@ -1989,7 +1989,7 @@ impl FnDecl { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Arguments { pub values: Vec, } @@ -2063,13 +2063,13 @@ impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Argument { pub type_: Type, pub name: String, } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] pub enum SelfTy { SelfValue, SelfBorrowed(Option, Mutability), @@ -2093,7 +2093,7 @@ impl Argument { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum FunctionRetTy { Return(Type), DefaultReturn, @@ -2117,7 +2117,7 @@ impl GetDefId for FunctionRetTy { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Trait { pub auto: bool, pub unsafety: hir::Unsafety, @@ -2153,7 +2153,7 @@ impl Clean for doctree::Trait<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct TraitAlias { pub generics: Generics, pub bounds: Vec, @@ -2437,7 +2437,7 @@ impl Clean for ty::AssocItem { } /// A trait reference, which may have higher ranked lifetimes. -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct PolyTrait { pub trait_: Type, pub generic_params: Vec, @@ -2446,7 +2446,7 @@ pub struct PolyTrait { /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most /// importantly, it does not preserve mutability or boxes. -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum Type { /// Structs/enums/traits (most that would be an `hir::TyKind::Path`). ResolvedPath { @@ -2469,7 +2469,6 @@ pub enum Type { Array(Box, String), Never, CVarArgs, - Unique(Box), RawPointer(Mutability, Box), BorrowedRef { lifetime: Option, @@ -2491,7 +2490,7 @@ pub enum Type { ImplTrait(Vec), } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)] pub enum PrimitiveType { Isize, I8, I16, I32, I64, I128, Usize, U8, U16, U32, U64, U128, @@ -2510,7 +2509,7 @@ pub enum PrimitiveType { CVarArgs, } -#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)] +#[derive(Clone, Copy, Debug)] pub enum TypeKind { Enum, Function, @@ -2520,7 +2519,6 @@ pub enum TypeKind { Struct, Union, Trait, - Variant, Typedef, Foreign, Macro, @@ -3190,7 +3188,7 @@ impl Clean for ty::FieldDef { } } -#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub enum Visibility { Public, Inherited, @@ -3219,7 +3217,7 @@ impl Clean> for ty::Visibility { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Struct { pub struct_type: doctree::StructType, pub generics: Generics, @@ -3227,7 +3225,7 @@ pub struct Struct { pub fields_stripped: bool, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Union { pub struct_type: doctree::StructType, pub generics: Generics, @@ -3278,7 +3276,7 @@ impl Clean for doctree::Union<'_> { /// This is a more limited form of the standard Struct, different in that /// it lacks the things most items have (name, id, parameterization). Found /// only as a variant in an enum. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct VariantStruct { pub struct_type: doctree::StructType, pub fields: Vec, @@ -3295,7 +3293,7 @@ impl Clean for ::rustc::hir::VariantData { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Enum { pub variants: IndexVec, pub generics: Generics, @@ -3321,7 +3319,7 @@ impl Clean for doctree::Enum<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Variant { pub kind: VariantKind, } @@ -3384,7 +3382,7 @@ impl Clean for ty::VariantDef { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub enum VariantKind { CLike, Tuple(Vec), @@ -3402,7 +3400,7 @@ impl Clean for hir::VariantData { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Span { pub filename: FileName, pub loline: usize, @@ -3448,7 +3446,7 @@ impl Clean for syntax_pos::Span { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Path { pub global: bool, pub res: Res, @@ -3471,7 +3469,7 @@ impl Clean for hir::Path { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericArg { Lifetime(Lifetime), Type(Type), @@ -3488,7 +3486,7 @@ impl fmt::Display for GenericArg { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericArgs { AngleBracketed { args: Vec, @@ -3528,7 +3526,7 @@ impl Clean for hir::GenericArgs { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct PathSegment { pub name: String, pub args: GenericArgs, @@ -3553,7 +3551,6 @@ fn strip_type(ty: Type) -> Type { } Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))), Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s), - Type::Unique(inner_ty) => Type::Unique(Box::new(strip_type(*inner_ty))), Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))), Type::BorrowedRef { lifetime, mutability, type_ } => { Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) } @@ -3625,7 +3622,7 @@ impl Clean for InternedString { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Typedef { pub type_: Type, pub generics: Generics, @@ -3649,7 +3646,7 @@ impl Clean for doctree::Typedef<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Existential { pub bounds: Vec, pub generics: Generics, @@ -3673,7 +3670,7 @@ impl Clean for doctree::Existential<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct BareFunctionDecl { pub unsafety: hir::Unsafety, pub generic_params: Vec, @@ -3695,7 +3692,7 @@ impl Clean for hir::BareFnTy { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Static { pub type_: Type, pub mutability: Mutability, @@ -3725,7 +3722,7 @@ impl Clean for doctree::Static<'_> { } } -#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Constant { pub type_: Type, pub expr: String, @@ -3749,7 +3746,7 @@ impl Clean for doctree::Constant<'_> { } } -#[derive(Debug, Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)] pub enum Mutability { Mutable, Immutable, @@ -3764,7 +3761,7 @@ impl Clean for hir::Mutability { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Copy, Debug, Hash)] pub enum ImplPolarity { Positive, Negative, @@ -3779,7 +3776,7 @@ impl Clean for hir::ImplPolarity { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Impl { pub unsafety: hir::Unsafety, pub generics: Generics, @@ -4003,7 +4000,7 @@ impl Clean> for doctree::Import<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub enum Import { // use source as str; Simple(String, ImportSource), @@ -4011,7 +4008,7 @@ pub enum Import { Glob(ImportSource) } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct ImportSource { pub path: Path, pub did: Option, @@ -4227,7 +4224,7 @@ fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Macro { pub source: String, pub imported_from: Option, @@ -4256,7 +4253,7 @@ impl Clean for doctree::Macro<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct ProcMacro { pub kind: MacroKind, pub helpers: Vec, @@ -4280,7 +4277,7 @@ impl Clean for doctree::ProcMacro<'_> { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Stability { pub level: stability::StabilityLevel, pub feature: Option, @@ -4290,7 +4287,7 @@ pub struct Stability { pub issue: Option, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Debug)] pub struct Deprecation { pub since: Option, pub note: Option, @@ -4340,13 +4337,13 @@ impl Clean for attr::Deprecation { /// An type binding on an associated type (e.g., `A = Bar` in `Foo` or /// `A: Send + Sync` in `Foo`). -#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct TypeBinding { pub name: String, pub kind: TypeBindingKind, } -#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum TypeBindingKind { Equality { ty: Type, @@ -4411,7 +4408,7 @@ pub fn enter_impl_trait(cx: &DocContext<'_>, f: F) -> R where F: FnOnce() -> R, { - let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default()); + let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut()); let r = f(); assert!(cx.impl_trait_bounds.borrow().is_empty()); *cx.impl_trait_bounds.borrow_mut() = old_bounds; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 36e6a6003df09..e4fba73b8205a 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -131,7 +131,7 @@ pub fn ty_params(mut params: Vec) -> Vec { - *bounds = ty_bounds(mem::replace(bounds, Vec::new())); + *bounds = ty_bounds(mem::take(bounds)); } _ => panic!("expected only type parameters"), } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 6b490f730afa0..67ca7f407d801 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -351,9 +351,6 @@ impl Options { .unwrap_or_else(|| PathBuf::from("doc")); let mut cfgs = matches.opt_strs("cfg"); cfgs.push("rustdoc".to_string()); - if should_test { - cfgs.push("test".to_string()); - } let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s)); diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 51deb4e9b9747..45a3c8a3c2256 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -6,11 +6,11 @@ use syntax::ast; use syntax::ast::{Name, NodeId}; use syntax::attr; use syntax::ext::base::MacroKind; -use syntax::ptr::P; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::def_id::CrateNum; +use rustc::hir::ptr::P; pub struct Module<'hir> { pub name: Option, @@ -78,7 +78,7 @@ impl Module<'hir> { } } -#[derive(Debug, Clone, RustcEncodable, RustcDecodable, Copy)] +#[derive(Debug, Clone, Copy)] pub enum StructType { /// A braced struct Plain, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fa3bc3f5f4f8b..9e5cc03b83123 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -737,9 +737,6 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> } } } - clean::Unique(..) => { - panic!("should have been cleaned") - } } } diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index 3f3f4c85e81fc..5f1a1b31616c1 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -110,7 +110,6 @@ impl From for ItemType { clean::TypeKind::Module => ItemType::Module, clean::TypeKind::Static => ItemType::Static, clean::TypeKind::Const => ItemType::Constant, - clean::TypeKind::Variant => ItemType::Variant, clean::TypeKind::Typedef => ItemType::Typedef, clean::TypeKind::Foreign => ItemType::ForeignType, clean::TypeKind::Macro => ItemType::Macro, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index f0aff961c6751..2d6503c944560 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -660,7 +660,7 @@ pub fn run(mut krate: clean::Crate, deref_trait_did, deref_mut_trait_did, owned_box_did, - masked_crates: mem::replace(&mut krate.masked_crates, Default::default()), + masked_crates: mem::take(&mut krate.masked_crates), param_names: external_param_names, aliases: Default::default(), }; @@ -5188,9 +5188,6 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec { clean::Type::Array(ty, _) => { work.push_back(*ty); }, - clean::Type::Unique(ty) => { - work.push_back(*ty); - }, clean::Type::RawPointer(_, ty) => { work.push_back(*ty); }, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7a8b088020c53..342264db43c79 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -21,6 +21,7 @@ #![feature(drain_filter)] #![feature(inner_deref)] #![feature(never_type)] +#![feature(mem_take)] #![recursion_limit="256"] @@ -42,8 +43,6 @@ extern crate test as testing; #[macro_use] extern crate log; extern crate rustc_errors as errors; -extern crate serialize as rustc_serialize; // used by deriving - use std::default::Default; use std::env; use std::panic; diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index 8666ba357b832..144ff226c4283 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -4,7 +4,7 @@ use crate::fold; use crate::fold::{DocFolder}; use crate::passes::Pass; -use std::mem::replace; +use std::mem::take; pub const COLLAPSE_DOCS: Pass = Pass { name: "collapse-docs", @@ -46,7 +46,7 @@ fn collapse(doc_strings: &mut Vec) { let mut docs = vec![]; let mut last_frag: Option = None; - for frag in replace(doc_strings, vec![]) { + for frag in take(doc_strings) { if let Some(mut curr_frag) = last_frag.take() { let curr_kind = curr_frag.kind(); let new_kind = frag.kind(); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index ddce5cab1ebcb..63545ab45bf64 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -44,8 +44,7 @@ pub fn run(options: Options) -> i32 { let input = config::Input::File(options.input.clone()); let sessopts = config::Options { - maybe_sysroot: options.maybe_sysroot.clone().or_else( - || Some(env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_path_buf())), + maybe_sysroot: options.maybe_sysroot.clone(), search_paths: options.libs.clone(), crate_types: vec![config::CrateType::Dylib], cg: options.codegen_options.clone(), @@ -225,8 +224,7 @@ fn run_test( let outputs = OutputTypes::new(&[(OutputType::Exe, None)]); let sessopts = config::Options { - maybe_sysroot: maybe_sysroot.or_else( - || Some(env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_path_buf())), + maybe_sysroot, search_paths: libs, crate_types: vec![config::CrateType::Executable], output_types: outputs, @@ -530,13 +528,8 @@ pub fn make_test(s: &str, prog.push_str(everything_else); } else { let returns_result = everything_else.trim_end().ends_with("(())"); - let returns_option = everything_else.trim_end().ends_with("Some(())"); let (main_pre, main_post) = if returns_result { - (if returns_option { - "fn main() { fn _inner() -> Option<()> {" - } else { - "fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {" - }, + ("fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {", "}\n_inner().unwrap() }") } else { ("fn main() {\n", "\n}") diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 5a2fe2b244f55..2925d8362c8d9 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2608,6 +2608,12 @@ mod test_map { use realstd::collections::CollectionAllocErr::*; use realstd::usize; + // https://github.com/rust-lang/rust/issues/62301 + fn _assert_hashmap_is_unwind_safe() { + fn assert_unwind_safe() {} + assert_unwind_safe::>>(); + } + #[test] fn test_zero_capacities() { type HM = HashMap; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 60e06139eba99..fb9a228880eb7 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -272,6 +272,7 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![feature(mem_take)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 7a3b5d30500a9..1d4fd98dd754f 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -4,6 +4,7 @@ use crate::any::Any; use crate::cell::UnsafeCell; +use crate::collections; use crate::fmt; use crate::future::Future; use crate::pin::Pin; @@ -285,6 +286,11 @@ impl RefUnwindSafe for atomic::AtomicBool {} #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] impl RefUnwindSafe for atomic::AtomicPtr {} +// https://github.com/rust-lang/rust/issues/62301 +#[stable(feature = "hashbrown", since = "1.36.0")] +impl UnwindSafe for collections::HashMap + where K: UnwindSafe, V: UnwindSafe, S: UnwindSafe {} + #[stable(feature = "catch_unwind", since = "1.9.0")] impl Deref for AssertUnwindSafe { type Target = T; diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 9ef42063f9412..952fd9ebfdf07 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -103,7 +103,9 @@ pub fn set_hook(hook: Box) + 'static + Sync + Send>) { HOOK_LOCK.write_unlock(); if let Hook::Custom(ptr) = old_hook { - Box::from_raw(ptr); + #[allow(unused_must_use)] { + Box::from_raw(ptr); + } } } } @@ -362,7 +364,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! { unsafe impl<'a> BoxMeUp for PanicPayload<'a> { fn box_me_up(&mut self) -> *mut (dyn Any + Send) { - let contents = mem::replace(self.fill(), String::new()); + let contents = mem::take(self.fill()); Box::into_raw(Box::new(contents)) } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index a568f46663730..000f80f99e7a9 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1765,33 +1765,6 @@ mod tests { assert_eq!(out, "foobar\n"); } - - #[test] - #[cfg_attr(target_os = "android", ignore)] - #[cfg(unix)] - fn uid_works() { - use crate::os::unix::prelude::*; - - let mut p = Command::new("/bin/sh") - .arg("-c").arg("true") - .uid(unsafe { libc::getuid() }) - .gid(unsafe { libc::getgid() }) - .spawn().unwrap(); - assert!(p.wait().unwrap().success()); - } - - #[test] - #[cfg_attr(target_os = "android", ignore)] - #[cfg(unix)] - fn uid_to_root_fails() { - use crate::os::unix::prelude::*; - - // if we're already root, this isn't a valid test. Most of the bots run - // as non-root though (android is an exception). - if unsafe { libc::getuid() == 0 } { return } - assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err()); - } - #[test] #[cfg_attr(target_os = "android", ignore)] fn test_process_status() { diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 3c4f8e077c922..f8fcd3ff5a5bc 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -383,7 +383,7 @@ impl Packet { // needs to be careful to destroy the data *outside* of the lock to // prevent deadlock. let _data = if guard.cap != 0 { - mem::replace(&mut guard.buf.buf, Vec::new()) + mem::take(&mut guard.buf.buf) } else { Vec::new() }; diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 47fb6792f08ae..4201de794b708 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -40,15 +40,15 @@ impl Condvar { target_os = "android", target_os = "hermit")))] pub unsafe fn init(&mut self) { - use crate::mem; - let mut attr: libc::pthread_condattr_t = mem::uninitialized(); - let r = libc::pthread_condattr_init(&mut attr); + use crate::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + let r = libc::pthread_condattr_init(attr.as_mut_ptr()); assert_eq!(r, 0); - let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC); + let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC); assert_eq!(r, 0); - let r = libc::pthread_cond_init(self.inner.get(), &attr); + let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr()); assert_eq!(r, 0); - let r = libc::pthread_condattr_destroy(&mut attr); + let r = libc::pthread_condattr_destroy(attr.as_mut_ptr()); assert_eq!(r, 0); } diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 3ccb0a1b1abc7..41090caee8459 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -40,10 +40,9 @@ use libc::MSG_NOSIGNAL; target_os = "haiku")))] const MSG_NOSIGNAL: libc::c_int = 0x0; -fn sun_path_offset() -> usize { +fn sun_path_offset(addr: &libc::sockaddr_un) -> usize { // Work with an actual instance of the type since using a null pointer is UB - let addr: libc::sockaddr_un = unsafe { mem::uninitialized() }; - let base = &addr as *const _ as usize; + let base = addr as *const _ as usize; let path = &addr.sun_path as *const _ as usize; path - base } @@ -69,7 +68,7 @@ unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::sockl // null byte for pathname addresses is already there because we zeroed the // struct - let mut len = sun_path_offset() + bytes.len(); + let mut len = sun_path_offset(&addr) + bytes.len(); match bytes.get(0) { Some(&0) | None => {} Some(_) => len += 1, @@ -122,7 +121,7 @@ impl SocketAddr { if len == 0 { // When there is a datagram from unnamed unix socket // linux returns zero bytes of address - len = sun_path_offset() as libc::socklen_t; // i.e., zero-length address + len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { return Err(io::Error::new(io::ErrorKind::InvalidInput, "file descriptor did not correspond to a Unix socket")); @@ -200,7 +199,7 @@ impl SocketAddr { } fn address<'a>(&'a self) -> AddressKind<'a> { - let len = self.len as usize - sun_path_offset(); + let len = self.len as usize - sun_path_offset(&self.addr); let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index b6a22e1962ab8..b43af8fdcaaa1 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -1,5 +1,5 @@ use crate::cell::UnsafeCell; -use crate::mem; +use crate::mem::MaybeUninit; pub struct Mutex { inner: UnsafeCell } @@ -40,14 +40,14 @@ impl Mutex { // references, we instead create the mutex with type // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to // re-lock it from the same thread, thus avoiding undefined behavior. - let mut attr: libc::pthread_mutexattr_t = mem::uninitialized(); - let r = libc::pthread_mutexattr_init(&mut attr); + let mut attr = MaybeUninit::::uninit(); + let r = libc::pthread_mutexattr_init(attr.as_mut_ptr()); debug_assert_eq!(r, 0); - let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL); + let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL); debug_assert_eq!(r, 0); - let r = libc::pthread_mutex_init(self.inner.get(), &attr); + let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr()); debug_assert_eq!(r, 0); - let r = libc::pthread_mutexattr_destroy(&mut attr); + let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); debug_assert_eq!(r, 0); } #[inline] @@ -89,19 +89,19 @@ unsafe impl Sync for ReentrantMutex {} impl ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex { - ReentrantMutex { inner: mem::uninitialized() } + ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) } } pub unsafe fn init(&mut self) { - let mut attr: libc::pthread_mutexattr_t = mem::uninitialized(); - let result = libc::pthread_mutexattr_init(&mut attr as *mut _); + let mut attr = MaybeUninit::::uninit(); + let result = libc::pthread_mutexattr_init(attr.as_mut_ptr()); debug_assert_eq!(result, 0); - let result = libc::pthread_mutexattr_settype(&mut attr as *mut _, + let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_RECURSIVE); debug_assert_eq!(result, 0); - let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _); + let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr()); debug_assert_eq!(result, 0); - let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _); + let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); debug_assert_eq!(result, 0); } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index f6a12a16396b4..3ff4f194cd1a9 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -437,7 +437,7 @@ mod tests { #[cfg(target_os = "android")] unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { - libc::memset(set as *mut _, 0, mem::size_of::()); + set.write_bytes(0u8, 1); return 0; } @@ -466,11 +466,11 @@ mod tests { // Test to make sure that a signal mask does not get inherited. let mut cmd = Command::new(OsStr::new("cat")); - let mut set: libc::sigset_t = mem::uninitialized(); - let mut old_set: libc::sigset_t = mem::uninitialized(); - t!(cvt(sigemptyset(&mut set))); - t!(cvt(sigaddset(&mut set, libc::SIGINT))); - t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set))); + let mut set = mem::MaybeUninit::::uninit(); + let mut old_set = mem::MaybeUninit::::uninit(); + t!(cvt(sigemptyset(set.as_mut_ptr()))); + t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT))); + t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr()))); cmd.stdin(Stdio::MakePipe); cmd.stdout(Stdio::MakePipe); @@ -479,7 +479,7 @@ mod tests { let stdin_write = pipes.stdin.take().unwrap(); let stdout_read = pipes.stdout.take().unwrap(); - t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set, + t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut()))); t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT))); diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 80fe763aecc88..be38a1334ec32 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -202,7 +202,7 @@ impl Command { // emscripten has no signal support. #[cfg(not(any(target_os = "emscripten")))] { - use crate::mem; + use crate::mem::MaybeUninit; // Reset signal handling so the child process starts in a // standardized state. libstd ignores SIGPIPE, and signal-handling // libraries often set a mask. Child processes inherit ignored @@ -210,18 +210,16 @@ impl Command { // UNIX programs do not reset these things on their own, so we // need to clean things up now to avoid confusing the program // we're about to run. - let mut set: libc::sigset_t = mem::uninitialized(); + let mut set = MaybeUninit::::uninit(); if cfg!(target_os = "android") { // Implementing sigemptyset allow us to support older Android // versions. See the comment about Android and sig* functions in // process_common.rs - libc::memset(&mut set as *mut _ as *mut _, - 0, - mem::size_of::()); + set.as_mut_ptr().write_bytes(0u8, 1); } else { - cvt(libc::sigemptyset(&mut set))?; + cvt(libc::sigemptyset(set.as_mut_ptr()))?; } - cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, + cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), ptr::null_mut()))?; let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL); if ret == libc::SIG_ERR { @@ -273,7 +271,7 @@ impl Command { fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { - use crate::mem; + use crate::mem::MaybeUninit; use crate::sys; if self.get_gid().is_some() || @@ -315,63 +313,63 @@ impl Command { let mut p = Process { pid: 0, status: None }; - struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t); + struct PosixSpawnFileActions(MaybeUninit); impl Drop for PosixSpawnFileActions { fn drop(&mut self) { unsafe { - libc::posix_spawn_file_actions_destroy(&mut self.0); + libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr()); } } } - struct PosixSpawnattr(libc::posix_spawnattr_t); + struct PosixSpawnattr(MaybeUninit); impl Drop for PosixSpawnattr { fn drop(&mut self) { unsafe { - libc::posix_spawnattr_destroy(&mut self.0); + libc::posix_spawnattr_destroy(self.0.as_mut_ptr()); } } } unsafe { - let mut file_actions = PosixSpawnFileActions(mem::uninitialized()); - let mut attrs = PosixSpawnattr(mem::uninitialized()); + let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit()); + let mut attrs = PosixSpawnattr(MaybeUninit::uninit()); - libc::posix_spawnattr_init(&mut attrs.0); - libc::posix_spawn_file_actions_init(&mut file_actions.0); + libc::posix_spawnattr_init(attrs.0.as_mut_ptr()); + libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr()); if let Some(fd) = stdio.stdin.fd() { - cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(), fd, libc::STDIN_FILENO))?; } if let Some(fd) = stdio.stdout.fd() { - cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(), fd, libc::STDOUT_FILENO))?; } if let Some(fd) = stdio.stderr.fd() { - cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(), fd, libc::STDERR_FILENO))?; } if let Some((f, cwd)) = addchdir { - cvt(f(&mut file_actions.0, cwd.as_ptr()))?; + cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?; } - let mut set: libc::sigset_t = mem::uninitialized(); - cvt(libc::sigemptyset(&mut set))?; - cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0, - &set))?; - cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?; - cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0, - &set))?; + let mut set = MaybeUninit::::uninit(); + cvt(libc::sigemptyset(set.as_mut_ptr()))?; + cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), + set.as_ptr()))?; + cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; + cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), + set.as_ptr()))?; let flags = libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK; - cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?; + cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource let _env_lock = sys::os::env_lock(); @@ -380,8 +378,8 @@ impl Command { let ret = libc::posix_spawnp( &mut p.pid, self.get_argv()[0], - &file_actions.0, - &attrs.0, + file_actions.0.as_ptr(), + attrs.0.as_ptr(), self.get_argv().as_ptr() as *const _, envp as *const _, ); diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 493ee8a9a2d7c..c77f30dfc7109 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -342,7 +342,7 @@ impl<'a> Drop for AsyncPipe<'a> { // If anything here fails, there's not really much we can do, so we leak // the buffer/OVERLAPPED pointers to ensure we're at least memory safe. if self.pipe.cancel_io().is_err() || self.result().is_err() { - let buf = mem::replace(self.dst, Vec::new()); + let buf = mem::take(self.dst); let overlapped = Box::new(unsafe { mem::zeroed() }); let overlapped = mem::replace(&mut self.overlapped, overlapped); mem::forget((buf, overlapped)); diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 436620ae7293b..453b6ebf3c49d 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -440,12 +440,12 @@ pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { }) } -pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> { +pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> { attrs.iter().find(|attr| attr.check_name(name)) } -pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol) - -> impl Iterator { +pub fn filter_by_name(attrs: &[Attribute], name: Symbol) + -> impl Iterator { attrs.iter().filter(move |attr| attr.check_name(name)) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5473f55aa3370..c71fa61443c43 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -13,8 +13,7 @@ use crate::parse::{DirectoryOwnership, PResult, ParseSess}; use crate::parse::token; use crate::parse::parser::Parser; use crate::ptr::P; -use crate::symbol::Symbol; -use crate::symbol::{kw, sym}; +use crate::symbol::{sym, Symbol}; use crate::tokenstream::{TokenStream, TokenTree}; use crate::visit::{self, Visitor}; use crate::util::map_in_place::MapInPlace; @@ -197,7 +196,6 @@ pub struct Invocation { pub enum InvocationKind { Bang { mac: ast::Mac, - ident: Option, span: Span, }, Attr { @@ -307,7 +305,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } else { self.resolve_imports(); if undetermined_invocations.is_empty() { break } - invocations = mem::replace(&mut undetermined_invocations, Vec::new()); + invocations = mem::take(&mut undetermined_invocations); force = !mem::replace(&mut progress, false); continue }; @@ -664,13 +662,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ext: &SyntaxExtension) -> Option { let kind = invoc.fragment_kind; - let (mac, ident, span) = match invoc.kind { - InvocationKind::Bang { mac, ident, span } => (mac, ident, span), + let (mac, span) = match invoc.kind { + InvocationKind::Bang { mac, span } => (mac, span), _ => unreachable!(), }; let path = &mac.node.path; - let ident = ident.unwrap_or_else(|| Ident::invalid()); let validate = |this: &mut Self| { // feature-gate the macro invocation if let Some((feature, issue)) = ext.unstable_feature { @@ -690,12 +687,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - if ident.name != kw::Invalid { - let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); - this.cx.span_err(path.span, &msg); - this.cx.trace_macros_diag(); - return Err(kind.dummy(span)); - } Ok(()) }; @@ -729,19 +720,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } SyntaxExtensionKind::Bang(expander) => { - if ident.name != kw::Invalid { - let msg = - format!("macro {}! expects no ident argument, given '{}'", path, ident); - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) - } else { - self.gate_proc_macro_expansion_kind(span, kind); - let tok_result = expander.expand(self.cx, span, mac.node.stream()); - let result = self.parse_ast_fragment(tok_result, kind, path, span); - self.gate_proc_macro_expansion(span, &result); - result - } + self.gate_proc_macro_expansion_kind(span, kind); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + let result = self.parse_ast_fragment(tok_result, kind, path, span); + self.gate_proc_macro_expansion(span, &result); + result } }; @@ -944,7 +927,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment { - self.collect(kind, InvocationKind::Bang { mac, ident: None, span }) + self.collect(kind, InvocationKind::Bang { mac, span }) } fn collect_attr(&mut self, @@ -1179,13 +1162,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ast::ItemKind::Mac(..) => { self.check_attributes(&item.attrs); item.and_then(|item| match item.node { - ItemKind::Mac(mac) => { - self.collect(AstFragmentKind::Items, InvocationKind::Bang { - mac, - ident: Some(item.ident), - span: item.span, - }).make_items() - } + ItemKind::Mac(mac) => self.collect( + AstFragmentKind::Items, InvocationKind::Bang { mac, span: item.span } + ).make_items(), _ => unreachable!(), }) } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 92ce3779a3c81..fc8aa4793bc61 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -901,7 +901,7 @@ fn may_begin_with(token: &Token, name: Name) -> bool { /// # Returns /// /// The parsed non-terminal. -fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> Nonterminal { +fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal { if name == sym::tt { return token::NtTT(p.parse_token_tree()); } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index ea7f8e356aa63..e04fd2ddc05bc 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -249,7 +249,7 @@ pub fn transcribe( quoted::TokenTree::Delimited(mut span, delimited) => { span = span.apply_mark(cx.current_expansion.mark); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); - result_stack.push(mem::replace(&mut result, Vec::new())); + result_stack.push(mem::take(&mut result)); } // Nothing much to do here. Just push the token to the result, being careful to diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a6e8441a915e0..4a0c957333bca 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -323,7 +323,7 @@ declare_features! ( (active, nll, "1.0.0", Some(43234), None), // Allows using slice patterns. - (active, slice_patterns, "1.0.0", Some(23121), None), + (active, slice_patterns, "1.0.0", Some(62254), None), // Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(57563), None), @@ -530,9 +530,6 @@ declare_features! ( // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. (active, lint_reasons, "1.31.0", Some(54503), None), - // Allows paths to enum variants on type aliases. - (active, type_alias_enum_variants, "1.31.0", Some(49683), None), - // Allows exhaustive integer pattern matching on `usize` and `isize`. (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), @@ -573,6 +570,9 @@ declare_features! ( // Allows explicit discriminants on non-unit enum variants. (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), + // Allows `impl Trait` with multiple unrelated lifetimes. + (active, member_constraints, "1.37.0", Some(61977), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -610,7 +610,7 @@ declare_features! ( (removed, allocator, "1.0.0", None, None, None), (removed, simd, "1.0.0", Some(27731), None, Some("removed in favor of `#[repr(simd)]`")), - (removed, advanced_slice_patterns, "1.0.0", Some(23121), None, + (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, Some("merged into `#![feature(slice_patterns)]`")), (removed, macro_reexport, "1.0.0", Some(29638), None, Some("subsumed by `pub use`")), @@ -853,6 +853,8 @@ declare_features! ( (accepted, extern_crate_self, "1.34.0", Some(56409), None), // Allows arbitrary delimited token streams in non-macro attributes. (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None), + // Allows paths to enum variants on type aliases including `Self`. + (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None), // Allows using `#[repr(align(X))]` on enums with equivalent semantics // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`. (accepted, repr_align_enum, "1.37.0", Some(57996), None), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 337b84247361d..7f16bb9dc1259 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -12,10 +12,12 @@ #![deny(unused_lifetimes)] #![feature(bind_by_move_pattern_guards)] +#![feature(box_syntax)] #![feature(const_fn)] #![feature(const_transmute)] #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(mem_take)] #![feature(nll)] #![feature(rustc_attrs)] #![feature(rustc_diagnostic_macros)] diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4e4fe4256c9b0..49f714e4e4654 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -83,28 +83,6 @@ impl<'a> StringReader<'a> { Ok(ret_val) } - /// Immutably extract string if found at current position with given delimiters - fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option { - let mut pos = self.pos; - let mut idx = self.src_index(pos); - let mut ch = char_at(&self.src, idx); - if ch != from_ch { - return None; - } - pos = pos + Pos::from_usize(ch.len_utf8()); - let start_pos = pos; - idx = self.src_index(pos); - while idx < self.end_src_index { - ch = char_at(&self.src, idx); - if ch == to_ch { - return Some(self.src[self.src_index(start_pos)..self.src_index(pos)].to_string()); - } - pos = pos + Pos::from_usize(ch.len_utf8()); - idx = self.src_index(pos); - } - return None; - } - fn try_real_token(&mut self) -> Result { let mut t = self.try_next_token()?; loop { diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 94ce6297fbefb..6a870685938a0 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -1,10 +1,11 @@ // Characters and their corresponding confusables were collected from // http://www.unicode.org/Public/security/10.0.0/confusables.txt -use syntax_pos::{Span, Pos, NO_EXPANSION}; -use errors::{Applicability, DiagnosticBuilder}; use super::StringReader; +use errors::{Applicability, DiagnosticBuilder}; +use syntax_pos::{Pos, Span, NO_EXPANSION}; +#[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('
', "Line Separator", ' '), ('
', "Paragraph Separator", ' '), @@ -293,8 +294,8 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('〉', "Right-Pointing Angle Bracket", '>'), ('〉', "Right Angle Bracket", '>'), ('》', "Right Double Angle Bracket", '>'), - ('>', "Fullwidth Greater-Than Sign", '>'), ]; - + ('>', "Fullwidth Greater-Than Sign", '>'), +]; const ASCII_ARRAY: &[(char, &str)] = &[ (' ', "Space"), @@ -321,46 +322,72 @@ const ASCII_ARRAY: &[(char, &str)] = &[ ('+', "Plus Sign"), ('<', "Less-Than Sign"), ('=', "Equals Sign"), - ('>', "Greater-Than Sign"), ]; - -crate fn check_for_substitution<'a>(reader: &StringReader<'a>, - ch: char, - err: &mut DiagnosticBuilder<'a>) -> bool { - UNICODE_ARRAY - .iter() - .find(|&&(c, _, _)| c == ch) - .map(|&(_, u_name, ascii_char)| { - let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); - match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { - Some(&(ascii_char, ascii_name)) => { - // special help suggestion for "directed" double quotes - if let Some(s) = reader.peek_delimited('“', '”') { - let msg = format!("Unicode characters '“' (Left Double Quotation Mark) and \ - '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", - ascii_char, ascii_name); - err.span_suggestion( - Span::new(reader.pos, reader.next_pos + Pos::from_usize(s.len()) + - Pos::from_usize('”'.len_utf8()), NO_EXPANSION), - &msg, - format!("\"{}\"", s), - Applicability::MaybeIncorrect); - } else { - let msg = - format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", - ch, u_name, ascii_char, ascii_name); - err.span_suggestion( - span, - &msg, - ascii_char.to_string(), - Applicability::MaybeIncorrect); - } - true - }, - None => { - let msg = format!("substitution character not found for '{}'", ch); - reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); - false - } + ('>', "Greater-Than Sign"), +]; + +crate fn check_for_substitution<'a>( + reader: &StringReader<'a>, + ch: char, + err: &mut DiagnosticBuilder<'a>, +) -> bool { + let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) { + Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char), + None => return false, + }; + + let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); + + let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { + Some((_ascii_char, ascii_name)) => ascii_name, + None => { + let msg = format!("substitution character not found for '{}'", ch); + reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + return false + }, + }; + + // special help suggestion for "directed" double quotes + if let Some(s) = reader.peek_delimited('“', '”') { + let msg = format!( + "Unicode characters '“' (Left Double Quotation Mark) and \ + '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", + ascii_char, ascii_name + ); + err.span_suggestion( + Span::new( + reader.pos, + reader.next_pos + Pos::from_usize(s.len()) + Pos::from_usize('”'.len_utf8()), + NO_EXPANSION, + ), + &msg, + format!("\"{}\"", s), + Applicability::MaybeIncorrect, + ); + } else { + let msg = format!( + "Unicode character '{}' ({}) looks like '{}' ({}), but it is not", + ch, u_name, ascii_char, ascii_name + ); + err.span_suggestion( + span, + &msg, + ascii_char.to_string(), + Applicability::MaybeIncorrect, + ); + } + true +} + +impl StringReader<'_> { + /// Immutably extract string if found at current position with given delimiters + fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<&str> { + let tail = &self.src[self.src_index(self.pos)..]; + let mut chars = tail.chars(); + let first_char = chars.next()?; + if first_char != from_ch { + return None; } - }).unwrap_or(false) + let last_char_idx = chars.as_str().find(to_ch)?; + Some(&chars.as_str()[..last_char_idx]) + } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fc206580e3811..9c1796000938f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4324,51 +4324,49 @@ impl<'a> Parser<'a> { fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span) -> PResult<'a, Option>> { let token_lo = self.token.span; - let (ident, def) = match self.token.kind { - token::Ident(name, false) if name == kw::Macro => { - self.bump(); - let ident = self.parse_ident()?; - let tokens = if self.check(&token::OpenDelim(token::Brace)) { - match self.parse_token_tree() { - TokenTree::Delimited(_, _, tts) => tts, - _ => unreachable!(), - } - } else if self.check(&token::OpenDelim(token::Paren)) { - let args = self.parse_token_tree(); - let body = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_token_tree() - } else { - self.unexpected()?; - unreachable!() - }; - TokenStream::new(vec![ - args.into(), - TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), - body.into(), - ]) + let (ident, def) = if self.eat_keyword(kw::Macro) { + let ident = self.parse_ident()?; + let tokens = if self.check(&token::OpenDelim(token::Brace)) { + match self.parse_token_tree() { + TokenTree::Delimited(_, _, tts) => tts, + _ => unreachable!(), + } + } else if self.check(&token::OpenDelim(token::Paren)) { + let args = self.parse_token_tree(); + let body = if self.check(&token::OpenDelim(token::Brace)) { + self.parse_token_tree() } else { self.unexpected()?; unreachable!() }; + TokenStream::new(vec![ + args.into(), + TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), + body.into(), + ]) + } else { + self.unexpected()?; + unreachable!() + }; - (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) - } - token::Ident(name, _) if name == sym::macro_rules && - self.look_ahead(1, |t| *t == token::Not) => { - let prev_span = self.prev_span; - self.complain_if_pub_macro(&vis.node, prev_span); - self.bump(); - self.bump(); - - let ident = self.parse_ident()?; - let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } + (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) + } else if self.check_keyword(sym::macro_rules) && + self.look_ahead(1, |t| *t == token::Not) && + self.look_ahead(2, |t| t.is_ident()) { + let prev_span = self.prev_span; + self.complain_if_pub_macro(&vis.node, prev_span); + self.bump(); + self.bump(); - (ident, ast::MacroDef { tokens, legacy: true }) + let ident = self.parse_ident()?; + let (delim, tokens) = self.expect_delimited_token_tree()?; + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } - _ => return Ok(None), + + (ident, ast::MacroDef { tokens, legacy: true }) + } else { + return Ok(None); }; let span = lo.to(self.prev_span); @@ -4412,14 +4410,14 @@ impl<'a> Parser<'a> { !self.is_existential_type_decl() && !self.is_auto_trait_item() && !self.is_async_fn() { - let pth = self.parse_path(PathStyle::Expr)?; + let path = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { let expr = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_struct_expr(lo, pth, ThinVec::new())? + self.parse_struct_expr(lo, path, ThinVec::new())? } else { let hi = self.prev_span; - self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new()) + self.mk_expr(lo.to(hi), ExprKind::Path(None, path), ThinVec::new()) }; let expr = self.with_res(Restrictions::STMT_EXPR, |this| { @@ -4434,34 +4432,6 @@ impl<'a> Parser<'a> { })); } - // it's a macro invocation - let id = match self.token.kind { - token::OpenDelim(_) => Ident::invalid(), // no special identifier - _ => self.parse_ident()?, - }; - - // check that we're pointing at delimiters (need to check - // again after the `if`, because of `parse_ident` - // consuming more tokens). - match self.token.kind { - token::OpenDelim(_) => {} - _ => { - // we only expect an ident if we didn't parse one - // above. - let ident_str = if id.name == kw::Invalid { - "identifier, " - } else { - "" - }; - let tok_str = self.this_token_descr(); - let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}", - ident_str, - tok_str)); - err.span_label(self.token.span, format!("expected {}`(` or `{{`", ident_str)); - return Err(err) - }, - } - let (delim, tts) = self.expect_delimited_token_tree()?; let hi = self.prev_span; @@ -4471,59 +4441,38 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - if id.name == kw::Invalid { - let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); - let node = if delim == MacDelimiter::Brace || - self.token == token::Semi || self.token == token::Eof { - StmtKind::Mac(P((mac, style, attrs.into()))) - } - // We used to incorrectly stop parsing macro-expanded statements here. - // If the next token will be an error anyway but could have parsed with the - // earlier behavior, stop parsing here and emit a warning to avoid breakage. - else if macro_legacy_warnings && - self.token.can_begin_expr() && - match self.token.kind { - // These can continue an expression, so we can't stop parsing and warn. - token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | - token::BinOp(token::Minus) | token::BinOp(token::Star) | - token::BinOp(token::And) | token::BinOp(token::Or) | - token::AndAnd | token::OrOr | - token::DotDot | token::DotDotDot | token::DotDotEq => false, - _ => true, - } { - self.warn_missing_semicolon(); - StmtKind::Mac(P((mac, style, attrs.into()))) - } else { - let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); - let e = self.maybe_recover_from_bad_qpath(e, true)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; - let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; - StmtKind::Expr(e) - }; - Stmt { - id: ast::DUMMY_NODE_ID, - span: lo.to(hi), - node, - } + let mac = respan(lo.to(hi), Mac_ { path, tts, delim }); + let node = if delim == MacDelimiter::Brace || + self.token == token::Semi || self.token == token::Eof { + StmtKind::Mac(P((mac, style, attrs.into()))) + } + // We used to incorrectly stop parsing macro-expanded statements here. + // If the next token will be an error anyway but could have parsed with the + // earlier behavior, stop parsing here and emit a warning to avoid breakage. + else if macro_legacy_warnings && + self.token.can_begin_expr() && + match self.token.kind { + // These can continue an expression, so we can't stop parsing and warn. + token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | + token::BinOp(token::Minus) | token::BinOp(token::Star) | + token::BinOp(token::And) | token::BinOp(token::Or) | + token::AndAnd | token::OrOr | + token::DotDot | token::DotDotDot | token::DotDotEq => false, + _ => true, + } { + self.warn_missing_semicolon(); + StmtKind::Mac(P((mac, style, attrs.into()))) } else { - // if it has a special ident, it's definitely an item - // - // Require a semicolon or braces. - if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } - let span = lo.to(hi); - Stmt { - id: ast::DUMMY_NODE_ID, - span, - node: StmtKind::Item({ - self.mk_item( - span, id /*id is good here*/, - ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })), - respan(lo, VisibilityKind::Inherited), - attrs) - }), - } + let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); + let e = self.maybe_recover_from_bad_qpath(e, true)?; + let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; + let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; + StmtKind::Expr(e) + }; + Stmt { + id: ast::DUMMY_NODE_ID, + span: lo.to(hi), + node, } } else { // FIXME: Bad copy of attrs @@ -5734,9 +5683,12 @@ impl<'a> Parser<'a> { { let is_const_fn = self.eat_keyword(kw::Const); let const_span = self.prev_span; - let unsafety = self.parse_unsafety(); let asyncness = self.parse_asyncness(); + if let IsAsync::Async { .. } = asyncness { + self.ban_async_in_2015(self.prev_span); + } let asyncness = respan(self.prev_span, asyncness); + let unsafety = self.parse_unsafety(); let (constness, unsafety, abi) = if is_const_fn { (respan(const_span, Constness::Const), unsafety, Abi::Rust) } else { @@ -7254,13 +7206,7 @@ impl<'a> Parser<'a> { item_, visibility, maybe_append(attrs, extra_attrs)); - if self.token.span.rust_2015() { - self.diagnostic().struct_span_err_with_code( - async_span, - "`async fn` is not permitted in the 2015 edition", - DiagnosticId::Error("E0670".into()) - ).emit(); - } + self.ban_async_in_2015(async_span); return Ok(Some(item)); } } @@ -7534,6 +7480,19 @@ impl<'a> Parser<'a> { self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility) } + /// We are parsing `async fn`. If we are on Rust 2015, emit an error. + fn ban_async_in_2015(&self, async_span: Span) { + if async_span.rust_2015() { + self.diagnostic() + .struct_span_err_with_code( + async_span, + "`async fn` is not permitted in the 2015 edition", + DiagnosticId::Error("E0670".into()) + ) + .emit(); + } + } + /// Parses a foreign item. crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> { maybe_whole!(self, NtForeignItem, |ni| ni); @@ -7609,26 +7568,17 @@ impl<'a> Parser<'a> { let mac_lo = self.token.span; // item macro. - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::Not)?; - - // a 'special' identifier (like what `macro_rules!` uses) - // is optional. We should eventually unify invoc syntax - // and remove this. - let id = if self.token.is_ident() { - self.parse_ident()? - } else { - Ident::invalid() // no special identifier - }; - // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; - let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim }); - let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs); + let mac = respan(mac_lo.to(hi), Mac_ { path, tts, delim }); + let item = + self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs); return Ok(Some(item)); } @@ -7654,9 +7604,9 @@ impl<'a> Parser<'a> { !(self.is_async_fn() && self.token.span.rust_2015()) { let prev_span = self.prev_span; let lo = self.token.span; - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; - if pth.segments.len() == 1 { + if path.segments.len() == 1 { if !self.eat(&token::Not) { return Err(self.missing_assoc_item_kind_err(item_kind, prev_span)); } @@ -7676,7 +7626,7 @@ impl<'a> Parser<'a> { self.expect(&token::Semi)?; } - Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim }))) + Ok(Some(respan(lo.to(self.prev_span), Mac_ { path, tts, delim }))) } else { Ok(None) } @@ -7689,7 +7639,7 @@ impl<'a> Parser<'a> { let mut tokens = Vec::new(); let prev_collecting = match self.token_cursor.frame.last_token { LastToken::Collecting(ref mut list) => { - Some(mem::replace(list, Vec::new())) + Some(mem::take(list)) } LastToken::Was(ref mut last) => { tokens.extend(last.take()); @@ -7707,7 +7657,7 @@ impl<'a> Parser<'a> { // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { - LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()), + LastToken::Collecting(ref mut v) => mem::take(v), LastToken::Was(_) => panic!("our vector went away?"), }; diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index f0cfa5a84a827..be580dc2e6a7e 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -41,11 +41,11 @@ pub struct P { ptr: Box } -#[allow(non_snake_case)] /// Construct a `P` from a `T` value. +#[allow(non_snake_case)] pub fn P(value: T) -> P { P { - ptr: Box::new(value) + ptr: box value } } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index f90b76721ee16..156fab8834ca4 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -120,8 +120,8 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { // We don't want to recurse into anything other than mods, since // mods or tests inside of functions will break things if let ast::ItemKind::Mod(mut module) = item.node { - let tests = mem::replace(&mut self.tests, Vec::new()); - let tested_submods = mem::replace(&mut self.tested_submods, Vec::new()); + let tests = mem::take(&mut self.tests); + let tested_submods = mem::take(&mut self.tested_submods); noop_visit_mod(&mut module, self); let tests = mem::replace(&mut self.tests, tests); let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 733c4f83e37d4..f850960624ce7 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -20,7 +20,7 @@ pub fn string_to_stream(source_str: String) -> TokenStream { } /// Map string to parser (via tts) -pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> { +pub fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> { new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str) } diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index 10d323ffb89f5..637614a18bcc3 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -131,7 +131,7 @@ fn parse_assert<'a>( Ok(Assert { cond_expr, custom_message }) } -fn parse_custom_message<'a>(parser: &mut Parser<'a>) -> Option { +fn parse_custom_message(parser: &mut Parser<'_>) -> Option { let ts = parser.parse_tokens(); if !ts.is_empty() { Some(ts) diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 444cf1263ce25..12482f7248e90 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -331,8 +331,8 @@ pub type CombineSubstructureFunc<'a> = pub type EnumNonMatchCollapsedFunc<'a> = Box, Span, (&[Ident], &[Ident]), &[P]) -> P + 'a>; -pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) - -> RefCell> { +pub fn combine_substructure(f: CombineSubstructureFunc<'_>) + -> RefCell> { RefCell::new(f) } diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 90d826429da4d..02b02e9b83695 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -39,10 +39,10 @@ pub enum PathKind { } impl<'a> Path<'a> { - pub fn new<'r>(path: Vec<&'r str>) -> Path<'r> { + pub fn new(path: Vec<&str>) -> Path<'_> { Path::new_(path, None, Vec::new(), PathKind::Std) } - pub fn new_local<'r>(path: &'r str) -> Path<'r> { + pub fn new_local(path: &str) -> Path<'_> { Path::new_(vec![path], None, Vec::new(), PathKind::Local) } pub fn new_<'r>(path: Vec<&'r str>, @@ -117,7 +117,7 @@ pub enum Const { pub fn borrowed_ptrty<'r>() -> PtrTy<'r> { Borrowed(None, ast::Mutability::Immutable) } -pub fn borrowed<'r>(ty: Box>) -> Ty<'r> { +pub fn borrowed(ty: Box>) -> Ty<'_> { Ptr(ty, borrowed_ptrty()) } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index bd9a9061b99ed..aee988d5148ae 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -389,6 +389,7 @@ symbols! { match_beginning_vert, match_default_bindings, may_dangle, + member_constraints, message, meta, min_const_fn, @@ -1132,6 +1133,7 @@ impl LocalInternedString { } } + #[inline] pub fn get(&self) -> &str { // This returns a valid string since we ensure that `self` outlives the interner // by creating the interner on a thread which outlives threads which can access it. @@ -1145,6 +1147,7 @@ impl std::convert::AsRef for LocalInternedString where str: std::convert::AsRef { + #[inline] fn as_ref(&self) -> &U { self.string.as_ref() } @@ -1185,6 +1188,7 @@ impl !Sync for LocalInternedString {} impl std::ops::Deref for LocalInternedString { type Target = str; + #[inline] fn deref(&self) -> &str { self.string } } diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 20280aa3c4130..e92c68f5b0c57 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -4,11 +4,13 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); - if cfg!(feature = "llvm-libunwind") && + // FIXME: the not(bootstrap) part is needed because of the issue addressed by #62286, + // and could be removed once that change is in beta. + if cfg!(all(not(bootstrap), feature = "llvm-libunwind")) && (target.contains("linux") || target.contains("fuchsia")) { // Build the unwinding from libunwind C/C++ source code. - #[cfg(feature = "llvm-libunwind")] + #[cfg(all(not(bootstrap), feature = "llvm-libunwind"))] llvm_libunwind::compile(); } else if target.contains("linux") { if target.contains("musl") { @@ -42,7 +44,7 @@ fn main() { } } -#[cfg(feature = "llvm-libunwind")] +#[cfg(all(not(bootstrap), feature = "llvm-libunwind"))] mod llvm_libunwind { use std::env; use std::path::Path; diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 5794e0b7683cb..7e640897af705 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -67,6 +67,8 @@ pub enum _Unwind_Context {} pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code, exception: *mut _Unwind_Exception); +#[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + link(name = "unwind", kind = "static"))] extern "C" { #[unwind(allowed)] pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !; @@ -91,6 +93,8 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm } pub use _Unwind_Action::*; + #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + link(name = "unwind", kind = "static"))] extern "C" { pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word; pub fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word); @@ -144,6 +148,8 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm pub const UNWIND_POINTER_REG: c_int = 12; pub const UNWIND_IP_REG: c_int = 15; + #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + link(name = "unwind", kind = "static"))] extern "C" { fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context, regclass: _Unwind_VRS_RegClass, @@ -206,6 +212,8 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm cfg_if::cfg_if! { if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { // Not 32-bit iOS + #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + link(name = "unwind", kind = "static"))] extern "C" { #[unwind(allowed)] pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code; @@ -215,6 +223,8 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { } } else { // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace() + #[cfg_attr(all(not(bootstrap), feature = "llvm-libunwind"), + link(name = "unwind", kind = "static"))] extern "C" { #[unwind(allowed)] pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; diff --git a/src/test/codegen/pgo-instrumentation.rs b/src/test/codegen/pgo-instrumentation.rs index e94365058862a..8200cf4e0167b 100644 --- a/src/test/codegen/pgo-instrumentation.rs +++ b/src/test/codegen/pgo-instrumentation.rs @@ -1,8 +1,8 @@ -// Test that `-Zpgo-gen` creates expected instrumentation artifacts in LLVM IR. +// Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR. // Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms. // needs-profiler-support -// compile-flags: -Z pgo-gen -Ccodegen-units=1 -Cpanic=abort +// compile-flags: -Cprofile-generate -Ccodegen-units=1 -Cpanic=abort // CHECK: @__llvm_profile_raw_version = // CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global diff --git a/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs b/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs index 13daa72a4d1f4..34f30548c5a81 100644 --- a/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs +++ b/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs @@ -5,7 +5,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph // aux-build:point.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/src/test/incremental/change_add_field/struct_point.rs b/src/test/incremental/change_add_field/struct_point.rs index 9e34aedbed307..662aa53533134 100644 --- a/src/test/incremental/change_add_field/struct_point.rs +++ b/src/test/incremental/change_add_field/struct_point.rs @@ -5,7 +5,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/src/test/incremental/change_crate_dep_kind.rs b/src/test/incremental/change_crate_dep_kind.rs index 04a41d71cc945..f5d1acb621be3 100644 --- a/src/test/incremental/change_crate_dep_kind.rs +++ b/src/test/incremental/change_crate_dep_kind.rs @@ -3,7 +3,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -Cpanic=unwind -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(panic_unwind)] diff --git a/src/test/incremental/change_private_fn/struct_point.rs b/src/test/incremental/change_private_fn/struct_point.rs index be287b86bbcba..722e62ef11ded 100644 --- a/src/test/incremental/change_private_fn/struct_point.rs +++ b/src/test/incremental/change_private_fn/struct_point.rs @@ -3,7 +3,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/src/test/incremental/change_private_fn_cc/struct_point.rs b/src/test/incremental/change_private_fn_cc/struct_point.rs index 521fe99ebc2eb..384441d6d0c71 100644 --- a/src/test/incremental/change_private_fn_cc/struct_point.rs +++ b/src/test/incremental/change_private_fn_cc/struct_point.rs @@ -4,7 +4,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph // aux-build:point.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/src/test/incremental/change_private_impl_method/struct_point.rs b/src/test/incremental/change_private_impl_method/struct_point.rs index c2796b5e3c90a..ec5899f3119d8 100644 --- a/src/test/incremental/change_private_impl_method/struct_point.rs +++ b/src/test/incremental/change_private_impl_method/struct_point.rs @@ -3,7 +3,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/src/test/incremental/change_private_impl_method_cc/struct_point.rs b/src/test/incremental/change_private_impl_method_cc/struct_point.rs index 731dcdf78c933..f0e78f8d0a483 100644 --- a/src/test/incremental/change_private_impl_method_cc/struct_point.rs +++ b/src/test/incremental/change_private_impl_method_cc/struct_point.rs @@ -4,7 +4,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph // aux-build:point.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs index 76dcff848caf7..641d20ed6cc8a 100644 --- a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs @@ -2,7 +2,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs b/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs index 9c95d4cc2a9a5..9b8f9517bf149 100644 --- a/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs @@ -2,7 +2,7 @@ // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs index 55dd37451235a..d859cbef39f09 100644 --- a/src/test/incremental/hashes/call_expressions.rs +++ b/src/test/incremental/hashes/call_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index 5165f9821fd88..24ab6b8e18455 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/consts.rs b/src/test/incremental/hashes/consts.rs index 516276a49ea8f..8e713a1d99237 100644 --- a/src/test/incremental/hashes/consts.rs +++ b/src/test/incremental/hashes/consts.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/enum_constructors.rs b/src/test/incremental/hashes/enum_constructors.rs index f553b2d1b5123..575b2e92966ea 100644 --- a/src/test/incremental/hashes/enum_constructors.rs +++ b/src/test/incremental/hashes/enum_constructors.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs index aa2dc798b81c8..7256c1aa15326 100644 --- a/src/test/incremental/hashes/enum_defs.rs +++ b/src/test/incremental/hashes/enum_defs.rs @@ -10,7 +10,7 @@ // results in a change of the ICH for the enum's metadata, and that it stays // the same between rev2 and rev3. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/exported_vs_not.rs b/src/test/incremental/hashes/exported_vs_not.rs index 5a29afa17d3c2..ef275cabeaff9 100644 --- a/src/test/incremental/hashes/exported_vs_not.rs +++ b/src/test/incremental/hashes/exported_vs_not.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/extern_mods.rs b/src/test/incremental/hashes/extern_mods.rs index e6423ebad128c..0b9a0fd79451a 100644 --- a/src/test/incremental/hashes/extern_mods.rs +++ b/src/test/incremental/hashes/extern_mods.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs index 503cb8732ef70..ca45d36a6b0e4 100644 --- a/src/test/incremental/hashes/for_loops.rs +++ b/src/test/incremental/hashes/for_loops.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index 7850291fc565a..84680a52ff3ce 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs index 6bc7d286e3adb..b84c393573b91 100644 --- a/src/test/incremental/hashes/if_expressions.rs +++ b/src/test/incremental/hashes/if_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/indexing_expressions.rs b/src/test/incremental/hashes/indexing_expressions.rs index eb0c33f7766b4..4d39ed68701dd 100644 --- a/src/test/incremental/hashes/indexing_expressions.rs +++ b/src/test/incremental/hashes/indexing_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 268c37508a73c..882383e841957 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs index 53e77a370a334..deb1c45a52885 100644 --- a/src/test/incremental/hashes/inline_asm.rs +++ b/src/test/incremental/hashes/inline_asm.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index e016b92a9ebdf..68545b7daaa5c 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs index c04bdd43a9528..6222d948c98e9 100644 --- a/src/test/incremental/hashes/loop_expressions.rs +++ b/src/test/incremental/hashes/loop_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/match_expressions.rs b/src/test/incremental/hashes/match_expressions.rs index 02f2cd6634daf..840b2222d90a1 100644 --- a/src/test/incremental/hashes/match_expressions.rs +++ b/src/test/incremental/hashes/match_expressions.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs index 0803f4e01d63b..b370fcce8efda 100644 --- a/src/test/incremental/hashes/panic_exprs.rs +++ b/src/test/incremental/hashes/panic_exprs.rs @@ -8,7 +8,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -C debug-assertions diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs index 3bee2aca5b6c2..6f74e0fdbc06e 100644 --- a/src/test/incremental/hashes/statics.rs +++ b/src/test/incremental/hashes/statics.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs index e478ff96c3276..b708b99eabc99 100644 --- a/src/test/incremental/hashes/struct_constructors.rs +++ b/src/test/incremental/hashes/struct_constructors.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/struct_defs.rs b/src/test/incremental/hashes/struct_defs.rs index 8d32e33054ccc..e0c5696483158 100644 --- a/src/test/incremental/hashes/struct_defs.rs +++ b/src/test/incremental/hashes/struct_defs.rs @@ -10,7 +10,7 @@ // results in a change of the ICH for the struct's metadata, and that it stays // the same between rev2 and rev3. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index da57b485beb8a..30b4e306820ed 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -10,7 +10,7 @@ // results in a change of the ICH for the trait's metadata, and that it stays // the same between rev2 and rev3. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/trait_impls.rs b/src/test/incremental/hashes/trait_impls.rs index 1487129d09ea6..fa28b2ebedd13 100644 --- a/src/test/incremental/hashes/trait_impls.rs +++ b/src/test/incremental/hashes/trait_impls.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/type_defs.rs b/src/test/incremental/hashes/type_defs.rs index 4ffa0d9bb7ba7..264e8f926ffe5 100644 --- a/src/test/incremental/hashes/type_defs.rs +++ b/src/test/incremental/hashes/type_defs.rs @@ -10,7 +10,7 @@ // results in a change of the ICH for the enum's metadata, and that it stays // the same between rev2 and rev3. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs index 8c53ae6a03854..776a0273ca7b6 100644 --- a/src/test/incremental/hashes/unary_and_binary_exprs.rs +++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs index 2d48707561c29..af2066b90f1d8 100644 --- a/src/test/incremental/hashes/while_let_loops.rs +++ b/src/test/incremental/hashes/while_let_loops.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs index 79a3bc9b20504..d8ec76d76aa31 100644 --- a/src/test/incremental/hashes/while_loops.rs +++ b/src/test/incremental/hashes/while_loops.rs @@ -5,7 +5,7 @@ // and make sure that the hash has changed, then change nothing between rev2 and // rev3 and make sure that the hash has not changed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans diff --git a/src/test/incremental/ich_nested_items.rs b/src/test/incremental/ich_nested_items.rs index 3c2ce765c4805..b2b7e663151e2 100644 --- a/src/test/incremental/ich_nested_items.rs +++ b/src/test/incremental/ich_nested_items.rs @@ -2,7 +2,7 @@ // the nested items (or even added new ones). // revisions: cfail1 cfail2 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/src/test/incremental/incremental_proc_macro.rs b/src/test/incremental/incremental_proc_macro.rs index b0e9b1f9180f6..becc1538fb225 100644 --- a/src/test/incremental/incremental_proc_macro.rs +++ b/src/test/incremental/incremental_proc_macro.rs @@ -1,6 +1,6 @@ // aux-build:incremental_proc_macro_aux.rs // revisions: cfail1 cfail2 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test makes sure that we still find the proc-macro registrar function // when we compile proc-macros incrementally (see #47292). diff --git a/src/test/incremental/issue-42602.rs b/src/test/incremental/issue-42602.rs index 17e1b82187881..b8d5303fb4734 100644 --- a/src/test/incremental/issue-42602.rs +++ b/src/test/incremental/issue-42602.rs @@ -8,7 +8,7 @@ // revisions:cfail1 cfail2 cfail3 // compile-flags:-Zquery-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/incremental/issue-49595/issue-49595.rs b/src/test/incremental/issue-49595/issue-49595.rs index ada93f79b261d..ab4d76eef364c 100644 --- a/src/test/incremental/issue-49595/issue-49595.rs +++ b/src/test/incremental/issue-49595/issue-49595.rs @@ -1,6 +1,6 @@ // revisions:cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph --test -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs index afc086213403c..709e9be663efa 100644 --- a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs +++ b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs @@ -3,7 +3,7 @@ // subsequent runs) if incremental compilation is enabled. // revisions: cfail1 cfail2 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(on_unimplemented)] #![deny(unused_attributes)] diff --git a/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs b/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs index 37bd8d0641fb9..bfb5e539cc18c 100644 --- a/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs +++ b/src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs @@ -4,7 +4,7 @@ // enabled. // revisions: cfail1 cfail2 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![deny(unused_attributes)] diff --git a/src/test/incremental/krate-inherent.rs b/src/test/incremental/krate-inherent.rs index 3e8d8fb1f94f1..6e791eacdf37a 100644 --- a/src/test/incremental/krate-inherent.rs +++ b/src/test/incremental/krate-inherent.rs @@ -1,6 +1,6 @@ // revisions: cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/src/test/incremental/macro_export.rs b/src/test/incremental/macro_export.rs index d1966646867a9..044d63fd2a9f1 100644 --- a/src/test/incremental/macro_export.rs +++ b/src/test/incremental/macro_export.rs @@ -1,5 +1,5 @@ // revisions: cfail1 cfail2 cfail3 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test case makes sure that we can compile with incremental compilation // enabled when there are macros exported from this crate. (See #37756) diff --git a/src/test/incremental/remove_source_file/main.rs b/src/test/incremental/remove_source_file/main.rs index 3af9c0518924a..b2411c0946fd4 100644 --- a/src/test/incremental/remove_source_file/main.rs +++ b/src/test/incremental/remove_source_file/main.rs @@ -6,7 +6,7 @@ // Note that we specify -g so that the SourceFiles actually get referenced by the // incr. comp. cache: // compile-flags: -Z query-dep-graph -g -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type= "rlib"] diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs index c39d4145b586f..b88acd2af75ab 100644 --- a/src/test/incremental/string_constant.rs +++ b/src/test/incremental/string_constant.rs @@ -1,6 +1,6 @@ // revisions: cfail1 cfail2 // compile-flags: -Z query-dep-graph -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/src/test/incremental/thinlto/cgu_invalidated_via_import.rs b/src/test/incremental/thinlto/cgu_invalidated_via_import.rs index 09c429f0ad8b6..8160f8f3a99f9 100644 --- a/src/test/incremental/thinlto/cgu_invalidated_via_import.rs +++ b/src/test/incremental/thinlto/cgu_invalidated_via_import.rs @@ -4,7 +4,7 @@ // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -O -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![crate_type="rlib"] diff --git a/src/test/incremental/thinlto/independent_cgus_dont_affect_each_other.rs b/src/test/incremental/thinlto/independent_cgus_dont_affect_each_other.rs index da6aa79b9d35d..24e5d2438bd0a 100644 --- a/src/test/incremental/thinlto/independent_cgus_dont_affect_each_other.rs +++ b/src/test/incremental/thinlto/independent_cgus_dont_affect_each_other.rs @@ -3,7 +3,7 @@ // revisions: cfail1 cfail2 cfail3 // compile-flags: -Z query-dep-graph -O -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![crate_type="rlib"] diff --git a/src/test/incremental/warnings-reemitted.rs b/src/test/incremental/warnings-reemitted.rs index f2acaa0121bb2..a1d11f8aa5bbe 100644 --- a/src/test/incremental/warnings-reemitted.rs +++ b/src/test/incremental/warnings-reemitted.rs @@ -1,6 +1,6 @@ // revisions: cfail1 cfail2 cfail3 // compile-flags: -Coverflow-checks=on -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![warn(const_err)] diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile index 59a7d61892ffb..f8efeca56141b 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile @@ -21,7 +21,7 @@ all: cpp-executable rust-executable cpp-executable: $(RUSTC) -Clinker-plugin-lto=on \ - -Zpgo-gen="$(TMPDIR)"/cpp-profdata \ + -Cprofile-generate="$(TMPDIR)"/cpp-profdata \ -o "$(TMPDIR)"/librustlib-xlto.a \ $(COMMON_FLAGS) \ ./rustlib.rs @@ -39,7 +39,7 @@ cpp-executable: -o "$(TMPDIR)"/cpp-profdata/merged.profdata \ "$(TMPDIR)"/cpp-profdata/default_*.profraw $(RUSTC) -Clinker-plugin-lto=on \ - -Zpgo-use="$(TMPDIR)"/cpp-profdata/merged.profdata \ + -Cprofile-use="$(TMPDIR)"/cpp-profdata/merged.profdata \ -o "$(TMPDIR)"/librustlib-xlto.a \ $(COMMON_FLAGS) \ ./rustlib.rs @@ -57,7 +57,7 @@ rust-executable: $(CLANG) ./clib.c -fprofile-generate="$(TMPDIR)"/rs-profdata -flto=thin -c -o $(TMPDIR)/clib.o -O3 (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) $(RUSTC) -Clinker-plugin-lto=on \ - -Zpgo-gen="$(TMPDIR)"/rs-profdata \ + -Cprofile-generate="$(TMPDIR)"/rs-profdata \ -L$(TMPDIR) \ $(COMMON_FLAGS) \ -Clinker=$(CLANG) \ @@ -78,7 +78,7 @@ rust-executable: rm "$(TMPDIR)"/libxyz.a (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) $(RUSTC) -Clinker-plugin-lto=on \ - -Zpgo-use="$(TMPDIR)"/rs-profdata/merged.profdata \ + -Cprofile-use="$(TMPDIR)"/rs-profdata/merged.profdata \ -L$(TMPDIR) \ $(COMMON_FLAGS) \ -Clinker=$(CLANG) \ diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile index 56f31434adee4..6c70d951c35ea 100644 --- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile @@ -2,7 +2,7 @@ -include ../tools.mk -COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)" +COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)" # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: # https://github.com/rust-lang/rust/issues/61002 diff --git a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile index bb86160d2dfdf..3fbfeb09eb373 100644 --- a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile @@ -2,7 +2,7 @@ -include ../tools.mk -COMPILE_FLAGS=-O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)" +COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)" # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: # https://github.com/rust-lang/rust/issues/61002 diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile index f0ab3b7d13d27..3b66427c14c29 100644 --- a/src/test/run-make-fulldeps/pgo-gen/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen/Makefile @@ -2,7 +2,7 @@ -include ../tools.mk -COMPILE_FLAGS=-g -Z pgo-gen="$(TMPDIR)" +COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)" # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: # https://github.com/rust-lang/rust/issues/61002 diff --git a/src/test/run-make-fulldeps/pgo-use/Makefile b/src/test/run-make-fulldeps/pgo-use/Makefile index 72c3c34ee3741..61a73587759fe 100644 --- a/src/test/run-make-fulldeps/pgo-use/Makefile +++ b/src/test/run-make-fulldeps/pgo-use/Makefile @@ -33,7 +33,7 @@ endif all: # Compile the test program with instrumentation - $(RUSTC) $(COMMON_FLAGS) -Z pgo-gen="$(TMPDIR)" main.rs + $(RUSTC) $(COMMON_FLAGS) -Cprofile-generate="$(TMPDIR)" main.rs # Run it in order to generate some profiling data $(call RUN,main some-argument) || exit 1 # Postprocess the profiling data so it can be used by the compiler @@ -41,7 +41,7 @@ all: -o "$(TMPDIR)"/merged.profdata \ "$(TMPDIR)"/default_*.profraw # Compile the test program again, making use of the profiling data - $(RUSTC) $(COMMON_FLAGS) -Z pgo-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs + $(RUSTC) $(COMMON_FLAGS) -Cprofile-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs # Check that the generate IR contains some things that we expect # # We feed the file into LLVM FileCheck tool *in reverse* so that we see the diff --git a/src/test/run-pass/async-await/async-fn-size-moved-locals.rs b/src/test/run-pass/async-await/async-fn-size-moved-locals.rs new file mode 100644 index 0000000000000..139be7fe0132b --- /dev/null +++ b/src/test/run-pass/async-await/async-fn-size-moved-locals.rs @@ -0,0 +1,98 @@ +// Test that we don't duplicate storage for futures moved around in .await, and +// for futures moved into other futures. +// +// The exact sizes can change by a few bytes (we'd like to know when they do). +// What we don't want to see is the wrong multiple of 1024 (the size of BigFut) +// being reflected in the size. +// +// See issue #59123 for a full explanation. + +// edition:2018 + +#![feature(async_await)] + +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +const BIG_FUT_SIZE: usize = 1024; +struct BigFut([u8; BIG_FUT_SIZE]); + +impl BigFut { + fn new() -> Self { + BigFut([0; BIG_FUT_SIZE]) + } } + +impl Drop for BigFut { + fn drop(&mut self) {} +} + +impl Future for BigFut { + type Output = (); + + fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll { + Poll::Ready(()) + } +} + +#[allow(dead_code)] +struct Joiner { + a: Option, + b: Option, + c: Option, +} + +impl Future for Joiner { + type Output = (); + + fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll { + Poll::Ready(()) + } +} + +fn noop() {} + +async fn single() { + let x = BigFut::new(); + x.await; +} + +async fn single_with_noop() { + let x = BigFut::new(); + noop(); + x.await; +} + +async fn joined() { + let a = BigFut::new(); + let b = BigFut::new(); + let c = BigFut::new(); + + let joiner = Joiner { + a: Some(a), + b: Some(b), + c: Some(c), + }; + joiner.await +} + +async fn joined_with_noop() { + let a = BigFut::new(); + let b = BigFut::new(); + let c = BigFut::new(); + + let joiner = Joiner { + a: Some(a), + b: Some(b), + c: Some(c), + }; + noop(); + joiner.await +} + +fn main() { + assert_eq!(1028, std::mem::size_of_val(&single())); + assert_eq!(1032, std::mem::size_of_val(&single_with_noop())); + assert_eq!(3084, std::mem::size_of_val(&joined())); + assert_eq!(3084, std::mem::size_of_val(&joined_with_noop())); +} diff --git a/src/test/run-pass/async-fn-size.rs b/src/test/run-pass/async-await/async-fn-size.rs similarity index 98% rename from src/test/run-pass/async-fn-size.rs rename to src/test/run-pass/async-await/async-fn-size.rs index 05afd6d401977..c4e328560ddf7 100644 --- a/src/test/run-pass/async-fn-size.rs +++ b/src/test/run-pass/async-await/async-fn-size.rs @@ -1,9 +1,9 @@ // edition:2018 -// aux-build:arc_wake.rs #![feature(async_await, await_macro)] -extern crate arc_wake; +#[path = "../auxiliary/arc_wake.rs"] +mod arc_wake; use std::pin::Pin; use std::future::Future; diff --git a/src/test/run-pass/async-await/issue-60709.rs b/src/test/run-pass/async-await/issue-60709.rs new file mode 100644 index 0000000000000..778d3ee0c7083 --- /dev/null +++ b/src/test/run-pass/async-await/issue-60709.rs @@ -0,0 +1,28 @@ +// This used to compile the future down to ud2, due to uninhabited types being +// handled incorrectly in generators. +// compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018 + +#![feature(async_await, await_macro)] +#![allow(unused)] + +use std::future::Future; +use std::task::Poll; +use std::task::Context; +use std::pin::Pin; +use std::rc::Rc; + +struct Never(); +impl Future for Never { + type Output = (); + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + Poll::Pending + } +} + +fn main() { + let fut = async { + let _rc = Rc::new(()); // Also crashes with Arc + await!(Never()); + }; + let _bla = fut; // Moving the future is required. +} diff --git a/src/test/run-pass/command-uid-gid.rs b/src/test/run-pass/command-uid-gid.rs new file mode 100644 index 0000000000000..2b52c5d104c24 --- /dev/null +++ b/src/test/run-pass/command-uid-gid.rs @@ -0,0 +1,26 @@ +#![feature(rustc_private)] + +fn main() { + #[cfg(unix)] + run() +} + +#[cfg(unix)] +fn run() { + extern crate libc; + use std::process::Command; + use std::os::unix::prelude::*; + + let mut p = Command::new("/bin/sh") + .arg("-c").arg("true") + .uid(unsafe { libc::getuid() }) + .gid(unsafe { libc::getgid() }) + .spawn().unwrap(); + assert!(p.wait().unwrap().success()); + + // if we're already root, this isn't a valid test. Most of the bots run + // as non-root though (android is an exception). + if unsafe { libc::getuid() != 0 } { + assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err()); + } +} diff --git a/src/test/run-pass/generator/size-moved-locals.rs b/src/test/run-pass/generator/size-moved-locals.rs new file mode 100644 index 0000000000000..37e2e0cfdcccf --- /dev/null +++ b/src/test/run-pass/generator/size-moved-locals.rs @@ -0,0 +1,62 @@ +// Test that we don't duplicate storage for a variable that is moved to another +// binding. This used to happen in the presence of unwind and drop edges (see +// `complex` below.) +// +// The exact sizes here can change (we'd like to know when they do). What we +// don't want to see is the `complex` generator size being upwards of 2048 bytes +// (which would indicate it is reserving space for two copies of Foo.) +// +// See issue #59123 for a full explanation. + +// edition:2018 + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +const FOO_SIZE: usize = 1024; +struct Foo([u8; FOO_SIZE]); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn move_before_yield() -> impl Generator { + static || { + let first = Foo([0; FOO_SIZE]); + let _second = first; + yield; + // _second dropped here + } +} + +fn noop() {} + +fn move_before_yield_with_noop() -> impl Generator { + static || { + let first = Foo([0; FOO_SIZE]); + noop(); + let _second = first; + yield; + // _second dropped here + } +} + +// Today we don't have NRVO (we allocate space for both `first` and `second`,) +// but we can overlap `first` with `_third`. +fn overlap_move_points() -> impl Generator { + static || { + let first = Foo([0; FOO_SIZE]); + yield; + let second = first; + yield; + let _third = second; + yield; + } +} + +fn main() { + assert_eq!(1028, std::mem::size_of_val(&move_before_yield())); + assert_eq!(1032, std::mem::size_of_val(&move_before_yield_with_noop())); + assert_eq!(2056, std::mem::size_of_val(&overlap_move_points())); +} diff --git a/src/test/run-pass/issues/issue-30530.rs b/src/test/run-pass/issues/issue-30530.rs index e837fc81721a8..111fb8aa506a4 100644 --- a/src/test/run-pass/issues/issue-30530.rs +++ b/src/test/run-pass/issues/issue-30530.rs @@ -12,7 +12,9 @@ pub enum Handler { } fn main() { - take(Handler::Default, Box::new(main)); + #[allow(unused_must_use)] { + take(Handler::Default, Box::new(main)); + } } #[inline(never)] diff --git a/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs b/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs new file mode 100644 index 0000000000000..6028b8f5ab491 --- /dev/null +++ b/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs @@ -0,0 +1,21 @@ +// If a struct is packed and its last field has drop glue, then that +// field needs to be Sized (to allow it to be destroyed out-of-place). +// +// This is checked by the compiler during wfcheck. That check used +// to have problems with associated types in the last field - test +// that this doesn't ICE. + +#![allow(unused_imports, dead_code)] + +pub struct S; + +pub trait Trait { type Assoc; } + +impl Trait for S { type Assoc = X; } + +#[repr(C, packed)] +struct PackedAssocSized { + pos: Box<>::Assoc>, +} + +fn main() { println!("Hello, world!"); } diff --git a/src/test/run-pass/panics/panic-handler-flail-wildly.rs b/src/test/run-pass/panics/panic-handler-flail-wildly.rs index ebe4f70378cf0..6badd203842ff 100644 --- a/src/test/run-pass/panics/panic-handler-flail-wildly.rs +++ b/src/test/run-pass/panics/panic-handler-flail-wildly.rs @@ -1,5 +1,7 @@ // run-pass + #![allow(stable_features)] +#![allow(unused_must_use)] // ignore-emscripten no threads support diff --git a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs index 51a3b46d4619b..0ab7e17f87b5a 100644 --- a/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs +++ b/src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs @@ -1,7 +1,7 @@ // run-pass #![feature(decl_macro)] -r#macro_rules! r#struct { +macro_rules! r#struct { ($r#struct:expr) => { $r#struct } } diff --git a/src/test/run-pass/type-alias-enum-variants-2.rs b/src/test/run-pass/type-alias-enum-variants-2.rs deleted file mode 100644 index 0cf413babcbf6..0000000000000 --- a/src/test/run-pass/type-alias-enum-variants-2.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![feature(type_alias_enum_variants)] - -#[derive(Debug, PartialEq, Eq)] -enum Foo { - Bar(i32), - Baz { i: i32 }, -} - -type FooAlias = Foo; -type OptionAlias = Option; - -impl Foo { - fn foo() -> Self { - Self::Bar(3) - } -} - -fn main() { - let t = FooAlias::Bar(1); - assert_eq!(t, Foo::Bar(1)); - let t = FooAlias::Baz { i: 2 }; - assert_eq!(t, Foo::Baz { i: 2 }); - match t { - FooAlias::Bar(_i) => {} - FooAlias::Baz { i } => { assert_eq!(i, 2); } - } - assert_eq!(Foo::foo(), Foo::Bar(3)); - - assert_eq!(OptionAlias::Some(4), Option::Some(4)); -} diff --git a/src/test/run-pass/type-alias-enum-variants.rs b/src/test/run-pass/type-alias-enum-variants.rs deleted file mode 100644 index 0cf413babcbf6..0000000000000 --- a/src/test/run-pass/type-alias-enum-variants.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![feature(type_alias_enum_variants)] - -#[derive(Debug, PartialEq, Eq)] -enum Foo { - Bar(i32), - Baz { i: i32 }, -} - -type FooAlias = Foo; -type OptionAlias = Option; - -impl Foo { - fn foo() -> Self { - Self::Bar(3) - } -} - -fn main() { - let t = FooAlias::Bar(1); - assert_eq!(t, Foo::Bar(1)); - let t = FooAlias::Baz { i: 2 }; - assert_eq!(t, Foo::Baz { i: 2 }); - match t { - FooAlias::Bar(_i) => {} - FooAlias::Baz { i } => { assert_eq!(i, 2); } - } - assert_eq!(Foo::foo(), Foo::Bar(3)); - - assert_eq!(OptionAlias::Some(4), Option::Some(4)); -} diff --git a/src/test/rustdoc-ui/cfg-test.rs b/src/test/rustdoc-ui/cfg-test.rs index e26034371f444..4dcf512d286ff 100644 --- a/src/test/rustdoc-ui/cfg-test.rs +++ b/src/test/rustdoc-ui/cfg-test.rs @@ -1,13 +1,16 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--test // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// Crates like core have doctests gated on `cfg(not(test))` so we need to make +// sure `cfg(test)` is not active when running `rustdoc --test`. + /// this doctest will be ignored: /// /// ``` /// assert!(false); /// ``` -#[cfg(not(test))] +#[cfg(test)] pub struct Foo; /// this doctest will be tested: @@ -15,5 +18,5 @@ pub struct Foo; /// ``` /// assert!(true); /// ``` -#[cfg(test)] +#[cfg(not(test))] pub struct Foo; diff --git a/src/test/rustdoc-ui/cfg-test.stdout b/src/test/rustdoc-ui/cfg-test.stdout index 30bb0038d1b8d..67873870e89b2 100644 --- a/src/test/rustdoc-ui/cfg-test.stdout +++ b/src/test/rustdoc-ui/cfg-test.stdout @@ -1,6 +1,6 @@ running 1 test -test $DIR/cfg-test.rs - Foo (line 15) ... ok +test $DIR/cfg-test.rs - Foo (line 18) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out diff --git a/src/test/rustdoc-ui/coverage/basic.rs b/src/test/rustdoc-ui/coverage/basic.rs index 4247fdf989556..d25ac633d7bf2 100644 --- a/src/test/rustdoc-ui/coverage/basic.rs +++ b/src/test/rustdoc-ui/coverage/basic.rs @@ -1,5 +1,5 @@ // compile-flags:-Z unstable-options --show-coverage -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_types)] diff --git a/src/test/rustdoc-ui/coverage/empty.rs b/src/test/rustdoc-ui/coverage/empty.rs index 463617a1143df..27bcf6f39383a 100644 --- a/src/test/rustdoc-ui/coverage/empty.rs +++ b/src/test/rustdoc-ui/coverage/empty.rs @@ -1,4 +1,4 @@ // compile-flags:-Z unstable-options --show-coverage -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // an empty crate still has one item to document: the crate root diff --git a/src/test/rustdoc-ui/coverage/enums.rs b/src/test/rustdoc-ui/coverage/enums.rs index 5cd7f490d1a9a..e4171d7cfb250 100644 --- a/src/test/rustdoc-ui/coverage/enums.rs +++ b/src/test/rustdoc-ui/coverage/enums.rs @@ -1,5 +1,5 @@ // compile-flags:-Z unstable-options --show-coverage -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! (remember the crate root is still a module) diff --git a/src/test/rustdoc-ui/coverage/exotic.rs b/src/test/rustdoc-ui/coverage/exotic.rs index b4adf45b90b8a..414d6f8405816 100644 --- a/src/test/rustdoc-ui/coverage/exotic.rs +++ b/src/test/rustdoc-ui/coverage/exotic.rs @@ -1,5 +1,5 @@ // compile-flags:-Z unstable-options --show-coverage -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(doc_keyword)] diff --git a/src/test/rustdoc-ui/coverage/private.rs b/src/test/rustdoc-ui/coverage/private.rs index 9024185856daa..6ff1bfa7275de 100644 --- a/src/test/rustdoc-ui/coverage/private.rs +++ b/src/test/rustdoc-ui/coverage/private.rs @@ -1,5 +1,5 @@ // compile-flags:-Z unstable-options --show-coverage --document-private-items -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] diff --git a/src/test/rustdoc-ui/coverage/statics-consts.rs b/src/test/rustdoc-ui/coverage/statics-consts.rs index 3c1dd35dfe1ab..b7d2b1dc10c62 100644 --- a/src/test/rustdoc-ui/coverage/statics-consts.rs +++ b/src/test/rustdoc-ui/coverage/statics-consts.rs @@ -1,5 +1,5 @@ // compile-flags:-Z unstable-options --show-coverage -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! gotta make sure we can count statics and consts correctly, too diff --git a/src/test/rustdoc-ui/coverage/traits.rs b/src/test/rustdoc-ui/coverage/traits.rs index 5f32d5b0cccc7..40d68423f1bc6 100644 --- a/src/test/rustdoc-ui/coverage/traits.rs +++ b/src/test/rustdoc-ui/coverage/traits.rs @@ -1,5 +1,5 @@ // compile-flags:-Z unstable-options --show-coverage -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(trait_alias)] diff --git a/src/test/rustdoc-ui/deprecated-attrs.rs b/src/test/rustdoc-ui/deprecated-attrs.rs index 6f6d5b8b654da..21169eeb8c83e 100644 --- a/src/test/rustdoc-ui/deprecated-attrs.rs +++ b/src/test/rustdoc-ui/deprecated-attrs.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![doc(no_default_passes, passes = "collapse-docs unindent-comments")] diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.rs b/src/test/rustdoc-ui/intra-links-warning-crlf.rs index 20f761fcf4f3b..67bd9f73eeb5b 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.rs +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.rs @@ -1,6 +1,6 @@ // ignore-tidy-cr -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file checks the spans of intra-link warnings in a file with CRLF line endings. The // .gitattributes file in this directory should enforce it. diff --git a/src/test/rustdoc-ui/intra-links-warning.rs b/src/test/rustdoc-ui/intra-links-warning.rs index 26d4598f7ad1e..20770efa95315 100644 --- a/src/test/rustdoc-ui/intra-links-warning.rs +++ b/src/test/rustdoc-ui/intra-links-warning.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! Test with [Foo::baz], [Bar::foo], ... //! , [Uniooon::X] and [Qux::Z]. diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs index 924e0386d3191..2b02d47d4b851 100644 --- a/src/test/rustdoc-ui/invalid-syntax.rs +++ b/src/test/rustdoc-ui/invalid-syntax.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) /// ``` /// \__________pkt->size___________/ \_result->size_/ \__pkt->size__/ diff --git a/src/test/rustdoc-ui/issue-58473-2.rs b/src/test/rustdoc-ui/issue-58473-2.rs index 5e5ddebe10884..1bb19353ba2f7 100644 --- a/src/test/rustdoc-ui/issue-58473-2.rs +++ b/src/test/rustdoc-ui/issue-58473-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(private_doc_tests)] diff --git a/src/test/rustdoc-ui/issue-58473.rs b/src/test/rustdoc-ui/issue-58473.rs index 0e5be3292c053..6756d3b5a6051 100644 --- a/src/test/rustdoc-ui/issue-58473.rs +++ b/src/test/rustdoc-ui/issue-58473.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Foo { /** diff --git a/src/test/rustdoc-ui/unused.rs b/src/test/rustdoc-ui/unused.rs index e82a41b7a7b81..ffa421d4f7f2d 100644 --- a/src/test/rustdoc-ui/unused.rs +++ b/src/test/rustdoc-ui/unused.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test purpose is to check that unused_imports lint isn't fired // by rustdoc. Why would it? Because when rustdoc is running, it uses diff --git a/src/test/rustdoc/process-termination.rs b/src/test/rustdoc/process-termination.rs index 31ae0143d4771..32258792b6e8b 100644 --- a/src/test/rustdoc/process-termination.rs +++ b/src/test/rustdoc/process-termination.rs @@ -21,16 +21,4 @@ /// Err("This is returned from `main`, leading to panic")?; /// Ok::<(), &'static str>(()) /// ``` -/// -/// This also works with `Option<()>`s now: -/// -/// ```rust -/// Some(()) -/// ``` -/// -/// ```rust,should_panic -/// let x: &[u32] = &[]; -/// let _ = x.iter().next()?; -/// Some(()) -/// ``` pub fn check_process_termination() {} diff --git a/src/test/ui/anon-params-deprecated.fixed b/src/test/ui/anon-params-deprecated.fixed index 7eee47dcb5fc7..fe42113eb2ee9 100644 --- a/src/test/ui/anon-params-deprecated.fixed +++ b/src/test/ui/anon-params-deprecated.fixed @@ -1,7 +1,7 @@ #![warn(anonymous_parameters)] // Test for the anonymous_parameters deprecation lint (RFC 1685) -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2015 // run-rustfix diff --git a/src/test/ui/anon-params-deprecated.rs b/src/test/ui/anon-params-deprecated.rs index 74de0c0b83407..dc0357721ec73 100644 --- a/src/test/ui/anon-params-deprecated.rs +++ b/src/test/ui/anon-params-deprecated.rs @@ -1,7 +1,7 @@ #![warn(anonymous_parameters)] // Test for the anonymous_parameters deprecation lint (RFC 1685) -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2015 // run-rustfix diff --git a/src/test/ui/associated-const/associated-const-trait-bound.rs b/src/test/ui/associated-const/associated-const-trait-bound.rs index 0ce46d312afef..403cdbd7ff330 100644 --- a/src/test/ui/associated-const/associated-const-trait-bound.rs +++ b/src/test/ui/associated-const/associated-const-trait-bound.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait ConstDefault { const DEFAULT: Self; diff --git a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs index 1b3e978594d69..f5a9bac6e3549 100644 --- a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs +++ b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/trait-params.rs b/src/test/ui/associated-type-bounds/trait-params.rs index a9081d50cfc5d..b0703a4ee22b3 100644 --- a/src/test/ui/associated-type-bounds/trait-params.rs +++ b/src/test/ui/associated-type-bounds/trait-params.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(associated_type_bounds)] diff --git a/src/test/ui/associated-type-bounds/type-alias.rs b/src/test/ui/associated-type-bounds/type-alias.rs index 1602fdd275a2e..34bc0c9acbf4c 100644 --- a/src/test/ui/associated-type-bounds/type-alias.rs +++ b/src/test/ui/associated-type-bounds/type-alias.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(associated_type_bounds)] diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs index 38261ca4570eb..0eae1467fbfa0 100644 --- a/src/test/ui/async-await/async-await.rs +++ b/src/test/ui/async-await/async-await.rs @@ -134,11 +134,15 @@ trait Bar { } impl Foo { - async fn async_method(x: u8) -> u8 { + async fn async_assoc_item(x: u8) -> u8 { unsafe { unsafe_async_fn(x).await } } + + async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 { + unsafe_async_fn(x).await + } } fn test_future_yields_once_then_returns(f: F) @@ -180,12 +184,17 @@ fn main() { async_fn, generic_async_fn, async_fn_with_internal_borrow, - Foo::async_method, + Foo::async_assoc_item, |x| { async move { unsafe { unsafe_async_fn(x).await } } }, + |x| { + async move { + unsafe { Foo::async_unsafe_assoc_item(x).await } + } + }, } test_with_borrow! { async_block_with_borrow_named_lifetime, diff --git a/src/test/ui/async-await/async-fn-multiple-lifetimes.rs b/src/test/ui/async-await/async-fn-multiple-lifetimes.rs deleted file mode 100644 index e3ac817b15ca5..0000000000000 --- a/src/test/ui/async-await/async-fn-multiple-lifetimes.rs +++ /dev/null @@ -1,19 +0,0 @@ -// edition:2018 - -#![feature(arbitrary_self_types, async_await, await_macro, pin)] - -use std::ops::Add; - -async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} -//~^ ERROR ambiguous lifetime bound in `async fn` - -async fn multiple_hrtb_and_single_named_lifetime_ok<'c>( - _: impl for<'a> Add<&'a u8>, - _: impl for<'b> Add<&'b u8>, - _: &'c u8, -) {} - -async fn multiple_elided_lifetimes(_: &u8, _: &u8) {} -//~^ ambiguous lifetime bound in `async fn` - -fn main() {} diff --git a/src/test/ui/async-await/async-fn-multiple-lifetimes.stderr b/src/test/ui/async-await/async-fn-multiple-lifetimes.stderr deleted file mode 100644 index 8c3ee2bed830b..0000000000000 --- a/src/test/ui/async-await/async-fn-multiple-lifetimes.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: ambiguous lifetime bound in `async fn` - --> $DIR/async-fn-multiple-lifetimes.rs:7:65 - | -LL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} - | ^ neither `'a` nor `'b` outlives the other - | - = note: multiple unrelated lifetimes are not allowed in `async fn`. - = note: if you're using argument-position elided lifetimes, consider switching to a single named lifetime. - -error: ambiguous lifetime bound in `async fn` - --> $DIR/async-fn-multiple-lifetimes.rs:16:52 - | -LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {} - | ^ the elided lifetimes here do not outlive one another - | - = note: multiple unrelated lifetimes are not allowed in `async fn`. - = note: if you're using argument-position elided lifetimes, consider switching to a single named lifetime. - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs index f07fc2fceb5b6..5e1b8c6280b81 100644 --- a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs +++ b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/async-matches-expr.rs b/src/test/ui/async-await/async-matches-expr.rs index f375d58d98495..e41a568ad2982 100644 --- a/src/test/ui/async-await/async-matches-expr.rs +++ b/src/test/ui/async-await/async-matches-expr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, await_macro)] diff --git a/src/test/ui/async-await/async-with-closure.rs b/src/test/ui/async-await/async-with-closure.rs index e94a5f0853d72..2b69c9b701a42 100644 --- a/src/test/ui/async-await/async-with-closure.rs +++ b/src/test/ui/async-await/async-with-closure.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, await_macro)] diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs index e1111f9e0e4b9..a5bc181015475 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs @@ -28,6 +28,12 @@ fn main() { async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition } + accept_item! { + impl Foo { + async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition + } + } + let inside_closure = || { async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition }; diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr index 05a06124dc220..efb4462095d0d 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr @@ -23,7 +23,19 @@ LL | async fn async_baz() { | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:32:9 + --> $DIR/edition-deny-async-fns-2015.rs:16:5 + | +LL | async fn foo() {} + | ^^^^^ + +error[E0670]: `async fn` is not permitted in the 2015 edition + --> $DIR/edition-deny-async-fns-2015.rs:20:5 + | +LL | async fn foo() {} + | ^^^^^ + +error[E0670]: `async fn` is not permitted in the 2015 edition + --> $DIR/edition-deny-async-fns-2015.rs:38:9 | LL | async fn bar() {} | ^^^^^ @@ -35,10 +47,10 @@ LL | async fn foo() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:16:5 + --> $DIR/edition-deny-async-fns-2015.rs:33:13 | -LL | async fn foo() {} - | ^^^^^ +LL | async fn bar() {} + | ^^^^^ error[E0706]: trait fns cannot be declared `async` --> $DIR/edition-deny-async-fns-2015.rs:20:5 @@ -46,12 +58,6 @@ error[E0706]: trait fns cannot be declared `async` LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ -error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:20:5 - | -LL | async fn foo() {} - | ^^^^^ - -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0670`. diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs index 913f1435c6adf..8b60f2f82f1d6 100644 --- a/src/test/ui/async-await/generics-and-bounds.rs +++ b/src/test/ui/async-await/generics-and-bounds.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags: --crate-type lib diff --git a/src/test/ui/async-await/issue-61793.rs b/src/test/ui/async-await/issue-61793.rs index bccdf0113ff69..a18fad8bb9150 100644 --- a/src/test/ui/async-await/issue-61793.rs +++ b/src/test/ui/async-await/issue-61793.rs @@ -3,7 +3,7 @@ // while those two fields were at the same offset (which is impossible). // That is, memory ordering of `(X, ())`, but offsets of `((), X)`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await)] diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs index 2157cf7d4f7ab..c493878e4c2dd 100644 --- a/src/test/ui/async-await/issues/issue-53249.rs +++ b/src/test/ui/async-await/issues/issue-53249.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(arbitrary_self_types, async_await, await_macro)] diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs index ad18f41187569..0cfe859b13b27 100644 --- a/src/test/ui/async-await/issues/issue-54974.rs +++ b/src/test/ui/async-await/issues/issue-54974.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, await_macro)] diff --git a/src/test/ui/async-await/issues/issue-55324.rs b/src/test/ui/async-await/issues/issue-55324.rs index 4572e543f22de..deaba6904f446 100644 --- a/src/test/ui/async-await/issues/issue-55324.rs +++ b/src/test/ui/async-await/issues/issue-55324.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, await_macro)] diff --git a/src/test/ui/async-await/issues/issue-58885.rs b/src/test/ui/async-await/issues/issue-58885.rs index 99d87b2273c2f..5868e022861a2 100644 --- a/src/test/ui/async-await/issues/issue-58885.rs +++ b/src/test/ui/async-await/issues/issue-58885.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, await_macro)] diff --git a/src/test/ui/async-await/issues/issue-59001.rs b/src/test/ui/async-await/issues/issue-59001.rs index c758244002ff6..ffa70d3b43cb4 100644 --- a/src/test/ui/async-await/issues/issue-59001.rs +++ b/src/test/ui/async-await/issues/issue-59001.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, await_macro)] diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs index f603c5bd3f946..e4bdc96511e3c 100644 --- a/src/test/ui/async-await/issues/issue-60518.rs +++ b/src/test/ui/async-await/issues/issue-60518.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await)] diff --git a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs index a4fe86501299f..2328ceb144f20 100644 --- a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs +++ b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs @@ -1,6 +1,6 @@ // Test that existential types are allowed to contain late-bound regions. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await, existential_type)] diff --git a/src/test/ui/async-await/issues/issue-60674.rs b/src/test/ui/async-await/issues/issue-60674.rs index ecb80803383b4..99cdcbafc766f 100644 --- a/src/test/ui/async-await/issues/issue-60674.rs +++ b/src/test/ui/async-await/issues/issue-60674.rs @@ -1,5 +1,5 @@ // aux-build:issue-60674.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(async_await)] diff --git a/src/test/ui/async-await/issues/issue-61986.rs b/src/test/ui/async-await/issues/issue-61986.rs index da8b22bc104bf..77ecc47dfef12 100644 --- a/src/test/ui/async-await/issues/issue-61986.rs +++ b/src/test/ui/async-await/issues/issue-61986.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // // Tests that we properly handle StorageDead/StorageLives for temporaries diff --git a/src/test/ui/async-await/multiple-lifetimes/elided.rs b/src/test/ui/async-await/multiple-lifetimes/elided.rs new file mode 100644 index 0000000000000..45f3170d4c309 --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/elided.rs @@ -0,0 +1,12 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +#![feature(async_await)] + +async fn multiple_elided_lifetimes(_: &u8, _: &u8) {} + +fn main() { + let _ = multiple_elided_lifetimes(&22, &44); +} diff --git a/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs new file mode 100644 index 0000000000000..a7254cee75526 --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs @@ -0,0 +1,14 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +#![feature(async_await)] + +async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8, _: fn(&u8)) {} + +fn gimme(_: &u8) { } + +fn main() { + let _ = multiple_named_lifetimes(&22, &44, gimme); +} diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs new file mode 100644 index 0000000000000..620b0080966b9 --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs @@ -0,0 +1,17 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +#![feature(arbitrary_self_types, async_await, await_macro)] +#![allow(dead_code)] + +use std::ops::Add; + +async fn multiple_hrtb_and_single_named_lifetime_ok<'c>( + _: impl for<'a> Add<&'a u8>, + _: impl for<'b> Add<&'b u8>, + _: &'c u8, +) {} + +fn main() {} diff --git a/src/test/ui/async-await/multiple-lifetimes/named.rs b/src/test/ui/async-await/multiple-lifetimes/named.rs new file mode 100644 index 0000000000000..7d13d48bc8bbd --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/named.rs @@ -0,0 +1,12 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +#![feature(arbitrary_self_types, async_await, await_macro)] + +async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} + +fn main() { + let _ = multiple_named_lifetimes(&22, &44); +} diff --git a/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs new file mode 100644 index 0000000000000..903c43950a5c4 --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs @@ -0,0 +1,15 @@ +// edition:2018 +// run-pass + +#![feature(async_await)] + +async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32) + where 'b: 'a +{ + drop((a, c)); + (b, b) +} + +fn main() { + let _ = lotsa_lifetimes(&22, &44, &66); +} diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs new file mode 100644 index 0000000000000..08622311f7b1c --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs @@ -0,0 +1,18 @@ +// edition:2018 +// run-pass + +// Test that a feature gate is needed to use `impl Trait` as the +// return type of an async. + +#![feature(async_await, member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + (a, b) +} + +fn main() { + let _ = async_ret_impl_trait(&22, &44); +} diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs new file mode 100644 index 0000000000000..08ecea4cc85fc --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs @@ -0,0 +1,18 @@ +// edition:2018 + +// Test that a feature gate is needed to use `impl Trait` as the +// return type of an async. + +#![feature(async_await)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + //~^ ERROR ambiguous lifetime bound + (a, b) +} + +fn main() { + let _ = async_ret_impl_trait(&22, &44); +} diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr new file mode 100644 index 0000000000000..de2c85d772a72 --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr @@ -0,0 +1,10 @@ +error: ambiguous lifetime bound in `impl Trait` + --> $DIR/ret-impl-trait-no-fg.rs:11:64 + | +LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other + | + = help: add #![feature(member_constraints)] to the crate attributes to enable + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr new file mode 100644 index 0000000000000..b4d5d3ec051e2 --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr @@ -0,0 +1,15 @@ +error: lifetime may not live long enough + --> $DIR/ret-impl-trait-one.rs:12:80 + | +LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { + | ________________________________--__--__________________________________________^ + | | | | + | | | lifetime `'b` defined here + | | lifetime `'a` defined here +LL | | +LL | | (a, b) +LL | | } + | |_^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs new file mode 100644 index 0000000000000..e1b714652737f --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs @@ -0,0 +1,27 @@ +// edition:2018 + +// Test that a feature gate is needed to use `impl Trait` as the +// return type of an async. + +#![feature(async_await, member_constraints)] + +trait Trait<'a> { } +impl Trait<'_> for T { } + +// Only `'a` permitted in return type, not `'b`. +async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { + //~^ ERROR lifetime mismatch + (a, b) +} + +// As above, but `'b: 'a`, so return type can be inferred to `(&'a u8, +// &'a u8)`. +async fn async_ret_impl_trait2<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> +where + 'b: 'a, +{ + (a, b) +} + +fn main() { +} diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr new file mode 100644 index 0000000000000..f6d611517bc8f --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -0,0 +1,11 @@ +error[E0623]: lifetime mismatch + --> $DIR/ret-impl-trait-one.rs:12:65 + | +LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { + | ------ ^^^^^^^^^^^^^^ + | | | + | | ...but data from `b` is returned here + | this parameter and the return type are declared with different lifetimes... + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs new file mode 100644 index 0000000000000..98da90161e5fd --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs @@ -0,0 +1,46 @@ +// edition:2018 + +// Test that we get the expected borrow check errors when an async +// function (which takes multiple lifetimes) only returns data from +// one of them. + +#![feature(async_await)] + +async fn multiple_named_lifetimes<'a, 'b>(a: &'a u8, _: &'b u8) -> &'a u8 { + a +} + +// Both are borrowed whilst the future is live. +async fn future_live() { + let mut a = 22; + let mut b = 44; + let future = multiple_named_lifetimes(&a, &b); + a += 1; //~ ERROR cannot assign + b += 1; //~ ERROR cannot assign + let p = future.await; + drop(p); +} + +// Just the return value is live after future is awaited. +async fn just_return_live() { + let mut a = 22; + let mut b = 44; + let future = multiple_named_lifetimes(&a, &b); + let p = future.await; + a += 1; //~ ERROR cannot assign + b += 1; + drop(p); +} + +// Once `p` is dead, both `a` and `b` are unborrowed. +async fn after_both_dead() { + let mut a = 22; + let mut b = 44; + let future = multiple_named_lifetimes(&a, &b); + let p = future.await; + drop(p); + a += 1; + b += 1; +} + +fn main() { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr new file mode 100644 index 0000000000000..fe70d35942c7c --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr @@ -0,0 +1,37 @@ +error[E0506]: cannot assign to `a` because it is borrowed + --> $DIR/ret-ref.rs:18:5 + | +LL | let future = multiple_named_lifetimes(&a, &b); + | -- borrow of `a` occurs here +LL | a += 1; + | ^^^^^^ assignment to borrowed `a` occurs here +LL | b += 1; +LL | let p = future.await; + | ------ borrow later used here + +error[E0506]: cannot assign to `b` because it is borrowed + --> $DIR/ret-ref.rs:19:5 + | +LL | let future = multiple_named_lifetimes(&a, &b); + | -- borrow of `b` occurs here +LL | a += 1; +LL | b += 1; + | ^^^^^^ assignment to borrowed `b` occurs here +LL | let p = future.await; + | ------ borrow later used here + +error[E0506]: cannot assign to `a` because it is borrowed + --> $DIR/ret-ref.rs:30:5 + | +LL | let future = multiple_named_lifetimes(&a, &b); + | -- borrow of `a` occurs here +LL | let p = future.await; +LL | a += 1; + | ^^^^^^ assignment to borrowed `a` occurs here +LL | b += 1; +LL | drop(p); + | - borrow later used here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/async-await/multiple-lifetimes/variance.rs b/src/test/ui/async-await/multiple-lifetimes/variance.rs new file mode 100644 index 0000000000000..b52ad17d5631d --- /dev/null +++ b/src/test/ui/async-await/multiple-lifetimes/variance.rs @@ -0,0 +1,18 @@ +// edition:2018 +// run-pass + +// Test for async fn where the parameters have distinct lifetime +// parameters that appear in all possible variances. + +#![feature(async_await)] + +#[allow(dead_code)] +async fn lotsa_lifetimes<'a, 'b, 'c>(_: fn(&'a u8), _: fn(&'b u8) -> &'b u8, _: fn() -> &'c u8) { } + +fn take_any(_: &u8) { } +fn identify(x: &u8) -> &u8 { x } +fn give_back() -> &'static u8 { &22 } + +fn main() { + let _ = lotsa_lifetimes(take_any, identify, give_back); +} diff --git a/src/test/ui/async-await/no-unsafe-async.rs b/src/test/ui/async-await/no-unsafe-async.rs new file mode 100644 index 0000000000000..81e0cd799ad70 --- /dev/null +++ b/src/test/ui/async-await/no-unsafe-async.rs @@ -0,0 +1,11 @@ +// edition:2018 + +struct S; + +impl S { + #[cfg(FALSE)] + unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found `async` +} + +#[cfg(FALSE)] +unsafe async fn f() {} //~ ERROR expected one of `extern`, `fn`, or `{`, found `async` diff --git a/src/test/ui/async-await/no-unsafe-async.stderr b/src/test/ui/async-await/no-unsafe-async.stderr new file mode 100644 index 0000000000000..c339c7c3bf5bf --- /dev/null +++ b/src/test/ui/async-await/no-unsafe-async.stderr @@ -0,0 +1,14 @@ +error: expected one of `extern` or `fn`, found `async` + --> $DIR/no-unsafe-async.rs:7:12 + | +LL | unsafe async fn g() {} + | ^^^^^ expected one of `extern` or `fn` here + +error: expected one of `extern`, `fn`, or `{`, found `async` + --> $DIR/no-unsafe-async.rs:11:8 + | +LL | unsafe async fn f() {} + | ^^^^^ expected one of `extern`, `fn`, or `{` here + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/attributes/attr-before-view-item.rs b/src/test/ui/attributes/attr-before-view-item.rs index fc040bd1a5d10..e1588aadab62c 100644 --- a/src/test/ui/attributes/attr-before-view-item.rs +++ b/src/test/ui/attributes/attr-before-view-item.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/attr-before-view-item2.rs b/src/test/ui/attributes/attr-before-view-item2.rs index c7fad3802e9d6..c1f667372f515 100644 --- a/src/test/ui/attributes/attr-before-view-item2.rs +++ b/src/test/ui/attributes/attr-before-view-item2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/attr-mix-new.rs b/src/test/ui/attributes/attr-mix-new.rs index d9cb551096092..8119df0c40cb0 100644 --- a/src/test/ui/attributes/attr-mix-new.rs +++ b/src/test/ui/attributes/attr-mix-new.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/class-attributes-1.rs b/src/test/ui/attributes/class-attributes-1.rs index 7808367f2c10f..027b701e591ba 100644 --- a/src/test/ui/attributes/class-attributes-1.rs +++ b/src/test/ui/attributes/class-attributes-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pp-exact - Make sure we actually print the attributes #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/class-attributes-2.rs b/src/test/ui/attributes/class-attributes-2.rs index 348c70f35c328..6aba6b89427e4 100644 --- a/src/test/ui/attributes/class-attributes-2.rs +++ b/src/test/ui/attributes/class-attributes-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/item-attributes.rs b/src/test/ui/attributes/item-attributes.rs index 72c9a35dc07f0..c760a28ecf0ba 100644 --- a/src/test/ui/attributes/item-attributes.rs +++ b/src/test/ui/attributes/item-attributes.rs @@ -2,7 +2,7 @@ // for completeness since .rs files linked from .rc files support this // notation to specify their module's attributes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/attributes/method-attributes.rs b/src/test/ui/attributes/method-attributes.rs index 2d608acc71f71..67439718bd3cc 100644 --- a/src/test/ui/attributes/method-attributes.rs +++ b/src/test/ui/attributes/method-attributes.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pp-exact - Make sure we print all the attributes // pretty-expanded FIXME #23616 diff --git a/src/test/ui/attributes/variant-attributes.rs b/src/test/ui/attributes/variant-attributes.rs index a910340f4a06d..ffcdeb52a042f 100644 --- a/src/test/ui/attributes/variant-attributes.rs +++ b/src/test/ui/attributes/variant-attributes.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pp-exact - Make sure we actually print the attributes // pretty-expanded FIXME #23616 diff --git a/src/test/ui/bastion-of-the-turbofish.rs b/src/test/ui/bastion-of-the-turbofish.rs index 0716fcf7f26a8..cc43210d8e3b9 100644 --- a/src/test/ui/bastion-of-the-turbofish.rs +++ b/src/test/ui/bastion-of-the-turbofish.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Bastion of the Turbofish // ------------------------ diff --git a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs index 6d91fd3508a86..1d98067ce738c 100644 --- a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs +++ b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274 // (for ensuring that NLL respects user-provided lifetime annotations) diff --git a/src/test/ui/check_match/issue-43253.rs b/src/test/ui/check_match/issue-43253.rs index 5d084248a7f99..a4d6e9b777f02 100644 --- a/src/test/ui/check_match/issue-43253.rs +++ b/src/test/ui/check_match/issue-43253.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(exclusive_range_pattern)] #![warn(unreachable_patterns)] diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs index 1bfaecd16c0b6..5f02e642defca 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] diff --git a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs index 3e42284b72c3f..0ee738c2c2f39 100644 --- a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs +++ b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn with_closure(_: F) where F: FnOnce(A, &u32) diff --git a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs index cf417d7c2a8e8..15711da4b0fbb 100644 --- a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs +++ b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn with_closure(_: F) where F: FnOnce(A, &u32) diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs index 477eb40c57e1f..f7b4f2b24549e 100644 --- a/src/test/ui/closure-expected-type/issue-24421.rs +++ b/src/test/ui/closure-expected-type/issue-24421.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn test(f: F) {} diff --git a/src/test/ui/closure_promotion.rs b/src/test/ui/closure_promotion.rs index db9c0a6ef3be4..db36985afe7a8 100644 --- a/src/test/ui/closure_promotion.rs +++ b/src/test/ui/closure_promotion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(const_err)] diff --git a/src/test/ui/codemap_tests/unicode_3.rs b/src/test/ui/codemap_tests/unicode_3.rs index ff6d54468b8ec..b9bcc1b88a336 100644 --- a/src/test/ui/codemap_tests/unicode_3.rs +++ b/src/test/ui/codemap_tests/unicode_3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; } diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.rs b/src/test/ui/coercion/coerce-issue-49593-box-never.rs index 81723bb15b774..f005245e6dcb9 100644 --- a/src/test/ui/coercion/coerce-issue-49593-box-never.rs +++ b/src/test/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(never_type)] #![allow(unreachable_code)] diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index e74067578069e..a0ff580671a20 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -5,7 +5,7 @@ // universe transition (#56105) may eventually become an error. // revisions: old re -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![cfg_attr(re, feature(re_rebalance_coherence))] diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs index a030314262270..22517f9da2e30 100644 --- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs +++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs @@ -2,7 +2,7 @@ // `MyType: !MyTrait` along with other "fundamental" wrappers. // aux-build:coherence_copy_like_lib.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // skip-codgen // revisions: old re diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs index f1ab2f0f9461f..0c7e7cad0359f 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-false.rs @@ -1,7 +1,7 @@ // Test that cfg_attr doesn't emit any attributes when the // configuration variable is false. This mirrors `cfg-attr-multi-true.rs` -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs index 86524e8bd28ff..645e4e71dfe9a 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -2,7 +2,7 @@ // This is done by emitting two attributes that cause new warnings, and then // triggering those warnings. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs index f592e486be951..cb40734c1d257 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash diff --git a/src/test/ui/const-generics/issue-60818-struct-constructors.rs b/src/test/ui/const-generics/issue-60818-struct-constructors.rs index 0b4aeae7a4a39..b810efe73847e 100644 --- a/src/test/ui/const-generics/issue-60818-struct-constructors.rs +++ b/src/test/ui/const-generics/issue-60818-struct-constructors.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash diff --git a/src/test/ui/consts/const-block-non-item-statement.rs b/src/test/ui/consts/const-block-non-item-statement.rs index 5ecf9a049842d..9aec85526955e 100644 --- a/src/test/ui/consts/const-block-non-item-statement.rs +++ b/src/test/ui/consts/const-block-non-item-statement.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Foo { Bar = { let x = 1; 3 } diff --git a/src/test/ui/consts/const-eval/const_prop_errors.rs b/src/test/ui/consts/const-eval/const_prop_errors.rs index 51b50b2e75f4f..48cfea82bd65e 100644 --- a/src/test/ui/consts/const-eval/const_prop_errors.rs +++ b/src/test/ui/consts/const-eval/const_prop_errors.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Foo { fn foo(self) -> u32; diff --git a/src/test/ui/consts/const-eval/const_signed_pat.rs b/src/test/ui/consts/const-eval/const_signed_pat.rs index cb4fb46bd055c..d209e60448687 100644 --- a/src/test/ui/consts/const-eval/const_signed_pat.rs +++ b/src/test/ui/consts/const-eval/const_signed_pat.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { const MIN: i8 = -5; diff --git a/src/test/ui/consts/const-eval/double_check.rs b/src/test/ui/consts/const-eval/double_check.rs index 9ac511767c0f7..2cf6a5494dd8d 100644 --- a/src/test/ui/consts/const-eval/double_check.rs +++ b/src/test/ui/consts/const-eval/double_check.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Foo { A = 5, diff --git a/src/test/ui/consts/const-eval/double_promotion.rs b/src/test/ui/consts/const-eval/double_promotion.rs index 0e75ea8e66b3c..a9a3f071bf89f 100644 --- a/src/test/ui/consts/const-eval/double_promotion.rs +++ b/src/test/ui/consts/const-eval/double_promotion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_fn, rustc_attrs)] diff --git a/src/test/ui/consts/const-eval/duration_conversion.rs b/src/test/ui/consts/const-eval/duration_conversion.rs index 854f97d4754df..029d4e5e3732e 100644 --- a/src/test/ui/consts/const-eval/duration_conversion.rs +++ b/src/test/ui/consts/const-eval/duration_conversion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::time::Duration; diff --git a/src/test/ui/consts/const-eval/extern_fat_pointer.rs b/src/test/ui/consts/const-eval/extern_fat_pointer.rs index f8e6fd09c7e0a..e2b3bc83c3f01 100644 --- a/src/test/ui/consts/const-eval/extern_fat_pointer.rs +++ b/src/test/ui/consts/const-eval/extern_fat_pointer.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_types)] diff --git a/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs b/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs index 2ad1a633d125f..ce0e11f29f442 100644 --- a/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs +++ b/src/test/ui/consts/const-eval/ice-generic-assoc-const.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Nullable { const NULL: Self; diff --git a/src/test/ui/consts/const-eval/ice-packed.rs b/src/test/ui/consts/const-eval/ice-packed.rs index b9fe4eadd4132..250bf954e9ac2 100644 --- a/src/test/ui/consts/const-eval/ice-packed.rs +++ b/src/test/ui/consts/const-eval/ice-packed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(Copy, Clone, PartialEq, Eq)] #[repr(packed)] pub struct Num(u64); diff --git a/src/test/ui/consts/const-eval/issue-47971.rs b/src/test/ui/consts/const-eval/issue-47971.rs index 9d7b05cd232b5..9de150bd0528d 100644 --- a/src/test/ui/consts/const-eval/issue-47971.rs +++ b/src/test/ui/consts/const-eval/issue-47971.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(pub &'static u32, pub u32); diff --git a/src/test/ui/consts/const-eval/issue-50706.rs b/src/test/ui/consts/const-eval/issue-50706.rs index cb45b86cd7ba3..bf69bc28da41a 100644 --- a/src/test/ui/consts/const-eval/issue-50706.rs +++ b/src/test/ui/consts/const-eval/issue-50706.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Stats; diff --git a/src/test/ui/consts/const-eval/issue-51300.rs b/src/test/ui/consts/const-eval/issue-51300.rs index 72a6072e4b7b4..4753bf0f7b174 100644 --- a/src/test/ui/consts/const-eval/issue-51300.rs +++ b/src/test/ui/consts/const-eval/issue-51300.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // https://github.com/rust-lang/rust/issues/51300 #[derive(PartialEq, Eq, Clone, Copy)] diff --git a/src/test/ui/consts/const-eval/issue-53157.rs b/src/test/ui/consts/const-eval/issue-53157.rs index b9958609971a7..ac0940b33e47a 100644 --- a/src/test/ui/consts/const-eval/issue-53157.rs +++ b/src/test/ui/consts/const-eval/issue-53157.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! m { () => {{ diff --git a/src/test/ui/consts/const-eval/issue-53401.rs b/src/test/ui/consts/const-eval/issue-53401.rs index e8ac5a90880ce..d300e0b5125da 100644 --- a/src/test/ui/consts/const-eval/issue-53401.rs +++ b/src/test/ui/consts/const-eval/issue-53401.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub const STATIC_TRAIT: &dyn Test = &(); diff --git a/src/test/ui/consts/const-eval/issue-55541.rs b/src/test/ui/consts/const-eval/issue-55541.rs index 611fb89341de4..d04570c67ff2e 100644 --- a/src/test/ui/consts/const-eval/issue-55541.rs +++ b/src/test/ui/consts/const-eval/issue-55541.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that we can handle newtypes wrapping extern types diff --git a/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs b/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs index 0d14cf0f6d951..cea367528c975 100644 --- a/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs +++ b/src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // if `X` were used instead of `x`, `X - 10` would result in a lint. // This file should never produce a lint, no matter how the const diff --git a/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs b/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs index 34f61ed5a3474..ca75d65a39a92 100644 --- a/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs +++ b/src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub fn main() { let y: &'static mut [u8; 0] = &mut []; diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index ebf80e7d2e670..fa8859cbb3bb6 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -1,19 +1,23 @@ -#![warn(const_err)] - -// compile-pass // compile-flags: -O + +#![deny(const_err)] + fn main() { println!("{}", 0u32 - 1); let _x = 0u32 - 1; - //~^ WARN const_err + //~^ ERROR this expression will panic at runtime [const_err] println!("{}", 1/(1-1)); - //~^ WARN const_err + //~^ ERROR this expression will panic at runtime [const_err] + //~| ERROR attempt to divide by zero [const_err] + //~| ERROR reaching this expression at runtime will panic or abort [const_err] let _x = 1/(1-1); - //~^ WARN const_err - //~| WARN const_err + //~^ ERROR const_err + //~| ERROR const_err println!("{}", 1/(false as u32)); - //~^ WARN const_err + //~^ ERROR this expression will panic at runtime [const_err] + //~| ERROR attempt to divide by zero [const_err] + //~| ERROR reaching this expression at runtime will panic or abort [const_err] let _x = 1/(false as u32); - //~^ WARN const_err - //~| WARN const_err + //~^ ERROR const_err + //~| ERROR const_err } diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index c9f3a7659f9cd..12407accf096f 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,72 +1,74 @@ -warning: this expression will panic at runtime +error: this expression will panic at runtime --> $DIR/promoted_errors.rs:7:14 | LL | let _x = 0u32 - 1; | ^^^^^^^^ attempt to subtract with overflow | note: lint level defined here - --> $DIR/promoted_errors.rs:1:9 + --> $DIR/promoted_errors.rs:3:9 | -LL | #![warn(const_err)] +LL | #![deny(const_err)] | ^^^^^^^^^ -warning: attempt to divide by zero +error: attempt to divide by zero --> $DIR/promoted_errors.rs:9:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ -warning: this expression will panic at runtime +error: this expression will panic at runtime --> $DIR/promoted_errors.rs:9:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ attempt to divide by zero -warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:11:14 +error: attempt to divide by zero + --> $DIR/promoted_errors.rs:13:14 | LL | let _x = 1/(1-1); | ^^^^^^^ -warning: this expression will panic at runtime - --> $DIR/promoted_errors.rs:11:14 +error: this expression will panic at runtime + --> $DIR/promoted_errors.rs:13:14 | LL | let _x = 1/(1-1); | ^^^^^^^ attempt to divide by zero -warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:14:20 +error: attempt to divide by zero + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ -warning: this expression will panic at runtime - --> $DIR/promoted_errors.rs:14:20 +error: this expression will panic at runtime + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -warning: attempt to divide by zero - --> $DIR/promoted_errors.rs:16:14 +error: attempt to divide by zero + --> $DIR/promoted_errors.rs:20:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ -warning: this expression will panic at runtime - --> $DIR/promoted_errors.rs:16:14 +error: this expression will panic at runtime + --> $DIR/promoted_errors.rs:20:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -warning: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:14:20 +error: reaching this expression at runtime will panic or abort + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -warning: reaching this expression at runtime will panic or abort +error: reaching this expression at runtime will panic or abort --> $DIR/promoted_errors.rs:9:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ attempt to divide by zero +error: aborting due to 11 previous errors + diff --git a/src/test/ui/consts/const-eval/pub_const_err.rs b/src/test/ui/consts/const-eval/pub_const_err.rs index d882dad295b16..4ff140fee7a71 100644 --- a/src/test/ui/consts/const-eval/pub_const_err.rs +++ b/src/test/ui/consts/const-eval/pub_const_err.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(const_err)] #![crate_type = "lib"] diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.rs b/src/test/ui/consts/const-eval/pub_const_err_bin.rs index dee09b70d9334..7f1586336e721 100644 --- a/src/test/ui/consts/const-eval/pub_const_err_bin.rs +++ b/src/test/ui/consts/const-eval/pub_const_err_bin.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(const_err)] pub const Z: u32 = 0 - 1; diff --git a/src/test/ui/consts/const-eval/simple_with_undef.rs b/src/test/ui/consts/const-eval/simple_with_undef.rs index 61398f3a375c2..8a9f3fe974d91 100644 --- a/src/test/ui/consts/const-eval/simple_with_undef.rs +++ b/src/test/ui/consts/const-eval/simple_with_undef.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) const PARSE_BOOL: Option<&'static str> = None; static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42); diff --git a/src/test/ui/consts/const-eval/valid-const.rs b/src/test/ui/consts/const-eval/valid-const.rs index a195e12defcea..30bd47219239e 100644 --- a/src/test/ui/consts/const-eval/valid-const.rs +++ b/src/test/ui/consts/const-eval/valid-const.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Some constants that *are* valid #![feature(const_transmute)] diff --git a/src/test/ui/consts/const-eval/zst_operand_eval.rs b/src/test/ui/consts/const-eval/zst_operand_eval.rs index d837da1066daa..7edb6bd03dabf 100644 --- a/src/test/ui/consts/const-eval/zst_operand_eval.rs +++ b/src/test/ui/consts/const-eval/zst_operand_eval.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) static ASSERT: () = [()][!(std::mem::size_of::() == 4) as usize]; diff --git a/src/test/ui/consts/const-expr-addr-operator.rs b/src/test/ui/consts/const-expr-addr-operator.rs index dc9f292c2b8ad..37bf24c2fbed1 100644 --- a/src/test/ui/consts/const-expr-addr-operator.rs +++ b/src/test/ui/consts/const-expr-addr-operator.rs @@ -1,5 +1,5 @@ // Encountered while testing #44614. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub fn main() { // Constant of generic type (int) diff --git a/src/test/ui/consts/const-fn-destructuring-arg.rs b/src/test/ui/consts/const-fn-destructuring-arg.rs index dcf89f90e31da..d2c89cb54a0eb 100644 --- a/src/test/ui/consts/const-fn-destructuring-arg.rs +++ b/src/test/ui/consts/const-fn-destructuring-arg.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) const fn i((a, b): (u32, u32)) -> u32 { a + b diff --git a/src/test/ui/consts/const-nonzero.rs b/src/test/ui/consts/const-nonzero.rs index c06ab227f6463..6db3d1b3331fa 100644 --- a/src/test/ui/consts/const-nonzero.rs +++ b/src/test/ui/consts/const-nonzero.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::num::NonZeroU8; diff --git a/src/test/ui/consts/const-pattern-not-const-evaluable.rs b/src/test/ui/consts/const-pattern-not-const-evaluable.rs index 8dd78ca0ba495..dae5343fe3011 100644 --- a/src/test/ui/consts/const-pattern-not-const-evaluable.rs +++ b/src/test/ui/consts/const-pattern-not-const-evaluable.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(PartialEq, Eq)] enum Cake { diff --git a/src/test/ui/consts/const-validation-fail-55455.rs b/src/test/ui/consts/const-validation-fail-55455.rs index def4062339f96..583074888c9b6 100644 --- a/src/test/ui/consts/const-validation-fail-55455.rs +++ b/src/test/ui/consts/const-validation-fail-55455.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/issues/55454 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct This(T); diff --git a/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs b/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs index c7617c9c7ad03..d22c789609f4d 100644 --- a/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs +++ b/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:const_fn_lib.rs extern crate const_fn_lib; diff --git a/src/test/ui/consts/const_let_assign.rs b/src/test/ui/consts/const_let_assign.rs index 0b09b8469fd75..343fcb4859b37 100644 --- a/src/test/ui/consts/const_let_assign.rs +++ b/src/test/ui/consts/const_let_assign.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(i32); diff --git a/src/test/ui/consts/const_let_assign2.rs b/src/test/ui/consts/const_let_assign2.rs index 1c44237e49b7a..4787c1750d291 100644 --- a/src/test/ui/consts/const_let_assign2.rs +++ b/src/test/ui/consts/const_let_assign2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct AA { pub data: [u8; 10], diff --git a/src/test/ui/consts/const_let_eq_float.rs b/src/test/ui/consts/const_let_eq_float.rs index c48f54e567b2c..0c927a0484d9d 100644 --- a/src/test/ui/consts/const_let_eq_float.rs +++ b/src/test/ui/consts/const_let_eq_float.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_fn)] diff --git a/src/test/ui/consts/const_let_irrefutable.rs b/src/test/ui/consts/const_let_irrefutable.rs index 424a16f7ed39b..e889abf4abe4a 100644 --- a/src/test/ui/consts/const_let_irrefutable.rs +++ b/src/test/ui/consts/const_let_irrefutable.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/consts/drop_none.rs b/src/test/ui/consts/drop_none.rs index 86a197ffb993e..9d98d3be87464 100644 --- a/src/test/ui/consts/drop_none.rs +++ b/src/test/ui/consts/drop_none.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A; impl Drop for A { diff --git a/src/test/ui/consts/int_ptr_for_zst_slices.rs b/src/test/ui/consts/int_ptr_for_zst_slices.rs index afa2c6a5b9e1c..34dafd00d28dc 100644 --- a/src/test/ui/consts/int_ptr_for_zst_slices.rs +++ b/src/test/ui/consts/int_ptr_for_zst_slices.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_raw_ptr_deref)] diff --git a/src/test/ui/consts/invalid_promotion.rs b/src/test/ui/consts/invalid_promotion.rs index f98406e50e9ae..a31eaf40e0ede 100644 --- a/src/test/ui/consts/invalid_promotion.rs +++ b/src/test/ui/consts/invalid_promotion.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // note this was only reproducible with lib crates // compile-flags: --crate-type=lib diff --git a/src/test/ui/consts/issue-62045.rs b/src/test/ui/consts/issue-62045.rs index 9f41ed9a24523..efeb9fc551cc9 100644 --- a/src/test/ui/consts/issue-62045.rs +++ b/src/test/ui/consts/issue-62045.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { assert_eq!(&mut [0; 1][..], &mut []); diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs b/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs index 23bd73325472e..cb8f74186bd74 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::UnsafeCell; use std::sync::atomic::AtomicU32; diff --git a/src/test/ui/consts/promote_evaluation_unused_result.rs b/src/test/ui/consts/promote_evaluation_unused_result.rs index dc21b9fe8cd1b..4eda785bb8989 100644 --- a/src/test/ui/consts/promote_evaluation_unused_result.rs +++ b/src/test/ui/consts/promote_evaluation_unused_result.rs @@ -1,4 +1,4 @@ -//compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { diff --git a/src/test/ui/consts/promote_fn_calls.rs b/src/test/ui/consts/promote_fn_calls.rs index 6b6eea36361bf..8995aaacd8549 100644 --- a/src/test/ui/consts/promote_fn_calls.rs +++ b/src/test/ui/consts/promote_fn_calls.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:promotable_const_fn_lib.rs extern crate promotable_const_fn_lib; diff --git a/src/test/ui/consts/promote_fn_calls_std.rs b/src/test/ui/consts/promote_fn_calls_std.rs index d982f350208e2..bdb472f3a9cce 100644 --- a/src/test/ui/consts/promote_fn_calls_std.rs +++ b/src/test/ui/consts/promote_fn_calls_std.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let x: &'static u8 = &u8::max_value(); diff --git a/src/test/ui/consts/promoted-validation-55454.rs b/src/test/ui/consts/promoted-validation-55454.rs index 5e193b1b7de0b..23cae4fb57d57 100644 --- a/src/test/ui/consts/promoted-validation-55454.rs +++ b/src/test/ui/consts/promoted-validation-55454.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/issues/55454 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(PartialEq)] struct This(T); diff --git a/src/test/ui/consts/promoted_regression.rs b/src/test/ui/consts/promoted_regression.rs index 68b9a20ecf90b..d57036ae58f35 100644 --- a/src/test/ui/consts/promoted_regression.rs +++ b/src/test/ui/consts/promoted_regression.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _ = &[("", ""); 3]; diff --git a/src/test/ui/consts/static_mut_containing_mut_ref.rs b/src/test/ui/consts/static_mut_containing_mut_ref.rs index 27e1a111163b1..df09c76c5584d 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42]; diff --git a/src/test/ui/consts/std/slice.rs b/src/test/ui/consts/std/slice.rs index ad38105b6aa0e..f19defc64dd71 100644 --- a/src/test/ui/consts/std/slice.rs +++ b/src/test/ui/consts/std/slice.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Wrap(T); unsafe impl Send for Wrap {} diff --git a/src/test/ui/consts/underscore_const_names.rs b/src/test/ui/consts/underscore_const_names.rs index 8d57e5074f1b1..d0e625bf1997a 100644 --- a/src/test/ui/consts/underscore_const_names.rs +++ b/src/test/ui/consts/underscore_const_names.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused)] diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs index 16b05310b9fcb..508ff7e0ae8e6 100644 --- a/src/test/ui/consts/union_constant.rs +++ b/src/test/ui/consts/union_constant.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) union Uninit { _never_use: *const u8, diff --git a/src/test/ui/dead-code-tuple-struct-field.rs b/src/test/ui/dead-code-tuple-struct-field.rs index 496ce4fb378ae..92a67950986b0 100644 --- a/src/test/ui/dead-code-tuple-struct-field.rs +++ b/src/test/ui/dead-code-tuple-struct-field.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(dead_code)] diff --git a/src/test/ui/deprecation/atomic_initializers.fixed b/src/test/ui/deprecation/atomic_initializers.fixed index dee1d979cff1d..363bda75f1695 100644 --- a/src/test/ui/deprecation/atomic_initializers.fixed +++ b/src/test/ui/deprecation/atomic_initializers.fixed @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[allow(deprecated, unused_imports)] use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; diff --git a/src/test/ui/deprecation/atomic_initializers.rs b/src/test/ui/deprecation/atomic_initializers.rs index b9e25e817bce4..00c5f7b0b1257 100644 --- a/src/test/ui/deprecation/atomic_initializers.rs +++ b/src/test/ui/deprecation/atomic_initializers.rs @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[allow(deprecated, unused_imports)] use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; diff --git a/src/test/ui/deprecation/derive_on_deprecated.rs b/src/test/ui/deprecation/derive_on_deprecated.rs index 4980a7f5aa31c..ed4055ecdd38c 100644 --- a/src/test/ui/deprecation/derive_on_deprecated.rs +++ b/src/test/ui/deprecation/derive_on_deprecated.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(deprecated)] diff --git a/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs index 235146bad9c85..3fd4346646756 100644 --- a/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs +++ b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![forbid(deprecated)] diff --git a/src/test/ui/derive-uninhabited-enum-38885.rs b/src/test/ui/derive-uninhabited-enum-38885.rs index b314eacc92e0e..2c4d64e4e6063 100644 --- a/src/test/ui/derive-uninhabited-enum-38885.rs +++ b/src/test/ui/derive-uninhabited-enum-38885.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Wunused // ensure there are no special warnings about uninhabited types diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs index f535791d7fbe4..cf14aef7900a7 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Under the 2015 edition with the keyword_idents lint, `dyn` is // not entirely acceptable as an identifier. diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs index 27e490558689f..0d85b87dee5a1 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Under the 2015 edition with the keyword_idents lint, `dyn` is // not entirely acceptable as an identifier. diff --git a/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs index 8cef5c2b34947..2a8b6b24831c0 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs +++ b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs @@ -1,7 +1,7 @@ // Under the 2015 edition without the keyword_idents lint, `dyn` is // entirely acceptable as an identifier. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(non_camel_case_types)] diff --git a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs index ff3830d61755a..2718e89a3f214 100644 --- a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs +++ b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#56327: Some occurrences of `dyn` within a macro are // not instances of identifiers, and thus should *not* be caught by the diff --git a/src/test/ui/editions/edition-extern-crate-allowed.rs b/src/test/ui/editions/edition-extern-crate-allowed.rs index 6361fff6ff43c..93fe69e0af217 100644 --- a/src/test/ui/editions/edition-extern-crate-allowed.rs +++ b/src/test/ui/editions/edition-extern-crate-allowed.rs @@ -1,6 +1,6 @@ // aux-build:edition-extern-crate-allowed.rs // edition:2015 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_idioms)] diff --git a/src/test/ui/editions/edition-feature-ok.rs b/src/test/ui/editions/edition-feature-ok.rs index c2468df49398a..126421326949b 100644 --- a/src/test/ui/editions/edition-feature-ok.rs +++ b/src/test/ui/editions/edition-feature-ok.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] diff --git a/src/test/ui/editions/edition-feature-redundant.rs b/src/test/ui/editions/edition-feature-redundant.rs index 87a2a22105f4e..4309a777d33f7 100644 --- a/src/test/ui/editions/edition-feature-redundant.rs +++ b/src/test/ui/editions/edition-feature-redundant.rs @@ -1,5 +1,5 @@ // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] //~^ WARN the feature `rust_2018_preview` is included in the Rust 2018 edition diff --git a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs index 940b0c3c63db0..310bff21d1851 100644 --- a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs +++ b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags:--extern edition_imports_2015 // aux-build:edition-imports-2015.rs diff --git a/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs b/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs index c3757ab193485..9c3beb1ce58c1 100644 --- a/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs +++ b/src/test/ui/editions/edition-keywords-2015-2015-expansion.rs @@ -1,6 +1,6 @@ // edition:2015 // aux-build:edition-kw-macro-2015.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(keyword_idents)] diff --git a/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs b/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs index 6a30c49821904..619e6424db441 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs +++ b/src/test/ui/editions/edition-keywords-2018-2015-expansion.rs @@ -1,6 +1,6 @@ // edition:2018 // aux-build:edition-kw-macro-2015.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(keyword_idents)] diff --git a/src/test/ui/emit-artifact-notifications.rs b/src/test/ui/emit-artifact-notifications.rs index c2c930c8b1bae..d309485f05311 100644 --- a/src/test/ui/emit-artifact-notifications.rs +++ b/src/test/ui/emit-artifact-notifications.rs @@ -1,5 +1,7 @@ // compile-flags:--emit=metadata --error-format=json -Z emit-artifact-notifications -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. // A very basic test for the emission of artifact notifications in JSON output. diff --git a/src/test/ui/error-codes/E0705.rs b/src/test/ui/error-codes/E0705.rs index cc2b8f64d9fa8..4e32ef355606c 100644 --- a/src/test/ui/error-codes/E0705.rs +++ b/src/test/ui/error-codes/E0705.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This is a stub feature that doesn't control anything, so to make tidy happy, // gate-test-test_2018_feature diff --git a/src/test/ui/existential_types/bound_reduction.rs b/src/test/ui/existential_types/bound_reduction.rs index c1c0c60d59ee0..46bc17293bc90 100644 --- a/src/test/ui/existential_types/bound_reduction.rs +++ b/src/test/ui/existential_types/bound_reduction.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] diff --git a/src/test/ui/existential_types/cross_crate_ice.rs b/src/test/ui/existential_types/cross_crate_ice.rs index c5d5ca916a48a..c30608176aada 100644 --- a/src/test/ui/existential_types/cross_crate_ice.rs +++ b/src/test/ui/existential_types/cross_crate_ice.rs @@ -1,5 +1,5 @@ // aux-build:cross_crate_ice.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate cross_crate_ice; diff --git a/src/test/ui/existential_types/cross_crate_ice2.rs b/src/test/ui/existential_types/cross_crate_ice2.rs index a0f3933ce33b2..3a7e490260f3f 100644 --- a/src/test/ui/existential_types/cross_crate_ice2.rs +++ b/src/test/ui/existential_types/cross_crate_ice2.rs @@ -1,5 +1,5 @@ // aux-build:cross_crate_ice2.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate cross_crate_ice2; diff --git a/src/test/ui/existential_types/different_defining_uses_never_type2.rs b/src/test/ui/existential_types/different_defining_uses_never_type2.rs index 2953f1745ee5b..0f02cfaad7e06 100644 --- a/src/test/ui/existential_types/different_defining_uses_never_type2.rs +++ b/src/test/ui/existential_types/different_defining_uses_never_type2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(existential_type)] diff --git a/src/test/ui/existential_types/existential-associated-type.rs b/src/test/ui/existential_types/existential-associated-type.rs index 299ae91b84386..bfb91f68ffdd1 100644 --- a/src/test/ui/existential_types/existential-associated-type.rs +++ b/src/test/ui/existential_types/existential-associated-type.rs @@ -1,5 +1,5 @@ #![feature(existential_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy; diff --git a/src/test/ui/existential_types/generic_duplicate_param_use10.rs b/src/test/ui/existential_types/generic_duplicate_param_use10.rs index 10f2c630582fc..0d9c7cdfe71c3 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use10.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use10.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(existential_type)] use std::fmt::Debug; diff --git a/src/test/ui/existential_types/generic_duplicate_param_use7.rs b/src/test/ui/existential_types/generic_duplicate_param_use7.rs index 5d8d05c308780..56e1528c213ef 100644 --- a/src/test/ui/existential_types/generic_duplicate_param_use7.rs +++ b/src/test/ui/existential_types/generic_duplicate_param_use7.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(existential_type)] use std::fmt::Debug; diff --git a/src/test/ui/existential_types/generic_lifetime_param.rs b/src/test/ui/existential_types/generic_lifetime_param.rs index a8bb0229f0e8d..1ea01f17b70a3 100644 --- a/src/test/ui/existential_types/generic_lifetime_param.rs +++ b/src/test/ui/existential_types/generic_lifetime_param.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(existential_type)] diff --git a/src/test/ui/existential_types/nested_existential_types.rs b/src/test/ui/existential_types/nested_existential_types.rs index 6d2a12da7e443..de52e88bae209 100644 --- a/src/test/ui/existential_types/nested_existential_types.rs +++ b/src/test/ui/existential_types/nested_existential_types.rs @@ -1,5 +1,5 @@ #![feature(existential_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod my_mod { use std::fmt::Debug; diff --git a/src/test/ui/existential_types/private_unused.rs b/src/test/ui/existential_types/private_unused.rs index 736d812bc0aff..92268f1861d63 100644 --- a/src/test/ui/existential_types/private_unused.rs +++ b/src/test/ui/existential_types/private_unused.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[deny(warnings)] diff --git a/src/test/ui/explain.rs b/src/test/ui/explain.rs index 3622ba7764530..28973d6756482 100644 --- a/src/test/ui/explain.rs +++ b/src/test/ui/explain.rs @@ -1,2 +1,2 @@ // compile-flags: --explain E0591 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) diff --git a/src/test/ui/extern-prelude.rs b/src/test/ui/extern-prelude.rs index 0e52f2c5158d4..50fed6034aa02 100644 --- a/src/test/ui/extern-prelude.rs +++ b/src/test/ui/extern-prelude.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--extern extern_prelude --extern Vec // aux-build:extern-prelude.rs // aux-build:extern-prelude-vec.rs diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs index 98ca3444c91bd..dab946bb81810 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs @@ -3,7 +3,7 @@ // `#![macro_escape]` is incompatible with crate-level `#![macro_use]` // already present in issue-43106-gating-of-builtin-attrs. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![macro_escape] //~^ WARN macro_escape is a deprecated synonym for macro_use diff --git a/src/test/ui/feature-gates/feature-gate-const-indexing.rs b/src/test/ui/feature-gates/feature-gate-const-indexing.rs index 4df1c7d6ed237..2b1067b34891c 100644 --- a/src/test/ui/feature-gates/feature-gate-const-indexing.rs +++ b/src/test/ui/feature-gates/feature-gate-const-indexing.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47]; diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.rs b/src/test/ui/feature-gates/feature-gate-member-constraints.rs new file mode 100644 index 0000000000000..293a93352e641 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-member-constraints.rs @@ -0,0 +1,9 @@ +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T {} + +fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { + //~^ ERROR ambiguous lifetime bound + (x, y) +} + +fn main() { } diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.stderr b/src/test/ui/feature-gates/feature-gate-member-constraints.stderr new file mode 100644 index 0000000000000..3745d5e1c59d6 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-member-constraints.stderr @@ -0,0 +1,10 @@ +error: ambiguous lifetime bound in `impl Trait` + --> $DIR/feature-gate-member-constraints.rs:4:43 + | +LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { + | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other + | + = help: add #![feature(member_constraints)] to the crate attributes to enable + +error: aborting due to previous error + diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr index fe3c1e0afdd6b..03bf933cd084d 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr @@ -4,7 +4,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [1, 2, ..] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -13,7 +13,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [1, .., 5] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -22,7 +22,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [.., 4, 5] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -31,7 +31,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [ xs.., 4, 5 ] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -40,7 +40,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [ 1, xs.., 5 ] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized @@ -49,7 +49,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized LL | [ 1, 2, xs.. ] => {} | ^^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/23121 + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable error: aborting due to 6 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs deleted file mode 100644 index c7d3304a128dd..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs +++ /dev/null @@ -1,19 +0,0 @@ -enum Foo { - Bar(i32), - Baz { i: i32 }, -} - -type Alias = Foo; - -fn main() { - let t = Alias::Bar(0); - //~^ ERROR enum variants on type aliases are experimental - let t = Alias::Baz { i: 0 }; - //~^ ERROR enum variants on type aliases are experimental - match t { - Alias::Bar(_i) => {} - //~^ ERROR enum variants on type aliases are experimental - Alias::Baz { i: _i } => {} - //~^ ERROR enum variants on type aliases are experimental - } -} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr deleted file mode 100644 index 43535af7c69d8..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:9:13 - | -LL | let t = Alias::Bar(0); - | ^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:11:13 - | -LL | let t = Alias::Baz { i: 0 }; - | ^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:14:9 - | -LL | Alias::Bar(_i) => {} - | ^^^^^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:16:9 - | -LL | Alias::Baz { i: _i } => {} - | ^^^^^^^^^^ - | - = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs index 8519cf741a320..e411854661603 100644 --- a/src/test/ui/fn_must_use.rs +++ b/src/test/ui/fn_must_use.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/generator/issue-53548-1.rs b/src/test/ui/generator/issue-53548-1.rs index df11800731c72..395456ce7c65b 100644 --- a/src/test/ui/generator/issue-53548-1.rs +++ b/src/test/ui/generator/issue-53548-1.rs @@ -2,7 +2,7 @@ // but which encountered the same ICE/error. See `issue-53548.rs` // for details. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::RefCell; use std::rc::Rc; diff --git a/src/test/ui/generator/issue-53548.rs b/src/test/ui/generator/issue-53548.rs index 73a2bcdd55538..8136c65923b79 100644 --- a/src/test/ui/generator/issue-53548.rs +++ b/src/test/ui/generator/issue-53548.rs @@ -15,7 +15,7 @@ // also analogous to what we would do for higher-ranked regions // appearing within the trait in other positions). // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(generators)] diff --git a/src/test/ui/generic/generic-param-attrs.rs b/src/test/ui/generic/generic-param-attrs.rs index 601d2a9e0a31f..39a600339aa90 100644 --- a/src/test/ui/generic/generic-param-attrs.rs +++ b/src/test/ui/generic/generic-param-attrs.rs @@ -6,7 +6,7 @@ // using `rustc_attrs` feature. There is a separate compile-fail/ test // ensuring that the attribute feature-gating works in this context.) -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/hello_world/main.rs b/src/test/ui/hello_world/main.rs index f790af64b4df0..22ce47414b28d 100644 --- a/src/test/ui/hello_world/main.rs +++ b/src/test/ui/hello_world/main.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that compiling hello world succeeds with no output of any kind. diff --git a/src/test/ui/hygiene/dollar-crate-modern.rs b/src/test/ui/hygiene/dollar-crate-modern.rs index 380ad20486ec4..9c25e138d2c28 100644 --- a/src/test/ui/hygiene/dollar-crate-modern.rs +++ b/src/test/ui/hygiene/dollar-crate-modern.rs @@ -1,6 +1,6 @@ // Make sure `$crate` and `crate` work in for basic cases of nested macros. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:intercrate.rs #![feature(decl_macro, crate_in_paths)] diff --git a/src/test/ui/hygiene/local_inner_macros.rs b/src/test/ui/hygiene/local_inner_macros.rs index f4c1a931f68ad..f361e3d5d4963 100644 --- a/src/test/ui/hygiene/local_inner_macros.rs +++ b/src/test/ui/hygiene/local_inner_macros.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:local_inner_macros.rs extern crate local_inner_macros; diff --git a/src/test/ui/hygiene/transparent-basic.rs b/src/test/ui/hygiene/transparent-basic.rs index 0a86234fdba1f..23ee558cc17b0 100644 --- a/src/test/ui/hygiene/transparent-basic.rs +++ b/src/test/ui/hygiene/transparent-basic.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:transparent-basic.rs #![feature(decl_macro, rustc_attrs)] diff --git a/src/test/ui/if/if-let.rs b/src/test/ui/if/if-let.rs index 741685fe9b649..3447f358d85f1 100644 --- a/src/test/ui/if/if-let.rs +++ b/src/test/ui/if/if-let.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn macros() { macro_rules! foo{ diff --git a/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs b/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs index 20d778d20aef9..9d7b2f2d088cc 100644 --- a/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs +++ b/src/test/ui/impl-header-lifetime-elision/inherent-impl.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Foo<'a>(&'a u8); diff --git a/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs b/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs index 26bd435cbac96..130de9ccf621d 100644 --- a/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs +++ b/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs @@ -1,5 +1,5 @@ #![feature(existential_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy(U); diff --git a/src/test/ui/impl-trait/associated-existential-type-trivial.rs b/src/test/ui/impl-trait/associated-existential-type-trivial.rs index cc974ffea7bbc..0e83b4084b6ac 100644 --- a/src/test/ui/impl-trait/associated-existential-type-trivial.rs +++ b/src/test/ui/impl-trait/associated-existential-type-trivial.rs @@ -1,5 +1,5 @@ #![feature(existential_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy; diff --git a/src/test/ui/impl-trait/associated-existential-type.rs b/src/test/ui/impl-trait/associated-existential-type.rs index 38511bd062c85..58966aefe1c32 100644 --- a/src/test/ui/impl-trait/associated-existential-type.rs +++ b/src/test/ui/impl-trait/associated-existential-type.rs @@ -1,5 +1,5 @@ #![feature(existential_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Bar {} struct Dummy; diff --git a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs index 90a7519074b53..7ae1ac4f5767c 100644 --- a/src/test/ui/impl-trait/can-return-unconstrained-closure.rs +++ b/src/test/ui/impl-trait/can-return-unconstrained-closure.rs @@ -10,7 +10,7 @@ // concrete type against the bound, which forces the return type to be // `&'static i32` here. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn make_identity() -> impl Sized { |x: &'static i32| x diff --git a/src/test/ui/impl-trait/deprecated_annotation.rs b/src/test/ui/impl-trait/deprecated_annotation.rs index dd9f5fd4647e0..f76724c8ab11d 100644 --- a/src/test/ui/impl-trait/deprecated_annotation.rs +++ b/src/test/ui/impl-trait/deprecated_annotation.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(warnings)] diff --git a/src/test/ui/impl-trait/existential-minimal.rs b/src/test/ui/impl-trait/existential-minimal.rs index c93c6a499bc75..6d3c0692970dc 100644 --- a/src/test/ui/impl-trait/existential-minimal.rs +++ b/src/test/ui/impl-trait/existential-minimal.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/impl-trait/existential_type_in_fn_body.rs b/src/test/ui/impl-trait/existential_type_in_fn_body.rs index b29ae064b76c4..32fc4a97ef44d 100644 --- a/src/test/ui/impl-trait/existential_type_in_fn_body.rs +++ b/src/test/ui/impl-trait/existential_type_in_fn_body.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(existential_type)] diff --git a/src/test/ui/impl-trait/issues/issue-42479.rs b/src/test/ui/impl-trait/issues/issue-42479.rs index 2da15ac5b6e7e..7d69cd0a3038f 100644 --- a/src/test/ui/impl-trait/issues/issue-42479.rs +++ b/src/test/ui/impl-trait/issues/issue-42479.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::iter::once; diff --git a/src/test/ui/impl-trait/issues/issue-49376.rs b/src/test/ui/impl-trait/issues/issue-49376.rs index 13671b8dbf448..12e69b16adf0b 100644 --- a/src/test/ui/impl-trait/issues/issue-49376.rs +++ b/src/test/ui/impl-trait/issues/issue-49376.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests for nested self-reference which caused a stack overflow. diff --git a/src/test/ui/impl-trait/issues/issue-52128.rs b/src/test/ui/impl-trait/issues/issue-52128.rs index eb4456a0d592e..ac26c10e55d83 100644 --- a/src/test/ui/impl-trait/issues/issue-52128.rs +++ b/src/test/ui/impl-trait/issues/issue-52128.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(warnings)] diff --git a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs index 50646edd61a85..0c07101bb7ba0 100644 --- a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs +++ b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs @@ -1,7 +1,7 @@ // This used to ICE because it creates an `impl Trait` that captures a // hidden empty region. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn server() -> impl FilterBase2 { segment2(|| { loop { } }).map2(|| "") diff --git a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs index 11f1a392239dc..ed066ce19243e 100644 --- a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs +++ b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs @@ -5,7 +5,7 @@ // opaque type. As all regions are now required to outlive the bound in an // opaque type we avoid the issue here. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct A(F); diff --git a/src/test/ui/impl-trait/multiple-lifetimes.rs b/src/test/ui/impl-trait/multiple-lifetimes.rs index 8346542135bec..92e5ea2f49df8 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes.rs @@ -1,5 +1,5 @@ // Test that multiple liftimes are allowed in impl trait types. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait X<'x>: Sized {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs new file mode 100644 index 0000000000000..61e858ee02d44 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs @@ -0,0 +1,22 @@ +// compile-flags:-Zborrowck=mir + +#![feature(member_constraints)] +#![feature(existential_type)] + +#[derive(Clone)] +struct CopyIfEq(T, U); + +impl Copy for CopyIfEq {} + +existential type E<'a, 'b>: Sized; + +fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { + //~^ ERROR lifetime may not live long enough + let v = CopyIfEq::<*mut _, *mut _>(&mut {x}, &mut y); + let u = v; + let _: *mut &'a i32 = u.1; + unsafe { let _: &'b i32 = *u.0; } + u.0 +} + +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr new file mode 100644 index 0000000000000..b59dfbe9f2ada --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> $DIR/error-handling.rs:13:56 + | +LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { + | -- lifetime `'a` defined here ^^^^^^^^^ opaque type requires that `'a` must outlive `'static` +help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint + | +LL | existential type E<'a, 'b>: Sized; + 'a + | + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs new file mode 100644 index 0000000000000..2da3886bb552b --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs @@ -0,0 +1,54 @@ +// edition:2018 +// run-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Invert<'a> <: Invert<'b>` if `'b: 'a`, unlike most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Invert<'a>(fn(&'a u8)); + +fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> +where + 'c: 'a, + 'c: 'b, + 'd: 'c, +{ + // Representing the where clauses as a graph, where `A: B` is an + // edge `B -> A`: + // + // ``` + // 'a -> 'c -> 'd + // ^ + // | + // 'b + // ``` + // + // Meanwhile we return a value &'0 u8 where we have the constraints: + // + // ``` + // '0: 'a + // '0: 'b + // '0 in ['d, 'e] + // ``` + // + // Here, ignoring the "in" constraint, the minimal choice for `'0` + // is `'c`, but that is not in the "in set". Still, that reduces + // the range of options in the "in set" to just `'d` (`'e: 'c` + // does not hold). + let p = if condition() { a } else { b }; + p +} + +fn condition() -> bool { + true +} + +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr new file mode 100644 index 0000000000000..4de872e8441ef --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr @@ -0,0 +1,19 @@ +warning[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/inverse-bounds.rs:16:70 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> + | ^^^^^^^^^^^^^^^^^^ + | + = note: hidden type `Invert<'_>` captures lifetime '_#8r + = warning: this error has been downgraded to a warning for backwards compatibility with previous releases + = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future + = note: for more information, try `rustc --explain E0729` + +warning: the feature `pin` has been stable since 1.33.0 and no longer requires an attribute to enable + --> $DIR/inverse-bounds.rs:4:60 + | +LL | #![feature(arbitrary_self_types, async_await, await_macro, pin)] + | ^^^ + | + = note: #[warn(stable_features)] on by default + diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs new file mode 100644 index 0000000000000..5f484773405cd --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs @@ -0,0 +1,29 @@ +// edition:2018 +// compile-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +// Test case where we have elision in the impl trait and we have to +// pick the right region. + +// Ultimately `Trait<'x, 'static>`. +fn upper_bounds1(a: &u8) -> impl Trait<'_, 'static> { + (a, a) +} + +// Ultimately `Trait<'x, 'x>`, so not really multiple bounds. +fn upper_bounds2(a: &u8) -> impl Trait<'_, '_> { + (a, a) +} + +// Kind of a weird annoying case. +fn upper_bounds3<'b>(a: &u8) -> impl Trait<'_, 'b> { + (a, a) +} + +fn main() { } diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs new file mode 100644 index 0000000000000..c17ae6f0519bf --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs @@ -0,0 +1,32 @@ +// edition:2018 +// compile-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] +#![feature(existential_type)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +// Here we wind up selecting `'a` and `'b` in the hidden type because +// those are the types that appear in the original values. + +existential type Foo<'a, 'b>: Trait<'a, 'b>; + +fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> { + // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['a, 'b] + // '1 in ['a, 'b] + // ``` + // + // We use the fact that `'a: 0'` must hold (combined with the in + // constraint) to determine that `'0 = 'a` must be the answer. + (a, b) +} + +fn main() { } diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs new file mode 100644 index 0000000000000..31891ef15c754 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs @@ -0,0 +1,29 @@ +// edition:2018 +// compile-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +// Here we wind up selecting `'a` and `'b` in the hidden type because +// those are the types that appear in the original values. + +fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['a, 'b] + // '1 in ['a, 'b] + // ``` + // + // We use the fact that `'a: 0'` must hold (combined with the in + // constraint) to determine that `'0 = 'a` must be the answer. + (a, b) +} + +fn main() { } diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs new file mode 100644 index 0000000000000..29c997085d8f4 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs @@ -0,0 +1,46 @@ +// edition:2018 +// compile-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Ordinary<'a>(&'a u8); + +// Here we wind up selecting `'e` in the hidden type because +// we need something outlived by both `'a` and `'b` and only `'e` applies. + +fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> +where + 'a: 'e, + 'b: 'e, + 'a: 'd, +{ + // We return a value: + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['d, 'e] + // ``` + // + // but we don't have it. + // + // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b. + let p = if condition() { a } else { b }; + p +} + +fn condition() -> bool { + true +} + +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr new file mode 100644 index 0000000000000..a255c48ec6ef1 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr @@ -0,0 +1,9 @@ +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ordinary-bounds-unrelated.rs:18:74 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs new file mode 100644 index 0000000000000..db1641b0140b9 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -0,0 +1,38 @@ +// edition:2018 + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Ordinary<'a>(&'a u8); + +// Here we get an error because none of our choices (either `'d` nor `'e`) are outlived +// by both `'a` and `'b`. + +fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> +//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds +where + 'a: 'e, + 'b: 'd, +{ + // Hidden type `Ordinary<'0>` with constraints: + // + // ``` + // 'a: '0 + // 'b: '0 + // 'a in ['d, 'e] + // ``` + if condition() { a } else { b } +} + +fn condition() -> bool { + true +} + +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr new file mode 100644 index 0000000000000..cd2d46ac18218 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -0,0 +1,21 @@ +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ordinary-bounds-unrelated.rs:18:74 + | +LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + | ^^^^^^^^^^^^^^^^^^ + | +note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 23:1 + --> $DIR/ordinary-bounds-unrelated.rs:23:1 + | +LL | / { +LL | | // Hidden type `Ordinary<'0>` with constraints: +LL | | // +LL | | // ``` +... | +LL | | if condition() { a } else { b } +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr new file mode 100644 index 0000000000000..af42ed1c5c15a --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr @@ -0,0 +1,9 @@ +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ordinary-bounds-unsuited.rs:20:62 + | +LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs new file mode 100644 index 0000000000000..7f9c92f15a2f9 --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -0,0 +1,41 @@ +// edition:2018 + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Ordinary<'a>(&'a u8); + +// Here we need something outlived by `'a` *and* outlived by `'b`, but +// we can only name `'a` and `'b` (and neither suits). So we get an +// error. Somewhat unfortunate, though, since the caller would have to +// consider the loans for both `'a` and `'b` alive. + +fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds +{ + // We return a value: + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['a, 'b] + // ``` + // + // but we don't have it. + // + // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b. + if condition() { a } else { b } +} + +fn condition() -> bool { + true +} + +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr new file mode 100644 index 0000000000000..59ce93fa78b6b --- /dev/null +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -0,0 +1,21 @@ +error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/ordinary-bounds-unsuited.rs:20:62 + | +LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + | ^^^^^^^^^^^^^^^^^^ + | +note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 22:1 + --> $DIR/ordinary-bounds-unsuited.rs:22:1 + | +LL | / { +LL | | // We return a value: +LL | | // +LL | | // ``` +... | +LL | | if condition() { a } else { b } +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.rs b/src/test/ui/impl-trait/needs_least_region_or_bound.rs index 2a5b365559e77..52475f65a8353 100644 --- a/src/test/ui/impl-trait/needs_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/needs_least_region_or_bound.rs @@ -1,10 +1,24 @@ +// run-pass + +#![feature(member_constraints)] + use std::fmt::Debug; trait MultiRegionTrait<'a, 'b> {} impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {} fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { -//~^ ERROR ambiguous lifetime bound + // Here we have a constraint that: + // + // (x, y) has type (&'0 u32, &'1 u32) + // + // where + // + // 'a: '0 + // + // then we require that `('0 u32, &'1 u32): MultiRegionTrait<'a, + // 'b>`, which winds up imposing a requirement that `'0 = 'a` and + // `'1 = 'b`. (x, y) } diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.stderr b/src/test/ui/impl-trait/needs_least_region_or_bound.stderr deleted file mode 100644 index f1b4d9c58f39f..0000000000000 --- a/src/test/ui/impl-trait/needs_least_region_or_bound.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/needs_least_region_or_bound.rs:6:55 - | -LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - -error: aborting due to previous error - diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs index 9c9397999ff67..244293be72636 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that `extern crate self;` is accepted // syntactically as an item for use in a macro. diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs index 6f6343a614886..9cebb622eeda3 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate self as foo; diff --git a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs index cf91a9714ade0..30d87f90b30a5 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 macro_rules! define_iso { () => { diff --git a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs index 6117e5f6f3cd7..cfae08fccaa4b 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--cfg my_feature #![no_std] diff --git a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs index bb4cf6ca99c75..c87d58f63e257 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:two_macros.rs extern crate two_macros; diff --git a/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs index c5adeaf17fa92..9e69a27d7c4ce 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:two_macros.rs extern crate two_macros as core; diff --git a/src/test/ui/imports/gensymed.rs b/src/test/ui/imports/gensymed.rs index 317441079ff87..613ccc0b24234 100644 --- a/src/test/ui/imports/gensymed.rs +++ b/src/test/ui/imports/gensymed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // aux-build:gensymed.rs diff --git a/src/test/ui/imports/issue-53140.rs b/src/test/ui/imports/issue-53140.rs index dbfba2c94339a..1854ddf96b8db 100644 --- a/src/test/ui/imports/issue-53140.rs +++ b/src/test/ui/imports/issue-53140.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod m { pub struct S(u8); diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs index 95316777fabf6..8cb602d868cd4 100644 --- a/src/test/ui/imports/issue-55811.rs +++ b/src/test/ui/imports/issue-55811.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:issue-55811.rs extern crate issue_55811; diff --git a/src/test/ui/imports/issue-56263.rs b/src/test/ui/imports/issue-56263.rs index 4113d4390c3c9..4763ae4be9995 100644 --- a/src/test/ui/imports/issue-56263.rs +++ b/src/test/ui/imports/issue-56263.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 use ::std; diff --git a/src/test/ui/imports/local-modularized-tricky-pass.rs b/src/test/ui/imports/local-modularized-tricky-pass.rs index 59aac952b9299..b52ddaf89549e 100644 --- a/src/test/ui/imports/local-modularized-tricky-pass.rs +++ b/src/test/ui/imports/local-modularized-tricky-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! define_exported { () => { #[macro_export] diff --git a/src/test/ui/imports/local-modularized.rs b/src/test/ui/imports/local-modularized.rs index a073fe26eb619..8eeb1cf07bb1a 100644 --- a/src/test/ui/imports/local-modularized.rs +++ b/src/test/ui/imports/local-modularized.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[macro_export(local_inner_macros)] macro_rules! dollar_crate_exported { diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs index 513b15ed088d8..a90b268db8c95 100644 --- a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs +++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // tests that the following code compiles, but produces a future-compatibility warning diff --git a/src/test/ui/issue-53912.rs b/src/test/ui/issue-53912.rs index d2347c3077cf3..4718aea0429c2 100644 --- a/src/test/ui/issue-53912.rs +++ b/src/test/ui/issue-53912.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the // reproduction compiles successfully and doesn't segfault, whereas that test just checks that the diff --git a/src/test/ui/issues/issue-10396.rs b/src/test/ui/issues/issue-10396.rs index d8e9aec81806e..0781e5e3ed990 100644 --- a/src/test/ui/issues/issue-10396.rs +++ b/src/test/ui/issues/issue-10396.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Debug)] enum Foo<'s> { diff --git a/src/test/ui/issues/issue-10456.rs b/src/test/ui/issues/issue-10456.rs index 4b548362f4aff..7eac095de5da4 100644 --- a/src/test/ui/issues/issue-10456.rs +++ b/src/test/ui/issues/issue-10456.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub struct Foo; diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index ceb44ecf7f583..111078abb3700 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -11,13 +11,9 @@ macro_rules! foo{ pub fn main() { foo!(); - assert!({one! two()}); - //~^ ERROR macros that expand to items - //~| ERROR cannot find macro `one!` in this scope - //~| ERROR mismatched types + assert!({one! two()}); //~ ERROR expected open delimiter // regardless of whether nested macro_rules works, the following should at // least throw a conventional error. - assert!({one! two}); - //~^ ERROR expected `(` or `{`, found `}` + assert!({one! two}); //~ ERROR expected open delimiter } diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index 584cdf43a8f4b..73f948107f185 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,38 +1,14 @@ -error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-10536.rs:14:22 +error: expected open delimiter + --> $DIR/issue-10536.rs:14:19 | LL | assert!({one! two()}); - | ^^ -help: change the delimiters to curly braces - | -LL | assert!({one! two {}}); - | ^^ -help: add a semicolon - | -LL | assert!({one! two();}); - | ^ + | ^^^ expected open delimiter -error: expected `(` or `{`, found `}` - --> $DIR/issue-10536.rs:21:22 +error: expected open delimiter + --> $DIR/issue-10536.rs:18:19 | LL | assert!({one! two}); - | ^ expected `(` or `{` - -error: cannot find macro `one!` in this scope - --> $DIR/issue-10536.rs:14:14 - | -LL | assert!({one! two()}); - | ^^^ - -error[E0308]: mismatched types - --> $DIR/issue-10536.rs:14:13 - | -LL | assert!({one! two()}); - | ^^^^^^^^^^^^ expected bool, found () - | - = note: expected type `bool` - found type `()` + | ^^^ expected open delimiter -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-10763.rs b/src/test/ui/issues/issue-10763.rs index f2d4c5b47d782..091a7c5296342 100644 --- a/src/test/ui/issues/issue-10763.rs +++ b/src/test/ui/issues/issue-10763.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-10853.rs b/src/test/ui/issues/issue-10853.rs index 0b74eaddcdd3a..c9de39feda691 100644 --- a/src/test/ui/issues/issue-10853.rs +++ b/src/test/ui/issues/issue-10853.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-10902.rs b/src/test/ui/issues/issue-10902.rs index 5e7f8ed7fd5d2..d53ce9a1db86f 100644 --- a/src/test/ui/issues/issue-10902.rs +++ b/src/test/ui/issues/issue-10902.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-11384.rs b/src/test/ui/issues/issue-11384.rs index 59d85b175cf69..443c2be08bbd0 100644 --- a/src/test/ui/issues/issue-11384.rs +++ b/src/test/ui/issues/issue-11384.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Common { fn dummy(&self) { } } diff --git a/src/test/ui/issues/issue-11592.rs b/src/test/ui/issues/issue-11592.rs index e2028bd56f9bf..0298f83baf81c 100644 --- a/src/test/ui/issues/issue-11592.rs +++ b/src/test/ui/issues/issue-11592.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! Ensure the private trait Bar isn't complained about. #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-11612.rs b/src/test/ui/issues/issue-11612.rs index fd4fb2443cbe7..553648a5ebc2e 100644 --- a/src/test/ui/issues/issue-11612.rs +++ b/src/test/ui/issues/issue-11612.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // #11612 // We weren't updating the auto adjustments with all the resolved diff --git a/src/test/ui/issues/issue-11869.rs b/src/test/ui/issues/issue-11869.rs index e62879f1f29ea..a44094bfb2391 100644 --- a/src/test/ui/issues/issue-11869.rs +++ b/src/test/ui/issues/issue-11869.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs index 84a14a8c09be6..63b5a4dd1b31a 100644 --- a/src/test/ui/issues/issue-1251.rs +++ b/src/test/ui/issues/issue-1251.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_attributes)] #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-12729.rs b/src/test/ui/issues/issue-12729.rs index c2572c78280eb..67c1bdc32ede9 100644 --- a/src/test/ui/issues/issue-12729.rs +++ b/src/test/ui/issues/issue-12729.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-13105.rs b/src/test/ui/issues/issue-13105.rs index 0e118043d5564..2410e2f136704 100644 --- a/src/test/ui/issues/issue-13105.rs +++ b/src/test/ui/issues/issue-13105.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/ui/issues/issue-13167.rs b/src/test/ui/issues/issue-13167.rs index dcc25a446fad6..e04faabb7e8e0 100644 --- a/src/test/ui/issues/issue-13167.rs +++ b/src/test/ui/issues/issue-13167.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 use std::slice; diff --git a/src/test/ui/issues/issue-13214.rs b/src/test/ui/issues/issue-13214.rs index af2d95c5e4286..0015169b11798 100644 --- a/src/test/ui/issues/issue-13214.rs +++ b/src/test/ui/issues/issue-13214.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // defining static with struct that contains enum // with &'static str variant used to cause ICE diff --git a/src/test/ui/issues/issue-13405.rs b/src/test/ui/issues/issue-13405.rs index 32965cb0c6d8c..fb48abe26484a 100644 --- a/src/test/ui/issues/issue-13405.rs +++ b/src/test/ui/issues/issue-13405.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-13703.rs b/src/test/ui/issues/issue-13703.rs index 212fff7bcecd7..fe5458a7d7c07 100644 --- a/src/test/ui/issues/issue-13703.rs +++ b/src/test/ui/issues/issue-13703.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize } diff --git a/src/test/ui/issues/issue-13775.rs b/src/test/ui/issues/issue-13775.rs index 39e42dc2c0d5a..0359bb581d585 100644 --- a/src/test/ui/issues/issue-13775.rs +++ b/src/test/ui/issues/issue-13775.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Foo { diff --git a/src/test/ui/issues/issue-13837.rs b/src/test/ui/issues/issue-13837.rs index d475ce1d83319..06790fbd32457 100644 --- a/src/test/ui/issues/issue-13837.rs +++ b/src/test/ui/issues/issue-13837.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-14082.rs b/src/test/ui/issues/issue-14082.rs index 4849077c144e1..e5f1b492f275b 100644 --- a/src/test/ui/issues/issue-14082.rs +++ b/src/test/ui/issues/issue-14082.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![allow(unused_imports, dead_code)] diff --git a/src/test/ui/issues/issue-14254.rs b/src/test/ui/issues/issue-14254.rs index 3ad388dc2d790..8b04fa192ada1 100644 --- a/src/test/ui/issues/issue-14254.rs +++ b/src/test/ui/issues/issue-14254.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Foo: Sized { diff --git a/src/test/ui/issues/issue-14330.rs b/src/test/ui/issues/issue-14330.rs index d8f225eb07c24..be31fa5eabc59 100644 --- a/src/test/ui/issues/issue-14330.rs +++ b/src/test/ui/issues/issue-14330.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_imports)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-14837.rs b/src/test/ui/issues/issue-14837.rs index 54387804affeb..a276e27f9dcc4 100644 --- a/src/test/ui/issues/issue-14837.rs +++ b/src/test/ui/issues/issue-14837.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #[deny(dead_code)] diff --git a/src/test/ui/issues/issue-14901.rs b/src/test/ui/issues/issue-14901.rs index 9b89c1631df15..c164658331e93 100644 --- a/src/test/ui/issues/issue-14901.rs +++ b/src/test/ui/issues/issue-14901.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Reader {} enum Wrapper<'a> { diff --git a/src/test/ui/issues/issue-14933.rs b/src/test/ui/issues/issue-14933.rs index 9249ba3d6466e..f229c0f7c26cf 100644 --- a/src/test/ui/issues/issue-14933.rs +++ b/src/test/ui/issues/issue-14933.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub type BigRat = T; diff --git a/src/test/ui/issues/issue-14936.rs b/src/test/ui/issues/issue-14936.rs index bd3c99ad8d78b..809a1088992a0 100644 --- a/src/test/ui/issues/issue-14936.rs +++ b/src/test/ui/issues/issue-14936.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_macros)] #![allow(dead_code)] #![feature(asm)] diff --git a/src/test/ui/issues/issue-14959.rs b/src/test/ui/issues/issue-14959.rs index 60daaafbcc8bd..bd6c7a2bda9f0 100644 --- a/src/test/ui/issues/issue-14959.rs +++ b/src/test/ui/issues/issue-14959.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![feature(fn_traits, unboxed_closures)] diff --git a/src/test/ui/issues/issue-15108.rs b/src/test/ui/issues/issue-15108.rs index d2b56c0949d63..b8231ad4e8326 100644 --- a/src/test/ui/issues/issue-15108.rs +++ b/src/test/ui/issues/issue-15108.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 fn main() {} diff --git a/src/test/ui/issues/issue-15261.rs b/src/test/ui/issues/issue-15261.rs index 4119cb055c590..dd859475f9c8e 100644 --- a/src/test/ui/issues/issue-15261.rs +++ b/src/test/ui/issues/issue-15261.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-15689-2.rs b/src/test/ui/issues/issue-15689-2.rs index 4a1326113910e..1731a356ccd19 100644 --- a/src/test/ui/issues/issue-15689-2.rs +++ b/src/test/ui/issues/issue-15689-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-15735.rs b/src/test/ui/issues/issue-15735.rs index 20634cc388110..0da4d4a620bf9 100644 --- a/src/test/ui/issues/issue-15735.rs +++ b/src/test/ui/issues/issue-15735.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A<'a> { a: &'a i32, diff --git a/src/test/ui/issues/issue-16596.rs b/src/test/ui/issues/issue-16596.rs index 3aa6c20ec57ec..693dea436bb06 100644 --- a/src/test/ui/issues/issue-16596.rs +++ b/src/test/ui/issues/issue-16596.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait MatrixRow { fn dummy(&self) { }} diff --git a/src/test/ui/issues/issue-16668.rs b/src/test/ui/issues/issue-16668.rs index b570a2ced67bc..a898ab20a4887 100644 --- a/src/test/ui/issues/issue-16668.rs +++ b/src/test/ui/issues/issue-16668.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Parser<'a, I, O> { parse: Box Result + 'a> diff --git a/src/test/ui/issues/issue-17121.rs b/src/test/ui/issues/issue-17121.rs index 706350fc1e205..0f1d4f5410d57 100644 --- a/src/test/ui/issues/issue-17121.rs +++ b/src/test/ui/issues/issue-17121.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 // ignore-cloudabi no std::fs diff --git a/src/test/ui/issues/issue-17263.rs b/src/test/ui/issues/issue-17263.rs index dce30275ff354..f24acb7b304e6 100644 --- a/src/test/ui/issues/issue-17263.rs +++ b/src/test/ui/issues/issue-17263.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_syntax)] diff --git a/src/test/ui/issues/issue-17336.rs b/src/test/ui/issues/issue-17336.rs index e2c0e8b91ccea..830d799fb652f 100644 --- a/src/test/ui/issues/issue-17336.rs +++ b/src/test/ui/issues/issue-17336.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] #[allow(dead_code)] fn check(a: &str) { diff --git a/src/test/ui/issues/issue-17450.rs b/src/test/ui/issues/issue-17450.rs index 70f33e3e66181..595e0a4d25c65 100644 --- a/src/test/ui/issues/issue-17450.rs +++ b/src/test/ui/issues/issue-17450.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, warnings)] static mut x: isize = 3; diff --git a/src/test/ui/issues/issue-17718-const-destructors.rs b/src/test/ui/issues/issue-17718-const-destructors.rs index 133420b688ec2..7ec025ec3af75 100644 --- a/src/test/ui/issues/issue-17718-const-destructors.rs +++ b/src/test/ui/issues/issue-17718-const-destructors.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A; impl Drop for A { diff --git a/src/test/ui/issues/issue-17732.rs b/src/test/ui/issues/issue-17732.rs index 7993bbb38bb4a..17135c191cafb 100644 --- a/src/test/ui/issues/issue-17732.rs +++ b/src/test/ui/issues/issue-17732.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-17746.rs b/src/test/ui/issues/issue-17746.rs index 45c5b858ecd17..847b2eb60bbb5 100644 --- a/src/test/ui/issues/issue-17746.rs +++ b/src/test/ui/issues/issue-17746.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #17746 diff --git a/src/test/ui/issues/issue-17904.rs b/src/test/ui/issues/issue-17904.rs index 2fe54957b3c08..d916abb9c7384 100644 --- a/src/test/ui/issues/issue-17904.rs +++ b/src/test/ui/issues/issue-17904.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test that we can parse where clauses on various forms of tuple // structs. diff --git a/src/test/ui/issues/issue-18083.rs b/src/test/ui/issues/issue-18083.rs index c2cf2919ff0c5..f159ed4a0cecc 100644 --- a/src/test/ui/issues/issue-18083.rs +++ b/src/test/ui/issues/issue-18083.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_imports)] // These crossed imports should resolve fine, and not block on diff --git a/src/test/ui/issues/issue-18088.rs b/src/test/ui/issues/issue-18088.rs index 67000d9a6ec3f..06f259958f822 100644 --- a/src/test/ui/issues/issue-18088.rs +++ b/src/test/ui/issues/issue-18088.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Indexable: std::ops::Index { fn index2(&self, i: usize) -> &T { diff --git a/src/test/ui/issues/issue-18188.rs b/src/test/ui/issues/issue-18188.rs index 4d0c4464759c6..da10a8647bac6 100644 --- a/src/test/ui/issues/issue-18188.rs +++ b/src/test/ui/issues/issue-18188.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 pub trait Promisable: Send + Sync {} diff --git a/src/test/ui/issues/issue-1821.rs b/src/test/ui/issues/issue-1821.rs index 0177b70a69885..db97a507b689a 100644 --- a/src/test/ui/issues/issue-1821.rs +++ b/src/test/ui/issues/issue-1821.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-18446-2.rs b/src/test/ui/issues/issue-18446-2.rs index 3e04a914d4586..6b984c13da5d3 100644 --- a/src/test/ui/issues/issue-18446-2.rs +++ b/src/test/ui/issues/issue-18446-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test that methods in trait impls should override default methods. diff --git a/src/test/ui/issues/issue-1866.rs b/src/test/ui/issues/issue-1866.rs index 3de547bfe6fce..0223e2ebea926 100644 --- a/src/test/ui/issues/issue-1866.rs +++ b/src/test/ui/issues/issue-1866.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-18738.rs b/src/test/ui/issues/issue-18738.rs index c3bd022fa443c..ec4429234bc59 100644 --- a/src/test/ui/issues/issue-18738.rs +++ b/src/test/ui/issues/issue-18738.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Eq, PartialEq, PartialOrd, Ord)] enum Test<'a> { diff --git a/src/test/ui/issues/issue-18809.rs b/src/test/ui/issues/issue-18809.rs index fb31666b22eb5..9b8275f811999 100644 --- a/src/test/ui/issues/issue-18809.rs +++ b/src/test/ui/issues/issue-18809.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Tup { type T0; type T1; diff --git a/src/test/ui/issues/issue-18906.rs b/src/test/ui/issues/issue-18906.rs index 0b9625b1868ef..387fd41fb7ae7 100644 --- a/src/test/ui/issues/issue-18906.rs +++ b/src/test/ui/issues/issue-18906.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-18988.rs b/src/test/ui/issues/issue-18988.rs index 7fe662e907d73..6dbfd3a0a982a 100644 --- a/src/test/ui/issues/issue-18988.rs +++ b/src/test/ui/issues/issue-18988.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] pub trait Foo : Send { } diff --git a/src/test/ui/issues/issue-19037.rs b/src/test/ui/issues/issue-19037.rs index 4efc0719ffbb2..30497d3e94f58 100644 --- a/src/test/ui/issues/issue-19037.rs +++ b/src/test/ui/issues/issue-19037.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-19081.rs b/src/test/ui/issues/issue-19081.rs index b487cdd5c7574..0948cd3271b1c 100644 --- a/src/test/ui/issues/issue-19081.rs +++ b/src/test/ui/issues/issue-19081.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Hasher { type State; diff --git a/src/test/ui/issues/issue-19097.rs b/src/test/ui/issues/issue-19097.rs index 8055e10625157..c800e0bd12a08 100644 --- a/src/test/ui/issues/issue-19097.rs +++ b/src/test/ui/issues/issue-19097.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // regression test for #19097 diff --git a/src/test/ui/issues/issue-19098.rs b/src/test/ui/issues/issue-19098.rs index 690fe944097c0..37c0d7f05222b 100644 --- a/src/test/ui/issues/issue-19098.rs +++ b/src/test/ui/issues/issue-19098.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Handler { fn handle(&self, _: &mut String); } diff --git a/src/test/ui/issues/issue-19102.rs b/src/test/ui/issues/issue-19102.rs index 962cd8d3f6f54..76ed3efc4ed49 100644 --- a/src/test/ui/issues/issue-19102.rs +++ b/src/test/ui/issues/issue-19102.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_imports)] #![deny(unused_qualifications)] diff --git a/src/test/ui/issues/issue-19129-1.rs b/src/test/ui/issues/issue-19129-1.rs index 4be2cc6d1797b..e17ee053f33d8 100644 --- a/src/test/ui/issues/issue-19129-1.rs +++ b/src/test/ui/issues/issue-19129-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Trait { diff --git a/src/test/ui/issues/issue-19129-2.rs b/src/test/ui/issues/issue-19129-2.rs index d11ef8af709ef..30c64573a1532 100644 --- a/src/test/ui/issues/issue-19129-2.rs +++ b/src/test/ui/issues/issue-19129-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-19398.rs b/src/test/ui/issues/issue-19398.rs index 5daa14b7cb7bb..28d266a1d61a2 100644 --- a/src/test/ui/issues/issue-19398.rs +++ b/src/test/ui/issues/issue-19398.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait T { diff --git a/src/test/ui/issues/issue-19404.rs b/src/test/ui/issues/issue-19404.rs index 59544393bae05..40c9fdac7b01f 100644 --- a/src/test/ui/issues/issue-19404.rs +++ b/src/test/ui/issues/issue-19404.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] use std::any::TypeId; diff --git a/src/test/ui/issues/issue-19479.rs b/src/test/ui/issues/issue-19479.rs index 8b78952a6e2b1..c134d85c7e93d 100644 --- a/src/test/ui/issues/issue-19479.rs +++ b/src/test/ui/issues/issue-19479.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Base { diff --git a/src/test/ui/issues/issue-19631.rs b/src/test/ui/issues/issue-19631.rs index 8c58331e581b7..015758dd6e1d2 100644 --- a/src/test/ui/issues/issue-19631.rs +++ b/src/test/ui/issues/issue-19631.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-19632.rs b/src/test/ui/issues/issue-19632.rs index b032b67c1ebd1..ddd87a9f6e978 100644 --- a/src/test/ui/issues/issue-19632.rs +++ b/src/test/ui/issues/issue-19632.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-19850.rs b/src/test/ui/issues/issue-19850.rs index fb64ef8940557..d51cf0cfcb980 100644 --- a/src/test/ui/issues/issue-19850.rs +++ b/src/test/ui/issues/issue-19850.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] // Test that `::Output` and `Self::Output` are accepted as type annotations in let // bindings diff --git a/src/test/ui/issues/issue-19982.rs b/src/test/ui/issues/issue-19982.rs index 6b5a4b2c10eda..fb88781ee283a 100644 --- a/src/test/ui/issues/issue-19982.rs +++ b/src/test/ui/issues/issue-19982.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(fn_traits, unboxed_closures)] diff --git a/src/test/ui/issues/issue-20009.rs b/src/test/ui/issues/issue-20009.rs index 6228d044ad11a..730f1a9a162a2 100644 --- a/src/test/ui/issues/issue-20009.rs +++ b/src/test/ui/issues/issue-20009.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that associated types are `Sized` // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-20091.rs b/src/test/ui/issues/issue-20091.rs index 4ea567d25ca53..68e0f65ca2382 100644 --- a/src/test/ui/issues/issue-20091.rs +++ b/src/test/ui/issues/issue-20091.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(stable_features)] // ignore-cloudabi no processes diff --git a/src/test/ui/issues/issue-20186.rs b/src/test/ui/issues/issue-20186.rs index 98d856e172a2c..28cbde772c51d 100644 --- a/src/test/ui/issues/issue-20186.rs +++ b/src/test/ui/issues/issue-20186.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] struct Foo; diff --git a/src/test/ui/issues/issue-20396.rs b/src/test/ui/issues/issue-20396.rs index 0e69b7f3d1e0c..5e0411b2cd259 100644 --- a/src/test/ui/issues/issue-20396.rs +++ b/src/test/ui/issues/issue-20396.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![allow(dead_code)] diff --git a/src/test/ui/issues/issue-20414.rs b/src/test/ui/issues/issue-20414.rs index 1653a9da0045a..5c6929d45d199 100644 --- a/src/test/ui/issues/issue-20414.rs +++ b/src/test/ui/issues/issue-20414.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-20454.rs b/src/test/ui/issues/issue-20454.rs index d4920c0c75903..13ce1daf30a2a 100644 --- a/src/test/ui/issues/issue-20454.rs +++ b/src/test/ui/issues/issue-20454.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] use std::thread; diff --git a/src/test/ui/issues/issue-2063-resource.rs b/src/test/ui/issues/issue-2063-resource.rs index 6ed3e027ffa48..ea4cbf2cedeb7 100644 --- a/src/test/ui/issues/issue-2063-resource.rs +++ b/src/test/ui/issues/issue-2063-resource.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // test that autoderef of a type like this does not // cause compiler to loop. Note that no instances diff --git a/src/test/ui/issues/issue-20644.rs b/src/test/ui/issues/issue-20644.rs index db32344864c46..bde65229ec286 100644 --- a/src/test/ui/issues/issue-20644.rs +++ b/src/test/ui/issues/issue-20644.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_imports)] #![allow(stable_features)] diff --git a/src/test/ui/issues/issue-20763-1.rs b/src/test/ui/issues/issue-20763-1.rs index c5b2852094591..0f0ac8f646203 100644 --- a/src/test/ui/issues/issue-20763-1.rs +++ b/src/test/ui/issues/issue-20763-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-20763-2.rs b/src/test/ui/issues/issue-20763-2.rs index cfa252b095e47..e3b566d050340 100644 --- a/src/test/ui/issues/issue-20763-2.rs +++ b/src/test/ui/issues/issue-20763-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-20797.rs b/src/test/ui/issues/issue-20797.rs index e504b4705daf2..bda7e8f818b15 100644 --- a/src/test/ui/issues/issue-20797.rs +++ b/src/test/ui/issues/issue-20797.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-cloudabi no std::fs // Regression test for #20797. diff --git a/src/test/ui/issues/issue-20825-2.rs b/src/test/ui/issues/issue-20825-2.rs index cceed54218669..7d72ef839eab7 100644 --- a/src/test/ui/issues/issue-20825-2.rs +++ b/src/test/ui/issues/issue-20825-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Subscriber { type Input; } diff --git a/src/test/ui/issues/issue-21140.rs b/src/test/ui/issues/issue-21140.rs index 86d4e63670f3b..92834bbb0e491 100644 --- a/src/test/ui/issues/issue-21140.rs +++ b/src/test/ui/issues/issue-21140.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Trait where Self::Out: std::fmt::Display { type Out; } diff --git a/src/test/ui/issues/issue-21174-2.rs b/src/test/ui/issues/issue-21174-2.rs index 145b062baf678..351a98d5c85b7 100644 --- a/src/test/ui/issues/issue-21174-2.rs +++ b/src/test/ui/issues/issue-21174-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] trait Trait<'a> { diff --git a/src/test/ui/issues/issue-21245.rs b/src/test/ui/issues/issue-21245.rs index edf482afc53d4..d0aa16bfb1645 100644 --- a/src/test/ui/issues/issue-21245.rs +++ b/src/test/ui/issues/issue-21245.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for issue #21245. Check that we are able to infer // the types in these examples correctly. It used to be that diff --git a/src/test/ui/issues/issue-21363.rs b/src/test/ui/issues/issue-21363.rs index 12efce9496efa..d5f1eec061d20 100644 --- a/src/test/ui/issues/issue-21363.rs +++ b/src/test/ui/issues/issue-21363.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #![no_implicit_prelude] diff --git a/src/test/ui/issues/issue-21402.rs b/src/test/ui/issues/issue-21402.rs index 518d3cfe5a660..21e0d58b5f4a3 100644 --- a/src/test/ui/issues/issue-21402.rs +++ b/src/test/ui/issues/issue-21402.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-21520.rs b/src/test/ui/issues/issue-21520.rs index 450448f1a1185..133bcc2360a22 100644 --- a/src/test/ui/issues/issue-21520.rs +++ b/src/test/ui/issues/issue-21520.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test that the requirement (in `Bar`) that `T::Bar : 'static` does // not wind up propagating to `T`. diff --git a/src/test/ui/issues/issue-21562.rs b/src/test/ui/issues/issue-21562.rs index e31316d0709b0..2f3ee7b749091 100644 --- a/src/test/ui/issues/issue-21562.rs +++ b/src/test/ui/issues/issue-21562.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-21622.rs b/src/test/ui/issues/issue-21622.rs index 2b80f2f36c5ad..4aae089943f5b 100644 --- a/src/test/ui/issues/issue-21622.rs +++ b/src/test/ui/issues/issue-21622.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/issues/issue-21634.rs b/src/test/ui/issues/issue-21634.rs index 8941bb1c24321..36b207bb2a481 100644 --- a/src/test/ui/issues/issue-21634.rs +++ b/src/test/ui/issues/issue-21634.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(stable_features)] #![feature(cfg_target_feature)] diff --git a/src/test/ui/issues/issue-21726.rs b/src/test/ui/issues/issue-21726.rs index f2065976b35d0..1c8284c8295dc 100644 --- a/src/test/ui/issues/issue-21726.rs +++ b/src/test/ui/issues/issue-21726.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #21726: an issue arose around the rules for // subtyping of projection types that resulted in an unconstrained diff --git a/src/test/ui/issues/issue-21891.rs b/src/test/ui/issues/issue-21891.rs index 9b1e44c181759..de0aa2919cfbc 100644 --- a/src/test/ui/issues/issue-21891.rs +++ b/src/test/ui/issues/issue-21891.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-22066.rs b/src/test/ui/issues/issue-22066.rs index 8c0b664d78ad5..fbf31aa42437c 100644 --- a/src/test/ui/issues/issue-22066.rs +++ b/src/test/ui/issues/issue-22066.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait LineFormatter<'a> { type Iter: Iterator + 'a; fn iter(&'a self, line: &'a str) -> Self::Iter; diff --git a/src/test/ui/issues/issue-22356.rs b/src/test/ui/issues/issue-22356.rs index 3f3b1d3e5f1d9..ec4695e5e0ac5 100644 --- a/src/test/ui/issues/issue-22356.rs +++ b/src/test/ui/issues/issue-22356.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(type_alias_bounds)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-22375.rs b/src/test/ui/issues/issue-22375.rs index bae7b2bfab453..201aea3a05c00 100644 --- a/src/test/ui/issues/issue-22375.rs +++ b/src/test/ui/issues/issue-22375.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait A> {} fn main() {} diff --git a/src/test/ui/issues/issue-22471.rs b/src/test/ui/issues/issue-22471.rs index a22c7e6173e17..befccc19bf8ef 100644 --- a/src/test/ui/issues/issue-22471.rs +++ b/src/test/ui/issues/issue-22471.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(type_alias_bounds)] diff --git a/src/test/ui/issues/issue-22777.rs b/src/test/ui/issues/issue-22777.rs index f9b264623d6bb..81efb250dfa96 100644 --- a/src/test/ui/issues/issue-22777.rs +++ b/src/test/ui/issues/issue-22777.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test is reduced from libsyntax. It is just checking that we // can successfully deal with a "deep" structure, which the drop-check // was hitting a recursion limit on at one point. diff --git a/src/test/ui/issues/issue-22781.rs b/src/test/ui/issues/issue-22781.rs index a7b94c106a4c8..37f40aa042140 100644 --- a/src/test/ui/issues/issue-22781.rs +++ b/src/test/ui/issues/issue-22781.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] use std::collections::HashMap; use std::collections::hash_map::Entry::Vacant; diff --git a/src/test/ui/issues/issue-22814.rs b/src/test/ui/issues/issue-22814.rs index bcc7a8a5ae0a3..065e7edc67e07 100644 --- a/src/test/ui/issues/issue-22814.rs +++ b/src/test/ui/issues/issue-22814.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Test {} macro_rules! test { diff --git a/src/test/ui/issues/issue-22894.rs b/src/test/ui/issues/issue-22894.rs index f5b26de54f519..7b1513a10c0ef 100644 --- a/src/test/ui/issues/issue-22894.rs +++ b/src/test/ui/issues/issue-22894.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[allow(dead_code)] static X: &'static str = &*""; fn main() {} diff --git a/src/test/ui/issues/issue-2311-2.rs b/src/test/ui/issues/issue-2311-2.rs index 40cda23186a47..f735338fcdbc9 100644 --- a/src/test/ui/issues/issue-2311-2.rs +++ b/src/test/ui/issues/issue-2311-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-2311.rs b/src/test/ui/issues/issue-2311.rs index 07b9951e68d39..151ad4e26645b 100644 --- a/src/test/ui/issues/issue-2311.rs +++ b/src/test/ui/issues/issue-2311.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(non_camel_case_types)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-2312.rs b/src/test/ui/issues/issue-2312.rs index 1fc7b5a3f34c5..b445f9581b345 100644 --- a/src/test/ui/issues/issue-2312.rs +++ b/src/test/ui/issues/issue-2312.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-23406.rs b/src/test/ui/issues/issue-23406.rs index 9d77af0914f17..2e57b16e3c7f0 100644 --- a/src/test/ui/issues/issue-23406.rs +++ b/src/test/ui/issues/issue-23406.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Inner { type T; diff --git a/src/test/ui/issues/issue-23442.rs b/src/test/ui/issues/issue-23442.rs index c3b613a06cdfe..659e1e07942fe 100644 --- a/src/test/ui/issues/issue-23442.rs +++ b/src/test/ui/issues/issue-23442.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::marker::PhantomData; diff --git a/src/test/ui/issues/issue-23477.rs b/src/test/ui/issues/issue-23477.rs index f363e6a0f4730..b10b2e49616fb 100644 --- a/src/test/ui/issues/issue-23477.rs +++ b/src/test/ui/issues/issue-23477.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compiler-flags: -g pub struct Dst { diff --git a/src/test/ui/issues/issue-23550.rs b/src/test/ui/issues/issue-23550.rs index 370d5c5aa3ea5..fad0ad7eccaa4 100644 --- a/src/test/ui/issues/issue-23550.rs +++ b/src/test/ui/issues/issue-23550.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(core_intrinsics)] #![allow(warnings)] diff --git a/src/test/ui/issues/issue-23649-3.rs b/src/test/ui/issues/issue-23649-3.rs index 718fe606b80de..febdc4256c757 100644 --- a/src/test/ui/issues/issue-23649-3.rs +++ b/src/test/ui/issues/issue-23649-3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(PartialEq)] struct Slice { slice: [u8] } diff --git a/src/test/ui/issues/issue-24085.rs b/src/test/ui/issues/issue-24085.rs index d06647762a9b8..dc2de922ff008 100644 --- a/src/test/ui/issues/issue-24085.rs +++ b/src/test/ui/issues/issue-24085.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #24085. Errors were occurring in region // inference due to the requirement that `'a:b'`, which was getting diff --git a/src/test/ui/issues/issue-24161.rs b/src/test/ui/issues/issue-24161.rs index 99b09ba74d5d9..c5c8651d43bad 100644 --- a/src/test/ui/issues/issue-24161.rs +++ b/src/test/ui/issues/issue-24161.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Copy,Clone)] struct Functions { diff --git a/src/test/ui/issues/issue-24227.rs b/src/test/ui/issues/issue-24227.rs index 83e12caff6dd0..eaadaf7c449df 100644 --- a/src/test/ui/issues/issue-24227.rs +++ b/src/test/ui/issues/issue-24227.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This resulted in an ICE. Test for future-proofing // Issue #24227 diff --git a/src/test/ui/issues/issue-24338.rs b/src/test/ui/issues/issue-24338.rs index fafeff06426dd..09cc99f95077a 100644 --- a/src/test/ui/issues/issue-24338.rs +++ b/src/test/ui/issues/issue-24338.rs @@ -1,5 +1,5 @@ // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait DictLike<'a> { type ItemsIterator: Iterator; diff --git a/src/test/ui/issues/issue-24389.rs b/src/test/ui/issues/issue-24389.rs index da48a76e2007d..63d1687af5073 100644 --- a/src/test/ui/issues/issue-24389.rs +++ b/src/test/ui/issues/issue-24389.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo; diff --git a/src/test/ui/issues/issue-24434.rs b/src/test/ui/issues/issue-24434.rs index 2424a1c92cd64..b500b9d56dd83 100644 --- a/src/test/ui/issues/issue-24434.rs +++ b/src/test/ui/issues/issue-24434.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--cfg set1 #![cfg_attr(set1, feature(rustc_attrs))] diff --git a/src/test/ui/issues/issue-2487-a.rs b/src/test/ui/issues/issue-2487-a.rs index 36e121ddb7ad9..a43933d20202d 100644 --- a/src/test/ui/issues/issue-2487-a.rs +++ b/src/test/ui/issues/issue-2487-a.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-2502.rs b/src/test/ui/issues/issue-2502.rs index 29b68c94c2e7c..9a2bbb82413f6 100644 --- a/src/test/ui/issues/issue-2502.rs +++ b/src/test/ui/issues/issue-2502.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/src/test/ui/issues/issue-25180.rs b/src/test/ui/issues/issue-25180.rs index 297f403c05ee7..12f8f88a17034 100644 --- a/src/test/ui/issues/issue-25180.rs +++ b/src/test/ui/issues/issue-25180.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-25394.rs b/src/test/ui/issues/issue-25394.rs index d1638aa98a0b0..c41b554df142a 100644 --- a/src/test/ui/issues/issue-25394.rs +++ b/src/test/ui/issues/issue-25394.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Debug)] struct Row([T]); diff --git a/src/test/ui/issues/issue-25579.rs b/src/test/ui/issues/issue-25579.rs index 31ba102746b34..32b4b75b0809c 100644 --- a/src/test/ui/issues/issue-25579.rs +++ b/src/test/ui/issues/issue-25579.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) enum Sexpression { Num(()), diff --git a/src/test/ui/issues/issue-26095.rs b/src/test/ui/issues/issue-26095.rs index 707cf1df512c2..1e3cc902e56b2 100644 --- a/src/test/ui/issues/issue-26095.rs +++ b/src/test/ui/issues/issue-26095.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-2611-3.rs b/src/test/ui/issues/issue-2611-3.rs index 5d4b65628de82..7335d53f8a640 100644 --- a/src/test/ui/issues/issue-2611-3.rs +++ b/src/test/ui/issues/issue-2611-3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Tests that impls are allowed to have looser, more permissive bounds // than the traits require. diff --git a/src/test/ui/issues/issue-26205.rs b/src/test/ui/issues/issue-26205.rs index 01b71652c0538..45ca998a831ef 100644 --- a/src/test/ui/issues/issue-26205.rs +++ b/src/test/ui/issues/issue-26205.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::ops::{Deref, DerefMut}; diff --git a/src/test/ui/issues/issue-26646.rs b/src/test/ui/issues/issue-26646.rs index 6aa5e03996b9d..d6f51ce9c99dc 100644 --- a/src/test/ui/issues/issue-26646.rs +++ b/src/test/ui/issues/issue-26646.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_attributes)] #[repr(C)] diff --git a/src/test/ui/issues/issue-26997.rs b/src/test/ui/issues/issue-26997.rs index dd48440720fda..a2b32a13678a5 100644 --- a/src/test/ui/issues/issue-26997.rs +++ b/src/test/ui/issues/issue-26997.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] pub struct Foo { x: isize, diff --git a/src/test/ui/issues/issue-27105.rs b/src/test/ui/issues/issue-27105.rs index 1aafa11768fd3..e7584d941ba6c 100644 --- a/src/test/ui/issues/issue-27105.rs +++ b/src/test/ui/issues/issue-27105.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::RefCell; use std::rc::Rc; diff --git a/src/test/ui/issues/issue-27281.rs b/src/test/ui/issues/issue-27281.rs index 8403d9b450787..58b8f07bca6d8 100644 --- a/src/test/ui/issues/issue-27281.rs +++ b/src/test/ui/issues/issue-27281.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Trait<'a> { type T; type U; diff --git a/src/test/ui/issues/issue-2748-a.rs b/src/test/ui/issues/issue-2748-a.rs index 683a931cc3d5b..5f566e186eb20 100644 --- a/src/test/ui/issues/issue-2748-a.rs +++ b/src/test/ui/issues/issue-2748-a.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_snake_case)] diff --git a/src/test/ui/issues/issue-27583.rs b/src/test/ui/issues/issue-27583.rs index 763e9ebe24b22..9981f867bd00b 100644 --- a/src/test/ui/issues/issue-27583.rs +++ b/src/test/ui/issues/issue-27583.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for issue #27583. Unclear how useful this will be // going forward, since the issue in question was EXTREMELY sensitive // to compiler internals (like the precise numbering of nodes), but diff --git a/src/test/ui/issues/issue-27889.rs b/src/test/ui/issues/issue-27889.rs index 22de7c7cfa537..bb5a186b457d9 100644 --- a/src/test/ui/issues/issue-27889.rs +++ b/src/test/ui/issues/issue-27889.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_assignments)] #![allow(unused_variables)] // Test that a field can have the same name in different variants diff --git a/src/test/ui/issues/issue-2804-2.rs b/src/test/ui/issues/issue-2804-2.rs index d5157420617d7..68933fc2e8a3b 100644 --- a/src/test/ui/issues/issue-2804-2.rs +++ b/src/test/ui/issues/issue-2804-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Minimized version of issue-2804.rs. Both check that callee IDs don't // clobber the previous node ID in a macro expr diff --git a/src/test/ui/issues/issue-28279.rs b/src/test/ui/issues/issue-28279.rs index fab91160a88be..e36a9551ab549 100644 --- a/src/test/ui/issues/issue-28279.rs +++ b/src/test/ui/issues/issue-28279.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::rc::Rc; diff --git a/src/test/ui/issues/issue-28561.rs b/src/test/ui/issues/issue-28561.rs index 9dcce9991f73c..cc4e63696e5f3 100644 --- a/src/test/ui/issues/issue-28561.rs +++ b/src/test/ui/issues/issue-28561.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] struct Array { f00: [T; 00], diff --git a/src/test/ui/issues/issue-28600.rs b/src/test/ui/issues/issue-28600.rs index 44a85924e3d54..05c4050b03a43 100644 --- a/src/test/ui/issues/issue-28600.rs +++ b/src/test/ui/issues/issue-28600.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // #28600 ICE: pub extern fn with parameter type &str inside struct impl struct Test; diff --git a/src/test/ui/issues/issue-28822.rs b/src/test/ui/issues/issue-28822.rs index 7381c348cd61a..2c0c01aa827ab 100644 --- a/src/test/ui/issues/issue-28822.rs +++ b/src/test/ui/issues/issue-28822.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] fn main() {} diff --git a/src/test/ui/issues/issue-28871.rs b/src/test/ui/issues/issue-28871.rs index b7e02b85878f2..43564dfcc46bf 100644 --- a/src/test/ui/issues/issue-28871.rs +++ b/src/test/ui/issues/issue-28871.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for #28871. The problem is that rustc encountered // two ways to project, one from a where clause and one from the where // clauses on the trait definition. (In fact, in this case, the where diff --git a/src/test/ui/issues/issue-28936.rs b/src/test/ui/issues/issue-28936.rs index 5365adf3e80de..9267491aafd9d 100644 --- a/src/test/ui/issues/issue-28936.rs +++ b/src/test/ui/issues/issue-28936.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub type Session = i32; pub struct StreamParser<'a, T> { _tokens: T, diff --git a/src/test/ui/issues/issue-28999.rs b/src/test/ui/issues/issue-28999.rs index 4f6fa412e8b93..888a8010a2f6b 100644 --- a/src/test/ui/issues/issue-28999.rs +++ b/src/test/ui/issues/issue-28999.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Xyz<'a, V> { pub v: (V, &'a u32), } diff --git a/src/test/ui/issues/issue-29030.rs b/src/test/ui/issues/issue-29030.rs index 9ac7742e4f8db..f9e89840314d4 100644 --- a/src/test/ui/issues/issue-29030.rs +++ b/src/test/ui/issues/issue-29030.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[derive(Debug)] struct Message<'a, P: 'a = &'a [u8]> { diff --git a/src/test/ui/issues/issue-29037.rs b/src/test/ui/issues/issue-29037.rs index e0eb71f5de6ec..b1ca76be10d0b 100644 --- a/src/test/ui/issues/issue-29037.rs +++ b/src/test/ui/issues/issue-29037.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // This test ensures that each pointer type `P` is covariant in `X`. diff --git a/src/test/ui/issues/issue-2904.rs b/src/test/ui/issues/issue-2904.rs index 42f71a1b09615..36bc8002f99db 100644 --- a/src/test/ui/issues/issue-2904.rs +++ b/src/test/ui/issues/issue-2904.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/src/test/ui/issues/issue-29048.rs b/src/test/ui/issues/issue-29048.rs index 6c4b6183c3761..e3ccb0d6579d7 100644 --- a/src/test/ui/issues/issue-29048.rs +++ b/src/test/ui/issues/issue-29048.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Chan; pub struct ChanSelect<'c, T> { chans: Vec<(&'c Chan, T)>, diff --git a/src/test/ui/issues/issue-29071.rs b/src/test/ui/issues/issue-29071.rs index 1ea4a54226c6c..7e016a715cd1f 100644 --- a/src/test/ui/issues/issue-29071.rs +++ b/src/test/ui/issues/issue-29071.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-29276.rs b/src/test/ui/issues/issue-29276.rs index 2a0358bc52ab0..2532dac977293 100644 --- a/src/test/ui/issues/issue-29276.rs +++ b/src/test/ui/issues/issue-29276.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct S([u8; { struct Z; 0 }]); diff --git a/src/test/ui/issues/issue-29516.rs b/src/test/ui/issues/issue-29516.rs index 8082694e15c02..8966730fd8739 100644 --- a/src/test/ui/issues/issue-29516.rs +++ b/src/test/ui/issues/issue-29516.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(optin_builtin_traits)] auto trait NotSame {} diff --git a/src/test/ui/issues/issue-29540.rs b/src/test/ui/issues/issue-29540.rs index b68205eda8615..e472f71aa7f25 100644 --- a/src/test/ui/issues/issue-29540.rs +++ b/src/test/ui/issues/issue-29540.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[derive(Debug)] pub struct Config { pub name: String, diff --git a/src/test/ui/issues/issue-29710.rs b/src/test/ui/issues/issue-29710.rs index 58907e78e4819..d4de756e56fa0 100644 --- a/src/test/ui/issues/issue-29710.rs +++ b/src/test/ui/issues/issue-29710.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_results)] #![allow(dead_code)] diff --git a/src/test/ui/issues/issue-29740.rs b/src/test/ui/issues/issue-29740.rs index f37d868ab7ebc..50a03d86acb58 100644 --- a/src/test/ui/issues/issue-29740.rs +++ b/src/test/ui/issues/issue-29740.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #29740. Inefficient MIR matching algorithms // generated way too much code for this sort of case, leading to OOM. diff --git a/src/test/ui/issues/issue-29743.rs b/src/test/ui/issues/issue-29743.rs index 5bc3b0c537a77..2598b07490e95 100644 --- a/src/test/ui/issues/issue-29743.rs +++ b/src/test/ui/issues/issue-29743.rs @@ -1,5 +1,5 @@ // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let mut i = [1, 2, 3]; diff --git a/src/test/ui/issues/issue-31260.rs b/src/test/ui/issues/issue-31260.rs index f7e717c59ac02..608900301e0ef 100644 --- a/src/test/ui/issues/issue-31260.rs +++ b/src/test/ui/issues/issue-31260.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] pub struct Struct { pub field: K, diff --git a/src/test/ui/issues/issue-3149.rs b/src/test/ui/issues/issue-3149.rs index c9a6f537757d0..da3fe9ad6ec3e 100644 --- a/src/test/ui/issues/issue-3149.rs +++ b/src/test/ui/issues/issue-3149.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_snake_case)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-31597.rs b/src/test/ui/issues/issue-31597.rs index 3962f13fe9b38..1d28a91ea7e01 100644 --- a/src/test/ui/issues/issue-31597.rs +++ b/src/test/ui/issues/issue-31597.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Make { type Out; diff --git a/src/test/ui/issues/issue-32324.rs b/src/test/ui/issues/issue-32324.rs index 9abbe321604b4..eaad98d678537 100644 --- a/src/test/ui/issues/issue-32324.rs +++ b/src/test/ui/issues/issue-32324.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Resources { diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.rs b/src/test/ui/issues/issue-33140-traitobject-crate.rs index 078f3f3dd2cd2..03567b20a8fa6 100644 --- a/src/test/ui/issues/issue-33140-traitobject-crate.rs +++ b/src/test/ui/issues/issue-33140-traitobject-crate.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(order_dependent_trait_objects)] diff --git a/src/test/ui/issues/issue-33264.rs b/src/test/ui/issues/issue-33264.rs index 51608b48be27c..e6370bc84deaf 100644 --- a/src/test/ui/issues/issue-33264.rs +++ b/src/test/ui/issues/issue-33264.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // only-x86_64 #![allow(dead_code, non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-33287.rs b/src/test/ui/issues/issue-33287.rs index cc47e58fcdc15..036a1e3768843 100644 --- a/src/test/ui/issues/issue-33287.rs +++ b/src/test/ui/issues/issue-33287.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] const A: [u32; 1] = [0]; diff --git a/src/test/ui/issues/issue-33903.rs b/src/test/ui/issues/issue-33903.rs index 4fdc8dda8b42c..6a8305dabebf8 100644 --- a/src/test/ui/issues/issue-33903.rs +++ b/src/test/ui/issues/issue-33903.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Issue 33903: // Built-in indexing should be used even when the index is not diff --git a/src/test/ui/issues/issue-34194.rs b/src/test/ui/issues/issue-34194.rs index b65de91d69b26..ea89e4cbdeb88 100644 --- a/src/test/ui/issues/issue-34194.rs +++ b/src/test/ui/issues/issue-34194.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct A { diff --git a/src/test/ui/issues/issue-3424.rs b/src/test/ui/issues/issue-3424.rs index 19f9f13e14416..a8ff03e2a2481 100644 --- a/src/test/ui/issues/issue-3424.rs +++ b/src/test/ui/issues/issue-3424.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] // rustc --test ignores2.rs && ./ignores2 diff --git a/src/test/ui/issues/issue-34751.rs b/src/test/ui/issues/issue-34751.rs index cca06c573e087..a921cb50612dd 100644 --- a/src/test/ui/issues/issue-34751.rs +++ b/src/test/ui/issues/issue-34751.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)' diff --git a/src/test/ui/issues/issue-34780.rs b/src/test/ui/issues/issue-34780.rs index bfe444e5d3fc0..3202ef6402162 100644 --- a/src/test/ui/issues/issue-34780.rs +++ b/src/test/ui/issues/issue-34780.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(stable_features)] #![feature(associated_consts)] diff --git a/src/test/ui/issues/issue-35376.rs b/src/test/ui/issues/issue-35376.rs index 2a80c9f05d84b..b415d6554058f 100644 --- a/src/test/ui/issues/issue-35376.rs +++ b/src/test/ui/issues/issue-35376.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(specialization)] fn main() {} diff --git a/src/test/ui/issues/issue-35546.rs b/src/test/ui/issues/issue-35546.rs index 500ba48e0b71c..e2f0f98d57b4f 100644 --- a/src/test/ui/issues/issue-35546.rs +++ b/src/test/ui/issues/issue-35546.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #35546. Check that we are able to codegen // this. Before we had problems because of the drop glue signature diff --git a/src/test/ui/issues/issue-3563-2.rs b/src/test/ui/issues/issue-3563-2.rs index 48f7c845d5e84..5ab668eed1899 100644 --- a/src/test/ui/issues/issue-3563-2.rs +++ b/src/test/ui/issues/issue-3563-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait Canvas { diff --git a/src/test/ui/issues/issue-36075.rs b/src/test/ui/issues/issue-36075.rs index c9ca2f71341ed..00c8cf1fb8aba 100644 --- a/src/test/ui/issues/issue-36075.rs +++ b/src/test/ui/issues/issue-36075.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait DeclarationParser { type Declaration; diff --git a/src/test/ui/issues/issue-3609.rs b/src/test/ui/issues/issue-3609.rs index 9bccb2a21e33c..e8fc073a15886 100644 --- a/src/test/ui/issues/issue-3609.rs +++ b/src/test/ui/issues/issue-3609.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_must_use)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/src/test/ui/issues/issue-36744-without-calls.rs b/src/test/ui/issues/issue-36744-without-calls.rs index 57d63e67f3c0b..4d03d9bbca6b6 100644 --- a/src/test/ui/issues/issue-36744-without-calls.rs +++ b/src/test/ui/issues/issue-36744-without-calls.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests for an LLVM abort when storing a lifetime-parametric fn into // context that is expecting one that is not lifetime-parametric // (i.e., has no `for <'_>`). diff --git a/src/test/ui/issues/issue-37323.rs b/src/test/ui/issues/issue-37323.rs index a7cf0cd1bd53d..61c8029adf53b 100644 --- a/src/test/ui/issues/issue-37323.rs +++ b/src/test/ui/issues/issue-37323.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(warnings)] diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs index 209f797b15cd8..1bec3d340d665 100644 --- a/src/test/ui/issues/issue-37598.rs +++ b/src/test/ui/issues/issue-37598.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![feature(slice_patterns)] diff --git a/src/test/ui/issues/issue-37655.rs b/src/test/ui/issues/issue-37655.rs index bfc6406b921c0..fecff4e024606 100644 --- a/src/test/ui/issues/issue-37655.rs +++ b/src/test/ui/issues/issue-37655.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for #37655. The problem was a false edge created by // coercion that wound up requiring that `'a` (in `split()`) outlive // `'b`, which shouldn't be necessary. diff --git a/src/test/ui/issues/issue-37725.rs b/src/test/ui/issues/issue-37725.rs index a572781f092db..eefdc72f0c3b3 100644 --- a/src/test/ui/issues/issue-37725.rs +++ b/src/test/ui/issues/issue-37725.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Foo { fn foo(&self); diff --git a/src/test/ui/issues/issue-37733.rs b/src/test/ui/issues/issue-37733.rs index 2dcb0cd8cee81..c1df28331a548 100644 --- a/src/test/ui/issues/issue-37733.rs +++ b/src/test/ui/issues/issue-37733.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] type A = for<> fn(); diff --git a/src/test/ui/issues/issue-38727.rs b/src/test/ui/issues/issue-38727.rs index d9f32637a90d0..3c728e9def1e9 100644 --- a/src/test/ui/issues/issue-38727.rs +++ b/src/test/ui/issues/issue-38727.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #[repr(u64)] enum A { diff --git a/src/test/ui/issues/issue-3874.rs b/src/test/ui/issues/issue-3874.rs index 8a7eaf29539cb..b290da5208042 100644 --- a/src/test/ui/issues/issue-3874.rs +++ b/src/test/ui/issues/issue-3874.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-38875/issue-38875.rs b/src/test/ui/issues/issue-38875/issue-38875.rs index df321b8dcbbe7..68981eaf2b568 100644 --- a/src/test/ui/issues/issue-38875/issue-38875.rs +++ b/src/test/ui/issues/issue-38875/issue-38875.rs @@ -1,5 +1,5 @@ // aux-build:issue-38875-b.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate issue_38875_b; diff --git a/src/test/ui/issues/issue-3888-2.rs b/src/test/ui/issues/issue-3888-2.rs index 27d05b470becf..3d4b184ab6bc5 100644 --- a/src/test/ui/issues/issue-3888-2.rs +++ b/src/test/ui/issues/issue-3888-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-39089.rs b/src/test/ui/issues/issue-39089.rs index 77be9d2c76bdb..12ca9e1da0ffb 100644 --- a/src/test/ui/issues/issue-39089.rs +++ b/src/test/ui/issues/issue-39089.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] fn f Sized>() {} diff --git a/src/test/ui/issues/issue-39467.rs b/src/test/ui/issues/issue-39467.rs index 077e5cefd528f..86e67560008ea 100644 --- a/src/test/ui/issues/issue-39467.rs +++ b/src/test/ui/issues/issue-39467.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] macro_rules! expr { () => { () } } diff --git a/src/test/ui/issues/issue-3979-2.rs b/src/test/ui/issues/issue-3979-2.rs index eec8c85f276c7..f3fcfd2c8fbff 100644 --- a/src/test/ui/issues/issue-3979-2.rs +++ b/src/test/ui/issues/issue-3979-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 trait A { diff --git a/src/test/ui/issues/issue-3991.rs b/src/test/ui/issues/issue-3991.rs index bc63aae0b9eac..b8ff671bf38ae 100644 --- a/src/test/ui/issues/issue-3991.rs +++ b/src/test/ui/issues/issue-3991.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-39984.rs b/src/test/ui/issues/issue-39984.rs index 5018b1c62c770..613aad1a34f1f 100644 --- a/src/test/ui/issues/issue-39984.rs +++ b/src/test/ui/issues/issue-39984.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unreachable_code)] // Regression test for issue #39984. diff --git a/src/test/ui/issues/issue-40136.rs b/src/test/ui/issues/issue-40136.rs index 0849f54374b49..412ddafdd97ce 100644 --- a/src/test/ui/issues/issue-40136.rs +++ b/src/test/ui/issues/issue-40136.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] macro_rules! m { () => { 0 } } diff --git a/src/test/ui/issues/issue-4025.rs b/src/test/ui/issues/issue-4025.rs index fc036f3edd82a..6e009ba6eb444 100644 --- a/src/test/ui/issues/issue-4025.rs +++ b/src/test/ui/issues/issue-4025.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_mut)] /* diff --git a/src/test/ui/issues/issue-40510-2.rs b/src/test/ui/issues/issue-40510-2.rs index 2304badd17dbb..499fa8a04f207 100644 --- a/src/test/ui/issues/issue-40510-2.rs +++ b/src/test/ui/issues/issue-40510-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] fn f() { diff --git a/src/test/ui/issues/issue-40510-4.rs b/src/test/ui/issues/issue-40510-4.rs index 45cd4fd94ef8b..5fad7e4a62917 100644 --- a/src/test/ui/issues/issue-40510-4.rs +++ b/src/test/ui/issues/issue-40510-4.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] fn f() { diff --git a/src/test/ui/issues/issue-40962.rs b/src/test/ui/issues/issue-40962.rs index 50d9276e79a32..c051133cbed08 100644 --- a/src/test/ui/issues/issue-40962.rs +++ b/src/test/ui/issues/issue-40962.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! m { ($i:meta) => { #[derive($i)] diff --git a/src/test/ui/issues/issue-41272.rs b/src/test/ui/issues/issue-41272.rs index 4a43e11f47f2e..9cd2003628635 100644 --- a/src/test/ui/issues/issue-41272.rs +++ b/src/test/ui/issues/issue-41272.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo; diff --git a/src/test/ui/issues/issue-41298.rs b/src/test/ui/issues/issue-41298.rs index e8eeabaf3a9e8..c719664de0d06 100644 --- a/src/test/ui/issues/issue-41298.rs +++ b/src/test/ui/issues/issue-41298.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Function { t: T, f: F } diff --git a/src/test/ui/issues/issue-41628.rs b/src/test/ui/issues/issue-41628.rs index b837a1e23466f..92369fdcd4910 100644 --- a/src/test/ui/issues/issue-41628.rs +++ b/src/test/ui/issues/issue-41628.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(dead_code)] #[used] diff --git a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs index 4dddc484d332c..6c6cec25a9a49 100644 --- a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs +++ b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for #41936. The coerce-unsized trait check in // coherence was using subtyping, which triggered variance diff --git a/src/test/ui/issues/issue-41998.rs b/src/test/ui/issues/issue-41998.rs index e54bc201c1db3..2f2842598fc08 100644 --- a/src/test/ui/issues/issue-41998.rs +++ b/src/test/ui/issues/issue-41998.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { diff --git a/src/test/ui/issues/issue-42467.rs b/src/test/ui/issues/issue-42467.rs index 9ad515bdf5a3a..f1a55169ffdfa 100644 --- a/src/test/ui/issues/issue-42467.rs +++ b/src/test/ui/issues/issue-42467.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo(T); diff --git a/src/test/ui/issues/issue-42956.rs b/src/test/ui/issues/issue-42956.rs index 34cb04657eba0..8cf0ae0030693 100644 --- a/src/test/ui/issues/issue-42956.rs +++ b/src/test/ui/issues/issue-42956.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(stable_features)] #![feature(associated_consts)] diff --git a/src/test/ui/issues/issue-43057.rs b/src/test/ui/issues/issue-43057.rs index 3ed64bba9046f..7e1d5036f37f1 100644 --- a/src/test/ui/issues/issue-43057.rs +++ b/src/test/ui/issues/issue-43057.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] macro_rules! column { diff --git a/src/test/ui/issues/issue-43357.rs b/src/test/ui/issues/issue-43357.rs index 6b8e7de85093e..3090e229b6dcc 100644 --- a/src/test/ui/issues/issue-43357.rs +++ b/src/test/ui/issues/issue-43357.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Trait { type Output; diff --git a/src/test/ui/issues/issue-43483.rs b/src/test/ui/issues/issue-43483.rs index a123ae4849661..f071d110f327e 100644 --- a/src/test/ui/issues/issue-43483.rs +++ b/src/test/ui/issues/issue-43483.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] trait VecN { diff --git a/src/test/ui/issues/issue-44005.rs b/src/test/ui/issues/issue-44005.rs index f6d1b7073a2b3..f6fe9fcbd89a3 100644 --- a/src/test/ui/issues/issue-44005.rs +++ b/src/test/ui/issues/issue-44005.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub trait Foo<'a> { type Bar; fn foo(&'a self) -> Self::Bar; diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs index 8ed371485c214..42f30bf30239a 100644 --- a/src/test/ui/issues/issue-44056.rs +++ b/src/test/ui/issues/issue-44056.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // only-x86_64 // no-prefer-dynamic // compile-flags: -Ctarget-feature=+avx -Clto diff --git a/src/test/ui/issues/issue-44247.rs b/src/test/ui/issues/issue-44247.rs index b45d541f21255..ef244e03857bf 100644 --- a/src/test/ui/issues/issue-44247.rs +++ b/src/test/ui/issues/issue-44247.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait T { type X; diff --git a/src/test/ui/issues/issue-44373-2.rs b/src/test/ui/issues/issue-44373-2.rs index 18b2ce85125f2..7fdc4b1ee5b54 100644 --- a/src/test/ui/issues/issue-44373-2.rs +++ b/src/test/ui/issues/issue-44373-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo(bool); diff --git a/src/test/ui/issues/issue-44402.rs b/src/test/ui/issues/issue-44402.rs index 7a2eaac1fd214..29b7eb5ee49c7 100644 --- a/src/test/ui/issues/issue-44402.rs +++ b/src/test/ui/issues/issue-44402.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![feature(never_type)] #![feature(exhaustive_patterns)] diff --git a/src/test/ui/issues/issue-4464.rs b/src/test/ui/issues/issue-4464.rs index c20c1cad66909..13df61124829d 100644 --- a/src/test/ui/issues/issue-4464.rs +++ b/src/test/ui/issues/issue-4464.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-44730.rs b/src/test/ui/issues/issue-44730.rs index 7dae6c8123bd9..93f0445d3433e 100644 --- a/src/test/ui/issues/issue-44730.rs +++ b/src/test/ui/issues/issue-44730.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) //! dox #![deny(missing_docs)] diff --git a/src/test/ui/issues/issue-44851.rs b/src/test/ui/issues/issue-44851.rs index 697b4dcf42745..735678047a539 100644 --- a/src/test/ui/issues/issue-44851.rs +++ b/src/test/ui/issues/issue-44851.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) macro_rules! a { () => { "a" } } diff --git a/src/test/ui/issues/issue-45425.rs b/src/test/ui/issues/issue-45425.rs index a2ef85a2a02c9..99e018ba6c855 100644 --- a/src/test/ui/issues/issue-45425.rs +++ b/src/test/ui/issues/issue-45425.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::ops::Add; diff --git a/src/test/ui/issues/issue-46959.rs b/src/test/ui/issues/issue-46959.rs index e1147ac99ace6..86f1158c1985e 100644 --- a/src/test/ui/issues/issue-46959.rs +++ b/src/test/ui/issues/issue-46959.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(non_camel_case_types)] #[allow(dead_code)] diff --git a/src/test/ui/issues/issue-46964.rs b/src/test/ui/issues/issue-46964.rs index 4688c9b0a1fd0..9cf53973d870a 100644 --- a/src/test/ui/issues/issue-46964.rs +++ b/src/test/ui/issues/issue-46964.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod my_mod { #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct Name<'a> { diff --git a/src/test/ui/issues/issue-47094.rs b/src/test/ui/issues/issue-47094.rs index 6c78a3ba964b4..f17d4f88d9094 100644 --- a/src/test/ui/issues/issue-47094.rs +++ b/src/test/ui/issues/issue-47094.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[repr(C,u8)] enum Foo { diff --git a/src/test/ui/issues/issue-47309.rs b/src/test/ui/issues/issue-47309.rs index a9aeecb61b6a5..03092022d4d55 100644 --- a/src/test/ui/issues/issue-47309.rs +++ b/src/test/ui/issues/issue-47309.rs @@ -3,7 +3,7 @@ // See https://github.com/rust-lang/rust/issues/47309 // compile-flags:-Clink-dead-code -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type="rlib"] diff --git a/src/test/ui/issues/issue-47673.rs b/src/test/ui/issues/issue-47673.rs index 6d7b8f9cc1b0c..0d813e2fad2c8 100644 --- a/src/test/ui/issues/issue-47673.rs +++ b/src/test/ui/issues/issue-47673.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_imports)] use {{}, {}}; diff --git a/src/test/ui/issues/issue-47703-1.rs b/src/test/ui/issues/issue-47703-1.rs index 74323317f1956..95738828647f9 100644 --- a/src/test/ui/issues/issue-47703-1.rs +++ b/src/test/ui/issues/issue-47703-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct AtomicRefMut<'a> { value: &'a mut i32, diff --git a/src/test/ui/issues/issue-47703-tuple.rs b/src/test/ui/issues/issue-47703-tuple.rs index 377eeb67ae1b9..1b285f219dcbc 100644 --- a/src/test/ui/issues/issue-47703-tuple.rs +++ b/src/test/ui/issues/issue-47703-tuple.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct WithDrop; diff --git a/src/test/ui/issues/issue-47703.rs b/src/test/ui/issues/issue-47703.rs index 22f2a1f364d1d..dbf49c7621f67 100644 --- a/src/test/ui/issues/issue-47703.rs +++ b/src/test/ui/issues/issue-47703.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct MyStruct<'a> { field: &'a mut (), diff --git a/src/test/ui/issues/issue-47722.rs b/src/test/ui/issues/issue-47722.rs index cefc872668ceb..b3c344257b6a2 100644 --- a/src/test/ui/issues/issue-47722.rs +++ b/src/test/ui/issues/issue-47722.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests that automatic coercions from &mut T to *mut T // allow borrows of T to expire immediately - essentially, that diff --git a/src/test/ui/issues/issue-47789.rs b/src/test/ui/issues/issue-47789.rs index 334bd608add15..28671db09982f 100644 --- a/src/test/ui/issues/issue-47789.rs +++ b/src/test/ui/issues/issue-47789.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(non_upper_case_globals)] static mut x: &'static u32 = &0; diff --git a/src/test/ui/issues/issue-4830.rs b/src/test/ui/issues/issue-4830.rs index cf94094a7985f..3724bb6393ce6 100644 --- a/src/test/ui/issues/issue-4830.rs +++ b/src/test/ui/issues/issue-4830.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-48551.rs b/src/test/ui/issues/issue-48551.rs index b5dd673b0477d..903b2e2992963 100644 --- a/src/test/ui/issues/issue-48551.rs +++ b/src/test/ui/issues/issue-48551.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test for #48551. Covers a case where duplicate candidates // arose during associated type projection. diff --git a/src/test/ui/issues/issue-49556.rs b/src/test/ui/issues/issue-49556.rs index 46d9e749aae23..d3c6d17f416ae 100644 --- a/src/test/ui/issues/issue-49556.rs +++ b/src/test/ui/issues/issue-49556.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn iter<'a>(data: &'a [usize]) -> impl Iterator + 'a { data.iter() .map( diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs index dd7b9eeb8d54e..79cc107d4fec2 100644 --- a/src/test/ui/issues/issue-49579.rs +++ b/src/test/ui/issues/issue-49579.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-emscripten no i128 support fn fibs(n: u32) -> impl Iterator { diff --git a/src/test/ui/issues/issue-49934.rs b/src/test/ui/issues/issue-49934.rs index ad410f30c04d4..e75381afae9ae 100644 --- a/src/test/ui/issues/issue-49934.rs +++ b/src/test/ui/issues/issue-49934.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(stmt_expr_attributes)] #![warn(unused_attributes)] //~ NOTE lint level defined here diff --git a/src/test/ui/issues/issue-50187.rs b/src/test/ui/issues/issue-50187.rs index cda1c4d5faae6..f530c3853e38c 100644 --- a/src/test/ui/issues/issue-50187.rs +++ b/src/test/ui/issues/issue-50187.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(decl_macro)] diff --git a/src/test/ui/issues/issue-50411.rs b/src/test/ui/issues/issue-50411.rs index 1ba47d3b932ef..a32faa69841fd 100644 --- a/src/test/ui/issues/issue-50411.rs +++ b/src/test/ui/issues/issue-50411.rs @@ -4,7 +4,7 @@ // second time. Uncool. // compile-flags:-Zmir-opt-level=3 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count(); diff --git a/src/test/ui/issues/issue-50471.rs b/src/test/ui/issues/issue-50471.rs index 6868d481962b5..e728e45e60bc2 100644 --- a/src/test/ui/issues/issue-50471.rs +++ b/src/test/ui/issues/issue-50471.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { assert!({false}); diff --git a/src/test/ui/issues/issue-50518.rs b/src/test/ui/issues/issue-50518.rs index d776d181b6268..653b52902d2b5 100644 --- a/src/test/ui/issues/issue-50518.rs +++ b/src/test/ui/issues/issue-50518.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::marker::PhantomData; struct Meta { diff --git a/src/test/ui/issues/issue-50761.rs b/src/test/ui/issues/issue-50761.rs index 70b4bc8b755aa..59d4f9afdaa01 100644 --- a/src/test/ui/issues/issue-50761.rs +++ b/src/test/ui/issues/issue-50761.rs @@ -1,6 +1,6 @@ // Confirm that we don't accidentally divide or mod by zero in llvm_type -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod a { pub trait A {} diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs index 772c45dee11d7..b170e09d02d06 100644 --- a/src/test/ui/issues/issue-50993.rs +++ b/src/test/ui/issues/issue-50993.rs @@ -1,5 +1,5 @@ // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` #![feature(no_core)] diff --git a/src/test/ui/issues/issue-51655.rs b/src/test/ui/issues/issue-51655.rs index 989fcc041a097..c2ad60fd8cfad 100644 --- a/src/test/ui/issues/issue-51655.rs +++ b/src/test/ui/issues/issue-51655.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] const PATH_DOT: &[u8] = &[b'.']; diff --git a/src/test/ui/issues/issue-51947.rs b/src/test/ui/issues/issue-51947.rs index 7b79807e4d7ff..b5ebf156a2730 100644 --- a/src/test/ui/issues/issue-51947.rs +++ b/src/test/ui/issues/issue-51947.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "lib"] #![feature(linkage)] diff --git a/src/test/ui/issues/issue-52992.rs b/src/test/ui/issues/issue-52992.rs index c58656330e12b..727dd43d57454 100644 --- a/src/test/ui/issues/issue-52992.rs +++ b/src/test/ui/issues/issue-52992.rs @@ -2,7 +2,7 @@ // implied bounds was causing outlives relations that were not // properly handled. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/issues/issue-53419.rs b/src/test/ui/issues/issue-53419.rs index bf6791734d4e2..64ac0b1c03b97 100644 --- a/src/test/ui/issues/issue-53419.rs +++ b/src/test/ui/issues/issue-53419.rs @@ -1,4 +1,4 @@ -//compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Foo { bar: dyn for<'r> Fn(usize, &'r dyn FnMut()) diff --git a/src/test/ui/issues/issue-5353.rs b/src/test/ui/issues/issue-5353.rs index 808b73ec72f75..cca17595051da 100644 --- a/src/test/ui/issues/issue-5353.rs +++ b/src/test/ui/issues/issue-5353.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-53568.rs b/src/test/ui/issues/issue-53568.rs index 4d3b3f80a97e5..7644810c94757 100644 --- a/src/test/ui/issues/issue-53568.rs +++ b/src/test/ui/issues/issue-53568.rs @@ -1,7 +1,7 @@ // Regression test for an NLL-related ICE (#53568) -- we failed to // resolve inference variables in "custom type-ops". // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Future { type Item; diff --git a/src/test/ui/issues/issue-53675-a-test-called-panic.rs b/src/test/ui/issues/issue-53675-a-test-called-panic.rs index 8a35b36d46d64..b8dca96946a41 100644 --- a/src/test/ui/issues/issue-53675-a-test-called-panic.rs +++ b/src/test/ui/issues/issue-53675-a-test-called-panic.rs @@ -1,7 +1,7 @@ // rust-lang/rust#53675: At one point the compiler errored when a test // named `panic` used the `assert!` macro in expression position. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: --test mod in_expression_position { diff --git a/src/test/ui/issues/issue-54387.rs b/src/test/ui/issues/issue-54387.rs index ac1033add0ee4..7aee500744d8e 100644 --- a/src/test/ui/issues/issue-54387.rs +++ b/src/test/ui/issues/issue-54387.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct GstRc { _obj: *const (), diff --git a/src/test/ui/issues/issue-54521-1.rs b/src/test/ui/issues/issue-54521-1.rs index d6a14a6e11f67..9bda7635effc2 100644 --- a/src/test/ui/issues/issue-54521-1.rs +++ b/src/test/ui/issues/issue-54521-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test checks that the `remove extra angle brackets` error doesn't happen for some // potential edge-cases.. diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs index 8d3a4e72de411..eca27819a409a 100644 --- a/src/test/ui/issues/issue-54943-1.rs +++ b/src/test/ui/issues/issue-54943-1.rs @@ -1,7 +1,7 @@ // This test is a minimal version of an ICE in the dropck-eyepatch tests // found in the fix for #54943. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn foo(_t: T) { } diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs index 41ca7c1498265..c32f85dbe1a8c 100644 --- a/src/test/ui/issues/issue-54943-2.rs +++ b/src/test/ui/issues/issue-54943-2.rs @@ -2,7 +2,7 @@ // found in the fix for #54943. In particular, this test is in unreachable // code as the initial fix for this ICE only worked if the code was reachable. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn foo(_t: T) { } diff --git a/src/test/ui/issues/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs index 185077bd684a8..a9cc99c79d01a 100644 --- a/src/test/ui/issues/issue-54943-3.rs +++ b/src/test/ui/issues/issue-54943-3.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // FIXME(#54943) This test targets the scenario where proving the WF requirements requires // knowing the value of the `_` type present in the user type annotation - unfortunately, figuring // out the value of that `_` requires type-checking the surrounding code, but that code is dead, diff --git a/src/test/ui/issues/issue-5500-1.rs b/src/test/ui/issues/issue-5500-1.rs index 56f5ce9901e68..edbbe33c66fcc 100644 --- a/src/test/ui/issues/issue-5500-1.rs +++ b/src/test/ui/issues/issue-5500-1.rs @@ -2,7 +2,7 @@ // is OK because the test is here to check that the compiler doesn't ICE (cf. // #5500). -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct TrieMapIterator<'a> { node: &'a usize diff --git a/src/test/ui/issues/issue-5572.rs b/src/test/ui/issues/issue-5572.rs index e5963a7c435f0..db26b0372a6cf 100644 --- a/src/test/ui/issues/issue-5572.rs +++ b/src/test/ui/issues/issue-5572.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs index 3a3eccdc33ce8..32d87586cf4d2 100644 --- a/src/test/ui/issues/issue-56128.rs +++ b/src/test/ui/issues/issue-56128.rs @@ -1,7 +1,7 @@ // Regression test for #56128. When this `pub(super) use...` gets // exploded in the HIR, we were not handling ids correctly. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod bar { pub(super) use self::baz::{x, y}; diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs index bd222b7fe980e..6d6f23d2844a6 100644 --- a/src/test/ui/issues/issue-56202.rs +++ b/src/test/ui/issues/issue-56202.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait FooTrait {} diff --git a/src/test/ui/issues/issue-56411-aux.rs b/src/test/ui/issues/issue-56411-aux.rs index bd689e913aba6..6880a8a98d25e 100644 --- a/src/test/ui/issues/issue-56411-aux.rs +++ b/src/test/ui/issues/issue-56411-aux.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct T {} diff --git a/src/test/ui/issues/issue-57156.rs b/src/test/ui/issues/issue-57156.rs index f20b0f41c7fa5..b6cd8c927a279 100644 --- a/src/test/ui/issues/issue-57156.rs +++ b/src/test/ui/issues/issue-57156.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo { type Output; diff --git a/src/test/ui/issues/issue-57162.rs b/src/test/ui/issues/issue-57162.rs index abe0887e927b5..7ba2f9cea8410 100644 --- a/src/test/ui/issues/issue-57162.rs +++ b/src/test/ui/issues/issue-57162.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo {} impl Foo for dyn Send {} diff --git a/src/test/ui/issues/issue-57410-1.rs b/src/test/ui/issues/issue-57410-1.rs index dab77bd660ca0..c4247b3b11c2c 100644 --- a/src/test/ui/issues/issue-57410-1.rs +++ b/src/test/ui/issues/issue-57410-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Originally from #53925. // Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`. diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/issues/issue-57410.rs index 0d697e5619d24..de7ae4b3c0764 100644 --- a/src/test/ui/issues/issue-57410.rs +++ b/src/test/ui/issues/issue-57410.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`. diff --git a/src/test/ui/issues/issue-5754.rs b/src/test/ui/issues/issue-5754.rs index 78e8701335905..a629729d39501 100644 --- a/src/test/ui/issues/issue-5754.rs +++ b/src/test/ui/issues/issue-5754.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(improper_ctypes)] diff --git a/src/test/ui/issues/issue-5884.rs b/src/test/ui/issues/issue-5884.rs index ad7067bb9b162..acb3e19765e66 100644 --- a/src/test/ui/issues/issue-5884.rs +++ b/src/test/ui/issues/issue-5884.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-5900.rs b/src/test/ui/issues/issue-5900.rs index 5ac7acc8e3980..850e67db629c1 100644 --- a/src/test/ui/issues/issue-5900.rs +++ b/src/test/ui/issues/issue-5900.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-5950.rs b/src/test/ui/issues/issue-5950.rs index 19e0cfc7f2703..5c2250e25fc83 100644 --- a/src/test/ui/issues/issue-5950.rs +++ b/src/test/ui/issues/issue-5950.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs index fe4eaff742d62..dca1e5979effb 100644 --- a/src/test/ui/issues/issue-60662.rs +++ b/src/test/ui/issues/issue-60662.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=hir #![feature(existential_type)] diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout index 5acfdf9ed5342..139808974c6c3 100644 --- a/src/test/ui/issues/issue-60662.stdout +++ b/src/test/ui/issues/issue-60662.stdout @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=hir #![feature(existential_type)] diff --git a/src/test/ui/issues/issue-6341.rs b/src/test/ui/issues/issue-6341.rs index 2b23ccd258643..2fb0fee60bac5 100644 --- a/src/test/ui/issues/issue-6341.rs +++ b/src/test/ui/issues/issue-6341.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 #[derive(PartialEq)] diff --git a/src/test/ui/issues/issue-6470.rs b/src/test/ui/issues/issue-6470.rs index 49a313f90de09..305f46c6d4ee9 100644 --- a/src/test/ui/issues/issue-6470.rs +++ b/src/test/ui/issues/issue-6470.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(improper_ctypes)] diff --git a/src/test/ui/issues/issue-6557.rs b/src/test/ui/issues/issue-6557.rs index aa091ca594aab..70b301d3d9cbb 100644 --- a/src/test/ui/issues/issue-6557.rs +++ b/src/test/ui/issues/issue-6557.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-6898.rs b/src/test/ui/issues/issue-6898.rs index 608c0c80716a6..6bf20d71d1f1e 100644 --- a/src/test/ui/issues/issue-6898.rs +++ b/src/test/ui/issues/issue-6898.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // pretty-expanded FIXME #23616 use std::mem; diff --git a/src/test/ui/issues/issue-6991.rs b/src/test/ui/issues/issue-6991.rs index e835edea1134b..aae67637f2cbf 100644 --- a/src/test/ui/issues/issue-6991.rs +++ b/src/test/ui/issues/issue-6991.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-7268.rs b/src/test/ui/issues/issue-7268.rs index 0b94fabf385df..69901e97894c8 100644 --- a/src/test/ui/issues/issue-7268.rs +++ b/src/test/ui/issues/issue-7268.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-7607-2.rs b/src/test/ui/issues/issue-7607-2.rs index 8b5c8505d3ad7..e336e0b47b283 100644 --- a/src/test/ui/issues/issue-7607-2.rs +++ b/src/test/ui/issues/issue-7607-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs index 619256c787193..9570386730a7b 100644 --- a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs index e4dafc073ab3b..653d002fa61b5 100644 --- a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs +++ b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-8398.rs b/src/test/ui/issues/issue-8398.rs index a65c667b08e45..5fe88854b39f4 100644 --- a/src/test/ui/issues/issue-8398.rs +++ b/src/test/ui/issues/issue-8398.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-8521.rs b/src/test/ui/issues/issue-8521.rs index 7007c8a3a98bc..02a0e14d55e62 100644 --- a/src/test/ui/issues/issue-8521.rs +++ b/src/test/ui/issues/issue-8521.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo1 {} trait A {} diff --git a/src/test/ui/issues/issue-8578.rs b/src/test/ui/issues/issue-8578.rs index 4cc21234796ae..6ffb721372a4e 100644 --- a/src/test/ui/issues/issue-8578.rs +++ b/src/test/ui/issues/issue-8578.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-9110.rs b/src/test/ui/issues/issue-9110.rs index 30acd61a34a09..f3bab42ee165f 100644 --- a/src/test/ui/issues/issue-9110.rs +++ b/src/test/ui/issues/issue-9110.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 #![allow(non_snake_case)] diff --git a/src/test/ui/issues/issue-9243.rs b/src/test/ui/issues/issue-9243.rs index e877dd6492214..78237421c982b 100644 --- a/src/test/ui/issues/issue-9243.rs +++ b/src/test/ui/issues/issue-9243.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Regression test for issue 9243 #![allow(non_upper_case_globals)] diff --git a/src/test/ui/issues/issue-9249.rs b/src/test/ui/issues/issue-9249.rs index e4e9c4597192e..b1f2bd7569a96 100644 --- a/src/test/ui/issues/issue-9249.rs +++ b/src/test/ui/issues/issue-9249.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/issues/issue-9719.rs b/src/test/ui/issues/issue-9719.rs index 1e38ab9c6c2a4..58eb32b111dd9 100644 --- a/src/test/ui/issues/issue-9719.rs +++ b/src/test/ui/issues/issue-9719.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/lint/command-line-lint-group-allow.rs b/src/test/ui/lint/command-line-lint-group-allow.rs index ac98724d03757..f26e157bc706e 100644 --- a/src/test/ui/lint/command-line-lint-group-allow.rs +++ b/src/test/ui/lint/command-line-lint-group-allow.rs @@ -1,5 +1,5 @@ // compile-flags: -A bad-style -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _InappropriateCamelCasing = true; diff --git a/src/test/ui/lint/command-line-lint-group-warn.rs b/src/test/ui/lint/command-line-lint-group-warn.rs index 73dd656f60cf4..d3a4201ba6070 100644 --- a/src/test/ui/lint/command-line-lint-group-warn.rs +++ b/src/test/ui/lint/command-line-lint-group-warn.rs @@ -1,5 +1,5 @@ // compile-flags: -W bad-style -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _InappropriateCamelCasing = true; diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed index d52c651ce38c8..9fce66a0a83cc 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // run-rustfix #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.rs b/src/test/ui/lint/inclusive-range-pattern-syntax.rs index 5174a8b8b7e6e..f886e778b5938 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.rs +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // run-rustfix #![warn(ellipsis_inclusive_range_patterns)] diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index 7d3fd441ae5db..4cb35e907c8f9 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_syntax)] #![feature(box_patterns)] diff --git a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs index 8872c0047fda5..47063a7c26786 100644 --- a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs +++ b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_parens)] diff --git a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs index e4be1edc5d7b5..3802e01a77556 100644 --- a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs +++ b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![forbid(non_camel_case_types)] #![allow(dead_code)] diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs index 3a52996195c0d..eda9e2cdfaa2f 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs +++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(ellipsis_inclusive_range_patterns)] #![allow(unreachable_patterns)] diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs index 8ca5af21630a2..95da4efa59041 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Issue #7526: lowercase static constants in patterns look like bindings // This is similar to lint-lowercase-static-const-pattern.rs, except it diff --git a/src/test/ui/lint/lint-non-camel-case-variant.rs b/src/test/ui/lint/lint-non-camel-case-variant.rs index 1f06b28398426..434e24c1d278c 100644 --- a/src/test/ui/lint/lint-non-camel-case-variant.rs +++ b/src/test/ui/lint/lint-non-camel-case-variant.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(non_camel_case_types)] diff --git a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs index c2fdfb4fe421a..d025ee948546a 100644 --- a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs +++ b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // This is ok because we often use the trailing underscore to mean 'prime' diff --git a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs index 9a6487d254239..5bec82ce1a6f5 100644 --- a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs +++ b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode.rs b/src/test/ui/lint/lint-nonstandard-style-unicode.rs index a0b4130c3e92a..40f0a676381b4 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] diff --git a/src/test/ui/lint/lint-output-format-2.rs b/src/test/ui/lint/lint-output-format-2.rs index c9b33f06e215a..32a41179965f3 100644 --- a/src/test/ui/lint/lint-output-format-2.rs +++ b/src/test/ui/lint/lint-output-format-2.rs @@ -1,7 +1,7 @@ // aux-build:lint_output_format.rs #![feature(unstable_test_feature)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) extern crate lint_output_format; use lint_output_format::{foo, bar}; diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index a2031c2189ae1..652fd04bdf526 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs diff --git a/src/test/ui/lint/lint-type-overflow2.rs b/src/test/ui/lint/lint-type-overflow2.rs index 507e8d0734970..c1f874c079cb5 100644 --- a/src/test/ui/lint/lint-type-overflow2.rs +++ b/src/test/ui/lint/lint-type-overflow2.rs @@ -1,15 +1,13 @@ // compile-flags: -O -#![warn(overflowing_literals)] -#![warn(const_err)] -// compile-pass -#[allow(unused_variables)] +#![deny(overflowing_literals)] +#![deny(const_err)] fn main() { - let x2: i8 = --128; //~ warn: literal out of range for i8 + let x2: i8 = --128; //~ ERROR literal out of range for `i8` - let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32 - let x = 3.40282357e+38_f32; //~ warn: literal out of range for f32 - let x = -1.7976931348623159e+308_f64; //~ warn: literal out of range for f64 - let x = 1.7976931348623159e+308_f64; //~ warn: literal out of range for f64 + let x = -3.40282357e+38_f32; //~ ERROR literal out of range for `f32` + let x = 3.40282357e+38_f32; //~ ERROR literal out of range for `f32` + let x = -1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64` + let x = 1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64` } diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr index c76e9e25d5a93..761b095464fe8 100644 --- a/src/test/ui/lint/lint-type-overflow2.stderr +++ b/src/test/ui/lint/lint-type-overflow2.stderr @@ -1,48 +1,38 @@ -warning: literal out of range for `i8` - --> $DIR/lint-type-overflow2.rs:9:20 +error: literal out of range for `i8` + --> $DIR/lint-type-overflow2.rs:7:20 | LL | let x2: i8 = --128; | ^^^ | note: lint level defined here - --> $DIR/lint-type-overflow2.rs:2:9 + --> $DIR/lint-type-overflow2.rs:3:9 | -LL | #![warn(overflowing_literals)] +LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ -warning: literal out of range for `f32` - --> $DIR/lint-type-overflow2.rs:11:14 +error: literal out of range for `f32` + --> $DIR/lint-type-overflow2.rs:9:14 | LL | let x = -3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ -warning: literal out of range for `f32` - --> $DIR/lint-type-overflow2.rs:12:14 +error: literal out of range for `f32` + --> $DIR/lint-type-overflow2.rs:10:14 | LL | let x = 3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ -warning: literal out of range for `f64` - --> $DIR/lint-type-overflow2.rs:13:14 +error: literal out of range for `f64` + --> $DIR/lint-type-overflow2.rs:11:14 | LL | let x = -1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: literal out of range for `f64` - --> $DIR/lint-type-overflow2.rs:14:14 +error: literal out of range for `f64` + --> $DIR/lint-type-overflow2.rs:12:14 | LL | let x = 1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: this expression will panic at runtime - --> $DIR/lint-type-overflow2.rs:9:18 - | -LL | let x2: i8 = --128; - | ^^^^^ attempt to negate with overflow - | -note: lint level defined here - --> $DIR/lint-type-overflow2.rs:3:9 - | -LL | #![warn(const_err)] - | ^^^^^^^^^ +error: aborting due to 5 previous errors diff --git a/src/test/ui/lint/lint-unknown-feature-default.rs b/src/test/ui/lint/lint-unknown-feature-default.rs index e04363faf4b60..aebc4f1808573 100644 --- a/src/test/ui/lint/lint-unknown-feature-default.rs +++ b/src/test/ui/lint/lint-unknown-feature-default.rs @@ -4,7 +4,7 @@ // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { } diff --git a/src/test/ui/lint/lint-unknown-feature.rs b/src/test/ui/lint/lint-unknown-feature.rs index c372a980bed5e..93fa7a6e96e37 100644 --- a/src/test/ui/lint/lint-unknown-feature.rs +++ b/src/test/ui/lint/lint-unknown-feature.rs @@ -4,7 +4,7 @@ // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() {} diff --git a/src/test/ui/lint/lints-in-foreign-macros.rs b/src/test/ui/lint/lints-in-foreign-macros.rs index adef2f9e7690f..e381c81453b10 100644 --- a/src/test/ui/lint/lints-in-foreign-macros.rs +++ b/src/test/ui/lint/lints-in-foreign-macros.rs @@ -1,5 +1,5 @@ // aux-build:lints-in-foreign-macros.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_imports)] //~ missing documentation for crate [missing_docs] #![warn(missing_docs)] diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/must-use-ops.rs index 60baa2349876c..d0adf6a875d3e 100644 --- a/src/test/ui/lint/must-use-ops.rs +++ b/src/test/ui/lint/must-use-ops.rs @@ -1,6 +1,6 @@ // Issue #50124 - Test warning for unused operator expressions -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_must_use)] diff --git a/src/test/ui/lint/must_use-array.rs b/src/test/ui/lint/must_use-array.rs new file mode 100644 index 0000000000000..97825dd2f6c43 --- /dev/null +++ b/src/test/ui/lint/must_use-array.rs @@ -0,0 +1,47 @@ +#![deny(unused_must_use)] + +#[must_use] +struct S; + +struct A; + +#[must_use] +trait T {} + +impl T for A {} + +fn empty() -> [S; 0] { + [] +} + +fn singleton() -> [S; 1] { + [S] +} + +fn many() -> [S; 4] { + [S, S, S, S] +} + +fn array_of_impl_trait() -> [impl T; 2] { + [A, A] +} + +fn impl_array() -> [(u8, Box); 2] { + [(0, Box::new(A)), (0, Box::new(A))] +} + +fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] { + [[[S], [S]]] +} + +fn main() { + empty(); // ok + singleton(); //~ ERROR unused array of `S` that must be used + many(); //~ ERROR unused array of `S` that must be used + ([S], 0, ()); //~ ERROR unused array of `S` in tuple element 0 that must be used + array_of_impl_trait(); //~ ERROR unused array of implementers of `T` that must be used + impl_array(); + //~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used + array_of_arrays_of_arrays(); + //~^ ERROR unused array of arrays of arrays of `S` that must be used +} diff --git a/src/test/ui/lint/must_use-array.stderr b/src/test/ui/lint/must_use-array.stderr new file mode 100644 index 0000000000000..a6dbd8e93d4d3 --- /dev/null +++ b/src/test/ui/lint/must_use-array.stderr @@ -0,0 +1,44 @@ +error: unused array of `S` that must be used + --> $DIR/must_use-array.rs:39:5 + | +LL | singleton(); + | ^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/must_use-array.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused array of `S` that must be used + --> $DIR/must_use-array.rs:40:5 + | +LL | many(); + | ^^^^^^^ + +error: unused array of `S` in tuple element 0 that must be used + --> $DIR/must_use-array.rs:41:6 + | +LL | ([S], 0, ()); + | ^^^ + +error: unused array of implementers of `T` that must be used + --> $DIR/must_use-array.rs:42:5 + | +LL | array_of_impl_trait(); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unused array of boxed `T` trait objects in tuple element 1 that must be used + --> $DIR/must_use-array.rs:43:5 + | +LL | impl_array(); + | ^^^^^^^^^^^^^ + +error: unused array of arrays of arrays of `S` that must be used + --> $DIR/must_use-array.rs:45:5 + | +LL | array_of_arrays_of_arrays(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/must_use-trait.rs index 23df4fa6132d3..0aa751443a080 100644 --- a/src/test/ui/lint/must_use-trait.rs +++ b/src/test/ui/lint/must_use-trait.rs @@ -17,6 +17,23 @@ fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { Anon {} } +fn get_boxed_critical() -> Box { + Box::new(Anon {}) +} + +fn get_nested_boxed_critical() -> Box> { + Box::new(Box::new(Anon {})) +} + +fn get_critical_tuple() -> (u32, Box, impl Critical, ()) { + (0, get_boxed_critical(), get_critical(), ()) +} + fn main() { get_critical(); //~ ERROR unused implementer of `Critical` that must be used + get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used + get_nested_boxed_critical(); + //~^ ERROR unused boxed boxed `Critical` trait object that must be used + get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1 + //~^ ERROR unused implementer of `Critical` in tuple element 2 } diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/must_use-trait.stderr index 7e2b2f67964ac..be74362e29d62 100644 --- a/src/test/ui/lint/must_use-trait.stderr +++ b/src/test/ui/lint/must_use-trait.stderr @@ -1,5 +1,5 @@ error: unused implementer of `Critical` that must be used - --> $DIR/must_use-trait.rs:21:5 + --> $DIR/must_use-trait.rs:33:5 | LL | get_critical(); | ^^^^^^^^^^^^^^^ @@ -10,5 +10,29 @@ note: lint level defined here LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: unused boxed `Critical` trait object that must be used + --> $DIR/must_use-trait.rs:34:5 + | +LL | get_boxed_critical(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: unused boxed boxed `Critical` trait object that must be used + --> $DIR/must_use-trait.rs:35:5 + | +LL | get_nested_boxed_critical(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unused boxed `Critical` trait object in tuple element 1 that must be used + --> $DIR/must_use-trait.rs:37:5 + | +LL | get_critical_tuple(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: unused implementer of `Critical` in tuple element 2 that must be used + --> $DIR/must_use-trait.rs:37:5 + | +LL | get_critical_tuple(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors diff --git a/src/test/ui/lint/not_found.rs b/src/test/ui/lint/not_found.rs index 0b5a4eb785195..979a67b15583a 100644 --- a/src/test/ui/lint/not_found.rs +++ b/src/test/ui/lint/not_found.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // this tests the `unknown_lint` lint, especially the suggestions diff --git a/src/test/ui/lint/reasons.rs b/src/test/ui/lint/reasons.rs index eba91d92afb5b..5320987040afc 100644 --- a/src/test/ui/lint/reasons.rs +++ b/src/test/ui/lint/reasons.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(lint_reasons)] diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index 64e5951207379..c145bd256d8f2 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(overflowing_literals)] fn main() { diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.rs b/src/test/ui/lint/unreachable_pub-pub_crate.rs index 6739c7f096b59..27b437b22eb03 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.rs +++ b/src/test/ui/lint/unreachable_pub-pub_crate.rs @@ -4,7 +4,7 @@ // suggestions to use `crate` given when it is on). When that feature becomes // stable, this test can be deleted. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] diff --git a/src/test/ui/lint/unreachable_pub.rs b/src/test/ui/lint/unreachable_pub.rs index 12726b6ecae38..545281604ea50 100644 --- a/src/test/ui/lint/unreachable_pub.rs +++ b/src/test/ui/lint/unreachable_pub.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(crate_visibility_modifier)] diff --git a/src/test/ui/lint/unused_import_warning_issue_45268.rs b/src/test/ui/lint/unused_import_warning_issue_45268.rs index 0bd7751113593..68a5819c9c708 100644 --- a/src/test/ui/lint/unused_import_warning_issue_45268.rs +++ b/src/test/ui/lint/unused_import_warning_issue_45268.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_imports)] // Warning explanation here, it's OK diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index 26ab9fbe5c8f2..d234a2fb1a02c 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -2,7 +2,7 @@ // should also deal with the edge cases where a label is shadowed, // within nested loops -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(label_break_value)] #![warn(unused_labels)] diff --git a/src/test/ui/lint/unused_parens_json_suggestion.rs b/src/test/ui/lint/unused_parens_json_suggestion.rs index 4462c53152aca..185bfacea8046 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_json_suggestion.rs @@ -1,5 +1,5 @@ // compile-flags: --error-format pretty-json -Zunstable-options -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index 07d96d5c48250..396395a17f732 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -8,8 +8,8 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 576, - "byte_end": 589, + "byte_start": 611, + "byte_end": 624, "line_start": 15, "line_end": 15, "column_start": 14, @@ -36,8 +36,8 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 422, - "byte_end": 435, + "byte_start": 457, + "byte_end": 470, "line_start": 10, "line_end": 10, "column_start": 9, @@ -66,8 +66,8 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 576, - "byte_end": 589, + "byte_start": 611, + "byte_end": 624, "line_start": 15, "line_end": 15, "column_start": 14, diff --git a/src/test/ui/lint/use-redundant.rs b/src/test/ui/lint/use-redundant.rs index 328f8232bafa8..6ec2af068018b 100644 --- a/src/test/ui/lint/use-redundant.rs +++ b/src/test/ui/lint/use-redundant.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused_imports)] use crate::foo::Bar; //~ WARNING first import diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs index 93f322ab36804..316ee64072de0 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-tidy-linelength diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs index 27f9862f70da5..5ed8b2f416ecd 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // ignore-tidy-linelength diff --git a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs b/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs index 435ad3391a0d0..9047fbb95a2ea 100644 --- a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs +++ b/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs @@ -1,7 +1,7 @@ // Issue #21633: reject duplicate loop labels in function bodies. // This is testing interaction between lifetime-params and labels. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, unused_variables)] diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs index 656ed6576e269..9bb6a253b7f4a 100644 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs +++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, unused_variables)] diff --git a/src/test/ui/macros/macro-expanded-include/test.rs b/src/test/ui/macros/macro-expanded-include/test.rs index fe697db9fbed6..b8eb854b0b0f1 100644 --- a/src/test/ui/macros/macro-expanded-include/test.rs +++ b/src/test/ui/macros/macro-expanded-include/test.rs @@ -1,5 +1,5 @@ // ignore-emscripten no asm! support -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(asm)] #![allow(unused)] diff --git a/src/test/ui/macros/macro-path-prelude-pass.rs b/src/test/ui/macros/macro-path-prelude-pass.rs index 3d35d53f777db..8daa1c84f1dc3 100644 --- a/src/test/ui/macros/macro-path-prelude-pass.rs +++ b/src/test/ui/macros/macro-path-prelude-pass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_prelude)] diff --git a/src/test/ui/macros/macro-shadowing-relaxed.rs b/src/test/ui/macros/macro-shadowing-relaxed.rs index 2477226ce212a..b2a639218b994 100644 --- a/src/test/ui/macros/macro-shadowing-relaxed.rs +++ b/src/test/ui/macros/macro-shadowing-relaxed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:macro-in-other-crate.rs #![feature(decl_macro)] diff --git a/src/test/ui/macros/macro-stmt-matchers.rs b/src/test/ui/macros/macro-stmt-matchers.rs index 6e53eb05121cc..a643e50e99557 100644 --- a/src/test/ui/macros/macro-stmt-matchers.rs +++ b/src/test/ui/macros/macro-stmt-matchers.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { diff --git a/src/test/ui/macros/macro-tt-matchers.rs b/src/test/ui/macros/macro-tt-matchers.rs index 17df72f36dbfe..2ee41b0880e18 100644 --- a/src/test/ui/macros/macro-tt-matchers.rs +++ b/src/test/ui/macros/macro-tt-matchers.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] macro_rules! foo { diff --git a/src/test/ui/macros/macro-use-scope.rs b/src/test/ui/macros/macro-use-scope.rs index 03d57d2229991..5e58fc9c1ede8 100644 --- a/src/test/ui/macros/macro-use-scope.rs +++ b/src/test/ui/macros/macro-use-scope.rs @@ -1,6 +1,6 @@ // aux-build:two_macros.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] fn f() { diff --git a/src/test/ui/macros/must-use-in-macro-55516.rs b/src/test/ui/macros/must-use-in-macro-55516.rs index a5de32e5d2a8b..4b6b65ec48b26 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.rs +++ b/src/test/ui/macros/must-use-in-macro-55516.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Wunused // make sure write!() can't hide its unused Result diff --git a/src/test/ui/macros/trace-macro.rs b/src/test/ui/macros/trace-macro.rs index efd658dd2b9a8..576120811dbc6 100644 --- a/src/test/ui/macros/trace-macro.rs +++ b/src/test/ui/macros/trace-macro.rs @@ -1,5 +1,5 @@ // compile-flags: -Z trace-macros -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { println!("Hello, World!"); diff --git a/src/test/ui/malformed/malformed-regressions.rs b/src/test/ui/malformed/malformed-regressions.rs index b5c992440d4dc..c1a9d04e6d5cb 100644 --- a/src/test/ui/malformed/malformed-regressions.rs +++ b/src/test/ui/malformed/malformed-regressions.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[doc] //~ WARN attribute must be of the form #[ignore()] //~ WARN attribute must be of the form diff --git a/src/test/ui/maybe-bounds-where-cpass.rs b/src/test/ui/maybe-bounds-where-cpass.rs index 860de200f6256..d4bc05f7cb421 100644 --- a/src/test/ui/maybe-bounds-where-cpass.rs +++ b/src/test/ui/maybe-bounds-where-cpass.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(*const T) where T: ?Sized; diff --git a/src/test/ui/methods/method-call-lifetime-args-subst-index.rs b/src/test/ui/methods/method-call-lifetime-args-subst-index.rs index 4ee09dcdf1965..8df58a3486eb0 100644 --- a/src/test/ui/methods/method-call-lifetime-args-subst-index.rs +++ b/src/test/ui/methods/method-call-lifetime-args-subst-index.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] struct S; diff --git a/src/test/ui/methods/method-trait-object-with-hrtb.rs b/src/test/ui/methods/method-trait-object-with-hrtb.rs index da2f13f5a2f8a..d1bee676c2f5c 100644 --- a/src/test/ui/methods/method-trait-object-with-hrtb.rs +++ b/src/test/ui/methods/method-trait-object-with-hrtb.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that method probing ObjectCandidate works in the presence of // auto traits and/or HRTBs. diff --git a/src/test/ui/missing/missing-semicolon-warning.rs b/src/test/ui/missing/missing-semicolon-warning.rs index 11204af702a1c..d962a52139eea 100644 --- a/src/test/ui/missing/missing-semicolon-warning.rs +++ b/src/test/ui/missing/missing-semicolon-warning.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] macro_rules! m { diff --git a/src/test/ui/never-assign-dead-code.rs b/src/test/ui/never-assign-dead-code.rs index 6b047c3506535..fd5fbc30611a9 100644 --- a/src/test/ui/never-assign-dead-code.rs +++ b/src/test/ui/never-assign-dead-code.rs @@ -1,7 +1,7 @@ // Test that an assignment of type ! makes the rest of the block dead code. #![feature(never_type)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/never_transmute_never.rs b/src/test/ui/never_transmute_never.rs index ef78eaa2120cf..5bad756b8762f 100644 --- a/src/test/ui/never_transmute_never.rs +++ b/src/test/ui/never_transmute_never.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type="lib"] diff --git a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs index 8ed6554877eae..7679bf22e3cd4 100644 --- a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs +++ b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that we propagate region relations from closures precisely when there is // more than one non-local lower bound. diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs index d1945f4864c9a..1df7c6114eeae 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs @@ -4,7 +4,7 @@ // regions is erased. // compile-flags:-Zborrowck=mir -Zverbose -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/constant.rs b/src/test/ui/nll/constant.rs index 2bc40fcb32783..b1ea2c906da88 100644 --- a/src/test/ui/nll/constant.rs +++ b/src/test/ui/nll/constant.rs @@ -2,7 +2,7 @@ // arbitrary types without ICEs. // compile-flags:-Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) const HI: &str = "hi"; diff --git a/src/test/ui/nll/drop-may-dangle.rs b/src/test/ui/nll/drop-may-dangle.rs index 5c72225b11f0f..0f3d27d066560 100644 --- a/src/test/ui/nll/drop-may-dangle.rs +++ b/src/test/ui/nll/drop-may-dangle.rs @@ -3,7 +3,7 @@ // including) the call to `use_x`. The `else` branch is not included. // compile-flags:-Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![feature(dropck_eyepatch)] diff --git a/src/test/ui/nll/empty-type-predicate.rs b/src/test/ui/nll/empty-type-predicate.rs index 75431d40ce542..48073f8749e75 100644 --- a/src/test/ui/nll/empty-type-predicate.rs +++ b/src/test/ui/nll/empty-type-predicate.rs @@ -3,7 +3,7 @@ // `dyn T:` is lowered to `dyn T: ReEmpty` - check that we don't ICE in NLL for // the unexpected region. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait T {} fn f() where dyn T: {} diff --git a/src/test/ui/nll/extra-unused-mut.rs b/src/test/ui/nll/extra-unused-mut.rs index 6d0d6e16a6775..e9c8df46213b5 100644 --- a/src/test/ui/nll/extra-unused-mut.rs +++ b/src/test/ui/nll/extra-unused-mut.rs @@ -1,6 +1,6 @@ // extra unused mut lint tests for #51918 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(generators, nll)] #![deny(unused_mut)] diff --git a/src/test/ui/nll/generator-distinct-lifetime.rs b/src/test/ui/nll/generator-distinct-lifetime.rs index d479a61baa22b..1bd39db35d9aa 100644 --- a/src/test/ui/nll/generator-distinct-lifetime.rs +++ b/src/test/ui/nll/generator-distinct-lifetime.rs @@ -6,7 +6,7 @@ // over a yield -- because the data that is borrowed (`*x`) is not // stored on the stack. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn foo(x: &mut u32) { move || { diff --git a/src/test/ui/nll/issue-16223.rs b/src/test/ui/nll/issue-16223.rs index e75362750645c..c1205ba96ad69 100644 --- a/src/test/ui/nll/issue-16223.rs +++ b/src/test/ui/nll/issue-16223.rs @@ -13,7 +13,7 @@ // | // = note: move occurs because the value has type `A`, which does not implement the `Copy` trait -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_patterns)] diff --git a/src/test/ui/nll/issue-21114-ebfull.rs b/src/test/ui/nll/issue-21114-ebfull.rs index 1fe4fffa324a6..5a5db1a17f3f4 100644 --- a/src/test/ui/nll/issue-21114-ebfull.rs +++ b/src/test/ui/nll/issue-21114-ebfull.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::collections::HashMap; use std::sync::Mutex; diff --git a/src/test/ui/nll/issue-21114-kixunil.rs b/src/test/ui/nll/issue-21114-kixunil.rs index 80a85293e5a5c..32c97a651c50f 100644 --- a/src/test/ui/nll/issue-21114-kixunil.rs +++ b/src/test/ui/nll/issue-21114-kixunil.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn from_stdin(min: u64) -> Vec { use std::io::BufRead; diff --git a/src/test/ui/nll/issue-22323-temp-destruction.rs b/src/test/ui/nll/issue-22323-temp-destruction.rs index 6357c3ccef1f8..1add91b1bd04a 100644 --- a/src/test/ui/nll/issue-22323-temp-destruction.rs +++ b/src/test/ui/nll/issue-22323-temp-destruction.rs @@ -1,7 +1,7 @@ // rust-lang/rust#22323: regression test demonstrating that NLL // precisely tracks temporary destruction order. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _s = construct().borrow().consume_borrowed(); diff --git a/src/test/ui/nll/issue-30104.rs b/src/test/ui/nll/issue-30104.rs index 27e519005f62b..3f4818a28c8d6 100644 --- a/src/test/ui/nll/issue-30104.rs +++ b/src/test/ui/nll/issue-30104.rs @@ -1,6 +1,6 @@ // Regression test for #30104 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::{Deref, DerefMut}; diff --git a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs index 7e0ffd6cf3644..bffff65015850 100644 --- a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs +++ b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#32382: Borrow checker used to complain about // `foobar_3` in the `impl` below, presumably due to some interaction diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs index c50473511f116..8bf9028690fcd 100644 --- a/src/test/ui/nll/issue-43058.rs +++ b/src/test/ui/nll/issue-43058.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::borrow::Cow; diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs index 3f8e0f5ad3d7a..ecd7071ecc783 100644 --- a/src/test/ui/nll/issue-47022.rs +++ b/src/test/ui/nll/issue-47022.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct LoadedObject { bodies: Vec, diff --git a/src/test/ui/nll/issue-50716-1.rs b/src/test/ui/nll/issue-50716-1.rs index ec992959a66ca..1e602f27247d7 100644 --- a/src/test/ui/nll/issue-50716-1.rs +++ b/src/test/ui/nll/issue-50716-1.rs @@ -3,7 +3,7 @@ // bounds derived from `Sized` requirements” that checks that the fixed compiler // accepts this code fragment with both AST and MIR borrow checkers. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Qey(Q); diff --git a/src/test/ui/nll/issue-51351.rs b/src/test/ui/nll/issue-51351.rs index b45477c7fb10d..efffe80aae45f 100644 --- a/src/test/ui/nll/issue-51351.rs +++ b/src/test/ui/nll/issue-51351.rs @@ -6,7 +6,7 @@ // of the closure, as they were not present in the closure's generic // declarations otherwise. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn creash<'a>() { let x: &'a () = &(); diff --git a/src/test/ui/nll/issue-52078.rs b/src/test/ui/nll/issue-52078.rs index 4b8e6c6807530..935bf8cda5e99 100644 --- a/src/test/ui/nll/issue-52078.rs +++ b/src/test/ui/nll/issue-52078.rs @@ -2,7 +2,7 @@ // between `'a` and `'b` below due to inference variables introduced // during the normalization process. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Drain<'a, T: 'a> { _marker: ::std::marker::PhantomData<&'a T>, diff --git a/src/test/ui/nll/issue-53119.rs b/src/test/ui/nll/issue-53119.rs index 7a47a77f6bb4c..f5400aaad8b45 100644 --- a/src/test/ui/nll/issue-53119.rs +++ b/src/test/ui/nll/issue-53119.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::Deref; diff --git a/src/test/ui/nll/issue-53570.rs b/src/test/ui/nll/issue-53570.rs index 81c50edfed1a4..25c1929b227c8 100644 --- a/src/test/ui/nll/issue-53570.rs +++ b/src/test/ui/nll/issue-53570.rs @@ -6,7 +6,7 @@ // parameter `x` -- since `'b` cannot be expressed in the caller's // space, that got promoted th `'static`. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::cell::{RefCell, Ref}; diff --git a/src/test/ui/nll/issue-55344.rs b/src/test/ui/nll/issue-55344.rs index 521d4d33d8633..a65635585dbb6 100644 --- a/src/test/ui/nll/issue-55344.rs +++ b/src/test/ui/nll/issue-55344.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_mut)] diff --git a/src/test/ui/nll/issue-55651.rs b/src/test/ui/nll/issue-55651.rs index 976098e40ad3d..73fce288f8bb6 100644 --- a/src/test/ui/nll/issue-55651.rs +++ b/src/test/ui/nll/issue-55651.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(untagged_unions)] diff --git a/src/test/ui/nll/issue-57280-1.rs b/src/test/ui/nll/issue-57280-1.rs index e02d6a0cb5a39..f9cea42e7c4cc 100644 --- a/src/test/ui/nll/issue-57280-1.rs +++ b/src/test/ui/nll/issue-57280-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo<'a> { const C: &'a u32; diff --git a/src/test/ui/nll/issue-57280.rs b/src/test/ui/nll/issue-57280.rs index 776a0d359cda6..65ca23cc88f6c 100644 --- a/src/test/ui/nll/issue-57280.rs +++ b/src/test/ui/nll/issue-57280.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo { const BLAH: &'static str; diff --git a/src/test/ui/nll/issue-61311-normalize.rs b/src/test/ui/nll/issue-61311-normalize.rs index 1164e9ef2d62f..9237c27f57ea8 100644 --- a/src/test/ui/nll/issue-61311-normalize.rs +++ b/src/test/ui/nll/issue-61311-normalize.rs @@ -1,7 +1,7 @@ // Regression test for #61311 // We would ICE after failing to normalize `Self::Proj` in the `impl` below. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct Unit; trait Obj {} diff --git a/src/test/ui/nll/issue-61320-normalize.rs b/src/test/ui/nll/issue-61320-normalize.rs index a36ccd36113b5..59bceed08f909 100644 --- a/src/test/ui/nll/issue-61320-normalize.rs +++ b/src/test/ui/nll/issue-61320-normalize.rs @@ -1,7 +1,7 @@ // Regression test for #61320 // This is the same issue as #61311, just a larger test case. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) pub struct AndThen where diff --git a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs index 3415c3eeabcdb..72212e9e70c0f 100644 --- a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs +++ b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs @@ -1,5 +1,5 @@ // compile-flags: -Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs index fdf3f59484172..5c340434691f1 100644 --- a/src/test/ui/nll/projection-return.rs +++ b/src/test/ui/nll/projection-return.rs @@ -1,5 +1,5 @@ // compile-flags:-Zborrowck=mir -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs index 23caa59b6b7bf..1bbc896c270a1 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs +++ b/src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs @@ -6,7 +6,7 @@ // another -- effectively, the single lifetime `'a` is just inferred // to be the intersection of the two distinct lifetimes. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:-Zno-leak-check #![feature(nll)] diff --git a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs index bac9e26588cae..4e8599b2e3fbe 100644 --- a/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs +++ b/src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs @@ -2,7 +2,7 @@ // function returning always its first argument can be upcast to one // that returns either first or second argument. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:-Zno-leak-check #![feature(nll)] diff --git a/src/test/ui/nll/relate_tys/issue-48071.rs b/src/test/ui/nll/relate_tys/issue-48071.rs index 72987629848c8..36cd57a1b2d34 100644 --- a/src/test/ui/nll/relate_tys/issue-48071.rs +++ b/src/test/ui/nll/relate_tys/issue-48071.rs @@ -4,7 +4,7 @@ // placeholder region, but in NLL land it would fail because we had // rewritten `'static` to a region variable. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Foo { fn foo(&self) { } diff --git a/src/test/ui/nll/ty-outlives/issue-53789-1.rs b/src/test/ui/nll/ty-outlives/issue-53789-1.rs index dc67c1a68aaf6..2293d7d4bbc0d 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-1.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-1.rs @@ -1,6 +1,6 @@ // Regression test for #53789. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::collections::BTreeMap; diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs index 1b80be2eaff99..313b615fe8085 100644 --- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs +++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs @@ -1,6 +1,6 @@ // Regression test for #53789. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::collections::BTreeMap; use std::ops::Range; diff --git a/src/test/ui/nll/ty-outlives/issue-55756.rs b/src/test/ui/nll/ty-outlives/issue-55756.rs index cda3915849e2d..147ea20348942 100644 --- a/src/test/ui/nll/ty-outlives/issue-55756.rs +++ b/src/test/ui/nll/ty-outlives/issue-55756.rs @@ -16,7 +16,7 @@ // Fixed by tweaking the solver to recognize that the constraint from // the environment duplicates one from the trait. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type="lib"] diff --git a/src/test/ui/nll/ty-outlives/projection-body.rs b/src/test/ui/nll/ty-outlives/projection-body.rs index 2e105ece8b55c..148120d848bc0 100644 --- a/src/test/ui/nll/ty-outlives/projection-body.rs +++ b/src/test/ui/nll/ty-outlives/projection-body.rs @@ -1,7 +1,7 @@ // Test that when we infer the lifetime to a subset of the fn body, it // works out. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyTrait<'a> { type Output; diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs index 452a8ea4f85d2..b9c9611e38c2c 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs @@ -3,7 +3,7 @@ // we don't even propagate constraints from the closures to the callers. // compile-flags:-Zborrowck=mir -Zverbose -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs index 7314766611121..4613dd29ef8f0 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env.rs @@ -4,7 +4,7 @@ // // Regression test for #53121. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyTrait<'a> { type Output; diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs b/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs index 7c7d64a8cb4d3..89328c2ef1b33 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs @@ -4,7 +4,7 @@ // MyTrait<'a>>::Output: 'a` outlives `'a` (because the trait says // so). // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyTrait<'a> { type Output: 'a; diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs index f61f54f80a78b..27c3e89c1c376 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs +++ b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs @@ -1,5 +1,5 @@ // compile-flags:-Zborrowck=mir -Zverbose -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that we assume that universal types like `T` outlive the // function body. diff --git a/src/test/ui/nll/user-annotations/downcast-infer.rs b/src/test/ui/nll/user-annotations/downcast-infer.rs index 23b76bb196470..3efea7136307c 100644 --- a/src/test/ui/nll/user-annotations/downcast-infer.rs +++ b/src/test/ui/nll/user-annotations/downcast-infer.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that we don't try to downcast `_` when type-checking the annotation. fn main() { diff --git a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs index 6b9d30f5ab425..66b3110d2afd0 100644 --- a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs +++ b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test is reduced from a scenario pnkfelix encountered while // bootstrapping the compiler. diff --git a/src/test/ui/no-warn-on-field-replace-issue-34101.rs b/src/test/ui/no-warn-on-field-replace-issue-34101.rs index af6ccf35d538c..eb701b9184e6a 100644 --- a/src/test/ui/no-warn-on-field-replace-issue-34101.rs +++ b/src/test/ui/no-warn-on-field-replace-issue-34101.rs @@ -18,7 +18,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Foo(String); diff --git a/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs b/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs index 25a9c2ed98e04..af6585aadae66 100644 --- a/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs +++ b/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) mod x; diff --git a/src/test/ui/object-safety/object-safety-by-value-self.rs b/src/test/ui/object-safety/object-safety-by-value-self.rs index a8b1ddfaba7f1..c74a4d1cbbbfc 100644 --- a/src/test/ui/object-safety/object-safety-by-value-self.rs +++ b/src/test/ui/object-safety/object-safety-by-value-self.rs @@ -1,6 +1,6 @@ // Check that a trait with by-value self is considered object-safe. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(trivial_casts)] diff --git a/src/test/ui/object-safety/object-safety-phantom-fn.rs b/src/test/ui/object-safety/object-safety-phantom-fn.rs index 59ed12c78f026..3ffeb81c1cbe3 100644 --- a/src/test/ui/object-safety/object-safety-phantom-fn.rs +++ b/src/test/ui/object-safety/object-safety-phantom-fn.rs @@ -1,6 +1,6 @@ // Check that `Self` appearing in a phantom fn does not make a trait not object safe. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait Baz { diff --git a/src/test/ui/panic_implementation-closures.rs b/src/test/ui/panic_implementation-closures.rs index 92c333b4092fc..b96125aa95260 100644 --- a/src/test/ui/panic_implementation-closures.rs +++ b/src/test/ui/panic_implementation-closures.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![crate_type = "rlib"] #![no_std] diff --git a/src/test/ui/parser/bounds-obj-parens.rs b/src/test/ui/parser/bounds-obj-parens.rs index 1e0f9e40cdca6..ae8112b61c66f 100644 --- a/src/test/ui/parser/bounds-obj-parens.rs +++ b/src/test/ui/parser/bounds-obj-parens.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(bare_trait_objects)] diff --git a/src/test/ui/parser/impl-qpath.rs b/src/test/ui/parser/impl-qpath.rs index 78c41f481af5d..ab45649f4de49 100644 --- a/src/test/ui/parser/impl-qpath.rs +++ b/src/test/ui/parser/impl-qpath.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z parse-only impl <*const u8>::AssocTy {} // OK diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.rs b/src/test/ui/parser/macro-bad-delimiter-ident.rs index 987c955d1dc38..13dec95435be0 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.rs +++ b/src/test/ui/parser/macro-bad-delimiter-ident.rs @@ -1,3 +1,3 @@ fn main() { - foo! bar < //~ ERROR expected `(` or `{`, found `<` + foo! bar < //~ ERROR expected open delimiter } diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.stderr b/src/test/ui/parser/macro-bad-delimiter-ident.stderr index 6a17d39e8bfec..e97839a4f4a52 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.stderr +++ b/src/test/ui/parser/macro-bad-delimiter-ident.stderr @@ -1,8 +1,8 @@ -error: expected `(` or `{`, found `<` - --> $DIR/macro-bad-delimiter-ident.rs:2:14 +error: expected open delimiter + --> $DIR/macro-bad-delimiter-ident.rs:2:10 | LL | foo! bar < - | ^ expected `(` or `{` + | ^^^ expected open delimiter error: aborting due to previous error diff --git a/src/test/ui/parser/trailing-plus-in-bounds.rs b/src/test/ui/parser/trailing-plus-in-bounds.rs index 3213e06805371..33c30d7310877 100644 --- a/src/test/ui/parser/trailing-plus-in-bounds.rs +++ b/src/test/ui/parser/trailing-plus-in-bounds.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(box_syntax)] #![allow(bare_trait_objects)] diff --git a/src/test/ui/parser/trait-plusequal-splitting.rs b/src/test/ui/parser/trait-plusequal-splitting.rs index c655a15d268c1..26ac3ead6a5a6 100644 --- a/src/test/ui/parser/trait-plusequal-splitting.rs +++ b/src/test/ui/parser/trait-plusequal-splitting.rs @@ -1,6 +1,6 @@ // Fixes issue where `+` in generics weren't parsed if they were part of a `+=`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Whitespace { t: T } struct TokenSplit { t: T } diff --git a/src/test/ui/parser/underscore-suffix-for-string.rs b/src/test/ui/parser/underscore-suffix-for-string.rs index bcd0b24c7507f..dd0599b4ab363 100644 --- a/src/test/ui/parser/underscore-suffix-for-string.rs +++ b/src/test/ui/parser/underscore-suffix-for-string.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { let _ = "Foo"_; diff --git a/src/test/ui/print-fuel/print-fuel.rs b/src/test/ui/print-fuel/print-fuel.rs index 1bd392426695a..e443469544617 100644 --- a/src/test/ui/print-fuel/print-fuel.rs +++ b/src/test/ui/print-fuel/print-fuel.rs @@ -3,7 +3,7 @@ // (#55495: The --error-format is to sidestep an issue in our test harness) // compile-flags: --error-format human -Z print-fuel=foo -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S1(u8, u16, u8); struct S2(u8, u16, u8); diff --git a/src/test/ui/print_type_sizes/anonymous.rs b/src/test/ui/print_type_sizes/anonymous.rs index 4d2a0e27fd1a9..b96348640fa15 100644 --- a/src/test/ui/print_type_sizes/anonymous.rs +++ b/src/test/ui/print_type_sizes/anonymous.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // All of the types that occur in this function are uninteresting, in // that one cannot control the sizes of these types with the same sort diff --git a/src/test/ui/print_type_sizes/generics.rs b/src/test/ui/print_type_sizes/generics.rs index 360c995868654..f165526dffa23 100644 --- a/src/test/ui/print_type_sizes/generics.rs +++ b/src/test/ui/print_type_sizes/generics.rs @@ -1,5 +1,8 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. // This file illustrates how generics are handled: types have to be // monomorphized, in the MIR of the original function in which they diff --git a/src/test/ui/print_type_sizes/multiple_types.rs b/src/test/ui/print_type_sizes/multiple_types.rs index 1b1d817420132..4cb7ae03b5406 100644 --- a/src/test/ui/print_type_sizes/multiple_types.rs +++ b/src/test/ui/print_type_sizes/multiple_types.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file illustrates that when multiple structural types occur in // a function, every one of them is included in the output. diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 0127261b2b7d0..d9845fd6d70cc 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -1,5 +1,8 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. // This file illustrates how niche-filling enums are handled, // modelled after cases like `Option<&u32>`, `Option` and such. diff --git a/src/test/ui/print_type_sizes/no_duplicates.rs b/src/test/ui/print_type_sizes/no_duplicates.rs index 7307c0fd8b406..4495a7770a760 100644 --- a/src/test/ui/print_type_sizes/no_duplicates.rs +++ b/src/test/ui/print_type_sizes/no_duplicates.rs @@ -1,5 +1,8 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. // This file illustrates that when the same type occurs repeatedly // (even if multiple functions), it is only printed once in the diff --git a/src/test/ui/print_type_sizes/packed.rs b/src/test/ui/print_type_sizes/packed.rs index ec3efd6923aef..dce4a61ef337b 100644 --- a/src/test/ui/print_type_sizes/packed.rs +++ b/src/test/ui/print_type_sizes/packed.rs @@ -1,5 +1,8 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. // This file illustrates how packing is handled; it should cause // the elimination of padding that would normally be introduced diff --git a/src/test/ui/print_type_sizes/padding.rs b/src/test/ui/print_type_sizes/padding.rs index c6d927cb1e56e..1f894c5e252fa 100644 --- a/src/test/ui/print_type_sizes/padding.rs +++ b/src/test/ui/print_type_sizes/padding.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file illustrates how padding is handled: alignment // requirements can lead to the introduction of padding, either before diff --git a/src/test/ui/print_type_sizes/repr-align.rs b/src/test/ui/print_type_sizes/repr-align.rs index fd452f411c51e..1e6f7ccca40f2 100644 --- a/src/test/ui/print_type_sizes/repr-align.rs +++ b/src/test/ui/print_type_sizes/repr-align.rs @@ -1,5 +1,8 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. // This file illustrates how padding is handled: alignment // requirements can lead to the introduction of padding, either before diff --git a/src/test/ui/print_type_sizes/repr_int_c.rs b/src/test/ui/print_type_sizes/repr_int_c.rs index 6816bb71a0012..7aad2715bc073 100644 --- a/src/test/ui/print_type_sizes/repr_int_c.rs +++ b/src/test/ui/print_type_sizes/repr_int_c.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)` // variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug). diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index 14245d0dc9a28..ae4e492456af9 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -1,5 +1,8 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. #![feature(never_type)] #![feature(start)] diff --git a/src/test/ui/print_type_sizes/variants.rs b/src/test/ui/print_type_sizes/variants.rs index aa2d25a3926a5..77e2b4befba7d 100644 --- a/src/test/ui/print_type_sizes/variants.rs +++ b/src/test/ui/print_type_sizes/variants.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // This file illustrates two things: // diff --git a/src/test/ui/privacy/issue-57264-1.rs b/src/test/ui/privacy/issue-57264-1.rs index dcffdc3d4ef87..5ef6a61fea174 100644 --- a/src/test/ui/privacy/issue-57264-1.rs +++ b/src/test/ui/privacy/issue-57264-1.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:issue-57264-1.rs extern crate issue_57264_1; diff --git a/src/test/ui/privacy/issue-57264-2.rs b/src/test/ui/privacy/issue-57264-2.rs index 79d0d2c7cd785..4d5c9cfa1d534 100644 --- a/src/test/ui/privacy/issue-57264-2.rs +++ b/src/test/ui/privacy/issue-57264-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:issue-57264-2.rs extern crate issue_57264_2; diff --git a/src/test/ui/privacy/private-in-public-existential.rs b/src/test/ui/privacy/private-in-public-existential.rs index 61c6130e47019..ef50875dcf678 100644 --- a/src/test/ui/privacy/private-in-public-existential.rs +++ b/src/test/ui/privacy/private-in-public-existential.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(existential_type)] #![deny(private_in_public)] diff --git a/src/test/ui/privacy/private-in-public-expr-pat.rs b/src/test/ui/privacy/private-in-public-expr-pat.rs index a3e53bdf45de3..5c9ecd13b0976 100644 --- a/src/test/ui/privacy/private-in-public-expr-pat.rs +++ b/src/test/ui/privacy/private-in-public-expr-pat.rs @@ -1,6 +1,6 @@ // Patterns and expressions are not interface parts and don't produce private-in-public errors. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct Priv1(usize); struct Priv2; diff --git a/src/test/ui/privacy/restricted/lookup-ignores-private.rs b/src/test/ui/privacy/restricted/lookup-ignores-private.rs index 419d521748c68..240ce1e2b03b6 100644 --- a/src/test/ui/privacy/restricted/lookup-ignores-private.rs +++ b/src/test/ui/privacy/restricted/lookup-ignores-private.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] mod foo { diff --git a/src/test/ui/proc-macro/attributes-included.rs b/src/test/ui/proc-macro/attributes-included.rs index 0ab17a1f3b312..4769607ff395d 100644 --- a/src/test/ui/proc-macro/attributes-included.rs +++ b/src/test/ui/proc-macro/attributes-included.rs @@ -1,5 +1,5 @@ // aux-build:attributes-included.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/proc-macro/auxiliary/generate-mod.rs b/src/test/ui/proc-macro/auxiliary/generate-mod.rs index 8b41e8b3b3eb8..e950f7d62d645 100644 --- a/src/test/ui/proc-macro/auxiliary/generate-mod.rs +++ b/src/test/ui/proc-macro/auxiliary/generate-mod.rs @@ -1,6 +1,7 @@ // run-pass // force-host // no-prefer-dynamic +// ignore-pass #![crate_type = "proc-macro"] diff --git a/src/test/ui/proc-macro/derive-helper-shadowed.rs b/src/test/ui/proc-macro/derive-helper-shadowed.rs index 0388e647b58aa..e299454e0fc73 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowed.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs // aux-build:derive-helper-shadowed-2.rs diff --git a/src/test/ui/proc-macro/derive-in-mod.rs b/src/test/ui/proc-macro/derive-in-mod.rs index e6b91324f95d0..8b5d4e9d09ce3 100644 --- a/src/test/ui/proc-macro/derive-in-mod.rs +++ b/src/test/ui/proc-macro/derive-in-mod.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs extern crate test_macros; diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs index 2615db3e119f1..2495e72751bb0 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // aux-build:test-macros.rs diff --git a/src/test/ui/proc-macro/edition-imports-2018.rs b/src/test/ui/proc-macro/edition-imports-2018.rs index f8d6bc5e0785d..5a77cd4ef4f5a 100644 --- a/src/test/ui/proc-macro/edition-imports-2018.rs +++ b/src/test/ui/proc-macro/edition-imports-2018.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // aux-build:edition-imports-2015.rs diff --git a/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs index 25a2a37614778..a6e64e1b1b1bd 100644 --- a/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs +++ b/src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 extern crate proc_macro; diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs b/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs index 6d3e5ec198d85..2e20a3de6bf47 100644 --- a/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs +++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #[macro_use(Empty)] diff --git a/src/test/ui/proc-macro/issue-53481.rs b/src/test/ui/proc-macro/issue-53481.rs index 2fbde5fedb95b..ae10a3baa3e3a 100644 --- a/src/test/ui/proc-macro/issue-53481.rs +++ b/src/test/ui/proc-macro/issue-53481.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #[macro_use] diff --git a/src/test/ui/proc-macro/macro-use-attr.rs b/src/test/ui/proc-macro/macro-use-attr.rs index d1b1430fb5d03..b101c09ed5424 100644 --- a/src/test/ui/proc-macro/macro-use-attr.rs +++ b/src/test/ui/proc-macro/macro-use-attr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #[macro_use] diff --git a/src/test/ui/proc-macro/macro-use-bang.rs b/src/test/ui/proc-macro/macro-use-bang.rs index d39c42267fb96..9d30f48846dba 100644 --- a/src/test/ui/proc-macro/macro-use-bang.rs +++ b/src/test/ui/proc-macro/macro-use-bang.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test-macros.rs #![feature(proc_macro_hygiene)] diff --git a/src/test/ui/proc-macro/no-missing-docs.rs b/src/test/ui/proc-macro/no-missing-docs.rs index e5a5f8beb4585..e1e8218582f6b 100644 --- a/src/test/ui/proc-macro/no-missing-docs.rs +++ b/src/test/ui/proc-macro/no-missing-docs.rs @@ -1,7 +1,7 @@ //! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs` //! warnings. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // force-host // no-prefer-dynamic diff --git a/src/test/ui/range/range_traits-4.rs b/src/test/ui/range/range_traits-4.rs index 52c706080f3c2..b8e88559b1518 100644 --- a/src/test/ui/range/range_traits-4.rs +++ b/src/test/ui/range/range_traits-4.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::*; diff --git a/src/test/ui/range/range_traits-5.rs b/src/test/ui/range/range_traits-5.rs index a8c3e9b0d62c0..4aec7a4159a13 100644 --- a/src/test/ui/range/range_traits-5.rs +++ b/src/test/ui/range/range_traits-5.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::*; diff --git a/src/test/ui/range/range_traits-7.rs b/src/test/ui/range/range_traits-7.rs index 548676063caf7..c7b310562d18e 100644 --- a/src/test/ui/range/range_traits-7.rs +++ b/src/test/ui/range/range_traits-7.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) use std::ops::*; diff --git a/src/test/ui/reachable/expr_andand.rs b/src/test/ui/reachable/expr_andand.rs index 173116ae357c5..d37eb0a3b843d 100644 --- a/src/test/ui/reachable/expr_andand.rs +++ b/src/test/ui/reachable/expr_andand.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_oror.rs b/src/test/ui/reachable/expr_oror.rs index ecfa072aa817d..e95062de4d732 100644 --- a/src/test/ui/reachable/expr_oror.rs +++ b/src/test/ui/reachable/expr_oror.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs index 5cbfe6ebebb7e..ee9e7a364b8c7 100644 --- a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs +++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs @@ -8,7 +8,7 @@ // follow the same lifetime-elision rules used elsehwere. See // rust-lang/rust#56537 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str { let free_dumb = |_x| { p }; // no type annotation at all diff --git a/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs b/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs index d6b36af9bd6f3..49de70ae01365 100644 --- a/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs +++ b/src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs @@ -1,7 +1,7 @@ // Test related to #22779. In this case, the impl is an inherent impl, // so it doesn't have to match any trait, so no error results. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct MySlice<'a, T:'a>(&'a mut [T]); diff --git a/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs b/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs index deef9ab15b01e..4ce5daf384227 100644 --- a/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs +++ b/src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs @@ -1,7 +1,7 @@ // Test related to #22779, but where the `'a:'b` relation // appears in the trait too. No error here. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Tr<'a, T> { fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b; diff --git a/src/test/ui/regions/region-object-lifetime-1.rs b/src/test/ui/regions/region-object-lifetime-1.rs index ab24eda2c2d96..e58bd31d9cbe9 100644 --- a/src/test/ui/regions/region-object-lifetime-1.rs +++ b/src/test/ui/regions/region-object-lifetime-1.rs @@ -1,7 +1,7 @@ // Various tests related to testing how region inference works // with respect to the object receivers. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] trait Foo { diff --git a/src/test/ui/regions/region-object-lifetime-3.rs b/src/test/ui/regions/region-object-lifetime-3.rs index cda4834706176..c3c7c51767d3a 100644 --- a/src/test/ui/regions/region-object-lifetime-3.rs +++ b/src/test/ui/regions/region-object-lifetime-3.rs @@ -1,7 +1,7 @@ // Various tests related to testing how region inference works // with respect to the object receivers. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(warnings)] trait Foo { diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs index d407bee416f1f..dcad2e81a5488 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs @@ -2,7 +2,7 @@ // "projection gap": in this test, we know that `T: 'x`, and that is // enough to conclude that `T::Foo: 'x`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs index c19fa98e91406..ff2e10804aec5 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs @@ -2,7 +2,7 @@ // "projection gap": in this test, we know that `T::Foo: 'x`, and that // is (naturally) enough to conclude that `T::Foo: 'x`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs index 7a19d17152cd4..3596bf7e8c2c4 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs @@ -2,7 +2,7 @@ // "projection gap": in this test, we know that `T: 'x`, and that // is (naturally) enough to conclude that `T: 'x`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs index 045d289149025..fc4d161840143 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs index e087d65a5c7bc..d716cb9c55ba7 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs index 20b391c263c26..39eb0842d3f6a 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -//compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs b/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs index 7f84441903f5b..561cad790f00e 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs index 07daa35a80981..e1287c34bac13 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs index 59da5fb0dc7de..7f22ae23b8500 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs index 096069c0ca4af..367f7a3020157 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs b/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs index 3c8c4a1ef52aa..f780275b684d1 100644 --- a/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs +++ b/src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs @@ -3,7 +3,7 @@ // // Rule OutlivesNominalType from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/regions/regions-outlives-projection-hrtype.rs b/src/test/ui/regions/regions-outlives-projection-hrtype.rs index a6e976ebf8c91..e7fe7b6c16d4f 100644 --- a/src/test/ui/regions/regions-outlives-projection-hrtype.rs +++ b/src/test/ui/regions/regions-outlives-projection-hrtype.rs @@ -5,7 +5,7 @@ // `'r` is bound, that leads to badness. This test checks that // everything works. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait TheTrait { diff --git a/src/test/ui/regions/regions-outlives-projection-trait-def.rs b/src/test/ui/regions/regions-outlives-projection-trait-def.rs index bad476d27794e..928ed4baaa030 100644 --- a/src/test/ui/regions/regions-outlives-projection-trait-def.rs +++ b/src/test/ui/regions/regions-outlives-projection-trait-def.rs @@ -1,7 +1,7 @@ // Test that `>::Type: 'b`, where `trait Foo<'a> { Type: // 'a; }`, does not require that `F: 'b`. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] trait SomeTrait<'a> { diff --git a/src/test/ui/regions/regions-outlives-scalar.rs b/src/test/ui/regions/regions-outlives-scalar.rs index ca012c4e1eda0..5d0ed9993800d 100644 --- a/src/test/ui/regions/regions-outlives-scalar.rs +++ b/src/test/ui/regions/regions-outlives-scalar.rs @@ -1,7 +1,7 @@ // Test that scalar values outlive all regions. // Rule OutlivesScalar from RFC 1214. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] struct Foo<'a> { diff --git a/src/test/ui/removing-extern-crate.fixed b/src/test/ui/removing-extern-crate.fixed index 71728e8a7313d..d2993dbc4a417 100644 --- a/src/test/ui/removing-extern-crate.fixed +++ b/src/test/ui/removing-extern-crate.fixed @@ -1,7 +1,7 @@ // edition:2018 // aux-build:removing-extern-crate.rs // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_idioms)] #![allow(unused_imports)] diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs index b9cc1810e7cb5..22fdfc2b0ec9c 100644 --- a/src/test/ui/removing-extern-crate.rs +++ b/src/test/ui/removing-extern-crate.rs @@ -1,7 +1,7 @@ // edition:2018 // aux-build:removing-extern-crate.rs // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_idioms)] #![allow(unused_imports)] diff --git a/src/test/ui/resolve/issue-57523.rs b/src/test/ui/resolve/issue-57523.rs index c2a2f28254226..5dc467d97e2be 100644 --- a/src/test/ui/resolve/issue-57523.rs +++ b/src/test/ui/resolve/issue-57523.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct S(u8); diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs index 7b499af632ece..6e75977b5900e 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs @@ -2,7 +2,7 @@ // rust-lang/rust#2329), that starts passing with this feature in // place. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(bind_by_move_pattern_guards)] diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs index aca6aa5f0f867..40588ca331eba 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs @@ -1,6 +1,6 @@ #![feature(bind_by_move_pattern_guards)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct A { a: Box } diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs index 97061310d19e2..221b5cf6bfad8 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs @@ -1,5 +1,5 @@ // aux-build:uninhabited.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] diff --git a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs index 62f6e4463f936..dacaf489a9082 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:variants.rs extern crate variants; diff --git a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs index 438923e29246c..b662685ae2435 100644 --- a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs +++ b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs @@ -6,7 +6,7 @@ // strange errors. This test ensures that we do not give compilation // errors. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait MyIterator<'a>: Iterator where Self::Item: 'a { } diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/rfc-2166-underscore-imports/basic.rs index 968da9c8d5681..4766d75c8f412 100644 --- a/src/test/ui/rfc-2166-underscore-imports/basic.rs +++ b/src/test/ui/rfc-2166-underscore-imports/basic.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:underscore-imports.rs #![warn(unused_imports, unused_extern_crates)] diff --git a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs b/src/test/ui/rfc-2166-underscore-imports/duplicate.rs index 95f7cae0b87d2..3662a466ded14 100644 --- a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs +++ b/src/test/ui/rfc-2166-underscore-imports/duplicate.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:duplicate.rs extern crate duplicate; diff --git a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs b/src/test/ui/rfc-2166-underscore-imports/intercrate.rs index 8b5bb8b326097..1cccc67e9ab63 100644 --- a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs +++ b/src/test/ui/rfc-2166-underscore-imports/intercrate.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:underscore-imports.rs extern crate underscore_imports; diff --git a/src/test/ui/rfc-2306/convert-id-const-with-gate.rs b/src/test/ui/rfc-2306/convert-id-const-with-gate.rs index a82feb961f7aa..762dfbe484396 100644 --- a/src/test/ui/rfc-2306/convert-id-const-with-gate.rs +++ b/src/test/ui/rfc-2306/convert-id-const-with-gate.rs @@ -1,6 +1,6 @@ // This test should pass since 'identity' is const fn. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) fn main() { const _FOO: u8 = ::std::convert::identity(42u8); diff --git a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs index e66d46575664f..710fdd57ed7b3 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=expanded fn main() { diff --git a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout index a6b15f9bbf65d..c88f50c6813ec 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout +++ b/src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout @@ -4,7 +4,7 @@ use ::std::prelude::v1::*; #[macro_use] extern crate std; -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z unpretty=expanded fn main() { if let 0 = 1 { } } diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs index c521d04fda562..e796e37bbaa45 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs @@ -1,5 +1,5 @@ // compile-flags: --cfg something -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(param_attrs)] diff --git a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs index 589e5fcc00ead..9fc32d7cc55f0 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs +++ b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z parse-only #![feature(generic_associated_types)] diff --git a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs index 7fa71e4dd1a55..7974ee9d39b19 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs +++ b/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Z parse-only #![feature(generic_associated_types)] diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs index 82a7c2510e5d7..03492631cb7c8 100644 --- a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs +++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs @@ -3,7 +3,7 @@ //FIXME(#44265): The lifetime shadowing and type parameter shadowing // should cause an error. Now it compiles (erroneously) and this will be addressed // by a future PR. Then remove the following: -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) trait Shadow<'a> { type Bar<'a>; // Error: shadowed lifetime diff --git a/src/test/ui/rmeta-lib-pass.rs b/src/test/ui/rmeta-lib-pass.rs index 4ab4117dd6ccd..fdd0516e4d654 100644 --- a/src/test/ui/rmeta-lib-pass.rs +++ b/src/test/ui/rmeta-lib-pass.rs @@ -1,7 +1,7 @@ // compile-flags: --emit=metadata // aux-build:rmeta-rlib.rs // no-prefer-dynamic -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that building a metadata crate works with a dependent, rlib crate. // This is a cfail test since there is no executable to run. diff --git a/src/test/ui/rmeta-pass.rs b/src/test/ui/rmeta-pass.rs index 9c88de7a0330b..4f0db23f47dd9 100644 --- a/src/test/ui/rmeta-pass.rs +++ b/src/test/ui/rmeta-pass.rs @@ -1,7 +1,7 @@ // compile-flags: --emit=metadata // aux-build:rmeta-meta.rs // no-prefer-dynamic -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Check that building a metadata crate works with a dependent, metadata-only // crate. diff --git a/src/test/ui/rmeta-priv-warn.rs b/src/test/ui/rmeta-priv-warn.rs index 823ce80623b6c..430c1f06f43ac 100644 --- a/src/test/ui/rmeta-priv-warn.rs +++ b/src/test/ui/rmeta-priv-warn.rs @@ -1,6 +1,6 @@ // compile-flags: --emit=metadata // no-prefer-dynamic -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #[deny(warnings)] diff --git a/src/test/ui/rust-2018/edition-lint-paths-2018.rs b/src/test/ui/rust-2018/edition-lint-paths-2018.rs index 09b31beb77585..2005d8f4d7941 100644 --- a/src/test/ui/rust-2018/edition-lint-paths-2018.rs +++ b/src/test/ui/rust-2018/edition-lint-paths-2018.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags:--extern edition_lint_paths // aux-build:edition-lint-paths.rs diff --git a/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs b/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs index 323c6e105f503..950ad1f504681 100644 --- a/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs +++ b/src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(unused)] #![deny(explicit_outlives_requirements)] diff --git a/src/test/ui/rust-2018/macro-use-warned-against.rs b/src/test/ui/rust-2018/macro-use-warned-against.rs index 368b8daf243ea..6cd54aa68aedd 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.rs +++ b/src/test/ui/rust-2018/macro-use-warned-against.rs @@ -1,6 +1,6 @@ // aux-build:macro-use-warned-against.rs // aux-build:macro-use-warned-against2.rs -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(macro_use_extern_crate, unused)] diff --git a/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs b/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs index 3311ded553117..2d4cb6514ec2c 100644 --- a/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs +++ b/src/test/ui/rust-2018/proc-macro-crate-in-paths.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // force-host // no-prefer-dynamic diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed index 14575d18c236a..7ddd2f547f071 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.fixed +++ b/src/test/ui/rust-2018/remove-extern-crate.fixed @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs index 0ee85f34e40d9..298b16140264a 100644 --- a/src/test/ui/rust-2018/remove-extern-crate.rs +++ b/src/test/ui/rust-2018/remove-extern-crate.rs @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:remove-extern-crate.rs // compile-flags:--extern remove_extern_crate diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed b/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed index f0ca24714ed48..7d136667b6dfb 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.fixed @@ -2,7 +2,7 @@ // edition:2015 // run-rustfix // rustfix-only-machine-applicable -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/suggestions-not-always-applicable.rs b/src/test/ui/rust-2018/suggestions-not-always-applicable.rs index f0ca24714ed48..7d136667b6dfb 100644 --- a/src/test/ui/rust-2018/suggestions-not-always-applicable.rs +++ b/src/test/ui/rust-2018/suggestions-not-always-applicable.rs @@ -2,7 +2,7 @@ // edition:2015 // run-rustfix // rustfix-only-machine-applicable -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rust_2018_preview)] #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-ident.fixed b/src/test/ui/rust-2018/try-ident.fixed index 5af13934e844a..f86a401cdf939 100644 --- a/src/test/ui/rust-2018/try-ident.fixed +++ b/src/test/ui/rust-2018/try-ident.fixed @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-ident.rs b/src/test/ui/rust-2018/try-ident.rs index faac13ab77912..6cc6aa12ff76e 100644 --- a/src/test/ui/rust-2018/try-ident.rs +++ b/src/test/ui/rust-2018/try-ident.rs @@ -1,5 +1,5 @@ // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/try-macro.fixed b/src/test/ui/rust-2018/try-macro.fixed index c65f0fc30ef0a..7c1692fd7fb13 100644 --- a/src/test/ui/rust-2018/try-macro.fixed +++ b/src/test/ui/rust-2018/try-macro.fixed @@ -1,7 +1,7 @@ // Test that `try!` macros are rewritten. // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] #![allow(unused_variables)] diff --git a/src/test/ui/rust-2018/try-macro.rs b/src/test/ui/rust-2018/try-macro.rs index f435890a61dcb..2089d367be698 100644 --- a/src/test/ui/rust-2018/try-macro.rs +++ b/src/test/ui/rust-2018/try-macro.rs @@ -1,7 +1,7 @@ // Test that `try!` macros are rewritten. // run-rustfix -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(rust_2018_compatibility)] #![allow(unused_variables)] diff --git a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs index 0c2da1884b758..c6525869b021a 100644 --- a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs +++ b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 fn main() { diff --git a/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs b/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs index 5c3c753f9a785..9af520a07693b 100644 --- a/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs +++ b/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![feature(decl_macro)] diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs index 9ec3a64113116..446b2d05717b0 100644 --- a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs +++ b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // compile-flags: --extern issue_56596_2 // aux-build:issue-56596-2.rs diff --git a/src/test/ui/rust-2018/uniform-paths/prelude.rs b/src/test/ui/rust-2018/uniform-paths/prelude.rs index 9a326b4c728bd..dca9587c5d369 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 // Macro imported with `#[macro_use] extern crate` diff --git a/src/test/ui/save-analysis/emit-notifications.rs b/src/test/ui/save-analysis/emit-notifications.rs index 411acbb14db68..e02f3ecc62923 100644 --- a/src/test/ui/save-analysis/emit-notifications.rs +++ b/src/test/ui/save-analysis/emit-notifications.rs @@ -1,4 +1,7 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: -Zsave-analysis -Zemit-artifact-notifications // compile-flags: --crate-type rlib --error-format=json +// ignore-pass +// ^-- needed because otherwise, the .stderr file changes with --pass check + pub fn foo() {} diff --git a/src/test/ui/self/explicit-self-closures.rs b/src/test/ui/self/explicit-self-closures.rs index 1217823da116e..b409dfd7a1e08 100644 --- a/src/test/ui/self/explicit-self-closures.rs +++ b/src/test/ui/self/explicit-self-closures.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // Test to make sure that explicit self params work inside closures diff --git a/src/test/ui/self/self-in-typedefs.rs b/src/test/ui/self/self-in-typedefs.rs index e4fe7324ef3a6..73f23a9cc17cf 100644 --- a/src/test/ui/self/self-in-typedefs.rs +++ b/src/test/ui/self/self-in-typedefs.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(untagged_unions)] diff --git a/src/test/ui/self/self-type-param.rs b/src/test/ui/self/self-type-param.rs index 57e01caa692de..5eb8c3622e4bd 100644 --- a/src/test/ui/self/self-type-param.rs +++ b/src/test/ui/self/self-type-param.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] // pretty-expanded FIXME #23616 diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs index 92b25cbf58410..d9d7e66d0cae2 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs @@ -5,7 +5,7 @@ // (Normally, using `'static` would be preferred, but there are // times when that is not what you want.) -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] diff --git a/src/test/ui/single-use-lifetime/one-use-in-struct.rs b/src/test/ui/single-use-lifetime/one-use-in-struct.rs index 6c4d2a4a7ad41..7285324ef6300 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-struct.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-struct.rs @@ -2,7 +2,7 @@ // even when they are only used once (since to not use a named // lifetime is illegal!) // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs b/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs index 4cdf1530a927b..8efe806b6e6e2 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs @@ -1,7 +1,7 @@ // Test that we DO NOT warn when lifetime name is used in // both the argument and return. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs b/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs index 375366e41c639..09b01d8b05bae 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs @@ -1,7 +1,7 @@ // Test that we DO NOT warn when lifetime name is used multiple // arguments, or more than once in a single argument. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs b/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs index 63d03a2cf0a85..eb85a148e6040 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs @@ -1,6 +1,6 @@ // Test that we DO NOT warn for a lifetime used twice in an impl. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs b/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs index d4a0d71713ccd..fd8c899f4fa6b 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs @@ -1,7 +1,7 @@ // Test that we DO NOT warn for a lifetime on an impl used in both // header and in an associated type. // -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(single_use_lifetimes)] #![allow(dead_code)] diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs index 82899fc896560..f51ea55d4e6b8 100644 --- a/src/test/ui/span/issue-24690.rs +++ b/src/test/ui/span/issue-24690.rs @@ -1,7 +1,7 @@ //! A test to ensure that helpful `note` messages aren't emitted more often //! than necessary. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Although there are three warnings, we should only get two "lint level defined // here" notes pointing at the `warnings` span, one for each error type. diff --git a/src/test/ui/span/macro-span-replacement.rs b/src/test/ui/span/macro-span-replacement.rs index c5998c1b40310..04c7ab0ea586f 100644 --- a/src/test/ui/span/macro-span-replacement.rs +++ b/src/test/ui/span/macro-span-replacement.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/span/multispan-import-lint.rs b/src/test/ui/span/multispan-import-lint.rs index 753c3599975fd..a49c60e1277f3 100644 --- a/src/test/ui/span/multispan-import-lint.rs +++ b/src/test/ui/span/multispan-import-lint.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![warn(unused)] diff --git a/src/test/ui/static/static-extern-type.rs b/src/test/ui/static/static-extern-type.rs index 3666982b4e298..4fa48fa133be1 100644 --- a/src/test/ui/static/static-extern-type.rs +++ b/src/test/ui/static/static-extern-type.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(extern_types)] pub mod a { diff --git a/src/test/ui/static_sized_requirement.rs b/src/test/ui/static_sized_requirement.rs index 0ee0637232ca4..074280b7b6646 100644 --- a/src/test/ui/static_sized_requirement.rs +++ b/src/test/ui/static_sized_requirement.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(no_core, lang_items)] #![no_core] diff --git a/src/test/ui/suggestions/issue-57672.rs b/src/test/ui/suggestions/issue-57672.rs index 1773f72fc741c..0881a631f3a76 100644 --- a/src/test/ui/suggestions/issue-57672.rs +++ b/src/test/ui/suggestions/issue-57672.rs @@ -1,6 +1,6 @@ // aux-build:foo.rs // compile-flags:--extern foo -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // edition:2018 #![deny(unused_extern_crates)] diff --git a/src/test/ui/test-on-macro.rs b/src/test/ui/test-on-macro.rs index ad7424a1bbbb9..a238db6d71623 100644 --- a/src/test/ui/test-on-macro.rs +++ b/src/test/ui/test-on-macro.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags:--test #![deny(warnings)] diff --git a/src/test/ui/test-shadowing/test-cant-be-shadowed.rs b/src/test/ui/test-shadowing/test-cant-be-shadowed.rs index b1c2a000d4a58..831372d4506b3 100644 --- a/src/test/ui/test-shadowing/test-cant-be-shadowed.rs +++ b/src/test/ui/test-shadowing/test-cant-be-shadowed.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // aux-build:test_macro.rs // compile-flags:--test diff --git a/src/test/ui/test-should-panic-attr.rs b/src/test/ui/test-should-panic-attr.rs index f936dd5758747..9c38322fe96fd 100644 --- a/src/test/ui/test-should-panic-attr.rs +++ b/src/test/ui/test-should-panic-attr.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // compile-flags: --test #[test] diff --git a/src/test/ui/traits/conservative_impl_trait.rs b/src/test/ui/traits/conservative_impl_trait.rs index 964e21779d51b..4f25e57be566b 100644 --- a/src/test/ui/traits/conservative_impl_trait.rs +++ b/src/test/ui/traits/conservative_impl_trait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // #39665 fn batches(n: &u32) -> impl Iterator { diff --git a/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs b/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs index 3dfcf03ce79da..284baa481497c 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs +++ b/src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Test that `dyn ... + ?Sized + ...` resulting from the expansion of trait aliases is okay. diff --git a/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs b/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs index 793d556d08ca2..d1b7bf6c2d766 100644 --- a/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs +++ b/src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // Regression test related to #56288. Check that a supertrait projection (of // `Output`) that references `Self` can be ok if it is referencing a projection (of diff --git a/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs b/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs index 3e9f612a2afee..83dfe6664a505 100644 --- a/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs +++ b/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // FIXME(eddyb) shorten the name so windows doesn't choke on it. #![crate_name = "trait_test"] diff --git a/src/test/ui/traits/trait-privacy.rs b/src/test/ui/traits/trait-privacy.rs index 6254157e25da3..17a2e05e99f2c 100644 --- a/src/test/ui/traits/trait-privacy.rs +++ b/src/test/ui/traits/trait-privacy.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] mod foo { pub use self::bar::T; diff --git a/src/test/ui/traits/trait-with-dst.rs b/src/test/ui/traits/trait-with-dst.rs index 86d6585bc6143..a3e3b31df922e 100644 --- a/src/test/ui/traits/trait-with-dst.rs +++ b/src/test/ui/traits/trait-with-dst.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // #55266 struct VTable { diff --git a/src/test/ui/traits/traits-issue-23003-overflow.rs b/src/test/ui/traits/traits-issue-23003-overflow.rs index 06aa698ddefd7..5538e0303ed12 100644 --- a/src/test/ui/traits/traits-issue-23003-overflow.rs +++ b/src/test/ui/traits/traits-issue-23003-overflow.rs @@ -2,7 +2,7 @@ // types are required. This test now just compiles fine, since the // relevant rules that triggered the overflow were removed. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::marker::PhantomData; diff --git a/src/test/ui/try-poll.rs b/src/test/ui/try-poll.rs index f63950ad5e905..d42e51c7405ba 100644 --- a/src/test/ui/try-poll.rs +++ b/src/test/ui/try-poll.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code, unused)] diff --git a/src/test/ui/type-alias-enum-variants-panic.rs b/src/test/ui/type-alias-enum-variants-panic.rs deleted file mode 100644 index f97592f5d3b15..0000000000000 --- a/src/test/ui/type-alias-enum-variants-panic.rs +++ /dev/null @@ -1,17 +0,0 @@ -// ignore-tidy-linelength - -#![feature(type_alias_enum_variants)] - -#![allow(unreachable_code)] - -enum Enum { Variant {} } -type Alias = Enum; - -fn main() { - Alias::Variant; - //~^ ERROR expected unit struct/variant or constant, found struct variant `::Variant` [E0533] - let Alias::Variant = panic!(); - //~^ ERROR expected unit struct/variant or constant, found struct variant `::Variant` [E0533] - let Alias::Variant(..) = panic!(); - //~^ ERROR expected tuple struct/variant, found struct variant `::Variant` [E0164] -} diff --git a/src/test/ui/type-alias-enum-variants-panic.stderr b/src/test/ui/type-alias-enum-variants-panic.stderr deleted file mode 100644 index 24cf85f52783f..0000000000000 --- a/src/test/ui/type-alias-enum-variants-panic.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0533]: expected unit struct/variant or constant, found struct variant `::Variant` - --> $DIR/type-alias-enum-variants-panic.rs:11:5 - | -LL | Alias::Variant; - | ^^^^^^^^^^^^^^ - -error[E0533]: expected unit struct/variant or constant, found struct variant `::Variant` - --> $DIR/type-alias-enum-variants-panic.rs:13:9 - | -LL | let Alias::Variant = panic!(); - | ^^^^^^^^^^^^^^ - -error[E0164]: expected tuple struct/variant, found struct variant `::Variant` - --> $DIR/type-alias-enum-variants-panic.rs:15:9 - | -LL | let Alias::Variant(..) = panic!(); - | ^^^^^^^^^^^^^^^^^^ not a tuple variant or struct - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0164`. diff --git a/src/test/ui/type-alias-enum-variants-priority-2.rs b/src/test/ui/type-alias-enum-variants-priority-2.rs deleted file mode 100644 index 295f8acf62f85..0000000000000 --- a/src/test/ui/type-alias-enum-variants-priority-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(type_alias_enum_variants)] - -enum E { - V(u8) -} - -impl E { - fn V() {} -} - -fn main() { - ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied -} diff --git a/src/test/ui/type-alias-enum-variants-priority-2.stderr b/src/test/ui/type-alias-enum-variants-priority-2.stderr deleted file mode 100644 index 10a4b44084a48..0000000000000 --- a/src/test/ui/type-alias-enum-variants-priority-2.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0061]: this function takes 1 parameter but 0 parameters were supplied - --> $DIR/type-alias-enum-variants-priority-2.rs:12:5 - | -LL | V(u8) - | ----- defined here -... -LL | ::V(); - | ^^^^^^^^ expected 1 parameter - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/type-alias-enum-variants-priority-3.rs b/src/test/ui/type-alias-enum-variants-priority-3.rs deleted file mode 100644 index 33f96553b57f0..0000000000000 --- a/src/test/ui/type-alias-enum-variants-priority-3.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(type_alias_enum_variants)] - -enum E { - V -} - -fn check() -> ::V {} -//~^ ERROR expected type, found variant `V` - -fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority.rs b/src/test/ui/type-alias-enum-variants-priority.rs deleted file mode 100644 index 82cd21b09d3e7..0000000000000 --- a/src/test/ui/type-alias-enum-variants-priority.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(type_alias_enum_variants)] - -enum E { - V -} - -trait Tr { - type V; - fn f() -> Self::V; -} - -impl Tr for E { - type V = u8; - fn f() -> Self::V { 0 } - //~^ ERROR ambiguous associated item - //~| WARN this was previously accepted -} - -fn main() {} diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs deleted file mode 100644 index c5974e5569223..0000000000000 --- a/src/test/ui/type-alias-enum-variants.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![feature(type_alias_enum_variants)] - -type Alias = Option; - -fn main() { - let _ = Option::::None; // OK - let _ = Option::None::; // OK (Lint in future!) - let _ = Alias::::None; // OK - let _ = Alias::None::; // Error - //~^ type arguments are not allowed for this type -} diff --git a/src/test/ui/pattern/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs similarity index 59% rename from src/test/ui/pattern/enum-variant-generic-args.rs rename to src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs index 85599530ea6a4..0c212096f9234 100644 --- a/src/test/ui/pattern/enum-variant-generic-args.rs +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs @@ -1,17 +1,22 @@ // run-pass -#![feature(type_alias_enum_variants)] +// Check that resolving, in the value namespace, to an `enum` variant +// through a type alias is well behaved in the presence of generics. +// We check for situations with: +// 1. a generic type `Alias`, we can type-apply `Alias` when referring to a variant. +// 2. a monotype `AliasFixed` of generic `Enum`, we can refer to variants +// and the type-application of `T` in `AliasFixed` is kept. #![allow(irrefutable_let_patterns)] -#[allow(dead_code)] -enum Enum { TSVariant(T), SVariant { v: T } } +enum Enum { TSVariant(T), SVariant { v: T }, UVariant } type Alias = Enum; type AliasFixed = Enum<()>; macro_rules! is_variant { (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr)); (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr)); + (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr)); (@check $variant:ident, $matcher:tt, $expr:expr) => ( assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false }, "expr does not have correct type"); @@ -40,4 +45,15 @@ fn main() { is_variant!(SVariant, Alias::<()>::SVariant { v: () }); is_variant!(SVariant, AliasFixed::SVariant { v: () }); + + // Unit variant + + is_variant!(UVariant, Enum::UVariant); + is_variant!(UVariant, Enum::UVariant::<()>); + is_variant!(UVariant, Enum::<()>::UVariant); + + is_variant!(UVariant, Alias::UVariant); + is_variant!(UVariant, Alias::<()>::UVariant); + + is_variant!(UVariant, AliasFixed::UVariant); } diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs similarity index 65% rename from src/test/ui/enum-variant-generic-args.rs rename to src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs index dd1f5f334df1d..f182c3ba8c798 100644 --- a/src/test/ui/enum-variant-generic-args.rs +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs @@ -1,6 +1,10 @@ -#![feature(type_alias_enum_variants)] +// Checks that applied type arguments of enums, and aliases to them, are respected. +// For example, `Self` is never a type constructor. Therefore, no types can be applied to it. +// +// We also check that the variant to an type-aliased enum cannot be type applied whether +// that alias is generic or monomorphic. -enum Enum { TSVariant(T), SVariant { v: T } } +enum Enum { TSVariant(T), SVariant { v: T }, UVariant } type Alias = Enum; type AliasFixed = Enum<()>; @@ -32,6 +36,16 @@ impl Enum { //~^^ ERROR type arguments are not allowed for this type [E0109] //~^^^ ERROR mismatched types [E0308] } + + fn u_variant() { + Self::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + Self::<()>::UVariant; + //~^ ERROR type arguments are not allowed for this type [E0109] + Self::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + //~^^ ERROR type arguments are not allowed for this type [E0109] + } } fn main() { @@ -70,4 +84,22 @@ fn main() { AliasFixed::<()>::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed for this type [E0109] //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] + + // Unit variant + + Enum::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + + Alias::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + Alias::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + + AliasFixed::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + AliasFixed::<()>::UVariant; + //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] + AliasFixed::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed for this type [E0109] + //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] } diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr similarity index 58% rename from src/test/ui/enum-variant-generic-args.stderr rename to src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index 97b111a5c8595..ee73622cb7bd1 100644 --- a/src/test/ui/enum-variant-generic-args.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:9:25 + --> $DIR/enum-variant-generic-args.rs:13:25 | LL | Self::TSVariant(()); | ^^ expected type parameter, found () @@ -8,19 +8,19 @@ LL | Self::TSVariant(()); found type `()` error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:11:27 + --> $DIR/enum-variant-generic-args.rs:15:27 | LL | Self::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:13:16 + --> $DIR/enum-variant-generic-args.rs:17:16 | LL | Self::<()>::TSVariant(()); | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:13:31 + --> $DIR/enum-variant-generic-args.rs:17:31 | LL | Self::<()>::TSVariant(()); | ^^ expected type parameter, found () @@ -29,19 +29,19 @@ LL | Self::<()>::TSVariant(()); found type `()` error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:16:16 + --> $DIR/enum-variant-generic-args.rs:20:16 | LL | Self::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:16:33 + --> $DIR/enum-variant-generic-args.rs:20:33 | LL | Self::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:22:29 + --> $DIR/enum-variant-generic-args.rs:26:29 | LL | Self::SVariant { v: () }; | ^^ expected type parameter, found () @@ -50,13 +50,13 @@ LL | Self::SVariant { v: () }; found type `()` error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:24:26 + --> $DIR/enum-variant-generic-args.rs:28:26 | LL | Self::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:24:35 + --> $DIR/enum-variant-generic-args.rs:28:35 | LL | Self::SVariant::<()> { v: () }; | ^^ expected type parameter, found () @@ -65,13 +65,13 @@ LL | Self::SVariant::<()> { v: () }; found type `()` error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:27:16 + --> $DIR/enum-variant-generic-args.rs:31:16 | LL | Self::<()>::SVariant { v: () }; | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:27:35 + --> $DIR/enum-variant-generic-args.rs:31:35 | LL | Self::<()>::SVariant { v: () }; | ^^ expected type parameter, found () @@ -80,19 +80,19 @@ LL | Self::<()>::SVariant { v: () }; found type `()` error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:30:16 + --> $DIR/enum-variant-generic-args.rs:34:16 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:30:32 + --> $DIR/enum-variant-generic-args.rs:34:32 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:30:41 + --> $DIR/enum-variant-generic-args.rs:34:41 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ expected type parameter, found () @@ -101,90 +101,156 @@ LL | Self::<()>::SVariant::<()> { v: () }; found type `()` error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:40:29 + --> $DIR/enum-variant-generic-args.rs:41:26 + | +LL | Self::UVariant::<()>; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:43:16 + | +LL | Self::<()>::UVariant; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:45:16 + | +LL | Self::<()>::UVariant::<()>; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:45:32 + | +LL | Self::<()>::UVariant::<()>; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:54:29 | LL | Enum::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:43:24 + --> $DIR/enum-variant-generic-args.rs:57:24 | LL | Alias::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:45:30 + --> $DIR/enum-variant-generic-args.rs:59:30 | LL | Alias::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:48:29 + --> $DIR/enum-variant-generic-args.rs:62:29 | LL | AliasFixed::TSVariant::<()>(()); | ^^ type argument not allowed error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:50:18 + --> $DIR/enum-variant-generic-args.rs:64:18 | LL | AliasFixed::<()>::TSVariant(()); | ^^ unexpected type argument error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:52:18 + --> $DIR/enum-variant-generic-args.rs:66:18 | LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ unexpected type argument error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:52:35 + --> $DIR/enum-variant-generic-args.rs:66:35 | LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:58:28 + --> $DIR/enum-variant-generic-args.rs:72:28 | LL | Enum::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:61:23 + --> $DIR/enum-variant-generic-args.rs:75:23 | LL | Alias::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:63:29 + --> $DIR/enum-variant-generic-args.rs:77:29 | LL | Alias::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:66:28 + --> $DIR/enum-variant-generic-args.rs:80:28 | LL | AliasFixed::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:68:18 + --> $DIR/enum-variant-generic-args.rs:82:18 | LL | AliasFixed::<()>::SVariant { v: () }; | ^^ unexpected type argument error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:70:18 + --> $DIR/enum-variant-generic-args.rs:84:18 | LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ unexpected type argument error[E0109]: type arguments are not allowed for this type - --> $DIR/enum-variant-generic-args.rs:70:34 + --> $DIR/enum-variant-generic-args.rs:84:34 | LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed -error: aborting due to 28 previous errors +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:90:28 + | +LL | Enum::<()>::UVariant::<()>; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:93:23 + | +LL | Alias::UVariant::<()>; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:95:29 + | +LL | Alias::<()>::UVariant::<()>; + | ^^ type argument not allowed + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:98:28 + | +LL | AliasFixed::UVariant::<()>; + | ^^ type argument not allowed + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-variant-generic-args.rs:100:18 + | +LL | AliasFixed::<()>::UVariant; + | ^^ unexpected type argument + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-variant-generic-args.rs:102:18 + | +LL | AliasFixed::<()>::UVariant::<()>; + | ^^ unexpected type argument + +error[E0109]: type arguments are not allowed for this type + --> $DIR/enum-variant-generic-args.rs:102:34 + | +LL | AliasFixed::<()>::UVariant::<()>; + | ^^ type argument not allowed + +error: aborting due to 39 previous errors Some errors have detailed explanations: E0107, E0109, E0308. For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs new file mode 100644 index 0000000000000..fa3e1a35fc27a --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs @@ -0,0 +1,23 @@ +// Check that an `enum` variant is resolved, in the value namespace, +// with higher priority than other inherent items when there is a conflict. + +enum E { + V(u8) +} + +impl E { + fn V() {} +} + +enum E2 { + V, +} + +impl E2 { + const V: u8 = 0; +} + +fn main() { + ::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied + let _: u8 = ::V; //~ ERROR mismatched types +} diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr new file mode 100644 index 0000000000000..0394ddab46cda --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -0,0 +1,22 @@ +error[E0061]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5 + | +LL | V(u8) + | ----- defined here +... +LL | ::V(); + | ^^^^^^^^ expected 1 parameter + +error[E0308]: mismatched types + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 + | +LL | let _: u8 = ::V; + | ^^^^^^^ expected u8, found enum `E2` + | + = note: expected type `u8` + found type `E2` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs new file mode 100644 index 0000000000000..7f69590400b3c --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs @@ -0,0 +1,37 @@ +// Check that a projection `Self::V` in a trait implementation, +// with an associated type named `V`, for an `enum` with a variant named `V`, +// results in triggering the deny-by-default lint `ambiguous_associated_items`. +// The lint suggests that qualified syntax should be used instead. +// That is, the user would write `::V`. +// +// The rationale for this is that while `enum` variants do currently +// not exist in the type namespace but solely in the value namespace, +// RFC #2593 "Enum variant types", would add enum variants to the type namespace. +// However, currently `enum` variants are resolved with high priority as +// they are resolved as inherent associated items. +// Should #2953 therefore be implemented, `Self::V` would suddenly switch +// from referring to the associated type `V` instead of the variant `V`. +// The lint exists to keep us forward compatible with #2593. +// +// As a closing note, provided that #2933 was implemented and +// if `enum` variants were given lower priority than associated types, +// it would be impossible to refer to the `enum` variant `V` whereas +// the associated type could be referred to with qualified syntax as seen above. + +enum E { + V +} + +trait Tr { + type V; + fn f() -> Self::V; +} + +impl Tr for E { + type V = u8; + fn f() -> Self::V { 0 } + //~^ ERROR ambiguous associated item + //~| WARN this was previously accepted +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr similarity index 74% rename from src/test/ui/type-alias-enum-variants-priority.stderr rename to src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr index b8271807b835d..f0dd689934f83 100644 --- a/src/test/ui/type-alias-enum-variants-priority.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -1,5 +1,5 @@ error: ambiguous associated item - --> $DIR/type-alias-enum-variants-priority.rs:14:15 + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15 | LL | fn f() -> Self::V { 0 } | ^^^^^^^ help: use fully-qualified syntax: `::V` @@ -8,12 +8,12 @@ LL | fn f() -> Self::V { 0 } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57644 note: `V` could refer to variant defined here - --> $DIR/type-alias-enum-variants-priority.rs:4:5 + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5 | LL | V | ^ note: `V` could also refer to associated type defined here - --> $DIR/type-alias-enum-variants-priority.rs:8:5 + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5 | LL | type V; | ^^^^^^^ diff --git a/src/test/ui/issues/issue-58006.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs similarity index 86% rename from src/test/ui/issues/issue-58006.rs rename to src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs index 1fb5fefa7596d..c1e56fc4caa9f 100644 --- a/src/test/ui/issues/issue-58006.rs +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs @@ -1,4 +1,3 @@ -#![feature(type_alias_enum_variants)] pub enum Enum { A(usize), } diff --git a/src/test/ui/issues/issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr similarity index 73% rename from src/test/ui/issues/issue-58006.stderr rename to src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr index c34e133c6c448..128a85e15634c 100644 --- a/src/test/ui/issues/issue-58006.stderr +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr @@ -1,5 +1,5 @@ error[E0533]: expected unit struct/variant or constant, found tuple variant `::A` - --> $DIR/issue-58006.rs:9:13 + --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13 | LL | Self::A => (), | ^^^^^^^ diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs new file mode 100644 index 0000000000000..ce45d59198af8 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs @@ -0,0 +1,21 @@ +// ignore-tidy-linelength + +// Check that creating/matching on an enum variant through an alias with +// the wrong braced/unit form is caught as an error. + +enum Enum { Braced {}, Unit, Tuple() } +type Alias = Enum; + +fn main() { + Alias::Braced; + //~^ ERROR expected unit struct/variant or constant, found struct variant `::Braced` [E0533] + let Alias::Braced = panic!(); + //~^ ERROR expected unit struct/variant or constant, found struct variant `::Braced` [E0533] + let Alias::Braced(..) = panic!(); + //~^ ERROR expected tuple struct/variant, found struct variant `::Braced` [E0164] + + Alias::Unit(); + //~^ ERROR expected function, found enum variant `::Unit` + let Alias::Unit() = panic!(); + //~^ ERROR expected tuple struct/variant, found unit variant `::Unit` [E0164] +} diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr new file mode 100644 index 0000000000000..c1ea816b7facf --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr @@ -0,0 +1,43 @@ +error[E0533]: expected unit struct/variant or constant, found struct variant `::Braced` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:5 + | +LL | Alias::Braced; + | ^^^^^^^^^^^^^ + +error[E0533]: expected unit struct/variant or constant, found struct variant `::Braced` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 + | +LL | let Alias::Braced = panic!(); + | ^^^^^^^^^^^^^ + +error[E0164]: expected tuple struct/variant, found struct variant `::Braced` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:14:9 + | +LL | let Alias::Braced(..) = panic!(); + | ^^^^^^^^^^^^^^^^^ not a tuple variant or struct + +error[E0618]: expected function, found enum variant `::Unit` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:5 + | +LL | enum Enum { Braced {}, Unit, Tuple() } + | ---- `::Unit` defined here +... +LL | Alias::Unit(); + | ^^^^^^^^^^^-- + | | + | call expression requires function +help: `::Unit` is a unit variant, you need to write it without the parenthesis + | +LL | ::Unit; + | ^^^^^^^^^^^^^ + +error[E0164]: expected tuple struct/variant, found unit variant `::Unit` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:19:9 + | +LL | let Alias::Unit() = panic!(); + | ^^^^^^^^^^^^^ not a tuple variant or struct + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0164, E0618. +For more information about an error, try `rustc --explain E0164`. diff --git a/src/test/ui/issues/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs similarity index 83% rename from src/test/ui/issues/issue-57866.rs rename to src/test/ui/type-alias-enum-variants/issue-57866.rs index 77c50e53868e1..058b58e174c5a 100644 --- a/src/test/ui/issues/issue-57866.rs +++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs @@ -1,6 +1,4 @@ -// compile-pass - -#![feature(type_alias_enum_variants)] +// build-pass (FIXME(62277): could be check-pass?) enum Outer { A(T) diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs index 21be61acb0c61..bff04daed0d58 100644 --- a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs +++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs @@ -1,9 +1,7 @@ // In this regression test we check that a path pattern referring to a unit variant // through a type alias is successful in inferring the generic argument. -// compile-pass - -#![feature(type_alias_enum_variants)] +// build-pass (FIXME(62277): could be check-pass?) enum Opt { N, diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs new file mode 100644 index 0000000000000..c1153fa4dc7b4 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs @@ -0,0 +1,14 @@ +// Check that a generic type for an `enum` admits type application +// on both the type constructor and the generic type's variant. +// +// Also check that a type alias to said generic type admits type application +// on the type constructor but *NOT* the variant. + +type Alias = Option; + +fn main() { + let _ = Option::::None; // OK + let _ = Option::None::; // OK (Lint in future!) + let _ = Alias::::None; // OK + let _ = Alias::None::; //~ ERROR type arguments are not allowed for this type +} diff --git a/src/test/ui/type-alias-enum-variants.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr similarity index 69% rename from src/test/ui/type-alias-enum-variants.stderr rename to src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr index 55f250fa7ee52..a1064d6925111 100644 --- a/src/test/ui/type-alias-enum-variants.stderr +++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr @@ -1,7 +1,7 @@ error[E0109]: type arguments are not allowed for this type - --> $DIR/type-alias-enum-variants.rs:9:27 + --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27 | -LL | let _ = Alias::None::; // Error +LL | let _ = Alias::None::; | ^^ type argument not allowed error: aborting due to previous error diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs new file mode 100644 index 0000000000000..11f4b05d0bf5d --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs @@ -0,0 +1,11 @@ +// Check that the compiler will resolve `::V` to the variant `V` in the type namespace +// but will reject this because `enum` variants do not exist in the type namespace. + +enum E { + V +} + +fn check() -> ::V {} +//~^ ERROR expected type, found variant `V` + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants-priority-3.stderr b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr similarity index 66% rename from src/test/ui/type-alias-enum-variants-priority-3.stderr rename to src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr index b3451542a2570..f190bfb69839e 100644 --- a/src/test/ui/type-alias-enum-variants-priority-3.stderr +++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr @@ -1,5 +1,5 @@ error: expected type, found variant `V` - --> $DIR/type-alias-enum-variants-priority-3.rs:7:15 + --> $DIR/resolve-to-enum-variant-in-type-namespace-and-error.rs:8:15 | LL | fn check() -> ::V {} | ^^^^^^ diff --git a/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs new file mode 100644 index 0000000000000..39677733d524d --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs @@ -0,0 +1,69 @@ +// run-pass + +// Check that it is possible to resolve, in the value namespace, +// to an `enum` variant through a type alias. This includes `Self`. +// Type qualified syntax `::Variant` also works when syntactically valid. + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Bar(i32), + Baz { i: i32 }, + Qux, +} + +type FooAlias = Foo; +type OptionAlias = Option; + +macro_rules! check_pat { + ($x:expr, $p:pat) => { + assert!(if let $p = $x { true } else { false }); + }; +} + +impl Foo { + fn bar() -> Self { + let x = Self::Bar(3); + assert_eq!(x, ::Bar(3)); + check_pat!(x, Self::Bar(3)); + x + } + + fn baz() -> Self { + let x = Self::Baz { i: 42 }; + check_pat!(x, Self::Baz { i: 42 }); + x + } + + fn qux() -> Self { + let x = Self::Qux; + assert_eq!(x, ::Qux); + check_pat!(x, Self::Qux); + check_pat!(x, ::Qux); + x + } +} + +fn main() { + let bar = Foo::Bar(1); + assert_eq!(bar, FooAlias::Bar(1)); + assert_eq!(bar, ::Bar(1)); + check_pat!(bar, FooAlias::Bar(1)); + + let baz = FooAlias::Baz { i: 2 }; + assert_eq!(baz, Foo::Baz { i: 2 }); + check_pat!(baz, FooAlias::Baz { i: 2 }); + + let qux = Foo::Qux; + assert_eq!(qux, FooAlias::Qux); + assert_eq!(qux, ::Qux); + check_pat!(qux, FooAlias::Qux); + check_pat!(qux, ::Qux); + + assert_eq!(Foo::bar(), Foo::Bar(3)); + assert_eq!(Foo::baz(), Foo::Baz { i: 42 }); + assert_eq!(Foo::qux(), Foo::Qux); + + let some = Option::Some(4); + assert_eq!(some, OptionAlias::Some(4)); + check_pat!(some, OptionAlias::Some(4)); +} diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs index f3cc5becc6f74..06705a2ebf5dd 100644 --- a/src/test/ui/type/type-alias-bounds.rs +++ b/src/test/ui/type/type-alias-bounds.rs @@ -1,6 +1,6 @@ // Test `ignored_generic_bounds` lint warning about bounds in type aliases. -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![allow(dead_code)] use std::rc::Rc; diff --git a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs index 9eed80ad886e0..710b7c9bbeefc 100644 --- a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs +++ b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // rust-lang/rust#55810: types for a binding in a match arm can be // inferred from arms that come later in the match. diff --git a/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs b/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs index 9fe8a5c832c5a..f476704cd8af0 100644 --- a/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs +++ b/src/test/ui/uninhabited/privately-uninhabited-dead-code.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![deny(unused_variables)] diff --git a/src/test/ui/union/union-const-eval.rs b/src/test/ui/union/union-const-eval.rs index 05e849a3bb617..90af8de447dfd 100644 --- a/src/test/ui/union/union-const-eval.rs +++ b/src/test/ui/union/union-const-eval.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(const_fn_union)] union U { diff --git a/src/test/ui/unreachable/unreachable-try-pattern.rs b/src/test/ui/unreachable/unreachable-try-pattern.rs index 6665c58e457f1..cbc5fcee2f035 100644 --- a/src/test/ui/unreachable/unreachable-try-pattern.rs +++ b/src/test/ui/unreachable/unreachable-try-pattern.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(never_type, exhaustive_patterns)] #![warn(unreachable_code)] #![warn(unreachable_patterns)] diff --git a/src/test/ui/unrestricted-attribute-tokens.rs b/src/test/ui/unrestricted-attribute-tokens.rs index b07ab96bce13f..e31bc91a00aad 100644 --- a/src/test/ui/unrestricted-attribute-tokens.rs +++ b/src/test/ui/unrestricted-attribute-tokens.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) #![feature(rustc_attrs)] diff --git a/src/test/ui/unsized-locals/unsized-index.rs b/src/test/ui/unsized-locals/unsized-index.rs index 2e6bd82bda302..19ad97a853e83 100644 --- a/src/test/ui/unsized-locals/unsized-index.rs +++ b/src/test/ui/unsized-locals/unsized-index.rs @@ -1,4 +1,4 @@ -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) // `std::ops::Index` has an `: ?Sized` bound on the `Idx` type param. This is // an accidental left-over from the times when it `Index` was by-reference. diff --git a/src/test/ui/user-defined-macro-rules.rs b/src/test/ui/user-defined-macro-rules.rs index 31bfdd025d99d..09e071ec45420 100644 --- a/src/test/ui/user-defined-macro-rules.rs +++ b/src/test/ui/user-defined-macro-rules.rs @@ -1,5 +1,9 @@ -#![allow(unused_macros)] +// check-pass -macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules` +macro_rules! macro_rules { () => { struct S; } } // OK -fn main() {} +macro_rules! {} // OK, calls the macro defined above + +fn main() { + let s = S; +} diff --git a/src/test/ui/user-defined-macro-rules.stderr b/src/test/ui/user-defined-macro-rules.stderr deleted file mode 100644 index 057515228e0d1..0000000000000 --- a/src/test/ui/user-defined-macro-rules.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: user-defined macros may not be named `macro_rules` - --> $DIR/user-defined-macro-rules.rs:3:1 - | -LL | macro_rules! macro_rules { () => {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/variance/variance-use-contravariant-struct-2.rs b/src/test/ui/variance/variance-use-contravariant-struct-2.rs index 77bd2b79f8cbc..2113eb2addb9b 100644 --- a/src/test/ui/variance/variance-use-contravariant-struct-2.rs +++ b/src/test/ui/variance/variance-use-contravariant-struct-2.rs @@ -2,7 +2,7 @@ // they permit lifetimes to be approximated as expected. #![allow(dead_code)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct SomeStruct(fn(T)); diff --git a/src/test/ui/variance/variance-use-covariant-struct-2.rs b/src/test/ui/variance/variance-use-covariant-struct-2.rs index cb8159d8a6848..ecd2204c991c6 100644 --- a/src/test/ui/variance/variance-use-covariant-struct-2.rs +++ b/src/test/ui/variance/variance-use-covariant-struct-2.rs @@ -2,7 +2,7 @@ // be shortened. #![allow(dead_code)] -// compile-pass +// build-pass (FIXME(62277): could be check-pass?) struct SomeStruct(T); diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 722979c3c1402..a75d9f0b0bb9b 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -99,6 +99,36 @@ impl fmt::Display for Mode { } } +#[derive(Clone, Copy, PartialEq, Debug, Hash)] +pub enum PassMode { + Check, + Build, + Run, +} + +impl FromStr for PassMode { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "check" => Ok(PassMode::Check), + "build" => Ok(PassMode::Build), + "run" => Ok(PassMode::Run), + _ => Err(()), + } + } +} + +impl fmt::Display for PassMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = match *self { + PassMode::Check => "check", + PassMode::Build => "build", + PassMode::Run => "run", + }; + fmt::Display::fmt(s, f) + } +} + #[derive(Clone, Debug, PartialEq)] pub enum CompareMode { Nll, @@ -184,6 +214,9 @@ pub struct Config { /// Exactly match the filter, rather than a substring pub filter_exact: bool, + /// Force the pass mode of a check/build/run-pass test to this mode. + pub force_pass_mode: Option, + /// Write out a parseable log of tests that were run pub logfile: Option, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 6ce7461f759a4..52f777db2daa6 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -6,7 +6,7 @@ use std::path::{Path, PathBuf}; use log::*; -use crate::common::{self, CompareMode, Config, Mode}; +use crate::common::{self, CompareMode, Config, Mode, PassMode}; use crate::util; use crate::extract_gdb_version; @@ -290,13 +290,6 @@ impl EarlyProps { } } -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum PassMode { - Check, - Build, - Run, -} - #[derive(Clone, Debug)] pub struct TestProps { // Lines that should be expected, in order, on standard out @@ -357,7 +350,9 @@ pub struct TestProps { // arguments. (In particular, it propagates to the aux-builds.) pub incremental_dir: Option, // How far should the test proceed while still passing. - pub pass_mode: Option, + pass_mode: Option, + // Ignore `--pass` overrides from the command line for this test. + ignore_pass: bool, // rustdoc will test the output of the `--test` option pub check_test_line_numbers_match: bool, // Do not pass `-Z ui-testing` to UI tests @@ -400,6 +395,7 @@ impl TestProps { forbid_output: vec![], incremental_dir: None, pass_mode: None, + ignore_pass: false, check_test_line_numbers_match: false, disable_ui_testing_normalization: false, normalize_stdout: vec![], @@ -528,6 +524,10 @@ impl TestProps { self.update_pass_mode(ln, cfg, config); + if !self.ignore_pass { + self.ignore_pass = config.parse_ignore_pass(ln); + } + if !self.disable_ui_testing_normalization { self.disable_ui_testing_normalization = config.parse_disable_ui_testing_normalization(ln); @@ -608,6 +608,15 @@ impl TestProps { (_, None) => {} } } + + pub fn pass_mode(&self, config: &Config) -> Option { + if !self.ignore_pass { + if let (mode @ Some(_), Some(_)) = (config.force_pass_mode, self.pass_mode) { + return mode; + } + } + self.pass_mode + } } fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) { @@ -743,6 +752,10 @@ impl Config { self.parse_name_directive(line, "check-test-line-numbers-match") } + fn parse_ignore_pass(&self, line: &str) -> bool { + self.parse_name_directive(line, "ignore-pass") + } + fn parse_assembly_output(&self, line: &str) -> Option { self.parse_name_value_directive(line, "assembly-output") .map(|r| r.trim().to_string()) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index d0dc9d11d3963..597fdf2d95e30 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -5,7 +5,7 @@ extern crate test; -use crate::common::CompareMode; +use crate::common::{CompareMode, PassMode}; use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS}; use crate::common::{Config, TestPaths}; use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; @@ -128,6 +128,12 @@ pub fn parse_config(args: Vec) -> Config { "(compile-fail|run-fail|run-pass|\ run-pass-valgrind|pretty|debug-info|incremental|mir-opt)", ) + .optopt( + "", + "pass", + "force {check,build,run}-pass tests to this mode.", + "check | build | run" + ) .optflag("", "ignored", "run tests marked as ignored") .optflag("", "exact", "filters match exactly") .optopt( @@ -320,6 +326,10 @@ pub fn parse_config(args: Vec) -> Config { run_ignored, filter: matches.free.first().cloned(), filter_exact: matches.opt_present("exact"), + force_pass_mode: matches.opt_str("pass").map(|mode| + mode.parse::() + .unwrap_or_else(|_| panic!("unknown `--pass` option `{}` given", mode)) + ), logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)), runtool: matches.opt_str("runtool"), host_rustcflags: matches.opt_str("host-rustcflags"), @@ -382,6 +392,10 @@ pub fn log_config(config: &Config) { ), ); logv(c, format!("filter_exact: {}", config.filter_exact)); + logv(c, format!( + "force_pass_mode: {}", + opt_str(&config.force_pass_mode.map(|m| format!("{}", m))), + )); logv(c, format!("runtool: {}", opt_str(&config.runtool))); logv( c, diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8b52a529d440a..35caf82dd7128 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,6 +1,6 @@ // ignore-tidy-filelength -use crate::common::CompareMode; +use crate::common::{CompareMode, PassMode}; use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; use crate::common::{output_base_dir, output_base_name, output_testname_unique}; use crate::common::{Codegen, CodegenUnits, Rustdoc}; @@ -10,7 +10,7 @@ use crate::common::{Config, TestPaths}; use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly}; use diff; use crate::errors::{self, Error, ErrorKind}; -use crate::header::{TestProps, PassMode}; +use crate::header::TestProps; use crate::json; use regex::{Captures, Regex}; use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; @@ -260,6 +260,10 @@ pub fn compute_stamp_hash(config: &Config) -> String { env::var_os("PYTHONPATH").hash(&mut hash); } + if let Ui | RunPass | Incremental | Pretty = config.mode { + config.force_pass_mode.hash(&mut hash); + } + format!("{:x}", hash.finish()) } @@ -309,10 +313,13 @@ impl<'test> TestCx<'test> { } } + fn pass_mode(&self) -> Option { + self.props.pass_mode(self.config) + } + fn should_run_successfully(&self) -> bool { match self.config.mode { - RunPass => true, - Ui => self.props.pass_mode == Some(PassMode::Run), + RunPass | Ui => self.pass_mode() == Some(PassMode::Run), mode => panic!("unimplemented for mode {:?}", mode), } } @@ -322,7 +329,7 @@ impl<'test> TestCx<'test> { CompileFail => false, RunPass => true, JsDocTest => true, - Ui => self.props.pass_mode.is_some(), + Ui => self.pass_mode().is_some(), Incremental => { let revision = self.revision .expect("incremental tests require a list of revisions"); @@ -330,7 +337,7 @@ impl<'test> TestCx<'test> { true } else if revision.starts_with("cfail") { // FIXME: would be nice if incremental revs could start with "cpass" - self.props.pass_mode.is_some() + self.pass_mode().is_some() } else { panic!("revision name must begin with rpass, rfail, or cfail"); } @@ -1341,7 +1348,7 @@ impl<'test> TestCx<'test> { fn check_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) { debug!("check_error_patterns"); if self.props.error_patterns.is_empty() { - if self.props.pass_mode.is_some() { + if self.pass_mode().is_some() { return; } else { self.fatal(&format!( @@ -1871,7 +1878,11 @@ impl<'test> TestCx<'test> { result } - fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> Command { + fn make_compile_args( + &self, + input_file: &Path, + output_file: TargetLocation, + ) -> Command { let is_rustdoc = self.config.src_base.ends_with("rustdoc-ui") || self.config.src_base.ends_with("rustdoc-js"); let mut rustc = if !is_rustdoc { @@ -1968,14 +1979,7 @@ impl<'test> TestCx<'test> { } } - if self.props.pass_mode == Some(PassMode::Check) { - assert!( - !self - .props - .compile_flags - .iter() - .any(|s| s.starts_with("--emit")) - ); + if let Some(PassMode::Check) = self.pass_mode() { rustc.args(&["--emit", "metadata"]); } diff --git a/src/tools/miri b/src/tools/miri index 945f007c0d305..d2df509867fbb 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 945f007c0d305c3ec069b5e5d911ef783f6d70e7 +Subproject commit d2df509867fbbbd35730c90aef54a8e73b046cd6 diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 9e7c18b7f566b..d5dff1dcae0d5 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -72,32 +72,33 @@ def issue( ): # Open an issue about the toolstate failure. assignees = [x.strip() for x in maintainers.split('@') if x != ''] - assignees.append(relevant_pr_user) if status == 'test-fail': status_description = 'has failing tests' else: status_description = 'no longer builds' + request = json.dumps({ + 'body': maybe_delink(textwrap.dedent('''\ + Hello, this is your friendly neighborhood mergebot. + After merging PR {}, I observed that the tool {} {}. + A follow-up PR to the repository {} is needed to fix the fallout. + + cc @{}, do you think you would have time to do the follow-up work? + If so, that would be great! + + cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. + + ''').format( + relevant_pr_number, tool, status_description, + REPOS.get(tool), relevant_pr_user, pr_reviewer + )), + 'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number), + 'assignees': assignees, + 'labels': ['T-compiler', 'I-nominated'], + }) + print("Creating issue:\n{}".format(request)) response = urllib2.urlopen(urllib2.Request( gh_url(), - json.dumps({ - 'body': maybe_delink(textwrap.dedent('''\ - Hello, this is your friendly neighborhood mergebot. - After merging PR {}, I observed that the tool {} {}. - A follow-up PR to the repository {} is needed to fix the fallout. - - cc @{}, do you think you would have time to do the follow-up work? - If so, that would be great! - - cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. - - ''').format( - relevant_pr_number, tool, status_description, - REPOS.get(tool), relevant_pr_user, pr_reviewer - )), - 'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number), - 'assignees': assignees, - 'labels': ['T-compiler', 'I-nominated'], - }), + request, { 'Authorization': 'token ' + github_token, 'Content-Type': 'application/json', @@ -135,13 +136,13 @@ def update_latest( for status in latest: tool = status['tool'] changed = False - create_issue = False + create_issue_for_status = None # set to the status that caused the issue for os, s in current_status.items(): old = status[os] new = s.get(tool, old) status[os] = new - if new > old: + if new > old: # comparing the strings, but they are ordered appropriately! # things got fixed or at least the status quo improved changed = True message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \ @@ -156,20 +157,24 @@ def update_latest( # Most tools only create issues for build failures. # Other failures can be spurious. if new == 'build-fail' or (tool == 'miri' and new == 'test-fail'): - create_issue = True + create_issue_for_status = new - if create_issue: + if create_issue_for_status is not None: try: issue( - tool, new, MAINTAINERS.get(tool, ''), + tool, create_issue_for_status, MAINTAINERS.get(tool, ''), relevant_pr_number, relevant_pr_user, pr_reviewer, ) - except IOError as e: + except urllib2.HTTPError as e: # network errors will simply end up not creating an issue, but that's better # than failing the entire build job - print("I/O error: {0}".format(e)) + print("HTTPError when creating issue for status regression: {0}\n{1}" + .format(e, e.read())) + except IOError as e: + print("I/O error when creating issue for status regression: {0}".format(e)) except: - print("Unexpected error: {0}".format(sys.exc_info()[0])) + print("Unexpected error when creating issue for status regression: {0}" + .format(sys.exc_info()[0])) raise if changed: diff --git a/src/tools/rls b/src/tools/rls index 597c9be8c75be..124483dd2f10f 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 597c9be8c75be3e664f189c4325c96cf9b464dc3 +Subproject commit 124483dd2f10fe3ba32f7f5b75f32224c77f9010