diff options
371 files changed, 3297 insertions, 2881 deletions
diff --git a/.gitattributes b/.gitattributes index a7de7ce8559..2c5c37007d5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,7 +3,7 @@ * text=auto eol=lf *.cpp rust *.h rust -*.rs rust +*.rs rust diff=rust *.fixed linguist-language=Rust src/etc/installer/gfx/* binary *.woff binary diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91241d2b214..84e39a4189e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -154,6 +154,11 @@ jobs: strategy: matrix: include: + - name: aarch64-gnu + os: + - self-hosted + - ARM64 + - linux - name: arm-android os: ubuntu-latest-xl env: {} @@ -178,9 +183,6 @@ jobs: - name: dist-i586-gnu-i586-i686-musl os: ubuntu-latest-xl env: {} - - name: dist-i686-freebsd - os: ubuntu-latest-xl - env: {} - name: dist-i686-linux os: ubuntu-latest-xl env: {} @@ -321,8 +323,6 @@ jobs: env: RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler" SCRIPT: make ci-subset-1 - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 os: windows-latest-xl - name: x86_64-msvc-2 env: @@ -333,23 +333,17 @@ jobs: env: RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-msvc" SCRIPT: make ci-subset-1 - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 os: windows-latest-xl - name: i686-msvc-2 env: RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-msvc" SCRIPT: make ci-subset-2 - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 os: windows-latest-xl - name: x86_64-msvc-cargo env: SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld" VCVARS_BAT: vcvars64.bat - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 os: windows-latest-xl - name: x86_64-msvc-tools env: @@ -361,8 +355,6 @@ jobs: RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu" SCRIPT: make ci-mingw-subset-1 CUSTOM_MINGW: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 os: windows-latest-xl - name: i686-mingw-2 env: @@ -375,8 +367,6 @@ jobs: SCRIPT: make ci-mingw-subset-1 RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler" CUSTOM_MINGW: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 os: windows-latest-xl - name: x86_64-mingw-2 env: @@ -509,116 +499,6 @@ jobs: 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-fallible: - name: auto-fallible - env: - CI_JOB_NAME: "${{ matrix.name }}" - SCCACHE_BUCKET: rust-lang-gha-caches - DEPLOY_BUCKET: rust-lang-gha - TOOLSTATE_REPO: "https://github.com/pietroalbini/rust-toolstate" - TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/pietroalbini/rust-toolstate/issues" - TOOLSTATE_PUBLISH: 1 - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZOMUQATD5 - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZH5AYXDVF - CACHE_DOMAIN: ci-caches-gha.rust-lang.org - if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - strategy: - fail-fast: false - matrix: - include: - - name: aarch64-gnu - os: - - self-hosted - - ARM64 - - linux - timeout-minutes: 600 - runs-on: "${{ matrix.os }}" - steps: - - name: disable git crlf conversion - run: git config --global core.autocrlf false - - name: checkout the source code - uses: actions/checkout@v2 - 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_JOBS && 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: configure GitHub Actions to kill the build when outdated - uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master - with: - github_token: "${{ secrets.github_token }}" - if: "success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'" - - 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 WIX - run: src/ci/scripts/install-wix.sh - if: success() && !env.SKIP_JOB - - name: ensure the build happens on a partition with enough space - run: src/ci/scripts/symlink-build-dir.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: 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: checkout submodules - run: src/ci/scripts/checkout-submodules.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: run the build - run: src/ci/scripts/run-build-from-ci.sh - 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: 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 env: diff --git a/.gitignore b/.gitignore index 1c50d9b054d..5f7135e38d1 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ __pycache__/ /inst/ /llvm/ /mingw-build/ +/src/tools/x/target # Created by default with `src/ci/docker/run.sh`: /obj/ /unicode-downloads diff --git a/Cargo.lock b/Cargo.lock index b992552a521..45a19fd7963 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,9 +460,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chalk-derive" -version = "0.32.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d072b2ba723f0bada7c515d8b3725224bc4f5052d2a92dcbeb0b118ff37084a" +checksum = "9f88ce4deae1dace71e49b7611cfae2d5489de3530d6daba5758043c47ac3a10" dependencies = [ "proc-macro2", "quote", @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "chalk-engine" -version = "0.32.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb5475f6083d6d6c509e1c335c4f69ad04144ac090faa1afb134a53c3695841" +checksum = "0e34c9b1b10616782143d7f49490f91ae94afaf2202de3ab0b2835e78b4f0ccc" dependencies = [ "chalk-derive", "chalk-ir", @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.32.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60cdb0e18c5455cb6a85e8464aad3622b70476018edfa8845691df66f7e9a05" +checksum = "63362c629c2014ab639b04029070763fb8224df136d1363d30e9ece4c8877da3" dependencies = [ "chalk-derive", "lazy_static", @@ -495,9 +495,9 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.32.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "981534d499a8476ecc0b520be4d3864757f96211826a75360fbf2cb6fae362ab" +checksum = "cac338a67af52a7f50bb2f8232e730a3518ce432dbe303246acfe525ddd838c7" dependencies = [ "chalk-derive", "chalk-ir", @@ -1968,18 +1968,6 @@ dependencies = [ [[package]] name = "measureme" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef709d3257013bba7cff14fc504e07e80631d3fe0f6d38ce63b8f6510ccb932" -dependencies = [ - "byteorder", - "memmap", - "parking_lot 0.9.0", - "rustc-hash", -] - -[[package]] -name = "measureme" version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22bf8d885d073610aee20e7fa205c4341ed32a761dbde96da5fd96301a8d3e82" @@ -2705,9 +2693,9 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.39" +version = "2.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9424b4650b9c1134d0a1b34dab82319691e1c95fa8af1658fc640deb1b6823c" +checksum = "68c5fb83bc092c10e12ca863ab8922b1833382d5d248aaafca779886d3396a44" dependencies = [ "bitflags", "clap", @@ -3033,19 +3021,18 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_arena" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e941a8fc3878a111d2bbfe78e39522d884136f0b412b12592195f26f653476" +checksum = "477085eefed2f12085c68577cc3827c8c39a31a4a750978aacb9af10f7903174" dependencies = [ - "rustc-ap-rustc_data_structures", "smallvec 1.4.2", ] [[package]] name = "rustc-ap-rustc_ast" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b58b6b035710df7f339a2bf86f6dafa876efd95439540970e24609e33598ca6" +checksum = "4d4ad5ec25f6b3d122354595be0d1b513f37fca3299d9b448b1db28f4a9e4b12" dependencies = [ "bitflags", "rustc-ap-rustc_data_structures", @@ -3060,9 +3047,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_ast_passes" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d379a900d6a1f098490d92ab83e87487dcee2e4ec3f04c3ac4512b5117b64e2" +checksum = "0c6d8635298d7736decdb3c6e92e784d3eccde557462a9c10ac11a34fec3d756" dependencies = [ "itertools 0.9.0", "rustc-ap-rustc_ast", @@ -3079,9 +3066,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_ast_pretty" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658d925c0da9e3c5cddc5e54f4fa8c03b41aff1fc6dc5e41837c1118ad010ac0" +checksum = "7a61bdb5252e1a95b7715038949e10f07ce770a436fcd497cdd9bc7255471de9" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_span", @@ -3091,9 +3078,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_attr" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f387037534f34c148aed753622677500e42d190a095670e7ac3fffc09811a59" +checksum = "84520a16cb61bd31e9c27e87eca5d933a9c94ac84f25649bddcc19989275ab2a" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_pretty", @@ -3110,10 +3097,11 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ffd17a37e00d77926a0713f191c59ff3aeb2b551a024c7cfffce14bab79be8" +checksum = "b1cb2b6a38759cf7c0c1434c8b4cbfcab9cd24970d05f960f2ca01226ddb4d68" dependencies = [ + "arrayvec", "bitflags", "cfg-if 0.1.10", "crossbeam-utils 0.7.2", @@ -3121,7 +3109,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme 0.7.1", + "measureme", "parking_lot 0.11.0", "rustc-ap-rustc_graphviz", "rustc-ap-rustc_index", @@ -3140,9 +3128,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_errors" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3263ddcfa9eb911e54a4e8088878dd9fd10e00d8b99b01033ba4a2733fe91d" +checksum = "46cfb19536426bf9252827a78552d635be207a4be74f4e92832aad82d7f2135c" dependencies = [ "annotate-snippets 0.8.0", "atty", @@ -3159,9 +3147,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_expand" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1ab7e68cede8a2273fd8b8623002ce9dc832e061dfc3330e9bcc1fc2a722d73" +checksum = "6273e60042a0ef31f6cfe783c519873993eb426f055be2bc058a48b6ca3934d0" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_passes", @@ -3182,9 +3170,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_feature" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea2dc95421bc19bbd4d939399833a882c46b684283b4267ad1fcf982fc043d9" +checksum = "2936e8346157e2848305e509f38aa3ed4e97697975ef68027587f5db6a38703f" dependencies = [ "rustc-ap-rustc_data_structures", "rustc-ap-rustc_span", @@ -3192,21 +3180,21 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_fs_util" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e44c1804f09635f83f6cf1e04c2e92f8aeb7b4e850ac6c53d373dab02c13053" +checksum = "9b4c3ae17776b5a5aa441ca510a650f75805e1f5569edd231caa8378552195a4" [[package]] name = "rustc-ap-rustc_graphviz" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc491f2b9be6e928f6df6b287549b8d50c48e8eff8638345155f40fa2cfb785d" +checksum = "5611bf0ac0ac49c2a22c959c7d8b17f85f69959293f0e8c4f753eca832fe7ad0" [[package]] name = "rustc-ap-rustc_index" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa73f3fed413cdb6290738a10267da17b9ae8e02087334778b9a8c9491c5efc0" +checksum = "ca67cf37c427057192e451c7f912e94ae9a8ca5ad69fd481c011fad3f86982cb" dependencies = [ "arrayvec", "rustc-ap-rustc_macros", @@ -3215,18 +3203,18 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_lexer" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e993881244a92f3b44cf43c8f22ae2ca5cefe4f55a34e2b65b72ee66fe5ad077" +checksum = "a5b04cd2159495584d976d501c5394498470c2e94e4f0cebb8186562d407a678" dependencies = [ "unicode-xid", ] [[package]] name = "rustc-ap-rustc_macros" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4effe366556e1d75344764adf4d54cba7c2fad33dbd07588e96d0853831ddc7c" +checksum = "61ec6d623853449acd3c65050d249d3674edab5f6e4d9f074c7bac183269f9c8" dependencies = [ "proc-macro2", "quote", @@ -3236,9 +3224,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_parse" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0342675835251571471d3dca9ea1576a853a8dfa1f4b0084db283c861223cb60" +checksum = "ca524bafce4b04d2b49fee2d40b4b26c3ebab9f1a4f731fdf561f00617862f02" dependencies = [ "bitflags", "rustc-ap-rustc_ast", @@ -3256,9 +3244,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_serialize" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "438255ed968d73bf6573aa18d3b8d33c0a85ecdfd14160ef09ff813938e0606c" +checksum = "c67920561e58f98c4de864407c92b2dd05ace5d5e5301e17444f10f742c005b7" dependencies = [ "indexmap", "smallvec 1.4.2", @@ -3266,9 +3254,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_session" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d61ff76dede8eb827f6805754900d1097a7046f938f950231b62b448f55bf78" +checksum = "0762fd855792e06ef639327237898e4e092ad68150e6a8e19aeb7dc06276ad7a" dependencies = [ "bitflags", "getopts", @@ -3287,9 +3275,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_span" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c267f15c3cfc82a8a441d2bf86bcccf299d1eb625822468e3d8ee6f7c5a1c89" +checksum = "0bf3db7b4ca5d21c14c45475df155e5e020c9a3760346945a662c9a9053b49c8" dependencies = [ "cfg-if 0.1.10", "md-5 0.8.0", @@ -3306,9 +3294,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_target" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1b4b266c4d44aac0f7f83b6741d8f0545b03d1ce32f3b5254f2014225cb96c" +checksum = "3aa6560bb9742b276064d67ab9edb5766ecb303f8ae3854835ad3fad4b432188" dependencies = [ "bitflags", "rustc-ap-rustc_data_structures", @@ -3393,6 +3381,7 @@ dependencies = [ name = "rustc-workspace-hack" version = "1.0.0" dependencies = [ + "byteorder", "crossbeam-utils 0.7.2", "proc-macro2", "quote", @@ -3523,7 +3512,7 @@ version = "0.0.0" dependencies = [ "bitflags", "libc", - "measureme 9.0.0", + "measureme", "rustc-demangle", "rustc_ast", "rustc_attr", @@ -3589,7 +3578,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme 9.0.0", + "measureme", "parking_lot 0.11.0", "rustc-hash", "rustc-rayon", @@ -3907,7 +3896,7 @@ version = "0.0.0" dependencies = [ "bitflags", "chalk-ir", - "measureme 9.0.0", + "measureme", "polonius-engine", "rustc-rayon-core", "rustc_apfloat", @@ -4340,7 +4329,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.22" +version = "1.4.24" dependencies = [ "annotate-snippets 0.6.1", "anyhow", @@ -5263,7 +5252,7 @@ dependencies = [ "chrono", "lazy_static", "matchers", - "parking_lot 0.11.0", + "parking_lot 0.9.0", "regex", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index c27e5c469cf..e1a36d88086 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,11 +29,17 @@ members = [ "src/tools/unicode-table-generator", "src/tools/expand-yaml-anchors", ] + exclude = [ "build", "compiler/rustc_codegen_cranelift", # HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`. "obj", + # The `x` binary is a thin wrapper that calls `x.py`, which initializes + # submodules, before which workspace members cannot be invoked because + # not all `Cargo.toml` files are available, so we exclude the `x` binary, + # so it can be invoked before the current checkout is set up. + "src/tools/x", ] [profile.release.package.compiler_builtins] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index fe9ad58c9ac..7b85d28568b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -210,11 +210,8 @@ pub trait MutVisitor: Sized { noop_visit_local(l, self); } - fn visit_mac(&mut self, _mac: &mut MacCall) { - panic!("visit_mac disabled by default"); - // N.B., see note about macros above. If you really want a visitor that - // works on macros, use this definition in your trait impl: - // mut_visit::noop_visit_mac(_mac, self); + fn visit_mac_call(&mut self, mac: &mut MacCall) { + noop_visit_mac(mac, self); } fn visit_macro_def(&mut self, def: &mut MacroDef) { @@ -461,7 +458,7 @@ pub fn noop_visit_ty_constraint<T: MutVisitor>( } pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { - let Ty { id, kind, span, tokens: _ } = ty.deref_mut(); + let Ty { id, kind, span, tokens } = ty.deref_mut(); vis.visit_id(id); match kind { TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never | TyKind::CVarArgs => {} @@ -494,9 +491,10 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { vis.visit_id(id); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } - TyKind::MacCall(mac) => vis.visit_mac(mac), + TyKind::MacCall(mac) => vis.visit_mac_call(mac), } vis.visit_span(span); + visit_lazy_tts(tokens, vis); } pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) { @@ -523,13 +521,14 @@ pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: vis.visit_span(span); } -pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens: _ }: &mut Path, vis: &mut T) { +pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) { vis.visit_span(span); for PathSegment { ident, id, args } in segments { vis.visit_ident(ident); vis.visit_id(id); visit_opt(args, |args| vis.visit_generic_args(args)); } + visit_lazy_tts(tokens, vis); } pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) { @@ -587,15 +586,17 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { } pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { - let Attribute { kind, id: _, style: _, span, tokens: _ } = attr; + let Attribute { kind, id: _, style: _, span, tokens } = attr; match kind { - AttrKind::Normal(AttrItem { path, args, tokens: _ }) => { + AttrKind::Normal(AttrItem { path, args, tokens }) => { vis.visit_path(path); visit_mac_args(args, vis); + visit_lazy_tts(tokens, vis); } AttrKind::DocComment(..) => {} } vis.visit_span(span); + visit_lazy_tts(tokens, vis); } pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { @@ -652,12 +653,22 @@ pub fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) { // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) { - if vis.token_visiting_enabled() { + if vis.token_visiting_enabled() && !tts.is_empty() { let tts = Lrc::make_mut(tts); visit_vec(tts, |(tree, _is_joint)| visit_tt(tree, vis)); } } +pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) { + if vis.token_visiting_enabled() { + visit_opt(lazy_tts, |lazy_tts| { + let mut tts = lazy_tts.create_token_stream(); + visit_tts(&mut tts, vis); + *lazy_tts = LazyTokenStream::new(tts); + }) + } +} + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. // Applies ident visitor if it's an ident; applies other visits to interpolated nodes. // In practice the ident part is not actually used by specific visitors right now, @@ -725,9 +736,10 @@ pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut token::NtLifetime(ident) => vis.visit_ident(ident), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { - let AttrItem { path, args, tokens: _ } = item.deref_mut(); + let AttrItem { path, args, tokens } = item.deref_mut(); vis.visit_path(path); visit_mac_args(args, vis); + visit_lazy_tts(tokens, vis); } token::NtPath(path) => vis.visit_path(path), token::NtTT(tt) => visit_tt(tt, vis), @@ -887,10 +899,11 @@ pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mu } pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) { - let Block { id, stmts, rules: _, span, tokens: _ } = block.deref_mut(); + let Block { id, stmts, rules: _, span, tokens } = block.deref_mut(); vis.visit_id(id); stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); vis.visit_span(span); + visit_lazy_tts(tokens, vis); } pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { @@ -946,7 +959,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { vis.visit_generics(generics); visit_bounds(bounds, vis); } - ItemKind::MacCall(m) => vis.visit_mac(m), + ItemKind::MacCall(m) => vis.visit_mac_call(m), ItemKind::MacroDef(def) => vis.visit_macro_def(def), } } @@ -955,7 +968,7 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>( mut item: P<AssocItem>, visitor: &mut T, ) -> SmallVec<[P<AssocItem>; 1]> { - let Item { id, ident, vis, attrs, kind, span, tokens: _ } = item.deref_mut(); + let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut(); visitor.visit_id(id); visitor.visit_ident(ident); visitor.visit_vis(vis); @@ -975,9 +988,10 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>( visit_bounds(bounds, visitor); visit_opt(ty, |ty| visitor.visit_ty(ty)); } - AssocItemKind::MacCall(mac) => visitor.visit_mac(mac), + AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), } visitor.visit_span(span); + visit_lazy_tts(tokens, visitor); smallvec![item] } @@ -1028,16 +1042,14 @@ pub fn noop_flat_map_item<T: MutVisitor>( mut item: P<Item>, visitor: &mut T, ) -> SmallVec<[P<Item>; 1]> { - let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); + let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); visitor.visit_ident(ident); visit_attrs(attrs, visitor); visitor.visit_id(id); visitor.visit_item_kind(kind); visitor.visit_vis(vis); visitor.visit_span(span); - - // FIXME: if `tokens` is modified with a call to `vis.visit_tts` it causes - // an ICE during resolve... odd! + visit_lazy_tts(tokens, visitor); smallvec![item] } @@ -1046,7 +1058,7 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>( mut item: P<ForeignItem>, visitor: &mut T, ) -> SmallVec<[P<ForeignItem>; 1]> { - let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); + let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); visitor.visit_id(id); visitor.visit_ident(ident); visitor.visit_vis(vis); @@ -1066,14 +1078,15 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>( visit_bounds(bounds, visitor); visit_opt(ty, |ty| visitor.visit_ty(ty)); } - ForeignItemKind::MacCall(mac) => visitor.visit_mac(mac), + ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), } visitor.visit_span(span); + visit_lazy_tts(tokens, visitor); smallvec![item] } pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { - let Pat { id, kind, span, tokens: _ } = pat.deref_mut(); + let Pat { id, kind, span, tokens } = pat.deref_mut(); vis.visit_id(id); match kind { PatKind::Wild | PatKind::Rest => {} @@ -1105,9 +1118,10 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { visit_vec(elems, |elem| vis.visit_pat(elem)) } PatKind::Paren(inner) => vis.visit_pat(inner), - PatKind::MacCall(mac) => vis.visit_mac(mac), + PatKind::MacCall(mac) => vis.visit_mac_call(mac), } vis.visit_span(span); + visit_lazy_tts(tokens, vis); } pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { @@ -1116,7 +1130,7 @@ pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonCo } pub fn noop_visit_expr<T: MutVisitor>( - Expr { kind, id, span, attrs, tokens: _ }: &mut Expr, + Expr { kind, id, span, attrs, tokens }: &mut Expr, vis: &mut T, ) { match kind { @@ -1270,7 +1284,7 @@ pub fn noop_visit_expr<T: MutVisitor>( } visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr)); } - ExprKind::MacCall(mac) => vis.visit_mac(mac), + ExprKind::MacCall(mac) => vis.visit_mac_call(mac), ExprKind::Struct(path, fields, expr) => { vis.visit_path(path); fields.flat_map_in_place(|field| vis.flat_map_field(field)); @@ -1295,6 +1309,7 @@ pub fn noop_visit_expr<T: MutVisitor>( vis.visit_id(id); vis.visit_span(span); visit_thin_attrs(attrs, vis); + visit_lazy_tts(tokens, vis); } pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> { @@ -1305,11 +1320,12 @@ pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Optio } pub fn noop_flat_map_stmt<T: MutVisitor>( - Stmt { kind, mut span, mut id, tokens }: Stmt, + Stmt { kind, mut span, mut id, mut tokens }: Stmt, vis: &mut T, ) -> SmallVec<[Stmt; 1]> { vis.visit_id(&mut id); vis.visit_span(&mut span); + visit_lazy_tts(&mut tokens, vis); noop_flat_map_stmt_kind(kind, vis) .into_iter() .map(|kind| Stmt { id, kind, span, tokens: tokens.clone() }) @@ -1331,7 +1347,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>( StmtKind::Empty => smallvec![StmtKind::Empty], StmtKind::MacCall(mut mac) => { let MacCallStmt { mac: mac_, style: _, attrs } = mac.deref_mut(); - vis.visit_mac(mac_); + vis.visit_mac_call(mac_); visit_thin_attrs(attrs, vis); smallvec![StmtKind::MacCall(mac)] } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 2ab6667ac3c..8751f09cfcb 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -176,13 +176,8 @@ pub trait Visitor<'ast>: Sized { fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { walk_lifetime(self, lifetime) } - fn visit_mac(&mut self, _mac: &'ast MacCall) { - panic!("visit_mac disabled by default"); - // N.B., see note about macros above. - // if you really want a visitor that - // works on macros, use this - // definition in your trait impl: - // visit::walk_mac(self, _mac) + fn visit_mac_call(&mut self, mac: &'ast MacCall) { + walk_mac(self, mac) } fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) { // Nothing to do @@ -346,7 +341,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); } - ItemKind::MacCall(ref mac) => visitor.visit_mac(mac), + ItemKind::MacCall(ref mac) => visitor.visit_mac_call(mac), ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), } walk_list!(visitor, visit_attribute, &item.attrs); @@ -414,7 +409,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { } TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {} - TyKind::MacCall(ref mac) => visitor.visit_mac(mac), + TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac), TyKind::Never | TyKind::CVarArgs => {} } } @@ -532,7 +527,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { PatKind::Tuple(ref elems) | PatKind::Slice(ref elems) | PatKind::Or(ref elems) => { walk_list!(visitor, visit_pat, elems); } - PatKind::MacCall(ref mac) => visitor.visit_mac(mac), + PatKind::MacCall(ref mac) => visitor.visit_mac_call(mac), } } @@ -557,7 +552,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI walk_list!(visitor, visit_ty, ty); } ForeignItemKind::MacCall(mac) => { - visitor.visit_mac(mac); + visitor.visit_mac_call(mac); } } } @@ -662,7 +657,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, walk_list!(visitor, visit_ty, ty); } AssocItemKind::MacCall(mac) => { - visitor.visit_mac(mac); + visitor.visit_mac_call(mac); } } } @@ -692,7 +687,7 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { StmtKind::Empty => {} StmtKind::MacCall(ref mac) => { let MacCallStmt { ref mac, style: _, ref attrs } = **mac; - visitor.visit_mac(mac); + visitor.visit_mac_call(mac); for attr in attrs.iter() { visitor.visit_attribute(attr); } @@ -823,7 +818,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { ExprKind::Ret(ref optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::MacCall(ref mac) => visitor.visit_mac(mac), + ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac), ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::InlineAsm(ref ia) => { for (op, _) in &ia.operands { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a6ac056b93b..1f2aba2b27e 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -9,6 +9,7 @@ use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; +use rustc_session::parse::feature_err; use rustc_span::hygiene::ForLoopLoc; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -146,7 +147,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label) } ExprKind::Assign(ref el, ref er, span) => { - hir::ExprKind::Assign(self.lower_expr(el), self.lower_expr(er), span) + self.lower_expr_assign(el, er, span, e.span) } ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp( self.lower_binop(op), @@ -840,6 +841,134 @@ impl<'hir> LoweringContext<'_, 'hir> { }) } + /// Destructure the LHS of complex assignments. + /// For instance, lower `(a, b) = t` to `{ let (lhs1, lhs2) = t; a = lhs1; b = lhs2; }`. + fn lower_expr_assign( + &mut self, + lhs: &Expr, + rhs: &Expr, + eq_sign_span: Span, + whole_span: Span, + ) -> hir::ExprKind<'hir> { + // Return early in case of an ordinary assignment. + fn is_ordinary(lhs: &Expr) -> bool { + match &lhs.kind { + ExprKind::Tup(..) => false, + ExprKind::Paren(e) => { + match e.kind { + // We special-case `(..)` for consistency with patterns. + ExprKind::Range(None, None, RangeLimits::HalfOpen) => false, + _ => is_ordinary(e), + } + } + _ => true, + } + } + if is_ordinary(lhs) { + return hir::ExprKind::Assign(self.lower_expr(lhs), self.lower_expr(rhs), eq_sign_span); + } + if !self.sess.features_untracked().destructuring_assignment { + feature_err( + &self.sess.parse_sess, + sym::destructuring_assignment, + eq_sign_span, + "destructuring assignments are unstable", + ) + .span_label(lhs.span, "cannot assign to this expression") + .emit(); + } + + let mut assignments = vec![]; + + // The LHS becomes a pattern: `(lhs1, lhs2)`. + let pat = self.destructure_assign(lhs, eq_sign_span, &mut assignments); + let rhs = self.lower_expr(rhs); + + // Introduce a `let` for destructuring: `let (lhs1, lhs2) = t`. + let destructure_let = self.stmt_let_pat( + ThinVec::new(), + whole_span, + Some(rhs), + pat, + hir::LocalSource::AssignDesugar(eq_sign_span), + ); + + // `a = lhs1; b = lhs2;`. + let stmts = self + .arena + .alloc_from_iter(std::iter::once(destructure_let).chain(assignments.into_iter())); + + // Wrap everything in a block. + hir::ExprKind::Block(&self.block_all(whole_span, stmts, None), None) + } + + /// Convert the LHS of a destructuring assignment to a pattern. + /// Each sub-assignment is recorded in `assignments`. + fn destructure_assign( + &mut self, + lhs: &Expr, + eq_sign_span: Span, + assignments: &mut Vec<hir::Stmt<'hir>>, + ) -> &'hir hir::Pat<'hir> { + match &lhs.kind { + // Tuples. + ExprKind::Tup(elements) => { + let (pats, rest) = + self.destructure_sequence(elements, "tuple", eq_sign_span, assignments); + let tuple_pat = hir::PatKind::Tuple(pats, rest.map(|r| r.0)); + return self.pat_without_dbm(lhs.span, tuple_pat); + } + ExprKind::Paren(e) => { + // We special-case `(..)` for consistency with patterns. + if let ExprKind::Range(None, None, RangeLimits::HalfOpen) = e.kind { + let tuple_pat = hir::PatKind::Tuple(&[], Some(0)); + return self.pat_without_dbm(lhs.span, tuple_pat); + } else { + return self.destructure_assign(e, eq_sign_span, assignments); + } + } + _ => {} + } + // Treat all other cases as normal lvalue. + let ident = Ident::new(sym::lhs, lhs.span); + let (pat, binding) = self.pat_ident(lhs.span, ident); + let ident = self.expr_ident(lhs.span, ident, binding); + let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, eq_sign_span); + let expr = self.expr(lhs.span, assign, ThinVec::new()); + assignments.push(self.stmt_expr(lhs.span, expr)); + pat + } + + /// Destructure a sequence of expressions occurring on the LHS of an assignment. + /// Such a sequence occurs in a tuple (struct)/slice. + /// Return a sequence of corresponding patterns, and the index and the span of `..` if it + /// exists. + /// Each sub-assignment is recorded in `assignments`. + fn destructure_sequence( + &mut self, + elements: &[AstP<Expr>], + ctx: &str, + eq_sign_span: Span, + assignments: &mut Vec<hir::Stmt<'hir>>, + ) -> (&'hir [&'hir hir::Pat<'hir>], Option<(usize, Span)>) { + let mut rest = None; + let elements = + self.arena.alloc_from_iter(elements.iter().enumerate().filter_map(|(i, e)| { + // Check for `..` pattern. + if let ExprKind::Range(None, None, RangeLimits::HalfOpen) = e.kind { + if let Some((_, prev_span)) = rest { + self.ban_extra_rest_pat(e.span, prev_span, ctx); + } else { + rest = Some((i, e.span)); + } + None + } else { + Some(self.destructure_assign(e, eq_sign_span, assignments)) + } + })); + (elements, rest) + } + /// Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`. fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> { let e1 = self.lower_expr_mut(e1); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 599599f415f..af2f96d5e62 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2531,6 +2531,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir_id, kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None), span, + default_binding_modes: true, }), hir_id, ) @@ -2541,7 +2542,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { - self.arena.alloc(hir::Pat { hir_id: self.next_id(), kind, span }) + self.arena.alloc(hir::Pat { + hir_id: self.next_id(), + kind, + span, + default_binding_modes: true, + }) + } + + fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { + self.arena.alloc(hir::Pat { + hir_id: self.next_id(), + kind, + span, + default_binding_modes: false, + }) } fn ty_path( diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index a1cbcde1f42..e4e7b24d29e 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -273,11 +273,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Construct a `Pat` with the `HirId` of `p.id` lowered. fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { - self.arena.alloc(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span }) + self.arena.alloc(hir::Pat { + hir_id: self.lower_node_id(p.id), + kind, + span: p.span, + default_binding_modes: true, + }) } /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. - fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { + crate fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { self.diagnostic() .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx)) .span_label(sp, &format!("can only be used once per {} pattern", ctx)) diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index 706dca2b7f4..6efc78c8842 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -114,9 +114,9 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_lifetime(self, lifetime) } - fn visit_mac(&mut self, _mac: &MacCall) { + fn visit_mac_call(&mut self, mac: &MacCall) { self.count += 1; - walk_mac(self, _mac) + walk_mac(self, mac) } fn visit_path(&mut self, path: &Path, _id: NodeId) { self.count += 1; diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs index 053aba86222..6cef26a13e6 100644 --- a/compiler/rustc_ast_passes/src/show_span.rs +++ b/compiler/rustc_ast_passes/src/show_span.rs @@ -54,10 +54,6 @@ impl<'a> Visitor<'a> for ShowSpanVisitor<'a> { } visit::walk_ty(self, t); } - - fn visit_mac(&mut self, mac: &'a ast::MacCall) { - visit::walk_mac(self, mac); - } } pub fn run(span_diagnostic: &rustc_errors::Handler, mode: &str, krate: &ast::Crate) { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 2e52d2a3923..0642edff6b6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -358,7 +358,7 @@ fn find_type_parameters( visit::walk_ty(self, ty) } - fn visit_mac(&mut self, mac: &ast::MacCall) { + fn visit_mac_call(&mut self, mac: &ast::MacCall) { self.cx.span_err(mac.span(), "`derive` cannot be used on items with type macros"); } } diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index c6ab3faf568..4e91436199a 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -344,10 +344,6 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { visit::walk_item(self, item); self.in_root = prev_in_root; } - - fn visit_mac(&mut self, mac: &'a ast::MacCall) { - visit::walk_mac(self, mac) - } } // Creates a new module which looks like: diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index da74f0aeaa1..e68b626e22d 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -130,10 +130,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { } smallvec![P(item)] } - - fn visit_mac(&mut self, _mac: &mut ast::MacCall) { - // Do nothing. - } } // Beware, this is duplicated in librustc_passes/entry.rs (with @@ -201,10 +197,6 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { smallvec![item] } - - fn visit_mac(&mut self, _mac: &mut ast::MacCall) { - // Do nothing. - } } /// Crawl over the crate, inserting test reexports and the test main function diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index eda77bf19d3..466758f2f86 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -361,13 +361,11 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { where T: TypeFoldable<'tcx> + Copy, { - if let Some(substs) = self.instance.substs_for_mir_body() { - self.tcx - .subst_and_normalize_erasing_regions(substs, ty::ParamEnv::reveal_all(), value) - } else { - self.tcx - .normalize_erasing_regions(ty::ParamEnv::reveal_all(), *value) - } + self.instance.subst_mir_and_normalize_erasing_regions( + self.tcx, + ty::ParamEnv::reveal_all(), + value + ) } pub(crate) fn clif_type(&self, ty: Ty<'tcx>) -> Option<Type> { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 84e82e88e8e..01fd1681593 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -92,15 +92,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { T: Copy + TypeFoldable<'tcx>, { debug!("monomorphize: self.instance={:?}", self.instance); - if let Some(substs) = self.instance.substs_for_mir_body() { - self.cx.tcx().subst_and_normalize_erasing_regions( - substs, - ty::ParamEnv::reveal_all(), - &value, - ) - } else { - self.cx.tcx().normalize_erasing_regions(ty::ParamEnv::reveal_all(), *value) - } + self.instance.subst_mir_and_normalize_erasing_regions( + self.cx.tcx(), + ty::ParamEnv::reveal_all(), + value, + ) } } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index c124ab64218..a07dd8ede8b 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -547,11 +547,6 @@ impl<'a> MutVisitor for StripUnconfigured<'a> { noop_flat_map_assoc_item(configure!(self, item), self) } - fn visit_mac(&mut self, _mac: &mut ast::MacCall) { - // Don't configure interpolated AST (cf. issue #34171). - // Interpolated AST will get configured once the surrounding tokens are parsed. - } - fn visit_pat(&mut self, pat: &mut P<ast::Pat>) { self.configure_pat(pat); noop_visit_pat(pat, self) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index f6959591b56..8c7a4f06838 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -850,8 +850,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { visit::walk_item(self, item); } - - fn visit_mac(&mut self, _: &'ast ast::MacCall) {} } if !self.cx.ecfg.proc_macro_hygiene() { diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 629e0e702b6..dde65d998d8 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -5,7 +5,6 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::token::{self, NtTT, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndSpacing}; -use rustc_ast::MacCall; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_errors::{pluralize, PResult}; @@ -27,10 +26,6 @@ impl MutVisitor for Marker { fn visit_span(&mut self, span: &mut Span) { *span = span.apply_mark(self.0, self.1) } - - fn visit_mac(&mut self, mac: &mut MacCall) { - mut_visit::noop_visit_mac(mac, self) - } } /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). diff --git a/compiler/rustc_expand/src/mut_visit/tests.rs b/compiler/rustc_expand/src/mut_visit/tests.rs index 9e65fc2eca7..be0300bad98 100644 --- a/compiler/rustc_expand/src/mut_visit/tests.rs +++ b/compiler/rustc_expand/src/mut_visit/tests.rs @@ -1,7 +1,7 @@ use crate::tests::{matches_codepattern, string_to_crate}; use rustc_ast as ast; -use rustc_ast::mut_visit::{self, MutVisitor}; +use rustc_ast::mut_visit::MutVisitor; use rustc_ast_pretty::pprust; use rustc_span::symbol::Ident; use rustc_span::with_default_session_globals; @@ -21,9 +21,6 @@ impl MutVisitor for ToZzIdentMutVisitor { fn visit_ident(&mut self, ident: &mut Ident) { *ident = Ident::from_str("zz"); } - fn visit_mac(&mut self, mac: &mut ast::MacCall) { - mut_visit::noop_visit_mac(mac, self) - } } // Maybe add to `expand.rs`. diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 0cffca17271..f0e5826f403 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -313,25 +313,24 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { // Implement the proposal described in // https://github.com/rust-lang/rust/issues/61733#issuecomment-509626449 // - // The macro invocation expands to the list of statements. - // If the list of statements is empty, then 'parse' - // the trailing semicolon on the original invocation - // as an empty statement. That is: + // The macro invocation expands to the list of statements. If the + // list of statements is empty, then 'parse' the trailing semicolon + // on the original invocation as an empty statement. That is: // // `empty();` is parsed as a single `StmtKind::Empty` // - // If the list of statements is non-empty, see if the - // final statement alreayd has a trailing semicolon. + // If the list of statements is non-empty, see if the final + // statement already has a trailing semicolon. // - // If it doesn't have a semicolon, then 'parse' the trailing semicolon - // from the invocation as part of the final statement, + // If it doesn't have a semicolon, then 'parse' the trailing + // semicolon from the invocation as part of the final statement, // using `stmt.add_trailing_semicolon()` // // If it does have a semicolon, then 'parse' the trailing semicolon // from the invocation as a new StmtKind::Empty - // FIXME: We will need to preserve the original - // semicolon token and span as part of #15701 + // FIXME: We will need to preserve the original semicolon token and + // span as part of #15701 let empty_stmt = ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Empty, @@ -386,8 +385,4 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { |item| !matches!(item.kind, ast::ItemKind::MacCall(_) if !self.cx.ecfg.keep_macs), ); } - - fn visit_mac(&mut self, _mac: &mut ast::MacCall) { - // Do nothing. - } } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index ad926a810e6..0df67b63eba 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -610,6 +610,12 @@ declare_features! ( /// Allows unsized fn parameters. (active, unsized_fn_params, "1.49.0", Some(48055), None), + /// Allows the use of destructuring assignments. + (active, destructuring_assignment, "1.49.0", Some(71126), None), + + /// Enables `#[cfg(panic = "...")]` config key. + (active, cfg_panic, "1.49.0", Some(77443), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 57ae534590d..5c5cf609ac3 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -33,6 +33,7 @@ const GATED_CFGS: &[GatedCfg] = &[ ), (sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)), (sym::version, sym::cfg_version, cfg_fn!(cfg_version)), + (sym::panic, sym::cfg_panic, cfg_fn!(cfg_panic)), ]; /// Find a gated cfg determined by the `pred`icate which is given the cfg's name. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index b9ec18688c5..3c28b48795f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -732,6 +732,9 @@ pub struct Pat<'hir> { pub hir_id: HirId, pub kind: PatKind<'hir>, pub span: Span, + // Whether to use default binding modes. + // At present, this is false only for destructuring assignment. + pub default_binding_modes: bool, } impl Pat<'_> { @@ -1680,6 +1683,9 @@ pub enum LocalSource { AsyncFn, /// A desugared `<expr>.await`. AwaitDesugar, + /// A desugared `expr = expr`, where the LHS is a tuple, struct or array. + /// The span is that of the `=` sign. + AssignDesugar(Span), } /// Hints at the original code for a `match _ { .. }`. @@ -2677,6 +2683,9 @@ impl<'hir> Node<'hir> { Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) | Node::ForeignItem(ForeignItem { ident, .. }) + | Node::Field(StructField { ident, .. }) + | Node::Variant(Variant { ident, .. }) + | Node::MacroDef(MacroDef { ident, .. }) | Node::Item(Item { ident, .. }) => Some(*ident), _ => None, } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 3ed7d20ae45..d9ec6d51cdf 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -880,12 +880,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { }) } } - - // in general the pretty printer processes unexpanded code, so - // we override the default `visit_mac` method which panics. - fn visit_mac(&mut self, mac: &mut ast::MacCall) { - noop_visit_mac(mac, self) - } } /// Returns a version string such as "rustc 1.46.0 (04488afe3 2020-08-24)" diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 9aeeb627792..08c147ec3ac 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -270,15 +270,9 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> self.check_id(id); } - fn visit_mac(&mut self, mac: &'a ast::MacCall) { - // FIXME(#54110): So, this setup isn't really right. I think - // that (a) the librustc_ast visitor ought to be doing this as - // part of `walk_mac`, and (b) we should be calling - // `visit_path`, *but* that would require a `NodeId`, and I - // want to get #53686 fixed quickly. -nmatsakis - ast_visit::walk_path(self, &mac.path); - + fn visit_mac_call(&mut self, mac: &'a ast::MacCall) { run_early_pass!(self, check_mac, mac); + ast_visit::walk_mac(self, mac); } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index ff7a145c266..1d0d6980b7a 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2801,6 +2801,7 @@ declare_lint_pass! { UNSTABLE_NAME_COLLISIONS, IRREFUTABLE_LET_PATTERNS, BROKEN_INTRA_DOC_LINKS, + PRIVATE_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_CRATE_LEVEL_DOCS, MISSING_DOC_CODE_EXAMPLES, diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index b16e22e8d77..8fa6e6a7101 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -16,9 +16,8 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: }) }); - let body_visit = s.fold(quote!(), |acc, bind| { + let body_visit = s.each(|bind| { quote! { - #acc ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?; } }); diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 66532ea02f3..3250f1830de 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,7 +26,7 @@ rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.32.0" +chalk-ir = "0.36.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "9.0.0" rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 106fa8c78fa..d86e8987195 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -478,7 +478,7 @@ impl<'hir> Map<'hir> { } pub fn get_if_local(&self, id: DefId) -> Option<Node<'hir>> { - id.as_local().map(|id| self.get(self.local_def_id_to_hir_id(id))) + id.as_local().and_then(|id| self.find(self.local_def_id_to_hir_id(id))) } pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> { diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index def9e5ebb52..41342764ba7 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -48,10 +48,12 @@ fn update_limit( .unwrap_or(attr.span); let error_str = match e.kind() { - IntErrorKind::Overflow => "`limit` is too large", + IntErrorKind::PosOverflow => "`limit` is too large", IntErrorKind::Empty => "`limit` must be a non-negative integer", IntErrorKind::InvalidDigit => "not a valid integer", - IntErrorKind::Underflow => bug!("`limit` should never underflow"), + IntErrorKind::NegOverflow => { + bug!("`limit` should never negatively overflow") + } IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), }; diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs index d8507d08c1b..f864ad8ebcd 100644 --- a/compiler/rustc_middle/src/traits/chalk.rs +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -102,48 +102,6 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { Some(write()) } - fn debug_application_ty( - application_ty: &chalk_ir::ApplicationTy<Self>, - fmt: &mut fmt::Formatter<'_>, - ) -> Option<fmt::Result> { - match application_ty.name { - chalk_ir::TypeName::Ref(mutbl) => { - let data = application_ty.substitution.interned(); - match (&**data[0].interned(), &**data[1].interned()) { - ( - chalk_ir::GenericArgData::Lifetime(lifetime), - chalk_ir::GenericArgData::Ty(ty), - ) => Some(match mutbl { - chalk_ir::Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty), - chalk_ir::Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty), - }), - _ => unreachable!(), - } - } - chalk_ir::TypeName::Array => { - let data = application_ty.substitution.interned(); - match (&**data[0].interned(), &**data[1].interned()) { - (chalk_ir::GenericArgData::Ty(ty), chalk_ir::GenericArgData::Const(len)) => { - Some(write!(fmt, "[{:?}; {:?}]", ty, len)) - } - _ => unreachable!(), - } - } - chalk_ir::TypeName::Slice => { - let data = application_ty.substitution.interned(); - let ty = match &**data[0].interned() { - chalk_ir::GenericArgData::Ty(t) => t, - _ => unreachable!(), - }; - Some(write!(fmt, "[{:?}]", ty)) - } - _ => { - let chalk_ir::ApplicationTy { name, substitution } = application_ty; - Some(write!(fmt, "{:?}{:?}", name, chalk_ir::debug::Angle(substitution.interned()))) - } - } - } - fn debug_substitution( substitution: &chalk_ir::Substitution<Self>, fmt: &mut fmt::Formatter<'_>, @@ -174,6 +132,32 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { Some(write!(fmt, "{:?}", clauses.interned())) } + fn debug_ty(ty: &chalk_ir::Ty<Self>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { + match &ty.interned().kind { + chalk_ir::TyKind::Ref(chalk_ir::Mutability::Not, lifetime, ty) => { + Some(write!(fmt, "(&{:?} {:?})", lifetime, ty)) + } + chalk_ir::TyKind::Ref(chalk_ir::Mutability::Mut, lifetime, ty) => { + Some(write!(fmt, "(&{:?} mut {:?})", lifetime, ty)) + } + chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)), + chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)), + chalk_ir::TyKind::Tuple(len, substs) => Some((|| { + write!(fmt, "(")?; + for (idx, substitution) in substs.interned().iter().enumerate() { + if idx == *len && *len != 1 { + // Don't add a trailing comma if the tuple has more than one element + write!(fmt, "{:?}", substitution)?; + } else { + write!(fmt, "{:?},", substitution)?; + } + } + write!(fmt, ")") + })()), + _ => None, + } + } + fn debug_alias( alias_ty: &chalk_ir::AliasTy<Self>, fmt: &mut fmt::Formatter<'_>, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8b3fb875070..306cebd9cb7 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,6 +1,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::subst::InternalSubsts; +use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable}; use rustc_errors::ErrorReported; use rustc_hir::def::Namespace; @@ -470,10 +470,33 @@ impl<'tcx> Instance<'tcx> { /// This function returns `Some(substs)` in the former case and `None` otherwise -- i.e., if /// this function returns `None`, then the MIR body does not require substitution during /// codegen. - pub fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> { + fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> { if self.def.has_polymorphic_mir_body() { Some(self.substs) } else { None } } + pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T + where + T: TypeFoldable<'tcx> + Copy, + { + if let Some(substs) = self.substs_for_mir_body() { v.subst(tcx, substs) } else { *v } + } + + pub fn subst_mir_and_normalize_erasing_regions<T>( + &self, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + v: &T, + ) -> T + where + T: TypeFoldable<'tcx> + Clone, + { + if let Some(substs) = self.substs_for_mir_body() { + tcx.subst_and_normalize_erasing_regions(substs, param_env, v) + } else { + tcx.normalize_erasing_regions(param_env, v.clone()) + } + } + /// Returns a new `Instance` where generic parameters in `instance.substs` are replaced by /// identify parameters if they are determined to be unused in `instance.def`. pub fn polymorphize(self, tcx: TyCtxt<'tcx>) -> Self { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index aa5a696b09c..0042b4a3a42 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2795,10 +2795,50 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) } + fn item_name_from_hir(self, def_id: DefId) -> Option<Ident> { + self.hir().get_if_local(def_id).and_then(|node| node.ident()) + } + + fn item_name_from_def_id(self, def_id: DefId) -> Option<Symbol> { + if def_id.index == CRATE_DEF_INDEX { + Some(self.original_crate_name(def_id.krate)) + } else { + let def_key = self.def_key(def_id); + match def_key.disambiguated_data.data { + // The name of a constructor is that of its parent. + rustc_hir::definitions::DefPathData::Ctor => self.item_name_from_def_id(DefId { + krate: def_id.krate, + index: def_key.parent.unwrap(), + }), + _ => def_key.disambiguated_data.data.get_opt_name(), + } + } + } + + /// Look up the name of an item across crates. This does not look at HIR. + /// + /// When possible, this function should be used for cross-crate lookups over + /// [`opt_item_name`] to avoid invalidating the incremental cache. If you + /// need to handle items without a name, or HIR items that will not be + /// serialized cross-crate, or if you need the span of the item, use + /// [`opt_item_name`] instead. + /// + /// [`opt_item_name`]: Self::opt_item_name + pub fn item_name(self, id: DefId) -> Symbol { + // Look at cross-crate items first to avoid invalidating the incremental cache + // unless we have to. + self.item_name_from_def_id(id).unwrap_or_else(|| { + bug!("item_name: no name for {:?}", self.def_path(id)); + }) + } + + /// Look up the name and span of an item or [`Node`]. + /// + /// See [`item_name`][Self::item_name] for more information. pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> { - def_id - .as_local() - .and_then(|def_id| self.hir().get(self.hir().local_def_id_to_hir_id(def_id)).ident()) + // Look at the HIR first so the span will be correct if this is a local item. + self.item_name_from_hir(def_id) + .or_else(|| self.item_name_from_def_id(def_id).map(Ident::with_dummy_span)) } pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> { @@ -2921,23 +2961,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn item_name(self, id: DefId) -> Symbol { - if id.index == CRATE_DEF_INDEX { - self.original_crate_name(id.krate) - } else { - let def_key = self.def_key(id); - match def_key.disambiguated_data.data { - // The name of a constructor is that of its parent. - rustc_hir::definitions::DefPathData::Ctor => { - self.item_name(DefId { krate: id.krate, index: def_key.parent.unwrap() }) - } - _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { - bug!("item_name: no name for {:?}", self.def_path(id)); - }), - } - } - } - /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { match instance { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 8ff4adda606..1e4fd0921ee 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -63,7 +63,7 @@ thread_local! { /// Avoids running any queries during any prints that occur /// during the closure. This may alter the appearance of some /// types (e.g. forcing verbose printing for opaque types). -/// This method is used during some queries (e.g. `predicates_of` +/// This method is used during some queries (e.g. `explicit_item_bounds` /// for opaque types), to ensure that any debug printing that /// occurs during the query computation does not end up recursively /// calling the same query. diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index 2e5a231fef0..2a90fb042dd 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs @@ -6,8 +6,8 @@ use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, RegionVid, Ty}; -use rustc_span::symbol::kw; -use rustc_span::{symbol::Symbol, Span, DUMMY_SP}; +use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::{Span, DUMMY_SP}; use crate::borrow_check::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; @@ -39,7 +39,7 @@ crate enum RegionNameSource { /// The region corresponding to a closure upvar. AnonRegionFromUpvar(Span, String), /// The region corresponding to the return type of a closure. - AnonRegionFromOutput(Span, String, String), + AnonRegionFromOutput(RegionNameHighlight, String), /// The region from a type yielded by a generator. AnonRegionFromYieldTy(Span, String), /// An anonymous region from an async fn. @@ -57,6 +57,10 @@ crate enum RegionNameHighlight { /// The anonymous region corresponds to a region where the type annotation is completely missing /// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference. CannotMatchHirTy(Span, String), + /// The anonymous region corresponds to a region where the type annotation is completely missing + /// from the code, and *even if* we print out the full name of the type, the region name won't + /// be included. This currently occurs for opaque types like `impl Future`. + Occluded(Span, String), } impl RegionName { @@ -81,13 +85,14 @@ impl RegionName { | RegionNameSource::NamedFreeRegion(span) | RegionNameSource::SynthesizedFreeEnvRegion(span, _) | RegionNameSource::AnonRegionFromUpvar(span, _) - | RegionNameSource::AnonRegionFromOutput(span, _, _) | RegionNameSource::AnonRegionFromYieldTy(span, _) | RegionNameSource::AnonRegionFromAsyncFn(span) => Some(span), - RegionNameSource::AnonRegionFromArgument(ref highlight) => match *highlight { + RegionNameSource::AnonRegionFromArgument(ref highlight) + | RegionNameSource::AnonRegionFromOutput(ref highlight, _) => match *highlight { RegionNameHighlight::MatchedHirTy(span) | RegionNameHighlight::MatchedAdtAndSegment(span) - | RegionNameHighlight::CannotMatchHirTy(span, _) => Some(span), + | RegionNameHighlight::CannotMatchHirTy(span, _) + | RegionNameHighlight::Occluded(span, _) => Some(span), }, } } @@ -112,6 +117,7 @@ impl RegionName { diag.span_label(*span, format!("has type `{}`", type_name)); } RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::MatchedHirTy(span)) + | RegionNameSource::AnonRegionFromOutput(RegionNameHighlight::MatchedHirTy(span), _) | RegionNameSource::AnonRegionFromAsyncFn(span) => { diag.span_label( *span, @@ -120,16 +126,44 @@ impl RegionName { } RegionNameSource::AnonRegionFromArgument( RegionNameHighlight::MatchedAdtAndSegment(span), + ) + | RegionNameSource::AnonRegionFromOutput( + RegionNameHighlight::MatchedAdtAndSegment(span), + _, ) => { diag.span_label(*span, format!("let's call this `{}`", self)); } + RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::Occluded( + span, + type_name, + )) => { + diag.span_label( + *span, + format!("lifetime `{}` appears in the type {}", self, type_name), + ); + } + RegionNameSource::AnonRegionFromOutput( + RegionNameHighlight::Occluded(span, type_name), + mir_description, + ) => { + diag.span_label( + *span, + format!( + "return type{} `{}` contains a lifetime `{}`", + mir_description, type_name, self + ), + ); + } RegionNameSource::AnonRegionFromUpvar(span, upvar_name) => { diag.span_label( *span, format!("lifetime `{}` appears in the type of `{}`", self, upvar_name), ); } - RegionNameSource::AnonRegionFromOutput(span, mir_description, type_name) => { + RegionNameSource::AnonRegionFromOutput( + RegionNameHighlight::CannotMatchHirTy(span, type_name), + mir_description, + ) => { diag.span_label(*span, format!("return type{} is {}", mir_description, type_name)); } RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { @@ -349,19 +383,21 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { argument_index, ); - self.get_argument_hir_ty_for_highlighting(argument_index) + let highlight = self + .get_argument_hir_ty_for_highlighting(argument_index) .and_then(|arg_hir_ty| self.highlight_if_we_can_match_hir_ty(fr, arg_ty, arg_hir_ty)) - .or_else(|| { + .unwrap_or_else(|| { // `highlight_if_we_cannot_match_hir_ty` needs to know the number we will give to // the anonymous region. If it succeeds, the `synthesize_region_name` call below // will increment the counter, "reserving" the number we just used. let counter = *self.next_region_name.try_borrow().unwrap(); self.highlight_if_we_cannot_match_hir_ty(fr, arg_ty, span, counter) - }) - .map(|highlight| RegionName { - name: self.synthesize_region_name(), - source: RegionNameSource::AnonRegionFromArgument(highlight), - }) + }); + + Some(RegionName { + name: self.synthesize_region_name(), + source: RegionNameSource::AnonRegionFromArgument(highlight), + }) } fn get_argument_hir_ty_for_highlighting( @@ -399,7 +435,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ty: Ty<'tcx>, span: Span, counter: usize, - ) -> Option<RegionNameHighlight> { + ) -> RegionNameHighlight { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(needle_fr, counter); let type_name = @@ -411,9 +447,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ); if type_name.find(&format!("'{}", counter)).is_some() { // Only add a label if we can confirm that a region was labelled. - Some(RegionNameHighlight::CannotMatchHirTy(span, type_name)) + RegionNameHighlight::CannotMatchHirTy(span, type_name) } else { - None + RegionNameHighlight::Occluded(span, type_name) } } @@ -643,6 +679,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// or be early bound (named, not in argument). fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option<RegionName> { let tcx = self.infcx.tcx; + let hir = tcx.hir(); let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); @@ -650,42 +687,123 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { return None; } - let mut highlight = RegionHighlightMode::default(); - highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); - let type_name = - self.infcx.extract_inference_diagnostics_data(return_ty.into(), Some(highlight)).name; + let mir_hir_id = self.mir_hir_id(); - let (return_span, mir_description) = match tcx.hir().get(self.mir_hir_id()) { + let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_, return_ty, _, span, gen_move), - .. - }) => ( - match return_ty.output { - hir::FnRetTy::DefaultReturn(_) => tcx.sess.source_map().end_point(*span), - hir::FnRetTy::Return(_) => return_ty.output.span(), - }, - if gen_move.is_some() { " of generator" } else { " of closure" }, - ), - hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(method_sig, _), + kind: hir::ExprKind::Closure(_, return_ty, body_id, span, _), .. - }) => (method_sig.decl.output.span(), ""), - _ => (self.body.span, ""), + }) => { + let (mut span, mut hir_ty) = match return_ty.output { + hir::FnRetTy::DefaultReturn(_) => { + (tcx.sess.source_map().end_point(*span), None) + } + hir::FnRetTy::Return(hir_ty) => (return_ty.output.span(), Some(hir_ty)), + }; + let mir_description = match hir.body(*body_id).generator_kind { + Some(hir::GeneratorKind::Async(gen)) => match gen { + hir::AsyncGeneratorKind::Block => " of async block", + hir::AsyncGeneratorKind::Closure => " of async closure", + hir::AsyncGeneratorKind::Fn => { + let parent_item = hir.get(hir.get_parent_item(mir_hir_id)); + let output = &parent_item + .fn_decl() + .expect("generator lowered from async fn should be in fn") + .output; + span = output.span(); + if let hir::FnRetTy::Return(ret) = output { + hir_ty = Some(self.get_future_inner_return_ty(*ret)); + } + " of async function" + } + }, + Some(hir::GeneratorKind::Gen) => " of generator", + None => " of closure", + }; + (span, mir_description, hir_ty) + } + node => match node.fn_decl() { + Some(fn_decl) => { + let hir_ty = match fn_decl.output { + hir::FnRetTy::DefaultReturn(_) => None, + hir::FnRetTy::Return(ty) => Some(ty), + }; + (fn_decl.output.span(), "", hir_ty) + } + None => (self.body.span, "", None), + }, }; + let highlight = hir_ty + .and_then(|hir_ty| self.highlight_if_we_can_match_hir_ty(fr, return_ty, hir_ty)) + .unwrap_or_else(|| { + // `highlight_if_we_cannot_match_hir_ty` needs to know the number we will give to + // the anonymous region. If it succeeds, the `synthesize_region_name` call below + // will increment the counter, "reserving" the number we just used. + let counter = *self.next_region_name.try_borrow().unwrap(); + self.highlight_if_we_cannot_match_hir_ty(fr, return_ty, return_span, counter) + }); + Some(RegionName { - // This counter value will already have been used, so this function will increment it - // so the next value will be used next and return the region name that would have been - // used. name: self.synthesize_region_name(), - source: RegionNameSource::AnonRegionFromOutput( - return_span, - mir_description.to_string(), - type_name, - ), + source: RegionNameSource::AnonRegionFromOutput(highlight, mir_description.to_string()), }) } + /// From the [`hir::Ty`] of an async function's lowered return type, + /// retrieve the `hir::Ty` representing the type the user originally wrote. + /// + /// e.g. given the function: + /// + /// ``` + /// async fn foo() -> i32 {} + /// ``` + /// + /// this function, given the lowered return type of `foo`, an [`OpaqueDef`] that implements `Future<Output=i32>`, + /// returns the `i32`. + /// + /// [`OpaqueDef`]: hir::TyKind::OpaqueDef + fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> { + let hir = self.infcx.tcx.hir(); + + if let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind { + let opaque_ty = hir.item(id.id); + if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { + bounds: + [hir::GenericBound::LangItemTrait( + hir::LangItem::Future, + _, + _, + hir::GenericArgs { + bindings: + [hir::TypeBinding { + ident: Ident { name: sym::Output, .. }, + kind: hir::TypeBindingKind::Equality { ty }, + .. + }], + .. + }, + )], + .. + }) = opaque_ty.kind + { + ty + } else { + span_bug!( + hir_ty.span, + "bounds from lowered return type of async fn did not match expected format: {:?}", + opaque_ty + ); + } + } else { + span_bug!( + hir_ty.span, + "lowered return type of async fn is not OpaqueDef: {:?}", + hir_ty + ); + } + } + fn give_name_if_anonymous_region_appears_in_yield_ty( &self, fr: RegionVid, diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 8d0c8c18537..0f86a181a55 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -505,11 +505,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, value: T, ) -> T { - if let Some(substs) = frame.instance.substs_for_mir_body() { - self.tcx.subst_and_normalize_erasing_regions(substs, self.param_env, &value) - } else { - self.tcx.normalize_erasing_regions(self.param_env, value) - } + frame.instance.subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, &value) } /// The `substs` are assumed to already be in our interpreter "universe" (param_env). diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 417176564b9..938181abff2 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -543,11 +543,11 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> { T: TypeFoldable<'tcx>, { debug!("monomorphize: self.instance={:?}", self.instance); - if let Some(substs) = self.instance.substs_for_mir_body() { - self.tcx.subst_and_normalize_erasing_regions(substs, ty::ParamEnv::reveal_all(), &value) - } else { - self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), value) - } + self.instance.subst_mir_and_normalize_erasing_regions( + self.tcx, + ty::ParamEnv::reveal_all(), + &value, + ) } } diff --git a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs index fb89b36060a..a8457043278 100644 --- a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs +++ b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs @@ -61,22 +61,35 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { fn lint_const_item_usage( &self, + place: &Place<'tcx>, const_item: DefId, location: Location, decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b>, ) { - let source_info = self.body.source_info(location); - let lint_root = self.body.source_scopes[source_info.scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root; + // Don't lint on borrowing/assigning to a dereference + // e.g: + // + // `unsafe { *FOO = 0; *BAR.field = 1; }` + // `unsafe { &mut *FOO }` + if !matches!(place.projection.last(), Some(PlaceElem::Deref)) { + let source_info = self.body.source_info(location); + let lint_root = self.body.source_scopes[source_info.scope] + .local_data + .as_ref() + .assert_crate_local() + .lint_root; - self.tcx.struct_span_lint_hir(CONST_ITEM_MUTATION, lint_root, source_info.span, |lint| { - decorate(lint) - .span_note(self.tcx.def_span(const_item), "`const` item defined here") - .emit() - }); + self.tcx.struct_span_lint_hir( + CONST_ITEM_MUTATION, + lint_root, + source_info.span, + |lint| { + decorate(lint) + .span_note(self.tcx.def_span(const_item), "`const` item defined here") + .emit() + }, + ); + } } } @@ -88,15 +101,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { // so emitting a lint would be redundant. if !lhs.projection.is_empty() { if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) { - // Don't lint on writes through a pointer - // (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`) - if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) { - self.lint_const_item_usage(def_id, loc, |lint| { - let mut lint = lint.build("attempting to modify a `const` item"); - lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified"); - lint - }) - } + self.lint_const_item_usage(&lhs, def_id, loc, |lint| { + let mut lint = lint.build("attempting to modify a `const` item"); + lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified"); + lint + }) } } // We are looking for MIR of the form: @@ -127,7 +136,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; - self.lint_const_item_usage(def_id, lint_loc, |lint| { + self.lint_const_item_usage(place, def_id, lint_loc, |lint| { let mut lint = lint.build("taking a mutable reference to a `const` item"); lint .note("each usage of a `const` item creates a new temporary") diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index cc697dfd7fe..ffa795134e2 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -147,8 +147,8 @@ impl DebugOptions { let mut counter_format = ExpressionFormat::default(); if let Ok(env_debug_options) = std::env::var(RUSTC_COVERAGE_DEBUG_OPTIONS) { - for setting_str in env_debug_options.replace(" ", "").replace("-", "_").split(",") { - let mut setting = setting_str.splitn(2, "="); + for setting_str in env_debug_options.replace(" ", "").replace("-", "_").split(',') { + let mut setting = setting_str.splitn(2, '='); match setting.next() { Some(option) if option == "allow_unused_expressions" => { allow_unused_expressions = bool_option_val(option, setting.next()); @@ -210,7 +210,7 @@ fn bool_option_val(option: &str, some_strval: Option<&str>) -> bool { fn counter_format_option_val(strval: &str) -> ExpressionFormat { let mut counter_format = ExpressionFormat { id: false, block: false, operation: false }; - let components = strval.splitn(3, "+"); + let components = strval.splitn(3, '+'); for component in components { match component { "id" => counter_format.id = true, @@ -695,7 +695,7 @@ pub(crate) fn dump_coverage_graphviz( let from_bcb_data = &basic_coverage_blocks[from_bcb]; let from_terminator = from_bcb_data.terminator(mir_body); let mut edge_labels = from_terminator.kind.fmt_successor_labels(); - edge_labels.retain(|label| label.to_string() != "unreachable"); + edge_labels.retain(|label| label != "unreachable"); let edge_counters = from_terminator .successors() .map(|&successor_bb| graphviz_data.get_edge_counter(from_bcb, successor_bb)); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 4de93739992..97b51344526 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -1,21 +1,20 @@ //! Inlining pass for MIR functions use rustc_attr as attr; +use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_span::{hygiene::ExpnKind, ExpnData, Span}; use rustc_target::spec::abi::Abi; use super::simplify::{remove_dead_blocks, CfgSimplifier}; use crate::transform::MirPass; -use std::collections::VecDeque; use std::iter; -use std::ops::RangeFrom; +use std::ops::{Range, RangeFrom}; const DEFAULT_THRESHOLD: usize = 50; const HINT_THRESHOLD: usize = 100; @@ -38,134 +37,128 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { - if tcx.sess.opts.debugging_opts.instrument_coverage { - // The current implementation of source code coverage injects code region counters - // into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code- - // based function. - debug!("function inlining is disabled when compiling with `instrument_coverage`"); - } else { - Inliner { - tcx, - param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()), - codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()), - } - .run_pass(body); - } + if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { + return; + } + + if tcx.sess.opts.debugging_opts.instrument_coverage { + // The current implementation of source code coverage injects code region counters + // into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code- + // based function. + debug!("function inlining is disabled when compiling with `instrument_coverage`"); + return; + } + + if inline(tcx, body) { + debug!("running simplify cfg on {:?}", body.source); + CfgSimplifier::new(body).simplify(); + remove_dead_blocks(body); } } } +fn inline(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { + let def_id = body.source.def_id(); + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + + // Only do inlining into fn bodies. + if !tcx.hir().body_owner_kind(hir_id).is_fn_or_closure() { + return false; + } + if body.source.promoted.is_some() { + return false; + } + + let mut this = Inliner { + tcx, + param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()), + codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()), + hir_id, + history: Vec::new(), + changed: false, + }; + let blocks = BasicBlock::new(0)..body.basic_blocks().next_index(); + this.process_blocks(body, blocks); + this.changed +} + struct Inliner<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, + /// Caller codegen attributes. codegen_fn_attrs: &'tcx CodegenFnAttrs, + /// Caller HirID. + hir_id: hir::HirId, + /// Stack of inlined instances. + history: Vec<Instance<'tcx>>, + /// Indicates that the caller body has been modified. + changed: bool, } impl Inliner<'tcx> { - fn run_pass(&self, caller_body: &mut Body<'tcx>) { - // Keep a queue of callsites to try inlining on. We take - // advantage of the fact that queries detect cycles here to - // allow us to try and fetch the fully optimized MIR of a - // call; if it succeeds, we can inline it and we know that - // they do not call us. Otherwise, we just don't try to - // inline. - // - // We use a queue so that we inline "broadly" before we inline - // in depth. It is unclear if this is the best heuristic, - // really, but that's true of all the heuristics in this - // file. =) - - let mut callsites = VecDeque::new(); - - let def_id = caller_body.source.def_id(); - - // Only do inlining into fn bodies. - let self_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - if self.tcx.hir().body_owner_kind(self_hir_id).is_fn_or_closure() - && caller_body.source.promoted.is_none() - { - for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated() { - if let Some(callsite) = self.get_valid_function_call(bb, bb_data, caller_body) { - callsites.push_back(callsite); - } + fn process_blocks(&mut self, caller_body: &mut Body<'tcx>, blocks: Range<BasicBlock>) { + for bb in blocks { + let callsite = match self.get_valid_function_call(bb, &caller_body[bb], caller_body) { + None => continue, + Some(it) => it, + }; + + if !self.is_mir_available(&callsite.callee, caller_body) { + debug!("MIR unavailable {}", callsite.callee); + continue; } - } else { - return; - } - let mut changed = false; - while let Some(callsite) = callsites.pop_front() { - debug!("checking whether to inline callsite {:?}", callsite); + let callee_body = self.tcx.instance_mir(callsite.callee.def); + if !self.should_inline(callsite, callee_body) { + continue; + } - if let InstanceDef::Item(_) = callsite.callee.def { - if !self.tcx.is_mir_available(callsite.callee.def_id()) { - debug!("checking whether to inline callsite {:?} - MIR unavailable", callsite,); - continue; - } + if !self.tcx.consider_optimizing(|| { + format!("Inline {:?} into {}", callee_body.span, callsite.callee) + }) { + return; } - let callee_body = if let Some(callee_def_id) = callsite.callee.def_id().as_local() { - let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id); - // Avoid a cycle here by only using `instance_mir` only if we have - // a lower `HirId` than the callee. This ensures that the callee will - // not inline us. This trick only works without incremental compilation. - // So don't do it if that is enabled. Also avoid inlining into generators, - // since their `optimized_mir` is used for layout computation, which can - // create a cycle, even when no attempt is made to inline the function - // in the other direction. - if !self.tcx.dep_graph.is_fully_enabled() - && self_hir_id < callee_hir_id - && caller_body.generator_kind.is_none() - { - self.tcx.instance_mir(callsite.callee.def) - } else { - continue; - } - } else { - // This cannot result in a cycle since the callee MIR is from another crate - // and is already optimized. - self.tcx.instance_mir(callsite.callee.def) - }; + let callee_body = callsite.callee.subst_mir_and_normalize_erasing_regions( + self.tcx, + self.param_env, + callee_body, + ); - let callee_body: &Body<'tcx> = &*callee_body; + let old_blocks = caller_body.basic_blocks().next_index(); + self.inline_call(callsite, caller_body, callee_body); + let new_blocks = old_blocks..caller_body.basic_blocks().next_index(); + self.changed = true; - let callee_body = if self.consider_optimizing(callsite, callee_body) { - self.tcx.subst_and_normalize_erasing_regions( - &callsite.callee.substs, - self.param_env, - callee_body, - ) - } else { - continue; - }; + self.history.push(callsite.callee); + self.process_blocks(caller_body, new_blocks); + self.history.pop(); + } + } - let start = caller_body.basic_blocks().len(); - debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body); - if !self.inline_call(callsite, caller_body, callee_body) { - debug!("attempting to inline callsite {:?} - failure", callsite); - continue; - } - debug!("attempting to inline callsite {:?} - success", callsite); - - // Add callsites from inlined function - for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) { - if let Some(new_callsite) = self.get_valid_function_call(bb, bb_data, caller_body) { - // Don't inline the same function multiple times. - if callsite.callee != new_callsite.callee { - callsites.push_back(new_callsite); - } - } + fn is_mir_available(&self, callee: &Instance<'tcx>, caller_body: &Body<'tcx>) -> bool { + if let InstanceDef::Item(_) = callee.def { + if !self.tcx.is_mir_available(callee.def_id()) { + return false; } - - changed = true; } - // Simplify if we inlined anything. - if changed { - debug!("running simplify cfg on {:?}", caller_body.source); - CfgSimplifier::new(caller_body).simplify(); - remove_dead_blocks(caller_body); + if let Some(callee_def_id) = callee.def_id().as_local() { + let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id); + // Avoid a cycle here by only using `instance_mir` only if we have + // a lower `HirId` than the callee. This ensures that the callee will + // not inline us. This trick only works without incremental compilation. + // So don't do it if that is enabled. Also avoid inlining into generators, + // since their `optimized_mir` is used for layout computation, which can + // create a cycle, even when no attempt is made to inline the function + // in the other direction. + !self.tcx.dep_graph.is_fully_enabled() + && self.hir_id < callee_hir_id + && caller_body.generator_kind.is_none() + } else { + // This cannot result in a cycle since the callee MIR is from another crate + // and is already optimized. + true } } @@ -182,7 +175,8 @@ impl Inliner<'tcx> { // Only consider direct calls to functions let terminator = bb_data.terminator(); - if let TerminatorKind::Call { func: ref op, .. } = terminator.kind { + // FIXME: Handle inlining of diverging calls + if let TerminatorKind::Call { func: ref op, destination: Some(_), .. } = terminator.kind { if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() { // To resolve an instance its substs have to be fully normalized, so // we do this here. @@ -203,14 +197,6 @@ impl Inliner<'tcx> { None } - fn consider_optimizing(&self, callsite: CallSite<'tcx>, callee_body: &Body<'tcx>) -> bool { - debug!("consider_optimizing({:?})", callsite); - self.should_inline(callsite, callee_body) - && self.tcx.consider_optimizing(|| { - format!("Inline {:?} into {:?}", callee_body.span, callsite) - }) - } - fn should_inline(&self, callsite: CallSite<'tcx>, callee_body: &Body<'tcx>) -> bool { debug!("should_inline({:?})", callsite); let tcx = self.tcx; @@ -309,7 +295,7 @@ impl Inliner<'tcx> { work_list.push(target); // If the place doesn't actually need dropping, treat it like // a regular goto. - let ty = place.ty(callee_body, tcx).subst(tcx, callsite.callee.substs).ty; + let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty); if ty.needs_drop(tcx, self.param_env) { cost += CALL_PENALTY; if let Some(unwind) = unwind { @@ -330,7 +316,18 @@ impl Inliner<'tcx> { } TerminatorKind::Call { func: Operand::Constant(ref f), cleanup, .. } => { - if let ty::FnDef(def_id, _) = *f.literal.ty.kind() { + if let ty::FnDef(def_id, substs) = + *callsite.callee.subst_mir(self.tcx, &f.literal.ty).kind() + { + let substs = self.tcx.normalize_erasing_regions(self.param_env, substs); + if let Ok(Some(instance)) = + Instance::resolve(self.tcx, self.param_env, def_id, substs) + { + if callsite.callee == instance || self.history.contains(&instance) { + debug!("`callee is recursive - not inlining"); + return false; + } + } // Don't give intrinsics the extra penalty for calls let f = tcx.fn_sig(def_id); if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic { @@ -371,8 +368,7 @@ impl Inliner<'tcx> { let ptr_size = tcx.data_layout.pointer_size.bytes(); for v in callee_body.vars_and_temps_iter() { - let v = &callee_body.local_decls[v]; - let ty = v.ty.subst(tcx, callsite.callee.substs); + let ty = callsite.callee.subst_mir(self.tcx, &callee_body.local_decls[v].ty); // Cost of the var is the size in machine-words, if we know // it. if let Some(size) = type_size_of(tcx, self.param_env, ty) { @@ -401,13 +397,10 @@ impl Inliner<'tcx> { callsite: CallSite<'tcx>, caller_body: &mut Body<'tcx>, mut callee_body: Body<'tcx>, - ) -> bool { + ) { let terminator = caller_body[callsite.bb].terminator.take().unwrap(); match terminator.kind { - // FIXME: Handle inlining of diverging calls TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => { - debug!("inlined {:?} into {:?}", callsite.callee, caller_body.source); - // If the call is something like `a[*i] = f(i)`, where // `i : &mut usize`, then just duplicating the `a[*i]` // Place could result in two different locations if `f` @@ -425,7 +418,7 @@ impl Inliner<'tcx> { } let dest = if dest_needs_borrow(destination.0) { - debug!("creating temp for return destination"); + trace!("creating temp for return destination"); let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, @@ -523,14 +516,8 @@ impl Inliner<'tcx> { matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _)) }), ); - - true - } - kind => { - caller_body[callsite.bb].terminator = - Some(Terminator { source_info: terminator.source_info, kind }); - false } + kind => bug!("unexpected terminator kind {:?}", kind), } } @@ -633,7 +620,7 @@ impl Inliner<'tcx> { } } - debug!("creating temp for argument {:?}", arg); + trace!("creating temp for argument {:?}", arg); // Otherwise, create a temporary for the arg let arg = Rvalue::Use(arg); @@ -703,19 +690,19 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { Local::new(self.new_locals.start.index() + (idx - self.args.len())) } }; - debug!("mapping local `{:?}` to `{:?}`", local, new); + trace!("mapping local `{:?}` to `{:?}`", local, new); new } fn map_scope(&self, scope: SourceScope) -> SourceScope { let new = SourceScope::new(self.new_scopes.start.index() + scope.index()); - debug!("mapping scope `{:?}` to `{:?}`", scope, new); + trace!("mapping scope `{:?}` to `{:?}`", scope, new); new } fn map_block(&self, block: BasicBlock) -> BasicBlock { let new = BasicBlock::new(self.new_blocks.start.index() + block.index()); - debug!("mapping block `{:?}` to `{:?}`", block, new); + trace!("mapping block `{:?}` to `{:?}`", block, new); new } } diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs index 1868d3b47f2..e1e6e71acb5 100644 --- a/compiler/rustc_mir/src/transform/validate.rs +++ b/compiler/rustc_mir/src/transform/validate.rs @@ -6,6 +6,7 @@ use crate::util::storage::AlwaysLiveLocals; use super::MirPass; use rustc_index::bit_set::BitSet; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::traversal; use rustc_middle::mir::visit::{PlaceContext, Visitor}; @@ -13,8 +14,8 @@ use rustc_middle::mir::{ AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef, Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo, }; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::fold::BottomUpFolder; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_target::abi::Size; #[derive(Copy, Clone, Debug)] @@ -77,79 +78,27 @@ pub fn equal_up_to_regions( return true; } - struct LifetimeIgnoreRelation<'tcx> { - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - } - - impl TypeRelation<'tcx> for LifetimeIgnoreRelation<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env - } - - fn tag(&self) -> &'static str { - "librustc_mir::transform::validate" - } - - fn a_is_expected(&self) -> bool { - true - } - - fn relate_with_variance<T: Relate<'tcx>>( - &mut self, - _: ty::Variance, - a: T, - b: T, - ) -> RelateResult<'tcx, T> { - // Ignore variance, require types to be exactly the same. - self.relate(a, b) - } - - fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - if a == b { - // Short-circuit. - return Ok(a); - } - ty::relate::super_relate_tys(self, a, b) - } - - fn regions( - &mut self, - a: ty::Region<'tcx>, - _b: ty::Region<'tcx>, - ) -> RelateResult<'tcx, ty::Region<'tcx>> { - // Ignore regions. - Ok(a) - } - - fn consts( - &mut self, - a: &'tcx ty::Const<'tcx>, - b: &'tcx ty::Const<'tcx>, - ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - ty::relate::super_relate_consts(self, a, b) - } - - fn binders<T>( - &mut self, - a: ty::Binder<T>, - b: ty::Binder<T>, - ) -> RelateResult<'tcx, ty::Binder<T>> - where - T: Relate<'tcx>, - { - self.relate(a.skip_binder(), b.skip_binder())?; - Ok(a) - } - } - - // Instantiate and run relation. - let mut relator: LifetimeIgnoreRelation<'tcx> = LifetimeIgnoreRelation { tcx: tcx, param_env }; - relator.relate(src, dest).is_ok() + // Normalize lifetimes away on both sides, then compare. + let param_env = param_env.with_reveal_all_normalized(tcx); + let normalize = |ty: Ty<'tcx>| { + tcx.normalize_erasing_regions( + param_env, + ty.fold_with(&mut BottomUpFolder { + tcx, + // FIXME: We erase all late-bound lifetimes, but this is not fully correct. + // If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`, + // this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`, + // since one may have an `impl SomeTrait for fn(&32)` and + // `impl SomeTrait for fn(&'static u32)` at the same time which + // specify distinct values for Assoc. (See also #56105) + lt_op: |_| tcx.lifetimes.re_erased, + // Leave consts and types unchanged. + ct_op: |ct| ct, + ty_op: |ty| ty, + }), + ) + }; + tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok()) } struct TypeChecker<'a, 'tcx> { diff --git a/compiler/rustc_mir/src/util/generic_graphviz.rs b/compiler/rustc_mir/src/util/generic_graphviz.rs index 91499bb61c2..8bd4a512bbb 100644 --- a/compiler/rustc_mir/src/util/generic_graphviz.rs +++ b/compiler/rustc_mir/src/util/generic_graphviz.rs @@ -174,7 +174,7 @@ impl< where W: Write, { - let lines = label.split("\n").map(|s| dot::escape_html(s)).collect::<Vec<_>>(); + let lines = label.split('\n').map(|s| dot::escape_html(s)).collect::<Vec<_>>(); let escaped_label = lines.join(r#"<br align="left"/>"#); writeln!(w, r#" label=<<br/><br/>{}<br align="left"/><br/><br/><br/>>;"#, escaped_label) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 205ad850c0c..14ed93f1127 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -69,6 +69,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { hir::LocalSource::ForLoopDesugar => ("`for` loop binding", None), hir::LocalSource::AsyncFn => ("async fn binding", None), hir::LocalSource::AwaitDesugar => ("`await` future binding", None), + hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None), }; self.check_irrefutable(&loc.pat, msg, sp); self.check_patterns(&loc.pat); diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 196790a0ab3..ee9a6dca5ad 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1,6 +1,6 @@ use super::{Parser, PathStyle}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; -use rustc_ast::mut_visit::{noop_visit_mac, noop_visit_pat, MutVisitor}; +use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::{self as ast, AttrVec, Attribute, FieldPat, MacCall, Pat, PatKind, RangeEnd}; @@ -570,10 +570,6 @@ impl<'a> Parser<'a> { fn make_all_value_bindings_mutable(pat: &mut P<Pat>) -> bool { struct AddMut(bool); impl MutVisitor for AddMut { - fn visit_mac(&mut self, mac: &mut MacCall) { - noop_visit_mac(mac, self); - } - fn visit_pat(&mut self, pat: &mut P<Pat>) { if let PatKind::Ident(BindingMode::ByValue(m @ Mutability::Not), ..) = &mut pat.kind { diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 9537321026e..1d02c9aa637 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -336,8 +336,9 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_lifetime(self, lifetime) } - fn visit_mac(&mut self, mac: &'v ast::MacCall) { + fn visit_mac_call(&mut self, mac: &'v ast::MacCall) { self.record("MacCall", Id::None, mac); + ast_visit::walk_mac(self, mac) } fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v ast::PathSegment) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 4e115c62c9e..5c7a7c1d0ae 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1021,17 +1021,11 @@ impl<'a> Resolver<'a> { ("", "") }; - let article = if built_in.is_empty() { res.article() } else { "a" }; - format!( - "{a}{built_in} {thing}{from}", - a = article, - thing = res.descr(), - built_in = built_in, - from = from - ) + let a = if built_in.is_empty() { res.article() } else { "a" }; + format!("{a}{built_in} {thing}{from}", thing = res.descr()) } else { let introduced = if b.is_import() { "imported" } else { "defined" }; - format!("the {thing} {introduced} here", thing = res.descr(), introduced = introduced) + format!("the {thing} {introduced} here", thing = res.descr()) } } @@ -1049,19 +1043,13 @@ impl<'a> Resolver<'a> { ident.span, E0659, "`{ident}` is ambiguous ({why})", - ident = ident, why = kind.descr() ); err.span_label(ident.span, "ambiguous name"); let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); - let note_msg = format!( - "`{ident}` could{also} refer to {what}", - ident = ident, - also = also, - what = what - ); + let note_msg = format!("`{ident}` could{also} refer to {what}"); let thing = b.res().descr(); let mut help_msgs = Vec::new(); @@ -1071,30 +1059,18 @@ impl<'a> Resolver<'a> { || kind == AmbiguityKind::GlobVsOuter && swapped != also.is_empty()) { help_msgs.push(format!( - "consider adding an explicit import of \ - `{ident}` to disambiguate", - ident = ident + "consider adding an explicit import of `{ident}` to disambiguate" )) } if b.is_extern_crate() && ident.span.rust_2018() { - help_msgs.push(format!( - "use `::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) + help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously")) } if misc == AmbiguityErrorMisc::SuggestCrate { - help_msgs.push(format!( - "use `crate::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) + help_msgs + .push(format!("use `crate::{ident}` to refer to this {thing} unambiguously")) } else if misc == AmbiguityErrorMisc::SuggestSelf { - help_msgs.push(format!( - "use `self::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) + help_msgs + .push(format!("use `self::{ident}` to refer to this {thing} unambiguously")) } err.span_note(b.span, ¬e_msg); @@ -1167,12 +1143,10 @@ impl<'a> Resolver<'a> { }; let first = ptr::eq(binding, first_binding); - let descr = get_descr(binding); let msg = format!( "{and_refers_to}the {item} `{name}`{which} is defined here{dots}", and_refers_to = if first { "" } else { "...and refers to " }, - item = descr, - name = name, + item = get_descr(binding), which = if first { "" } else { " which" }, dots = if next_binding.is_some() { "..." } else { "" }, ); diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 269d25be0a5..026cf8be738 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -872,6 +872,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> { let orig_vis = import.vis.replace(ty::Visibility::Invisible); + let orig_unusable_binding = match &import.kind { + ImportKind::Single { target_bindings, .. } => { + Some(mem::replace(&mut self.r.unusable_binding, target_bindings[TypeNS].get())) + } + _ => None, + }; let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); let path_res = self.r.resolve_path( &import.module_path, @@ -882,6 +888,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> { import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; + if let Some(orig_unusable_binding) = orig_unusable_binding { + self.r.unusable_binding = orig_unusable_binding; + } import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics. @@ -892,8 +901,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // Consistency checks, analogous to `finalize_macro_resolutions`. if let Some(initial_module) = import.imported_module.get() { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { - let msg = "inconsistent resolution for an import"; - self.r.session.span_err(import.span, msg); + span_bug!(import.span, "inconsistent resolution for an import"); } } else if self.r.privacy_errors.is_empty() { let msg = "cannot determine resolution for the import"; @@ -913,6 +921,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => { if no_ambiguity { + assert!(import.imported_module.get().is_none()); let err = match self.make_path_suggestion( span, import.module_path.clone(), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 14f8c7b09f8..00e6d5ca381 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -865,7 +865,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, &format!("use struct {} syntax instead", descr), - format!("{} {{{pad}{}{pad}}}", path_str, fields, pad = pad), + format!("{path_str} {{{pad}{fields}{pad}}}"), applicability, ); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 30cd9944b1a..f1e30470f8e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -11,6 +11,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] +#![feature(format_args_capture)] #![feature(nll)] #![feature(or_patterns)] #![recursion_limit = "256"] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b632bfbed30..ab694ad4c5a 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -793,6 +793,9 @@ pub fn default_configuration(sess: &Session) -> CrateConfig { } } + let panic_strategy = sess.panic_strategy(); + ret.insert((sym::panic, Some(panic_strategy.desc_symbol()))); + for s in sess.opts.debugging_opts.sanitizer { let symbol = Symbol::intern(&s.to_string()); ret.insert((sym::sanitize, Some(symbol))); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1a6c45b6c80..ad58f89d87d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -326,6 +326,7 @@ symbols! { cfg_attr, cfg_attr_multi, cfg_doctest, + cfg_panic, cfg_sanitize, cfg_target_feature, cfg_target_has_atomic, @@ -434,6 +435,7 @@ symbols! { deref_mut, deref_target, derive, + destructuring_assignment, diagnostic, direct, discriminant_kind, diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index c15bd9a08fc..098651614d0 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { - let mut base = super::apple_base::opts(); + let mut base = super::apple_base::opts("macos"); base.cpu = "apple-a12".to_string(); base.max_atomic_width = Some(128); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]); @@ -16,15 +16,9 @@ pub fn target() -> Target { Target { llvm_target, - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), arch: arch.to_string(), - target_os: "macos".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "\u{1}mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index 0019fc4492d..2218c6c6da7 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs @@ -1,19 +1,13 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::Arm64); + let base = opts("ios", Arch::Arm64); Target { llvm_target: "arm64-apple-ios".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "ios".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".to_string(), eliminate_frame_pointer: false, diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index 276682c591d..a83de77dc2a 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs @@ -1,19 +1,13 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::Arm64); + let base = opts("tvos", Arch::Arm64); Target { llvm_target: "arm64-apple-tvos".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "tvos".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".to_string(), eliminate_frame_pointer: false, diff --git a/compiler/rustc_target/src/spec/aarch64_fuchsia.rs b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs index 1f81a03c4a5..1252741f979 100644 --- a/compiler/rustc_target/src/spec/aarch64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-fuchsia".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "fuchsia".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs index 1ed4f0da79c..fa6108df206 100644 --- a/compiler/rustc_target/src/spec/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a // for target ABI requirements. @@ -11,15 +11,9 @@ pub fn target() -> Target { base.features = "+neon,+fp-armv8".to_string(); Target { llvm_target: "aarch64-linux-android".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "android".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs index 32fa2d69540..1369d9d0798 100644 --- a/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::windows_msvc_base::opts(); @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "pc".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: base, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs index f9d62519bd9..67f69b40e55 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::cloudabi_base::opts(); @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-cloudabi".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "cloudabi".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs index 3d008290240..d48389d4a35 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-freebsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "freebsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs index a7050cbee9e..44beb2f6ad8 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::hermit_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-hermit".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "hermit".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: base, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs index 10255012e41..9d9698a440d 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_env: "gnu".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "linux".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), target_mcount: "\u{1}_mcount".to_string(), diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs index f530163faf7..2dd703b66ff 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_env: "musl".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "linux".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), target_mcount: "\u{1}_mcount".to_string(), diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs index dcb157d7aab..81e383ca5f1 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); @@ -7,15 +7,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-netbsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "netbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "__mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs index 6d3e72906d5..1088807f2c2 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs @@ -10,6 +10,8 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp pub fn target() -> Target { let opts = TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_owned()), features: "+strict-align,+neon,+fp-armv8".to_string(), executables: true, @@ -23,15 +25,9 @@ pub fn target() -> Target { }; Target { llvm_target: "aarch64-unknown-none".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs index 784cd7eb3c9..044c9fa1de8 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs @@ -10,6 +10,8 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp pub fn target() -> Target { let opts = TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_owned()), features: "+strict-align,-neon,-fp-armv8".to_string(), executables: true, @@ -23,15 +25,9 @@ pub fn target() -> Target { }; Target { llvm_target: "aarch64-unknown-none".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs index e03690e86b8..83ba1ecd1d3 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); @@ -7,15 +7,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-openbsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "openbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs index 13adec9d4c4..b9c9325831d 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::redox_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-redox".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "redox".to_string(), - target_env: "relibc".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs index d6af5dd3628..e0a81df2b0d 100644 --- a/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::windows_uwp_msvc_base::opts(); @@ -7,15 +7,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "uwp".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: base, } } diff --git a/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs index 6fce200a96e..beb8ce30cc9 100644 --- a/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); @@ -6,15 +6,9 @@ pub fn target() -> Target { Target { llvm_target: "aarch64-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index 0824bc30358..1bd5eb6988c 100644 --- a/compiler/rustc_target/src/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs @@ -2,6 +2,7 @@ use crate::spec::{LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); + base.target_os = "android".to_string(); // Many of the symbols defined in compiler-rt are also defined in libgcc. // Android's linker doesn't like that by default. base.pre_link_args diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 2e3c835c0e5..045d9967f30 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -2,7 +2,7 @@ use std::env; use crate::spec::{LinkArgs, TargetOptions}; -pub fn opts() -> TargetOptions { +pub fn opts(os: &str) -> TargetOptions { // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 // either the linker will complain if it is used or the binary will end up // segfaulting at runtime when run on 10.6. Rust by default supports macOS @@ -17,6 +17,8 @@ pub fn opts() -> TargetOptions { let version = macos_deployment_target(); TargetOptions { + target_os: os.to_string(), + target_vendor: "apple".to_string(), // macOS has -dead_strip, which doesn't rely on function_sections function_sections: false, dynamic_linking: true, diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index 1b17c2c278f..092401f1146 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -31,7 +31,7 @@ fn link_env_remove(arch: Arch) -> Vec<String> { } } -pub fn opts(arch: Arch) -> TargetOptions { +pub fn opts(os: &str, arch: Arch) -> TargetOptions { TargetOptions { cpu: target_cpu(arch), dynamic_linking: false, @@ -39,6 +39,6 @@ pub fn opts(arch: Arch) -> TargetOptions { link_env_remove: link_env_remove(arch), has_elf_tls: false, eliminate_frame_pointer: false, - ..super::apple_base::opts() + ..super::apple_base::opts(os) } } diff --git a/compiler/rustc_target/src/spec/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs index f9c69217460..43537569e7d 100644 --- a/compiler/rustc_target/src/spec/arm_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::android_base::opts(); @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { llvm_target: "arm-linux-androideabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "android".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs index 96a444fc465..dca0b1ec2e4 100644 --- a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs @@ -1,19 +1,13 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_base::opts(); base.max_atomic_width = Some(64); Target { llvm_target: "arm-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+strict-align,+v6".to_string(), diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs index 534b98cc607..ee71ae61972 100644 --- a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs @@ -1,19 +1,13 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_base::opts(); base.max_atomic_width = Some(64); Target { llvm_target: "arm-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+strict-align,+v6,+vfp2,-d32".to_string(), diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs index e5fa3e3a1cb..6938a043602 100644 --- a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -12,15 +12,9 @@ pub fn target() -> Target { // to determine the calling convention and float ABI, and it doesn't // support the "musleabi" value. llvm_target: "arm-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), target_mcount: "\u{1}mcount".to_string(), diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs index b631a0010a0..4adf3a33893 100644 --- a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -12,15 +12,9 @@ pub fn target() -> Target { // uses it to determine the calling convention and float ABI, and it // doesn't support the "musleabihf" value. llvm_target: "arm-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), target_mcount: "\u{1}mcount".to_string(), diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs index 86d0cd57af3..7bfa5baecb5 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs @@ -6,17 +6,14 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "armebv7r-unknown-none-eabi".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: "".to_string(), - target_vendor: "".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + target_endian: "big".to_string(), + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, linker: Some("rust-lld".to_owned()), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs index 9ea44b3b25e..7afc933a28f 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs @@ -6,17 +6,14 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "armebv7r-unknown-none-eabihf".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + target_endian: "big".to_string(), + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, linker: Some("rust-lld".to_owned()), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs index be32731a869..c58fa7407b4 100644 --- a/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs @@ -1,18 +1,12 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::linux_base::opts(); Target { llvm_target: "armv4t-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+soft-float,+strict-align".to_string(), diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs index 4ea4b650623..049a031398a 100644 --- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs @@ -1,18 +1,12 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::linux_base::opts(); Target { llvm_target: "armv5te-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+soft-float,+strict-align".to_string(), diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs index a41a5409ac9..77cf8bb76d3 100644 --- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::linux_musl_base::opts(); @@ -7,15 +7,9 @@ pub fn target() -> Target { // uses it to determine the calling convention and float ABI, and LLVM // doesn't support the "musleabihf" value. llvm_target: "armv5te-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+soft-float,+strict-align".to_string(), diff --git a/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs index 68f6502133a..981d615f684 100644 --- a/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs @@ -1,20 +1,15 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::freebsd_base::opts(); Target { llvm_target: "armv6-unknown-freebsd-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "freebsd".to_string(), - target_env: "gnueabihf".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_env: "gnueabihf".to_string(), features: "+v6,+vfp2,-d32".to_string(), max_atomic_width: Some(64), unsupported_abis: super::arm_base::unsupported_abis(), diff --git a/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs index 23a20ca1c9f..8417a8f2801 100644 --- a/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs @@ -1,21 +1,16 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.max_atomic_width = Some(64); Target { llvm_target: "armv6-unknown-netbsdelf-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "netbsd".to_string(), - target_env: "eabihf".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_env: "eabihf".to_string(), features: "+v6,+vfp2,-d32".to_string(), unsupported_abis: super::arm_base::unsupported_abis(), target_mcount: "__mcount".to_string(), diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs index 24a47dd56a9..051a394657c 100644 --- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs @@ -1,19 +1,13 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::Armv7); + let base = opts("ios", Arch::Armv7); Target { llvm_target: "armv7-apple-ios".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(), arch: "arm".to_string(), - target_os: "ios".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v7,+vfp3,+neon".to_string(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs index 342959883cb..9aa378a8018 100644 --- a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs @@ -16,15 +16,9 @@ pub fn target() -> Target { Target { llvm_target: "armv7-none-linux-android".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "android".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs index d4bb4e963fb..921640d0aa6 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::cloudabi_base::opts(); @@ -10,15 +10,9 @@ pub fn target() -> Target { Target { llvm_target: "armv7-unknown-cloudabi-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "cloudabi".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "\u{1}mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs index c32e2d4376e..88d5c86cfab 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs @@ -1,20 +1,15 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::freebsd_base::opts(); Target { llvm_target: "armv7-unknown-freebsd-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "freebsd".to_string(), - target_env: "gnueabihf".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_env: "gnueabihf".to_string(), features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), max_atomic_width: Some(64), unsupported_abis: super::arm_base::unsupported_abis(), diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs index 66d3b3e5d07..2a31bf4e332 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // This target is for glibc Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -7,15 +7,9 @@ pub fn target() -> Target { let base = super::linux_base::opts(); Target { llvm_target: "armv7-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v7,+thumb2,+soft-float,-neon".to_string(), diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs index c1ef540a01d..d04400b79df 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // This target is for glibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -7,15 +7,9 @@ pub fn target() -> Target { let base = super::linux_base::opts(); Target { llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs index d4d26b14556..ebbbd61fc11 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // This target is for musl Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -12,15 +12,9 @@ pub fn target() -> Target { // to determine the calling convention and float ABI, and it doesn't // support the "musleabi" value. llvm_target: "armv7-unknown-linux-gnueabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v7,+thumb2,+soft-float,-neon".to_string(), diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs index 88db04a74e2..ee603aa0684 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // This target is for musl Linux on ARMv7 without thumb-mode or NEON. @@ -9,15 +9,9 @@ pub fn target() -> Target { // uses it to determine the calling convention and float ABI, and LLVM // doesn't support the "musleabihf" value. llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, // Most of these settings are copied from the armv7_unknown_linux_gnueabihf // target. diff --git a/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs index fe2471ab0d0..09c531ebc8a 100644 --- a/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs @@ -1,20 +1,15 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::netbsd_base::opts(); Target { llvm_target: "armv7-unknown-netbsdelf-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "netbsd".to_string(), - target_env: "eabihf".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_env: "eabihf".to_string(), features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), cpu: "generic".to_string(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs index 9b8cefdfa9e..6a43054067f 100644 --- a/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs @@ -1,18 +1,12 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let base = super::vxworks_base::opts(); Target { llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs index 4199ac4569a..b6b34e27562 100644 --- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs @@ -21,6 +21,8 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp pub fn target() -> Target { let opts = TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_owned()), features: "+v7,+thumb2,+soft-float,-neon,+strict-align".to_string(), executables: true, @@ -34,15 +36,9 @@ pub fn target() -> Target { }; Target { llvm_target: "armv7a-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, } } diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs index 99a06590097..8b9df361844 100644 --- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs @@ -9,6 +9,8 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp pub fn target() -> Target { let opts = TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_owned()), features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".to_string(), executables: true, @@ -22,15 +24,9 @@ pub fn target() -> Target { }; Target { llvm_target: "armv7a-none-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, } } diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs index f0e79072bc1..fdd74d27619 100644 --- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs @@ -6,17 +6,13 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "armv7r-unknown-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: "".to_string(), - target_vendor: "".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, linker: Some("rust-lld".to_owned()), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs index 4c464d2b256..7baafea90b9 100644 --- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs @@ -6,17 +6,13 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "armv7r-unknown-none-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: "".to_string(), - target_vendor: "".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, linker: Some("rust-lld".to_owned()), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs index 4c2d70ae34b..be74136a2d6 100644 --- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs @@ -1,19 +1,13 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::Armv7s); + let base = opts("ios", Arch::Armv7s); Target { llvm_target: "armv7s-apple-ios".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(), arch: "arm".to_string(), - target_os: "ios".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v7,+vfp4,+neon".to_string(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index 01445dc3898..268af87cfe9 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -8,14 +8,10 @@ pub fn target(target_cpu: String) -> Target { arch: "avr".to_string(), data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".to_string(), llvm_target: "avr-unknown-unknown".to_string(), - target_endian: "little".to_string(), pointer_width: 16, - linker_flavor: LinkerFlavor::Gcc, - target_os: "unknown".to_string(), - target_env: "".to_string(), - target_vendor: "unknown".to_string(), - target_c_int_width: 16.to_string(), options: TargetOptions { + target_c_int_width: "16".to_string(), + target_os: "unknown".to_string(), cpu: target_cpu.clone(), exe_suffix: ".elf".to_string(), diff --git a/compiler/rustc_target/src/spec/cloudabi_base.rs b/compiler/rustc_target/src/spec/cloudabi_base.rs index 39039435f58..0053adb8552 100644 --- a/compiler/rustc_target/src/spec/cloudabi_base.rs +++ b/compiler/rustc_target/src/spec/cloudabi_base.rs @@ -12,6 +12,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "cloudabi".to_string(), executables: true, target_family: None, linker_is_gnu: true, diff --git a/compiler/rustc_target/src/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs index 82dc5f54659..a182e37dd80 100644 --- a/compiler/rustc_target/src/spec/dragonfly_base.rs +++ b/compiler/rustc_target/src/spec/dragonfly_base.rs @@ -16,6 +16,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "dragonfly".to_string(), dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index 051325a8df6..25535117743 100644 --- a/compiler/rustc_target/src/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs @@ -16,6 +16,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "freebsd".to_string(), dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), diff --git a/compiler/rustc_target/src/spec/fuchsia_base.rs b/compiler/rustc_target/src/spec/fuchsia_base.rs index 6f432dc1171..97998eed886 100644 --- a/compiler/rustc_target/src/spec/fuchsia_base.rs +++ b/compiler/rustc_target/src/spec/fuchsia_base.rs @@ -20,6 +20,9 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "fuchsia".to_string(), + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_owned()), lld_flavor: LldFlavor::Ld, dynamic_linking: true, diff --git a/compiler/rustc_target/src/spec/haiku_base.rs b/compiler/rustc_target/src/spec/haiku_base.rs index 3d7ae6c302d..3d9dd44e786 100644 --- a/compiler/rustc_target/src/spec/haiku_base.rs +++ b/compiler/rustc_target/src/spec/haiku_base.rs @@ -2,6 +2,7 @@ use crate::spec::{RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { + target_os: "haiku".to_string(), dynamic_linking: true, executables: true, has_rpath: false, diff --git a/compiler/rustc_target/src/spec/hermit_base.rs b/compiler/rustc_target/src/spec/hermit_base.rs index e063c94cf2c..2953646afd0 100644 --- a/compiler/rustc_target/src/spec/hermit_base.rs +++ b/compiler/rustc_target/src/spec/hermit_base.rs @@ -9,6 +9,8 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "hermit".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_owned()), executables: true, has_elf_tls: true, diff --git a/compiler/rustc_target/src/spec/hermit_kernel_base.rs b/compiler/rustc_target/src/spec/hermit_kernel_base.rs index 01b9f75637f..7d06cbd62f5 100644 --- a/compiler/rustc_target/src/spec/hermit_kernel_base.rs +++ b/compiler/rustc_target/src/spec/hermit_kernel_base.rs @@ -9,6 +9,8 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "hermit".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), disable_redzone: true, linker: Some("rust-lld".to_owned()), executables: true, diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs index 143b93dfeef..73d5e2057f9 100644 --- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkArgs, LinkerFlavor, Target}; +use crate::spec::{LinkArgs, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -19,9 +19,7 @@ pub fn target() -> Target { Target { llvm_target: "hexagon-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: concat!( "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32", ":32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32", @@ -30,10 +28,6 @@ pub fn target() -> Target { ) .to_string(), arch: "hexagon".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index 21421497965..302306ee579 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -1,21 +1,15 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::I386); + let base = opts("ios", Arch::I386); Target { llvm_target: "i386-apple-ios".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:128-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "ios".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, } } diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 9c7e7241b57..ac295aa3587 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { - let mut base = super::apple_base::opts(); + let mut base = super::apple_base::opts("macos"); base.cpu = "yonah".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); @@ -17,17 +17,11 @@ pub fn target() -> Target { Target { llvm_target, - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:128-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "macos".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "\u{1}mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs index d116ae62e0f..52059b930d1 100644 --- a/compiler/rustc_target/src/spec/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/i686_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; // See https://developer.android.com/ndk/guides/abis.html#x86 // for target ABI requirements. @@ -15,17 +15,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-linux-android".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "android".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs index 84585bd515a..4979a5b3bc8 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs @@ -18,17 +18,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-pc-windows-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-f80:32-n8:16:32-a:0:32-S32" .to_string(), arch: "x86".to_string(), - target_os: "windows".to_string(), - target_env: "gnu".to_string(), - target_vendor: "pc".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs index db20b6094b7..e7a5643eaaa 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs @@ -22,17 +22,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-f80:32-n8:16:32-a:0:32-S32" .to_string(), arch: "x86".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "pc".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs index d9365d59e0e..0cdb9f9de56 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs @@ -10,17 +10,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-cloudabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "cloudabi".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index ba379a40f50..fc1c8607d65 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs @@ -11,17 +11,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-freebsd".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "freebsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs index 02754b39fa7..22c8ba54753 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs @@ -9,17 +9,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-haiku".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "haiku".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index b7ceaefef93..62b02d841c2 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs @@ -9,17 +9,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index 9240b56aeaf..1673b2a1802 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -24,17 +24,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index a4421924a7b..2568fabfb05 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -9,17 +9,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-netbsdelf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "netbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "__mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index fe5030f661b..87642efdee8 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs @@ -10,17 +10,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-openbsd".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "openbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/i686_unknown_uefi.rs index 676a8ca0acc..5af3a6b41e2 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_uefi.rs @@ -5,7 +5,7 @@ // The cdecl ABI is used. It differs from the stdcall or fastcall ABI. // "i686-unknown-windows" is used to get the minimal subset of windows-specific features. -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::uefi_msvc_base::opts(); @@ -78,17 +78,11 @@ pub fn target() -> Target { // remove -gnu and use the default one. Target { llvm_target: "i686-unknown-windows-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-f80:32-n8:16:32-a:0:32-S32" .to_string(), - target_os: "uefi".to_string(), - target_env: "".to_string(), - target_vendor: "unknown".to_string(), arch: "x86".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), options: base, } diff --git a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs index ec5a9cc68ce..a3de93efb78 100644 --- a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs @@ -17,17 +17,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-pc-windows-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-f80:32-n8:16:32-a:0:32-S32" .to_string(), arch: "x86".to_string(), - target_os: "windows".to_string(), - target_env: "gnu".to_string(), - target_vendor: "uwp".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs index d960a130351..ce6200be81f 100644 --- a/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::windows_uwp_msvc_base::opts(); @@ -8,17 +8,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-f80:32-n8:16:32-a:0:32-S32" .to_string(), arch: "x86".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "uwp".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: base, } } diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index 0e5c7b6143e..c0825358cab 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -9,17 +9,11 @@ pub fn target() -> Target { Target { llvm_target: "i686-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ f64:32:64-f80:32-n8:16:32-S128" .to_string(), arch: "x86".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs index 214142b88fc..625f7b18b25 100644 --- a/compiler/rustc_target/src/spec/illumos_base.rs +++ b/compiler/rustc_target/src/spec/illumos_base.rs @@ -16,6 +16,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "illumos".to_string(), dynamic_linking: true, executables: true, has_rpath: true, diff --git a/compiler/rustc_target/src/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs index 5caad10161d..6d1e610d0e9 100644 --- a/compiler/rustc_target/src/spec/l4re_base.rs +++ b/compiler/rustc_target/src/spec/l4re_base.rs @@ -17,6 +17,9 @@ pub fn opts() -> TargetOptions { args.insert(LinkerFlavor::Gcc, vec![]); TargetOptions { + target_os: "l4re".to_string(), + target_env: "uclibc".to_string(), + linker_flavor: LinkerFlavor::Ld, executables: true, has_elf_tls: false, panic_strategy: PanicStrategy::Abort, diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index 7ad972b0692..b3a850591fd 100644 --- a/compiler/rustc_target/src/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs @@ -19,6 +19,8 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "linux".to_string(), + target_env: "gnu".to_string(), dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 6d929d12447..9c883f9a188 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -8,6 +8,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_env: "gnu".to_string(), disable_redzone: true, panic_strategy: PanicStrategy::Abort, stack_probes: true, diff --git a/compiler/rustc_target/src/spec/linux_musl_base.rs b/compiler/rustc_target/src/spec/linux_musl_base.rs index 16cc3b762f6..3a44d3326eb 100644 --- a/compiler/rustc_target/src/spec/linux_musl_base.rs +++ b/compiler/rustc_target/src/spec/linux_musl_base.rs @@ -4,6 +4,7 @@ use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); + base.target_env = "musl".to_string(); base.pre_link_objects_fallback = crt_objects::pre_musl_fallback(); base.post_link_objects_fallback = crt_objects::post_musl_fallback(); base.crt_objects_fallback = Some(CrtObjectsFallback::Musl); diff --git a/compiler/rustc_target/src/spec/linux_uclibc_base.rs b/compiler/rustc_target/src/spec/linux_uclibc_base.rs new file mode 100644 index 00000000000..ce7c79c1644 --- /dev/null +++ b/compiler/rustc_target/src/spec/linux_uclibc_base.rs @@ -0,0 +1,5 @@ +use crate::spec::TargetOptions; + +pub fn opts() -> TargetOptions { + TargetOptions { target_env: "uclibc".to_string(), ..super::linux_base::opts() } +} diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs index 5cbd6bcd3d8..f0a266a63af 100644 --- a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs @@ -1,18 +1,13 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mips64-unknown-linux-gnuabi64".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_endian: "big".to_string(), // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".to_string(), features: "+mips64r2".to_string(), diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs index 3ca92dd1d04..805a965bc0f 100644 --- a/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -8,15 +8,13 @@ pub fn target() -> Target { Target { // LLVM doesn't recognize "muslabi64" yet. llvm_target: "mips64-unknown-linux-musl".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs index 4761be5b7ef..f47b058bd08 100644 --- a/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs @@ -1,17 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mips64el-unknown-linux-gnuabi64".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".to_string(), diff --git a/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs index d87170b6868..5c985eb842c 100644 --- a/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { // LLVM doesn't recognize "muslabi64" yet. llvm_target: "mips64el-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs index e51cf3c59f6..1fc66861364 100644 --- a/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs @@ -1,18 +1,13 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mips-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_endian: "big".to_string(), cpu: "mips32r2".to_string(), features: "+mips32r2,+fpxx,+nooddspreg".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs index 44d136ee7e9..ed03f5d990e 100644 --- a/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -8,15 +8,13 @@ pub fn target() -> Target { base.crt_static_default = false; Target { llvm_target: "mips-unknown-linux-musl".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs index 7e168836dc7..fa1d789bfa8 100644 --- a/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs @@ -1,24 +1,19 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mips-unknown-linux-uclibc".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "uclibc".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_endian: "big".to_string(), cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float".to_string(), max_atomic_width: Some(32), target_mcount: "_mcount".to_string(), - ..super::linux_base::opts() + ..super::linux_uclibc_base::opts() }, } } diff --git a/compiler/rustc_target/src/spec/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs index 9897b0093fc..3f426e2e5fe 100644 --- a/compiler/rustc_target/src/spec/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs @@ -10,17 +10,14 @@ pub fn target() -> Target { Target { llvm_target: "mipsel-sony-psp".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "psp".to_string(), - target_env: "".to_string(), - target_vendor: "sony".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + target_os: "psp".to_string(), + target_vendor: "sony".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), cpu: "mips2".to_string(), executables: true, linker: Some("rust-lld".to_owned()), diff --git a/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs index 509f3e04ba7..16fbab58140 100644 --- a/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs @@ -1,17 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsel-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r2".to_string(), diff --git a/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs index 0d3691dd5b9..d1b603cd9de 100644 --- a/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -8,15 +8,9 @@ pub fn target() -> Target { base.crt_static_default = false; Target { llvm_target: "mipsel-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs index 6d50d9ba81e..a09f7ad0121 100644 --- a/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs @@ -1,17 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsel-unknown-linux-uclibc".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "uclibc".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r2".to_string(), @@ -19,7 +13,7 @@ pub fn target() -> Target { max_atomic_width: Some(32), target_mcount: "_mcount".to_string(), - ..super::linux_base::opts() + ..super::linux_uclibc_base::opts() }, } } diff --git a/compiler/rustc_target/src/spec/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/mipsel_unknown_none.rs index 1651ff9c2d6..60c4c3bb051 100644 --- a/compiler/rustc_target/src/spec/mipsel_unknown_none.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_none.rs @@ -9,17 +9,13 @@ use crate::spec::{PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsel-unknown-none".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float,+noabicalls".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs index d6e71d2922f..417ee6e043b 100644 --- a/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs @@ -1,18 +1,13 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_endian: "big".to_string(), cpu: "mips32r6".to_string(), features: "+mips32r6".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs index 67e97fd2f0f..cf273c6ab2b 100644 --- a/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs @@ -1,17 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r6".to_string(), diff --git a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs index c3a7ae8b11f..1d82395f536 100644 --- a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -1,18 +1,13 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_endian: "big".to_string(), // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".to_string(), features: "+mips64r6".to_string(), diff --git a/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs index 467e05a00d4..aadd36235bf 100644 --- a/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -1,17 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".to_string(), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index d3c5a9433d0..55d27fd8698 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -37,7 +37,9 @@ use crate::spec::abi::{lookup as lookup_abi, Abi}; use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_serialize::json::{Json, ToJson}; +use rustc_span::symbol::{sym, Symbol}; use std::collections::BTreeMap; +use std::ops::Deref; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{fmt, io}; @@ -64,6 +66,7 @@ mod l4re_base; mod linux_base; mod linux_kernel_base; mod linux_musl_base; +mod linux_uclibc_base; mod msvc_base; mod netbsd_base; mod openbsd_base; @@ -174,6 +177,13 @@ impl PanicStrategy { PanicStrategy::Abort => "abort", } } + + pub fn desc_symbol(&self) -> Symbol { + match *self { + PanicStrategy::Unwind => sym::unwind, + PanicStrategy::Abort => sym::abort, + } + } } impl ToJson for PanicStrategy { @@ -664,26 +674,13 @@ supported_targets! { pub struct Target { /// Target triple to pass to LLVM. pub llvm_target: String, - /// String to use as the `target_endian` `cfg` variable. - pub target_endian: String, /// Number of bits in a pointer. Influences the `target_pointer_width` `cfg` variable. pub pointer_width: u32, - /// Width of c_int type - pub target_c_int_width: String, - /// OS name to use for conditional compilation. - pub target_os: String, - /// Environment name to use for conditional compilation. - pub target_env: String, - /// Vendor name to use for conditional compilation. - pub target_vendor: String, /// Architecture to use for ABI considerations. Valid options include: "x86", /// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others. pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, - /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed - /// on the command line. - pub linker_flavor: LinkerFlavor, /// Optional settings with defaults. pub options: TargetOptions, } @@ -707,6 +704,20 @@ pub struct TargetOptions { /// Whether the target is built-in or loaded from a custom target specification. pub is_builtin: bool, + /// String to use as the `target_endian` `cfg` variable. Defaults to "little". + pub target_endian: String, + /// Width of c_int type. Defaults to "32". + pub target_c_int_width: String, + /// OS name to use for conditional compilation. Defaults to "none". + pub target_os: String, + /// Environment name to use for conditional compilation. Defaults to "". + pub target_env: String, + /// Vendor name to use for conditional compilation. Defaults to "unknown". + pub target_vendor: String, + /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed + /// on the command line. Defaults to `LinkerFlavor::Gcc`. + pub linker_flavor: LinkerFlavor, + /// Linker to invoke pub linker: Option<String>, @@ -985,6 +996,12 @@ impl Default for TargetOptions { fn default() -> TargetOptions { TargetOptions { is_builtin: false, + target_endian: "little".to_string(), + target_c_int_width: "32".to_string(), + target_os: "none".to_string(), + target_env: String::new(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()), lld_flavor: LldFlavor::Ld, pre_link_args: LinkArgs::new(), @@ -1075,6 +1092,17 @@ impl Default for TargetOptions { } } +/// `TargetOptions` being a separate type is basically an implementation detail of `Target` that is +/// used for providing defaults. Perhaps there's a way to merge `TargetOptions` into `Target` so +/// this `Deref` implementation is no longer necessary. +impl Deref for Target { + type Target = TargetOptions; + + fn deref(&self) -> &Self::Target { + &self.options + } +} + impl Target { /// Given a function ABI, turn it into the correct ABI for this target. pub fn adjust_abi(&self, abi: Abi) -> Abi { @@ -1135,27 +1163,13 @@ impl Target { .ok_or_else(|| format!("Field {} in target specification is required", name)) }; - let get_opt_field = |name: &str, default: &str| { - obj.find(name) - .and_then(|s| s.as_string()) - .map(|s| s.to_string()) - .unwrap_or_else(|| default.to_string()) - }; - let mut base = Target { llvm_target: get_req_field("llvm-target")?, - target_endian: get_req_field("target-endian")?, pointer_width: get_req_field("target-pointer-width")? .parse::<u32>() .map_err(|_| "target-pointer-width must be an integer".to_string())?, - target_c_int_width: get_req_field("target-c-int-width")?, data_layout: get_req_field("data-layout")?, arch: get_req_field("arch")?, - target_os: get_req_field("os")?, - target_env: get_opt_field("env", ""), - target_vendor: get_opt_field("vendor", "unknown"), - linker_flavor: LinkerFlavor::from_str(&*get_req_field("linker-flavor")?) - .ok_or_else(|| format!("linker flavor must be {}", LinkerFlavor::one_of()))?, options: Default::default(), }; @@ -1166,6 +1180,12 @@ impl Target { base.options.$key_name = s.to_string(); } } ); + ($key_name:ident = $json_name:expr) => ( { + let name = $json_name; + if let Some(s) = obj.find(&name).and_then(Json::as_string) { + base.options.$key_name = s.to_string(); + } + } ); ($key_name:ident, bool) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(s) = obj.find(&name).and_then(Json::as_boolean) { @@ -1301,11 +1321,13 @@ impl Target { } ); ($key_name:ident, LinkerFlavor) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[..]).and_then(|o| o.as_string().map(|s| { - LinkerFlavor::from_str(&s).ok_or_else(|| { - Err(format!("'{}' is not a valid value for linker-flavor. \ - Use 'em', 'gcc', 'ld' or 'msvc.", s)) - }) + obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { + match LinkerFlavor::from_str(s) { + Some(linker_flavor) => base.options.$key_name = linker_flavor, + _ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \ + Use {}", s, LinkerFlavor::one_of()))), + } + Some(Ok(())) })).unwrap_or(Ok(())) } ); ($key_name:ident, crt_objects_fallback) => ( { @@ -1392,6 +1414,12 @@ impl Target { } key!(is_builtin, bool); + key!(target_endian); + key!(target_c_int_width); + key!(target_os = "os"); + key!(target_env = "env"); + key!(target_vendor = "vendor"); + key!(linker_flavor, LinkerFlavor)?; key!(linker, optional); key!(lld_flavor, LldFlavor)?; key!(pre_link_objects, link_objects); @@ -1619,17 +1647,17 @@ impl ToJson for Target { } target_val!(llvm_target); - target_val!(target_endian); d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json()); - target_val!(target_c_int_width); target_val!(arch); - target_val!(target_os, "os"); - target_val!(target_env, "env"); - target_val!(target_vendor, "vendor"); target_val!(data_layout); - target_val!(linker_flavor); target_option_val!(is_builtin); + target_option_val!(target_endian); + target_option_val!(target_c_int_width); + target_option_val!(target_os, "os"); + target_option_val!(target_env, "env"); + target_option_val!(target_vendor, "vendor"); + target_option_val!(linker_flavor); target_option_val!(linker); target_option_val!(lld_flavor); target_option_val!(pre_link_objects); diff --git a/compiler/rustc_target/src/spec/msp430_none_elf.rs b/compiler/rustc_target/src/spec/msp430_none_elf.rs index 5bb8109ce26..48b6d1be9ce 100644 --- a/compiler/rustc_target/src/spec/msp430_none_elf.rs +++ b/compiler/rustc_target/src/spec/msp430_none_elf.rs @@ -1,19 +1,15 @@ -use crate::spec::{LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "msp430-none-elf".to_string(), - target_endian: "little".to_string(), pointer_width: 16, - target_c_int_width: "16".to_string(), data_layout: "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16".to_string(), arch: "msp430".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_c_int_width: "16".to_string(), + target_vendor: String::new(), executables: true, // The LLVM backend currently can't generate object files. To diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs index f57ef87cf12..8cd6735a8c1 100644 --- a/compiler/rustc_target/src/spec/msvc_base.rs +++ b/compiler/rustc_target/src/spec/msvc_base.rs @@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions { pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); TargetOptions { + linker_flavor: LinkerFlavor::Msvc, executables: true, is_like_windows: true, is_like_msvc: true, diff --git a/compiler/rustc_target/src/spec/netbsd_base.rs b/compiler/rustc_target/src/spec/netbsd_base.rs index d7baf81fce3..437b50b6f11 100644 --- a/compiler/rustc_target/src/spec/netbsd_base.rs +++ b/compiler/rustc_target/src/spec/netbsd_base.rs @@ -14,6 +14,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "netbsd".to_string(), dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), diff --git a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs index 86360c181d1..f759724445e 100644 --- a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs @@ -6,18 +6,12 @@ pub fn target() -> Target { arch: "nvptx64".to_string(), data_layout: "e-i64:64-i128:128-v16:16-v32:32-n16:32:64".to_string(), llvm_target: "nvptx64-nvidia-cuda".to_string(), - - target_os: "cuda".to_string(), - target_vendor: "nvidia".to_string(), - target_env: String::new(), - - linker_flavor: LinkerFlavor::PtxLinker, - - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), options: TargetOptions { + target_os: "cuda".to_string(), + target_vendor: "nvidia".to_string(), + linker_flavor: LinkerFlavor::PtxLinker, // The linker can be installed from `crates.io`. linker: Some("rust-ptx-linker".to_string()), diff --git a/compiler/rustc_target/src/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index 92a382e826b..5e83e79d9ed 100644 --- a/compiler/rustc_target/src/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs @@ -16,6 +16,7 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "openbsd".to_string(), dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs index 563ff96a403..3d20f15b391 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs @@ -8,15 +8,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64-unknown-freebsd".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - target_os: "freebsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs index 7d37670e5b0..e52643eb893 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs @@ -12,15 +12,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs index e108d75f337..315192929ac 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs @@ -8,15 +8,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64-unknown-linux-musl".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index 9784c637c7e..a31256761a4 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { ..base }, + options: TargetOptions { target_endian: "big".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs index 46d847f6e5f..4cf296c3fa7 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64le-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs index e04ee013701..41756028cbe 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs @@ -8,15 +8,9 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64le-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs index 80fc63e78e4..f3ec02c10d2 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs @@ -7,15 +7,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs index 612d2967ee0..4e3ffca0a08 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs @@ -7,15 +7,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc-unknown-linux-gnuspe".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs index fd89262e464..1d5c19b5420 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs @@ -7,15 +7,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc-unknown-linux-musl".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "_mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index d33258d1859..4d7eb8d0100 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -7,15 +7,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc-unknown-netbsd".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - target_os: "netbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "__mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "__mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index 6a12f4c59f6..dc6a4e28a3d 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -8,15 +8,13 @@ pub fn target() -> Target { Target { llvm_target: "powerpc-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { features: "+secure-plt".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + features: "+secure-plt".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index 5fee61fa0bd..1ce3fa21918 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -8,16 +8,11 @@ pub fn target() -> Target { Target { llvm_target: "powerpc-unknown-linux-gnuspe".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { + target_endian: "big".to_string(), // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2 features: "+secure-plt,+msync".to_string(), ..base diff --git a/compiler/rustc_target/src/spec/redox_base.rs b/compiler/rustc_target/src/spec/redox_base.rs index 18cafe654d1..04409a1cd04 100644 --- a/compiler/rustc_target/src/spec/redox_base.rs +++ b/compiler/rustc_target/src/spec/redox_base.rs @@ -19,6 +19,8 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "redox".to_string(), + target_env: "relibc".to_string(), dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), diff --git a/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs index 415d7c5607d..f9405d9dfb6 100644 --- a/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs @@ -1,17 +1,11 @@ -use crate::spec::{CodeModel, LinkerFlavor, Target, TargetOptions}; +use crate::spec::{CodeModel, Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "riscv32-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_env: "gnu".to_string(), data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(), arch: "riscv32".to_string(), - target_os: "linux".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::riscv_base::unsupported_abis(), code_model: Some(CodeModel::Medium), diff --git a/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs index 022768f6ab8..a31a08a8cf9 100644 --- a/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs @@ -5,16 +5,11 @@ pub fn target() -> Target { Target { data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(), llvm_target: "riscv32".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), arch: "riscv32".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_string()), cpu: "generic-rv32".to_string(), max_atomic_width: Some(0), diff --git a/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs index 13f0d42d6fd..2ee53fdc401 100644 --- a/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs @@ -5,16 +5,11 @@ pub fn target() -> Target { Target { data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(), llvm_target: "riscv32".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), arch: "riscv32".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_string()), cpu: "generic-rv32".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs index 86189c27bbd..89d760e082f 100644 --- a/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs @@ -5,16 +5,11 @@ pub fn target() -> Target { Target { data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(), llvm_target: "riscv32".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), arch: "riscv32".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_string()), cpu: "generic-rv32".to_string(), max_atomic_width: Some(0), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs index 808d7159f82..3b7ff47a540 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs @@ -1,17 +1,11 @@ -use crate::spec::{CodeModel, LinkerFlavor, Target, TargetOptions}; +use crate::spec::{CodeModel, Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "riscv64-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_env: "gnu".to_string(), data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".to_string(), arch: "riscv64".to_string(), - target_os: "linux".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::riscv_base::unsupported_abis(), code_model: Some(CodeModel::Medium), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs index 0211bc02d2d..33a785fdfee 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs @@ -5,16 +5,11 @@ pub fn target() -> Target { Target { data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".to_string(), llvm_target: "riscv64".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), arch: "riscv64".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_string()), cpu: "generic-rv64".to_string(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs index 1050ce5ba74..908367ee200 100644 --- a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs @@ -5,16 +5,11 @@ pub fn target() -> Target { Target { data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".to_string(), llvm_target: "riscv64".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), arch: "riscv64".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker: Some("rust-lld".to_string()), cpu: "generic-rv64".to_string(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs index 653b83646ce..69b880cdb81 100644 --- a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs @@ -1,7 +1,8 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::linux_base::opts(); + base.target_endian = "big".to_string(); // z10 is the oldest CPU supported by LLVM base.cpu = "z10".to_string(); // FIXME: The data_layout string below and the ABI implementation in @@ -13,15 +14,9 @@ pub fn target() -> Target { Target { llvm_target: "s390x-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".to_string(), arch: "s390x".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/solaris_base.rs b/compiler/rustc_target/src/spec/solaris_base.rs index 3d7f0034b8b..1454d83e936 100644 --- a/compiler/rustc_target/src/spec/solaris_base.rs +++ b/compiler/rustc_target/src/spec/solaris_base.rs @@ -2,6 +2,8 @@ use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { TargetOptions { + target_os: "solaris".to_string(), + target_vendor: "sun".to_string(), dynamic_linking: true, executables: true, has_rpath: true, diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs index e50c114fcfa..f02b01a514b 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs @@ -1,21 +1,16 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::linux_base::opts(); + base.target_endian = "big".to_string(); base.cpu = "v9".to_string(); base.max_atomic_width = Some(64); Target { llvm_target: "sparc64-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), arch: "sparc64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index 6d8e433949b..de35bb8fe14 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs @@ -8,15 +8,13 @@ pub fn target() -> Target { Target { llvm_target: "sparc64-unknown-netbsd".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), arch: "sparc64".to_string(), - target_os: "netbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, - options: TargetOptions { target_mcount: "__mcount".to_string(), ..base }, + options: TargetOptions { + target_endian: "big".to_string(), + target_mcount: "__mcount".to_string(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs index 45700e14c53..301c91e432c 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs @@ -2,21 +2,16 @@ use crate::spec::{LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); + base.target_endian = "big".to_string(); base.cpu = "v9".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); Target { llvm_target: "sparc64-unknown-openbsd".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), arch: "sparc64".to_string(), - target_os: "openbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs index fc400dd3446..071175819f4 100644 --- a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs @@ -2,21 +2,16 @@ use crate::spec::{LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::linux_base::opts(); + base.target_endian = "big".to_string(); base.cpu = "v9".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mv8plus".to_string()); Target { llvm_target: "sparc-unknown-linux-gnu".to_string(), - target_endian: "big".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".to_string(), arch: "sparc".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs index 0878e7fd21e..e8c30dcbf85 100644 --- a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs @@ -2,6 +2,7 @@ use crate::spec::{LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); + base.target_endian = "big".to_string(); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); // llvm calls this "v9" base.cpu = "v9".to_string(); @@ -9,19 +10,13 @@ pub fn target() -> Target { Target { llvm_target: "sparcv9-sun-solaris".to_string(), - target_endian: "big".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), // Use "sparc64" instead of "sparcv9" here, since the former is already // used widely in the source base. If we ever needed ABI // differentiation from the sparc64, we could, but that would probably // just be confusing. arch: "sparc64".to_string(), - target_os: "solaris".to_string(), - target_env: String::new(), - target_vendor: "sun".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs index 2f7d15d5856..cc955799d2f 100644 --- a/compiler/rustc_target/src/spec/thumb_base.rs +++ b/compiler/rustc_target/src/spec/thumb_base.rs @@ -27,11 +27,13 @@ // differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of // build scripts / gcc flags. -use crate::spec::{PanicStrategy, RelocModel, TargetOptions}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions}; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults TargetOptions { + target_vendor: String::new(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, // In most cases, LLD is good enough linker: Some("rust-lld".to_string()), diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index d5ce62d8c1c..d87c06d49cb 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -13,12 +13,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv4t-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "none".to_string(), - target_env: "".to_string(), - target_vendor: "".to_string(), arch: "arm".to_string(), /* Data layout args are '-' separated: * little endian @@ -30,8 +25,8 @@ pub fn target() -> Target { * All other elements are default */ data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), - linker_flavor: LinkerFlavor::Ld, options: TargetOptions { + linker_flavor: LinkerFlavor::Ld, linker: Some("arm-none-eabi-ld".to_string()), linker_is_gnu: true, diff --git a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs index 407fa6116c5..11c8bf46348 100644 --- a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs @@ -1,19 +1,13 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv6m-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them diff --git a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs index d34f42cdc61..8131a6e2ea4 100644 --- a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs @@ -23,15 +23,9 @@ pub fn target() -> Target { Target { llvm_target: "thumbv7a-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "pc".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: TargetOptions { features: "+vfp3,+neon".to_string(), diff --git a/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs index 143a9a48a4a..a2c1b6bb90c 100644 --- a/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions}; +use crate::spec::{PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::windows_uwp_msvc_base::opts(); @@ -11,15 +11,9 @@ pub fn target() -> Target { Target { llvm_target: "thumbv7a-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "uwp".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: TargetOptions { features: "+vfp3,+neon".to_string(), cpu: "generic".to_string(), diff --git a/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs index e0b00460e08..141eb7e78b9 100644 --- a/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs @@ -9,20 +9,14 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv7em-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() }, } diff --git a/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs index eecd75e4614..f5bd054f859 100644 --- a/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs @@ -8,20 +8,14 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv7em-none-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the diff --git a/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs index a02100ee199..7af28cd9c9f 100644 --- a/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs @@ -1,19 +1,13 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv7m-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() }, } diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs index 35e7d480f3f..41fdbc2f0a0 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs @@ -16,15 +16,9 @@ pub fn target() -> Target { Target { llvm_target: "armv7-none-linux-android".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "android".to_string(), - target_env: "".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs index 946b0db4c22..561da4d15cd 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // This target is for glibc Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -10,15 +10,9 @@ pub fn target() -> Target { let base = super::linux_base::opts(); Target { llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs index 91945f9dcdc..5b1fc74bdd0 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; // This target is for musl Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -13,15 +13,9 @@ pub fn target() -> Target { // uses it to determine the calling convention and float ABI, and LLVM // doesn't support the "musleabihf" value. llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf // target. diff --git a/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs index 383346400b5..a2200bc64e7 100644 --- a/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs @@ -1,19 +1,13 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv8m.base-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them diff --git a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs index 3d0fb664cf6..67cdbab4860 100644 --- a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs @@ -1,20 +1,14 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv8m.main-none-eabi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() }, } diff --git a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs index 82368cb59b2..49748f5ec6d 100644 --- a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs @@ -1,20 +1,14 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { Target { llvm_target: "thumbv8m.main-none-eabihf".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), - target_os: "none".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: TargetOptions { // If the Floating Point extension is implemented in the Cortex-M33 diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index 3f7c78c8e7d..91a39f7b9b4 100644 --- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs @@ -37,6 +37,8 @@ pub fn opts() -> TargetOptions { .extend(pre_link_args_msvc); TargetOptions { + target_os: "uefi".to_string(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), disable_redzone: true, exe_suffix: ".efi".to_string(), allows_weak_linkage: false, diff --git a/compiler/rustc_target/src/spec/vxworks_base.rs b/compiler/rustc_target/src/spec/vxworks_base.rs index 777bb58d7db..e8044e4dc1a 100644 --- a/compiler/rustc_target/src/spec/vxworks_base.rs +++ b/compiler/rustc_target/src/spec/vxworks_base.rs @@ -17,6 +17,9 @@ pub fn opts() -> TargetOptions { ); TargetOptions { + target_os: "vxworks".to_string(), + target_env: "gnu".to_string(), + target_vendor: "wrs".to_string(), linker: Some("wr-c++".to_string()), exe_suffix: ".vxe".to_string(), dynamic_linking: true, diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index aea06412aa2..dbafe362f2a 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs @@ -17,6 +17,8 @@ pub fn target() -> Target { ); let opts = TargetOptions { + target_os: "emscripten".to_string(), + linker_flavor: LinkerFlavor::Em, // emcc emits two files - a .js file to instantiate the wasm and supply platform // functionality, and a .wasm file. exe_suffix: ".js".to_string(), @@ -30,15 +32,9 @@ pub fn target() -> Target { }; Target { llvm_target: "wasm32-unknown-emscripten".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "emscripten".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), - linker_flavor: LinkerFlavor::Em, options: opts, } } diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 1ef0a819378..4401772788b 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -15,6 +15,8 @@ use super::{LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { let mut options = wasm32_base::options(); + options.target_os = "unknown".to_string(); + options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap(); // Make sure clang uses LLD as its linker and is configured appropriately @@ -32,15 +34,9 @@ pub fn target() -> Target { Target { llvm_target: "wasm32-unknown-unknown".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "unknown".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm), options, } } diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 8c2bb920829..6f5316e30f6 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -78,6 +78,9 @@ use super::{crt_objects, LinkerFlavor, LldFlavor, Target}; pub fn target() -> Target { let mut options = wasm32_base::options(); + options.target_os = "wasi".to_string(); + options.target_vendor = String::new(); + options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); options .pre_link_args .entry(LinkerFlavor::Gcc) @@ -106,15 +109,9 @@ pub fn target() -> Target { Target { llvm_target: "wasm32-wasi".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), - target_os: "wasi".to_string(), - target_env: String::new(), - target_vendor: String::new(), data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm), options, } } diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index 98e42f6c37c..37188a59eb5 100644 --- a/compiler/rustc_target/src/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -62,6 +62,9 @@ pub fn opts() -> TargetOptions { late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs); TargetOptions { + target_os: "windows".to_string(), + target_env: "gnu".to_string(), + target_vendor: "pc".to_string(), // FIXME(#13846) this should be enabled for windows function_sections: false, linker: Some("gcc".to_string()), diff --git a/compiler/rustc_target/src/spec/windows_msvc_base.rs b/compiler/rustc_target/src/spec/windows_msvc_base.rs index 77171f8672e..c1101623867 100644 --- a/compiler/rustc_target/src/spec/windows_msvc_base.rs +++ b/compiler/rustc_target/src/spec/windows_msvc_base.rs @@ -4,6 +4,9 @@ pub fn opts() -> TargetOptions { let base = super::msvc_base::opts(); TargetOptions { + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + target_vendor: "pc".to_string(), dynamic_linking: true, dll_prefix: String::new(), dll_suffix: ".dll".to_string(), diff --git a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs index fcb2af0005f..225b94c3755 100644 --- a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs @@ -25,6 +25,7 @@ pub fn opts() -> TargetOptions { late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs); TargetOptions { + target_vendor: "uwp".to_string(), executables: false, limit_rdylib_exports: false, late_link_args, diff --git a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs index 04ffa1a0add..380d685dacf 100644 --- a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs @@ -3,6 +3,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut opts = super::windows_msvc_base::opts(); + opts.target_vendor = "uwp".to_string(); let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()]; opts.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); opts.pre_link_args diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 2b39fec594a..6cd4daa7a74 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { - let mut base = super::apple_base::opts(); + let mut base = super::apple_base::opts("macos"); base.cpu = "core2".to_string(); base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.eliminate_frame_pointer = false; @@ -20,16 +20,10 @@ pub fn target() -> Target { Target { llvm_target, - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: arch.to_string(), - target_os: "macos".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "\u{1}mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index 685e046b64b..c9c7eeb7231 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -1,20 +1,14 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::X86_64); + let base = opts("ios", Arch::X86_64); Target { llvm_target: "x86_64-apple-ios".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "ios".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index ff7331560ed..6b360e5495b 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -1,20 +1,14 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::X86_64_macabi); + let base = opts("ios", Arch::X86_64_macabi); Target { llvm_target: "x86_64-apple-ios13.0-macabi".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "ios".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index 7c0a819f5dd..5b2a62a23fd 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -1,19 +1,13 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts(Arch::X86_64); + let base = opts("tvos", Arch::X86_64); Target { llvm_target: "x86_64-apple-tvos".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), arch: "x86_64".to_string(), - target_os: "tvos".to_string(), - target_env: String::new(), - target_vendor: "apple".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(64), stack_probes: true, ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs index 8f1627d4a29..550d308ed8f 100644 --- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs @@ -55,6 +55,10 @@ pub fn target() -> Target { "TEXT_SIZE", ]; let opts = TargetOptions { + target_os: "unknown".into(), + target_env: "sgx".into(), + target_vendor: "fortanix".into(), + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), dynamic_linking: false, executables: true, linker_is_gnu: true, @@ -76,16 +80,10 @@ pub fn target() -> Target { }; Target { llvm_target: "x86_64-elf".into(), - target_endian: "little".into(), pointer_width: 64, - target_c_int_width: "32".into(), - target_os: "unknown".into(), - target_env: "sgx".into(), - target_vendor: "fortanix".into(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), arch: "x86_64".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, } } diff --git a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs index 71add0a6c0a..6c049c2635c 100644 --- a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); @@ -8,16 +8,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-fuchsia".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "fuchsia".to_string(), - target_env: String::new(), - target_vendor: String::new(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index aa5e48cee07..27327160178 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs @@ -11,16 +11,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-linux-android".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "android".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs b/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs index 243167558be..43e683ddbcc 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs @@ -16,16 +16,10 @@ pub fn target() -> Target { Target { // FIXME: Some dispute, the linux-on-clang folks think this should use "Linux" llvm_target: "x86_64-elf".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), - target_os: "none".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), arch: "x86_64".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs index 3b2edc91bc2..36726ab4aed 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs @@ -14,16 +14,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-pc-windows-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "windows".to_string(), - target_env: "gnu".to_string(), - target_vendor: "pc".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs index f21b059551d..72bbb10323c 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::windows_msvc_base::opts(); @@ -8,16 +8,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "pc".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs index 2e009d7abbf..511a4559935 100644 --- a/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs @@ -2,6 +2,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); + base.target_vendor = "rumprun".to_string(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.linker = Some("x86_64-rumprun-netbsd-gcc".to_string()); @@ -15,16 +16,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-rumprun-netbsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "netbsd".to_string(), - target_env: String::new(), - target_vendor: "rumprun".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "__mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs index aef06157cdd..6ccf78402e1 100644 --- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-pc-solaris".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "solaris".to_string(), - target_env: String::new(), - target_vendor: "sun".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs index bdaab883d90..cf57f4ec624 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs @@ -10,16 +10,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-cloudabi".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "cloudabi".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index 13a62d5081c..30aa2909873 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-dragonfly".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "dragonfly".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index 145983022e8..ee904d76242 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-freebsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "freebsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs index d88812e4248..ea7e068e516 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs @@ -11,16 +11,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-haiku".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "haiku".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs index a5002091d07..4005aaf58b1 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::hermit_base::opts(); @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-hermit".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "hermit".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs index 91d7b0eaefc..b72d529363a 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::hermit_kernel_base::opts(); @@ -11,16 +11,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-hermit".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "hermit".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs index e49f009be0f..d3f9349d99b 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs @@ -10,16 +10,10 @@ pub fn target() -> Target { // LLVM does not currently have a separate illumos target, // so we still pass Solaris to it llvm_target: "x86_64-pc-solaris".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "illumos".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs index fc5b1ba60ec..1fbd0bb4cec 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::l4re_base::opts(); @@ -7,16 +7,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-l4re-uclibc".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "l4re".to_string(), - target_env: "uclibc".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Ld, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 9d9f99c9b59..1f368ff1611 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index e4a0d913bab..375b22fd92b 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs @@ -13,17 +13,11 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-linux-gnux32".to_string(), - target_endian: "little".to_string(), pointer_width: 32, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "linux".to_string(), - target_env: "gnu".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index a7d3324b2c7..3669c10981e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs @@ -10,16 +10,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-linux-musl".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "linux".to_string(), - target_env: "musl".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index a8106c0c770..656ef90892c 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-netbsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "netbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { target_mcount: "__mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index 5afe73ea713..0fe01f09c2e 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-openbsd".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "openbsd".to_string(), - target_env: String::new(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index e21148887d9..cdd445b2614 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs @@ -9,16 +9,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-redox".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "redox".to_string(), - target_env: "relibc".to_string(), - target_vendor: "unknown".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs index 894bd334169..b7dcce5f895 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs @@ -5,7 +5,7 @@ // The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features. -use crate::spec::{CodeModel, LinkerFlavor, LldFlavor, Target}; +use crate::spec::{CodeModel, Target}; pub fn target() -> Target { let mut base = super::uefi_msvc_base::opts(); @@ -30,16 +30,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-windows".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), - target_os: "uefi".to_string(), - target_env: "".to_string(), - target_vendor: "unknown".to_string(), arch: "x86_64".to_string(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), options: base, } diff --git a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs index a4fa0d03546..57913ba0dab 100644 --- a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs @@ -13,16 +13,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-pc-windows-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "windows".to_string(), - target_env: "gnu".to_string(), - target_vendor: "uwp".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs index aaf85bbce81..27c579ed5bc 100644 --- a/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::Target; pub fn target() -> Target { let mut base = super::windows_uwp_msvc_base::opts(); @@ -8,16 +8,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-pc-windows-msvc".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "windows".to_string(), - target_env: "msvc".to_string(), - target_vendor: "uwp".to_string(), - linker_flavor: LinkerFlavor::Msvc, options: base, } } diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 5edf7e7af51..163af6fd8e1 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -10,16 +10,10 @@ pub fn target() -> Target { Target { llvm_target: "x86_64-unknown-linux-gnu".to_string(), - target_endian: "little".to_string(), pointer_width: 64, - target_c_int_width: "32".to_string(), data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .to_string(), arch: "x86_64".to_string(), - target_os: "vxworks".to_string(), - target_env: "gnu".to_string(), - target_vendor: "wrs".to_string(), - linker_flavor: LinkerFlavor::Gcc, options: base, } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 827b1d35f1c..a85ffd3c961 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -338,7 +338,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let ty = ty.super_fold_with(self); match *ty.kind() { - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index d748fc8235e..42a598ce3a0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -108,7 +108,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { let ty = ty.super_fold_with(self); let res = (|| match *ty.kind() { - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty, diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index a54fe08394e..8bd9e29629d 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -12,9 +12,9 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.32.0" -chalk-solve = "0.32.0" -chalk-engine = "0.32.0" +chalk-ir = "0.36.0" +chalk-solve = "0.36.0" +chalk-engine = "0.36.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index e5ae899a2f3..c5a46b1003d 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -37,7 +37,7 @@ impl<'tcx> RustIrDatabase<'tcx> { def_id: DefId, bound_vars: SubstsRef<'tcx>, ) -> Vec<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> { - let predicates = self.interner.tcx.predicates_of(def_id).predicates; + let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates; let mut regions_substitutor = lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder); predicates @@ -118,34 +118,27 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t .map(|i| chalk_ir::AssocTypeId(i.def_id)) .collect(); - let well_known = if self.interner.tcx.lang_items().sized_trait() == Some(def_id) { + let lang_items = self.interner.tcx.lang_items(); + let well_known = if lang_items.sized_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::Sized) - } else if self.interner.tcx.lang_items().copy_trait() == Some(def_id) { + } else if lang_items.copy_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::Copy) - } else if self.interner.tcx.lang_items().clone_trait() == Some(def_id) { + } else if lang_items.clone_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::Clone) - } else if self.interner.tcx.lang_items().drop_trait() == Some(def_id) { + } else if lang_items.drop_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::Drop) - } else if self.interner.tcx.lang_items().fn_trait() == Some(def_id) { + } else if lang_items.fn_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::Fn) - } else if self - .interner - .tcx - .lang_items() - .fn_once_trait() - .map(|t| def_id == t) - .unwrap_or(false) - { + } else if lang_items.fn_once_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce) - } else if self - .interner - .tcx - .lang_items() - .fn_mut_trait() - .map(|t| def_id == t) - .unwrap_or(false) - { + } else if lang_items.fn_mut_trait() == Some(def_id) { Some(chalk_solve::rust_ir::WellKnownTrait::FnMut) + } else if lang_items.unsize_trait() == Some(def_id) { + Some(chalk_solve::rust_ir::WellKnownTrait::Unsize) + } else if lang_items.unpin_trait() == Some(def_id) { + Some(chalk_solve::rust_ir::WellKnownTrait::Unpin) + } else if lang_items.coerce_unsized_trait() == Some(def_id) { + Some(chalk_solve::rust_ir::WellKnownTrait::CoerceUnsized) } else { None }; @@ -281,11 +274,20 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t where_clauses, }; + let associated_ty_value_ids: Vec<_> = self + .interner + .tcx + .associated_items(def_id) + .in_definition_order() + .filter(|i| i.kind == AssocKind::Type) + .map(|i| chalk_solve::rust_ir::AssociatedTyValueId(i.def_id)) + .collect(); + Arc::new(chalk_solve::rust_ir::ImplDatum { - polarity: chalk_solve::rust_ir::Polarity::Positive, + polarity: self.interner.tcx.impl_polarity(def_id).lower_into(&self.interner), binders: chalk_ir::Binders::new(binders, value), impl_type: chalk_solve::rust_ir::ImplType::Local, - associated_ty_value_ids: vec![], + associated_ty_value_ids, }) } @@ -324,19 +326,19 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t fn impl_provided_for( &self, auto_trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, - app_ty: &chalk_ir::ApplicationTy<RustInterner<'tcx>>, + chalk_ty: &chalk_ir::TyKind<RustInterner<'tcx>>, ) -> bool { use chalk_ir::Scalar::*; - use chalk_ir::TypeName::*; + use chalk_ir::TyKind::*; let trait_def_id = auto_trait_id.0; let all_impls = self.interner.tcx.all_impls(trait_def_id); for impl_def_id in all_impls { let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap(); let self_ty = trait_ref.self_ty(); - let provides = match (self_ty.kind(), app_ty.name) { - (&ty::Adt(impl_adt_def, ..), Adt(id)) => impl_adt_def.did == id.0.did, - (_, AssociatedType(_ty_id)) => { + let provides = match (self_ty.kind(), chalk_ty) { + (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did == id.0.did, + (_, AssociatedType(_ty_id, ..)) => { // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774 false } @@ -365,10 +367,10 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t (ast::FloatTy::F32, chalk_ir::FloatTy::F32) | (ast::FloatTy::F64, chalk_ir::FloatTy::F64) ), - (&ty::Tuple(..), Tuple(..)) => true, - (&ty::Array(..), Array) => true, - (&ty::Slice(..), Slice) => true, - (&ty::RawPtr(type_and_mut), Raw(mutability)) => { + (&ty::Tuple(substs), Tuple(len, _)) => substs.len() == *len, + (&ty::Array(..), Array(..)) => true, + (&ty::Slice(..), Slice(..)) => true, + (&ty::RawPtr(type_and_mut), Raw(mutability, _)) => { match (type_and_mut.mutbl, mutability) { (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, @@ -376,17 +378,19 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, } } - (&ty::Ref(.., mutability1), Ref(mutability2)) => match (mutability1, mutability2) { - (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, - (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, - (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, - (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, - }, - (&ty::Opaque(def_id, ..), OpaqueType(opaque_ty_id)) => def_id == opaque_ty_id.0, - (&ty::FnDef(def_id, ..), FnDef(fn_def_id)) => def_id == fn_def_id.0, + (&ty::Ref(.., mutability1), Ref(mutability2, ..)) => { + match (mutability1, mutability2) { + (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, + (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, + (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, + (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, + } + } + (&ty::Opaque(def_id, ..), OpaqueType(opaque_ty_id, ..)) => def_id == opaque_ty_id.0, + (&ty::FnDef(def_id, ..), FnDef(fn_def_id, ..)) => def_id == fn_def_id.0, (&ty::Str, Str) => true, (&ty::Never, Never) => true, - (&ty::Closure(def_id, ..), Closure(closure_id)) => def_id == closure_id.0, + (&ty::Closure(def_id, ..), Closure(closure_id, _)) => def_id == closure_id.0, (&ty::Foreign(def_id), Foreign(foreign_def_id)) => def_id == foreign_def_id.0, (&ty::Error(..), Error) => false, _ => false, @@ -404,24 +408,38 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t ) -> Arc<chalk_solve::rust_ir::AssociatedTyValue<RustInterner<'tcx>>> { let def_id = associated_ty_id.0; let assoc_item = self.interner.tcx.associated_item(def_id); - let impl_id = match assoc_item.container { - AssocItemContainer::TraitContainer(def_id) => def_id, - _ => unimplemented!("Not possible??"), + let (impl_id, trait_id) = match assoc_item.container { + AssocItemContainer::TraitContainer(def_id) => (def_id, def_id), + AssocItemContainer::ImplContainer(def_id) => { + (def_id, self.interner.tcx.impl_trait_ref(def_id).unwrap().def_id) + } }; match assoc_item.kind { AssocKind::Type => {} _ => unimplemented!("Not possible??"), } + + let trait_item = self + .interner + .tcx + .associated_items(trait_id) + .find_by_name_and_kind(self.interner.tcx, assoc_item.ident, assoc_item.kind, trait_id) + .unwrap(); let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); - let ty = self.interner.tcx.type_of(def_id); + let ty = self + .interner + .tcx + .type_of(def_id) + .subst(self.interner.tcx, bound_vars) + .lower_into(&self.interner); Arc::new(chalk_solve::rust_ir::AssociatedTyValue { impl_id: chalk_ir::ImplId(impl_id), - associated_ty_id: chalk_ir::AssocTypeId(def_id), + associated_ty_id: chalk_ir::AssocTypeId(trait_item.def_id), value: chalk_ir::Binders::new( binders, - chalk_solve::rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }, + chalk_solve::rust_ir::AssociatedTyValueBound { ty }, ), }) } @@ -441,19 +459,61 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t &self, opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>, ) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> { - let bound_vars = bound_vars_for_item(self.interner.tcx, opaque_ty_id.0); - let binders = binders_for(&self.interner, bound_vars); + let bound_vars = ty::fold::shift_vars( + self.interner.tcx, + &bound_vars_for_item(self.interner.tcx, opaque_ty_id.0), + 1, + ); let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars); - let bounds = self.bounds_for(opaque_ty_id.0, bound_vars); + + let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0); + + let bounds = + self.interner + .tcx + .explicit_item_bounds(opaque_ty_id.0) + .iter() + .map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars)) + .map(|bound| { + bound.fold_with(&mut ty::fold::BottomUpFolder { + tcx: self.interner.tcx, + ty_op: |ty| { + if let ty::Opaque(def_id, substs) = *ty.kind() { + if def_id == opaque_ty_id.0 && substs == identity_substs { + return self.interner.tcx.mk_ty(ty::Bound( + ty::INNERMOST, + ty::BoundTy::from(ty::BoundVar::from_u32(0)), + )); + } + } + ty + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }) + }) + .filter_map(|bound| { + LowerInto::< + Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> + >::lower_into(bound, &self.interner) + }) + .collect(); + + // Binder for the bound variable representing the concrete impl Trait type. + let existential_binder = chalk_ir::VariableKinds::from1( + &self.interner, + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), + ); let value = chalk_solve::rust_ir::OpaqueTyDatumBound { - bounds: chalk_ir::Binders::new(binders.clone(), bounds), - where_clauses: chalk_ir::Binders::new(binders, where_clauses), + bounds: chalk_ir::Binders::new(existential_binder.clone(), bounds), + where_clauses: chalk_ir::Binders::new(existential_binder, where_clauses), }; + let binders = binders_for(&self.interner, bound_vars); Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { opaque_ty_id, - bound: chalk_ir::Binders::empty(&self.interner, value), + bound: chalk_ir::Binders::new(binders, value), }) } @@ -506,17 +566,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t substs: &chalk_ir::Substitution<RustInterner<'tcx>>, ) -> chalk_solve::rust_ir::ClosureKind { let kind = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 3]; - match kind.assert_ty_ref(&self.interner).data(&self.interner) { - chalk_ir::TyData::Apply(apply) => match apply.name { - chalk_ir::TypeName::Scalar(scalar) => match scalar { - chalk_ir::Scalar::Int(int_ty) => match int_ty { - chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn, - chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut, - chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce, - _ => bug!("bad closure kind"), - }, - _ => bug!("bad closure kind"), - }, + match kind.assert_ty_ref(&self.interner).kind(&self.interner) { + chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(int_ty)) => match int_ty { + chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn, + chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut, + chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce, _ => bug!("bad closure kind"), }, _ => bug!("bad closure kind"), @@ -530,23 +584,19 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t ) -> chalk_ir::Binders<chalk_solve::rust_ir::FnDefInputsAndOutputDatum<RustInterner<'tcx>>> { let sig = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 2]; - match sig.assert_ty_ref(&self.interner).data(&self.interner) { - chalk_ir::TyData::Function(f) => { + match sig.assert_ty_ref(&self.interner).kind(&self.interner) { + chalk_ir::TyKind::Function(f) => { let substitution = f.substitution.as_slice(&self.interner); let return_type = substitution.last().unwrap().assert_ty_ref(&self.interner).clone(); // Closure arguments are tupled let argument_tuple = substitution[0].assert_ty_ref(&self.interner); - let argument_types = match argument_tuple.data(&self.interner) { - chalk_ir::TyData::Apply(apply) => match apply.name { - chalk_ir::TypeName::Tuple(_) => apply - .substitution - .iter(&self.interner) - .map(|arg| arg.assert_ty_ref(&self.interner)) - .cloned() - .collect(), - _ => bug!("Expecting closure FnSig args to be tupled."), - }, + let argument_types = match argument_tuple.kind(&self.interner) { + chalk_ir::TyKind::Tuple(_len, substitution) => substitution + .iter(&self.interner) + .map(|arg| arg.assert_ty_ref(&self.interner)) + .cloned() + .collect(), _ => bug!("Expecting closure FnSig args to be tupled."), }; @@ -637,7 +687,7 @@ fn binders_for<'tcx>( bound_vars.iter().map(|arg| match arg.unpack() { ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::VariableKind::Lifetime, ty::subst::GenericArgKind::Type(_ty) => { - chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General) + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General) } ty::subst::GenericArgKind::Const(c) => { chalk_ir::VariableKind::Const(c.ty.lower_into(interner)) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 01c4dd12487..c4e2c7f839d 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -31,11 +31,12 @@ //! not. To lower anything wrapped in a `Binder`, we first deeply find any bound //! variables from the current `Binder`. +use rustc_ast::ast; use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner}; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ - self, Binder, BoundRegion, Region, RegionKind, Ty, TyCtxt, TyKind, TypeFoldable, TypeVisitor, + self, Binder, BoundRegion, Region, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor, }; use rustc_span::def_id::DefId; @@ -240,24 +241,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>> impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty<RustInterner<'tcx>> { - use chalk_ir::TyData; use rustc_ast as ast; - use TyKind::*; - let empty = || chalk_ir::Substitution::empty(interner); - let struct_ty = - |def_id| chalk_ir::TypeName::Adt(chalk_ir::AdtId(interner.tcx.adt_def(def_id))); - let apply = |name, substitution| { - TyData::Apply(chalk_ir::ApplicationTy { name, substitution }).intern(interner) - }; - let int = |i| apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Int(i)), empty()); - let uint = |i| apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Uint(i)), empty()); - let float = |f| apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Float(f)), empty()); + let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)); + let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)); + let float = |f| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Float(f)); match *self.kind() { - Bool => apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Bool), empty()), - Char => apply(chalk_ir::TypeName::Scalar(chalk_ir::Scalar::Char), empty()), - Int(ty) => match ty { + ty::Bool => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool), + ty::Char => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Char), + ty::Int(ty) => match ty { ast::IntTy::Isize => int(chalk_ir::IntTy::Isize), ast::IntTy::I8 => int(chalk_ir::IntTy::I8), ast::IntTy::I16 => int(chalk_ir::IntTy::I16), @@ -265,7 +258,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { ast::IntTy::I64 => int(chalk_ir::IntTy::I64), ast::IntTy::I128 => int(chalk_ir::IntTy::I128), }, - Uint(ty) => match ty { + ty::Uint(ty) => match ty { ast::UintTy::Usize => uint(chalk_ir::UintTy::Usize), ast::UintTy::U8 => uint(chalk_ir::UintTy::U8), ast::UintTy::U16 => uint(chalk_ir::UintTy::U16), @@ -273,80 +266,35 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { ast::UintTy::U64 => uint(chalk_ir::UintTy::U64), ast::UintTy::U128 => uint(chalk_ir::UintTy::U128), }, - Float(ty) => match ty { + ty::Float(ty) => match ty { ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32), ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64), }, - Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)), - Foreign(def_id) => apply(chalk_ir::TypeName::Foreign(ForeignDefId(def_id)), empty()), - Str => apply(chalk_ir::TypeName::Str, empty()), - Array(ty, len) => { - let value = match len.val { - ty::ConstKind::Value(val) => { - chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: val }) - } - ty::ConstKind::Bound(db, bound) => { - chalk_ir::ConstValue::BoundVar(chalk_ir::BoundVar::new( - chalk_ir::DebruijnIndex::new(db.as_u32()), - bound.index(), - )) - } - _ => unimplemented!("Const not implemented. {:?}", len.val), - }; - apply( - chalk_ir::TypeName::Array, - chalk_ir::Substitution::from_iter( - interner, - &[ - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), - chalk_ir::GenericArgData::Const( - chalk_ir::ConstData { ty: len.ty.lower_into(interner), value } - .intern(interner), - ) - .intern(interner), - ], - ), - ) + ty::Adt(def, substs) => { + chalk_ir::TyKind::Adt(chalk_ir::AdtId(def), substs.lower_into(interner)) } - Slice(ty) => apply( - chalk_ir::TypeName::Slice, - chalk_ir::Substitution::from1( - interner, - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), - ), - ), - RawPtr(ptr) => { - let name = match ptr.mutbl { - ast::Mutability::Mut => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Mut), - ast::Mutability::Not => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Not), - }; - apply(name, chalk_ir::Substitution::from1(interner, ptr.ty.lower_into(interner))) + ty::Foreign(def_id) => chalk_ir::TyKind::Foreign(ForeignDefId(def_id)), + ty::Str => chalk_ir::TyKind::Str, + ty::Array(ty, len) => { + chalk_ir::TyKind::Array(ty.lower_into(interner), len.lower_into(interner)) } - Ref(region, ty, mutability) => { - let name = match mutability { - ast::Mutability::Mut => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Mut), - ast::Mutability::Not => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Not), - }; - apply( - name, - chalk_ir::Substitution::from_iter( - interner, - &[ - chalk_ir::GenericArgData::Lifetime(region.lower_into(interner)) - .intern(interner), - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), - ], - ), - ) + ty::Slice(ty) => chalk_ir::TyKind::Slice(ty.lower_into(interner)), + + ty::RawPtr(ptr) => { + chalk_ir::TyKind::Raw(ptr.mutbl.lower_into(interner), ptr.ty.lower_into(interner)) } - FnDef(def_id, substs) => apply( - chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(def_id)), - substs.lower_into(interner), + ty::Ref(region, ty, mutability) => chalk_ir::TyKind::Ref( + mutability.lower_into(interner), + region.lower_into(interner), + ty.lower_into(interner), ), - FnPtr(sig) => { + ty::FnDef(def_id, substs) => { + chalk_ir::TyKind::FnDef(chalk_ir::FnDefId(def_id), substs.lower_into(interner)) + } + ty::FnPtr(sig) => { let (inputs_and_outputs, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output()); - TyData::Function(chalk_ir::FnPointer { + chalk_ir::TyKind::Function(chalk_ir::FnPointer { num_binders: binders.len(interner), sig: sig.lower_into(interner), substitution: chalk_ir::Substitution::from_iter( @@ -356,148 +304,115 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { }), ), }) - .intern(interner) } - Dynamic(predicates, region) => TyData::Dyn(chalk_ir::DynTy { + ty::Dynamic(predicates, region) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner), lifetime: region.lower_into(interner), - }) - .intern(interner), - Closure(def_id, substs) => apply( - chalk_ir::TypeName::Closure(chalk_ir::ClosureId(def_id)), - substs.lower_into(interner), - ), - Generator(_def_id, _substs, _) => unimplemented!(), - GeneratorWitness(_) => unimplemented!(), - Never => apply(chalk_ir::TypeName::Never, empty()), - Tuple(substs) => { - apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner)) + }), + ty::Closure(def_id, substs) => { + chalk_ir::TyKind::Closure(chalk_ir::ClosureId(def_id), substs.lower_into(interner)) } - Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner), - Opaque(def_id, substs) => { - TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { + ty::Generator(_def_id, _substs, _) => unimplemented!(), + ty::GeneratorWitness(_) => unimplemented!(), + ty::Never => chalk_ir::TyKind::Never, + ty::Tuple(substs) => chalk_ir::TyKind::Tuple(substs.len(), substs.lower_into(interner)), + ty::Projection(proj) => chalk_ir::TyKind::Alias(proj.lower_into(interner)), + ty::Opaque(def_id, substs) => { + chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id: chalk_ir::OpaqueTyId(def_id), substitution: substs.lower_into(interner), })) - .intern(interner) } // This should have been done eagerly prior to this, and all Params // should have been substituted to placeholders - Param(_) => panic!("Lowering Param when not expected."), - Bound(db, bound) => TyData::BoundVar(chalk_ir::BoundVar::new( + ty::Param(_) => panic!("Lowering Param when not expected."), + ty::Bound(db, bound) => chalk_ir::TyKind::BoundVar(chalk_ir::BoundVar::new( chalk_ir::DebruijnIndex::new(db.as_u32()), bound.var.index(), - )) - .intern(interner), - Placeholder(_placeholder) => TyData::Placeholder(chalk_ir::PlaceholderIndex { - ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() }, - idx: _placeholder.name.as_usize(), - }) - .intern(interner), - Infer(_infer) => unimplemented!(), - Error(_) => apply(chalk_ir::TypeName::Error, empty()), + )), + ty::Placeholder(_placeholder) => { + chalk_ir::TyKind::Placeholder(chalk_ir::PlaceholderIndex { + ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() }, + idx: _placeholder.name.as_usize(), + }) + } + ty::Infer(_infer) => unimplemented!(), + ty::Error(_) => chalk_ir::TyKind::Error, } + .intern(interner) } } impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { fn lower_into(self, interner: &RustInterner<'tcx>) -> Ty<'tcx> { - use chalk_ir::TyData; - use rustc_ast::ast; + use chalk_ir::TyKind; - let kind = match self.data(interner) { - TyData::Apply(application_ty) => match application_ty.name { - chalk_ir::TypeName::Adt(struct_id) => { - ty::Adt(struct_id.0, application_ty.substitution.lower_into(interner)) - } - chalk_ir::TypeName::Scalar(scalar) => match scalar { - chalk_ir::Scalar::Bool => ty::Bool, - chalk_ir::Scalar::Char => ty::Char, - chalk_ir::Scalar::Int(int_ty) => match int_ty { - chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize), - chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8), - chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16), - chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32), - chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64), - chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128), - }, - chalk_ir::Scalar::Uint(int_ty) => match int_ty { - chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize), - chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8), - chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16), - chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32), - chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64), - chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128), - }, - chalk_ir::Scalar::Float(float_ty) => match float_ty { - chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32), - chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64), - }, + let kind = match self.kind(interner) { + TyKind::Adt(struct_id, substitution) => { + ty::Adt(struct_id.0, substitution.lower_into(interner)) + } + TyKind::Scalar(scalar) => match scalar { + chalk_ir::Scalar::Bool => ty::Bool, + chalk_ir::Scalar::Char => ty::Char, + chalk_ir::Scalar::Int(int_ty) => match int_ty { + chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize), + chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8), + chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16), + chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32), + chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64), + chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128), + }, + chalk_ir::Scalar::Uint(int_ty) => match int_ty { + chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize), + chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8), + chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16), + chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32), + chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64), + chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128), + }, + chalk_ir::Scalar::Float(float_ty) => match float_ty { + chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32), + chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64), }, - chalk_ir::TypeName::Array => { - let substs = application_ty.substitution.as_slice(interner); - let ty = substs[0].assert_ty_ref(interner).lower_into(interner); - let c = substs[1].assert_const_ref(interner).lower_into(interner); - ty::Array(ty, interner.tcx.mk_const(c)) - } - chalk_ir::TypeName::FnDef(id) => { - ty::FnDef(id.0, application_ty.substitution.lower_into(interner)) - } - chalk_ir::TypeName::Closure(closure) => { - ty::Closure(closure.0, application_ty.substitution.lower_into(interner)) - } - chalk_ir::TypeName::Generator(_) => unimplemented!(), - chalk_ir::TypeName::GeneratorWitness(_) => unimplemented!(), - chalk_ir::TypeName::Never => ty::Never, - chalk_ir::TypeName::Tuple(_size) => { - ty::Tuple(application_ty.substitution.lower_into(interner)) - } - chalk_ir::TypeName::Slice => ty::Slice( - application_ty.substitution.as_slice(interner)[0] - .ty(interner) - .unwrap() - .lower_into(interner), - ), - chalk_ir::TypeName::Raw(mutbl) => ty::RawPtr(ty::TypeAndMut { - ty: application_ty.substitution.as_slice(interner)[0] - .ty(interner) - .unwrap() - .lower_into(interner), - mutbl: match mutbl { - chalk_ir::Mutability::Mut => ast::Mutability::Mut, - chalk_ir::Mutability::Not => ast::Mutability::Not, - }, - }), - chalk_ir::TypeName::Ref(mutbl) => ty::Ref( - application_ty.substitution.as_slice(interner)[0] - .lifetime(interner) - .unwrap() - .lower_into(interner), - application_ty.substitution.as_slice(interner)[1] - .ty(interner) - .unwrap() - .lower_into(interner), - match mutbl { - chalk_ir::Mutability::Mut => ast::Mutability::Mut, - chalk_ir::Mutability::Not => ast::Mutability::Not, - }, - ), - chalk_ir::TypeName::Str => ty::Str, - chalk_ir::TypeName::OpaqueType(opaque_ty) => { - ty::Opaque(opaque_ty.0, application_ty.substitution.lower_into(interner)) - } - chalk_ir::TypeName::AssociatedType(assoc_ty) => ty::Projection(ty::ProjectionTy { - substs: application_ty.substitution.lower_into(interner), - item_def_id: assoc_ty.0, - }), - chalk_ir::TypeName::Foreign(def_id) => ty::Foreign(def_id.0), - chalk_ir::TypeName::Error => unimplemented!(), }, - TyData::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { + TyKind::Array(ty, c) => { + let ty = ty.lower_into(interner); + let c = c.lower_into(interner); + ty::Array(ty, interner.tcx.mk_const(c)) + } + TyKind::FnDef(id, substitution) => ty::FnDef(id.0, substitution.lower_into(interner)), + TyKind::Closure(closure, substitution) => { + ty::Closure(closure.0, substitution.lower_into(interner)) + } + TyKind::Generator(..) => unimplemented!(), + TyKind::GeneratorWitness(..) => unimplemented!(), + TyKind::Never => ty::Never, + TyKind::Tuple(_len, substitution) => ty::Tuple(substitution.lower_into(interner)), + TyKind::Slice(ty) => ty::Slice(ty.lower_into(interner)), + TyKind::Raw(mutbl, ty) => ty::RawPtr(ty::TypeAndMut { + ty: ty.lower_into(interner), + mutbl: mutbl.lower_into(interner), + }), + TyKind::Ref(mutbl, lifetime, ty) => ty::Ref( + lifetime.lower_into(interner), + ty.lower_into(interner), + mutbl.lower_into(interner), + ), + TyKind::Str => ty::Str, + TyKind::OpaqueType(opaque_ty, substitution) => { + ty::Opaque(opaque_ty.0, substitution.lower_into(interner)) + } + TyKind::AssociatedType(assoc_ty, substitution) => ty::Projection(ty::ProjectionTy { + substs: substitution.lower_into(interner), + item_def_id: assoc_ty.0, + }), + TyKind::Foreign(def_id) => ty::Foreign(def_id.0), + TyKind::Error => return interner.tcx.ty_error(), + TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { universe: ty::UniverseIndex::from_usize(placeholder.ui.counter), name: ty::BoundVar::from_usize(placeholder.idx), }), - chalk_ir::TyData::Alias(alias_ty) => match alias_ty { + TyKind::Alias(alias_ty) => match alias_ty { chalk_ir::AliasTy::Projection(projection) => ty::Projection(ty::ProjectionTy { item_def_id: projection.associated_ty_id.0, substs: projection.substitution.lower_into(interner), @@ -506,16 +421,16 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { ty::Opaque(opaque.opaque_ty_id.0, opaque.substitution.lower_into(interner)) } }, - TyData::Function(_quantified_ty) => unimplemented!(), - TyData::BoundVar(_bound) => ty::Bound( + TyKind::Function(_quantified_ty) => unimplemented!(), + TyKind::BoundVar(_bound) => ty::Bound( ty::DebruijnIndex::from_usize(_bound.debruijn.depth() as usize), ty::BoundTy { var: ty::BoundVar::from_usize(_bound.index), kind: ty::BoundTyKind::Anon, }, ), - TyData::InferenceVar(_, _) => unimplemented!(), - TyData::Dyn(_) => unimplemented!(), + TyKind::InferenceVar(_, _) => unimplemented!(), + TyKind::Dyn(_) => unimplemented!(), }; interner.tcx.mk_ty(kind) } @@ -706,8 +621,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru self, interner: &RustInterner<'tcx>, ) -> chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>> { + // `Self` has one binder: + // Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>> + // The return type has two: + // Binders<&[Binders<WhereClause<I>>]> + // This means that any variables that are escaping `self` need to be + // shifted in by one so that they are still escaping. + let shifted_predicates = ty::fold::shift_vars(interner.tcx, &self, 1); + let (predicates, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &self); + collect_bound_vars(interner, interner.tcx, &shifted_predicates); let self_ty = interner.tcx.mk_ty(ty::Bound( // This is going to be wrapped in a binder ty::DebruijnIndex::from_usize(1), @@ -716,7 +639,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru let where_clauses = predicates.into_iter().map(|predicate| match predicate { ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { chalk_ir::Binders::new( - chalk_ir::VariableKinds::empty(interner), + binders.clone(), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(def_id), substitution: interner @@ -727,25 +650,34 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru ) } ty::ExistentialPredicate::Projection(predicate) => chalk_ir::Binders::new( - chalk_ir::VariableKinds::empty(interner), + binders.clone(), chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { associated_ty_id: chalk_ir::AssocTypeId(predicate.item_def_id), - substitution: predicate.substs.lower_into(interner), + substitution: interner + .tcx + .mk_substs_trait(self_ty, predicate.substs) + .lower_into(interner), }), ty: predicate.ty.lower_into(interner), }), ), ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( - chalk_ir::VariableKinds::empty(interner), + binders.clone(), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(def_id), substitution: interner.tcx.mk_substs_trait(self_ty, &[]).lower_into(interner), }), ), }); + + // Binder for the bound variable representing the concrete underlying type. + let existential_binder = chalk_ir::VariableKinds::from1( + interner, + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), + ); let value = chalk_ir::QuantifiedWhereClauses::from_iter(interner, where_clauses); - chalk_ir::Binders::new(binders, value) + chalk_ir::Binders::new(existential_binder, value) } } @@ -818,6 +750,35 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::TraitBound<RustInterner<'tcx>>> } } +impl<'tcx> LowerInto<'tcx, chalk_ir::Mutability> for ast::Mutability { + fn lower_into(self, _interner: &RustInterner<'tcx>) -> chalk_ir::Mutability { + match self { + rustc_ast::Mutability::Mut => chalk_ir::Mutability::Mut, + rustc_ast::Mutability::Not => chalk_ir::Mutability::Not, + } + } +} + +impl<'tcx> LowerInto<'tcx, ast::Mutability> for chalk_ir::Mutability { + fn lower_into(self, _interner: &RustInterner<'tcx>) -> ast::Mutability { + match self { + chalk_ir::Mutability::Mut => ast::Mutability::Mut, + chalk_ir::Mutability::Not => ast::Mutability::Not, + } + } +} + +impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::Polarity> for ty::ImplPolarity { + fn lower_into(self, _interner: &RustInterner<'tcx>) -> chalk_solve::rust_ir::Polarity { + match self { + ty::ImplPolarity::Positive => chalk_solve::rust_ir::Polarity::Positive, + ty::ImplPolarity::Negative => chalk_solve::rust_ir::Polarity::Negative, + // FIXME(chalk) reservation impls + ty::ImplPolarity::Reservation => chalk_solve::rust_ir::Polarity::Negative, + } + } +} + impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>>> for ty::ProjectionPredicate<'tcx> { @@ -910,7 +871,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { match self.parameters.entry(bound_ty.var.as_u32()) { Entry::Vacant(entry) => { - entry.insert(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)); + entry.insert(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)); } Entry::Occupied(entry) => match entry.get() { chalk_ir::VariableKind::Ty(_) => {} diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index f174a92274e..b117e28875e 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -69,15 +69,15 @@ crate fn evaluate_goal<'tcx>( CanonicalVarKind::PlaceholderRegion(_ui) => unimplemented!(), CanonicalVarKind::Ty(ty) => match ty { CanonicalTyVarKind::General(ui) => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General), + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), chalk_ir::UniverseIndex { counter: ui.index() }, ), CanonicalTyVarKind::Int => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyKind::Integer), + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Integer), chalk_ir::UniverseIndex::root(), ), CanonicalTyVarKind::Float => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyKind::Float), + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Float), chalk_ir::UniverseIndex::root(), ), }, @@ -97,7 +97,8 @@ crate fn evaluate_goal<'tcx>( use chalk_solve::Solver; let mut solver = chalk_engine::solve::SLGSolver::new(32, None); let db = ChalkRustIrDatabase { interner, reempty_placeholder }; - let solution = chalk_solve::logging::with_tracing_logs(|| solver.solve(&db, &lowered_goal)); + let solution = solver.solve(&db, &lowered_goal); + debug!(?obligation, ?solution, "evaluatate goal"); // Ideally, the code to convert *back* to rustc types would live close to // the code to convert *from* rustc types. Right now though, we don't diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 324aa1a66a6..af19ad08c1d 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -718,39 +718,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - fn is_destructuring_place_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> bool { - match &expr.kind { - ExprKind::Array(comps) | ExprKind::Tup(comps) => { - comps.iter().all(|e| self.is_destructuring_place_expr(e)) - } - ExprKind::Struct(_path, fields, rest) => { - rest.as_ref().map(|e| self.is_destructuring_place_expr(e)).unwrap_or(true) - && fields.iter().all(|f| self.is_destructuring_place_expr(&f.expr)) - } - _ => expr.is_syntactic_place_expr(), - } - } - pub(crate) fn check_lhs_assignable( &self, lhs: &'tcx hir::Expr<'tcx>, err_code: &'static str, expr_span: &Span, ) { - if !lhs.is_syntactic_place_expr() { - // FIXME: Make this use SessionDiagnostic once error codes can be dynamically set. - let mut err = self.tcx.sess.struct_span_err_with_code( - *expr_span, - "invalid left-hand side of assignment", - DiagnosticId::Error(err_code.into()), - ); - err.span_label(lhs.span, "cannot assign to this expression"); - if self.is_destructuring_place_expr(lhs) { - err.note("destructuring assignments are not currently supported"); - err.note("for more information, see https://github.com/rust-lang/rfcs/issues/372"); - } - err.emit(); + if lhs.is_syntactic_place_expr() { + return; } + + // FIXME: Make this use SessionDiagnostic once error codes can be dynamically set. + let mut err = self.tcx.sess.struct_span_err_with_code( + *expr_span, + "invalid left-hand side of assignment", + DiagnosticId::Error(err_code.into()), + ); + err.span_label(lhs.span, "cannot assign to this expression"); + err.emit(); } /// Type check assignment expression `expr` of form `lhs = rhs`. diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index f76f42dea1e..6489b7838d6 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -270,6 +270,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`. fn calc_adjust_mode(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> AdjustMode { + // When we perform destructuring assignment, we disable default match bindings, which are + // unintuitive in this context. + if !pat.default_binding_modes { + return AdjustMode::Reset; + } match &pat.kind { // Type checking these product-like types successfully always require // that the expected type be of those types and not reference types. diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index ba0f22513a1..7b31b9f3915 100644 --- a/compiler/rustc_typeck/src/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs @@ -577,7 +577,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { fn link_pattern(&self, discr_cmt: PlaceWithHirId<'tcx>, root_pat: &hir::Pat<'_>) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", discr_cmt, root_pat); ignore_err!(self.with_mc(|mc| { - mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id }| { + mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id, .. }| { // `ref x` pattern if let PatKind::Binding(..) = kind { if let Some(ty::BindByReference(mutbl)) = diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs index 9c29ceeb593..e596dd1a396 100644 --- a/compiler/rustc_typeck/src/collect/item_bounds.rs +++ b/compiler/rustc_typeck/src/collect/item_bounds.rs @@ -61,23 +61,23 @@ fn opaque_type_bounds<'tcx>( bounds: &'tcx [hir::GenericBound<'tcx>], span: Span, ) -> &'tcx [(ty::Predicate<'tcx>, Span)] { - let item_ty = - tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id)); + ty::print::with_no_queries(|| { + let item_ty = + tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id)); - let bounds = ty::print::with_no_queries(|| { - AstConv::compute_bounds( + let bounds = AstConv::compute_bounds( &ItemCtxt::new(tcx, opaque_def_id), item_ty, bounds, SizedByDefault::Yes, span, ) - }); + .predicates(tcx, item_ty); - let bounds = bounds.predicates(tcx, item_ty); - debug!("opaque_type_bounds({}) = {:?}", tcx.def_path_str(opaque_def_id), bounds); + debug!("opaque_type_bounds({}) = {:?}", tcx.def_path_str(opaque_def_id), bounds); - tcx.arena.alloc_slice(&bounds) + tcx.arena.alloc_slice(&bounds) + }) } pub(super) fn explicit_item_bounds( diff --git a/config.toml.example b/config.toml.example index 1edb390e0fe..1dcc5f13415 100644 --- a/config.toml.example +++ b/config.toml.example @@ -138,6 +138,9 @@ changelog-seen = 2 # Whether or not to specify `-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=YES` #allow-old-toolchain = false +# Whether to include the Polly optimizer. +#polly = false + # ============================================================================= # General build configuration options # ============================================================================= diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index d5b1c600d93..4fea6adf541 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -42,7 +42,7 @@ fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T> } } -impl<'a, K: 'a, V: 'a> BTreeMap<K, V> { +impl<K, V> BTreeMap<K, V> { /// Panics if the map (or the code navigating it) is corrupted. fn check(&self) where @@ -54,14 +54,14 @@ impl<'a, K: 'a, V: 'a> BTreeMap<K, V> { assert!(root_node.ascend().is_err()); root_node.assert_back_pointers(); - let counted = root_node.assert_ascending(); - assert_eq!(self.length, counted); assert_eq!(self.length, root_node.calc_length()); root_node.assert_min_len(if root_node.height() > 0 { 1 } else { 0 }); } else { assert_eq!(self.length, 0); } + + self.assert_ascending(); } /// Returns the height of the root, if any. @@ -79,10 +79,28 @@ impl<'a, K: 'a, V: 'a> BTreeMap<K, V> { String::from("not yet allocated") } } + + /// Asserts that the keys are in strictly ascending order. + fn assert_ascending(&self) + where + K: Copy + Debug + Ord, + { + let mut num_seen = 0; + let mut keys = self.keys(); + if let Some(mut previous) = keys.next() { + num_seen = 1; + for next in keys { + assert!(previous < next, "{:?} >= {:?}", previous, next); + previous = next; + num_seen += 1; + } + } + assert_eq!(num_seen, self.len()); + } } impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> { - pub fn assert_min_len(self, min_len: usize) { + fn assert_min_len(self, min_len: usize) { assert!(self.len() >= min_len, "{} < {}", self.len(), min_len); if let node::ForceResult::Internal(node) = self.force() { for idx in 0..=node.len() { diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index c8d3de9e5cd..dbf9031620e 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -32,7 +32,6 @@ use core::cmp::Ordering; use core::marker::PhantomData; use core::mem::{self, MaybeUninit}; use core::ptr::{self, NonNull, Unique}; -use core::slice; use crate::alloc::{AllocRef, Global, Layout}; use crate::boxed::Box; @@ -120,11 +119,11 @@ struct BoxedNode<K, V> { impl<K, V> BoxedNode<K, V> { fn from_leaf(node: Box<LeafNode<K, V>>) -> Self { - BoxedNode { ptr: Box::into_unique(node).0 } + BoxedNode { ptr: Unique::from(Box::leak(node)) } } fn from_internal(node: Box<InternalNode<K, V>>) -> Self { - BoxedNode { ptr: Unique::from(&mut Box::leak(node).data) } + BoxedNode { ptr: Unique::from(Box::leak(node)).cast() } } fn as_ptr(&self) -> NonNull<LeafNode<K, V>> { @@ -189,6 +188,11 @@ impl<K, V> Root<K, V> { NodeRef { height: self.height, node: self.node.as_ptr(), _marker: PhantomData } } + /// Packs the reference, aware of type and height, into a type-agnostic pointer. + fn into_boxed_node(self) -> BoxedNode<K, V> { + self.node + } + /// Adds a new internal node with a single edge pointing to the previous root node, /// make that new node the root node, and return it. This increases the height by 1 /// and is the opposite of `pop_internal_level`. @@ -218,15 +222,16 @@ impl<K, V> Root<K, V> { pub fn pop_internal_level(&mut self) { assert!(self.height > 0); - let top = self.node.ptr; + let top = BoxedNode::as_ptr(&self.node); let mut internal_node = unsafe { self.internal_node_as_mut() }; - self.node = unsafe { internal_node.as_internal_mut().edges[0].assume_init_read() }; + let internal_node = NodeRef::as_internal_mut(&mut internal_node); + self.node = unsafe { internal_node.edges[0].assume_init_read() }; self.height -= 1; - self.node_as_mut().as_leaf_mut().parent = None; + self.node_as_mut().clear_parent_link(); unsafe { - Global.dealloc(NonNull::from(top).cast(), Layout::new::<InternalNode<K, V>>()); + Global.dealloc(top.cast(), Layout::new::<InternalNode<K, V>>()); } } } @@ -236,21 +241,49 @@ impl<K, V> Root<K, V> { // internal use of `NodeRef` because we stay completely generic over `K` and `V`. // However, whenever a public type wraps `NodeRef`, make sure that it has the // correct variance. +/// /// A reference to a node. /// /// This type has a number of parameters that controls how it acts: -/// - `BorrowType`: This can be `Immut<'a>`, `Mut<'a>` or `ValMut<'a>' for some `'a` -/// or `Owned`. -/// When this is `Immut<'a>`, the `NodeRef` acts roughly like `&'a Node`, -/// when this is `Mut<'a>`, the `NodeRef` acts roughly like `&'a mut Node`, -/// when this is `ValMut<'a>`, the `NodeRef` acts as immutable with respect -/// to keys and tree structure, but allows mutable references to values, -/// and when this is `Owned`, the `NodeRef` acts roughly like `Box<Node>`. -/// - `K` and `V`: These control what types of things are stored in the nodes. +/// - `BorrowType`: A dummy type that describes the kind of borrow and carries a lifetime. +/// - When this is `Immut<'a>`, the `NodeRef` acts roughly like `&'a Node`. +/// - When this is `ValMut<'a>`, the `NodeRef` acts roughly like `&'a Node` +/// with respect to keys and tree structure, but also allows many +/// mutable references to values throughout the tree to coexist. +/// - When this is `Mut<'a>`, the `NodeRef` acts roughly like `&'a mut Node`, +/// although insert methods allow a mutable pointer to a value to coexist. +/// - When this is `Owned`, the `NodeRef` acts roughly like `Box<Node>`, +/// but does not have a destructor, and must be cleaned up manually. +/// - `K` and `V`: These are the types of keys and values stored in the nodes. /// - `Type`: This can be `Leaf`, `Internal`, or `LeafOrInternal`. When this is /// `Leaf`, the `NodeRef` points to a leaf node, when this is `Internal` the /// `NodeRef` points to an internal node, and when this is `LeafOrInternal` the /// `NodeRef` could be pointing to either type of node. +/// `Type` is named `NodeType` when used outside `NodeRef`. +/// +/// Both `BorrowType` and `NodeType` restrict what methods we implement, to +/// exploit static type safety. There are limitations in the way we can apply +/// such restrictions: +/// - For each type parameter, we can only define a method either generically +/// or for one particular type. For example, we cannot define a method like +/// `key_at` generically for all `BorrowType`, because we want to return +/// `&'a K` for most choices of `BorrowType`, but plain `K` for `Owned`. +/// We cannot define `key_at` once for all types that have a lifetime. +/// Therefore, we define it only for the least powerful type `Immut<'a>`. +/// - We cannot get implicit coercion from say `Mut<'a>` to `Immut<'a>`. +/// Therefore, we have to explicitly call `reborrow` on a more powerfull +/// `NodeRef` in order to reach a method like `key_at`. +/// - All methods on `NodeRef` that return some kind of reference, except +/// `reborrow` and `reborrow_mut`, take `self` by value and not by reference. +/// This avoids silently returning a second reference somewhere in the tree. +/// That is irrelevant when `BorrowType` is `Immut<'a>`, but the rule does +/// no harm because we make those `NodeRef` implicitly `Copy`. +/// The rule also avoids implicitly returning the lifetime of `&self`, +/// instead of the lifetime contained in `BorrowType`. +/// An exception to this rule are the insert functions. +/// - Given the above, we need a `reborrow_mut` to explicitly copy a `Mut<'a>` +/// `NodeRef` whenever we want to invoke a method returning an extra reference +/// somewhere in the tree. pub struct NodeRef<BorrowType, K, V, Type> { /// The number of levels below the node, a property of the node that cannot be /// entirely described by `Type` and that the node does not store itself either. @@ -277,30 +310,45 @@ unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send for NodeRef<marker::Mut<' unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send for NodeRef<marker::ValMut<'a>, K, V, Type> {} unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Owned, K, V, Type> {} +impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> { + /// Unpack a node reference that was packed by `Root::into_boxed_node`. + fn from_boxed_node(boxed_node: BoxedNode<K, V>, height: usize) -> Self { + NodeRef { height, node: boxed_node.as_ptr(), _marker: PhantomData } + } +} + +impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> { + /// Unpack a node reference that was packed as `NodeRef::parent`. + fn from_internal(node: NonNull<InternalNode<K, V>>, height: usize) -> Self { + debug_assert!(height > 0); + NodeRef { height, node: node.cast(), _marker: PhantomData } + } +} + impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> { - /// Exposes the data of an internal node for reading. + /// Exposes the data of an internal node. /// - /// Returns a raw ptr to avoid invalidating other references to this node, - /// which is possible when BorrowType is marker::ValMut. - fn as_internal_ptr(&self) -> *const InternalNode<K, V> { - self.node.as_ptr() as *const InternalNode<K, V> + /// Returns a raw ptr to avoid invalidating other references to this node. + fn as_internal_ptr(this: &Self) -> *mut InternalNode<K, V> { + // SAFETY: the static node type is `Internal`. + this.node.as_ptr() as *mut InternalNode<K, V> } } -impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { - /// Exposes the data of an internal node for reading, - /// when we know we have exclusive access. - fn as_internal(&mut self) -> &InternalNode<K, V> { - unsafe { &*self.as_internal_ptr() } +impl<'a, K, V> NodeRef<marker::Immut<'a>, K, V, marker::Internal> { + /// Exposes the data of an internal node in an immutable tree. + fn as_internal(this: &Self) -> &'a InternalNode<K, V> { + let ptr = Self::as_internal_ptr(this); + // SAFETY: there can be no mutable references into this tree borrowed as `Immut`. + unsafe { &*ptr } } } impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { - /// Exposes the data of an internal node for writing. - /// - /// We don't need to return a raw ptr because we have unique access to the entire node. - fn as_internal_mut(&mut self) -> &mut InternalNode<K, V> { - unsafe { &mut *(self.node.as_ptr() as *mut InternalNode<K, V>) } + /// Offers exclusive access to the data of an internal node. + fn as_internal_mut(this: &mut Self) -> &'a mut InternalNode<K, V> { + let ptr = Self::as_internal_ptr(this); + unsafe { &mut *ptr } } } @@ -312,7 +360,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { pub fn len(&self) -> usize { // Crucially, we only access the `len` field here. If BorrowType is marker::ValMut, // there might be outstanding mutable references to values that we must not invalidate. - unsafe { usize::from((*self.as_leaf_ptr()).len) } + unsafe { usize::from((*Self::as_leaf_ptr(self)).len) } } /// Returns the height of this node with respect to the leaf level. Zero height means the @@ -322,48 +370,49 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { } /// Temporarily takes out another, immutable reference to the same node. - fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> { + pub fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> { NodeRef { height: self.height, node: self.node, _marker: PhantomData } } /// Exposes the leaf portion of any leaf or internal node. /// - /// Returns a raw ptr to avoid invalidating other references to this node, - /// which is possible when BorrowType is marker::ValMut. - fn as_leaf_ptr(&self) -> *const LeafNode<K, V> { + /// Returns a raw ptr to avoid invalidating other references to this node. + fn as_leaf_ptr(this: &Self) -> *mut LeafNode<K, V> { // The node must be valid for at least the LeafNode portion. // This is not a reference in the NodeRef type because we don't know if // it should be unique or shared. - self.node.as_ptr() + this.node.as_ptr() } +} - /// Borrows a reference to one of the keys stored in the node. +impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { + /// Exposes one of the keys stored in the node. /// /// # Safety /// The node has more than `idx` initialized elements. - pub unsafe fn key_at(&self, idx: usize) -> &K { - unsafe { self.reborrow().into_key_at(idx) } + pub unsafe fn key_at(self, idx: usize) -> &'a K { + debug_assert!(idx < self.len()); + unsafe { Self::as_leaf(&self).keys.get_unchecked(idx).assume_init_ref() } } - /// Borrows a reference to one of the values stored in the node. + /// Exposes one of the values stored in the node. /// /// # Safety /// The node has more than `idx` initialized elements. - unsafe fn val_at(&self, idx: usize) -> &V { - unsafe { self.reborrow().into_val_at(idx) } + unsafe fn val_at(self, idx: usize) -> &'a V { + debug_assert!(idx < self.len()); + unsafe { Self::as_leaf(&self).vals.get_unchecked(idx).assume_init_ref() } } } -impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> { - /// Borrows a reference to the contents of one of the edges that delimit - /// the elements of the node, without invalidating other references. +impl<'a, K, V> NodeRef<marker::Immut<'a>, K, V, marker::Internal> { + /// Exposes the contents of one of the edges in the node. /// /// # Safety /// The node has more than `idx` initialized elements. - unsafe fn edge_at(&self, idx: usize) -> &BoxedNode<K, V> { + unsafe fn edge_at(self, idx: usize) -> &'a BoxedNode<K, V> { debug_assert!(idx <= self.len()); - let node = self.as_internal_ptr(); - unsafe { (*node).edges.get_unchecked(idx).assume_init_ref() } + unsafe { Self::as_internal(&self).edges.get_unchecked(idx).assume_init_ref() } } } @@ -380,15 +429,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { ) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> { // We need to use raw pointers to nodes because, if BorrowType is marker::ValMut, // there might be outstanding mutable references to values that we must not invalidate. - let leaf_ptr = self.as_leaf_ptr(); + let leaf_ptr: *const _ = Self::as_leaf_ptr(&self); unsafe { (*leaf_ptr).parent } .as_ref() .map(|parent| Handle { - node: NodeRef { - height: self.height + 1, - node: parent.cast(), - _marker: PhantomData, - }, + node: NodeRef::from_internal(*parent, self.height + 1), idx: unsafe { usize::from((*leaf_ptr).parent_idx.assume_init()) }, _marker: PhantomData, }) @@ -420,11 +465,11 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> { } impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { - /// Exposes the data of a leaf node for reading in an immutable tree. - fn into_leaf(self) -> &'a LeafNode<K, V> { - // SAFETY: we can access the entire node freely and do no need raw pointers, - // because there can be no mutable references to this Immut tree. - unsafe { &(*self.as_leaf_ptr()) } + /// Exposes the leaf portion of any leaf or internal node in an immutable tree. + fn as_leaf(this: &Self) -> &'a LeafNode<K, V> { + let ptr = Self::as_leaf_ptr(this); + // SAFETY: there can be no mutable references into this tree borrowed as `Immut`. + unsafe { &*ptr } } } @@ -473,139 +518,155 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> { NodeRef { height: self.height, node: self.node, _marker: PhantomData } } - /// Exposes the leaf portion of any leaf or internal node for writing. - /// - /// We don't need to return a raw ptr because we have unique access to the entire node. - fn as_leaf_mut(&mut self) -> &'a mut LeafNode<K, V> { - unsafe { &mut (*self.node.as_ptr()) } + /// Offers exclusive access to the leaf portion of any leaf or internal node. + fn as_leaf_mut(this: &mut Self) -> &'a mut LeafNode<K, V> { + let ptr = Self::as_leaf_ptr(this); + // SAFETY: we have exclusive access to the entire node. + unsafe { &mut *ptr } } +} - /// Borrows a mutable reference to one of the keys stored in the node. +impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { + /// Offers exclusive access to a part of the key storage area. /// /// # Safety /// The node has more than `idx` initialized elements. - unsafe fn key_mut_at(&mut self, idx: usize) -> &mut K { - unsafe { self.reborrow_mut().into_key_mut_at(idx) } + unsafe fn into_key_area_mut_at(mut self, idx: usize) -> &'a mut MaybeUninit<K> { + debug_assert!(idx < self.len()); + unsafe { Self::as_leaf_mut(&mut self).keys.get_unchecked_mut(idx) } } - /// Borrows a mutable reference to one of the values stored in the node. + /// Offers exclusive access to a part of the value storage area. /// /// # Safety /// The node has more than `idx` initialized elements. - unsafe fn val_mut_at(&mut self, idx: usize) -> &mut V { - unsafe { self.reborrow_mut().into_val_mut_at(idx) } - } - - fn keys_mut(&mut self) -> &mut [K] - where - K: 'a, - V: 'a, - { - // SAFETY: the caller will not be able to call further methods on self - // until the key slice reference is dropped, as we have unique access - // for the lifetime of the borrow. - // SAFETY: The keys of a node must always be initialized up to length. - unsafe { - slice::from_raw_parts_mut( - MaybeUninit::slice_as_mut_ptr(&mut self.as_leaf_mut().keys), - self.len(), - ) - } - } - - fn vals_mut(&mut self) -> &mut [V] - where - K: 'a, - V: 'a, - { - // SAFETY: the caller will not be able to call further methods on self - // until the value slice reference is dropped, as we have unique access - // for the lifetime of the borrow. - // SAFETY: The values of a node must always be initialized up to length. - unsafe { - slice::from_raw_parts_mut( - MaybeUninit::slice_as_mut_ptr(&mut self.as_leaf_mut().vals), - self.len(), - ) - } + unsafe fn into_val_area_mut_at(mut self, idx: usize) -> &'a mut MaybeUninit<V> { + debug_assert!(idx < self.len()); + unsafe { Self::as_leaf_mut(&mut self).vals.get_unchecked_mut(idx) } } } -impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { - fn edges_mut(&mut self) -> &mut [BoxedNode<K, V>] { - unsafe { - slice::from_raw_parts_mut( - MaybeUninit::slice_as_mut_ptr(&mut self.as_internal_mut().edges), - self.len() + 1, - ) - } +impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { + /// Offers exclusive access to a part of the storage area for edge contents. + /// + /// # Safety + /// The node has at least `idx` initialized elements. + unsafe fn into_edge_area_mut_at(mut self, idx: usize) -> &'a mut MaybeUninit<BoxedNode<K, V>> { + debug_assert!(idx <= self.len()); + unsafe { Self::as_internal_mut(&mut self).edges.get_unchecked_mut(idx) } } } impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> { - /// # Safety - /// The node has more than `idx` initialized elements. - unsafe fn into_key_at(self, idx: usize) -> &'a K { - unsafe { self.into_leaf().keys.get_unchecked(idx).assume_init_ref() } + /// Exposes the entire key storage area in the node, + /// regardless of the node's current length, + /// having exclusive access to the entire node. + unsafe fn key_area(self) -> &'a [MaybeUninit<K>] { + Self::as_leaf(&self).keys.as_slice() } - /// # Safety - /// The node has more than `idx` initialized elements. - unsafe fn into_val_at(self, idx: usize) -> &'a V { - unsafe { self.into_leaf().vals.get_unchecked(idx).assume_init_ref() } + /// Exposes the entire value storage area in the node, + /// regardless of the node's current length, + /// having exclusive access to the entire node. + unsafe fn val_area(self) -> &'a [MaybeUninit<V>] { + Self::as_leaf(&self).vals.as_slice() } } -impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { - /// # Safety - /// The node has more than `idx` initialized elements. - unsafe fn into_key_mut_at(mut self, idx: usize) -> &'a mut K { - debug_assert!(idx < self.len()); +impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::Internal> { + /// Exposes the entire storage area for edge contents in the node, + /// regardless of the node's current length, + /// having exclusive access to the entire node. + unsafe fn edge_area(self) -> &'a [MaybeUninit<BoxedNode<K, V>>] { + Self::as_internal(&self).edges.as_slice() + } +} - let leaf = self.as_leaf_mut(); - unsafe { leaf.keys.get_unchecked_mut(idx).assume_init_mut() } +impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { + /// Offers exclusive access to a sized slice of key storage area in the node. + unsafe fn into_key_area_slice(mut self) -> &'a mut [MaybeUninit<K>] { + let len = self.len(); + // SAFETY: the caller will not be able to call further methods on self + // until the key slice reference is dropped, as we have unique access + // for the lifetime of the borrow. + unsafe { Self::as_leaf_mut(&mut self).keys.get_unchecked_mut(..len) } } - /// # Safety - /// The node has more than `idx` initialized elements. - unsafe fn into_val_mut_at(mut self, idx: usize) -> &'a mut V { - debug_assert!(idx < self.len()); + /// Offers exclusive access to a sized slice of value storage area in the node. + unsafe fn into_val_area_slice(mut self) -> &'a mut [MaybeUninit<V>] { + let len = self.len(); + // SAFETY: the caller will not be able to call further methods on self + // until the value slice reference is dropped, as we have unique access + // for the lifetime of the borrow. + unsafe { Self::as_leaf_mut(&mut self).vals.get_unchecked_mut(..len) } + } +} - let leaf = self.as_leaf_mut(); - unsafe { leaf.vals.get_unchecked_mut(idx).assume_init_mut() } +impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { + /// Offers exclusive access to a sized slice of storage area for edge contents in the node. + unsafe fn into_edge_area_slice(mut self) -> &'a mut [MaybeUninit<BoxedNode<K, V>>] { + let len = self.len(); + // SAFETY: the caller will not be able to call further methods on self + // until the edge slice reference is dropped, as we have unique access + // for the lifetime of the borrow. + unsafe { Self::as_internal_mut(&mut self).edges.get_unchecked_mut(..len + 1) } } } impl<'a, K, V, Type> NodeRef<marker::ValMut<'a>, K, V, Type> { /// # Safety - /// The node has more than `idx` initialized elements. - unsafe fn into_key_val_mut_at(self, idx: usize) -> (&'a K, &'a mut V) { + /// - The node has more than `idx` initialized elements. + /// - The keys and values of the node must be initialized up to its current length. + unsafe fn into_key_val_mut_at(mut self, idx: usize) -> (&'a K, &'a mut V) { // We only create a reference to the one element we are interested in, // to avoid aliasing with outstanding references to other elements, // in particular, those returned to the caller in earlier iterations. - let leaf = self.node.as_ptr(); + let leaf = Self::as_leaf_ptr(&mut self); let keys = unsafe { &raw const (*leaf).keys }; let vals = unsafe { &raw mut (*leaf).vals }; // We must coerce to unsized array pointers because of Rust issue #74679. let keys: *const [_] = keys; let vals: *mut [_] = vals; - // SAFETY: The keys and values of a node must always be initialized up to length. let key = unsafe { (&*keys.get_unchecked(idx)).assume_init_ref() }; let val = unsafe { (&mut *vals.get_unchecked_mut(idx)).assume_init_mut() }; (key, val) } } +impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { + /// Exposes exclusive access to the length of the node. + pub fn into_len_mut(mut self) -> &'a mut u16 { + &mut (*Self::as_leaf_mut(&mut self)).len + } +} + +impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { + /// Set or clear the node's link to its parent edge, + /// without invalidating other references to the node. + fn set_parent_link(&mut self, parent: NonNull<InternalNode<K, V>>, parent_idx: usize) { + let leaf = Self::as_leaf_ptr(self); + unsafe { (*leaf).parent = Some(parent) }; + unsafe { (*leaf).parent_idx.write(parent_idx as u16) }; + } + + /// Clear the node's link to its parent edge, freeing it from its tree. + /// This only makes sense when there are no other references to the node. + fn clear_parent_link(&mut self) { + let leaf = Self::as_leaf_mut(self); + leaf.parent = None; + } +} + impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> { /// Adds a key/value pair to the end of the node. pub fn push(&mut self, key: K, val: V) { - let len = &mut self.as_leaf_mut().len; + let len = unsafe { self.reborrow_mut().into_len_mut() }; let idx = usize::from(*len); assert!(idx < CAPACITY); *len += 1; unsafe { - ptr::write(self.key_mut_at(idx), key); - ptr::write(self.val_mut_at(idx), val); + self.reborrow_mut().into_key_area_mut_at(idx).write(key); + self.reborrow_mut().into_val_area_mut_at(idx).write(val); } } @@ -614,10 +675,10 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> { assert!(self.len() < CAPACITY); unsafe { - slice_insert(self.keys_mut(), 0, key); - slice_insert(self.vals_mut(), 0, val); + *self.reborrow_mut().into_len_mut() += 1; + slice_insert(self.reborrow_mut().into_key_area_slice(), 0, key); + slice_insert(self.reborrow_mut().into_val_area_slice(), 0, val); } - self.as_leaf_mut().len += 1; } } @@ -643,14 +704,14 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { pub fn push(&mut self, key: K, val: V, edge: Root<K, V>) { assert!(edge.height == self.height - 1); - let len = &mut self.as_leaf_mut().len; + let len = unsafe { self.reborrow_mut().into_len_mut() }; let idx = usize::from(*len); assert!(idx < CAPACITY); *len += 1; unsafe { - ptr::write(self.key_mut_at(idx), key); - ptr::write(self.val_mut_at(idx), val); - self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node); + self.reborrow_mut().into_key_area_mut_at(idx).write(key); + self.reborrow_mut().into_val_area_mut_at(idx).write(val); + self.reborrow_mut().into_edge_area_mut_at(idx + 1).write(edge.into_boxed_node()); Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link(); } } @@ -662,13 +723,12 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { assert!(self.len() < CAPACITY); unsafe { - slice_insert(self.keys_mut(), 0, key); - slice_insert(self.vals_mut(), 0, val); - slice_insert(self.edges_mut(), 0, edge.node); + *self.reborrow_mut().into_len_mut() += 1; + slice_insert(self.reborrow_mut().into_key_area_slice(), 0, key); + slice_insert(self.reborrow_mut().into_val_area_slice(), 0, val); + slice_insert(self.reborrow_mut().into_edge_area_slice(), 0, edge.into_boxed_node()); } - self.as_leaf_mut().len += 1; - self.correct_all_childrens_parent_links(); } } @@ -683,19 +743,21 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { let idx = self.len() - 1; unsafe { - let key = ptr::read(self.key_at(idx)); - let val = ptr::read(self.val_at(idx)); + let key = ptr::read(self.reborrow().key_at(idx)); + let val = ptr::read(self.reborrow().val_at(idx)); let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(internal) => { - let edge = ptr::read(internal.edge_at(idx + 1)); - let mut new_root = Root { node: edge, height: internal.height - 1 }; - new_root.node_as_mut().as_leaf_mut().parent = None; - Some(new_root) + let boxed_node = ptr::read(internal.reborrow().edge_at(idx + 1)); + let mut edge = Root { node: boxed_node, height: internal.height - 1 }; + // In practice, clearing the parent is a waste of time, because we will + // insert the node elsewhere and set its parent link again. + edge.node_as_mut().clear_parent_link(); + Some(edge) } }; - self.as_leaf_mut().len -= 1; + *self.reborrow_mut().into_len_mut() -= 1; (key, val, edge) } } @@ -709,29 +771,35 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { let old_len = self.len(); unsafe { - let key = slice_remove(self.keys_mut(), 0); - let val = slice_remove(self.vals_mut(), 0); + let key = slice_remove(self.reborrow_mut().into_key_area_slice(), 0); + let val = slice_remove(self.reborrow_mut().into_val_area_slice(), 0); let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(mut internal) => { - let edge = slice_remove(internal.edges_mut(), 0); - let mut new_root = Root { node: edge, height: internal.height - 1 }; - new_root.node_as_mut().as_leaf_mut().parent = None; + let boxed_node = + slice_remove(internal.reborrow_mut().into_edge_area_slice(), 0); + let mut edge = Root { node: boxed_node, height: internal.height - 1 }; + // In practice, clearing the parent is a waste of time, because we will + // insert the node elsewhere and set its parent link again. + edge.node_as_mut().clear_parent_link(); internal.correct_childrens_parent_links(0..old_len); - Some(new_root) + Some(edge) } }; - self.as_leaf_mut().len -= 1; + *self.reborrow_mut().into_len_mut() -= 1; (key, val, edge) } } fn into_kv_pointers_mut(mut self) -> (*mut K, *mut V) { - (self.keys_mut().as_mut_ptr(), self.vals_mut().as_mut_ptr()) + let leaf = Self::as_leaf_mut(&mut self); + let keys = MaybeUninit::slice_as_mut_ptr(&mut leaf.keys); + let vals = MaybeUninit::slice_as_mut_ptr(&mut leaf.vals); + (keys, vals) } } @@ -816,7 +884,7 @@ impl<BorrowType, K, V, NodeType> NodeRef<BorrowType, K, V, NodeType> { /// Could be a public implementation of PartialEq, but only used in this module. fn eq(&self, other: &Self) -> bool { let Self { node, height, _marker: _ } = self; - if *node == other.node { + if node.eq(&other.node) { debug_assert_eq!(*height, other.height); true } else { @@ -924,11 +992,11 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark debug_assert!(self.node.len() < CAPACITY); unsafe { - slice_insert(self.node.keys_mut(), self.idx, key); - slice_insert(self.node.vals_mut(), self.idx, val); - self.node.as_leaf_mut().len += 1; + *self.node.reborrow_mut().into_len_mut() += 1; + slice_insert(self.node.reborrow_mut().into_key_area_slice(), self.idx, key); + slice_insert(self.node.reborrow_mut().into_val_area_slice(), self.idx, val); - self.node.val_mut_at(self.idx) + self.node.reborrow_mut().into_val_area_mut_at(self.idx).assume_init_mut() } } } @@ -964,12 +1032,12 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge> { /// Fixes the parent pointer and index in the child node below this edge. This is useful /// when the ordering of edges has been changed, such as in the various `insert` methods. - fn correct_parent_link(mut self) { - let idx = self.idx as u16; - let ptr = NonNull::new(self.node.as_internal_mut()); + fn correct_parent_link(self) { + // Create backpointer without invalidating other references to the node. + let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) }; + let idx = self.idx; let mut child = self.descend(); - child.as_leaf_mut().parent = ptr; - child.as_leaf_mut().parent_idx.write(idx); + child.set_parent_link(ptr, idx); } } @@ -981,11 +1049,12 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, debug_assert!(self.node.len() < CAPACITY); debug_assert!(edge.height == self.node.height - 1); + let boxed_node = edge.into_boxed_node(); unsafe { - slice_insert(self.node.keys_mut(), self.idx, key); - slice_insert(self.node.vals_mut(), self.idx, val); - slice_insert(self.node.edges_mut(), self.idx + 1, edge.node); - self.node.as_leaf_mut().len += 1; + *self.node.reborrow_mut().into_len_mut() += 1; + slice_insert(self.node.reborrow_mut().into_key_area_slice(), self.idx, key); + slice_insert(self.node.reborrow_mut().into_val_area_slice(), self.idx, val); + slice_insert(self.node.reborrow_mut().into_edge_area_slice(), self.idx + 1, boxed_node); self.node.correct_childrens_parent_links((self.idx + 1)..=self.node.len()); } @@ -1073,28 +1142,25 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marke // node pointer is dereferenced, we access the edges array with a // reference (Rust issue #73987) and invalidate any other references // to or inside the array, should any be around. - let internal_node = self.node.as_internal_ptr(); - NodeRef { - height: self.node.height - 1, - node: unsafe { (&*(*internal_node).edges.get_unchecked(self.idx).as_ptr()).as_ptr() }, - _marker: PhantomData, - } + let parent_ptr = NodeRef::as_internal_ptr(&self.node); + let boxed_node = unsafe { (*parent_ptr).edges.get_unchecked(self.idx).assume_init_read() }; + NodeRef::from_boxed_node(boxed_node, self.node.height - 1) } } impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Immut<'a>, K, V, NodeType>, marker::KV> { pub fn into_kv(self) -> (&'a K, &'a V) { - (unsafe { self.node.into_key_at(self.idx) }, unsafe { self.node.into_val_at(self.idx) }) + (unsafe { self.node.key_at(self.idx) }, unsafe { self.node.val_at(self.idx) }) } } impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> { pub fn into_key_mut(self) -> &'a mut K { - unsafe { self.node.into_key_mut_at(self.idx) } + unsafe { self.node.into_key_area_mut_at(self.idx).assume_init_mut() } } pub fn into_val_mut(self) -> &'a mut V { - unsafe { self.node.into_val_mut_at(self.idx) } + unsafe { self.node.into_val_area_mut_at(self.idx).assume_init_mut() } } } @@ -1106,12 +1172,14 @@ impl<'a, K, V, NodeType> Handle<NodeRef<marker::ValMut<'a>, K, V, NodeType>, mar impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> { pub fn kv_mut(&mut self) -> (&mut K, &mut V) { - // We cannot call into_key_mut_at and into_val_mut_at, because calling the second one + // We cannot call separate key and value methods, because calling the second one // invalidates the reference returned by the first. - let leaf = self.node.as_leaf_mut(); - let key = unsafe { leaf.keys.get_unchecked_mut(self.idx).assume_init_mut() }; - let val = unsafe { leaf.vals.get_unchecked_mut(self.idx).assume_init_mut() }; - (key, val) + unsafe { + let leaf = NodeRef::as_leaf_mut(&mut self.node.reborrow_mut()); + let key = leaf.keys.get_unchecked_mut(self.idx).assume_init_mut(); + let val = leaf.vals.get_unchecked_mut(self.idx).assume_init_mut(); + (key, val) + } } } @@ -1127,23 +1195,23 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType> /// by taking care of leaf data. fn split_leaf_data(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V) { let new_len = self.split_new_node_len(); + new_node.len = new_len as u16; unsafe { - let k = ptr::read(self.node.key_at(self.idx)); - let v = ptr::read(self.node.val_at(self.idx)); + let k = ptr::read(self.node.reborrow().key_at(self.idx)); + let v = ptr::read(self.node.reborrow().val_at(self.idx)); ptr::copy_nonoverlapping( - self.node.key_at(self.idx + 1), - MaybeUninit::slice_as_mut_ptr(&mut new_node.keys), + self.node.reborrow().key_area().as_ptr().add(self.idx + 1), + new_node.keys.as_mut_ptr(), new_len, ); ptr::copy_nonoverlapping( - self.node.val_at(self.idx + 1), - MaybeUninit::slice_as_mut_ptr(&mut new_node.vals), + self.node.reborrow().val_area().as_ptr().add(self.idx + 1), + new_node.vals.as_mut_ptr(), new_len, ); - self.node.as_leaf_mut().len = self.idx as u16; - new_node.len = new_len as u16; + *self.node.reborrow_mut().into_len_mut() = self.idx as u16; (k, v) } } @@ -1174,9 +1242,9 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark mut self, ) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) { unsafe { - let k = slice_remove(self.node.keys_mut(), self.idx); - let v = slice_remove(self.node.vals_mut(), self.idx); - self.node.as_leaf_mut().len -= 1; + let k = slice_remove(self.node.reborrow_mut().into_key_area_slice(), self.idx); + let v = slice_remove(self.node.reborrow_mut().into_val_area_slice(), self.idx); + *self.node.reborrow_mut().into_len_mut() -= 1; ((k, v), self.left_edge()) } } @@ -1205,11 +1273,11 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Internal>, K, V, Root<K, V>) { unsafe { let mut new_node = Box::new(InternalNode::new()); - // Move edges out before reducing length: let new_len = self.split_new_node_len(); + // Move edges out before reducing length: ptr::copy_nonoverlapping( - self.node.edge_at(self.idx + 1), - MaybeUninit::slice_as_mut_ptr(&mut new_node.edges), + self.node.reborrow().edge_area().as_ptr().add(self.idx + 1), + new_node.edges.as_mut_ptr(), new_len + 1, ); let (k, v) = self.split_leaf_data(&mut new_node.data); @@ -1241,31 +1309,28 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, assert!(left_len + right_len < CAPACITY); unsafe { - ptr::write( - left_node.keys_mut().get_unchecked_mut(left_len), - slice_remove(self.node.keys_mut(), self.idx), - ); + *left_node.reborrow_mut().into_len_mut() += right_len as u16 + 1; + + let parent_key = slice_remove(self.node.reborrow_mut().into_key_area_slice(), self.idx); + left_node.reborrow_mut().into_key_area_mut_at(left_len).write(parent_key); ptr::copy_nonoverlapping( - right_node.key_at(0), - left_node.keys_mut().as_mut_ptr().add(left_len + 1), + right_node.reborrow().key_area().as_ptr(), + left_node.reborrow_mut().into_key_area_slice().as_mut_ptr().add(left_len + 1), right_len, ); - ptr::write( - left_node.vals_mut().get_unchecked_mut(left_len), - slice_remove(self.node.vals_mut(), self.idx), - ); + + let parent_val = slice_remove(self.node.reborrow_mut().into_val_area_slice(), self.idx); + left_node.reborrow_mut().into_val_area_mut_at(left_len).write(parent_val); ptr::copy_nonoverlapping( - right_node.val_at(0), - left_node.vals_mut().as_mut_ptr().add(left_len + 1), + right_node.reborrow().val_area().as_ptr(), + left_node.reborrow_mut().into_val_area_slice().as_mut_ptr().add(left_len + 1), right_len, ); - slice_remove(&mut self.node.edges_mut(), self.idx + 1); + slice_remove(&mut self.node.reborrow_mut().into_edge_area_slice(), self.idx + 1); let self_len = self.node.len(); self.node.correct_childrens_parent_links(self.idx + 1..self_len); - self.node.as_leaf_mut().len -= 1; - - left_node.as_leaf_mut().len += right_len as u16 + 1; + *self.node.reborrow_mut().into_len_mut() -= 1; if self.node.height > 1 { // SAFETY: the height of the nodes being merged is one below the height @@ -1273,8 +1338,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, let mut left_node = left_node.cast_to_internal_unchecked(); let right_node = right_node.cast_to_internal_unchecked(); ptr::copy_nonoverlapping( - right_node.edge_at(0), - left_node.edges_mut().as_mut_ptr().add(left_len + 1), + right_node.reborrow().edge_area().as_ptr(), + left_node.reborrow_mut().into_edge_area_slice().as_mut_ptr().add(left_len + 1), right_len + 1, ); @@ -1360,13 +1425,14 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, move_kv(left_kv, new_left_len, parent_kv, 0, 1); } - left_node.as_leaf_mut().len -= count as u16; - right_node.as_leaf_mut().len += count as u16; + *left_node.reborrow_mut().into_len_mut() -= count as u16; + *right_node.reborrow_mut().into_len_mut() += count as u16; match (left_node.force(), right_node.force()) { (ForceResult::Internal(left), ForceResult::Internal(mut right)) => { // Make room for stolen edges. - let right_edges = right.reborrow_mut().as_internal_mut().edges.as_mut_ptr(); + let left = left.reborrow(); + let right_edges = right.reborrow_mut().into_edge_area_slice().as_mut_ptr(); ptr::copy(right_edges, right_edges.add(count), right_len + 1); right.correct_childrens_parent_links(count..count + right_len + 1); @@ -1415,15 +1481,15 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, ptr::copy(right_kv.1.add(count), right_kv.1, new_right_len); } - left_node.as_leaf_mut().len += count as u16; - right_node.as_leaf_mut().len -= count as u16; + *left_node.reborrow_mut().into_len_mut() += count as u16; + *right_node.reborrow_mut().into_len_mut() -= count as u16; match (left_node.force(), right_node.force()) { (ForceResult::Internal(left), ForceResult::Internal(mut right)) => { - move_edges(right.reborrow_mut(), 0, left, left_len + 1, count); + move_edges(right.reborrow(), 0, left, left_len + 1, count); // Fix right indexing. - let right_edges = right.reborrow_mut().as_internal_mut().edges.as_mut_ptr(); + let right_edges = right.reborrow_mut().into_edge_area_slice().as_mut_ptr(); ptr::copy(right_edges.add(count), right_edges, new_right_len + 1); right.correct_childrens_parent_links(0..=new_right_len); } @@ -1448,16 +1514,16 @@ unsafe fn move_kv<K, V>( } // Source and destination must have the same height. -unsafe fn move_edges<K, V>( - mut source: NodeRef<marker::Mut<'_>, K, V, marker::Internal>, +unsafe fn move_edges<'a, K: 'a, V: 'a>( + source: NodeRef<marker::Immut<'a>, K, V, marker::Internal>, source_offset: usize, - mut dest: NodeRef<marker::Mut<'_>, K, V, marker::Internal>, + mut dest: NodeRef<marker::Mut<'a>, K, V, marker::Internal>, dest_offset: usize, count: usize, ) { - let source_ptr = source.as_internal().edges.as_ptr(); - let dest_ptr = dest.as_internal_mut().edges.as_mut_ptr(); unsafe { + let source_ptr = source.edge_area().as_ptr(); + let dest_ptr = dest.reborrow_mut().into_edge_area_slice().as_mut_ptr(); ptr::copy_nonoverlapping(source_ptr.add(source_offset), dest_ptr.add(dest_offset), count); dest.correct_childrens_parent_links(dest_offset..dest_offset + count); } @@ -1553,11 +1619,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, ma move_kv(left_kv, left_new_len, right_kv, 0, right_new_len); - left_node.as_leaf_mut().len = left_new_len as u16; - right_node.as_leaf_mut().len = right_new_len as u16; + *left_node.reborrow_mut().into_len_mut() = left_new_len as u16; + *right_node.reborrow_mut().into_len_mut() = right_new_len as u16; match (left_node.force(), right_node.force()) { (ForceResult::Internal(left), ForceResult::Internal(right)) => { + let left = left.reborrow(); move_edges(left, left_new_len + 1, right, 1, right_new_len); } (ForceResult::Leaf(_), ForceResult::Leaf(_)) => {} @@ -1606,17 +1673,34 @@ pub mod marker { pub enum Edge {} } -unsafe fn slice_insert<T>(slice: &mut [T], idx: usize, val: T) { +/// Inserts a value into a slice of initialized elements followed by one uninitialized element. +/// +/// # Safety +/// The slice has more than `idx` elements. +unsafe fn slice_insert<T>(slice: &mut [MaybeUninit<T>], idx: usize, val: T) { unsafe { - ptr::copy(slice.as_ptr().add(idx), slice.as_mut_ptr().add(idx + 1), slice.len() - idx); - ptr::write(slice.get_unchecked_mut(idx), val); + let len = slice.len(); + debug_assert!(len > idx); + let slice_ptr = slice.as_mut_ptr(); + if len > idx + 1 { + ptr::copy(slice_ptr.add(idx), slice_ptr.add(idx + 1), len - idx - 1); + } + (*slice_ptr.add(idx)).write(val); } } -unsafe fn slice_remove<T>(slice: &mut [T], idx: usize) -> T { +/// Removes and returns a value from a slice of all initialized elements, leaving behind one +/// trailing uninitialized element. +/// +/// # Safety +/// The slice has more than `idx` elements. +unsafe fn slice_remove<T>(slice: &mut [MaybeUninit<T>], idx: usize) -> T { unsafe { - let ret = ptr::read(slice.get_unchecked(idx)); - ptr::copy(slice.as_ptr().add(idx + 1), slice.as_mut_ptr().add(idx), slice.len() - idx - 1); + let len = slice.len(); + debug_assert!(idx < len); + let slice_ptr = slice.as_mut_ptr(); + let ret = (*slice_ptr.add(idx)).assume_init_read(); + ptr::copy(slice_ptr.add(idx + 1), slice_ptr.add(idx), len - idx - 1); ret } } diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs index d6527057c5d..38c75de34ee 100644 --- a/library/alloc/src/collections/btree/node/tests.rs +++ b/library/alloc/src/collections/btree/node/tests.rs @@ -17,43 +17,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal> } } - /// Asserts that the keys are in strictly ascending order. - /// Returns how many keys it encountered. - pub fn assert_ascending(self) -> usize - where - K: Copy + Debug + Ord, - { - struct SeriesChecker<T> { - num_seen: usize, - previous: Option<T>, - } - impl<T: Copy + Debug + Ord> SeriesChecker<T> { - fn is_ascending(&mut self, next: T) { - if let Some(previous) = self.previous { - assert!(previous < next, "{:?} >= {:?}", previous, next); - } - self.previous = Some(next); - self.num_seen += 1; - } - } - - let mut checker = SeriesChecker { num_seen: 0, previous: None }; - self.visit_nodes_in_order(|pos| match pos { - navigate::Position::Leaf(node) => { - for idx in 0..node.len() { - let key = *unsafe { node.key_at(idx) }; - checker.is_ascending(key); - } - } - navigate::Position::InternalKV(kv) => { - let key = *kv.into_kv().0; - checker.is_ascending(key); - } - navigate::Position::Internal(_) => {} - }); - checker.num_seen - } - pub fn dump_keys(self) -> String where K: Debug, diff --git a/library/alloc/src/collections/btree/search.rs b/library/alloc/src/collections/btree/search.rs index 1526c0673c6..701d5ec73e2 100644 --- a/library/alloc/src/collections/btree/search.rs +++ b/library/alloc/src/collections/btree/search.rs @@ -72,7 +72,7 @@ where // is an index -- not a reference. let len = node.len(); for i in 0..len { - let k = unsafe { node.key_at(i) }; + let k = unsafe { node.reborrow().key_at(i) }; match key.cmp(k.borrow()) { Ordering::Greater => {} Ordering::Equal => return (i, true), diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index a886e17f5a9..5ebc4d6c4c1 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -309,13 +309,13 @@ //! * `?` ⇒ [`Debug`] //! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers //! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers -//! * `o` ⇒ [`Octal`](trait.Octal.html) -//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html) -//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html) -//! * `p` ⇒ [`Pointer`](trait.Pointer.html) +//! * `o` ⇒ [`Octal`] +//! * `x` ⇒ [`LowerHex`] +//! * `X` ⇒ [`UpperHex`] +//! * `p` ⇒ [`Pointer`] //! * `b` ⇒ [`Binary`] -//! * `e` ⇒ [`LowerExp`](trait.LowerExp.html) -//! * `E` ⇒ [`UpperExp`](trait.UpperExp.html) +//! * `e` ⇒ [`LowerExp`] +//! * `E` ⇒ [`UpperExp`] //! //! What this means is that any type of argument which implements the //! [`fmt::Binary`][`Binary`] trait can then be formatted with `{:b}`. Implementations diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 405667e0b2a..f21fc8854d0 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -78,6 +78,7 @@ #![cfg_attr(test, feature(new_uninit))] #![feature(allocator_api)] #![feature(array_chunks)] +#![feature(array_methods)] #![feature(array_value_iter)] #![feature(array_windows)] #![feature(allow_internal_unstable)] @@ -119,7 +120,6 @@ #![feature(raw_ref_op)] #![feature(rustc_attrs)] #![feature(receiver_trait)] -#![feature(renamed_spin_loop)] #![feature(min_specialization)] #![feature(slice_ptr_get)] #![feature(slice_ptr_len)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index ef2a5dd570f..b2afb702eeb 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -406,7 +406,8 @@ impl<T> Cell<T> { /// assert_eq!(five, 5); /// ``` #[stable(feature = "move_cell", since = "1.17.0")] - pub fn into_inner(self) -> T { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> T { self.value.into_inner() } } @@ -573,7 +574,7 @@ pub struct RefCell<T: ?Sized> { value: UnsafeCell<T>, } -/// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow). +/// An error returned by [`RefCell::try_borrow`]. #[stable(feature = "try_borrow", since = "1.13.0")] pub struct BorrowError { _private: (), @@ -593,7 +594,7 @@ impl Display for BorrowError { } } -/// An error returned by [`RefCell::try_borrow_mut`](struct.RefCell.html#method.try_borrow_mut). +/// An error returned by [`RefCell::try_borrow_mut`]. #[stable(feature = "try_borrow", since = "1.13.0")] pub struct BorrowMutError { _private: (), @@ -668,12 +669,11 @@ impl<T> RefCell<T> { /// let five = c.into_inner(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] #[inline] - pub fn into_inner(self) -> T { + pub const fn into_inner(self) -> T { // Since this function takes `self` (the `RefCell`) by value, the // compiler statically verifies that it is not currently borrowed. - // Therefore the following assertion is just a `debug_assert!`. - debug_assert!(self.borrow.get() == UNUSED); self.value.into_inner() } @@ -1682,7 +1682,8 @@ impl<T> UnsafeCell<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn into_inner(self) -> T { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> T { self.value } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index a048f65a149..bbb3a3dea43 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,7 +29,7 @@ use self::Ordering::*; /// /// This trait allows for partial equality, for types that do not have a full /// equivalence relation. For example, in floating point numbers `NaN != NaN`, -/// so floating point types implement `PartialEq` but not [`Eq`](Eq). +/// so floating point types implement `PartialEq` but not [`Eq`]. /// /// Formally, the equality must be (for all `a`, `b` and `c`): /// diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 63866a5d110..d95d43f0854 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1,4 +1,6 @@ -use crate::fmt; +#![allow(unused_imports)] + +use crate::fmt::{self, Debug, Formatter}; struct PadAdapter<'buf, 'state> { buf: &'buf mut (dyn fmt::Write + 'buf), @@ -53,14 +55,12 @@ impl fmt::Write for PadAdapter<'_, '_> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted struct as a part of your -/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_struct`](struct.Formatter.html#method.debug_struct) -/// method. +/// This can be constructed by the [`Formatter::debug_struct`] method. /// /// # Examples /// @@ -257,14 +257,12 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted tuple as a part of your -/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_tuple`](struct.Formatter.html#method.debug_tuple) -/// method. +/// This can be constructed by the [`Formatter::debug_tuple`] method. /// /// # Examples /// @@ -428,14 +426,12 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted set of items as a part -/// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// of your [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_set`](struct.Formatter.html#method.debug_set) -/// method. +/// This can be constructed by the [`Formatter::debug_set`] method. /// /// # Examples /// @@ -560,14 +556,12 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted list of items as a part -/// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// of your [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_list`](struct.Formatter.html#method.debug_list) -/// method. +/// This can be constructed by the [`Formatter::debug_list`] method. /// /// # Examples /// @@ -692,14 +686,12 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted map as a part of your -/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_map`](struct.Formatter.html#method.debug_map) -/// method. +/// This can be constructed by the [`Formatter::debug_map`] method. /// /// # Examples /// diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 454fb34e77e..979a5f8cf50 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -1,6 +1,7 @@ #![stable(feature = "core_hint", since = "1.27.0")] //! Hints to compiler that affects how code should be emitted or optimized. +//! Hints may be compile time or runtime. use crate::intrinsics; @@ -24,7 +25,6 @@ use crate::intrinsics; /// Otherwise, consider using the [`unreachable!`] macro, which does not allow /// optimizations but will panic when executed. /// -/// /// # Example /// /// ``` @@ -51,18 +51,62 @@ pub const unsafe fn unreachable_unchecked() -> ! { unsafe { intrinsics::unreachable() } } -/// Emits a machine instruction hinting to the processor that it is running in busy-wait -/// spin-loop ("spin lock"). +/// Emits a machine instruction to signal the processor that it is running in +/// a busy-wait spin-loop ("spin lock"). +/// +/// Upon receiving the spin-loop signal the processor can optimize its behavior by, +/// for example, saving power or switching hyper-threads. +/// +/// This function is different from [`thread::yield_now`] which directly +/// yields to the system's scheduler, whereas `spin_loop` does not interact +/// with the operating system. +/// +/// A common use case for `spin_loop` is implementing bounded optimistic +/// spinning in a CAS loop in synchronization primitives. To avoid problems +/// like priority inversion, it is strongly recommended that the spin loop is +/// terminated after a finite amount of iterations and an appropriate blocking +/// syscall is made. +/// +/// **Note**: On platforms that do not support receiving spin-loop hints this +/// function does not do anything at all. +/// +/// # Examples /// -/// For a discussion of different locking strategies and their trade-offs, see -/// [`core::sync::atomic::spin_loop_hint`]. +/// ``` +/// use std::sync::atomic::{AtomicBool, Ordering}; +/// use std::sync::Arc; +/// use std::{hint, thread}; +/// +/// // A shared atomic value that threads will use to coordinate +/// let live = Arc::new(AtomicBool::new(false)); +/// +/// // In a background thread we'll eventually set the value +/// let bg_work = { +/// let live = live.clone(); +/// thread::spawn(move || { +/// // Do some work, then make the value live +/// do_some_work(); +/// live.store(true, Ordering::Release); +/// }) +/// }; /// -/// **Note**: On platforms that do not support receiving spin-loop hints this function does not -/// do anything at all. +/// // Back on our current thread, we wait for the value to be set +/// while live.load(Ordering::Acquire) { +/// // The spin loop is a hint to the CPU that we're waiting, but probably +/// // not for very long +/// hint::spin_loop(); +/// } +/// +/// // The value is now set +/// # fn do_some_work() {} +/// do_some_work(); +/// bg_work.join()?; +/// # Ok::<(), Box<dyn core::any::Any + Send + 'static>>(()) +/// ``` /// -/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint +/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html #[inline] -#[unstable(feature = "renamed_spin_loop", issue = "55002")] +#[stable(feature = "renamed_spin_loop", since = "1.49.0")] pub fn spin_loop() { #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))] { diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 35adb4f69d8..96d0a60a327 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -121,7 +121,7 @@ where /// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`flatten`]: trait.Iterator.html#method.flatten +/// [`flatten`]: Iterator::flatten /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iterator_flatten", since = "1.29.0")] diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 9c8e639c2d8..9586284e1d7 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -85,7 +85,7 @@ pub unsafe trait SourceIter { /// * whatever remains in the source after iteration has stopped /// * the memory that has become unused by advancing a consuming iterator /// - /// [`next()`]: trait.Iterator.html#method.next + /// [`next()`]: Iterator::next unsafe fn as_inner(&mut self) -> &mut Self::Source; } @@ -94,7 +94,7 @@ pub unsafe trait SourceIter { /// This `struct` is created by the [`rev`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`rev`]: trait.Iterator.html#method.rev +/// [`rev`]: Iterator::rev /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -228,7 +228,7 @@ unsafe impl<I> TrustedLen for Rev<I> where I: TrustedLen + DoubleEndedIterator { /// This `struct` is created by the [`copied`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`copied`]: trait.Iterator.html#method.copied +/// [`copied`]: Iterator::copied /// [`Iterator`]: trait.Iterator.html #[stable(feature = "iter_copied", since = "1.36.0")] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -380,7 +380,7 @@ where /// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`cloned`]: trait.Iterator.html#method.cloned +/// [`cloned`]: Iterator::cloned /// [`Iterator`]: trait.Iterator.html #[stable(feature = "iter_cloned", since = "1.1.0")] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -515,7 +515,7 @@ where /// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`cycle`]: trait.Iterator.html#method.cycle +/// [`cycle`]: Iterator::cycle /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -600,7 +600,7 @@ impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {} /// This `struct` is created by the [`step_by`] method on [`Iterator`]. See /// its documentation for more. /// -/// [`step_by`]: trait.Iterator.html#method.step_by +/// [`step_by`]: Iterator::step_by /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iterator_step_by", since = "1.28.0")] @@ -833,7 +833,7 @@ impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {} /// This `struct` is created by the [`map`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`map`]: trait.Iterator.html#method.map +/// [`map`]: Iterator::map /// [`Iterator`]: trait.Iterator.html /// /// # Notes about side effects @@ -1042,7 +1042,7 @@ unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for Map<I, F> where F: FnM /// This `struct` is created by the [`filter`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`filter`]: trait.Iterator.html#method.filter +/// [`filter`]: Iterator::filter /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1191,7 +1191,7 @@ unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnM /// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`filter_map`]: trait.Iterator.html#method.filter_map +/// [`filter_map`]: Iterator::filter_map /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1338,7 +1338,7 @@ unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`enumerate`]: trait.Iterator.html#method.enumerate +/// [`enumerate`]: Iterator::enumerate /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -1574,7 +1574,7 @@ unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {} /// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`peekable`]: trait.Iterator.html#method.peekable +/// [`peekable`]: Iterator::peekable /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -1743,7 +1743,7 @@ impl<I: Iterator> Peekable<I> { /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`. /// But if the iteration is over, `None` is returned. /// - /// [`next`]: trait.Iterator.html#tymethod.next + /// [`next`]: Iterator::next /// /// Because `peek()` returns a reference, and many iterators iterate over /// references, there can be a possibly confusing situation where the @@ -1871,7 +1871,7 @@ unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {} /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`skip_while`]: trait.Iterator.html#method.skip_while +/// [`skip_while`]: Iterator::skip_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1993,7 +1993,7 @@ unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`take_while`]: trait.Iterator.html#method.take_while +/// [`take_while`]: Iterator::take_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2128,7 +2128,7 @@ unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where /// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`map_while`]: trait.Iterator.html#method.map_while +/// [`map_while`]: Iterator::map_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] @@ -2226,7 +2226,7 @@ unsafe impl<B, I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> where /// This `struct` is created by the [`skip`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`skip`]: trait.Iterator.html#method.skip +/// [`skip`]: Iterator::skip /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -2422,7 +2422,7 @@ unsafe impl<I: InPlaceIterable> InPlaceIterable for Skip<I> {} /// This `struct` is created by the [`take`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`take`]: trait.Iterator.html#method.take +/// [`take`]: Iterator::take /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -2627,7 +2627,7 @@ unsafe impl<I: TrustedLen> TrustedLen for Take<I> {} /// This `struct` is created by the [`scan`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`scan`]: trait.Iterator.html#method.scan +/// [`scan`]: Iterator::scan /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2735,7 +2735,7 @@ unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> whe /// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`inspect`]: trait.Iterator.html#method.inspect +/// [`inspect`]: Iterator::inspect /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 069e6e7e718..41202546566 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -70,6 +70,7 @@ #![feature(cfg_target_has_atomic)] #![feature(const_alloc_layout)] #![feature(const_discriminant)] +#![feature(const_cell_into_inner)] #![feature(const_checked_int_methods)] #![feature(const_euclidean_int_methods)] #![feature(const_float_classify)] @@ -158,6 +159,7 @@ #![feature(slice_ptr_get)] #![feature(no_niche)] // rust-lang/rust#68303 #![feature(unsafe_block_in_unsafe_fn)] +#![feature(int_error_matching)] #![deny(unsafe_op_in_unsafe_fn)] #[prelude_import] diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index aab17155186..9d8c8c86291 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -98,15 +98,18 @@ pub enum IntErrorKind { /// /// Among other causes, this variant will be constructed when parsing an empty string. Empty, - /// Contains an invalid digit. + /// Contains an invalid digit in its context. /// /// Among other causes, this variant will be constructed when parsing a string that - /// contains a letter. + /// contains a non-ASCII char. + /// + /// This variant is also constructed when a `+` or `-` is misplaced within a string + /// either on its own or in the middle of a number. InvalidDigit, /// Integer is too large to store in target integer type. - Overflow, + PosOverflow, /// Integer is too small to store in target integer type. - Underflow, + NegOverflow, /// Value was Zero /// /// This variant will be emitted when the parsing string has a value of zero, which @@ -119,7 +122,7 @@ impl ParseIntError { #[unstable( feature = "int_error_matching", reason = "it can be useful to match errors when making error messages \ - for integer parsing", + for integer parsing", issue = "22639" )] pub fn kind(&self) -> &IntErrorKind { @@ -136,8 +139,8 @@ impl ParseIntError { match self.kind { IntErrorKind::Empty => "cannot parse integer from empty string", IntErrorKind::InvalidDigit => "invalid digit found in string", - IntErrorKind::Overflow => "number too large to fit in target type", - IntErrorKind::Underflow => "number too small to fit in target type", + IntErrorKind::PosOverflow => "number too large to fit in target type", + IntErrorKind::NegOverflow => "number too small to fit in target type", IntErrorKind::Zero => "number would be zero for non-zero type", } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 4f64e30ccf8..9f5ae57b74a 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -63,7 +63,12 @@ pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, No #[stable(feature = "try_from", since = "1.34.0")] pub use error::TryFromIntError; -#[unstable(feature = "int_error_matching", issue = "22639")] +#[unstable( + feature = "int_error_matching", + reason = "it can be useful to match errors when making error messages \ + for integer parsing", + issue = "22639" +)] pub use error::IntErrorKind; macro_rules! usize_isize_to_xe_bytes_doc { @@ -130,7 +135,7 @@ impl i128 { #[cfg(target_pointer_width = "16")] #[lang = "isize"] impl isize { - int_impl! { isize, i16, u16, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", + int_impl! { isize, i16, usize, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } @@ -138,7 +143,7 @@ impl isize { #[cfg(target_pointer_width = "32")] #[lang = "isize"] impl isize { - int_impl! { isize, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301", + int_impl! { isize, i32, usize, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301", "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } @@ -147,7 +152,7 @@ impl isize { #[cfg(target_pointer_width = "64")] #[lang = "isize"] impl isize { - int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "", + int_impl! { isize, i64, usize, 64, -9223372036854775808, 9223372036854775807, "", "", 12, "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", @@ -830,15 +835,14 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par let src = src.as_bytes(); let (is_positive, digits) = match src[0] { + b'+' | b'-' if src[1..].is_empty() => { + return Err(PIE { kind: InvalidDigit }); + } b'+' => (true, &src[1..]), b'-' if is_signed_ty => (false, &src[1..]), _ => (true, src), }; - if digits.is_empty() { - return Err(PIE { kind: Empty }); - } - let mut result = T::from_u32(0); if is_positive { // The number is positive @@ -849,11 +853,11 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par }; result = match result.checked_mul(radix) { Some(result) => result, - None => return Err(PIE { kind: Overflow }), + None => return Err(PIE { kind: PosOverflow }), }; result = match result.checked_add(x) { Some(result) => result, - None => return Err(PIE { kind: Overflow }), + None => return Err(PIE { kind: PosOverflow }), }; } } else { @@ -865,11 +869,11 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par }; result = match result.checked_mul(radix) { Some(result) => result, - None => return Err(PIE { kind: Underflow }), + None => return Err(PIE { kind: NegOverflow }), }; result = match result.checked_sub(x) { Some(result) => result, - None => return Err(PIE { kind: Underflow }), + None => return Err(PIE { kind: NegOverflow }), }; } } diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 2edeb81011a..d48c02bf59c 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -115,23 +115,13 @@ use crate::hint::spin_loop; /// Signals the processor that it is inside a busy-wait spin-loop ("spin lock"). /// -/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving -/// power or switching hyper-threads. -/// -/// This function is different from [`std::thread::yield_now`] which directly yields to the -/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system. -/// -/// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS -/// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly -/// recommended that the spin loop is terminated after a finite amount of iterations and an -/// appropriate blocking syscall is made. +/// This function is expected to be deprecated in favor of +/// [`hint::spin_loop`]. /// /// **Note**: On platforms that do not support receiving spin-loop hints this function does not /// do anything at all. /// -/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html -/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html -/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html +/// [`hint::spin_loop`]: crate::hint::spin_loop #[inline] #[stable(feature = "spin_loop_hint", since = "1.24.0")] pub fn spin_loop_hint() { @@ -365,7 +355,8 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] - pub fn into_inner(self) -> bool { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> bool { self.v.into_inner() != 0 } @@ -941,7 +932,8 @@ impl<T> AtomicPtr<T> { /// ``` #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] - pub fn into_inner(self) -> *mut T { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> *mut T { self.p.into_inner() } @@ -1462,7 +1454,8 @@ assert_eq!(some_var.into_inner(), 5); ```"), #[inline] #[$stable_access] - pub fn into_inner(self) -> $int_type { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> $int_type { self.v.into_inner() } } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 4e987a53b2c..6851f3fcd2f 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -39,15 +39,17 @@ impl<T> Poll<T> { /// Returns `true` if this is `Poll::Ready` #[inline] + #[rustc_const_stable(feature = "const_poll", since = "1.49.0")] #[stable(feature = "futures_api", since = "1.36.0")] - pub fn is_ready(&self) -> bool { + pub const fn is_ready(&self) -> bool { matches!(*self, Poll::Ready(_)) } /// Returns `true` if this is `Poll::Pending` #[inline] + #[rustc_const_stable(feature = "const_poll", since = "1.49.0")] #[stable(feature = "futures_api", since = "1.36.0")] - pub fn is_pending(&self) -> bool { + pub const fn is_pending(&self) -> bool { !self.is_ready() } } diff --git a/library/core/tests/cell.rs b/library/core/tests/cell.rs index 40be01f4439..77517879dd2 100644 --- a/library/core/tests/cell.rs +++ b/library/core/tests/cell.rs @@ -422,3 +422,15 @@ fn refcell_format() { let msg = format!("{name} {}", &*what.borrow(), name = &*name.borrow()); assert_eq!(msg, "rust rocks".to_string()); } + +#[allow(dead_code)] +fn const_cells() { + const UNSAFE_CELL: UnsafeCell<i32> = UnsafeCell::new(3); + const _: i32 = UNSAFE_CELL.into_inner(); + + const REF_CELL: RefCell<i32> = RefCell::new(3); + const _: i32 = REF_CELL.into_inner(); + + const CELL: Cell<i32> = Cell::new(3); + const _: i32 = CELL.into_inner(); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 0c4ce867f54..c9f9b890c39 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -9,6 +9,7 @@ #![feature(box_syntax)] #![feature(cell_update)] #![feature(const_assume)] +#![feature(const_cell_into_inner)] #![feature(core_intrinsics)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] @@ -91,5 +92,6 @@ mod result; mod slice; mod str; mod str_lossy; +mod task; mod time; mod tuple; diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index 825e5e63b59..fb1293c99bb 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -135,11 +135,11 @@ fn test_from_str() { ); assert_eq!( "-129".parse::<NonZeroI8>().err().map(|e| e.kind().clone()), - Some(IntErrorKind::Underflow) + Some(IntErrorKind::NegOverflow) ); assert_eq!( "257".parse::<NonZeroU8>().err().map(|e| e.kind().clone()), - Some(IntErrorKind::Overflow) + Some(IntErrorKind::PosOverflow) ); } diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 190528fd445..49e5cc0eaa5 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -2,10 +2,11 @@ use core::cmp::PartialEq; use core::convert::{TryFrom, TryInto}; use core::fmt::Debug; use core::marker::Copy; -use core::num::TryFromIntError; +use core::num::{IntErrorKind, ParseIntError, TryFromIntError}; use core::ops::{Add, Div, Mul, Rem, Sub}; use core::option::Option; -use core::option::Option::{None, Some}; +use core::option::Option::None; +use core::str::FromStr; #[macro_use] mod int_macros; @@ -67,6 +68,15 @@ where assert_eq!(ten.rem(two), ten % two); } +/// Helper function for asserting number parsing returns a specific error +fn test_parse<T>(num_str: &str, expected: Result<T, IntErrorKind>) +where + T: FromStr<Err = ParseIntError>, + Result<T, IntErrorKind>: PartialEq + Debug, +{ + assert_eq!(num_str.parse::<T>().map_err(|e| e.kind().clone()), expected) +} + #[test] fn from_str_issue7588() { let u: Option<u8> = u8::from_str_radix("1000", 10).ok(); @@ -77,49 +87,52 @@ fn from_str_issue7588() { #[test] fn test_int_from_str_overflow() { - assert_eq!("127".parse::<i8>().ok(), Some(127i8)); - assert_eq!("128".parse::<i8>().ok(), None); + test_parse::<i8>("127", Ok(127)); + test_parse::<i8>("128", Err(IntErrorKind::PosOverflow)); - assert_eq!("-128".parse::<i8>().ok(), Some(-128i8)); - assert_eq!("-129".parse::<i8>().ok(), None); + test_parse::<i8>("-128", Ok(-128)); + test_parse::<i8>("-129", Err(IntErrorKind::NegOverflow)); - assert_eq!("32767".parse::<i16>().ok(), Some(32_767i16)); - assert_eq!("32768".parse::<i16>().ok(), None); + test_parse::<i16>("32767", Ok(32_767)); + test_parse::<i16>("32768", Err(IntErrorKind::PosOverflow)); - assert_eq!("-32768".parse::<i16>().ok(), Some(-32_768i16)); - assert_eq!("-32769".parse::<i16>().ok(), None); + test_parse::<i16>("-32768", Ok(-32_768)); + test_parse::<i16>("-32769", Err(IntErrorKind::NegOverflow)); - assert_eq!("2147483647".parse::<i32>().ok(), Some(2_147_483_647i32)); - assert_eq!("2147483648".parse::<i32>().ok(), None); + test_parse::<i32>("2147483647", Ok(2_147_483_647)); + test_parse::<i32>("2147483648", Err(IntErrorKind::PosOverflow)); - assert_eq!("-2147483648".parse::<i32>().ok(), Some(-2_147_483_648i32)); - assert_eq!("-2147483649".parse::<i32>().ok(), None); + test_parse::<i32>("-2147483648", Ok(-2_147_483_648)); + test_parse::<i32>("-2147483649", Err(IntErrorKind::NegOverflow)); - assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(9_223_372_036_854_775_807i64)); - assert_eq!("9223372036854775808".parse::<i64>().ok(), None); + test_parse::<i64>("9223372036854775807", Ok(9_223_372_036_854_775_807)); + test_parse::<i64>("9223372036854775808", Err(IntErrorKind::PosOverflow)); - assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(-9_223_372_036_854_775_808i64)); - assert_eq!("-9223372036854775809".parse::<i64>().ok(), None); + test_parse::<i64>("-9223372036854775808", Ok(-9_223_372_036_854_775_808)); + test_parse::<i64>("-9223372036854775809", Err(IntErrorKind::NegOverflow)); } #[test] fn test_leading_plus() { - assert_eq!("+127".parse::<u8>().ok(), Some(127)); - assert_eq!("+9223372036854775807".parse::<i64>().ok(), Some(9223372036854775807)); + test_parse::<u8>("+127", Ok(127)); + test_parse::<i64>("+9223372036854775807", Ok(9223372036854775807)); } #[test] fn test_invalid() { - assert_eq!("--129".parse::<i8>().ok(), None); - assert_eq!("++129".parse::<i8>().ok(), None); - assert_eq!("Съешь".parse::<u8>().ok(), None); + test_parse::<i8>("--129", Err(IntErrorKind::InvalidDigit)); + test_parse::<i8>("++129", Err(IntErrorKind::InvalidDigit)); + test_parse::<u8>("Съешь", Err(IntErrorKind::InvalidDigit)); + test_parse::<u8>("123Hello", Err(IntErrorKind::InvalidDigit)); + test_parse::<i8>("--", Err(IntErrorKind::InvalidDigit)); + test_parse::<i8>("-", Err(IntErrorKind::InvalidDigit)); + test_parse::<i8>("+", Err(IntErrorKind::InvalidDigit)); + test_parse::<u8>("-1", Err(IntErrorKind::InvalidDigit)); } #[test] fn test_empty() { - assert_eq!("-".parse::<i8>().ok(), None); - assert_eq!("+".parse::<i8>().ok(), None); - assert_eq!("".parse::<u8>().ok(), None); + test_parse::<u8>("", Err(IntErrorKind::Empty)); } #[test] diff --git a/library/core/tests/task.rs b/library/core/tests/task.rs new file mode 100644 index 00000000000..d71fef9e5c8 --- /dev/null +++ b/library/core/tests/task.rs @@ -0,0 +1,14 @@ +use core::task::Poll; + +#[test] +fn poll_const() { + // test that the methods of `Poll` are usable in a const context + + const POLL: Poll<usize> = Poll::Pending; + + const IS_READY: bool = POLL.is_ready(); + assert!(!IS_READY); + + const IS_PENDING: bool = POLL.is_pending(); + assert!(IS_PENDING); +} diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index d1244c2ca53..fa229251703 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1390,8 +1390,6 @@ pub struct IntoValues<K, V> { /// A builder for computing where in a HashMap a key-value pair would be stored. /// /// See the [`HashMap::raw_entry_mut`] docs for usage examples. -/// -/// [`HashMap::raw_entry_mut`]: HashMap::raw_entry_mut #[unstable(feature = "hash_raw_entry", issue = "56167")] pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> { map: &'a mut HashMap<K, V, S>, @@ -1430,8 +1428,6 @@ pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> { /// A builder for computing where in a HashMap a key-value pair would be stored. /// /// See the [`HashMap::raw_entry`] docs for usage examples. -/// -/// [`HashMap::raw_entry`]: HashMap::raw_entry #[unstable(feature = "hash_raw_entry", issue = "56167")] pub struct RawEntryBuilder<'a, K: 'a, V: 'a, S: 'a> { map: &'a HashMap<K, V, S>, diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 161bfe3795c..c256f556b3c 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1701,10 +1701,14 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> { /// The `dst` path will be a link pointing to the `src` path. Note that systems /// often require these two paths to both be located on the same filesystem. /// +/// If `src` names a symbolic link, it is platform-specific whether the symbolic +/// link is followed. On platforms where it's possible to not follow it, it is +/// not followed, and the created hard link points to the symbolic link itself. +/// /// # Platform-specific behavior /// -/// This function currently corresponds to the `link` function on Unix -/// and the `CreateHardLink` function on Windows. +/// This function currently corresponds to the `linkat` function with no flags +/// on Unix and the `CreateHardLink` function on Windows. /// Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 38fd470a1c3..0642dca8e48 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1336,3 +1336,54 @@ fn metadata_access_times() { } } } + +/// Test creating hard links to symlinks. +#[test] +fn symlink_hard_link() { + let tmpdir = tmpdir(); + + // Create "file", a file. + check!(fs::File::create(tmpdir.join("file"))); + + // Create "symlink", a symlink to "file". + check!(symlink_file("file", tmpdir.join("symlink"))); + + // Create "hard_link", a hard link to "symlink". + check!(fs::hard_link(tmpdir.join("symlink"), tmpdir.join("hard_link"))); + + // "hard_link" should appear as a symlink. + assert!(check!(fs::symlink_metadata(tmpdir.join("hard_link"))).file_type().is_symlink()); + + // We sould be able to open "file" via any of the above names. + let _ = check!(fs::File::open(tmpdir.join("file"))); + assert!(fs::File::open(tmpdir.join("file.renamed")).is_err()); + let _ = check!(fs::File::open(tmpdir.join("symlink"))); + let _ = check!(fs::File::open(tmpdir.join("hard_link"))); + + // Rename "file" to "file.renamed". + check!(fs::rename(tmpdir.join("file"), tmpdir.join("file.renamed"))); + + // Now, the symlink and the hard link should be dangling. + assert!(fs::File::open(tmpdir.join("file")).is_err()); + let _ = check!(fs::File::open(tmpdir.join("file.renamed"))); + assert!(fs::File::open(tmpdir.join("symlink")).is_err()); + assert!(fs::File::open(tmpdir.join("hard_link")).is_err()); + + // The symlink and the hard link should both still point to "file". + assert!(fs::read_link(tmpdir.join("file")).is_err()); + assert!(fs::read_link(tmpdir.join("file.renamed")).is_err()); + assert_eq!(check!(fs::read_link(tmpdir.join("symlink"))), Path::new("file")); + assert_eq!(check!(fs::read_link(tmpdir.join("hard_link"))), Path::new("file")); + + // Remove "file.renamed". + check!(fs::remove_file(tmpdir.join("file.renamed"))); + + // Now, we can't open the file by any name. + assert!(fs::File::open(tmpdir.join("file")).is_err()); + assert!(fs::File::open(tmpdir.join("file.renamed")).is_err()); + assert!(fs::File::open(tmpdir.join("symlink")).is_err()); + assert!(fs::File::open(tmpdir.join("hard_link")).is_err()); + + // "hard_link" should still appear as a symlink. + assert!(check!(fs::symlink_metadata(tmpdir.join("hard_link"))).file_type().is_symlink()); +} diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 5733735dc4a..bbee2cc9842 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -94,7 +94,8 @@ impl<T> Cursor<T> { /// # force_inference(&buff); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(inner: T) -> Cursor<T> { + #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] + pub const fn new(inner: T) -> Cursor<T> { Cursor { pos: 0, inner } } @@ -130,7 +131,8 @@ impl<T> Cursor<T> { /// let reference = buff.get_ref(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_ref(&self) -> &T { + #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] + pub const fn get_ref(&self) -> &T { &self.inner } @@ -175,7 +177,8 @@ impl<T> Cursor<T> { /// assert_eq!(buff.position(), 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn position(&self) -> u64 { + #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] + pub const fn position(&self) -> u64 { self.pos } diff --git a/library/std/src/io/cursor/tests.rs b/library/std/src/io/cursor/tests.rs index 80d88ca66f6..5da31ce0ba7 100644 --- a/library/std/src/io/cursor/tests.rs +++ b/library/std/src/io/cursor/tests.rs @@ -514,3 +514,10 @@ fn test_eq() { let _: AssertEq<Cursor<Vec<u8>>> = AssertEq(Cursor::new(Vec::new())); } + +#[allow(dead_code)] +fn const_cursor() { + const CURSOR: Cursor<&[u8]> = Cursor::new(&[0]); + const _: &&[u8] = CURSOR.get_ref(); + const _: u64 = CURSOR.position(); +} diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index dc05b9648fd..2b1f371129e 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -102,7 +102,8 @@ pub struct Empty { /// assert!(buffer.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn empty() -> Empty { +#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] +pub const fn empty() -> Empty { Empty { _priv: () } } @@ -159,7 +160,8 @@ pub struct Repeat { /// assert_eq!(buffer, [0b101, 0b101, 0b101]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn repeat(byte: u8) -> Repeat { +#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] +pub const fn repeat(byte: u8) -> Repeat { Repeat { byte } } @@ -226,7 +228,8 @@ pub struct Sink { /// assert_eq!(num_bytes, 5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn sink() -> Sink { +#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] +pub const fn sink() -> Sink { Sink { _priv: () } } diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index e5e32ecb405..9450b1ee124 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -1,5 +1,5 @@ use crate::io::prelude::*; -use crate::io::{copy, empty, repeat, sink}; +use crate::io::{copy, empty, repeat, sink, Empty, Repeat, Sink}; #[test] fn copy_copies() { @@ -43,3 +43,10 @@ fn take_some_bytes() { assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4); assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20); } + +#[allow(dead_code)] +fn const_utils() { + const _: Empty = empty(); + const _: Repeat = repeat(b'c'); + const _: Sink = sink(); +} diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 96a7755c688..bc218b77c87 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -242,6 +242,7 @@ #![feature(const_fn_transmute)] #![feature(const_fn)] #![feature(const_fn_fn_ptr_basics)] +#![feature(const_io_structs)] #![feature(const_ip)] #![feature(const_ipv6)] #![feature(const_raw_ptr_deref)] @@ -296,7 +297,6 @@ #![feature(raw)] #![feature(raw_ref_macros)] #![feature(ready_macro)] -#![feature(renamed_spin_loop)] #![feature(rustc_attrs)] #![feature(rustc_private)] #![feature(shrink_to)] diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index dc13c9433f1..db0777ee9f0 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -535,9 +535,6 @@ unsafe impl<T: Send> Send for SyncSender<T> {} /// A **send** operation can only fail if the receiving end of a channel is /// disconnected, implying that the data could never be received. The error /// contains the data being sent as a payload so it can be recovered. -/// -/// [`Sender::send`]: Sender::send -/// [`SyncSender::send`]: SyncSender::send #[stable(feature = "rust1", since = "1.0.0")] #[derive(PartialEq, Eq, Clone, Copy)] pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T); diff --git a/library/std/src/sys/cloudabi/abi/cloudabi.rs b/library/std/src/sys/cloudabi/abi/cloudabi.rs index 5c4e3fd85c4..d67f0f81a9f 100644 --- a/library/std/src/sys/cloudabi/abi/cloudabi.rs +++ b/library/std/src/sys/cloudabi/abi/cloudabi.rs @@ -143,7 +143,7 @@ pub enum advice { WILLNEED = 6, } -/// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html). +/// Enumeration describing the kind of value stored in [`auxv`]. #[repr(u32)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] #[non_exhaustive] @@ -246,7 +246,7 @@ pub struct condvar(pub u32); pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0); /// Identifier for a device containing a file system. Can be used -/// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the +/// in combination with [`inode`] to uniquely identify a file on the /// local system. #[repr(C)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] @@ -808,7 +808,7 @@ bitflags! { const FILE_SYMLINK = 0x0000000001000000; /// The right to invoke [`file_unlink()`](fn.file_unlink.html). const FILE_UNLINK = 0x0000000002000000; - /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to + /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`] set to /// zero. const MEM_MAP = 0x0000000004000000; /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke @@ -1020,7 +1020,7 @@ bitflags! { /// written it into locks when acquiring them for writing. It is /// not advised to use these identifiers for any other purpose. /// -/// As the thread identifier is also stored in [`lock`](struct.lock.html) when +/// As the thread identifier is also stored in [`lock`] when /// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread /// must always be set to zero. #[repr(C)] @@ -1373,7 +1373,7 @@ fn lookup_layout_test() { /// Entry point for a process (`_start`). /// /// **auxv**: -/// The auxiliary vector. See [`auxv`](struct.auxv.html). +/// The auxiliary vector. See [`auxv`]. pub type processentry = unsafe extern "C" fn(auxv: *const auxv) -> (); /// Arguments of [`sock_recv()`](fn.sock_recv.html). @@ -2372,7 +2372,7 @@ pub unsafe fn file_open( /// /// When successful, the contents of the output buffer consist of /// a sequence of directory entries. Each directory entry consists -/// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes +/// of a [`dirent`] object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes /// holding the name of the directory entry. /// /// This system call fills the output buffer as much as possible, diff --git a/library/std/src/sys/sgx/ext/io.rs b/library/std/src/sys/sgx/ext/io.rs index 8aa84a550d2..f79874a4aec 100644 --- a/library/std/src/sys/sgx/ext/io.rs +++ b/library/std/src/sys/sgx/ext/io.rs @@ -1,7 +1,7 @@ //! SGX-specific extensions to general I/O primitives //! //! SGX file descriptors behave differently from Unix file descriptors. See the -//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details. +//! description of [`TryIntoRawFd`] for more details. #![unstable(feature = "sgx_platform", issue = "56975")] use crate::net; diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index d27d6e2c565..96594095cc3 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1081,7 +1081,20 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { pub fn link(src: &Path, dst: &Path) -> io::Result<()> { let src = cstr(src)?; let dst = cstr(dst)?; - cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?; + cfg_if::cfg_if! { + if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android"))] { + // VxWorks, Redox, and old versions of Android lack `linkat`, so use + // `link` instead. POSIX leaves it implementation-defined whether + // `link` follows symlinks, so rely on the `symlink_hard_link` test + // in library/std/src/fs/tests.rs to check the behavior. + cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?; + } else { + // Use `linkat` with `AT_FDCWD` instead of `link` as `linkat` gives + // us a flag to specify how symlinks should be handled. Pass 0 as + // the flags argument, meaning don't follow symlinks. + cvt(unsafe { libc::linkat(libc::AT_FDCWD, src.as_ptr(), libc::AT_FDCWD, dst.as_ptr(), 0) })?; + } + } Ok(()) } diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 74c7db27226..378d690f8bf 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -55,9 +55,18 @@ impl Socket { pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { unsafe { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { - // On Linux we pass the SOCK_CLOEXEC flag to atomically create - // the socket and set it as CLOEXEC, added in 2.6.27. + if #[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "opensbd", + ))] { + // On platforms that support it we pass the SOCK_CLOEXEC + // flag to atomically create the socket and set it as + // CLOEXEC. On Linux this was added in 2.6.27. let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?; Ok(Socket(FileDesc::new(fd))) } else { @@ -83,7 +92,15 @@ impl Socket { let mut fds = [0, 0]; cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "opensbd", + ))] { // Like above, set cloexec atomically cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1])))) @@ -174,13 +191,28 @@ impl Socket { pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> { // Unfortunately the only known way right now to accept a socket and // atomically set the CLOEXEC flag is to use the `accept4` syscall on - // Linux. This was added in 2.6.28, glibc 2.10 and musl 0.9.5. + // platforms that support it. On Linux, this was added in 2.6.28, + // glibc 2.10 and musl 0.9.5. cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "opensbd", + ))] { let fd = cvt_r(|| unsafe { libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC) })?; Ok(Socket(FileDesc::new(fd))) + // While the Android kernel supports the syscall, + // it is not included in all versions of Android's libc. + } else if #[cfg(target_os = "android")] { + let fd = cvt_r(|| unsafe { + libc::syscall(libc::SYS_accept4, self.0.raw(), storage, len, libc::SOCK_CLOEXEC) + })?; + Ok(Socket(FileDesc::new(fd as c_int))) } else { let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?; let fd = FileDesc::new(fd); diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs index e72fbf0beb4..10aa34e9443 100644 --- a/library/std/src/sys/unix/process/process_common/tests.rs +++ b/library/std/src/sys/unix/process/process_common/tests.rs @@ -14,17 +14,22 @@ macro_rules! t { }; } -// See #14232 for more information, but it appears that signal delivery to a -// newly spawned process may just be raced in the macOS, so to prevent this -// test from being flaky we ignore it on macOS. #[test] -#[cfg_attr(target_os = "macos", ignore)] -// When run under our current QEMU emulation test suite this test fails, -// although the reason isn't very clear as to why. For now this test is -// ignored there. -#[cfg_attr(target_arch = "arm", ignore)] -#[cfg_attr(target_arch = "aarch64", ignore)] -#[cfg_attr(target_arch = "riscv64", ignore)] +#[cfg_attr( + any( + // See #14232 for more information, but it appears that signal delivery to a + // newly spawned process may just be raced in the macOS, so to prevent this + // test from being flaky we ignore it on macOS. + target_os = "macos", + // When run under our current QEMU emulation test suite this test fails, + // although the reason isn't very clear as to why. For now this test is + // ignored there. + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] fn test_process_mask() { unsafe { // Test to make sure that a signal mask does not get inherited. diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index d8db5d1aa69..dd438858c37 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -255,7 +255,7 @@ impl<T: 'static> LocalKey<T> { /// /// This will lazily initialize the value if this thread has not referenced /// this key yet. If the key has been destroyed (which may happen if this is called - /// in a destructor), this function will return an [`AccessError`](struct.AccessError.html). + /// in a destructor), this function will return an [`AccessError`]. /// /// # Panics /// diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index bdb8fc7807b..fefaa77a2a1 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -137,7 +137,6 @@ //! [`thread::current`]: current //! [`thread::Result`]: Result //! [`unpark`]: Thread::unpark -//! [`Thread::name`]: Thread::name //! [`thread::park_timeout`]: park_timeout //! [`Cell`]: crate::cell::Cell //! [`RefCell`]: crate::cell::RefCell diff --git a/library/test/src/helpers/concurrency.rs b/library/test/src/helpers/concurrency.rs index 7e9bd50f556..c39a9b0ec02 100644 --- a/library/test/src/helpers/concurrency.rs +++ b/library/test/src/helpers/concurrency.rs @@ -1,18 +1,14 @@ //! Helper module which helps to determine amount of threads to be used //! during tests execution. -use std::env; -use std::thread; +use std::{env, num::NonZeroUsize, thread}; -#[allow(deprecated)] pub fn get_concurrency() -> usize { - match env::var("RUST_TEST_THREADS") { - Ok(s) => { - let opt_n: Option<usize> = s.parse().ok(); - match opt_n { - Some(n) if n > 0 => n, - _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", s), - } + if let Ok(value) = env::var("RUST_TEST_THREADS") { + match value.parse::<NonZeroUsize>().ok() { + Some(n) => n.get(), + _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", value), } - Err(..) => thread::available_concurrency().map(|n| n.get()).unwrap_or(1), + } else { + thread::available_concurrency().map(|n| n.get()).unwrap_or(1) } } diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 7bb4e504275..a103c9fb0b7 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) - The default bootstrap profiles are now located at `bootstrap/defaults/config.$PROFILE.toml` (previously they were located at `bootstrap/defaults/config.toml.$PROFILE`) [#77558](https://github.com/rust-lang/rust/pull/77558) +- If you have Rust already installed, `x.py` will now infer the host target + from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513) ## [Version 2] - 2020-09-25 diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 87e15363818..54d0a23dec5 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -187,8 +187,23 @@ def format_build_time(duration): return str(datetime.timedelta(seconds=int(duration))) -def default_build_triple(): +def default_build_triple(verbose): """Build triple as in LLVM""" + # If the user already has a host build triple with an existing `rustc` + # install, use their preference. This fixes most issues with Windows builds + # being detected as GNU instead of MSVC. + try: + version = subprocess.check_output(["rustc", "--version", "--verbose"]) + host = next(x for x in version.split('\n') if x.startswith("host: ")) + triple = host.split("host: ")[1] + if verbose: + print("detected default triple {}".format(triple)) + return triple + except Exception as e: + if verbose: + print("rustup not detected: {}".format(e)) + print("falling back to auto-detect") + default_encoding = sys.getdefaultencoding() required = sys.platform != 'win32' ostype = require(["uname", "-s"], exit=required) @@ -831,7 +846,7 @@ class RustBuild(object): config = self.get_toml('build') if config: return config - return default_build_triple() + return default_build_triple(self.verbose) def check_submodule(self, module, slow_submodules): if not slow_submodules: diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b48508f2c24..db671c5fe65 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1178,6 +1178,14 @@ impl<'a> Builder<'a> { } } + // Compile everything except libraries and proc macros with the more + // efficient initial-exec TLS model. This doesn't work with `dlopen`, + // so we can't use it by default in general, but we can use it for tools + // and our own internal libraries. + if !mode.must_support_dlopen() { + rustflags.arg("-Ztls-model=initial-exec"); + } + if self.config.incremental { cargo.env("CARGO_INCREMENTAL", "1"); } else { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 7698ff62880..2fc121a2e86 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -99,6 +99,7 @@ pub struct Config { pub llvm_version_suffix: Option<String>, pub llvm_use_linker: Option<String>, pub llvm_allow_old_toolchain: Option<bool>, + pub llvm_polly: Option<bool>, pub llvm_from_ci: bool, pub use_lld: bool, @@ -418,6 +419,7 @@ struct Llvm { use_libcxx: Option<bool>, use_linker: Option<String>, allow_old_toolchain: Option<bool>, + polly: Option<bool>, download_ci_llvm: Option<StringOrBool>, } @@ -762,6 +764,7 @@ impl Config { set(&mut config.llvm_use_libcxx, llvm.use_libcxx); config.llvm_use_linker = llvm.use_linker.clone(); config.llvm_allow_old_toolchain = llvm.allow_old_toolchain; + config.llvm_polly = llvm.polly; config.llvm_from_ci = match llvm.download_ci_llvm { Some(StringOrBool::String(s)) => { assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s); @@ -795,6 +798,7 @@ impl Config { check_ci_llvm!(llvm.use_libcxx); check_ci_llvm!(llvm.use_linker); check_ci_llvm!(llvm.allow_old_toolchain); + check_ci_llvm!(llvm.polly); // CI-built LLVM is shared config.llvm_link_shared = true; @@ -913,11 +917,18 @@ impl Config { set(&mut config.missing_tools, t.missing_tools); } - // Cargo does not provide a RUSTFMT environment variable, so we - // synthesize it manually. Note that we also later check the config.toml - // and set this to that path if necessary. - let rustfmt = config.initial_rustc.with_file_name(exe("rustfmt", config.build)); - config.initial_rustfmt = if rustfmt.exists() { Some(rustfmt) } else { None }; + config.initial_rustfmt = config.initial_rustfmt.or_else({ + let build = config.build; + let initial_rustc = &config.initial_rustc; + + move || { + // Cargo does not provide a RUSTFMT environment variable, so we + // synthesize it manually. + let rustfmt = initial_rustc.with_file_name(exe("rustfmt", build)); + + if rustfmt.exists() { Some(rustfmt) } else { None } + } + }); // Now that we've reached the end of our configuration, infer the // default values for all options that we haven't otherwise stored yet. diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e156952d56f..322e9d69232 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -266,7 +266,7 @@ config = {} def build(): if 'build' in known_args: return known_args['build'][-1][1] - return bootstrap.default_build_triple() + return bootstrap.default_build_triple(verbose=False) def set(key, value): diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 0878b0ff789..3d111839dc7 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -332,6 +332,10 @@ impl Mode { pub fn is_tool(&self) -> bool { matches!(self, Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd) } + + pub fn must_support_dlopen(&self) -> bool { + matches!(self, Mode::Std | Mode::Codegen) + } } impl Build { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 37d6fab070b..6dc83c7d70a 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -257,6 +257,10 @@ impl Step for Llvm { enabled_llvm_projects.push("compiler-rt"); } + if let Some(true) = builder.config.llvm_polly { + enabled_llvm_projects.push("polly"); + } + // We want libxml to be disabled. // See https://github.com/rust-lang/rust/pull/50104 cfg.define("LLVM_ENABLE_LIBXML2", "OFF"); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index b48e9696c9a..2b87c4b91af 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1205,17 +1205,6 @@ note: if you're sure you want to do this, please open an issue as to why. In the // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") { - cmd.arg("--cc") - .arg(builder.cc(target)) - .arg("--cxx") - .arg(builder.cxx(target).unwrap()) - .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); - copts_passed = true; - if let Some(ar) = builder.ar(target) { - cmd.arg("--ar").arg(ar); - } - // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. let llvm_bin_path = llvm_config @@ -1241,6 +1230,21 @@ note: if you're sure you want to do this, please open an issue as to why. In the } } + // Only pass correct values for these flags for the `run-make` suite as it + // requires that a C++ compiler was configured which isn't always the case. + if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") { + cmd.arg("--cc") + .arg(builder.cc(target)) + .arg("--cxx") + .arg(builder.cxx(target).unwrap()) + .arg("--cflags") + .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); + copts_passed = true; + if let Some(ar) = builder.ar(target) { + cmd.arg("--ar").arg(ar); + } + } + if !llvm_components_passed { cmd.arg("--llvm-components").arg(""); } diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile index df65f9df441..95c54ca1abc 100644 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile @@ -35,6 +35,5 @@ ENV HOSTS=aarch64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --enable-full-tools \ --enable-profiler \ - --enable-sanitizers \ - --disable-docs + --enable-sanitizers ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile deleted file mode 100644 index 7db6e58c4d6..00000000000 --- a/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update && apt-get install -y --no-install-recommends \ - clang \ - make \ - ninja-build \ - file \ - curl \ - ca-certificates \ - python3 \ - git \ - cmake \ - sudo \ - bzip2 \ - xz-utils \ - wget \ - libssl-dev \ - pkg-config - -COPY scripts/freebsd-toolchain.sh /tmp/ -RUN /tmp/freebsd-toolchain.sh i686 - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -ENV \ - AR_i686_unknown_freebsd=i686-unknown-freebsd11-ar \ - CC_i686_unknown_freebsd=i686-unknown-freebsd11-clang \ - CXX_i686_unknown_freebsd=i686-unknown-freebsd11-clang++ - -ENV HOSTS=i686-unknown-freebsd - -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 47a66f74808..b8b81ab327b 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -48,6 +48,9 @@ ENV \ CFLAGS_x86_64_fortanix_unknown_sgx="-mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \ CXX_x86_64_fortanix_unknown_sgx=x86_64-fortanix-unknown-sgx-clang++-11 \ CXXFLAGS_x86_64_fortanix_unknown_sgx="-mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \ + AR_i686_unknown_freebsd=i686-unknown-freebsd11-ar \ + CC_i686_unknown_freebsd=i686-unknown-freebsd11-clang \ + CXX_i686_unknown_freebsd=i686-unknown-freebsd11-clang++ \ CC=gcc-7 \ CXX=g++-7 @@ -74,6 +77,9 @@ RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh COPY host-x86_64/dist-various-2/build-wasi-toolchain.sh /tmp/ RUN /tmp/build-wasi-toolchain.sh +COPY scripts/freebsd-toolchain.sh /tmp/ +RUN /tmp/freebsd-toolchain.sh i686 + COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh @@ -99,6 +105,7 @@ ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi +ENV TARGETS=$TARGETS,i686-unknown-freebsd # As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211 # we need asm in the search path for gcc-7 (for gnux32) but not in the search path of the diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile index 930061fca6f..0e28ea9668f 100644 --- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile @@ -27,6 +27,3 @@ RUN echo "optimize = false" >> /config/nopt-std-config.toml ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests ENV SCRIPT python3 ../x.py test --stage 0 --config /config/nopt-std-config.toml library/std \ && python3 ../x.py --stage 2 test - -# FIXME(#59637) takes too long on CI right now -ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile index ea178bcf4f2..195601755f3 100644 --- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile @@ -28,6 +28,3 @@ ENV SCRIPT python3 ../x.py --stage 2 test \ --exclude src/test/rustdoc-js \ --exclude src/tools/error_index_generator \ --exclude src/tools/linkchecker - -# FIXME(#59637) takes too long on CI right now -ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile index 5f98edf6171..5faa0ccab56 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile @@ -22,10 +22,3 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --set rust.ignore-git=false ENV SCRIPT python3 ../x.py --stage 2 test distcheck ENV DIST_SRC 1 - -# The purpose of this builder is to test that we can `./x.py --stage 2 test` successfully -# from a tarball, not to test LLVM/rustc's own set of assertions. These cause a -# significant hit to CI compile time (over a half hour as observed in #61185), -# so disable assertions for this builder. -ENV NO_LLVM_ASSERTIONS=1 -ENV NO_DEBUG_ASSERTIONS=1 diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile index 34c6396b7b5..bd046f802c8 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile @@ -57,9 +57,3 @@ ENV SCRIPT python2.7 ../x.py --stage 2 test --exclude src/tools/tidy && \ python2.7 ../x.py --stage 2 test src/test/ui --pass=check && \ # Run tidy at the very end, after all the other tests. python2.7 ../x.py --stage 2 test src/tools/tidy - -# The purpose of this container isn't to test with debug assertions and -# this is run on all PRs, so let's get speedier builds by disabling these extra -# checks. -ENV NO_DEBUG_ASSERTIONS=1 -ENV NO_LLVM_ASSERTIONS=1 diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 0df191f8f74..031000d147c 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -301,6 +301,9 @@ jobs: # Linux/Docker builders # ############################# + - name: aarch64-gnu + <<: *job-aarch64-linux + - name: arm-android <<: *job-linux-xl @@ -325,9 +328,6 @@ jobs: - name: dist-i586-gnu-i586-i686-musl <<: *job-linux-xl - - name: dist-i686-freebsd - <<: *job-linux-xl - - name: dist-i686-linux <<: *job-linux-xl @@ -500,9 +500,6 @@ jobs: env: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler SCRIPT: make ci-subset-1 - # FIXME(#59637) - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 <<: *job-windows-xl - name: x86_64-msvc-2 @@ -515,18 +512,12 @@ jobs: env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc SCRIPT: make ci-subset-1 - # FIXME(#59637) - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 <<: *job-windows-xl - name: i686-msvc-2 env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc SCRIPT: make ci-subset-2 - # FIXME(#59637) - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 <<: *job-windows-xl - name: x86_64-msvc-cargo @@ -534,9 +525,6 @@ jobs: SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld VCVARS_BAT: vcvars64.bat - # FIXME(#59637) - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 <<: *job-windows-xl - name: x86_64-msvc-tools @@ -566,9 +554,6 @@ jobs: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-1 CUSTOM_MINGW: 1 - # FIXME(#59637) - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 <<: *job-windows-xl - name: i686-mingw-2 @@ -583,9 +568,6 @@ jobs: SCRIPT: make ci-mingw-subset-1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-profiler CUSTOM_MINGW: 1 - # FIXME(#59637) - NO_DEBUG_ASSERTIONS: 1 - NO_LLVM_ASSERTIONS: 1 <<: *job-windows-xl - name: x86_64-mingw-2 @@ -653,23 +635,6 @@ jobs: SCRIPT: python x.py dist <<: *job-windows-xl - auto-fallible: - <<: *base-ci-job - name: auto-fallible - env: - <<: [*shared-ci-variables, *dummy-variables] - if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' - strategy: - fail-fast: false - matrix: - include: - ############################# - # Linux/Docker builders # - ############################# - - - name: aarch64-gnu - <<: *job-aarch64-linux - try: <<: *base-ci-job name: try diff --git a/src/ci/scripts/should-skip-this.sh b/src/ci/scripts/should-skip-this.sh index f945db0ada2..36bf4368990 100755 --- a/src/ci/scripts/should-skip-this.sh +++ b/src/ci/scripts/should-skip-this.sh @@ -14,6 +14,10 @@ elif git diff HEAD^ | grep --quiet "^index .* 160000"; then # Submodules pseudo-files inside git have the 160000 permissions, so when # those files are present in the diff a submodule was updated. echo "Executing the job since submodules are updated" +elif git diff --name-only HEAD^ | grep --quiet src/tools/clippy; then + # There is not an easy blanket search for subtrees. For now, manually list + # clippy. + echo "Executing the job since clippy subtree was updated" else echo "Not executing this job since no submodules were updated" ciCommandSetEnv SKIP_JOB 1 diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 85c6f91f085..215e5d3d104 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -34,6 +34,7 @@ Specifically they will each satisfy the following requirements: target | std | host | notes -------|-----|------|------- +`aarch64-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes] `i686-pc-windows-gnu` | ✓ | ✓ | 32-bit MinGW (Windows 7+) `i686-pc-windows-msvc` | ✓ | ✓ | 32-bit MSVC (Windows 7+) `i686-unknown-linux-gnu` | ✓ | ✓ | 32-bit Linux (kernel 2.6.32+, glibc 2.11+) @@ -42,6 +43,12 @@ target | std | host | notes `x86_64-pc-windows-msvc` | ✓ | ✓ | 64-bit MSVC (Windows 7+) `x86_64-unknown-linux-gnu` | ✓ | ✓ | 64-bit Linux (kernel 2.6.32+, glibc 2.11+) +[^missing-stack-probes]: Stack probes support is missing on + `aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near + future. The implementation is tracked on [issue #77071][77071]. + +[77071]: https://github.com/rust-lang/rust/issues/77071 + ## Tier 2 Tier 2 platforms can be thought of as "guaranteed to build". Automated tests @@ -62,7 +69,6 @@ target | std | host | notes `aarch64-fuchsia` | ✓ | | ARM64 Fuchsia `aarch64-linux-android` | ✓ | | ARM64 Android `aarch64-pc-windows-msvc` | ✓ | ✓ | ARM64 Windows MSVC -`aarch64-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (kernel 4.2, glibc 2.17) `aarch64-unknown-linux-musl` | ✓ | ✓ | ARM64 Linux with MUSL `aarch64-unknown-none` | * | | Bare ARM64, hardfloat `aarch64-unknown-none-softfloat` | * | | Bare ARM64, softfloat @@ -88,7 +94,7 @@ target | std | host | notes `i586-unknown-linux-gnu` | ✓ | | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23) `i586-unknown-linux-musl` | ✓ | | 32-bit Linux w/o SSE, MUSL `i686-linux-android` | ✓ | | 32-bit x86 Android -`i686-unknown-freebsd` | ✓ | ✓ | 32-bit FreeBSD +`i686-unknown-freebsd` | ✓ | | 32-bit FreeBSD `i686-unknown-linux-musl` | ✓ | | 32-bit Linux with MUSL `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) `mips-unknown-linux-musl` | ✓ | | MIPS Linux with MUSL diff --git a/src/doc/unstable-book/src/language-features/cfg-panic.md b/src/doc/unstable-book/src/language-features/cfg-panic.md new file mode 100644 index 00000000000..f5b73128ad6 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/cfg-panic.md @@ -0,0 +1,38 @@ +# `cfg_panic` + +The tracking issue for this feature is: [#77443] + +[#77443]: https://github.com/rust-lang/rust/issues/77443 + +------------------------ + +The `cfg_panic` feature makes it possible to execute different code +depending on the panic strategy. + +Possible values at the moment are `"unwind"` or `"abort"`, although +it is possible that new panic strategies may be added to Rust in the +future. + +## Examples + +```rust +#![feature(cfg_panic)] + +#[cfg(panic = "unwind")] +fn a() { + // ... +} + +#[cfg(not(panic = "unwind"))] +fn a() { + // ... +} + +fn b() { + if cfg!(panic = "abort") { + // ... + } else { + // ... + } +} +``` diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5eca54199d6..4cad6418d6a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -322,7 +322,8 @@ pub fn run_core( let cpath = Some(input.clone()); let input = Input::File(input); - let intra_link_resolution_failure_name = lint::builtin::BROKEN_INTRA_DOC_LINKS.name; + let broken_intra_doc_links = lint::builtin::BROKEN_INTRA_DOC_LINKS.name; + let private_intra_doc_links = lint::builtin::PRIVATE_INTRA_DOC_LINKS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; @@ -336,7 +337,8 @@ pub fn run_core( // In addition to those specific lints, we also need to allow those given through // command line, otherwise they'll get ignored and we don't want that. let lints_to_show = vec![ - intra_link_resolution_failure_name.to_owned(), + broken_intra_doc_links.to_owned(), + private_intra_doc_links.to_owned(), missing_docs.to_owned(), missing_doc_example.to_owned(), private_doc_tests.to_owned(), @@ -349,9 +351,8 @@ pub fn run_core( ]; let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| { - if lint.name == intra_link_resolution_failure_name - || lint.name == invalid_codeblock_attributes_name - { + // FIXME: why is this necessary? + if lint.name == broken_intra_doc_links || lint.name == invalid_codeblock_attributes_name { None } else { Some((lint.name_lower(), lint::Allow)) diff --git a/src/librustdoc/html/static/settings.css b/src/librustdoc/html/static/settings.css index 4bacd7b245b..fb8990b30e2 100644 --- a/src/librustdoc/html/static/settings.css +++ b/src/librustdoc/html/static/settings.css @@ -26,7 +26,8 @@ } .toggle input { - display: none; + opacity: 0; + position: absolute; } .select-wrapper { @@ -90,7 +91,7 @@ input:checked + .slider { } input:focus + .slider { - box-shadow: 0 0 1px #2196F3; + box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3); } input:checked + .slider:before { diff --git a/src/test/mir-opt/inline/inline-cycle.rs b/src/test/mir-opt/inline/inline-cycle.rs new file mode 100644 index 00000000000..63ad57de1d4 --- /dev/null +++ b/src/test/mir-opt/inline/inline-cycle.rs @@ -0,0 +1,60 @@ +// Check that inliner handles various forms of recursion and doesn't fall into +// an infinite inlining cycle. The particular outcome of inlining is not +// crucial otherwise. +// +// Regression test for issue #78573. + +fn main() { + one(); + two(); +} + +// EMIT_MIR inline_cycle.one.Inline.diff +fn one() { + <C as Call>::call(); +} + +pub trait Call { + fn call(); +} + +pub struct A<T>(T); +pub struct B<T>(T); +pub struct C; + +impl<T: Call> Call for A<T> { + #[inline] + fn call() { + <B<T> as Call>::call() + } +} + + +impl<T: Call> Call for B<T> { + #[inline] + fn call() { + <T as Call>::call() + } +} + +impl Call for C { + #[inline] + fn call() { + A::<C>::call() + } +} + +// EMIT_MIR inline_cycle.two.Inline.diff +fn two() { + call(f); +} + +#[inline] +fn call<F: FnOnce()>(f: F) { + f(); +} + +#[inline] +fn f() { + call(f); +} diff --git a/src/test/mir-opt/inline/inline-shims.rs b/src/test/mir-opt/inline/inline-shims.rs new file mode 100644 index 00000000000..7c8618f71e5 --- /dev/null +++ b/src/test/mir-opt/inline/inline-shims.rs @@ -0,0 +1,13 @@ +// ignore-wasm32-bare compiled with panic=abort by default +#![crate_type = "lib"] + +// EMIT_MIR inline_shims.clone.Inline.diff +pub fn clone<A, B>(f: fn(A, B)) -> fn(A, B) { + f.clone() +} + +// EMIT_MIR inline_shims.drop.Inline.diff +pub fn drop<A, B>(a: *mut Vec<A>, b: *mut Option<B>) { + unsafe { std::ptr::drop_in_place(a) } + unsafe { std::ptr::drop_in_place(b) } +} diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff new file mode 100644 index 00000000000..1b53c827885 --- /dev/null +++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff @@ -0,0 +1,27 @@ +- // MIR for `one` before Inline ++ // MIR for `one` after Inline + + fn one() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:13:10: 13:10 + let _1: (); // in scope 0 at $DIR/inline-cycle.rs:14:5: 14:24 ++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle.rs:14:5: 14:24 ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:14:5: 14:24 +- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle.rs:14:5: 14:24 ++ _1 = <A<C> as Call>::call() -> bb1; // scope 1 at $DIR/inline-cycle.rs:14:5: 14:24 + // mir::Constant +- // + span: $DIR/inline-cycle.rs:14:5: 14:22 +- // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(Scalar(<ZST>)) } ++ // + span: $DIR/inline-cycle.rs:14:5: 14:24 ++ // + literal: Const { ty: fn() {<A<C> as Call>::call}, val: Value(Scalar(<ZST>)) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:14:24: 14:25 + _0 = const (); // scope 0 at $DIR/inline-cycle.rs:13:10: 15:2 + return; // scope 0 at $DIR/inline-cycle.rs:15:2: 15:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff new file mode 100644 index 00000000000..b44baca9bf4 --- /dev/null +++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff @@ -0,0 +1,47 @@ +- // MIR for `two` before Inline ++ // MIR for `two` after Inline + + fn two() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:48:10: 48:10 + let _1: (); // in scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 ++ let mut _2: fn() {f}; // in scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 ++ let mut _5: (); // in scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 ++ scope 1 (inlined call::<fn() {f}>) { // at $DIR/inline-cycle.rs:49:5: 49:12 ++ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline-cycle.rs:49:5: 49:12 ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 +- _1 = call::<fn() {f}>(f) -> bb1; // scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 ++ StorageLive(_2); // scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 ++ _2 = f; // scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 + // mir::Constant +- // + span: $DIR/inline-cycle.rs:49:5: 49:9 +- // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(Scalar(<ZST>)) } +- // mir::Constant + // + span: $DIR/inline-cycle.rs:49:10: 49:11 + // + literal: Const { ty: fn() {f}, val: Value(Scalar(<ZST>)) } ++ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ _5 = const (); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ _3 = move _4() -> bb1; // scope 2 at $DIR/inline-cycle.rs:49:5: 49:12 + } + + bb1: { ++ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ _1 = const (); // scope 1 at $DIR/inline-cycle.rs:49:5: 49:12 ++ StorageDead(_2); // scope 0 at $DIR/inline-cycle.rs:49:5: 49:12 + StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:49:12: 49:13 + _0 = const (); // scope 0 at $DIR/inline-cycle.rs:48:10: 50:2 + return; // scope 0 at $DIR/inline-cycle.rs:50:2: 50:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff new file mode 100644 index 00000000000..3bdd4f4ff56 --- /dev/null +++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff @@ -0,0 +1,26 @@ +- // MIR for `clone` before Inline ++ // MIR for `clone` after Inline + + fn clone(_1: fn(A, B)) -> fn(A, B) { + debug f => _1; // in scope 0 at $DIR/inline-shims.rs:5:20: 5:21 + let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline-shims.rs:5:36: 5:44 + let mut _2: &fn(A, B); // in scope 0 at $DIR/inline-shims.rs:6:5: 6:6 ++ scope 1 (inlined <fn(A, B) as Clone>::clone - shim(fn(A, B))) { // at $DIR/inline-shims.rs:6:5: 6:14 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-shims.rs:6:5: 6:6 + _2 = &_1; // scope 0 at $DIR/inline-shims.rs:6:5: 6:6 +- _0 = <fn(A, B) as Clone>::clone(move _2) -> bb1; // scope 0 at $DIR/inline-shims.rs:6:5: 6:14 +- // mir::Constant +- // + span: $DIR/inline-shims.rs:6:7: 6:12 +- // + literal: Const { ty: for<'r> fn(&'r fn(A, B)) -> fn(A, B) {<fn(A, B) as std::clone::Clone>::clone}, val: Value(Scalar(<ZST>)) } +- } +- +- bb1: { ++ _0 = (*_2); // scope 1 at $DIR/inline-shims.rs:6:5: 6:14 + StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:6:13: 6:14 + return; // scope 0 at $DIR/inline-shims.rs:7:2: 7:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff new file mode 100644 index 00000000000..503d8bc6b7a --- /dev/null +++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff @@ -0,0 +1,52 @@ +- // MIR for `drop` before Inline ++ // MIR for `drop` after Inline + + fn drop(_1: *mut Vec<A>, _2: *mut Option<B>) -> () { + debug a => _1; // in scope 0 at $DIR/inline-shims.rs:10:19: 10:20 + debug b => _2; // in scope 0 at $DIR/inline-shims.rs:10:35: 10:36 + let mut _0: (); // return place in scope 0 at $DIR/inline-shims.rs:10:54: 10:54 + let _3: (); // in scope 0 at $DIR/inline-shims.rs:11:14: 11:40 + let mut _4: *mut std::vec::Vec<A>; // in scope 0 at $DIR/inline-shims.rs:11:38: 11:39 + let mut _5: *mut std::option::Option<B>; // in scope 0 at $DIR/inline-shims.rs:12:38: 12:39 + scope 1 { + } + scope 2 { ++ scope 3 (inlined drop_in_place::<Option<B>> - shim(Some(Option<B>))) { // at $DIR/inline-shims.rs:12:14: 12:40 ++ let mut _6: isize; // in scope 3 at $DIR/inline-shims.rs:12:14: 12:40 ++ let mut _7: isize; // in scope 3 at $DIR/inline-shims.rs:12:14: 12:40 ++ } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline-shims.rs:11:5: 11:42 + StorageLive(_4); // scope 1 at $DIR/inline-shims.rs:11:38: 11:39 + _4 = _1; // scope 1 at $DIR/inline-shims.rs:11:38: 11:39 + _3 = drop_in_place::<Vec<A>>(move _4) -> bb1; // scope 1 at $DIR/inline-shims.rs:11:14: 11:40 + // mir::Constant + // + span: $DIR/inline-shims.rs:11:14: 11:37 + // + literal: Const { ty: unsafe fn(*mut std::vec::Vec<A>) {std::intrinsics::drop_in_place::<std::vec::Vec<A>>}, val: Value(Scalar(<ZST>)) } + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/inline-shims.rs:11:39: 11:40 + StorageDead(_3); // scope 0 at $DIR/inline-shims.rs:11:41: 11:42 + StorageLive(_5); // scope 2 at $DIR/inline-shims.rs:12:38: 12:39 + _5 = _2; // scope 2 at $DIR/inline-shims.rs:12:38: 12:39 +- _0 = drop_in_place::<Option<B>>(move _5) -> bb2; // scope 2 at $DIR/inline-shims.rs:12:14: 12:40 +- // mir::Constant +- // + span: $DIR/inline-shims.rs:12:14: 12:37 +- // + literal: Const { ty: unsafe fn(*mut std::option::Option<B>) {std::intrinsics::drop_in_place::<std::option::Option<B>>}, val: Value(Scalar(<ZST>)) } ++ _6 = discriminant((*_5)); // scope 3 at $DIR/inline-shims.rs:12:14: 12:40 ++ switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $DIR/inline-shims.rs:12:14: 12:40 + } + + bb2: { + StorageDead(_5); // scope 2 at $DIR/inline-shims.rs:12:39: 12:40 + return; // scope 0 at $DIR/inline-shims.rs:13:2: 13:2 ++ } ++ ++ bb3: { ++ drop((((*_5) as Some).0: B)) -> bb2; // scope 3 at $DIR/inline-shims.rs:12:14: 12:40 + } + } + diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs new file mode 100644 index 00000000000..95683241aba --- /dev/null +++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.rs @@ -0,0 +1,37 @@ +// edition:2018 +#![feature(async_closure)] +use std::future::Future; + +// test the quality of annotations giving lifetimes names (`'1`) when async constructs are involved + +pub async fn async_fn(x: &mut i32) -> &i32 { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y +} + +pub fn async_closure(x: &mut i32) -> impl Future<Output=&i32> { + (async move || { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y + })() +} + +pub fn async_closure_explicit_return_type(x: &mut i32) -> impl Future<Output=&i32> { + (async move || -> &i32 { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y + })() +} + +pub fn async_block(x: &mut i32) -> impl Future<Output=&i32> { + async move { + let y = &*x; + *x += 1; //~ ERROR cannot assign to `*x` because it is borrowed + y + } +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr new file mode 100644 index 00000000000..123c3192cff --- /dev/null +++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -0,0 +1,51 @@ +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5 + | +LL | pub async fn async_fn(x: &mut i32) -> &i32 { + | - let's call the lifetime of this reference `'1` +LL | let y = &*x; + | --- borrow of `*x` occurs here +LL | *x += 1; + | ^^^^^^^ assignment to borrowed `*x` occurs here +LL | y + | - returning this value requires that `*x` is borrowed for `'1` + +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:16:9 + | +LL | let y = &*x; + | --- borrow of `*x` occurs here +LL | *x += 1; + | ^^^^^^^ assignment to borrowed `*x` occurs here +LL | y + | - returning this value requires that `*x` is borrowed for `'1` +LL | })() + | - return type of async closure is &'1 i32 + +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:24:9 + | +LL | (async move || -> &i32 { + | - let's call the lifetime of this reference `'1` +LL | let y = &*x; + | --- borrow of `*x` occurs here +LL | *x += 1; + | ^^^^^^^ assignment to borrowed `*x` occurs here +LL | y + | - returning this value requires that `*x` is borrowed for `'1` + +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/issue-74072-lifetime-name-annotations.rs:32:9 + | +LL | let y = &*x; + | --- borrow of `*x` occurs here +LL | *x += 1; + | ^^^^^^^ assignment to borrowed `*x` occurs here +LL | y + | - returning this value requires that `*x` is borrowed for `'1` +LL | } + | - return type of async block is &'1 i32 + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/async-await/issue-74497-lifetime-in-opaque.rs b/src/test/ui/async-await/issue-74497-lifetime-in-opaque.rs new file mode 100644 index 00000000000..2d765eb41be --- /dev/null +++ b/src/test/ui/async-await/issue-74497-lifetime-in-opaque.rs @@ -0,0 +1,19 @@ +// edition:2018 + +// test that names give to anonymous lifetimes in opaque types like `impl Future` are correctly +// introduced in error messages + +use std::future::Future; + +pub async fn foo<F, T>(_: F) +where + F: Fn(&u8) -> T, + T: Future<Output = ()>, +{ +} + +pub async fn bar(_: &u8) {} + +fn main() { + let _ = foo(|x| bar(x)); //~ ERROR lifetime may not live long enough +} diff --git a/src/test/ui/async-await/issue-74497-lifetime-in-opaque.stderr b/src/test/ui/async-await/issue-74497-lifetime-in-opaque.stderr new file mode 100644 index 00000000000..89fe1abb365 --- /dev/null +++ b/src/test/ui/async-await/issue-74497-lifetime-in-opaque.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/issue-74497-lifetime-in-opaque.rs:18:21 + | +LL | let _ = foo(|x| bar(x)); + | -- ^^^^^^ returning this value requires that `'1` must outlive `'2` + | || + | |return type of closure `impl Future` contains a lifetime `'2` + | has type `&'1 u8` + +error: aborting due to previous error + diff --git a/src/test/ui/bad/bad-expr-lhs.rs b/src/test/ui/bad/bad-expr-lhs.rs index d7cf1b77005..39536f12e3b 100644 --- a/src/test/ui/bad/bad-expr-lhs.rs +++ b/src/test/ui/bad/bad-expr-lhs.rs @@ -1,10 +1,12 @@ fn main() { 1 = 2; //~ ERROR invalid left-hand side of assignment 1 += 2; //~ ERROR invalid left-hand side of assignment - (1, 2) = (3, 4); //~ ERROR invalid left-hand side of assignment + (1, 2) = (3, 4); //~ ERROR destructuring assignments are unstable + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment let (a, b) = (1, 2); - (a, b) = (3, 4); //~ ERROR invalid left-hand side of assignment + (a, b) = (3, 4); //~ ERROR destructuring assignments are unstable None = Some(3); //~ ERROR invalid left-hand side of assignment } diff --git a/src/test/ui/bad/bad-expr-lhs.stderr b/src/test/ui/bad/bad-expr-lhs.stderr index a195e1054d0..d4b2193d09f 100644 --- a/src/test/ui/bad/bad-expr-lhs.stderr +++ b/src/test/ui/bad/bad-expr-lhs.stderr @@ -1,3 +1,25 @@ +error[E0658]: destructuring assignments are unstable + --> $DIR/bad-expr-lhs.rs:4:12 + | +LL | (1, 2) = (3, 4); + | ------ ^ + | | + | cannot assign to this expression + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/bad-expr-lhs.rs:9:12 + | +LL | (a, b) = (3, 4); + | ------ ^ + | | + | cannot assign to this expression + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + error[E0070]: invalid left-hand side of assignment --> $DIR/bad-expr-lhs.rs:2:7 | @@ -18,30 +40,27 @@ error[E0070]: invalid left-hand side of assignment --> $DIR/bad-expr-lhs.rs:4:12 | LL | (1, 2) = (3, 4); - | ------ ^ - | | - | cannot assign to this expression + | - ^ + | | + | cannot assign to this expression error[E0070]: invalid left-hand side of assignment - --> $DIR/bad-expr-lhs.rs:7:12 - | -LL | (a, b) = (3, 4); - | ------ ^ - | | - | cannot assign to this expression + --> $DIR/bad-expr-lhs.rs:4:12 | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 +LL | (1, 2) = (3, 4); + | - ^ + | | + | cannot assign to this expression error[E0070]: invalid left-hand side of assignment - --> $DIR/bad-expr-lhs.rs:9:10 + --> $DIR/bad-expr-lhs.rs:11:10 | LL | None = Some(3); | ---- ^ | | | cannot assign to this expression -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0067, E0070. +Some errors have detailed explanations: E0067, E0070, E0658. For more information about an error, try `rustc --explain E0067`. diff --git a/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr b/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr index e8a026cfab9..a7c3b9eec73 100644 --- a/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr +++ b/src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | let _action = move || { | ------- | | | - | | return type of closure is [closure@$DIR/issue-53432-nested-closure-outlives-borrowed-value.rs:4:9: 4:15] + | | return type of closure `[closure@$DIR/issue-53432-nested-closure-outlives-borrowed-value.rs:4:9: 4:15]` contains a lifetime `'2` | lifetime `'1` represents this closure's body LL | || f() // The `nested` closure | ^^^^^^ returning this value requires that `'1` must outlive `'2` diff --git a/src/test/ui/cfg/cfg-panic-abort.rs b/src/test/ui/cfg/cfg-panic-abort.rs new file mode 100644 index 00000000000..9b88eff12ed --- /dev/null +++ b/src/test/ui/cfg/cfg-panic-abort.rs @@ -0,0 +1,16 @@ +// build-pass +// compile-flags: -C panic=abort +// no-prefer-dynamic +#![feature(cfg_panic)] + +#[cfg(panic = "unwind")] +pub fn bad() -> i32 { } + +#[cfg(not(panic = "abort"))] +pub fn bad() -> i32 { } + +#[cfg(panic = "some_imaginary_future_panic_handler")] +pub fn bad() -> i32 { } + +#[cfg(panic = "abort")] +pub fn main() { } diff --git a/src/test/ui/cfg/cfg-panic.rs b/src/test/ui/cfg/cfg-panic.rs new file mode 100644 index 00000000000..dbb5932a9bb --- /dev/null +++ b/src/test/ui/cfg/cfg-panic.rs @@ -0,0 +1,18 @@ +// build-pass +// compile-flags: -C panic=unwind +// ignore-emscripten no panic_unwind implementation +// ignore-wasm32 no panic_unwind implementation +// ignore-wasm64 no panic_unwind implementation +#![feature(cfg_panic)] + +#[cfg(panic = "abort")] +pub fn bad() -> i32 { } + +#[cfg(not(panic = "unwind"))] +pub fn bad() -> i32 { } + +#[cfg(panic = "some_imaginary_future_panic_handler")] +pub fn bad() -> i32 { } + +#[cfg(panic = "unwind")] +pub fn main() { } diff --git a/src/test/ui/chalkify/arithmetic.rs b/src/test/ui/chalkify/arithmetic.rs new file mode 100644 index 00000000000..a20acce4c76 --- /dev/null +++ b/src/test/ui/chalkify/arithmetic.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: -Z chalk + +fn main() { + 1 + 2; + 3 * 6; + 2 - 5; + 17 / 6; + 23 % 11; + 4 & 6; + 7 | 15; + 4 << 7; + 123 >> 3; + 1 == 2; + 5 != 5; + 6 < 2; + 7 > 11; + 3 <= 1; + 9 >= 14; +} diff --git a/src/test/ui/chalkify/trait-objects.rs b/src/test/ui/chalkify/trait-objects.rs new file mode 100644 index 00000000000..13d9e6a6578 --- /dev/null +++ b/src/test/ui/chalkify/trait-objects.rs @@ -0,0 +1,13 @@ +// check-pass +// compile-flags: -Z chalk + +use std::fmt::Display; + +fn main() { + let d: &dyn Display = &mut 3; + // FIXME(chalk) should be able to call d.to_string() as well, but doing so + // requires Chalk to be able to prove trait object well-formed goals. + (&d).to_string(); + let f: &dyn Fn(i32) -> _ = &|x| x + x; + f(2); +} diff --git a/src/test/ui/consts/control-flow/assert.panic.stderr b/src/test/ui/consts/control-flow/assert.const_panic.stderr index 03662a35209..03662a35209 100644 --- a/src/test/ui/consts/control-flow/assert.panic.stderr +++ b/src/test/ui/consts/control-flow/assert.const_panic.stderr diff --git a/src/test/ui/consts/control-flow/assert.rs b/src/test/ui/consts/control-flow/assert.rs index 30cd31ee8a7..90017fee193 100644 --- a/src/test/ui/consts/control-flow/assert.rs +++ b/src/test/ui/consts/control-flow/assert.rs @@ -1,14 +1,14 @@ // Test that `assert` works when `const_panic` is enabled. -// revisions: stock panic +// revisions: stock const_panic -#![cfg_attr(panic, feature(const_panic))] +#![cfg_attr(const_panic, feature(const_panic))] const _: () = assert!(true); //[stock]~^ ERROR panicking in constants is unstable const _: () = assert!(false); //[stock]~^ ERROR panicking in constants is unstable -//[panic]~^^ ERROR any use of this value will cause an error +//[const_panic]~^^ ERROR any use of this value will cause an error fn main() {} diff --git a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs new file mode 100644 index 00000000000..adecd0ff291 --- /dev/null +++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.rs @@ -0,0 +1,7 @@ +#![feature(destructuring_assignment)] + +fn main() { + let mut x = &0; + let mut y = &0; + (x, y) = &(1, 2); //~ ERROR mismatched types +} diff --git a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr new file mode 100644 index 00000000000..e6161fdfa24 --- /dev/null +++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/default-match-bindings-forbidden.rs:6:5 + | +LL | (x, y) = &(1, 2); + | ^^^^^^ ------- this expression has type `&({integer}, {integer})` + | | + | expected reference, found tuple + | + = note: expected type `&({integer}, {integer})` + found tuple `(_, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/destructuring-assignment/note-unsupported.rs b/src/test/ui/destructuring-assignment/note-unsupported.rs index 876c9efea26..e0cb9dc9158 100644 --- a/src/test/ui/destructuring-assignment/note-unsupported.rs +++ b/src/test/ui/destructuring-assignment/note-unsupported.rs @@ -3,23 +3,24 @@ struct S { x: u8, y: u8 } fn main() { let (a, b) = (1, 2); - (a, b) = (3, 4); //~ ERROR invalid left-hand side of assignment + (a, b) = (3, 4); //~ ERROR destructuring assignments are unstable (a, b) += (3, 4); //~ ERROR invalid left-hand side of assignment - //~^ ERROR binary assignment operation `+=` cannot be applied + //~| ERROR binary assignment operation `+=` cannot be applied [a, b] = [3, 4]; //~ ERROR invalid left-hand side of assignment [a, b] += [3, 4]; //~ ERROR invalid left-hand side of assignment - //~^ ERROR binary assignment operation `+=` cannot be applied + //~| ERROR binary assignment operation `+=` cannot be applied let s = S { x: 3, y: 4 }; S { x: a, y: b } = s; //~ ERROR invalid left-hand side of assignment S { x: a, y: b } += s; //~ ERROR invalid left-hand side of assignment - //~^ ERROR binary assignment operation `+=` cannot be applied + //~| ERROR binary assignment operation `+=` cannot be applied - S { x: a, ..s } = S { x: 3, y: 4 }; //~ ERROR invalid left-hand side of assignment + S { x: a, ..s } = S { x: 3, y: 4 }; + //~^ ERROR invalid left-hand side of assignment let c = 3; - ((a, b), c) = ((3, 4), 5); //~ ERROR invalid left-hand side of assignment + ((a, b), c) = ((3, 4), 5); //~ ERROR destructuring assignments are unstable } diff --git a/src/test/ui/destructuring-assignment/note-unsupported.stderr b/src/test/ui/destructuring-assignment/note-unsupported.stderr index d4e25930d22..c5543fab825 100644 --- a/src/test/ui/destructuring-assignment/note-unsupported.stderr +++ b/src/test/ui/destructuring-assignment/note-unsupported.stderr @@ -1,4 +1,4 @@ -error[E0070]: invalid left-hand side of assignment +error[E0658]: destructuring assignments are unstable --> $DIR/note-unsupported.rs:6:12 | LL | (a, b) = (3, 4); @@ -6,8 +6,19 @@ LL | (a, b) = (3, 4); | | | cannot assign to this expression | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error[E0658]: destructuring assignments are unstable + --> $DIR/note-unsupported.rs:25:17 + | +LL | ((a, b), c) = ((3, 4), 5); + | ----------- ^ + | | + | cannot assign to this expression + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable error[E0368]: binary assignment operation `+=` cannot be applied to type `({integer}, {integer})` --> $DIR/note-unsupported.rs:7:5 @@ -24,9 +35,6 @@ LL | (a, b) += (3, 4); | ------ ^^ | | | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 error[E0070]: invalid left-hand side of assignment --> $DIR/note-unsupported.rs:10:12 @@ -35,9 +43,6 @@ LL | [a, b] = [3, 4]; | ------ ^ | | | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 error[E0368]: binary assignment operation `+=` cannot be applied to type `[{integer}; 2]` --> $DIR/note-unsupported.rs:11:5 @@ -54,9 +59,6 @@ LL | [a, b] += [3, 4]; | ------ ^^ | | | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 error[E0070]: invalid left-hand side of assignment --> $DIR/note-unsupported.rs:16:22 @@ -65,9 +67,6 @@ LL | S { x: a, y: b } = s; | ---------------- ^ | | | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 error[E0368]: binary assignment operation `+=` cannot be applied to type `S` --> $DIR/note-unsupported.rs:17:5 @@ -86,9 +85,6 @@ LL | S { x: a, y: b } += s; | ---------------- ^^ | | | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 error[E0070]: invalid left-hand side of assignment --> $DIR/note-unsupported.rs:20:21 @@ -97,22 +93,8 @@ LL | S { x: a, ..s } = S { x: 3, y: 4 }; | --------------- ^ | | | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 - -error[E0070]: invalid left-hand side of assignment - --> $DIR/note-unsupported.rs:24:17 - | -LL | ((a, b), c) = ((3, 4), 5); - | ----------- ^ - | | - | cannot assign to this expression - | - = note: destructuring assignments are not currently supported - = note: for more information, see https://github.com/rust-lang/rfcs/issues/372 error: aborting due to 11 previous errors -Some errors have detailed explanations: E0067, E0070, E0368. +Some errors have detailed explanations: E0067, E0070, E0368, E0658. For more information about an error, try `rustc --explain E0067`. diff --git a/src/test/ui/destructuring-assignment/tuple_destructure.rs b/src/test/ui/destructuring-assignment/tuple_destructure.rs new file mode 100644 index 00000000000..16aafc4693f --- /dev/null +++ b/src/test/ui/destructuring-assignment/tuple_destructure.rs @@ -0,0 +1,37 @@ +// run-pass + +#![feature(destructuring_assignment)] + +fn main() { + let (mut a, mut b); + (a, b) = (0, 1); + assert_eq!((a, b), (0, 1)); + (b, a) = (a, b); + assert_eq!((a, b), (1, 0)); + (a, .., b) = (1, 2); + assert_eq!((a, b), (1, 2)); + (.., a) = (1, 2); + assert_eq!((a, b), (2, 2)); + (..) = (3, 4); + assert_eq!((a, b), (2, 2)); + (b, ..) = (5, 6, 7); + assert_eq!(b, 5); + + // Test for a non-Copy type (String): + let (mut c, mut d); + (c, d) = ("c".to_owned(), "d".to_owned()); + assert_eq!(c, "c"); + assert_eq!(d, "d"); + (d, c) = (c, d); + assert_eq!(c, "d"); + assert_eq!(d, "c"); + + // Test nesting/parentheses: + ((a, b)) = (0, 1); + assert_eq!((a, b), (0, 1)); + (((a, b)), (c)) = ((2, 3), d); + assert_eq!((a, b), (2, 3)); + assert_eq!(c, "c"); + ((a, .., b), .., (..)) = ((4, 5), ()); + assert_eq!((a, b), (4, 5)); +} diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs b/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs new file mode 100644 index 00000000000..b76f4968e62 --- /dev/null +++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.rs @@ -0,0 +1,10 @@ +#![feature(destructuring_assignment)] + +const C: i32 = 1; + +fn main() { + let (mut a, mut b); + (a, .., b, ..) = (0, 1); //~ ERROR `..` can only be used once per tuple pattern + (a, a, b) = (1, 2); //~ ERROR mismatched types + (C, ..) = (0,1); //~ ERROR invalid left-hand side of assignment +} diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr new file mode 100644 index 00000000000..a60e1cb1eec --- /dev/null +++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr @@ -0,0 +1,31 @@ +error: `..` can only be used once per tuple pattern + --> $DIR/tuple_destructure_fail.rs:7:16 + | +LL | (a, .., b, ..) = (0, 1); + | -- ^^ can only be used once per tuple pattern + | | + | previously used here + +error[E0308]: mismatched types + --> $DIR/tuple_destructure_fail.rs:8:5 + | +LL | (a, a, b) = (1, 2); + | ^^^^^^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 3 elements + | + = note: expected type `({integer}, {integer})` + found tuple `(_, _, _)` + +error[E0070]: invalid left-hand side of assignment + --> $DIR/tuple_destructure_fail.rs:9:13 + | +LL | (C, ..) = (0,1); + | - ^ + | | + | cannot assign to this expression + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0070, E0308. +For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/destructuring-assignment/warn-unused-duplication.rs b/src/test/ui/destructuring-assignment/warn-unused-duplication.rs new file mode 100644 index 00000000000..c1c5c2cd3ce --- /dev/null +++ b/src/test/ui/destructuring-assignment/warn-unused-duplication.rs @@ -0,0 +1,23 @@ +// run-pass + +#![feature(destructuring_assignment)] + +#![warn(unused_assignments)] + +fn main() { + let mut a; + // Assignment occurs left-to-right. + // However, we emit warnings when this happens, so it is clear that this is happening. + (a, a) = (0, 1); //~ WARN value assigned to `a` is never read + assert_eq!(a, 1); + + // We can't always tell when a variable is being assigned to twice, which is why we don't try + // to emit an error, which would be fallible. + let mut x = 1; + (*foo(&mut x), *foo(&mut x)) = (5, 6); + assert_eq!(x, 6); +} + +fn foo<'a>(x: &'a mut u32) -> &'a mut u32 { + x +} diff --git a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr new file mode 100644 index 00000000000..b87ef6f1571 --- /dev/null +++ b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr @@ -0,0 +1,15 @@ +warning: value assigned to `a` is never read + --> $DIR/warn-unused-duplication.rs:11:6 + | +LL | (a, a) = (0, 1); + | ^ + | +note: the lint level is defined here + --> $DIR/warn-unused-duplication.rs:5:9 + | +LL | #![warn(unused_assignments)] + | ^^^^^^^^^^^^^^^^^^ + = help: maybe it is overwritten before being read? + +warning: 1 warning emitted + diff --git a/src/test/ui/feature-gates/feature-gate-cfg-panic.rs b/src/test/ui/feature-gates/feature-gate-cfg-panic.rs new file mode 100644 index 00000000000..1508374d942 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-cfg-panic.rs @@ -0,0 +1,11 @@ +#[cfg(panic = "unwind")] +//~^ ERROR `cfg(panic)` is experimental and subject to change +fn foo() -> bool { true } +#[cfg(not(panic = "unwind"))] +//~^ ERROR `cfg(panic)` is experimental and subject to change +fn foo() -> bool { false } + + +fn main() { + assert!(foo()); +} diff --git a/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr b/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr new file mode 100644 index 00000000000..ea5cd54fa90 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr @@ -0,0 +1,21 @@ +error[E0658]: `cfg(panic)` is experimental and subject to change + --> $DIR/feature-gate-cfg-panic.rs:1:7 + | +LL | #[cfg(panic = "unwind")] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #77443 <https://github.com/rust-lang/rust/issues/77443> for more information + = help: add `#![feature(cfg_panic)]` to the crate attributes to enable + +error[E0658]: `cfg(panic)` is experimental and subject to change + --> $DIR/feature-gate-cfg-panic.rs:4:11 + | +LL | #[cfg(not(panic = "unwind"))] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #77443 <https://github.com/rust-lang/rust/issues/77443> for more information + = help: add `#![feature(cfg_panic)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs b/src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs new file mode 100644 index 00000000000..e7801f0e8ec --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-destructuring_assignment.rs @@ -0,0 +1,4 @@ +fn main() { + let (a, b) = (0, 1); + (a, b) = (2, 3); //~ ERROR destructuring assignments are unstable +} diff --git a/src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr b/src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr new file mode 100644 index 00000000000..62e71decb32 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-destructuring_assignment.stderr @@ -0,0 +1,14 @@ +error[E0658]: destructuring assignments are unstable + --> $DIR/feature-gate-destructuring_assignment.rs:3:12 + | +LL | (a, b) = (2, 3); + | ------ ^ + | | + | cannot assign to this expression + | + = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information + = help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs index 7490632110c..9348bb46dfe 100644 --- a/src/test/ui/fmt/format-args-capture.rs +++ b/src/test/ui/fmt/format-args-capture.rs @@ -1,13 +1,16 @@ // run-pass -// ignore-wasm32 -// ignore-wasm64 #![feature(format_args_capture)] +#![feature(cfg_panic)] fn main() { named_argument_takes_precedence_to_captured(); - panic_with_single_argument_does_not_get_formatted(); - panic_with_multiple_arguments_is_formatted(); formatting_parameters_can_be_captured(); + + #[cfg(panic = "unwind")] + { + panic_with_single_argument_does_not_get_formatted(); + panic_with_multiple_arguments_is_formatted(); + } } fn named_argument_takes_precedence_to_captured() { @@ -22,6 +25,7 @@ fn named_argument_takes_precedence_to_captured() { assert_eq!(&s, "positional-named-captured"); } +#[cfg(panic = "unwind")] fn panic_with_single_argument_does_not_get_formatted() { // panic! with a single argument does not perform string formatting. // RFC #2795 suggests that this may need to change so that captured arguments are formatted. @@ -34,6 +38,7 @@ fn panic_with_single_argument_does_not_get_formatted() { assert_eq!(msg.downcast_ref::<&str>(), Some(&"{foo}")) } +#[cfg(panic = "unwind")] fn panic_with_multiple_arguments_is_formatted() { let foo = "captured"; diff --git a/src/test/ui/imports/issue-62767.rs b/src/test/ui/imports/issue-62767.rs index 0e0f915ea53..01184eea9b4 100644 --- a/src/test/ui/imports/issue-62767.rs +++ b/src/test/ui/imports/issue-62767.rs @@ -1,3 +1,5 @@ +// check-pass + // Minimized case from #62767. mod m { pub enum Same { @@ -9,7 +11,7 @@ use m::*; // The variant `Same` introduced by this import is also considered when resolving the prefix // `Same::` during import validation to avoid effects similar to time travel (#74556). -use Same::Same; //~ ERROR unresolved import `Same` +use Same::Same; // Case from #74556. mod foo { @@ -21,8 +23,8 @@ mod foo { } use foo::*; -use bar::bar; //~ ERROR unresolved import `bar::bar` - //~| ERROR inconsistent resolution for an import +use bar::bar; + use bar::foobar; fn main() {} diff --git a/src/test/ui/imports/issue-62767.stderr b/src/test/ui/imports/issue-62767.stderr deleted file mode 100644 index a4334bda6dd..00000000000 --- a/src/test/ui/imports/issue-62767.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: inconsistent resolution for an import - --> $DIR/issue-62767.rs:24:5 - | -LL | use bar::bar; - | ^^^^^^^^ - -error[E0432]: unresolved import `Same` - --> $DIR/issue-62767.rs:12:5 - | -LL | use Same::Same; - | ^^^^ `Same` is a variant, not a module - -error[E0432]: unresolved import `bar::bar` - --> $DIR/issue-62767.rs:24:5 - | -LL | use bar::bar; - | ^^^^^^^^ no `bar` in `foo::bar::bar` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/issues/issue-68696-catch-during-unwind.rs b/src/test/ui/issues/issue-68696-catch-during-unwind.rs index d042bed225d..f25a78f59cd 100644 --- a/src/test/ui/issues/issue-68696-catch-during-unwind.rs +++ b/src/test/ui/issues/issue-68696-catch-during-unwind.rs @@ -4,8 +4,7 @@ // entering the catch_unwind. // // run-pass -// ignore-wasm no panic support -// ignore-emscripten no panic support +#![feature(cfg_panic)] use std::panic::catch_unwind; @@ -19,6 +18,7 @@ impl Drop for Guard { } fn main() { + #[cfg(panic = "unwind")] let _ = catch_unwind(|| { let _guard = Guard::default(); panic!(); diff --git a/src/test/ui/lint/lint-const-item-mutation.rs b/src/test/ui/lint/lint-const-item-mutation.rs index c49a13f1065..ef55f31593b 100644 --- a/src/test/ui/lint/lint-const-item-mutation.rs +++ b/src/test/ui/lint/lint-const-item-mutation.rs @@ -29,6 +29,7 @@ const RAW_PTR: *mut u8 = 1 as *mut u8; const MUTABLE: Mutable = Mutable { msg: "" }; const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() }; const VEC: Vec<i32> = Vec::new(); +const PTR: *mut () = 1 as *mut _; fn main() { ARRAY[0] = 5; //~ WARN attempting to modify @@ -50,4 +51,8 @@ fn main() { MUTABLE.msg = "wow"; // no warning, because Drop observes the mutation MUTABLE2.msg = "wow"; //~ WARN attempting to modify VEC.push(0); //~ WARN taking a mutable reference to a `const` item + + // Test that we don't warn when converting a raw pointer + // into a mutable reference + unsafe { &mut *PTR }; } diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr index 11b5124b2d2..ae95abc72f3 100644 --- a/src/test/ui/lint/lint-const-item-mutation.stderr +++ b/src/test/ui/lint/lint-const-item-mutation.stderr @@ -1,11 +1,11 @@ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:34:5 + --> $DIR/lint-const-item-mutation.rs:35:5 | LL | ARRAY[0] = 5; | ^^^^^^^^^^^^ | = note: `#[warn(const_item_mutation)]` on by default - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:26:1 | @@ -13,12 +13,12 @@ LL | const ARRAY: [u8; 1] = [25]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:35:5 + --> $DIR/lint-const-item-mutation.rs:36:5 | LL | MY_STRUCT.field = false; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:27:1 | @@ -26,12 +26,12 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:36:5 + --> $DIR/lint-const-item-mutation.rs:37:5 | LL | MY_STRUCT.inner_array[0] = 'b'; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:27:1 | @@ -39,7 +39,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:37:5 + --> $DIR/lint-const-item-mutation.rs:38:5 | LL | MY_STRUCT.use_mut(); | ^^^^^^^^^^^^^^^^^^^ @@ -58,7 +58,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:38:5 + --> $DIR/lint-const-item-mutation.rs:39:5 | LL | &mut MY_STRUCT; | ^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:39:5 + --> $DIR/lint-const-item-mutation.rs:40:5 | LL | (&mut MY_STRUCT).use_mut(); | ^^^^^^^^^^^^^^^^ @@ -86,12 +86,12 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:51:5 + --> $DIR/lint-const-item-mutation.rs:52:5 | LL | MUTABLE2.msg = "wow"; | ^^^^^^^^^^^^^^^^^^^^ | - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:30:1 | @@ -99,7 +99,7 @@ LL | const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:52:5 + --> $DIR/lint-const-item-mutation.rs:53:5 | LL | VEC.push(0); | ^^^^^^^^^^^ diff --git a/src/test/ui/nll/issue-58053.stderr b/src/test/ui/nll/issue-58053.stderr index 297681ff403..e41ee8a8970 100644 --- a/src/test/ui/nll/issue-58053.stderr +++ b/src/test/ui/nll/issue-58053.stderr @@ -2,9 +2,9 @@ error: lifetime may not live long enough --> $DIR/issue-58053.rs:6:33 | LL | let f = |x: &i32| -> &i32 { x }; - | - ---- ^ returning this value requires that `'1` must outlive `'2` + | - - ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 i32 + | | let's call the lifetime of this reference `'2` | let's call the lifetime of this reference `'1` error: lifetime may not live long enough diff --git a/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs index 97a405b6999..30f3781bf77 100644 --- a/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs +++ b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs @@ -1,4 +1,4 @@ -// Regression test; used to ICE with 'visit_mac disabled by default' due to a +// Regression test; used to ICE with 'visit_mac_call disabled by default' due to a // `MutVisitor` in `fn make_all_value_bindings_mutable` (`parse/parser/pat.rs`). macro_rules! mac1 { diff --git a/src/test/ui/print_type_sizes/anonymous.rs b/src/test/ui/print_type_sizes/anonymous.rs index b96348640fa..2b008ca3b3a 100644 --- a/src/test/ui/print_type_sizes/anonymous.rs +++ b/src/test/ui/print_type_sizes/anonymous.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // All of the types that occur in this function are uninteresting, in // that one cannot control the sizes of these types with the same sort diff --git a/src/test/ui/print_type_sizes/generics.rs b/src/test/ui/print_type_sizes/generics.rs index f165526dffa..3ef7b60db2c 100644 --- a/src/test/ui/print_type_sizes/generics.rs +++ b/src/test/ui/print_type_sizes/generics.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/multiple_types.rs b/src/test/ui/print_type_sizes/multiple_types.rs index 4cb7ae03b54..f1ad27ec131 100644 --- a/src/test/ui/print_type_sizes/multiple_types.rs +++ b/src/test/ui/print_type_sizes/multiple_types.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This file illustrates that when multiple structural types occur in // a function, every one of them is included in the output. diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index d9845fd6d70..37ac45f7e05 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/no_duplicates.rs b/src/test/ui/print_type_sizes/no_duplicates.rs index 4495a7770a7..e45e4794a35 100644 --- a/src/test/ui/print_type_sizes/no_duplicates.rs +++ b/src/test/ui/print_type_sizes/no_duplicates.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/packed.rs b/src/test/ui/print_type_sizes/packed.rs index dce4a61ef33..269cc3cc282 100644 --- a/src/test/ui/print_type_sizes/packed.rs +++ b/src/test/ui/print_type_sizes/packed.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/padding.rs b/src/test/ui/print_type_sizes/padding.rs index 1f894c5e252..d1acad16d7e 100644 --- a/src/test/ui/print_type_sizes/padding.rs +++ b/src/test/ui/print_type_sizes/padding.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This file illustrates how padding is handled: alignment // requirements can lead to the introduction of padding, either before diff --git a/src/test/ui/print_type_sizes/repr-align.rs b/src/test/ui/print_type_sizes/repr-align.rs index 1e6f7ccca40..07544935b2f 100644 --- a/src/test/ui/print_type_sizes/repr-align.rs +++ b/src/test/ui/print_type_sizes/repr-align.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/repr_int_c.rs b/src/test/ui/print_type_sizes/repr_int_c.rs index 7aad2715bc0..b8067c112ee 100644 --- a/src/test/ui/print_type_sizes/repr_int_c.rs +++ b/src/test/ui/print_type_sizes/repr_int_c.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)` // variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug). diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index ae4e492456a..c234547bd14 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/variants.rs b/src/test/ui/print_type_sizes/variants.rs index 77e2b4befba..6c8553cc23d 100644 --- a/src/test/ui/print_type_sizes/variants.rs +++ b/src/test/ui/print_type_sizes/variants.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This file illustrates two things: // diff --git a/src/test/ui/print_type_sizes/zero-sized-fields.rs b/src/test/ui/print_type_sizes/zero-sized-fields.rs index 71d09167747..e02a33109e5 100644 --- a/src/test/ui/print_type_sizes/zero-sized-fields.rs +++ b/src/test/ui/print_type_sizes/zero-sized-fields.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // At one point, zero-sized fields such as those in this file were causing diff --git a/src/test/ui/proc-macro/nonterminal-token-hygiene.rs b/src/test/ui/proc-macro/nonterminal-token-hygiene.rs new file mode 100644 index 00000000000..98fd4306004 --- /dev/null +++ b/src/test/ui/proc-macro/nonterminal-token-hygiene.rs @@ -0,0 +1,33 @@ +// Make sure that marks from declarative macros are applied to tokens in nonterminal. + +// check-pass +// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene +// compile-flags: -Z trim-diagnostic-paths=no +// normalize-stdout-test "\d+#" -> "0#" +// aux-build:test-macros.rs + +#![feature(decl_macro)] + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +macro_rules! outer { + ($item:item) => { + macro inner() { + print_bang! { $item } + } + + inner!(); + }; +} + +struct S; + +outer! { + struct S; // OK, not a duplicate definition of `S` +} + +fn main() {} diff --git a/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout b/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout new file mode 100644 index 00000000000..1623d677726 --- /dev/null +++ b/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -0,0 +1,88 @@ +PRINT-BANG INPUT (DISPLAY): struct S; +PRINT-BANG RE-COLLECTED (DISPLAY): struct S ; +PRINT-BANG INPUT (DEBUG): TokenStream [ + Group { + delimiter: None, + stream: TokenStream [ + Ident { + ident: "struct", + span: $DIR/nonterminal-token-hygiene.rs:30:5: 30:11 (#5), + }, + Ident { + ident: "S", + span: $DIR/nonterminal-token-hygiene.rs:30:12: 30:13 (#5), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/nonterminal-token-hygiene.rs:30:13: 30:14 (#5), + }, + ], + span: $DIR/nonterminal-token-hygiene.rs:20:27: 20:32 (#6), + }, +] +#![feature /* 0#0 */(prelude_import)] +#![no_std /* 0#0 */] +// Make sure that marks from declarative macros are applied to tokens in nonterminal. + +// check-pass +// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene +// compile-flags: -Z trim-diagnostic-paths=no +// normalize-stdout-test "\d+#" -> "0#" +// aux-build:test-macros.rs + +#![feature /* 0#0 */(decl_macro)] + +#![no_std /* 0#0 */] +#[prelude_import /* 0#1 */] +use ::core /* 0#1 */::prelude /* 0#1 */::v1 /* 0#1 */::*; +#[macro_use /* 0#1 */] +extern crate core /* 0#2 */; +#[macro_use /* 0#1 */] +extern crate compiler_builtins /* 0#2 */; +// Don't load unnecessary hygiene information from std +extern crate std /* 0#0 */; + +#[macro_use /* 0#0 */] +extern crate test_macros /* 0#0 */; + +macro_rules! outer + /* + 0#0 + */ { + ($ item : item) => + { + macro inner() { print_bang ! { $ item } } inner ! () ; + + } ; +} + +struct S /* 0#0 */; +macro inner /* 0#4 */ { () => { print_bang ! { struct S; } } } + +struct S /* 0#5 */; +// OK, not a duplicate definition of `S` + +fn main /* 0#0 */() { } + +/* +Expansions: +0: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Root +1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports) +2: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "outer") +3: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports) +4: parent: ExpnId(2), call_site_ctxt: #4, def_site_ctxt: #4, kind: Macro(Bang, "inner") +5: parent: ExpnId(4), call_site_ctxt: #6, def_site_ctxt: #0, kind: Macro(Bang, "print_bang") + +SyntaxContexts: +#0: parent: #0, outer_mark: (ExpnId(0), Opaque) +#1: parent: #0, outer_mark: (ExpnId(1), Opaque) +#2: parent: #0, outer_mark: (ExpnId(1), Transparent) +#3: parent: #0, outer_mark: (ExpnId(3), Opaque) +#4: parent: #0, outer_mark: (ExpnId(2), SemiTransparent) +#5: parent: #0, outer_mark: (ExpnId(4), Opaque) +#6: parent: #4, outer_mark: (ExpnId(4), Opaque) +#7: parent: #0, outer_mark: (ExpnId(5), Opaque) +#8: parent: #6, outer_mark: (ExpnId(5), Transparent) +#9: parent: #5, outer_mark: (ExpnId(5), SemiTransparent) +*/ diff --git a/src/test/ui/test-attrs/test-allow-fail-attr.rs b/src/test/ui/test-attrs/test-allow-fail-attr.rs index 1a478460efc..29ce9f7c2e9 100644 --- a/src/test/ui/test-attrs/test-allow-fail-attr.rs +++ b/src/test/ui/test-attrs/test-allow-fail-attr.rs @@ -1,11 +1,12 @@ // run-pass -// ignore-wasm32-bare compiled with panic=abort by default // compile-flags: --test #![feature(allow_fail)] +#![feature(cfg_panic)] #[test] #[allow_fail] fn test1() { + #[cfg(not(panic = "abort"))] panic!(); } diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs deleted file mode 100644 index e643a8cab5b..00000000000 --- a/src/test/ui/type-alias-impl-trait/issue-72793.rs +++ /dev/null @@ -1,27 +0,0 @@ -// build-pass - -// Regression test for #72793. -// FIXME: This still shows ICE with `-Zmir-opt-level=2`. - -#![feature(type_alias_impl_trait)] - -trait T { type Item; } - -type Alias<'a> = impl T<Item = &'a ()>; - -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} - -fn filter_positive<'a>() -> Alias<'a> { - &S -} - -fn with_positive(fun: impl Fn(Alias<'_>)) { - fun(filter_positive()); -} - -fn main() { - with_positive(|_| ()); -} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 9a8f2404e4a..687354dc6ae 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -155,6 +155,7 @@ static TARGETS: &[&str] = &[ ]; static DOCS_TARGETS: &[&str] = &[ + "aarch64-unknown-linux-gnu", "i686-apple-darwin", "i686-pc-windows-gnu", "i686-pc-windows-msvc", diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs index 485888fa944..6b175490cc8 100644 --- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs +++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs @@ -1,6 +1,6 @@ use crate::utils::{span_lint, span_lint_and_then}; use rustc_ast::ast::{ - Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, MacCall, Pat, PatKind, + Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, Pat, PatKind, }; use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor}; use rustc_lint::{EarlyContext, EarlyLintPass}; @@ -150,9 +150,6 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> { _ => walk_pat(self, pat), } } - fn visit_mac(&mut self, _mac: &MacCall) { - // do not check macs - } } #[must_use] @@ -357,9 +354,6 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> { fn visit_item(&mut self, _: &Item) { // do not recurse into inner items } - fn visit_mac(&mut self, _mac: &MacCall) { - // do not check macs - } } impl EarlyLintPass for NonExpressiveNames { diff --git a/src/tools/miri b/src/tools/miri -Subproject 6359b1b0eb724f2432fd4776c3fc5f5cad9e67d +Subproject 30e0c303a019737cb0e22db464c774ac66b14e0 diff --git a/src/tools/rls b/src/tools/rls -Subproject 1f686d5f707269b1086f6afcdced36225c0c5ff +Subproject dab1468d6aeed0e49f7d0569c1d2128b5a7751e diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index 213cb07fddf..337d65e4da4 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -61,6 +61,7 @@ features = [ ] [dependencies] +byteorder = { version = "1", features = ['default', 'std'] } curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } crossbeam-utils = { version = "0.7.2", features = ["nightly"] } proc-macro2 = { version = "1", features = ["default"] } diff --git a/src/tools/rustfmt b/src/tools/rustfmt -Subproject 97d0301011533e1c131c0edd660d77b4bd476c8 +Subproject eb894d53708122a67762de9489881c11aa8ce25 diff --git a/src/tools/x/Cargo.lock b/src/tools/x/Cargo.lock new file mode 100644 index 00000000000..723d6cb25ed --- /dev/null +++ b/src/tools/x/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "x" +version = "0.1.0" diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml new file mode 100644 index 00000000000..72c4948c617 --- /dev/null +++ b/src/tools/x/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "x" +version = "0.1.0" +description = "Run x.py slightly more conveniently" +authors = ["Casey Rodarmor <casey@rodarmor.com>"] +edition = "2018" +publish = false diff --git a/src/tools/x/README.md b/src/tools/x/README.md new file mode 100644 index 00000000000..3b3cf2847c2 --- /dev/null +++ b/src/tools/x/README.md @@ -0,0 +1,3 @@ +# x + +`x` invokes `x.py` from any subdirectory. diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs new file mode 100644 index 00000000000..6c0311433d6 --- /dev/null +++ b/src/tools/x/src/main.rs @@ -0,0 +1,92 @@ +//! Run `x.py` from any subdirectory of a rust compiler checkout. +//! +//! We prefer `exec`, to avoid adding an extra process in the process tree. +//! However, since `exec` isn't available on Windows, we indirect through +//! `exec_or_status`, which will call `exec` on unix and `status` on Windows. +//! +//! We use `python`, `python3`, or `python2` as the python interpreter to run +//! `x.py`, in that order of preference. + +use std::{ + env, io, + process::{self, Command, ExitStatus}, +}; + +const PYTHON: &str = "python"; +const PYTHON2: &str = "python2"; +const PYTHON3: &str = "python3"; + +fn python() -> &'static str { + let val = match env::var_os("PATH") { + Some(val) => val, + None => return PYTHON, + }; + + let mut python2 = false; + let mut python3 = false; + + for dir in env::split_paths(&val) { + if dir.join(PYTHON).exists() { + return PYTHON; + } + + python2 |= dir.join(PYTHON2).exists(); + python3 |= dir.join(PYTHON3).exists(); + } + + if python3 { + PYTHON3 + } else if python2 { + PYTHON2 + } else { + PYTHON + } +} + +#[cfg(unix)] +fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> { + use std::os::unix::process::CommandExt; + Err(command.exec()) +} + +#[cfg(not(unix))] +fn exec_or_status(command: &mut Command) -> io::Result<ExitStatus> { + command.status() +} + +fn main() { + let current = match env::current_dir() { + Ok(dir) => dir, + Err(err) => { + eprintln!("Failed to get current directory: {}", err); + process::exit(1); + } + }; + + for dir in current.ancestors() { + let candidate = dir.join("x.py"); + + if candidate.exists() { + let mut python = Command::new(python()); + + python.arg(&candidate).args(env::args().skip(1)).current_dir(dir); + + let result = exec_or_status(&mut python); + + match result { + Err(error) => { + eprintln!("Failed to invoke `{}`: {}", candidate.display(), error); + } + Ok(status) => { + process::exit(status.code().unwrap_or(1)); + } + } + } + } + + eprintln!( + "x.py not found. Please run inside of a checkout of `https://github.com/rust-lang/rust`." + ); + + process::exit(1); +} |
