mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 06:22:00 +00:00
Auto merge of #3513 - rust-lang:rustup-2024-04-25, r=RalfJung
Automatic Rustup
This commit is contained in:
commit
9d7a47fe31
2
.github/ISSUE_TEMPLATE/tracking_issue.md
vendored
2
.github/ISSUE_TEMPLATE/tracking_issue.md
vendored
@ -28,6 +28,8 @@ Tracking issues are used to record the overall progress of implementation.
|
||||
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
|
||||
A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature.
|
||||
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
|
||||
Discussion comments will get marked as off-topic or deleted.
|
||||
Repeated discussions on the tracking issue may lead to the tracking issue getting locked.
|
||||
|
||||
### Steps
|
||||
<!--
|
||||
|
570
.github/workflows/ci.yml
vendored
570
.github/workflows/ci.yml
vendored
@ -45,575 +45,25 @@ jobs:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
- name: Calculate the CI job matrix
|
||||
run: python3 src/ci/scripts/calculate-job-matrix.py >> $GITHUB_OUTPUT
|
||||
run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT
|
||||
id: jobs
|
||||
pr:
|
||||
name: "PR - ${{ matrix.name }}"
|
||||
job:
|
||||
name: "${{ matrix.name }}"
|
||||
needs:
|
||||
- calculate_matrix
|
||||
env:
|
||||
PR_CI_JOB: 1
|
||||
CI_JOB_NAME: "${{ matrix.name }}"
|
||||
CI_JOB_NAME: "${{ matrix.image }}"
|
||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||
HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
|
||||
DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
SCCACHE_BUCKET: rust-lang-ci-sccache2
|
||||
TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
|
||||
CACHE_DOMAIN: ci-caches.rust-lang.org
|
||||
if: "github.event_name == 'pull_request'"
|
||||
continue-on-error: "${{ matrix.name == 'mingw-check-tidy' }}"
|
||||
continue-on-error: "${{ matrix.continue_on_error || false }}"
|
||||
strategy:
|
||||
matrix:
|
||||
include: "${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}"
|
||||
defaults:
|
||||
run:
|
||||
shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
|
||||
timeout-minutes: 600
|
||||
runs-on: "${{ matrix.os }}"
|
||||
steps:
|
||||
- if: "contains(matrix.os, 'windows')"
|
||||
uses: msys2/setup-msys2@v2.22.0
|
||||
with:
|
||||
msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}"
|
||||
update: false
|
||||
release: true
|
||||
path-type: inherit
|
||||
install: "make dos2unix diffutils\n"
|
||||
- name: disable git crlf conversion
|
||||
run: git config --global core.autocrlf false
|
||||
- name: checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: configure the PR in which the error message will be posted
|
||||
run: "echo \"[CI_PR_NUMBER=$num]\""
|
||||
env:
|
||||
num: "${{ github.event.number }}"
|
||||
if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'"
|
||||
- name: add extra environment variables
|
||||
run: src/ci/scripts/setup-environment.sh
|
||||
env:
|
||||
EXTRA_VARIABLES: "${{ toJson(matrix.env) }}"
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: decide whether to skip this job
|
||||
run: src/ci/scripts/should-skip-this.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure the channel matches the target branch
|
||||
run: src/ci/scripts/verify-channel.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: collect CPU statistics
|
||||
run: src/ci/scripts/collect-cpu-stats.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: show the current environment
|
||||
run: src/ci/scripts/dump-environment.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install awscli
|
||||
run: src/ci/scripts/install-awscli.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install sccache
|
||||
run: src/ci/scripts/install-sccache.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: select Xcode
|
||||
run: src/ci/scripts/select-xcode.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install clang
|
||||
run: src/ci/scripts/install-clang.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install tidy
|
||||
run: src/ci/scripts/install-tidy.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install WIX
|
||||
run: src/ci/scripts/install-wix.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: disable git crlf conversion
|
||||
run: src/ci/scripts/disable-git-crlf-conversion.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: checkout submodules
|
||||
run: src/ci/scripts/checkout-submodules.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install MSYS2
|
||||
run: src/ci/scripts/install-msys2.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install MinGW
|
||||
run: src/ci/scripts/install-mingw.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install ninja
|
||||
run: src/ci/scripts/install-ninja.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: enable ipv6 on Docker
|
||||
run: src/ci/scripts/enable-docker-ipv6.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: disable git crlf conversion
|
||||
run: src/ci/scripts/disable-git-crlf-conversion.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure line endings are correct
|
||||
run: src/ci/scripts/verify-line-endings.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure backported commits are in upstream branches
|
||||
run: src/ci/scripts/verify-backported-commits.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure the stable version number is correct
|
||||
run: src/ci/scripts/verify-stable-version-number.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: run the build
|
||||
run: src/ci/scripts/run-build-from-ci.sh 2>&1
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}"
|
||||
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
|
||||
TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: create github artifacts
|
||||
run: src/ci/scripts/create-doc-artifacts.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to github
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ env.DOC_ARTIFACT_NAME }}"
|
||||
path: obj/artifacts/doc
|
||||
if-no-files-found: ignore
|
||||
retention-days: 5
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to S3
|
||||
run: src/ci/scripts/upload-artifacts.sh
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}"
|
||||
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}"
|
||||
if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')"
|
||||
auto:
|
||||
name: "auto - ${{ matrix.name }}"
|
||||
env:
|
||||
CI_JOB_NAME: "${{ matrix.name }}"
|
||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||
HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
|
||||
DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
SCCACHE_BUCKET: rust-lang-ci-sccache2
|
||||
DEPLOY_BUCKET: rust-lang-ci2
|
||||
TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
|
||||
TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues"
|
||||
TOOLSTATE_PUBLISH: 1
|
||||
CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
|
||||
ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
|
||||
AWS_REGION: us-west-1
|
||||
CACHE_DOMAIN: ci-caches.rust-lang.org
|
||||
if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: aarch64-gnu
|
||||
os:
|
||||
- self-hosted
|
||||
- ARM64
|
||||
- linux
|
||||
- name: arm-android
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: armhf-gnu
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-aarch64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: "llvm,cranelift"
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: dist-android
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-arm-linux
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
env: {}
|
||||
- name: dist-armhf-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-armv7-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-i586-gnu-i586-i686-musl
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-i686-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-loongarch64-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-ohos
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-powerpc-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-powerpc64-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-powerpc64le-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-riscv64-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-s390x-linux
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-various-1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-various-2
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-x86_64-freebsd
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-x86_64-illumos
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: dist-x86_64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: "llvm,cranelift"
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
- name: dist-x86_64-linux-alt
|
||||
env:
|
||||
IMAGE: dist-x86_64-linux
|
||||
CODEGEN_BACKENDS: "llvm,cranelift"
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
- name: dist-x86_64-musl
|
||||
env:
|
||||
CODEGEN_BACKENDS: "llvm,cranelift"
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: dist-x86_64-netbsd
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: i686-gnu
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: i686-gnu-nopt
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: mingw-check
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: test-various
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: x86_64-gnu
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-stable
|
||||
env:
|
||||
IMAGE: x86_64-gnu
|
||||
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
- name: x86_64-gnu-aux
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-integration
|
||||
env:
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-debug
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-distcheck
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-llvm-18
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-llvm-17
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-nopt
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-tools
|
||||
env:
|
||||
DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: dist-x86_64-apple
|
||||
env:
|
||||
SCRIPT: "./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin"
|
||||
RUST_CONFIGURE_ARGS: "--enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
CODEGEN_BACKENDS: "llvm,cranelift"
|
||||
os: macos-13
|
||||
- name: dist-apple-various
|
||||
env:
|
||||
SCRIPT: "./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim"
|
||||
RUST_CONFIGURE_ARGS: "--enable-sanitizers --enable-profiler --set rust.jemalloc"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-13
|
||||
- name: x86_64-apple-1
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps"
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-13
|
||||
- name: x86_64-apple-2
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps"
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-13
|
||||
- name: dist-aarch64-apple
|
||||
env:
|
||||
SCRIPT: "./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin"
|
||||
RUST_CONFIGURE_ARGS: "--enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false --set rust.lto=thin"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
USE_XCODE_CLANG: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: macos-14
|
||||
- name: aarch64-apple
|
||||
env:
|
||||
SCRIPT: "./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin"
|
||||
RUST_CONFIGURE_ARGS: "--enable-sanitizers --enable-profiler --set rust.jemalloc"
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
USE_XCODE_CLANG: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
os: macos-14
|
||||
- name: x86_64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler"
|
||||
SCRIPT: make ci-msvc
|
||||
os: windows-2019-8core-32gb
|
||||
- name: i686-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-msvc"
|
||||
SCRIPT: make ci-msvc
|
||||
os: windows-2019-8core-32gb
|
||||
- name: x86_64-msvc-ext
|
||||
env:
|
||||
SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
|
||||
HOST_TARGET: x86_64-pc-windows-msvc
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json"
|
||||
DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
|
||||
os: windows-2019-8core-32gb
|
||||
- name: i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu"
|
||||
SCRIPT: make ci-mingw
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: x86_64-mingw
|
||||
env:
|
||||
SCRIPT: make ci-mingw
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: dist-x86_64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc --enable-full-tools --enable-profiler --set rust.codegen-units=1"
|
||||
SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: dist-i686-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler"
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: dist-aarch64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc --enable-full-tools --enable-profiler"
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: dist-i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --enable-full-tools --enable-profiler"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: dist-x86_64-mingw
|
||||
env:
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: windows-2019-8core-32gb
|
||||
- name: dist-x86_64-msvc-alt
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-extended --enable-profiler"
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
os: windows-2019-8core-32gb
|
||||
defaults:
|
||||
run:
|
||||
shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
|
||||
timeout-minutes: 600
|
||||
runs-on: "${{ matrix.os }}"
|
||||
steps:
|
||||
- if: "contains(matrix.os, 'windows')"
|
||||
uses: msys2/setup-msys2@v2.22.0
|
||||
with:
|
||||
msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}"
|
||||
update: false
|
||||
release: true
|
||||
path-type: inherit
|
||||
install: "make dos2unix diffutils\n"
|
||||
- name: disable git crlf conversion
|
||||
run: git config --global core.autocrlf false
|
||||
- name: checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: configure the PR in which the error message will be posted
|
||||
run: "echo \"[CI_PR_NUMBER=$num]\""
|
||||
env:
|
||||
num: "${{ github.event.number }}"
|
||||
if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'"
|
||||
- name: add extra environment variables
|
||||
run: src/ci/scripts/setup-environment.sh
|
||||
env:
|
||||
EXTRA_VARIABLES: "${{ toJson(matrix.env) }}"
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: decide whether to skip this job
|
||||
run: src/ci/scripts/should-skip-this.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure the channel matches the target branch
|
||||
run: src/ci/scripts/verify-channel.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: collect CPU statistics
|
||||
run: src/ci/scripts/collect-cpu-stats.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: show the current environment
|
||||
run: src/ci/scripts/dump-environment.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install awscli
|
||||
run: src/ci/scripts/install-awscli.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install sccache
|
||||
run: src/ci/scripts/install-sccache.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: select Xcode
|
||||
run: src/ci/scripts/select-xcode.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install clang
|
||||
run: src/ci/scripts/install-clang.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install tidy
|
||||
run: src/ci/scripts/install-tidy.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install WIX
|
||||
run: src/ci/scripts/install-wix.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: disable git crlf conversion
|
||||
run: src/ci/scripts/disable-git-crlf-conversion.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: checkout submodules
|
||||
run: src/ci/scripts/checkout-submodules.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install MSYS2
|
||||
run: src/ci/scripts/install-msys2.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install MinGW
|
||||
run: src/ci/scripts/install-mingw.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: install ninja
|
||||
run: src/ci/scripts/install-ninja.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: enable ipv6 on Docker
|
||||
run: src/ci/scripts/enable-docker-ipv6.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: disable git crlf conversion
|
||||
run: src/ci/scripts/disable-git-crlf-conversion.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure line endings are correct
|
||||
run: src/ci/scripts/verify-line-endings.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure backported commits are in upstream branches
|
||||
run: src/ci/scripts/verify-backported-commits.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: ensure the stable version number is correct
|
||||
run: src/ci/scripts/verify-stable-version-number.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: run the build
|
||||
run: src/ci/scripts/run-build-from-ci.sh 2>&1
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}"
|
||||
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
|
||||
TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: create github artifacts
|
||||
run: src/ci/scripts/create-doc-artifacts.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to github
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ env.DOC_ARTIFACT_NAME }}"
|
||||
path: obj/artifacts/doc
|
||||
if-no-files-found: ignore
|
||||
retention-days: 5
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to S3
|
||||
run: src/ci/scripts/upload-artifacts.sh
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}"
|
||||
AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}"
|
||||
if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')"
|
||||
try:
|
||||
name: "try - ${{ matrix.name }}"
|
||||
env:
|
||||
DIST_TRY_BUILD: 1
|
||||
CI_JOB_NAME: "${{ matrix.name }}"
|
||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||
HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
|
||||
DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
SCCACHE_BUCKET: rust-lang-ci-sccache2
|
||||
DEPLOY_BUCKET: rust-lang-ci2
|
||||
TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
|
||||
TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues"
|
||||
TOOLSTATE_PUBLISH: 1
|
||||
CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
|
||||
ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
|
||||
AWS_REGION: us-west-1
|
||||
CACHE_DOMAIN: ci-caches.rust-lang.org
|
||||
if: "github.event_name == 'push' && (((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust') || ((github.ref == 'refs/heads/automation/bors/try') && github.repository == 'rust-lang/rust'))"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: dist-x86_64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: "llvm,cranelift"
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
if: "fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null"
|
||||
defaults:
|
||||
run:
|
||||
shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
|
||||
@ -755,7 +205,7 @@ jobs:
|
||||
if: success() && !env.SKIP_JOB
|
||||
try-success:
|
||||
needs:
|
||||
- try
|
||||
- job
|
||||
if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
|
||||
steps:
|
||||
- name: mark the job as a success
|
||||
@ -765,7 +215,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
try-failure:
|
||||
needs:
|
||||
- try
|
||||
- job
|
||||
if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
|
||||
steps:
|
||||
- name: mark the job as a failure
|
||||
@ -775,7 +225,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
auto-success:
|
||||
needs:
|
||||
- auto
|
||||
- job
|
||||
if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
|
||||
steps:
|
||||
- name: mark the job as a success
|
||||
@ -785,7 +235,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
auto-failure:
|
||||
needs:
|
||||
- auto
|
||||
- job
|
||||
if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
|
||||
steps:
|
||||
- name: mark the job as a failure
|
||||
|
@ -3112,6 +3112,7 @@ pub struct Delegation {
|
||||
/// Path resolution id.
|
||||
pub id: NodeId,
|
||||
pub qself: Option<P<QSelf>>,
|
||||
pub rename: Option<Ident>,
|
||||
pub path: Path,
|
||||
pub body: Option<P<Block>>,
|
||||
}
|
||||
|
@ -1149,10 +1149,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
}
|
||||
ItemKind::MacCall(m) => vis.visit_mac_call(m),
|
||||
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
|
||||
ItemKind::Delegation(box Delegation { id, qself, path, body }) => {
|
||||
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
|
||||
vis.visit_id(id);
|
||||
vis.visit_qself(qself);
|
||||
vis.visit_path(path);
|
||||
if let Some(rename) = rename {
|
||||
vis.visit_ident(rename);
|
||||
}
|
||||
if let Some(body) = body {
|
||||
vis.visit_block(body);
|
||||
}
|
||||
@ -1195,10 +1198,13 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
|
||||
visit_opt(ty, |ty| visitor.visit_ty(ty));
|
||||
}
|
||||
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
|
||||
AssocItemKind::Delegation(box Delegation { id, qself, path, body }) => {
|
||||
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_qself(qself);
|
||||
visitor.visit_path(path);
|
||||
if let Some(rename) = rename {
|
||||
visitor.visit_ident(rename);
|
||||
}
|
||||
if let Some(body) = body {
|
||||
visitor.visit_block(body);
|
||||
}
|
||||
|
@ -382,11 +382,12 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) -> V::Resu
|
||||
}
|
||||
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
|
||||
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
|
||||
ItemKind::Delegation(box Delegation { id, qself, path, body }) => {
|
||||
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
|
||||
if let Some(qself) = qself {
|
||||
try_visit!(visitor.visit_ty(&qself.ty));
|
||||
}
|
||||
try_visit!(visitor.visit_path(path, *id));
|
||||
visit_opt!(visitor, visit_ident, *rename);
|
||||
visit_opt!(visitor, visit_block, body);
|
||||
}
|
||||
}
|
||||
@ -782,11 +783,12 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
|
||||
AssocItemKind::MacCall(mac) => {
|
||||
try_visit!(visitor.visit_mac_call(mac));
|
||||
}
|
||||
AssocItemKind::Delegation(box Delegation { id, qself, path, body }) => {
|
||||
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
|
||||
if let Some(qself) = qself {
|
||||
try_visit!(visitor.visit_ty(&qself.ty));
|
||||
}
|
||||
try_visit!(visitor.visit_path(path, *id));
|
||||
visit_opt!(visitor, visit_ident, *rename);
|
||||
visit_opt!(visitor, visit_block, body);
|
||||
}
|
||||
}
|
||||
|
@ -163,3 +163,6 @@ ast_lowering_underscore_expr_lhs_assign =
|
||||
.label = `_` not allowed here
|
||||
|
||||
ast_lowering_use_angle_brackets = use angle brackets instead
|
||||
ast_lowering_yield_in_closure =
|
||||
`yield` can only be used in `#[coroutine]` closures, or `gen` blocks
|
||||
.suggestion = use `#[coroutine]` to make this closure a coroutine
|
||||
|
@ -49,7 +49,7 @@ use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::ResolverAstLowering;
|
||||
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
|
||||
use rustc_span::{symbol::Ident, Span};
|
||||
use rustc_target::spec::abi;
|
||||
use std::iter;
|
||||
@ -67,7 +67,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
return false;
|
||||
};
|
||||
if let Some(local_sig_id) = sig_id.as_local() {
|
||||
self.resolver.has_self.contains(&local_sig_id)
|
||||
self.resolver.delegation_fn_sigs[&local_sig_id].has_self
|
||||
} else {
|
||||
match self.tcx.def_kind(sig_id) {
|
||||
DefKind::Fn => false,
|
||||
@ -82,13 +82,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
delegation: &Delegation,
|
||||
item_id: NodeId,
|
||||
) -> DelegationResults<'hir> {
|
||||
let span = delegation.path.segments.last().unwrap().ident.span;
|
||||
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
|
||||
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);
|
||||
match sig_id {
|
||||
Ok(sig_id) => {
|
||||
let decl = self.lower_delegation_decl(sig_id, span);
|
||||
let sig = self.lower_delegation_sig(span, decl);
|
||||
let body_id = self.lower_delegation_body(sig.decl, delegation);
|
||||
let (param_count, c_variadic) = self.param_count(sig_id);
|
||||
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
|
||||
let sig = self.lower_delegation_sig(sig_id, decl, span);
|
||||
let body_id = self.lower_delegation_body(delegation, param_count, span);
|
||||
|
||||
let generics = self.lower_delegation_generics(span);
|
||||
DelegationResults { body_id, sig, generics }
|
||||
@ -123,34 +124,47 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
})
|
||||
}
|
||||
|
||||
// Function parameter count, including C variadic `...` if present.
|
||||
fn param_count(&self, sig_id: DefId) -> (usize, bool /*c_variadic*/) {
|
||||
if let Some(local_sig_id) = sig_id.as_local() {
|
||||
// Map may be filled incorrectly due to recursive delegation.
|
||||
// Error will be emmited later during HIR ty lowering.
|
||||
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
|
||||
Some(sig) => (sig.param_count, sig.c_variadic),
|
||||
None => (0, false),
|
||||
}
|
||||
} else {
|
||||
let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
|
||||
(sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic)
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_delegation_decl(
|
||||
&mut self,
|
||||
sig_id: DefId,
|
||||
param_span: Span,
|
||||
param_count: usize,
|
||||
c_variadic: bool,
|
||||
span: Span,
|
||||
) -> &'hir hir::FnDecl<'hir> {
|
||||
let args_count = if let Some(local_sig_id) = sig_id.as_local() {
|
||||
// Map may be filled incorrectly due to recursive delegation.
|
||||
// Error will be emitted later during HIR ty lowering.
|
||||
self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
|
||||
} else {
|
||||
self.tcx.fn_arg_names(sig_id).len()
|
||||
};
|
||||
let inputs = self.arena.alloc_from_iter((0..args_count).map(|arg| hir::Ty {
|
||||
// The last parameter in C variadic functions is skipped in the signature,
|
||||
// like during regular lowering.
|
||||
let decl_param_count = param_count - c_variadic as usize;
|
||||
let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Input(arg)),
|
||||
span: self.lower_span(param_span),
|
||||
span,
|
||||
}));
|
||||
|
||||
let output = self.arena.alloc(hir::Ty {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Output),
|
||||
span: self.lower_span(param_span),
|
||||
span,
|
||||
});
|
||||
|
||||
self.arena.alloc(hir::FnDecl {
|
||||
inputs,
|
||||
output: hir::FnRetTy::Return(output),
|
||||
c_variadic: false,
|
||||
c_variadic,
|
||||
lifetime_elision_allowed: true,
|
||||
implicit_self: hir::ImplicitSelfKind::None,
|
||||
})
|
||||
@ -158,35 +172,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
fn lower_delegation_sig(
|
||||
&mut self,
|
||||
span: Span,
|
||||
sig_id: DefId,
|
||||
decl: &'hir hir::FnDecl<'hir>,
|
||||
span: Span,
|
||||
) -> hir::FnSig<'hir> {
|
||||
hir::FnSig {
|
||||
decl,
|
||||
header: hir::FnHeader {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
constness: hir::Constness::NotConst,
|
||||
asyncness: hir::IsAsync::NotAsync,
|
||||
abi: abi::Abi::Rust,
|
||||
},
|
||||
span: self.lower_span(span),
|
||||
}
|
||||
let header = if let Some(local_sig_id) = sig_id.as_local() {
|
||||
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
|
||||
Some(sig) => self.lower_fn_header(sig.header),
|
||||
None => self.generate_header_error(),
|
||||
}
|
||||
} else {
|
||||
let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
|
||||
let asyncness = match self.tcx.asyncness(sig_id) {
|
||||
Asyncness::Yes => hir::IsAsync::Async(span),
|
||||
Asyncness::No => hir::IsAsync::NotAsync,
|
||||
};
|
||||
hir::FnHeader {
|
||||
unsafety: sig.unsafety,
|
||||
constness: self.tcx.constness(sig_id),
|
||||
asyncness,
|
||||
abi: sig.abi,
|
||||
}
|
||||
};
|
||||
hir::FnSig { decl, header, span }
|
||||
}
|
||||
|
||||
fn generate_param(&mut self, ty: &'hir hir::Ty<'hir>) -> (hir::Param<'hir>, NodeId) {
|
||||
fn generate_param(&mut self, span: Span) -> (hir::Param<'hir>, NodeId) {
|
||||
let pat_node_id = self.next_node_id();
|
||||
let pat_id = self.lower_node_id(pat_node_id);
|
||||
let pat = self.arena.alloc(hir::Pat {
|
||||
hir_id: pat_id,
|
||||
kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, Ident::empty(), None),
|
||||
span: ty.span,
|
||||
span,
|
||||
default_binding_modes: false,
|
||||
});
|
||||
|
||||
(hir::Param { hir_id: self.next_id(), pat, ty_span: ty.span, span: ty.span }, pat_node_id)
|
||||
(hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
|
||||
}
|
||||
|
||||
fn generate_arg(&mut self, ty: &'hir hir::Ty<'hir>, param_id: HirId) -> hir::Expr<'hir> {
|
||||
fn generate_arg(&mut self, param_id: HirId, span: Span) -> hir::Expr<'hir> {
|
||||
let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {
|
||||
ident: Ident::empty(),
|
||||
hir_id: self.next_id(),
|
||||
@ -195,20 +219,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
infer_args: false,
|
||||
}));
|
||||
|
||||
let path =
|
||||
self.arena.alloc(hir::Path { span: ty.span, res: Res::Local(param_id), segments });
|
||||
let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });
|
||||
|
||||
hir::Expr {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
|
||||
span: ty.span,
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_delegation_body(
|
||||
&mut self,
|
||||
decl: &'hir hir::FnDecl<'hir>,
|
||||
delegation: &Delegation,
|
||||
param_count: usize,
|
||||
span: Span,
|
||||
) -> BodyId {
|
||||
let path = self.lower_qpath(
|
||||
delegation.id,
|
||||
@ -224,8 +248,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let mut parameters: Vec<hir::Param<'_>> = Vec::new();
|
||||
let mut args: Vec<hir::Expr<'hir>> = Vec::new();
|
||||
|
||||
for (idx, param_ty) in decl.inputs.iter().enumerate() {
|
||||
let (param, pat_node_id) = this.generate_param(param_ty);
|
||||
for idx in 0..param_count {
|
||||
let (param, pat_node_id) = this.generate_param(span);
|
||||
parameters.push(param);
|
||||
|
||||
let arg = if let Some(block) = block
|
||||
@ -245,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
} else {
|
||||
let pat_hir_id = this.lower_node_id(pat_node_id);
|
||||
this.generate_arg(param_ty, pat_hir_id)
|
||||
this.generate_arg(pat_hir_id, span)
|
||||
};
|
||||
args.push(arg);
|
||||
}
|
||||
@ -304,7 +328,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
implicit_self: hir::ImplicitSelfKind::None,
|
||||
});
|
||||
|
||||
let sig = self.lower_delegation_sig(span, decl);
|
||||
let header = self.generate_header_error();
|
||||
let sig = hir::FnSig { decl, header, span };
|
||||
|
||||
let body_id = self.lower_body(|this| {
|
||||
let expr =
|
||||
hir::Expr { hir_id: this.next_id(), kind: hir::ExprKind::Err(err), span: span };
|
||||
@ -312,6 +338,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
});
|
||||
DelegationResults { generics, body_id, sig }
|
||||
}
|
||||
|
||||
fn generate_header_error(&self) -> hir::FnHeader {
|
||||
hir::FnHeader {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
constness: hir::Constness::NotConst,
|
||||
asyncness: hir::IsAsync::NotAsync,
|
||||
abi: abi::Abi::Rust,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SelfResolver<'a> {
|
||||
|
@ -421,3 +421,12 @@ pub(crate) struct NoPreciseCapturesOnApit {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_lowering_yield_in_closure)]
|
||||
pub(crate) struct YieldInClosure {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
|
||||
pub suggestion: Option<Span>,
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use super::errors::{
|
||||
};
|
||||
use super::ResolverAstLoweringExt;
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
||||
use crate::errors::YieldInClosure;
|
||||
use crate::{FnDeclKind, ImplTraitPosition};
|
||||
use rustc_ast::ptr::P as AstP;
|
||||
use rustc_ast::*;
|
||||
@ -217,6 +218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
binder,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
hir_id,
|
||||
*constness,
|
||||
*movability,
|
||||
fn_decl,
|
||||
@ -955,6 +957,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
binder: &ClosureBinder,
|
||||
capture_clause: CaptureBy,
|
||||
closure_id: NodeId,
|
||||
closure_hir_id: hir::HirId,
|
||||
constness: Const,
|
||||
movability: Movability,
|
||||
decl: &FnDecl,
|
||||
@ -965,8 +968,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
|
||||
|
||||
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
|
||||
let mut coroutine_kind = None;
|
||||
let mut coroutine_kind = if this
|
||||
.attrs
|
||||
.get(&closure_hir_id.local_id)
|
||||
.is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine)))
|
||||
{
|
||||
Some(hir::CoroutineKind::Coroutine(Movability::Movable))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let body_id = this.lower_fn_body(decl, |this| {
|
||||
this.coroutine_kind = coroutine_kind;
|
||||
let e = this.lower_expr_mut(body);
|
||||
coroutine_kind = this.coroutine_kind;
|
||||
e
|
||||
@ -1565,7 +1577,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
let suggestion = self.current_item.map(|s| s.shrink_to_lo());
|
||||
self.dcx().emit_err(YieldInClosure { span, suggestion });
|
||||
self.coroutine_kind = Some(hir::CoroutineKind::Coroutine(Movability::Movable));
|
||||
|
||||
false
|
||||
}
|
||||
};
|
||||
|
@ -203,7 +203,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
body,
|
||||
..
|
||||
}) => {
|
||||
self.with_new_scopes(ident.span, |this| {
|
||||
self.with_new_scopes(*fn_sig_span, |this| {
|
||||
// Note: we don't need to change the return type from `T` to
|
||||
// `impl Future<Output = T>` here because lower_body
|
||||
// only cares about the input argument patterns in the function
|
||||
@ -1344,7 +1344,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
||||
}
|
||||
|
||||
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
||||
pub(super) fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
||||
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
|
||||
hir::IsAsync::Async(span)
|
||||
} else {
|
||||
|
@ -556,7 +556,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||
half_open_range_patterns_in_slices,
|
||||
"half-open range patterns in slices are unstable"
|
||||
);
|
||||
gate_all!(inline_const, "inline-const is experimental");
|
||||
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
|
||||
gate_all!(associated_const_equality, "associated const equality is incomplete");
|
||||
gate_all!(yeet_expr, "`do yeet` expression is experimental");
|
||||
|
@ -347,7 +347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
mpi: MovePathIndex,
|
||||
err: &mut Diag<'tcx>,
|
||||
in_pattern: &mut bool,
|
||||
move_spans: UseSpans<'_>,
|
||||
move_spans: UseSpans<'tcx>,
|
||||
) {
|
||||
let move_span = match move_spans {
|
||||
UseSpans::ClosureUse { capture_kind_span, .. } => capture_kind_span,
|
||||
@ -491,11 +491,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
..
|
||||
} = move_spans
|
||||
{
|
||||
self.suggest_cloning(err, ty, expr, None);
|
||||
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
|
||||
} else if self.suggest_hoisting_call_outside_loop(err, expr) {
|
||||
// The place where the the type moves would be misleading to suggest clone.
|
||||
// #121466
|
||||
self.suggest_cloning(err, ty, expr, None);
|
||||
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
|
||||
}
|
||||
}
|
||||
if let Some(pat) = finder.pat {
|
||||
@ -1085,6 +1085,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
mut expr: &'cx hir::Expr<'cx>,
|
||||
mut other_expr: Option<&'cx hir::Expr<'cx>>,
|
||||
use_spans: Option<UseSpans<'tcx>>,
|
||||
) {
|
||||
if let hir::ExprKind::Struct(_, _, Some(_)) = expr.kind {
|
||||
// We have `S { foo: val, ..base }`. In `check_aggregate_rvalue` we have a single
|
||||
@ -1197,14 +1198,50 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
.all(|field| self.implements_clone(field.ty(self.infcx.tcx, args)))
|
||||
})
|
||||
{
|
||||
let ty_span = self.infcx.tcx.def_span(def.did());
|
||||
let mut span: MultiSpan = ty_span.into();
|
||||
span.push_span_label(ty_span, "consider implementing `Clone` for this type");
|
||||
span.push_span_label(expr.span, "you could clone this value");
|
||||
err.span_note(
|
||||
self.infcx.tcx.def_span(def.did()),
|
||||
span,
|
||||
format!("if `{ty}` implemented `Clone`, you could clone the value"),
|
||||
);
|
||||
} else if let ty::Param(param) = ty.kind()
|
||||
&& let Some(_clone_trait_def) = self.infcx.tcx.lang_items().clone_trait()
|
||||
&& let generics = self.infcx.tcx.generics_of(self.mir_def_id())
|
||||
&& let generic_param = generics.type_param(*param, self.infcx.tcx)
|
||||
&& let param_span = self.infcx.tcx.def_span(generic_param.def_id)
|
||||
&& if let Some(UseSpans::FnSelfUse { kind, .. }) = use_spans
|
||||
&& let CallKind::FnCall { fn_trait_id, self_ty } = kind
|
||||
&& let ty::Param(_) = self_ty.kind()
|
||||
&& ty == self_ty
|
||||
&& [
|
||||
self.infcx.tcx.lang_items().fn_once_trait(),
|
||||
self.infcx.tcx.lang_items().fn_mut_trait(),
|
||||
self.infcx.tcx.lang_items().fn_trait(),
|
||||
]
|
||||
.contains(&Some(fn_trait_id))
|
||||
{
|
||||
// Do not suggest `F: FnOnce() + Clone`.
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
{
|
||||
let mut span: MultiSpan = param_span.into();
|
||||
span.push_span_label(
|
||||
param_span,
|
||||
"consider constraining this type parameter with `Clone`",
|
||||
);
|
||||
span.push_span_label(expr.span, "you could clone this value");
|
||||
err.span_help(
|
||||
span,
|
||||
format!("if `{ty}` implemented `Clone`, you could clone the value"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
|
||||
pub(crate) fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
|
||||
let Some(clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() else { return false };
|
||||
self.infcx
|
||||
.type_implements_trait(clone_trait_def, [ty], self.param_env)
|
||||
@ -1403,7 +1440,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if let Some(expr) = self.find_expr(borrow_span)
|
||||
&& let Some(ty) = typeck_results.node_type_opt(expr.hir_id)
|
||||
{
|
||||
self.suggest_cloning(&mut err, ty, expr, self.find_expr(span));
|
||||
self.suggest_cloning(&mut err, ty, expr, self.find_expr(span), Some(move_spans));
|
||||
}
|
||||
self.buffer_error(err);
|
||||
}
|
||||
@ -1964,7 +2001,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
pub(crate) fn find_expr(&self, span: Span) -> Option<&hir::Expr<'_>> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let body_id = tcx.hir_node(self.mir_hir_id()).body_id()?;
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, tcx);
|
||||
expr_finder.visit_expr(tcx.hir().body(body_id).value);
|
||||
expr_finder.result
|
||||
}
|
||||
@ -1998,14 +2035,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
};
|
||||
|
||||
let mut expr_finder =
|
||||
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span);
|
||||
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span, tcx);
|
||||
expr_finder.visit_expr(hir.body(body_id).value);
|
||||
let Some(index1) = expr_finder.result else {
|
||||
note_default_suggestion();
|
||||
return;
|
||||
};
|
||||
|
||||
expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span);
|
||||
expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span, tcx);
|
||||
expr_finder.visit_expr(hir.body(body_id).value);
|
||||
let Some(index2) = expr_finder.result else {
|
||||
note_default_suggestion();
|
||||
|
@ -76,7 +76,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||
&& let Some(body_id) = node.body_id()
|
||||
{
|
||||
let body = tcx.hir().body(body_id);
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, tcx);
|
||||
expr_finder.visit_expr(body.value);
|
||||
if let Some(mut expr) = expr_finder.result {
|
||||
while let hir::ExprKind::AddrOf(_, _, inner)
|
||||
|
@ -2,10 +2,13 @@
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{CaptureBy, ExprKind, HirId, Node};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
|
||||
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
|
||||
use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
|
||||
|
||||
use crate::diagnostics::CapturedMessageOpt;
|
||||
use crate::diagnostics::{DescribePlaceOpt, UseSpans};
|
||||
@ -303,6 +306,121 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
self.cannot_move_out_of(span, &description)
|
||||
}
|
||||
|
||||
fn suggest_clone_of_captured_var_in_move_closure(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
upvar_hir_id: HirId,
|
||||
upvar_name: &str,
|
||||
use_spans: Option<UseSpans<'tcx>>,
|
||||
) {
|
||||
let tcx = self.infcx.tcx;
|
||||
let typeck_results = tcx.typeck(self.mir_def_id());
|
||||
let Some(use_spans) = use_spans else { return };
|
||||
// We only care about the case where a closure captured a binding.
|
||||
let UseSpans::ClosureUse { args_span, .. } = use_spans else { return };
|
||||
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
|
||||
// Fetch the type of the expression corresponding to the closure-captured binding.
|
||||
let Some(captured_ty) = typeck_results.node_type_opt(upvar_hir_id) else { return };
|
||||
if !self.implements_clone(captured_ty) {
|
||||
// We only suggest cloning the captured binding if the type can actually be cloned.
|
||||
return;
|
||||
};
|
||||
// Find the closure that captured the binding.
|
||||
let mut expr_finder = FindExprBySpan::new(args_span, tcx);
|
||||
expr_finder.include_closures = true;
|
||||
expr_finder.visit_expr(tcx.hir().body(body_id).value);
|
||||
let Some(closure_expr) = expr_finder.result else { return };
|
||||
let ExprKind::Closure(closure) = closure_expr.kind else { return };
|
||||
// We'll only suggest cloning the binding if it's a `move` closure.
|
||||
let CaptureBy::Value { .. } = closure.capture_clause else { return };
|
||||
// Find the expression within the closure where the binding is consumed.
|
||||
let mut suggested = false;
|
||||
let use_span = use_spans.var_or_use();
|
||||
let mut expr_finder = FindExprBySpan::new(use_span, tcx);
|
||||
expr_finder.include_closures = true;
|
||||
expr_finder.visit_expr(tcx.hir().body(body_id).value);
|
||||
let Some(use_expr) = expr_finder.result else { return };
|
||||
let parent = tcx.parent_hir_node(use_expr.hir_id);
|
||||
if let Node::Expr(expr) = parent
|
||||
&& let ExprKind::Assign(lhs, ..) = expr.kind
|
||||
&& lhs.hir_id == use_expr.hir_id
|
||||
{
|
||||
// Cloning the value being assigned makes no sense:
|
||||
//
|
||||
// error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
|
||||
// --> $DIR/option-content-move2.rs:11:9
|
||||
// |
|
||||
// LL | let mut var = None;
|
||||
// | ------- captured outer variable
|
||||
// LL | func(|| {
|
||||
// | -- captured by this `FnMut` closure
|
||||
// LL | // Shouldn't suggest `move ||.as_ref()` here
|
||||
// LL | move || {
|
||||
// | ^^^^^^^ `var` is moved here
|
||||
// LL |
|
||||
// LL | var = Some(NotCopyable);
|
||||
// | ---
|
||||
// | |
|
||||
// | variable moved due to use in closure
|
||||
// | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
|
||||
// |
|
||||
return;
|
||||
}
|
||||
|
||||
// Search for an appropriate place for the structured `.clone()` suggestion to be applied.
|
||||
// If we encounter a statement before the borrow error, we insert a statement there.
|
||||
for (_, node) in tcx.hir().parent_iter(closure_expr.hir_id) {
|
||||
if let Node::Stmt(stmt) = node {
|
||||
let padding = tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.indentation_before(stmt.span)
|
||||
.unwrap_or_else(|| " ".to_string());
|
||||
err.multipart_suggestion_verbose(
|
||||
"clone the value before moving it into the closure",
|
||||
vec![
|
||||
(
|
||||
stmt.span.shrink_to_lo(),
|
||||
format!("let value = {upvar_name}.clone();\n{padding}"),
|
||||
),
|
||||
(use_span, "value".to_string()),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
suggested = true;
|
||||
break;
|
||||
} else if let Node::Expr(expr) = node
|
||||
&& let ExprKind::Closure(_) = expr.kind
|
||||
{
|
||||
// We want to suggest cloning only on the first closure, not
|
||||
// subsequent ones (like `ui/suggestions/option-content-move2.rs`).
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !suggested {
|
||||
// If we couldn't find a statement for us to insert a new `.clone()` statement before,
|
||||
// we have a bare expression, so we suggest the creation of a new block inline to go
|
||||
// from `move || val` to `{ let value = val.clone(); move || value }`.
|
||||
let padding = tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.indentation_before(closure_expr.span)
|
||||
.unwrap_or_else(|| " ".to_string());
|
||||
err.multipart_suggestion_verbose(
|
||||
"clone the value before moving it into the closure",
|
||||
vec![
|
||||
(
|
||||
closure_expr.span.shrink_to_lo(),
|
||||
format!("{{\n{padding}let value = {upvar_name}.clone();\n{padding}"),
|
||||
),
|
||||
(use_spans.var_or_use(), "value".to_string()),
|
||||
(closure_expr.span.shrink_to_hi(), format!("\n{padding}}}")),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_cannot_move_from_borrowed_content(
|
||||
&mut self,
|
||||
move_place: Place<'tcx>,
|
||||
@ -310,10 +428,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
span: Span,
|
||||
use_spans: Option<UseSpans<'tcx>>,
|
||||
) -> Diag<'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
// Inspect the type of the content behind the
|
||||
// borrow to provide feedback about why this
|
||||
// was a move rather than a copy.
|
||||
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
|
||||
let ty = deref_target_place.ty(self.body, tcx).ty;
|
||||
let upvar_field = self
|
||||
.prefixes(move_place.as_ref(), PrefixSet::All)
|
||||
.find_map(|p| self.is_upvar_field_projection(p));
|
||||
@ -363,8 +482,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
let upvar = &self.upvars[upvar_field.unwrap().index()];
|
||||
let upvar_hir_id = upvar.get_root_variable();
|
||||
let upvar_name = upvar.to_string(self.infcx.tcx);
|
||||
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
|
||||
let upvar_name = upvar.to_string(tcx);
|
||||
let upvar_span = tcx.hir().span(upvar_hir_id);
|
||||
|
||||
let place_name = self.describe_any_place(move_place.as_ref());
|
||||
|
||||
@ -380,12 +499,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
closure_kind_ty, closure_kind, place_description,
|
||||
);
|
||||
|
||||
self.cannot_move_out_of(span, &place_description)
|
||||
let closure_span = tcx.def_span(def_id);
|
||||
let mut err = self
|
||||
.cannot_move_out_of(span, &place_description)
|
||||
.with_span_label(upvar_span, "captured outer variable")
|
||||
.with_span_label(
|
||||
self.infcx.tcx.def_span(def_id),
|
||||
closure_span,
|
||||
format!("captured by this `{closure_kind}` closure"),
|
||||
)
|
||||
);
|
||||
self.suggest_clone_of_captured_var_in_move_closure(
|
||||
&mut err,
|
||||
upvar_hir_id,
|
||||
&upvar_name,
|
||||
use_spans,
|
||||
);
|
||||
err
|
||||
}
|
||||
_ => {
|
||||
let source = self.borrowed_content_source(deref_base);
|
||||
@ -415,7 +543,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
),
|
||||
(_, _, _) => self.cannot_move_out_of(
|
||||
span,
|
||||
&source.describe_for_unnamed_place(self.infcx.tcx),
|
||||
&source.describe_for_unnamed_place(tcx),
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -447,7 +575,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
if let Some(expr) = self.find_expr(span) {
|
||||
self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span));
|
||||
self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span), None);
|
||||
}
|
||||
|
||||
err.subdiagnostic(
|
||||
@ -482,7 +610,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
if let Some(expr) = self.find_expr(use_span) {
|
||||
self.suggest_cloning(err, place_ty, expr, self.find_expr(span));
|
||||
self.suggest_cloning(
|
||||
err,
|
||||
place_ty,
|
||||
expr,
|
||||
self.find_expr(span),
|
||||
Some(use_spans),
|
||||
);
|
||||
}
|
||||
|
||||
err.subdiagnostic(
|
||||
@ -595,7 +729,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let place_desc = &format!("`{}`", self.local_names[*local].unwrap());
|
||||
|
||||
if let Some(expr) = self.find_expr(binding_span) {
|
||||
self.suggest_cloning(err, bind_to.ty, expr, None);
|
||||
self.suggest_cloning(err, bind_to.ty, expr, None, None);
|
||||
}
|
||||
|
||||
err.subdiagnostic(
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
use std::ops::Coroutine;
|
||||
use std::pin::Pin;
|
||||
@ -8,7 +8,8 @@ fn main() {
|
||||
}
|
||||
|
||||
fn run_coroutine<T>() {
|
||||
let mut coroutine = || {
|
||||
let mut coroutine = #[coroutine]
|
||||
|| {
|
||||
yield;
|
||||
return;
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![feature(
|
||||
core_intrinsics,
|
||||
coroutines,
|
||||
stmt_expr_attributes,
|
||||
coroutine_trait,
|
||||
is_sorted,
|
||||
repr_simd,
|
||||
@ -123,9 +124,12 @@ fn main() {
|
||||
test_simd();
|
||||
}
|
||||
|
||||
Box::pin(move |mut _task_context| {
|
||||
yield ();
|
||||
})
|
||||
Box::pin(
|
||||
#[coroutine]
|
||||
move |mut _task_context| {
|
||||
yield ();
|
||||
},
|
||||
)
|
||||
.as_mut()
|
||||
.resume(0);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![allow(internal_features)]
|
||||
#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted)]
|
||||
#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted, stmt_expr_attributes)]
|
||||
|
||||
#[cfg(feature="master")]
|
||||
#[cfg(target_arch="x86_64")]
|
||||
@ -103,7 +103,7 @@ fn main() {
|
||||
test_simd();
|
||||
}
|
||||
|
||||
Box::pin(move |mut _task_context| {
|
||||
Box::pin(#[coroutine] move |mut _task_context| {
|
||||
yield ();
|
||||
}).as_mut().resume(0);
|
||||
|
||||
|
@ -898,26 +898,20 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
self.gcc_checked_binop(oop, typ, lhs, rhs)
|
||||
}
|
||||
|
||||
fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> {
|
||||
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
|
||||
// Ideally, we shouldn't need to do this check.
|
||||
let aligned_type = if ty == self.cx.u128_type || ty == self.cx.i128_type {
|
||||
ty
|
||||
} else {
|
||||
ty.get_aligned(align.bytes())
|
||||
};
|
||||
fn alloca(&mut self, size: Size, align: Align) -> RValue<'gcc> {
|
||||
let ty = self.cx.type_array(self.cx.type_i8(), size.bytes()).get_aligned(align.bytes());
|
||||
// TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial.
|
||||
self.stack_var_count.set(self.stack_var_count.get() + 1);
|
||||
self.current_func()
|
||||
.new_local(
|
||||
self.location,
|
||||
aligned_type,
|
||||
ty,
|
||||
&format!("stack_var_{}", self.stack_var_count.get()),
|
||||
)
|
||||
.get_address(self.location)
|
||||
}
|
||||
|
||||
fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> {
|
||||
fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -531,7 +531,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||
// We instead thus allocate some scratch space...
|
||||
let scratch_size = cast.size(bx);
|
||||
let scratch_align = cast.align(bx);
|
||||
let llscratch = bx.alloca(cast.gcc_type(bx), scratch_align);
|
||||
let llscratch = bx.alloca(scratch_size, scratch_align);
|
||||
bx.lifetime_start(llscratch, scratch_size);
|
||||
|
||||
// ... where we first store the value...
|
||||
|
@ -18,7 +18,7 @@ use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::layout::HasTyCtxt;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_target::abi::Align;
|
||||
use rustc_target::abi::{Align, Size};
|
||||
|
||||
use crate::builder::Builder;
|
||||
#[cfg(not(feature = "master"))]
|
||||
@ -558,7 +558,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
let ze = bx.zext(result, bx.type_ix(expected_bytes * 8));
|
||||
|
||||
// Convert the integer to a byte array
|
||||
let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE);
|
||||
let ptr = bx.alloca(Size::from_bytes(expected_bytes), Align::ONE);
|
||||
bx.store(ze, ptr, Align::ONE);
|
||||
let array_ty = bx.type_array(bx.type_i8(), expected_bytes);
|
||||
let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty));
|
||||
|
@ -227,7 +227,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||
// when passed by value, making it larger.
|
||||
let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes());
|
||||
// Allocate some scratch space...
|
||||
let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
|
||||
let llscratch = bx.alloca(scratch_size, scratch_align);
|
||||
bx.lifetime_start(llscratch, scratch_size);
|
||||
// ...store the value...
|
||||
bx.store(val, llscratch, scratch_align);
|
||||
|
@ -468,9 +468,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
val
|
||||
}
|
||||
|
||||
fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
|
||||
fn alloca(&mut self, size: Size, align: Align) -> &'ll Value {
|
||||
let mut bx = Builder::with_cx(self.cx);
|
||||
bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) });
|
||||
let ty = self.cx().type_array(self.cx().type_i8(), size.bytes());
|
||||
unsafe {
|
||||
let alloca = llvm::LLVMBuildAlloca(bx.llbuilder, ty, UNNAMED);
|
||||
llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
|
||||
@ -478,10 +479,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn byte_array_alloca(&mut self, len: &'ll Value, align: Align) -> &'ll Value {
|
||||
fn dynamic_alloca(&mut self, size: &'ll Value, align: Align) -> &'ll Value {
|
||||
unsafe {
|
||||
let alloca =
|
||||
llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), len, UNNAMED);
|
||||
llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), size, UNNAMED);
|
||||
llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
|
||||
alloca
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Ty};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
|
||||
use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size};
|
||||
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
@ -649,8 +649,9 @@ fn codegen_msvc_try<'ll>(
|
||||
// }
|
||||
//
|
||||
// More information can be found in libstd's seh.rs implementation.
|
||||
let ptr_size = bx.tcx().data_layout.pointer_size;
|
||||
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
|
||||
let slot = bx.alloca(bx.type_ptr(), ptr_align);
|
||||
let slot = bx.alloca(ptr_size, ptr_align);
|
||||
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
|
||||
|
||||
@ -920,15 +921,14 @@ fn codegen_emcc_try<'ll>(
|
||||
|
||||
// We need to pass two values to catch_func (ptr and is_rust_panic), so
|
||||
// create an alloca and pass a pointer to that.
|
||||
let ptr_size = bx.tcx().data_layout.pointer_size;
|
||||
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
|
||||
let i8_align = bx.tcx().data_layout.i8_align.abi;
|
||||
let catch_data_type = bx.type_struct(&[bx.type_ptr(), bx.type_bool()], false);
|
||||
let catch_data = bx.alloca(catch_data_type, ptr_align);
|
||||
let catch_data_0 =
|
||||
bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(0)]);
|
||||
bx.store(ptr, catch_data_0, ptr_align);
|
||||
let catch_data_1 =
|
||||
bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(1)]);
|
||||
// Required in order for there to be no padding between the fields.
|
||||
assert!(i8_align <= ptr_align);
|
||||
let catch_data = bx.alloca(2 * ptr_size, ptr_align);
|
||||
bx.store(ptr, catch_data, ptr_align);
|
||||
let catch_data_1 = bx.inbounds_ptradd(catch_data, bx.const_usize(ptr_size.bytes()));
|
||||
bx.store(is_rust_panic, catch_data_1, i8_align);
|
||||
|
||||
let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
|
||||
@ -1374,7 +1374,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
let ze = bx.zext(i_, bx.type_ix(expected_bytes * 8));
|
||||
|
||||
// Convert the integer to a byte array
|
||||
let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE);
|
||||
let ptr = bx.alloca(Size::from_bytes(expected_bytes), Align::ONE);
|
||||
bx.store(ze, ptr, Align::ONE);
|
||||
let array_ty = bx.type_array(bx.type_i8(), expected_bytes);
|
||||
return Ok(bx.load(array_ty, ptr, Align::ONE));
|
||||
|
@ -508,7 +508,7 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
let ptr_size = bx.tcx().data_layout.pointer_size;
|
||||
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
|
||||
let arg_argc = bx.const_int(cx.type_isize(), 2);
|
||||
let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), ptr_align);
|
||||
let arg_argv = bx.alloca(2 * ptr_size, ptr_align);
|
||||
bx.store(param_handle, arg_argv, ptr_align);
|
||||
let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes()));
|
||||
bx.store(param_system_table, arg_argv_el1, ptr_align);
|
||||
|
@ -1517,7 +1517,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
// when passed by value, making it larger.
|
||||
let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes());
|
||||
// Allocate some scratch space...
|
||||
let llscratch = bx.alloca(bx.cast_backend_type(cast), scratch_align);
|
||||
let llscratch = bx.alloca(scratch_size, scratch_align);
|
||||
bx.lifetime_start(llscratch, scratch_size);
|
||||
// ...memcpy the value...
|
||||
bx.memcpy(
|
||||
|
@ -327,7 +327,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
||||
let llfield_ty = bx.cx().backend_type(field);
|
||||
|
||||
// Can't bitcast an aggregate, so round trip through memory.
|
||||
let llptr = bx.alloca(llfield_ty, field.align.abi);
|
||||
let llptr = bx.alloca(field.size, field.align.abi);
|
||||
bx.store(*llval, llptr, field.align.abi);
|
||||
*llval = bx.load(llfield_ty, llptr, field.align.abi);
|
||||
}
|
||||
@ -470,7 +470,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
|
||||
let align_minus_1 = bx.sub(align, one);
|
||||
let size_extra = bx.add(size, align_minus_1);
|
||||
let min_align = Align::ONE;
|
||||
let alloca = bx.byte_array_alloca(size_extra, min_align);
|
||||
let alloca = bx.dynamic_alloca(size_extra, min_align);
|
||||
let address = bx.ptrtoint(alloca, bx.type_isize());
|
||||
let neg_address = bx.neg(address);
|
||||
let offset = bx.and(neg_address, align_minus_1);
|
||||
|
@ -81,7 +81,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
||||
align: Align,
|
||||
) -> Self {
|
||||
assert!(layout.is_sized(), "tried to statically allocate unsized place");
|
||||
let tmp = bx.alloca(bx.cx().backend_type(layout), align);
|
||||
let tmp = bx.alloca(layout.size, align);
|
||||
Self::new_sized_aligned(tmp, layout, align)
|
||||
}
|
||||
|
||||
|
@ -144,8 +144,8 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
}
|
||||
fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value;
|
||||
|
||||
fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
|
||||
fn byte_array_alloca(&mut self, len: Self::Value, align: Align) -> Self::Value;
|
||||
fn alloca(&mut self, size: Size, align: Align) -> Self::Value;
|
||||
fn dynamic_alloca(&mut self, size: Self::Value, align: Align) -> Self::Value;
|
||||
|
||||
fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value;
|
||||
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value;
|
||||
|
@ -4,10 +4,10 @@ yield point.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0626
|
||||
# #![feature(coroutines, coroutine_trait, pin)]
|
||||
# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
# use std::ops::Coroutine;
|
||||
# use std::pin::Pin;
|
||||
let mut b = || {
|
||||
let mut b = #[coroutine] || {
|
||||
let a = &String::new(); // <-- This borrow...
|
||||
yield (); // ...is still in scope here, when the yield occurs.
|
||||
println!("{}", a);
|
||||
@ -23,10 +23,10 @@ resolve the previous example by removing the borrow and just storing
|
||||
the integer by value:
|
||||
|
||||
```
|
||||
# #![feature(coroutines, coroutine_trait, pin)]
|
||||
# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
# use std::ops::Coroutine;
|
||||
# use std::pin::Pin;
|
||||
let mut b = || {
|
||||
let mut b = #[coroutine] || {
|
||||
let a = 3;
|
||||
yield ();
|
||||
println!("{}", a);
|
||||
@ -41,10 +41,10 @@ in those cases, something like the `Rc` or `Arc` types may be useful.
|
||||
This error also frequently arises with iteration:
|
||||
|
||||
```compile_fail,E0626
|
||||
# #![feature(coroutines, coroutine_trait, pin)]
|
||||
# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
# use std::ops::Coroutine;
|
||||
# use std::pin::Pin;
|
||||
let mut b = || {
|
||||
let mut b = #[coroutine] || {
|
||||
let v = vec![1,2,3];
|
||||
for &x in &v { // <-- borrow of `v` is still in scope...
|
||||
yield x; // ...when this yield occurs.
|
||||
@ -57,10 +57,10 @@ Such cases can sometimes be resolved by iterating "by value" (or using
|
||||
`into_iter()`) to avoid borrowing:
|
||||
|
||||
```
|
||||
# #![feature(coroutines, coroutine_trait, pin)]
|
||||
# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
# use std::ops::Coroutine;
|
||||
# use std::pin::Pin;
|
||||
let mut b = || {
|
||||
let mut b = #[coroutine] || {
|
||||
let v = vec![1,2,3];
|
||||
for x in v { // <-- Take ownership of the values instead!
|
||||
yield x; // <-- Now yield is OK.
|
||||
@ -72,10 +72,10 @@ Pin::new(&mut b).resume(());
|
||||
If taking ownership is not an option, using indices can work too:
|
||||
|
||||
```
|
||||
# #![feature(coroutines, coroutine_trait, pin)]
|
||||
# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
# use std::ops::Coroutine;
|
||||
# use std::pin::Pin;
|
||||
let mut b = || {
|
||||
let mut b = #[coroutine] || {
|
||||
let v = vec![1,2,3];
|
||||
let len = v.len(); // (*)
|
||||
for i in 0..len {
|
||||
|
@ -3,7 +3,7 @@ A yield expression was used outside of the coroutine literal.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0627
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
fn fake_coroutine() -> &'static str {
|
||||
yield 1;
|
||||
@ -19,10 +19,10 @@ The error occurs because keyword `yield` can only be used inside the coroutine
|
||||
literal. This can be fixed by constructing the coroutine correctly.
|
||||
|
||||
```
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let mut coroutine = || {
|
||||
let mut coroutine = #[coroutine] || {
|
||||
yield 1;
|
||||
return "foo"
|
||||
};
|
||||
|
@ -3,10 +3,10 @@ More than one parameter was used for a coroutine.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0628
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let coroutine = |a: i32, b: i32| {
|
||||
let coroutine = #[coroutine] |a: i32, b: i32| {
|
||||
// error: too many parameters for a coroutine
|
||||
// Allowed only 0 or 1 parameter
|
||||
yield a;
|
||||
@ -20,10 +20,10 @@ at most 1 parameter for the coroutine. For example, we might resolve
|
||||
the previous example by passing only one parameter.
|
||||
|
||||
```
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let coroutine = |a: i32| {
|
||||
let coroutine = #[coroutine] |a: i32| {
|
||||
yield a;
|
||||
};
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ A `yield` clause was used in an `async` context.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0727,edition2018
|
||||
#![feature(coroutines)]
|
||||
#![feature(coroutines, stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let coroutine = || {
|
||||
let coroutine = #[coroutine] || {
|
||||
async {
|
||||
yield;
|
||||
}
|
||||
@ -20,10 +20,10 @@ which is not yet supported.
|
||||
To fix this error, you have to move `yield` out of the `async` block:
|
||||
|
||||
```edition2018
|
||||
#![feature(coroutines)]
|
||||
#![feature(coroutines, stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let coroutine = || {
|
||||
let coroutine = #[coroutine] || {
|
||||
yield;
|
||||
};
|
||||
}
|
||||
|
@ -211,6 +211,8 @@ declare_features! (
|
||||
(accepted, inclusive_range_syntax, "1.26.0", Some(28237)),
|
||||
/// Allows inferring outlives requirements (RFC 2093).
|
||||
(accepted, infer_outlives_requirements, "1.30.0", Some(44493)),
|
||||
/// Allow anonymous constants from an inline `const` block
|
||||
(accepted, inline_const, "CURRENT_RUSTC_VERSION", Some(76001)),
|
||||
/// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
|
||||
(accepted, irrefutable_let_patterns, "1.33.0", Some(44495)),
|
||||
/// Allows `#[instruction_set(_)]` attribute.
|
||||
|
@ -534,6 +534,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
EncodeCrossCrate::Yes, experimental!(cfi_encoding)
|
||||
),
|
||||
|
||||
// `#[coroutine]` attribute to be applied to closures to make them coroutines instead
|
||||
gated!(
|
||||
coroutine, Normal, template!(Word), ErrorFollowing,
|
||||
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
|
||||
),
|
||||
|
||||
// ==========================================================================
|
||||
// Internal attributes: Stability, deprecation, and unsafe:
|
||||
// ==========================================================================
|
||||
|
@ -501,8 +501,6 @@ declare_features! (
|
||||
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
|
||||
/// Allows associated types in inherent impls.
|
||||
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
|
||||
/// Allow anonymous constants from an inline `const` block
|
||||
(unstable, inline_const, "1.49.0", Some(76001)),
|
||||
/// Allow anonymous constants from an inline `const` block in pattern position
|
||||
(unstable, inline_const_pat, "1.58.0", Some(76001)),
|
||||
/// Allows using `pointer` and `reference` in intra-doc links
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![feature(absolute_path)]
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
|
@ -1964,11 +1964,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
try_emit("recursive delegation");
|
||||
}
|
||||
|
||||
let sig = self.tcx().fn_sig(sig_id).instantiate_identity();
|
||||
if sig.output().has_opaque_types() {
|
||||
try_emit("delegation to a function with opaque type");
|
||||
}
|
||||
|
||||
let sig_generics = self.tcx().generics_of(sig_id);
|
||||
let parent = self.tcx().parent(self.item_def_id());
|
||||
let parent_generics = self.tcx().generics_of(parent);
|
||||
@ -1991,29 +1986,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
try_emit("delegation to a trait method from a free function");
|
||||
}
|
||||
|
||||
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
|
||||
try_emit("delegation to async functions");
|
||||
}
|
||||
|
||||
if self.tcx().constness(sig_id) == hir::Constness::Const {
|
||||
try_emit("delegation to const functions");
|
||||
}
|
||||
|
||||
if sig.c_variadic() {
|
||||
try_emit("delegation to variadic functions");
|
||||
// variadic functions are also `unsafe` and `extern "C"`.
|
||||
// Do not emit same error multiple times.
|
||||
return error_occured;
|
||||
}
|
||||
|
||||
if let hir::Unsafety::Unsafe = sig.unsafety() {
|
||||
try_emit("delegation to unsafe functions");
|
||||
}
|
||||
|
||||
if abi::Abi::Rust != sig.abi() {
|
||||
try_emit("delegation to non Rust ABI functions");
|
||||
}
|
||||
|
||||
error_occured
|
||||
}
|
||||
|
||||
|
@ -1139,7 +1139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// are the same function and their parameters have a LUB.
|
||||
match self.commit_if_ok(|_| {
|
||||
self.at(cause, self.param_env).lub(
|
||||
DefineOpaqueTypes::No,
|
||||
DefineOpaqueTypes::Yes,
|
||||
prev_ty,
|
||||
new_ty,
|
||||
)
|
||||
|
@ -1260,30 +1260,34 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
id: DefIndex,
|
||||
sess: &'a Session,
|
||||
) -> impl Iterator<Item = ModChild> + 'a {
|
||||
iter::from_coroutine(move || {
|
||||
if let Some(data) = &self.root.proc_macro_data {
|
||||
// If we are loading as a proc macro, we want to return
|
||||
// the view of this crate as a proc macro crate.
|
||||
if id == CRATE_DEF_INDEX {
|
||||
for child_index in data.macros.decode(self) {
|
||||
iter::from_coroutine(
|
||||
#[cfg_attr(not(bootstrap), coroutine)]
|
||||
move || {
|
||||
if let Some(data) = &self.root.proc_macro_data {
|
||||
// If we are loading as a proc macro, we want to return
|
||||
// the view of this crate as a proc macro crate.
|
||||
if id == CRATE_DEF_INDEX {
|
||||
for child_index in data.macros.decode(self) {
|
||||
yield self.get_mod_child(child_index, sess);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Iterate over all children.
|
||||
let non_reexports =
|
||||
self.root.tables.module_children_non_reexports.get(self, id);
|
||||
for child_index in non_reexports.unwrap().decode(self) {
|
||||
yield self.get_mod_child(child_index, sess);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Iterate over all children.
|
||||
let non_reexports = self.root.tables.module_children_non_reexports.get(self, id);
|
||||
for child_index in non_reexports.unwrap().decode(self) {
|
||||
yield self.get_mod_child(child_index, sess);
|
||||
}
|
||||
|
||||
let reexports = self.root.tables.module_children_reexports.get(self, id);
|
||||
if !reexports.is_default() {
|
||||
for reexport in reexports.decode((self, sess)) {
|
||||
yield reexport;
|
||||
let reexports = self.root.tables.module_children_reexports.get(self, id);
|
||||
if !reexports.is_default() {
|
||||
for reexport in reexports.decode((self, sess)) {
|
||||
yield reexport;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn is_ctfe_mir_available(self, id: DefIndex) -> bool {
|
||||
|
@ -35,8 +35,9 @@
|
||||
#![feature(const_type_name)]
|
||||
#![feature(discriminant_kind)]
|
||||
#![feature(coroutines)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(inline_const)]
|
||||
#![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#![feature(iter_from_coroutine)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
|
@ -422,49 +422,53 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>(
|
||||
child_captures: impl IntoIterator<Item = &'a CapturedPlace<'tcx>>,
|
||||
mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T,
|
||||
) -> impl Iterator<Item = T> + Captures<'a> + Captures<'tcx> {
|
||||
std::iter::from_coroutine(move || {
|
||||
let mut child_captures = child_captures.into_iter().enumerate().peekable();
|
||||
std::iter::from_coroutine(
|
||||
#[cfg_attr(not(bootstrap), coroutine)]
|
||||
move || {
|
||||
let mut child_captures = child_captures.into_iter().enumerate().peekable();
|
||||
|
||||
// One parent capture may correspond to several child captures if we end up
|
||||
// refining the set of captures via edition-2021 precise captures. We want to
|
||||
// match up any number of child captures with one parent capture, so we keep
|
||||
// peeking off this `Peekable` until the child doesn't match anymore.
|
||||
for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() {
|
||||
// Make sure we use every field at least once, b/c why are we capturing something
|
||||
// if it's not used in the inner coroutine.
|
||||
let mut field_used_at_least_once = false;
|
||||
// One parent capture may correspond to several child captures if we end up
|
||||
// refining the set of captures via edition-2021 precise captures. We want to
|
||||
// match up any number of child captures with one parent capture, so we keep
|
||||
// peeking off this `Peekable` until the child doesn't match anymore.
|
||||
for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() {
|
||||
// Make sure we use every field at least once, b/c why are we capturing something
|
||||
// if it's not used in the inner coroutine.
|
||||
let mut field_used_at_least_once = false;
|
||||
|
||||
// A parent matches a child if they share the same prefix of projections.
|
||||
// The child may have more, if it is capturing sub-fields out of
|
||||
// something that is captured by-move in the parent closure.
|
||||
while child_captures.peek().map_or(false, |(_, child_capture)| {
|
||||
child_prefix_matches_parent_projections(parent_capture, child_capture)
|
||||
}) {
|
||||
let (child_field_idx, child_capture) = child_captures.next().unwrap();
|
||||
// This analysis only makes sense if the parent capture is a
|
||||
// prefix of the child capture.
|
||||
assert!(
|
||||
child_capture.place.projections.len() >= parent_capture.place.projections.len(),
|
||||
"parent capture ({parent_capture:#?}) expected to be prefix of \
|
||||
// A parent matches a child if they share the same prefix of projections.
|
||||
// The child may have more, if it is capturing sub-fields out of
|
||||
// something that is captured by-move in the parent closure.
|
||||
while child_captures.peek().map_or(false, |(_, child_capture)| {
|
||||
child_prefix_matches_parent_projections(parent_capture, child_capture)
|
||||
}) {
|
||||
let (child_field_idx, child_capture) = child_captures.next().unwrap();
|
||||
// This analysis only makes sense if the parent capture is a
|
||||
// prefix of the child capture.
|
||||
assert!(
|
||||
child_capture.place.projections.len()
|
||||
>= parent_capture.place.projections.len(),
|
||||
"parent capture ({parent_capture:#?}) expected to be prefix of \
|
||||
child capture ({child_capture:#?})"
|
||||
);
|
||||
);
|
||||
|
||||
yield for_each(
|
||||
(parent_field_idx, parent_capture),
|
||||
(child_field_idx, child_capture),
|
||||
);
|
||||
yield for_each(
|
||||
(parent_field_idx, parent_capture),
|
||||
(child_field_idx, child_capture),
|
||||
);
|
||||
|
||||
field_used_at_least_once = true;
|
||||
field_used_at_least_once = true;
|
||||
}
|
||||
|
||||
// Make sure the field was used at least once.
|
||||
assert!(
|
||||
field_used_at_least_once,
|
||||
"we captured {parent_capture:#?} but it was not used in the child coroutine?"
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure the field was used at least once.
|
||||
assert!(
|
||||
field_used_at_least_once,
|
||||
"we captured {parent_capture:#?} but it was not used in the child coroutine?"
|
||||
);
|
||||
}
|
||||
assert_eq!(child_captures.next(), None, "leftover child captures?");
|
||||
})
|
||||
assert_eq!(child_captures.next(), None, "leftover child captures?");
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn child_prefix_matches_parent_projections(
|
||||
|
@ -1284,20 +1284,23 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
|
||||
|
||||
let definitions = &self.untracked.definitions;
|
||||
std::iter::from_coroutine(|| {
|
||||
let mut i = 0;
|
||||
std::iter::from_coroutine(
|
||||
#[cfg_attr(not(bootstrap), coroutine)]
|
||||
|| {
|
||||
let mut i = 0;
|
||||
|
||||
// Recompute the number of definitions each time, because our caller may be creating
|
||||
// new ones.
|
||||
while i < { definitions.read().num_definitions() } {
|
||||
let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
|
||||
yield LocalDefId { local_def_index };
|
||||
i += 1;
|
||||
}
|
||||
// Recompute the number of definitions each time, because our caller may be creating
|
||||
// new ones.
|
||||
while i < { definitions.read().num_definitions() } {
|
||||
let local_def_index = rustc_span::def_id::DefIndex::from_usize(i);
|
||||
yield LocalDefId { local_def_index };
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// Freeze definitions once we finish iterating on them, to prevent adding new ones.
|
||||
definitions.freeze();
|
||||
})
|
||||
// Freeze definitions once we finish iterating on them, to prevent adding new ones.
|
||||
definitions.freeze();
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
|
||||
|
@ -45,7 +45,7 @@ use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
@ -224,8 +224,15 @@ pub struct ResolverAstLowering {
|
||||
pub lint_buffer: Steal<LintBuffer>,
|
||||
|
||||
/// Information about functions signatures for delegation items expansion
|
||||
pub has_self: LocalDefIdSet,
|
||||
pub fn_parameter_counts: LocalDefIdMap<usize>,
|
||||
pub delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DelegationFnSig {
|
||||
pub header: ast::FnHeader,
|
||||
pub param_count: usize,
|
||||
pub has_self: bool,
|
||||
pub c_variadic: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -4,7 +4,7 @@
|
||||
#![feature(cow_is_borrowed)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![feature(inline_const)]
|
||||
#![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#![feature(is_sorted)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(map_try_insert)]
|
||||
|
@ -686,6 +686,8 @@ impl<'a> Parser<'a> {
|
||||
(None, self.parse_path(PathStyle::Expr)?)
|
||||
};
|
||||
|
||||
let rename = if self.eat_keyword(kw::As) { Some(self.parse_ident()?) } else { None };
|
||||
|
||||
let body = if self.check(&token::OpenDelim(Delimiter::Brace)) {
|
||||
Some(self.parse_block()?)
|
||||
} else {
|
||||
@ -695,11 +697,9 @@ impl<'a> Parser<'a> {
|
||||
let span = span.to(self.prev_token.span);
|
||||
self.psess.gated_spans.gate(sym::fn_delegation, span);
|
||||
|
||||
let ident = path.segments.last().map(|seg| seg.ident).unwrap_or(Ident::empty());
|
||||
Ok((
|
||||
ident,
|
||||
ItemKind::Delegation(Box::new(Delegation { id: DUMMY_NODE_ID, qself, path, body })),
|
||||
))
|
||||
let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
|
||||
let deleg = Delegation { id: DUMMY_NODE_ID, qself, path, rename, body };
|
||||
Ok((ident, ItemKind::Delegation(Box::new(deleg))))
|
||||
}
|
||||
|
||||
fn parse_item_list<T>(
|
||||
|
@ -1252,8 +1252,6 @@ impl<'a> Parser<'a> {
|
||||
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
|
||||
if pat {
|
||||
self.psess.gated_spans.gate(sym::inline_const_pat, span);
|
||||
} else {
|
||||
self.psess.gated_spans.gate(sym::inline_const, span);
|
||||
}
|
||||
self.eat_keyword(kw::Const);
|
||||
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
|
||||
|
@ -21,6 +21,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, Par
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate};
|
||||
use rustc_middle::middle::resolve_bound_vars::Set1;
|
||||
use rustc_middle::ty::DelegationFnSig;
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::config::{CrateType, ResolveDocLinks};
|
||||
use rustc_session::lint;
|
||||
@ -4749,12 +4750,13 @@ struct ItemInfoCollector<'a, 'b, 'tcx> {
|
||||
|
||||
impl ItemInfoCollector<'_, '_, '_> {
|
||||
fn collect_fn_info(&mut self, sig: &FnSig, id: NodeId) {
|
||||
let def_id = self.r.local_def_id(id);
|
||||
self.r.fn_parameter_counts.insert(def_id, sig.decl.inputs.len());
|
||||
|
||||
if sig.decl.has_self() {
|
||||
self.r.has_self.insert(def_id);
|
||||
}
|
||||
let sig = DelegationFnSig {
|
||||
header: sig.header,
|
||||
param_count: sig.decl.inputs.len(),
|
||||
has_self: sig.decl.has_self(),
|
||||
c_variadic: sig.decl.c_variadic(),
|
||||
};
|
||||
self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2039,7 +2039,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
ast::AssocItemKind::Fn(..) => AssocSuggestion::AssocFn { called },
|
||||
ast::AssocItemKind::Type(..) => AssocSuggestion::AssocType,
|
||||
ast::AssocItemKind::Delegation(..)
|
||||
if self.r.has_self.contains(&self.r.local_def_id(assoc_item.id)) =>
|
||||
if self.r.delegation_fn_sigs[&self.r.local_def_id(assoc_item.id)]
|
||||
.has_self =>
|
||||
{
|
||||
AssocSuggestion::MethodWithSelf { called }
|
||||
}
|
||||
@ -2062,7 +2063,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
if filter_fn(res) {
|
||||
let def_id = res.def_id();
|
||||
let has_self = match def_id.as_local() {
|
||||
Some(def_id) => self.r.has_self.contains(&def_id),
|
||||
Some(def_id) => {
|
||||
self.r.delegation_fn_sigs.get(&def_id).map_or(false, |sig| sig.has_self)
|
||||
}
|
||||
None => self
|
||||
.r
|
||||
.tcx
|
||||
|
@ -43,7 +43,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES;
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::NonMacroAttrKind;
|
||||
use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::{PrimTy, TraitCandidate};
|
||||
use rustc_index::IndexVec;
|
||||
@ -52,8 +52,8 @@ use rustc_middle::metadata::ModChild;
|
||||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt, TyCtxtFeed};
|
||||
use rustc_middle::ty::{Feed, ResolverGlobalCtxt, ResolverOutputs};
|
||||
use rustc_middle::ty::{self, DelegationFnSig, Feed, MainDefinition, RegisteredTools};
|
||||
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs, TyCtxt, TyCtxtFeed};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
|
||||
use rustc_session::lint::LintBuffer;
|
||||
@ -992,7 +992,6 @@ pub struct Resolver<'a, 'tcx> {
|
||||
extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
|
||||
|
||||
/// N.B., this is used only for better diagnostics, not name resolution itself.
|
||||
has_self: LocalDefIdSet,
|
||||
field_def_ids: LocalDefIdMap<&'tcx [DefId]>,
|
||||
|
||||
/// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax.
|
||||
@ -1149,8 +1148,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
|
||||
/// Amount of lifetime parameters for each item in the crate.
|
||||
item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
|
||||
/// Amount of parameters for each function in the crate.
|
||||
fn_parameter_counts: LocalDefIdMap<usize>,
|
||||
delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
|
||||
|
||||
main_def: Option<MainDefinition>,
|
||||
trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
|
||||
@ -1399,7 +1397,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
prelude: None,
|
||||
extern_prelude,
|
||||
|
||||
has_self: Default::default(),
|
||||
field_def_ids: Default::default(),
|
||||
field_visibility_spans: FxHashMap::default(),
|
||||
|
||||
@ -1508,7 +1505,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
doc_link_resolutions: Default::default(),
|
||||
doc_link_traits_in_scope: Default::default(),
|
||||
all_macro_rules: Default::default(),
|
||||
fn_parameter_counts: Default::default(),
|
||||
delegation_fn_sigs: Default::default(),
|
||||
};
|
||||
|
||||
let root_parent_scope = ParentScope::module(graph_root, &resolver);
|
||||
@ -1621,8 +1618,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
trait_map: self.trait_map,
|
||||
lifetime_elision_allowed: self.lifetime_elision_allowed,
|
||||
lint_buffer: Steal::new(self.lint_buffer),
|
||||
has_self: self.has_self,
|
||||
fn_parameter_counts: self.fn_parameter_counts,
|
||||
delegation_fn_sigs: self.delegation_fn_sigs,
|
||||
};
|
||||
ResolverOutputs { global_ctxt, ast_lowering }
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
|
||||
#![feature(const_option)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(inline_const)]
|
||||
#![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![feature(ptr_sub_ptr)]
|
||||
|
@ -1888,9 +1888,12 @@ fn collect_print_requests(
|
||||
let prints =
|
||||
PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
|
||||
let prints = prints.join(", ");
|
||||
early_dcx.early_fatal(format!(
|
||||
"unknown print request `{req}`. Valid print requests are: {prints}"
|
||||
));
|
||||
|
||||
let mut diag =
|
||||
early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
diag.help(format!("valid print requests are: {prints}"));
|
||||
diag.emit()
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -192,6 +192,7 @@ symbols! {
|
||||
Duration,
|
||||
Encodable,
|
||||
Encoder,
|
||||
Enumerate,
|
||||
Eq,
|
||||
Equal,
|
||||
Err,
|
||||
|
@ -50,22 +50,38 @@ pub struct FindExprBySpan<'hir> {
|
||||
pub span: Span,
|
||||
pub result: Option<&'hir hir::Expr<'hir>>,
|
||||
pub ty_result: Option<&'hir hir::Ty<'hir>>,
|
||||
pub include_closures: bool,
|
||||
pub tcx: TyCtxt<'hir>,
|
||||
}
|
||||
|
||||
impl<'hir> FindExprBySpan<'hir> {
|
||||
pub fn new(span: Span) -> Self {
|
||||
Self { span, result: None, ty_result: None }
|
||||
pub fn new(span: Span, tcx: TyCtxt<'hir>) -> Self {
|
||||
Self { span, result: None, ty_result: None, tcx, include_closures: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> Visitor<'v> for FindExprBySpan<'v> {
|
||||
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||
if self.span == ex.span {
|
||||
self.result = Some(ex);
|
||||
} else {
|
||||
if let hir::ExprKind::Closure(..) = ex.kind
|
||||
&& self.include_closures
|
||||
&& let closure_header_sp = self.span.with_hi(ex.span.hi())
|
||||
&& closure_header_sp == ex.span
|
||||
{
|
||||
self.result = Some(ex);
|
||||
}
|
||||
hir::intravisit::walk_expr(self, ex);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
|
||||
if self.span == ty.span {
|
||||
self.ty_result = Some(ty);
|
||||
|
@ -901,7 +901,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
// Remove all the desugaring and macro contexts.
|
||||
span.remove_mark();
|
||||
}
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
|
||||
return;
|
||||
};
|
||||
@ -1367,7 +1367,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
return false;
|
||||
};
|
||||
let body = self.tcx.hir().body(body_id);
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
expr_finder.visit_expr(body.value);
|
||||
let Some(expr) = expr_finder.result else {
|
||||
return false;
|
||||
@ -1469,7 +1469,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
// Remove all the hir desugaring contexts while maintaining the macro contexts.
|
||||
span.remove_mark();
|
||||
}
|
||||
let mut expr_finder = super::FindExprBySpan::new(span);
|
||||
let mut expr_finder = super::FindExprBySpan::new(span, self.tcx);
|
||||
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
|
||||
return false;
|
||||
};
|
||||
|
@ -2457,7 +2457,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
&& let Some(body_id) =
|
||||
self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
|
||||
{
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
expr_finder.visit_expr(self.tcx.hir().body(body_id).value);
|
||||
|
||||
if let Some(hir::Expr {
|
||||
|
@ -183,7 +183,7 @@ pub enum TyKind<I: Interner> {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(coroutines)]
|
||||
/// static |a| {
|
||||
/// #[coroutine] static |a| {
|
||||
/// let x = &vec![3];
|
||||
/// yield a;
|
||||
/// yield x[0];
|
||||
|
@ -31,7 +31,7 @@
|
||||
//! // instead of a max-heap.
|
||||
//! impl Ord for State {
|
||||
//! fn cmp(&self, other: &Self) -> Ordering {
|
||||
//! // Notice that the we flip the ordering on costs.
|
||||
//! // Notice that we flip the ordering on costs.
|
||||
//! // In case of a tie we compare positions - this step is necessary
|
||||
//! // to make implementations of `PartialEq` and `Ord` consistent.
|
||||
//! other.cost.cmp(&self.cost)
|
||||
|
@ -128,7 +128,6 @@
|
||||
#![feature(fn_traits)]
|
||||
#![feature(hasher_prefixfree_extras)]
|
||||
#![feature(hint_assert_unchecked)]
|
||||
#![feature(inline_const)]
|
||||
#![feature(inplace_iteration)]
|
||||
#![feature(iter_advance_by)]
|
||||
#![feature(iter_next_chunk)]
|
||||
@ -169,6 +168,7 @@
|
||||
// Language features:
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
|
||||
#![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
|
||||
#![cfg_attr(not(test), feature(coroutine_trait))]
|
||||
#![cfg_attr(test, feature(panic_update_hook))]
|
||||
|
@ -15,6 +15,7 @@ use crate::ops::Try;
|
||||
#[derive(Clone, Debug)]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "Enumerate")]
|
||||
pub struct Enumerate<I> {
|
||||
iter: I,
|
||||
count: usize,
|
||||
|
@ -14,7 +14,7 @@ use crate::pin::Pin;
|
||||
/// #![feature(coroutines)]
|
||||
/// #![feature(iter_from_coroutine)]
|
||||
///
|
||||
/// let it = std::iter::from_coroutine(|| {
|
||||
/// let it = std::iter::from_coroutine(#[cfg_attr(not(bootstrap), coroutine)] || {
|
||||
/// yield 1;
|
||||
/// yield 2;
|
||||
/// yield 3;
|
||||
|
@ -201,6 +201,7 @@
|
||||
//
|
||||
// Language features:
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#![feature(abi_unadjusted)]
|
||||
#![feature(adt_const_params)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
@ -231,7 +232,6 @@
|
||||
#![feature(fundamental)]
|
||||
#![feature(generic_arg_infer)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(inline_const)]
|
||||
#![feature(intra_doc_pointers)]
|
||||
#![feature(intrinsics)]
|
||||
#![feature(lang_items)]
|
||||
|
@ -40,12 +40,13 @@ pub enum CoroutineState<Y, R> {
|
||||
/// ```rust
|
||||
/// #![feature(coroutines)]
|
||||
/// #![feature(coroutine_trait)]
|
||||
/// #![feature(stmt_expr_attributes)]
|
||||
///
|
||||
/// use std::ops::{Coroutine, CoroutineState};
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut coroutine = || {
|
||||
/// let mut coroutine = #[cfg_attr(not(bootstrap), coroutine)] || {
|
||||
/// yield 1;
|
||||
/// "foo"
|
||||
/// };
|
||||
|
@ -1809,7 +1809,7 @@ impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> where Ptr: DispatchFromDyn<U>
|
||||
/// fn coroutine_fn() -> impl Coroutine<Yield = usize, Return = ()> /* not Unpin */ {
|
||||
/// // Allow coroutine to be self-referential (not `Unpin`)
|
||||
/// // vvvvvv so that locals can cross yield points.
|
||||
/// static || {
|
||||
/// #[cfg_attr(not(bootstrap), coroutine)] static || {
|
||||
/// let foo = String::from("foo");
|
||||
/// let foo_ref = &foo; // ------+
|
||||
/// yield 0; // | <- crosses yield point!
|
||||
|
@ -511,7 +511,8 @@ impl AtomicBool {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(atomic_from_mut, inline_const)]
|
||||
/// #![feature(atomic_from_mut)]
|
||||
/// # #![cfg_attr(bootstrap, feature(inline_const))]
|
||||
/// use std::sync::atomic::{AtomicBool, Ordering};
|
||||
///
|
||||
/// let mut some_bools = [const { AtomicBool::new(false) }; 10];
|
||||
@ -1313,7 +1314,8 @@ impl<T> AtomicPtr<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(atomic_from_mut, inline_const)]
|
||||
/// #![feature(atomic_from_mut)]
|
||||
/// # #![cfg_attr(bootstrap, feature(inline_const))]
|
||||
/// use std::ptr::null_mut;
|
||||
/// use std::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
@ -2303,7 +2305,8 @@ macro_rules! atomic_int {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(atomic_from_mut, inline_const)]
|
||||
/// #![feature(atomic_from_mut)]
|
||||
/// # #![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
|
||||
///
|
||||
#[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
|
||||
|
@ -46,7 +46,7 @@
|
||||
#![feature(hasher_prefixfree_extras)]
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(try_find)]
|
||||
#![feature(inline_const)]
|
||||
#![cfg_attr(bootstrap, feature(inline_const))]
|
||||
#![feature(is_sorted)]
|
||||
#![feature(layout_for_ptr)]
|
||||
#![feature(pattern)]
|
||||
|
@ -7,7 +7,6 @@
|
||||
convert_float_to_int,
|
||||
core_intrinsics,
|
||||
decl_macro,
|
||||
inline_const,
|
||||
intra_doc_pointers,
|
||||
repr_simd,
|
||||
simd_ffi,
|
||||
|
@ -3332,7 +3332,6 @@ impl Error for StripPrefixError {
|
||||
/// ## Posix paths
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(absolute_path)]
|
||||
/// # #[cfg(unix)]
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
/// use std::path::{self, Path};
|
||||
@ -3357,7 +3356,6 @@ impl Error for StripPrefixError {
|
||||
/// ## Windows paths
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(absolute_path)]
|
||||
/// # #[cfg(windows)]
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
/// use std::path::{self, Path};
|
||||
@ -3382,7 +3380,7 @@ impl Error for StripPrefixError {
|
||||
///
|
||||
/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
||||
/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
|
||||
#[unstable(feature = "absolute_path", issue = "92750")]
|
||||
#[stable(feature = "absolute_path", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
if path.as_os_str().is_empty() {
|
||||
|
@ -201,14 +201,21 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
|
||||
// currently reside in the buffer. This function is an abstraction over these
|
||||
// functions by making them easier to call.
|
||||
//
|
||||
// The first callback, `f1`, is yielded a (pointer, len) pair which can be
|
||||
// The first callback, `f1`, is passed a (pointer, len) pair which can be
|
||||
// passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
|
||||
// The closure is expected to return what the syscall returns which will be
|
||||
// interpreted by this function to determine if the syscall needs to be invoked
|
||||
// again (with more buffer space).
|
||||
// The closure is expected to:
|
||||
// - On success, return the actual length of the written data *without* the null terminator.
|
||||
// This can be 0. In this case the last_error must be left unchanged.
|
||||
// - On insufficient buffer space,
|
||||
// - either return the required length *with* the null terminator,
|
||||
// - or set the last-error to ERROR_INSUFFICIENT_BUFFER and return `len`.
|
||||
// - On other failure, return 0 and set last_error.
|
||||
//
|
||||
// This is how most but not all syscalls indicate the required buffer space.
|
||||
// Other syscalls may need translation to match this protocol.
|
||||
//
|
||||
// Once the syscall has completed (errors bail out early) the second closure is
|
||||
// yielded the data which has been read from the syscall. The return value
|
||||
// passed the data which has been read from the syscall. The return value
|
||||
// from this closure is then the return value of the function.
|
||||
pub fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
|
||||
where
|
||||
|
@ -326,6 +326,8 @@ fn home_dir_crt() -> Option<PathBuf> {
|
||||
|
||||
super::fill_utf16_buf(
|
||||
|buf, mut sz| {
|
||||
// GetUserProfileDirectoryW does not quite use the usual protocol for
|
||||
// negotiating the buffer size, so we have to translate.
|
||||
match c::GetUserProfileDirectoryW(
|
||||
ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN),
|
||||
buf,
|
||||
|
@ -141,9 +141,15 @@ impl StaticKey {
|
||||
panic!("out of TLS indexes");
|
||||
}
|
||||
|
||||
self.key.store(key + 1, Release);
|
||||
register_dtor(self);
|
||||
|
||||
// Release-storing the key needs to be the last thing we do.
|
||||
// This is because in `fn key()`, other threads will do an acquire load of the key,
|
||||
// and if that sees this write then it will entirely bypass the `InitOnce`. We thus
|
||||
// need to establish synchronization through `key`. In particular that acquire load
|
||||
// must happen-after the register_dtor above, to ensure the dtor actually runs!
|
||||
self.key.store(key + 1, Release);
|
||||
|
||||
let r = c::InitOnceComplete(self.once.get(), 0, ptr::null_mut());
|
||||
debug_assert_eq!(r, c::TRUE);
|
||||
|
||||
@ -313,8 +319,22 @@ unsafe fn run_dtors() {
|
||||
// Use acquire ordering to observe key initialization.
|
||||
let mut cur = DTORS.load(Acquire);
|
||||
while !cur.is_null() {
|
||||
let key = (*cur).key.load(Relaxed) - 1;
|
||||
let pre_key = (*cur).key.load(Acquire);
|
||||
let dtor = (*cur).dtor.unwrap();
|
||||
cur = (*cur).next.load(Relaxed);
|
||||
|
||||
// In StaticKey::init, we register the dtor before setting `key`.
|
||||
// So if one thread's `run_dtors` races with another thread executing `init` on the same
|
||||
// `StaticKey`, we can encounter a key of 0 here. That means this key was never
|
||||
// initialized in this thread so we can safely skip it.
|
||||
if pre_key == 0 {
|
||||
continue;
|
||||
}
|
||||
// If this is non-zero, then via the `Acquire` load above we synchronized with
|
||||
// everything relevant for this key. (It's not clear that this is needed, since the
|
||||
// release-acquire pair on DTORS also establishes synchronization, but better safe than
|
||||
// sorry.)
|
||||
let key = pre_key - 1;
|
||||
|
||||
let ptr = c::TlsGetValue(key);
|
||||
if !ptr.is_null() {
|
||||
@ -322,8 +342,6 @@ unsafe fn run_dtors() {
|
||||
dtor(ptr as *mut _);
|
||||
any_run = true;
|
||||
}
|
||||
|
||||
cur = (*cur).next.load(Relaxed);
|
||||
}
|
||||
|
||||
if !any_run {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
set -euf -o pipefail
|
||||
|
||||
INTEGRATION_SHA=56310bca298872ffb5ea02e665956d9b6dc41171
|
||||
INTEGRATION_SHA=1011e3298775ee7cdf6f6dc73e808d6a86e33bd6
|
||||
PICK_REFS=()
|
||||
|
||||
checkout=fuchsia
|
||||
|
@ -4,13 +4,13 @@ set -ex
|
||||
source shared.sh
|
||||
|
||||
FUCHSIA_SDK_URL=https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64
|
||||
FUCHSIA_SDK_ID=MrhQwtmP8CpZre-i_PNOREcThbUcrX3bA-45d6WQr-cC
|
||||
FUCHSIA_SDK_SHA256=32b850c2d98ff02a59adefa2fcf34e44471385b51cad7ddb03ee3977a590afe7
|
||||
FUCHSIA_SDK_ID=version:20.20240412.3.1
|
||||
FUCHSIA_SDK_SHA256=cc52f3497487dd813c89d9316e6967efcea89c7759edccf3e40fcf3662e53f19
|
||||
FUCHSIA_SDK_USR_DIR=/usr/local/core-linux-amd64-fuchsia-sdk
|
||||
CLANG_DOWNLOAD_URL=\
|
||||
https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64
|
||||
CLANG_DOWNLOAD_ID=Tpc85d1ZwSlZ6UKl2d96GRUBGNA5JKholOKe24sRDr0C
|
||||
CLANG_DOWNLOAD_SHA256=4e973ce5dd59c12959e942a5d9df7a19150118d03924a86894e29edb8b110ebd
|
||||
CLANG_DOWNLOAD_ID=git_revision:c777c011a709dffd4fa5e79cad7947b7c3405d02
|
||||
CLANG_DOWNLOAD_SHA256=779167422ad73c292f049dcea5569f84577af9292189ed2749518b966a4d0844
|
||||
|
||||
install_clang() {
|
||||
mkdir -p clang_download
|
||||
|
@ -280,7 +280,7 @@ class TestEnvironment:
|
||||
# Look up the product bundle transfer manifest.
|
||||
self.log_info("Looking up the product bundle transfer manifest...")
|
||||
product_name = "minimal." + self.triple_to_arch(self.target)
|
||||
fuchsia_version = "14.20230811.2.1"
|
||||
fuchsia_version = "20.20240412.3.1"
|
||||
|
||||
# FIXME: We should be able to replace this with the machine parsable
|
||||
# `ffx --machine json product lookup ...` once F15 is released.
|
||||
|
115
src/ci/github-actions/calculate-job-matrix.py
Executable file
115
src/ci/github-actions/calculate-job-matrix.py
Executable file
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This script serves for generating a matrix of jobs that should
|
||||
be executed on CI.
|
||||
|
||||
It reads job definitions from `src/ci/github-actions/jobs.yml`
|
||||
and filters them based on the event that happened on CI.
|
||||
"""
|
||||
import dataclasses
|
||||
import enum
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Any, Optional
|
||||
|
||||
import yaml
|
||||
|
||||
JOBS_YAML_PATH = Path(__file__).absolute().parent / "jobs.yml"
|
||||
|
||||
|
||||
def name_jobs(jobs: List[Dict], prefix: str) -> List[Dict]:
|
||||
"""
|
||||
Add a `name` attribute to each job, based on its image and the given `prefix`.
|
||||
"""
|
||||
for job in jobs:
|
||||
job["name"] = f"{prefix} - {job['image']}"
|
||||
return jobs
|
||||
|
||||
|
||||
def add_base_env(jobs: List[Dict], environment: Dict[str, str]) -> List[Dict]:
|
||||
"""
|
||||
Prepends `environment` to the `env` attribute of each job.
|
||||
The `env` of each job has higher precedence than `environment`.
|
||||
"""
|
||||
for job in jobs:
|
||||
env = environment.copy()
|
||||
env.update(job.get("env", {}))
|
||||
job["env"] = env
|
||||
return jobs
|
||||
|
||||
|
||||
class JobType(enum.Enum):
|
||||
PR = enum.auto()
|
||||
Try = enum.auto()
|
||||
Auto = enum.auto()
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class GitHubCtx:
|
||||
event_name: str
|
||||
ref: str
|
||||
repository: str
|
||||
|
||||
|
||||
def find_job_type(ctx: GitHubCtx) -> Optional[JobType]:
|
||||
if ctx.event_name == "pull_request":
|
||||
return JobType.PR
|
||||
elif ctx.event_name == "push":
|
||||
old_bors_try_build = (
|
||||
ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and
|
||||
ctx.repository == "rust-lang-ci/rust"
|
||||
)
|
||||
new_bors_try_build = (
|
||||
ctx.ref == "refs/heads/automation/bors/try" and
|
||||
ctx.repository == "rust-lang/rust"
|
||||
)
|
||||
try_build = old_bors_try_build or new_bors_try_build
|
||||
|
||||
if try_build:
|
||||
return JobType.Try
|
||||
|
||||
if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust":
|
||||
return JobType.Auto
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
if job_type == JobType.PR:
|
||||
return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"])
|
||||
elif job_type == JobType.Try:
|
||||
return add_base_env(name_jobs(job_data["try"], "try"), job_data["envs"]["try"])
|
||||
elif job_type == JobType.Auto:
|
||||
return add_base_env(name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"])
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def get_github_ctx() -> GitHubCtx:
|
||||
return GitHubCtx(
|
||||
event_name=os.environ["GITHUB_EVENT_NAME"],
|
||||
ref=os.environ["GITHUB_REF"],
|
||||
repository=os.environ["GITHUB_REPOSITORY"]
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
with open(JOBS_YAML_PATH) as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
github_ctx = get_github_ctx()
|
||||
|
||||
job_type = find_job_type(github_ctx)
|
||||
logging.info(f"Job type: {job_type}")
|
||||
|
||||
jobs = []
|
||||
if job_type is not None:
|
||||
jobs = calculate_jobs(job_type, data)
|
||||
|
||||
logging.info(f"Output:\n{yaml.dump(jobs, indent=4)}")
|
||||
print(f"jobs={json.dumps(jobs)}")
|
@ -342,6 +342,8 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
# The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml.
|
||||
# It calculates which jobs should be executed, based on the data of the ${{ github }} context.
|
||||
# If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml.
|
||||
calculate_matrix:
|
||||
name: Calculate job matrix
|
||||
runs-on: ubuntu-latest
|
||||
@ -351,422 +353,34 @@ jobs:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
- name: Calculate the CI job matrix
|
||||
run: python3 src/ci/scripts/calculate-job-matrix.py >> $GITHUB_OUTPUT
|
||||
run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT
|
||||
id: jobs
|
||||
pr:
|
||||
job:
|
||||
<<: *base-ci-job
|
||||
name: PR - ${{ matrix.name }}
|
||||
name: ${{ matrix.name }}
|
||||
needs: [ calculate_matrix ]
|
||||
env:
|
||||
<<: [*shared-ci-variables, *public-variables]
|
||||
PR_CI_JOB: 1
|
||||
if: github.event_name == 'pull_request'
|
||||
continue-on-error: ${{ matrix.name == 'mingw-check-tidy' }}
|
||||
CI_JOB_NAME: ${{ matrix.image }}
|
||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||
# commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SCCACHE_BUCKET: rust-lang-ci-sccache2
|
||||
TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate
|
||||
CACHE_DOMAIN: ci-caches.rust-lang.org
|
||||
continue-on-error: ${{ matrix.continue_on_error || false }}
|
||||
strategy:
|
||||
matrix:
|
||||
# Check the `calculate_matrix` job to see how is the matrix defined.
|
||||
include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}
|
||||
|
||||
auto:
|
||||
<<: *base-ci-job
|
||||
name: auto - ${{ matrix.name }}
|
||||
env:
|
||||
<<: [*shared-ci-variables, *prod-variables]
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
#############################
|
||||
# Linux/Docker builders #
|
||||
#############################
|
||||
|
||||
- name: aarch64-gnu
|
||||
<<: *job-aarch64-linux
|
||||
|
||||
- name: arm-android
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: armhf-gnu
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-aarch64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-android
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-arm-linux
|
||||
<<: *job-linux-16c
|
||||
|
||||
- name: dist-armhf-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-armv7-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-i586-gnu-i586-i686-musl
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-i686-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-loongarch64-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-ohos
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-powerpc-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-powerpc64-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-powerpc64le-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-riscv64-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-s390x-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-various-1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-various-2
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-x86_64-freebsd
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-x86_64-illumos
|
||||
<<: *job-linux-8c
|
||||
|
||||
- &dist-x86_64-linux
|
||||
name: dist-x86_64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-16c
|
||||
|
||||
- name: dist-x86_64-linux-alt
|
||||
env:
|
||||
IMAGE: dist-x86_64-linux
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-16c
|
||||
|
||||
- name: dist-x86_64-musl
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: dist-x86_64-netbsd
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: i686-gnu
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: i686-gnu-nopt
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: mingw-check
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: test-various
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu
|
||||
<<: *job-linux-4c
|
||||
|
||||
# This job ensures commits landing on nightly still pass the full
|
||||
# test suite on the stable channel. There are some UI tests that
|
||||
# depend on the channel being built (for example if they include the
|
||||
# channel name on the output), and this builder prevents landing
|
||||
# changes that would result in broken builds after a promotion.
|
||||
- name: x86_64-gnu-stable
|
||||
env:
|
||||
IMAGE: x86_64-gnu
|
||||
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
|
||||
# Only run this job on the nightly channel. Running this on beta
|
||||
# could cause failures when `dev: 1` in `stage0.txt`, and running
|
||||
# this on stable is useless.
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: x86_64-gnu-aux
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: x86_64-gnu-integration
|
||||
env:
|
||||
# Only run this job on the nightly channel. Fuchsia requires
|
||||
# nightly features to compile, and this job would fail if
|
||||
# executed on beta and stable.
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-debug
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-distcheck
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-llvm-18
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-llvm-17
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-nopt
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: x86_64-gnu-tools
|
||||
env:
|
||||
DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
|
||||
<<: *job-linux-8c
|
||||
|
||||
####################
|
||||
# macOS Builders #
|
||||
####################
|
||||
|
||||
- name: dist-x86_64-apple
|
||||
env:
|
||||
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin
|
||||
RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-macos-xl
|
||||
|
||||
- name: dist-apple-various
|
||||
env:
|
||||
SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim
|
||||
RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
<<: *job-macos-xl
|
||||
|
||||
- name: x86_64-apple-1
|
||||
env: &env-x86_64-apple-tests
|
||||
SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
<<: *job-macos-xl
|
||||
|
||||
- name: x86_64-apple-2
|
||||
env:
|
||||
SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps
|
||||
<<: *env-x86_64-apple-tests
|
||||
<<: *job-macos-xl
|
||||
|
||||
# This target only needs to support 11.0 and up as nothing else supports the hardware
|
||||
- name: dist-aarch64-apple
|
||||
env:
|
||||
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--enable-full-tools
|
||||
--enable-sanitizers
|
||||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
--set llvm.ninja=false
|
||||
--set rust.lto=thin
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
USE_XCODE_CLANG: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-macos-m1
|
||||
|
||||
# This target only needs to support 11.0 and up as nothing else supports the hardware
|
||||
- name: aarch64-apple
|
||||
env:
|
||||
SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--enable-sanitizers
|
||||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
USE_XCODE_CLANG: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
<<: *job-macos-m1
|
||||
|
||||
######################
|
||||
# Windows Builders #
|
||||
######################
|
||||
|
||||
- name: x86_64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
|
||||
SCRIPT: make ci-msvc
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: i686-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
|
||||
SCRIPT: make ci-msvc
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: x86_64-msvc-ext
|
||||
env:
|
||||
SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
|
||||
HOST_TARGET: x86_64-pc-windows-msvc
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json
|
||||
DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
|
||||
<<: *job-windows-8c
|
||||
|
||||
# 32/64-bit MinGW builds.
|
||||
#
|
||||
# We are using MinGW with POSIX threads since LLVM requires
|
||||
# C++'s std::thread which is disabled in libstdc++ with win32 threads.
|
||||
# FIXME: Libc++ doesn't have this limitation so we can avoid
|
||||
# winpthreads if we switch to it.
|
||||
#
|
||||
# Instead of relying on the MinGW version installed on CI we download
|
||||
# and install one ourselves so we won't be surprised by changes to CI's
|
||||
# build image.
|
||||
#
|
||||
# Finally, note that the downloads below are all in the `rust-lang-ci` S3
|
||||
# bucket, but they clearly didn't originate there! The downloads originally
|
||||
# came from the mingw-w64 SourceForge download site. Unfortunately
|
||||
# SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
|
||||
|
||||
- name: i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
|
||||
SCRIPT: make ci-mingw
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: x86_64-mingw
|
||||
env:
|
||||
SCRIPT: make ci-mingw
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-gnu
|
||||
--enable-profiler
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: dist-x86_64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-msvc
|
||||
--host=x86_64-pc-windows-msvc
|
||||
--target=x86_64-pc-windows-msvc
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
--set rust.codegen-units=1
|
||||
SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: dist-i686-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=i686-pc-windows-msvc
|
||||
--host=i686-pc-windows-msvc
|
||||
--target=i686-pc-windows-msvc,i586-pc-windows-msvc
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: dist-aarch64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-msvc
|
||||
--host=aarch64-pc-windows-msvc
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: dist-i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=i686-pc-windows-gnu
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: dist-x86_64-mingw
|
||||
env:
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-gnu
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- name: dist-x86_64-msvc-alt
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
<<: *job-windows-8c
|
||||
|
||||
try:
|
||||
<<: *base-ci-job
|
||||
name: try - ${{ matrix.name }}
|
||||
env:
|
||||
DIST_TRY_BUILD: 1
|
||||
<<: [*shared-ci-variables, *prod-variables]
|
||||
if: github.event_name == 'push' && (((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust') || ((github.ref == 'refs/heads/automation/bors/try') && github.repository == 'rust-lang/rust'))
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- &dist-x86_64-linux
|
||||
name: dist-x86_64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-16c
|
||||
|
||||
# GitHub Actions fails the workflow if an empty list of jobs is provided to
|
||||
# the workflow, so we need to skip this job if nothing was produced by
|
||||
# the Python script.
|
||||
#
|
||||
# Unfortunately checking whether a list is empty is not possible in a nice
|
||||
# way due to GitHub Actions expressions limits.
|
||||
# This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82
|
||||
if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null
|
||||
|
||||
master:
|
||||
name: master
|
||||
@ -791,18 +405,18 @@ jobs:
|
||||
# build completed, as there is no practical way to detect when a workflow is
|
||||
# successful listening to webhooks only.
|
||||
try-success:
|
||||
needs: [try]
|
||||
needs: [ job ]
|
||||
if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
|
||||
<<: *base-success-job
|
||||
try-failure:
|
||||
needs: [try]
|
||||
needs: [ job ]
|
||||
if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
|
||||
<<: *base-failure-job
|
||||
auto-success:
|
||||
needs: [auto]
|
||||
needs: [ job ]
|
||||
if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
|
||||
<<: *base-success-job
|
||||
auto-failure:
|
||||
needs: [auto]
|
||||
needs: [ job ]
|
||||
if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
|
||||
<<: *base-failure-job
|
||||
|
@ -2,7 +2,7 @@
|
||||
# dynamically in CI from ci.yml.
|
||||
# You *do not* need to re-run `src/tools/expand-yaml-anchors` when you
|
||||
# modify this file.
|
||||
shared_defs:
|
||||
runners:
|
||||
- &base-job
|
||||
env: { }
|
||||
|
||||
@ -37,14 +37,430 @@ shared_defs:
|
||||
- &job-aarch64-linux
|
||||
os: [ self-hosted, ARM64, linux ]
|
||||
|
||||
envs:
|
||||
production:
|
||||
&production
|
||||
DEPLOY_BUCKET: rust-lang-ci2
|
||||
TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/rust-lang/rust/issues
|
||||
TOOLSTATE_PUBLISH: 1
|
||||
# AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named
|
||||
# AWS_SECRET_ACCESS_KEY_<keyid>. Including the key id in the name allows to
|
||||
# rotate them in a single branch while keeping the old key in another
|
||||
# branch, which wouldn't be possible if the key was named with the kind
|
||||
# (caches, artifacts...).
|
||||
CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
|
||||
ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
|
||||
AWS_REGION: us-west-1
|
||||
|
||||
try:
|
||||
<<: *production
|
||||
DIST_TRY_BUILD: 1
|
||||
|
||||
auto:
|
||||
<<: *production
|
||||
|
||||
pr:
|
||||
PR_CI_JOB: 1
|
||||
|
||||
# Jobs that run on each push to a pull request (PR)
|
||||
# These jobs automatically inherit envs.pr, to avoid repeating
|
||||
# it in each job definition.
|
||||
pr:
|
||||
- name: mingw-check
|
||||
- image: mingw-check
|
||||
<<: *job-linux-4c
|
||||
- name: mingw-check-tidy
|
||||
- image: mingw-check-tidy
|
||||
continue_on_error: true
|
||||
<<: *job-linux-4c
|
||||
- name: x86_64-gnu-llvm-17
|
||||
- image: x86_64-gnu-llvm-17
|
||||
env:
|
||||
ENABLE_GCC_CODEGEN: "1"
|
||||
<<: *job-linux-16c
|
||||
- name: x86_64-gnu-tools
|
||||
- image: x86_64-gnu-tools
|
||||
<<: *job-linux-16c
|
||||
|
||||
# Jobs that run when you perform a try build (@bors try)
|
||||
# These jobs automatically inherit envs.production, to avoid repeating
|
||||
# it in each job definition.
|
||||
try:
|
||||
- image: dist-x86_64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-16c
|
||||
|
||||
# Main CI jobs that have to be green to merge a commit into master
|
||||
# These jobs automatically inherit envs.production, to avoid repeating
|
||||
# it in each job definition.
|
||||
auto:
|
||||
#############################
|
||||
# Linux/Docker builders #
|
||||
#############################
|
||||
|
||||
- image: aarch64-gnu
|
||||
<<: *job-aarch64-linux
|
||||
|
||||
- image: arm-android
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: armhf-gnu
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-aarch64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-android
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-arm-linux
|
||||
<<: *job-linux-16c
|
||||
|
||||
- image: dist-armhf-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-armv7-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-i586-gnu-i586-i686-musl
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-i686-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-loongarch64-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-ohos
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-powerpc-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-powerpc64-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-powerpc64le-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-riscv64-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-s390x-linux
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-various-1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-various-2
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-x86_64-freebsd
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-x86_64-illumos
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-x86_64-linux
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-16c
|
||||
|
||||
- image: dist-x86_64-linux-alt
|
||||
env:
|
||||
IMAGE: dist-x86_64-linux
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-16c
|
||||
|
||||
- image: dist-x86_64-musl
|
||||
env:
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: dist-x86_64-netbsd
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: i686-gnu
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: i686-gnu-nopt
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: mingw-check
|
||||
<<: *job-linux-4c
|
||||
|
||||
- image: test-various
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: x86_64-gnu
|
||||
<<: *job-linux-4c
|
||||
|
||||
# This job ensures commits landing on nightly still pass the full
|
||||
# test suite on the stable channel. There are some UI tests that
|
||||
# depend on the channel being built (for example if they include the
|
||||
# channel name on the output), and this builder prevents landing
|
||||
# changes that would result in broken builds after a promotion.
|
||||
- image: x86_64-gnu-stable
|
||||
env:
|
||||
IMAGE: x86_64-gnu
|
||||
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
|
||||
# Only run this job on the nightly channel. Running this on beta
|
||||
# could cause failures when `dev: 1` in `stage0.txt`, and running
|
||||
# this on stable is useless.
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
<<: *job-linux-4c
|
||||
|
||||
- image: x86_64-gnu-aux
|
||||
<<: *job-linux-4c
|
||||
|
||||
- image: x86_64-gnu-integration
|
||||
env:
|
||||
# Only run this job on the nightly channel. Fuchsia requires
|
||||
# nightly features to compile, and this job would fail if
|
||||
# executed on beta and stable.
|
||||
CI_ONLY_WHEN_CHANNEL: nightly
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: x86_64-gnu-debug
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: x86_64-gnu-distcheck
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: x86_64-gnu-llvm-18
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: x86_64-gnu-llvm-17
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- image: x86_64-gnu-nopt
|
||||
<<: *job-linux-4c
|
||||
|
||||
- image: x86_64-gnu-tools
|
||||
env:
|
||||
DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
|
||||
<<: *job-linux-8c
|
||||
|
||||
####################
|
||||
# macOS Builders #
|
||||
####################
|
||||
|
||||
- image: dist-x86_64-apple
|
||||
env:
|
||||
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin
|
||||
RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
CODEGEN_BACKENDS: llvm,cranelift
|
||||
<<: *job-macos-xl
|
||||
|
||||
- image: dist-apple-various
|
||||
env:
|
||||
SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim
|
||||
RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
<<: *job-macos-xl
|
||||
|
||||
- image: x86_64-apple-1
|
||||
env: &env-x86_64-apple-tests
|
||||
SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.12
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
<<: *job-macos-xl
|
||||
|
||||
- image: x86_64-apple-2
|
||||
env:
|
||||
SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps
|
||||
<<: *env-x86_64-apple-tests
|
||||
<<: *job-macos-xl
|
||||
|
||||
# This target only needs to support 11.0 and up as nothing else supports the hardware
|
||||
- image: dist-aarch64-apple
|
||||
env:
|
||||
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--enable-full-tools
|
||||
--enable-sanitizers
|
||||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
--set llvm.ninja=false
|
||||
--set rust.lto=thin
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
USE_XCODE_CLANG: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-macos-m1
|
||||
|
||||
# This target only needs to support 11.0 and up as nothing else supports the hardware
|
||||
- image: aarch64-apple
|
||||
env:
|
||||
SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--enable-sanitizers
|
||||
--enable-profiler
|
||||
--set rust.jemalloc
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
|
||||
SELECT_XCODE: /Applications/Xcode_14.3.1.app
|
||||
USE_XCODE_CLANG: 1
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
|
||||
NO_LLVM_ASSERTIONS: 1
|
||||
NO_DEBUG_ASSERTIONS: 1
|
||||
NO_OVERFLOW_CHECKS: 1
|
||||
<<: *job-macos-m1
|
||||
|
||||
######################
|
||||
# Windows Builders #
|
||||
######################
|
||||
|
||||
- image: x86_64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
|
||||
SCRIPT: make ci-msvc
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: i686-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
|
||||
SCRIPT: make ci-msvc
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: x86_64-msvc-ext
|
||||
env:
|
||||
SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
|
||||
HOST_TARGET: x86_64-pc-windows-msvc
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json
|
||||
DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
|
||||
<<: *job-windows-8c
|
||||
|
||||
# 32/64-bit MinGW builds.
|
||||
#
|
||||
# We are using MinGW with POSIX threads since LLVM requires
|
||||
# C++'s std::thread which is disabled in libstdc++ with win32 threads.
|
||||
# FIXME: Libc++ doesn't have this limitation so we can avoid
|
||||
# winpthreads if we switch to it.
|
||||
#
|
||||
# Instead of relying on the MinGW version installed on CI we download
|
||||
# and install one ourselves so we won't be surprised by changes to CI's
|
||||
# build image.
|
||||
#
|
||||
# Finally, note that the downloads below are all in the `rust-lang-ci` S3
|
||||
# bucket, but they clearly didn't originate there! The downloads originally
|
||||
# came from the mingw-w64 SourceForge download site. Unfortunately
|
||||
# SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
|
||||
|
||||
- image: i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
|
||||
SCRIPT: make ci-mingw
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: x86_64-mingw
|
||||
env:
|
||||
SCRIPT: make ci-mingw
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-gnu
|
||||
--enable-profiler
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-x86_64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-msvc
|
||||
--host=x86_64-pc-windows-msvc
|
||||
--target=x86_64-pc-windows-msvc
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
--set rust.codegen-units=1
|
||||
SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-i686-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=i686-pc-windows-msvc
|
||||
--host=i686-pc-windows-msvc
|
||||
--target=i686-pc-windows-msvc,i586-pc-windows-msvc
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-aarch64-msvc
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-msvc
|
||||
--host=aarch64-pc-windows-msvc
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=i686-pc-windows-gnu
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-x86_64-mingw
|
||||
env:
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
RUST_CONFIGURE_ARGS: >-
|
||||
--build=x86_64-pc-windows-gnu
|
||||
--enable-full-tools
|
||||
--enable-profiler
|
||||
# We are intentionally allowing an old toolchain on this builder (and that's
|
||||
# incompatible with LLVM downloads today).
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
<<: *job-windows-8c
|
||||
|
||||
- image: dist-x86_64-msvc-alt
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
|
||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||
<<: *job-windows-8c
|
||||
|
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This script serves for generating a matrix of jobs that should
|
||||
be executed on CI.
|
||||
|
||||
It reads job definitions from `src/ci/github-actions/jobs.yml`
|
||||
and filters them based on the event that happened on CI.
|
||||
|
||||
Currently, it only supports PR builds.
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
JOBS_YAML_PATH = Path(__file__).absolute().parent.parent / "github-actions" / "jobs.yml"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open(JOBS_YAML_PATH) as f:
|
||||
jobs = yaml.safe_load(f)
|
||||
job_output = jobs["pr"]
|
||||
print(f"jobs={json.dumps(job_output)}")
|
@ -26,13 +26,13 @@ tweaks to the overall design.
|
||||
A syntactical example of a coroutine is:
|
||||
|
||||
```rust
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
use std::ops::{Coroutine, CoroutineState};
|
||||
use std::pin::Pin;
|
||||
|
||||
fn main() {
|
||||
let mut coroutine = || {
|
||||
let mut coroutine = #[coroutine] || {
|
||||
yield 1;
|
||||
return "foo"
|
||||
};
|
||||
@ -48,7 +48,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Coroutines are closure-like literals which can contain a `yield` statement. The
|
||||
Coroutines are closure-like literals which are annotated with `#[coroutine]`
|
||||
and can contain a `yield` statement. The
|
||||
`yield` statement takes an optional expression of a value to yield out of the
|
||||
coroutine. All coroutine literals implement the `Coroutine` trait in the
|
||||
`std::ops` module. The `Coroutine` trait has one main method, `resume`, which
|
||||
@ -58,13 +59,13 @@ An example of the control flow of coroutines is that the following example
|
||||
prints all numbers in order:
|
||||
|
||||
```rust
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
use std::ops::Coroutine;
|
||||
use std::pin::Pin;
|
||||
|
||||
fn main() {
|
||||
let mut coroutine = || {
|
||||
let mut coroutine = #[coroutine] || {
|
||||
println!("2");
|
||||
yield;
|
||||
println!("4");
|
||||
@ -78,9 +79,9 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
At this time the main intended use case of coroutines is an implementation
|
||||
primitive for async/await syntax, but coroutines will likely be extended to
|
||||
ergonomic implementations of iterators and other primitives in the future.
|
||||
At this time the main use case of coroutines is an implementation
|
||||
primitive for `async`/`await` and `gen` syntax, but coroutines
|
||||
will likely be extended to other primitives in the future.
|
||||
Feedback on the design and usage is always appreciated!
|
||||
|
||||
### The `Coroutine` trait
|
||||
@ -163,14 +164,14 @@ which point all state is saved off in the coroutine and a value is returned.
|
||||
Let's take a look at an example to see what's going on here:
|
||||
|
||||
```rust
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
use std::ops::Coroutine;
|
||||
use std::pin::Pin;
|
||||
|
||||
fn main() {
|
||||
let ret = "foo";
|
||||
let mut coroutine = move || {
|
||||
let mut coroutine = #[coroutine] move || {
|
||||
yield 1;
|
||||
return ret
|
||||
};
|
||||
@ -183,7 +184,7 @@ fn main() {
|
||||
This coroutine literal will compile down to something similar to:
|
||||
|
||||
```rust
|
||||
#![feature(arbitrary_self_types, coroutines, coroutine_trait)]
|
||||
#![feature(arbitrary_self_types, coroutine_trait)]
|
||||
|
||||
use std::ops::{Coroutine, CoroutineState};
|
||||
use std::pin::Pin;
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
The tracking issue for this feature is: [#76001]
|
||||
|
||||
See also [`inline_const`](inline-const.md)
|
||||
|
||||
------
|
||||
|
||||
This feature allows you to use inline constant expressions in pattern position:
|
||||
|
@ -1,32 +0,0 @@
|
||||
# `inline_const`
|
||||
|
||||
The tracking issue for this feature is: [#76001]
|
||||
|
||||
See also [`inline_const_pat`](inline-const-pat.md)
|
||||
|
||||
------
|
||||
|
||||
This feature allows you to use inline constant expressions. For example, you can
|
||||
turn this code:
|
||||
|
||||
```rust
|
||||
# fn add_one(x: i32) -> i32 { x + 1 }
|
||||
const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
|
||||
|
||||
fn main() {
|
||||
let x = add_one(MY_COMPUTATION);
|
||||
}
|
||||
```
|
||||
|
||||
into this code:
|
||||
|
||||
```rust
|
||||
#![feature(inline_const)]
|
||||
|
||||
# fn add_one(x: i32) -> i32 { x + 1 }
|
||||
fn main() {
|
||||
let x = add_one(const { 1 + 2 * 3 / 4 });
|
||||
}
|
||||
```
|
||||
|
||||
[#76001]: https://github.com/rust-lang/rust/issues/76001
|
@ -5,13 +5,13 @@ each one organized by a "feature flag." That is, when using an unstable
|
||||
feature of Rust, you must use a flag, like this:
|
||||
|
||||
```rust
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
use std::ops::{Coroutine, CoroutineState};
|
||||
use std::pin::Pin;
|
||||
|
||||
fn main() {
|
||||
let mut coroutine = || {
|
||||
let mut coroutine = #[coroutine] || {
|
||||
yield 1;
|
||||
return "foo"
|
||||
};
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(inline_const)]
|
||||
#![warn(clippy::indexing_slicing)]
|
||||
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
|
||||
// we want to avoid false positives.
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: indexing may panic
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:27:5
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:26:5
|
||||
|
|
||||
LL | x[index];
|
||||
| ^^^^^^^^
|
||||
@ -9,7 +9,7 @@ LL | x[index];
|
||||
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:41:5
|
||||
|
|
||||
LL | v[0];
|
||||
| ^^^^
|
||||
@ -17,7 +17,7 @@ LL | v[0];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
|
||||
|
|
||||
LL | v[10];
|
||||
| ^^^^^
|
||||
@ -25,7 +25,7 @@ LL | v[10];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:44:5
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
|
||||
|
|
||||
LL | v[1 << 3];
|
||||
| ^^^^^^^^^
|
||||
@ -33,7 +33,7 @@ LL | v[1 << 3];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:49:5
|
||||
|
|
||||
LL | v[N];
|
||||
| ^^^^
|
||||
@ -41,7 +41,7 @@ LL | v[N];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:51:5
|
||||
--> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
|
||||
|
|
||||
LL | v[M];
|
||||
| ^^^^
|
||||
|
@ -10,7 +10,7 @@
|
||||
arithmetic_overflow,
|
||||
unconditional_panic
|
||||
)]
|
||||
#![feature(const_mut_refs, inline_const)]
|
||||
#![feature(const_mut_refs)]
|
||||
#![warn(clippy::arithmetic_side_effects)]
|
||||
|
||||
extern crate proc_macro_derive;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(let_chains, inline_const)]
|
||||
#![feature(let_chains)]
|
||||
#![warn(clippy::bool_to_int_with_if)]
|
||||
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(let_chains, inline_const)]
|
||||
#![feature(let_chains)]
|
||||
#![warn(clippy::bool_to_int_with_if)]
|
||||
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(inline_const)]
|
||||
#![warn(clippy::const_is_empty)]
|
||||
#![allow(clippy::needless_late_init, unused_must_use)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:6:8
|
||||
--> tests/ui/const_is_empty.rs:5:8
|
||||
|
|
||||
LL | if "".is_empty() {
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -8,151 +8,151 @@ LL | if "".is_empty() {
|
||||
= help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]`
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:9:8
|
||||
--> tests/ui/const_is_empty.rs:8:8
|
||||
|
|
||||
LL | if "foobar".is_empty() {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:15:8
|
||||
--> tests/ui/const_is_empty.rs:14:8
|
||||
|
|
||||
LL | if b"".is_empty() {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:18:8
|
||||
--> tests/ui/const_is_empty.rs:17:8
|
||||
|
|
||||
LL | if b"foobar".is_empty() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:35:8
|
||||
--> tests/ui/const_is_empty.rs:34:8
|
||||
|
|
||||
LL | if empty2.is_empty() {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:38:8
|
||||
--> tests/ui/const_is_empty.rs:37:8
|
||||
|
|
||||
LL | if non_empty2.is_empty() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:60:13
|
||||
--> tests/ui/const_is_empty.rs:59:13
|
||||
|
|
||||
LL | let _ = EMPTY_STR.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:62:13
|
||||
--> tests/ui/const_is_empty.rs:61:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_STR.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:64:13
|
||||
--> tests/ui/const_is_empty.rs:63:13
|
||||
|
|
||||
LL | let _ = EMPTY_BSTR.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:66:13
|
||||
--> tests/ui/const_is_empty.rs:65:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_BSTR.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:68:13
|
||||
--> tests/ui/const_is_empty.rs:67:13
|
||||
|
|
||||
LL | let _ = EMPTY_ARRAY.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:70:13
|
||||
--> tests/ui/const_is_empty.rs:69:13
|
||||
|
|
||||
LL | let _ = EMPTY_ARRAY_REPEAT.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:72:13
|
||||
--> tests/ui/const_is_empty.rs:71:13
|
||||
|
|
||||
LL | let _ = EMPTY_U8_SLICE.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:74:13
|
||||
--> tests/ui/const_is_empty.rs:73:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_U8_SLICE.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:76:13
|
||||
--> tests/ui/const_is_empty.rs:75:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_ARRAY.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:78:13
|
||||
--> tests/ui/const_is_empty.rs:77:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_ARRAY_REPEAT.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:80:13
|
||||
--> tests/ui/const_is_empty.rs:79:13
|
||||
|
|
||||
LL | let _ = EMPTY_REF_ARRAY.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:82:13
|
||||
--> tests/ui/const_is_empty.rs:81:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_REF_ARRAY.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:84:13
|
||||
--> tests/ui/const_is_empty.rs:83:13
|
||||
|
|
||||
LL | let _ = EMPTY_SLICE.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:86:13
|
||||
--> tests/ui/const_is_empty.rs:85:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_SLICE.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:88:13
|
||||
--> tests/ui/const_is_empty.rs:87:13
|
||||
|
|
||||
LL | let _ = NON_EMPTY_SLICE_REPEAT.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:94:13
|
||||
--> tests/ui/const_is_empty.rs:93:13
|
||||
|
|
||||
LL | let _ = value.is_empty();
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to false
|
||||
--> tests/ui/const_is_empty.rs:97:13
|
||||
--> tests/ui/const_is_empty.rs:96:13
|
||||
|
|
||||
LL | let _ = x.is_empty();
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:99:13
|
||||
--> tests/ui/const_is_empty.rs:98:13
|
||||
|
|
||||
LL | let _ = "".is_empty();
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:101:13
|
||||
--> tests/ui/const_is_empty.rs:100:13
|
||||
|
|
||||
LL | let _ = b"".is_empty();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: this expression always evaluates to true
|
||||
--> tests/ui/const_is_empty.rs:155:13
|
||||
--> tests/ui/const_is_empty.rs:154:13
|
||||
|
|
||||
LL | let _ = val.is_empty();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,9 +1,9 @@
|
||||
// Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562
|
||||
|
||||
#![feature(coroutines, coroutine_trait)]
|
||||
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||
|
||||
fn main() {
|
||||
let _ = || {
|
||||
let _ = #[coroutine] || {
|
||||
yield;
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
//@compile-flags: -Zdeduplicate-diagnostics=yes
|
||||
|
||||
#![feature(inline_const)]
|
||||
#![warn(clippy::indexing_slicing)]
|
||||
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
|
||||
// we want to avoid false positives.
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:16:20
|
||||
--> tests/ui/indexing_slicing_index.rs:15:20
|
||||
|
|
||||
LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
|
||||
| ^^^^^^^^^^
|
||||
@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re
|
||||
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
|
||||
|
||||
error[E0080]: evaluation of `main::{constant#3}` failed
|
||||
--> tests/ui/indexing_slicing_index.rs:48:14
|
||||
--> tests/ui/indexing_slicing_index.rs:47:14
|
||||
|
|
||||
LL | const { &ARR[idx4()] };
|
||||
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
|
||||
|
||||
note: erroneous constant encountered
|
||||
--> tests/ui/indexing_slicing_index.rs:48:5
|
||||
--> tests/ui/indexing_slicing_index.rs:47:5
|
||||
|
|
||||
LL | const { &ARR[idx4()] };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:29:5
|
||||
--> tests/ui/indexing_slicing_index.rs:28:5
|
||||
|
|
||||
LL | x[index];
|
||||
| ^^^^^^^^
|
||||
@ -30,7 +30,7 @@ LL | x[index];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: index is out of bounds
|
||||
--> tests/ui/indexing_slicing_index.rs:32:5
|
||||
--> tests/ui/indexing_slicing_index.rs:31:5
|
||||
|
|
||||
LL | x[4];
|
||||
| ^^^^
|
||||
@ -39,13 +39,13 @@ LL | x[4];
|
||||
= help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
|
||||
|
||||
error: index is out of bounds
|
||||
--> tests/ui/indexing_slicing_index.rs:34:5
|
||||
--> tests/ui/indexing_slicing_index.rs:33:5
|
||||
|
|
||||
LL | x[1 << 3];
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:45:14
|
||||
--> tests/ui/indexing_slicing_index.rs:44:14
|
||||
|
|
||||
LL | const { &ARR[idx()] };
|
||||
| ^^^^^^^^^^
|
||||
@ -54,7 +54,7 @@ LL | const { &ARR[idx()] };
|
||||
= note: the suggestion might not be applicable in constant blocks
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:48:14
|
||||
--> tests/ui/indexing_slicing_index.rs:47:14
|
||||
|
|
||||
LL | const { &ARR[idx4()] };
|
||||
| ^^^^^^^^^^^
|
||||
@ -63,13 +63,13 @@ LL | const { &ARR[idx4()] };
|
||||
= note: the suggestion might not be applicable in constant blocks
|
||||
|
||||
error: index is out of bounds
|
||||
--> tests/ui/indexing_slicing_index.rs:55:5
|
||||
--> tests/ui/indexing_slicing_index.rs:54:5
|
||||
|
|
||||
LL | y[4];
|
||||
| ^^^^
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:58:5
|
||||
--> tests/ui/indexing_slicing_index.rs:57:5
|
||||
|
|
||||
LL | v[0];
|
||||
| ^^^^
|
||||
@ -77,7 +77,7 @@ LL | v[0];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:60:5
|
||||
--> tests/ui/indexing_slicing_index.rs:59:5
|
||||
|
|
||||
LL | v[10];
|
||||
| ^^^^^
|
||||
@ -85,7 +85,7 @@ LL | v[10];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:62:5
|
||||
--> tests/ui/indexing_slicing_index.rs:61:5
|
||||
|
|
||||
LL | v[1 << 3];
|
||||
| ^^^^^^^^^
|
||||
@ -93,13 +93,13 @@ LL | v[1 << 3];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: index is out of bounds
|
||||
--> tests/ui/indexing_slicing_index.rs:70:5
|
||||
--> tests/ui/indexing_slicing_index.rs:69:5
|
||||
|
|
||||
LL | x[N];
|
||||
| ^^^^
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:73:5
|
||||
--> tests/ui/indexing_slicing_index.rs:72:5
|
||||
|
|
||||
LL | v[N];
|
||||
| ^^^^
|
||||
@ -107,7 +107,7 @@ LL | v[N];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: indexing may panic
|
||||
--> tests/ui/indexing_slicing_index.rs:75:5
|
||||
--> tests/ui/indexing_slicing_index.rs:74:5
|
||||
|
|
||||
LL | v[M];
|
||||
| ^^^^
|
||||
@ -115,7 +115,7 @@ LL | v[M];
|
||||
= help: consider using `.get(n)` or `.get_mut(n)` instead
|
||||
|
||||
error: index is out of bounds
|
||||
--> tests/ui/indexing_slicing_index.rs:79:13
|
||||
--> tests/ui/indexing_slicing_index.rs:78:13
|
||||
|
|
||||
LL | let _ = x[4];
|
||||
| ^^^^
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(coroutines)]
|
||||
#![warn(clippy::large_futures)]
|
||||
#![allow(clippy::never_loop)]
|
||||
#![allow(clippy::future_not_send)]
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(coroutines)]
|
||||
#![warn(clippy::large_futures)]
|
||||
#![allow(clippy::never_loop)]
|
||||
#![allow(clippy::future_not_send)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: large future with a size of 16385 bytes
|
||||
--> tests/ui/large_futures.rs:11:9
|
||||
--> tests/ui/large_futures.rs:10:9
|
||||
|
|
||||
LL | big_fut([0u8; 1024 * 16]).await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))`
|
||||
@ -8,37 +8,37 @@ LL | big_fut([0u8; 1024 * 16]).await;
|
||||
= help: to override `-D warnings` add `#[allow(clippy::large_futures)]`
|
||||
|
||||
error: large future with a size of 16386 bytes
|
||||
--> tests/ui/large_futures.rs:15:5
|
||||
--> tests/ui/large_futures.rs:14:5
|
||||
|
|
||||
LL | f.await
|
||||
| ^ help: consider `Box::pin` on it: `Box::pin(f)`
|
||||
|
||||
error: large future with a size of 16387 bytes
|
||||
--> tests/ui/large_futures.rs:20:9
|
||||
--> tests/ui/large_futures.rs:19:9
|
||||
|
|
||||
LL | wait().await;
|
||||
| ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())`
|
||||
|
||||
error: large future with a size of 16387 bytes
|
||||
--> tests/ui/large_futures.rs:25:13
|
||||
--> tests/ui/large_futures.rs:24:13
|
||||
|
|
||||
LL | wait().await;
|
||||
| ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())`
|
||||
|
||||
error: large future with a size of 65540 bytes
|
||||
--> tests/ui/large_futures.rs:33:5
|
||||
--> tests/ui/large_futures.rs:32:5
|
||||
|
|
||||
LL | foo().await;
|
||||
| ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())`
|
||||
|
||||
error: large future with a size of 49159 bytes
|
||||
--> tests/ui/large_futures.rs:35:5
|
||||
--> tests/ui/large_futures.rs:34:5
|
||||
|
|
||||
LL | calls_fut(fut).await;
|
||||
| ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))`
|
||||
|
||||
error: large future with a size of 65540 bytes
|
||||
--> tests/ui/large_futures.rs:48:5
|
||||
--> tests/ui/large_futures.rs:47:5
|
||||
|
|
||||
LL | / async {
|
||||
LL | |
|
||||
@ -59,7 +59,7 @@ LL + })
|
||||
|
|
||||
|
||||
error: large future with a size of 65540 bytes
|
||||
--> tests/ui/large_futures.rs:60:13
|
||||
--> tests/ui/large_futures.rs:59:13
|
||||
|
|
||||
LL | / async {
|
||||
LL | | let x = [0i32; 1024 * 16];
|
||||
|
@ -2,7 +2,6 @@
|
||||
//@aux-build:proc_macros.rs
|
||||
#![allow(clippy::needless_if, unused)]
|
||||
#![warn(clippy::manual_is_infinite, clippy::manual_is_finite)]
|
||||
#![feature(inline_const)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macros;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: manually checking if a float is infinite
|
||||
--> tests/ui/manual_float_methods.rs:23:8
|
||||
--> tests/ui/manual_float_methods.rs:22:8
|
||||
|
|
||||
LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
|
||||
@ -8,7 +8,7 @@ LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {}
|
||||
= help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]`
|
||||
|
||||
error: manually checking if a float is finite
|
||||
--> tests/ui/manual_float_methods.rs:24:8
|
||||
--> tests/ui/manual_float_methods.rs:23:8
|
||||
|
|
||||
LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -29,13 +29,13 @@ LL | if !x.is_infinite() {}
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: manually checking if a float is infinite
|
||||
--> tests/ui/manual_float_methods.rs:25:8
|
||||
--> tests/ui/manual_float_methods.rs:24:8
|
||||
|
|
||||
LL | if x == INFINITE || x == NEG_INFINITE {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
|
||||
|
||||
error: manually checking if a float is finite
|
||||
--> tests/ui/manual_float_methods.rs:26:8
|
||||
--> tests/ui/manual_float_methods.rs:25:8
|
||||
|
|
||||
LL | if x != INFINITE && x != NEG_INFINITE {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -54,13 +54,13 @@ LL | if !x.is_infinite() {}
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
|
||||
error: manually checking if a float is infinite
|
||||
--> tests/ui/manual_float_methods.rs:28:8
|
||||
--> tests/ui/manual_float_methods.rs:27:8
|
||||
|
|
||||
LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
|
||||
|
||||
error: manually checking if a float is finite
|
||||
--> tests/ui/manual_float_methods.rs:29:8
|
||||
--> tests/ui/manual_float_methods.rs:28:8
|
||||
|
|
||||
LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(inline_const, try_blocks)]
|
||||
#![feature(try_blocks)]
|
||||
#![allow(
|
||||
clippy::eq_op,
|
||||
clippy::single_match,
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::let_unit_value)]
|
||||
#![feature(inline_const)]
|
||||
#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
|
||||
|
||||
extern crate core;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: `panic` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:23:5
|
||||
--> tests/ui/panicking_macros.rs:22:5
|
||||
|
|
||||
LL | panic!();
|
||||
| ^^^^^^^^
|
||||
@ -8,19 +8,19 @@ LL | panic!();
|
||||
= help: to override `-D warnings` add `#[allow(clippy::panic)]`
|
||||
|
||||
error: `panic` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:26:5
|
||||
--> tests/ui/panicking_macros.rs:25:5
|
||||
|
|
||||
LL | panic!("message");
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `panic` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:28:5
|
||||
--> tests/ui/panicking_macros.rs:27:5
|
||||
|
|
||||
LL | panic!("{} {}", "panic with", "multiple arguments");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `todo` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:35:5
|
||||
--> tests/ui/panicking_macros.rs:34:5
|
||||
|
|
||||
LL | todo!();
|
||||
| ^^^^^^^
|
||||
@ -29,19 +29,19 @@ LL | todo!();
|
||||
= help: to override `-D warnings` add `#[allow(clippy::todo)]`
|
||||
|
||||
error: `todo` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:38:5
|
||||
--> tests/ui/panicking_macros.rs:37:5
|
||||
|
|
||||
LL | todo!("message");
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `todo` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:40:5
|
||||
--> tests/ui/panicking_macros.rs:39:5
|
||||
|
|
||||
LL | todo!("{} {}", "panic with", "multiple arguments");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `unimplemented` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:47:5
|
||||
--> tests/ui/panicking_macros.rs:46:5
|
||||
|
|
||||
LL | unimplemented!();
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
@ -50,19 +50,19 @@ LL | unimplemented!();
|
||||
= help: to override `-D warnings` add `#[allow(clippy::unimplemented)]`
|
||||
|
||||
error: `unimplemented` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:50:5
|
||||
--> tests/ui/panicking_macros.rs:49:5
|
||||
|
|
||||
LL | unimplemented!("message");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `unimplemented` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:52:5
|
||||
--> tests/ui/panicking_macros.rs:51:5
|
||||
|
|
||||
LL | unimplemented!("{} {}", "panic with", "multiple arguments");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: usage of the `unreachable!` macro
|
||||
--> tests/ui/panicking_macros.rs:59:5
|
||||
--> tests/ui/panicking_macros.rs:58:5
|
||||
|
|
||||
LL | unreachable!();
|
||||
| ^^^^^^^^^^^^^^
|
||||
@ -71,37 +71,37 @@ LL | unreachable!();
|
||||
= help: to override `-D warnings` add `#[allow(clippy::unreachable)]`
|
||||
|
||||
error: usage of the `unreachable!` macro
|
||||
--> tests/ui/panicking_macros.rs:62:5
|
||||
--> tests/ui/panicking_macros.rs:61:5
|
||||
|
|
||||
LL | unreachable!("message");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: usage of the `unreachable!` macro
|
||||
--> tests/ui/panicking_macros.rs:64:5
|
||||
--> tests/ui/panicking_macros.rs:63:5
|
||||
|
|
||||
LL | unreachable!("{} {}", "panic with", "multiple arguments");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `panic` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:71:5
|
||||
--> tests/ui/panicking_macros.rs:70:5
|
||||
|
|
||||
LL | panic!();
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `todo` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:73:5
|
||||
--> tests/ui/panicking_macros.rs:72:5
|
||||
|
|
||||
LL | todo!();
|
||||
| ^^^^^^^
|
||||
|
||||
error: `unimplemented` should not be present in production code
|
||||
--> tests/ui/panicking_macros.rs:75:5
|
||||
--> tests/ui/panicking_macros.rs:74:5
|
||||
|
|
||||
LL | unimplemented!();
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: usage of the `unreachable!` macro
|
||||
--> tests/ui/panicking_macros.rs:77:5
|
||||
--> tests/ui/panicking_macros.rs:76:5
|
||||
|
|
||||
LL | unreachable!();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,7 +1,7 @@
|
||||
//@aux-build:proc_macros.rs
|
||||
#![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]
|
||||
#![warn(clippy::redundant_locals)]
|
||||
#![feature(async_closure, coroutines)]
|
||||
#![feature(async_closure, coroutines, stmt_expr_attributes)]
|
||||
|
||||
extern crate proc_macros;
|
||||
use proc_macros::{external, with_span};
|
||||
@ -191,11 +191,11 @@ fn issue12225() {
|
||||
let v4 = v4;
|
||||
dbg!(&v4);
|
||||
});
|
||||
assert_static(static || {
|
||||
assert_static(#[coroutine] static || {
|
||||
let v5 = v5;
|
||||
yield;
|
||||
});
|
||||
assert_static(|| {
|
||||
assert_static(#[coroutine] || {
|
||||
let v6 = v6;
|
||||
yield;
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user