Merge branch 'master' into box-alloc

This commit is contained in:
Tim Diekmann 2020-10-16 08:54:38 +02:00 committed by GitHub
commit 955b37b305
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
895 changed files with 16039 additions and 11283 deletions

68
.github/ISSUE_TEMPLATE/regression.md vendored Normal file
View file

@ -0,0 +1,68 @@
---
name: Regression
about: Report something that unexpectedly changed between Rust versions.
labels: C-bug regression-untriaged
---
<!--
Thank you for filing a regression report! 🐛 A regression is something that changed between versions of Rust but was not supposed to.
Please provide a short summary of the regression, along with any information you feel is relevant to replicate it.
-->
### Code
I tried this code:
```rust
<code>
```
I expected to see this happen: *explanation*
Instead, this happened: *explanation*
### Version it worked on
<!--
Provide the most recent version this worked on, for example:
It most recently worked on: Rust 1.47
-->
It most recently worked on: <!-- version -->
### Version with regression
<!--
Provide the version you are using that has the regression.
-->
`rustc --version --verbose`:
```
<version>
```
<!--
Did the compiler crash? If so, please provide a backtrace.
-->
### Backtrace
<!--
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
environment. E.g. `RUST_BACKTRACE=1 cargo build`.
-->
<details><summary>Backtrace</summary>
<p>
```
<backtrace>
```
</p>
</details>
<!--
If you know when this regression occurred, please add a line like below, replacing `{channel}` with one of stable, beta, or nightly.
@rustbot modify labels: +regression-from-stable-to-{channel} -regression-untriaged
-->

View file

@ -89,6 +89,9 @@ jobs:
- 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
@ -300,6 +303,20 @@ jobs:
NO_LLVM_ASSERTIONS: 1
NO_DEBUG_ASSERTIONS: 1
os: macos-latest
- name: dist-aarch64-apple
env:
SCRIPT: "./x.py dist --stage 2"
RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --host=aarch64-apple-darwin --target=aarch64-apple-darwin --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
SELECT_XCODE: /Applications/Xcode_12.2.app
USE_XCODE_CLANG: 1
MACOSX_DEPLOYMENT_TARGET: 11.0
MACOSX_STD_DEPLOYMENT_TARGET: 11.0
NO_LLVM_ASSERTIONS: 1
NO_DEBUG_ASSERTIONS: 1
DIST_REQUIRE_ALL_TOOLS: 1
JEMALLOC_SYS_WITH_LG_PAGE: 14
os: macos-latest
- name: x86_64-msvc-1
env:
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler"
@ -369,7 +386,7 @@ jobs:
os: windows-latest-xl
- name: dist-x86_64-msvc
env:
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc --enable-full-tools --enable-profiler"
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc --enable-full-tools --enable-profiler"
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 1
os: windows-latest-xl
@ -379,6 +396,12 @@ jobs:
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 1
os: windows-latest-xl
- name: dist-aarch64-msvc
env:
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc --enable-full-tools --enable-profiler"
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 0
os: windows-latest-xl
- name: dist-i686-mingw
env:
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --enable-full-tools --enable-profiler"
@ -437,6 +460,9 @@ jobs:
- 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
@ -544,6 +570,9 @@ jobs:
- 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
@ -648,6 +677,9 @@ jobs:
- 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

2
.gitmodules vendored
View file

@ -37,7 +37,7 @@
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/rust-lang/llvm-project.git
branch = rustc/11.0-2020-09-22
branch = rustc/11.0-2020-10-12
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git

View file

@ -132,13 +132,13 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "backtrace"
version = "0.3.50"
version = "0.3.53"
dependencies = [
"addr2line",
"cfg-if",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
"object 0.21.1",
"rustc-demangle",
]
@ -243,6 +243,7 @@ dependencies = [
"anyhow",
"flate2",
"hex 0.4.2",
"num_cpus",
"rayon",
"serde",
"serde_json",
@ -294,7 +295,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
[[package]]
name = "cargo"
version = "0.49.0"
version = "0.50.0"
dependencies = [
"anyhow",
"atty",
@ -305,7 +306,7 @@ dependencies = [
"clap",
"core-foundation",
"crates-io",
"crossbeam-utils 0.7.2",
"crossbeam-utils 0.8.0",
"crypto-hash",
"curl",
"curl-sys",
@ -441,10 +442,16 @@ dependencies = [
]
[[package]]
name = "chalk-derive"
version = "0.31.0"
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca40c97e20f43e4aac2282d342103d45fafad74ad9bfcbaaf0b5d386f9ce1f39"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chalk-derive"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d072b2ba723f0bada7c515d8b3725224bc4f5052d2a92dcbeb0b118ff37084a"
dependencies = [
"proc-macro2",
"quote",
@ -454,9 +461,9 @@ dependencies = [
[[package]]
name = "chalk-engine"
version = "0.31.0"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88e3d545394fbc4f7d8fe203c6a78d2b73f82bb119f21af98de1f924c2518e34"
checksum = "6fb5475f6083d6d6c509e1c335c4f69ad04144ac090faa1afb134a53c3695841"
dependencies = [
"chalk-derive",
"chalk-ir",
@ -467,9 +474,9 @@ dependencies = [
[[package]]
name = "chalk-ir"
version = "0.31.0"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4183955e084fcc387b515f867ed0e17e9e7301f5eee29c0338d5e63315bb41"
checksum = "f60cdb0e18c5455cb6a85e8464aad3622b70476018edfa8845691df66f7e9a05"
dependencies = [
"chalk-derive",
"lazy_static",
@ -477,9 +484,9 @@ dependencies = [
[[package]]
name = "chalk-solve"
version = "0.31.0"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50e8407bba06d9e760011a28060e8f3b3f87b82ea53fb8bfaa43614c19c14dcc"
checksum = "981534d499a8476ecc0b520be4d3864757f96211826a75360fbf2cb6fae362ab"
dependencies = [
"chalk-derive",
"chalk-ir",
@ -548,7 +555,6 @@ dependencies = [
"cargo_metadata 0.11.1",
"if_chain",
"itertools 0.9.0",
"lazy_static",
"pulldown-cmark 0.8.0",
"quine-mc_cluskey",
"quote",
@ -670,6 +676,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "const_fn"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@ -723,17 +735,17 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6"
checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
dependencies = [
"cfg-if",
"crossbeam-utils 0.7.2",
"maybe-uninit",
]
[[package]]
@ -754,7 +766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
"autocfg",
"cfg-if",
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
"lazy_static",
"maybe-uninit",
@ -777,7 +789,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
"maybe-uninit",
]
@ -788,7 +800,7 @@ version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"lazy_static",
]
@ -799,7 +811,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"cfg-if 0.1.10",
"lazy_static",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
dependencies = [
"autocfg",
"cfg-if 1.0.0",
"const_fn",
"lazy_static",
]
@ -929,7 +953,7 @@ version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"dirs-sys",
]
@ -1071,7 +1095,7 @@ version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"redox_syscall",
"winapi 0.3.9",
@ -1089,7 +1113,7 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"crc32fast",
"libc",
"libz-sys",
@ -1220,7 +1244,7 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"wasi",
]
@ -1231,7 +1255,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"wasi",
]
@ -1249,9 +1273,9 @@ dependencies = [
[[package]]
name = "git2"
version = "0.13.8"
version = "0.13.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ac22e49b7d886b6802c66662b12609452248b1bc9e87d6d83ecea3db96f557"
checksum = "ca6f1a0238d7f8f8fd5ee642f4ebac4dbc03e03d1f78fbe7a3ede35dcf7e2224"
dependencies = [
"bitflags",
"libc",
@ -1669,9 +1693,9 @@ dependencies = [
[[package]]
name = "libgit2-sys"
version = "0.12.9+1.0.1"
version = "0.12.14+1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b33bf3d9d4c45b48ae1ea7c334be69994624dc0a69f833d5d9f7605f24b552b"
checksum = "8f25af58e6495f7caf2919d08f212de550cfa3ed2f5e744988938ea292b9f549"
dependencies = [
"cc",
"libc",
@ -1693,9 +1717,9 @@ dependencies = [
[[package]]
name = "libssh2-sys"
version = "0.2.18"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eafa907407504b0e683786d4aba47acf250f114d37357d56608333fd167dd0fc"
checksum = "ca46220853ba1c512fc82826d0834d87b06bcd3c2a42241b7de72f3d2fe17056"
dependencies = [
"cc",
"libc",
@ -1760,7 +1784,7 @@ version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -1990,7 +2014,7 @@ version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
@ -2071,7 +2095,7 @@ version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"winapi 0.3.9",
]
@ -2122,6 +2146,12 @@ dependencies = [
"rustc-std-workspace-core",
]
[[package]]
name = "object"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693"
[[package]]
name = "once_cell"
version = "1.4.1"
@ -2165,7 +2195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
dependencies = [
"bitflags",
"cfg-if",
"cfg-if 0.1.10",
"foreign-types",
"lazy_static",
"libc",
@ -2180,9 +2210,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
[[package]]
name = "openssl-src"
version = "111.10.2+1.1.1g"
version = "111.12.0+1.1.1h"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a287fdb22e32b5b60624d4a5a7a02dbe82777f730ec0dbc42a0554326fef5a70"
checksum = "858a4132194f8570a7ee9eb8629e85b23cbc4565f2d4a162e87556e5956abf61"
dependencies = [
"cc",
]
@ -2222,14 +2252,14 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
name = "panic_abort"
version = "0.0.0"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"compiler_builtins",
"core",
"libc",
@ -2240,7 +2270,7 @@ name = "panic_unwind"
version = "0.0.0"
dependencies = [
"alloc",
"cfg-if",
"cfg-if 0.1.10",
"compiler_builtins",
"core",
"libc",
@ -2303,7 +2333,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"cloudabi 0.0.3",
"libc",
"redox_syscall",
@ -2318,7 +2348,7 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"cloudabi 0.0.3",
"libc",
"redox_syscall",
@ -2332,7 +2362,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"cloudabi 0.1.0",
"instant",
"libc",
@ -3036,7 +3066,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14ffd17a37e00d77926a0713f191c59ff3aeb2b551a024c7cfffce14bab79be8"
dependencies = [
"bitflags",
"cfg-if",
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
"ena",
"indexmap",
@ -3212,7 +3242,7 @@ version = "679.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c267f15c3cfc82a8a441d2bf86bcccf299d1eb625822468e3d8ee6f7c5a1c89"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"md-5",
"rustc-ap-rustc_arena",
"rustc-ap-rustc_data_structures",
@ -3338,7 +3368,6 @@ dependencies = [
name = "rustc_arena"
version = "0.0.0"
dependencies = [
"rustc_data_structures",
"smallvec 1.4.2",
]
@ -3505,7 +3534,7 @@ version = "0.0.0"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if",
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
"ena",
"indexmap",
@ -4056,7 +4085,7 @@ dependencies = [
name = "rustc_span"
version = "0.0.0"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"md-5",
"rustc_arena",
"rustc_data_structures",
@ -4417,7 +4446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"cfg-if 0.1.10",
"cpuid-bool",
"digest 0.9.0",
"opaque-debug 0.3.0",
@ -4503,7 +4532,7 @@ version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"redox_syscall",
"winapi 0.3.9",
@ -4522,7 +4551,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21ccb4c06ec57bc82d0f610f1a2963d7648700e43a6f513e564b9c89f7991786"
dependencies = [
"cc",
"cfg-if",
"cfg-if 0.1.10",
"libc",
"psm",
"winapi 0.3.9",
@ -4534,7 +4563,7 @@ version = "0.0.0"
dependencies = [
"addr2line",
"alloc",
"cfg-if",
"cfg-if 0.1.10",
"compiler_builtins",
"core",
"dlmalloc",
@ -4543,7 +4572,7 @@ dependencies = [
"hermit-abi",
"libc",
"miniz_oxide",
"object",
"object 0.20.0",
"panic_abort",
"panic_unwind",
"profiler_builtins",
@ -4676,7 +4705,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"rand",
"redox_syscall",
@ -4736,7 +4765,7 @@ dependencies = [
name = "test"
version = "0.0.0"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"core",
"getopts",
"libc",
@ -5068,9 +5097,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.5.6"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
dependencies = [
"serde",
]
@ -5081,7 +5110,7 @@ version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"tracing-attributes",
"tracing-core",
]
@ -5099,9 +5128,9 @@ dependencies = [
[[package]]
name = "tracing-core"
version = "0.1.15"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f0e00789804e99b20f12bc7003ca416309d28a6f495d6af58d1e2c2842461b5"
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
dependencies = [
"lazy_static",
]
@ -5129,9 +5158,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
version = "0.2.11"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abd165311cc4d7a555ad11cc77a37756df836182db0d81aac908c8184c584f40"
checksum = "4ef0a5e15477aa303afbfac3a44cba9b6430fdaad52423b1e6c0dbbe28c3eedd"
dependencies = [
"ansi_term 0.12.1",
"chrono",
@ -5144,6 +5173,7 @@ dependencies = [
"sharded-slab",
"smallvec 1.4.2",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
"tracing-serde",
@ -5277,7 +5307,7 @@ name = "unwind"
version = "0.0.0"
dependencies = [
"cc",
"cfg-if",
"cfg-if 0.1.10",
"compiler_builtins",
"core",
"libc",

View file

@ -5,5 +5,4 @@ version = "0.0.0"
edition = "2018"
[dependencies]
rustc_data_structures = { path = "../rustc_data_structures" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }

View file

@ -16,7 +16,6 @@
#![feature(maybe_uninit_slice)]
#![cfg_attr(test, feature(test))]
use rustc_data_structures::cold_path;
use smallvec::SmallVec;
use std::alloc::Layout;
@ -27,6 +26,12 @@ use std::mem::{self, MaybeUninit};
use std::ptr;
use std::slice;
#[inline(never)]
#[cold]
pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
f()
}
/// An arena that can hold objects of only one type.
pub struct TypedArena<T> {
/// A pointer to the next object to be allocated.

View file

@ -27,6 +27,7 @@ use crate::token::{self, CommentKind, DelimToken};
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_macros::HashStable_Generic;
@ -166,13 +167,6 @@ pub enum GenericArgs {
}
impl GenericArgs {
pub fn is_parenthesized(&self) -> bool {
match *self {
Parenthesized(..) => true,
_ => false,
}
}
pub fn is_angle_bracketed(&self) -> bool {
match *self {
AngleBracketed(..) => true,
@ -856,13 +850,6 @@ impl BinOpKind {
}
}
pub fn is_shift(&self) -> bool {
match *self {
BinOpKind::Shl | BinOpKind::Shr => true,
_ => false,
}
}
pub fn is_comparison(&self) -> bool {
use BinOpKind::*;
// Note for developers: please keep this as is;
@ -872,11 +859,6 @@ impl BinOpKind {
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
}
}
/// Returns `true` if the binary operator takes its arguments by value
pub fn is_by_value(&self) -> bool {
!self.is_comparison()
}
}
pub type BinOp = Spanned<BinOpKind>;
@ -895,14 +877,6 @@ pub enum UnOp {
}
impl UnOp {
/// Returns `true` if the unary operator takes its argument by value
pub fn is_by_value(u: UnOp) -> bool {
match u {
UnOp::Neg | UnOp::Not => true,
_ => false,
}
}
pub fn to_string(op: UnOp) -> &'static str {
match op {
UnOp::Deref => "*",
@ -1752,13 +1726,6 @@ impl IntTy {
}
}
pub fn val_to_string(&self, val: i128) -> String {
// Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
// are parsed as `u128`, so we wouldn't want to print an extra negative
// sign.
format!("{}{}", val as u128, self.name_str())
}
pub fn bit_width(&self) -> Option<u64> {
Some(match *self {
IntTy::Isize => return None,
@ -1817,10 +1784,6 @@ impl UintTy {
}
}
pub fn val_to_string(&self, val: u128) -> String {
format!("{}{}", val, self.name_str())
}
pub fn bit_width(&self) -> Option<u64> {
Some(match *self {
UintTy::Usize => return None,
@ -1864,7 +1827,7 @@ pub enum AssocTyConstraintKind {
Bound { bounds: GenericBounds },
}
#[derive(Clone, Encodable, Decodable, Debug)]
#[derive(Encodable, Decodable, Debug)]
pub struct Ty {
pub id: NodeId,
pub kind: TyKind,
@ -1872,6 +1835,27 @@ pub struct Ty {
pub tokens: Option<TokenStream>,
}
impl Clone for Ty {
fn clone(&self) -> Self {
ensure_sufficient_stack(|| Self {
id: self.id,
kind: self.kind.clone(),
span: self.span,
tokens: self.tokens.clone(),
})
}
}
impl Ty {
pub fn peel_refs(&self) -> &Self {
let mut final_ty = self;
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
final_ty = &ty;
}
final_ty
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct BareFnTy {
pub unsafety: Unsafe,

View file

@ -101,11 +101,6 @@ impl NestedMetaItem {
self.meta_item().is_some()
}
/// Returns `true` if the variant is `Literal`.
pub fn is_literal(&self) -> bool {
self.literal().is_some()
}
/// Returns `true` if `self` is a `MetaItem` and the meta item is a word.
pub fn is_word(&self) -> bool {
self.meta_item().map_or(false, |meta_item| meta_item.is_word())
@ -232,10 +227,6 @@ impl MetaItem {
pub fn is_value_str(&self) -> bool {
self.value_str().is_some()
}
pub fn is_meta_item_list(&self) -> bool {
self.meta_item_list().is_some()
}
}
impl AttrItem {

View file

@ -54,16 +54,6 @@ pub enum DelimToken {
NoDelim,
}
impl DelimToken {
pub fn len(self) -> usize {
if self == NoDelim { 0 } else { 1 }
}
pub fn is_empty(self) -> bool {
self == NoDelim
}
}
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum LitKind {
Bool, // AST only, must never appear in a `Token`
@ -810,10 +800,10 @@ impl Nonterminal {
if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind {
let filename = source_map.span_to_filename(orig_span);
if let FileName::Real(RealFileName::Named(path)) = filename {
let matches_prefix = |prefix| {
// Check for a path that ends with 'prefix*/src/lib.rs'
let matches_prefix = |prefix, filename| {
// Check for a path that ends with 'prefix*/src/<filename>'
let mut iter = path.components().rev();
iter.next().and_then(|p| p.as_os_str().to_str()) == Some("lib.rs")
iter.next().and_then(|p| p.as_os_str().to_str()) == Some(filename)
&& iter.next().and_then(|p| p.as_os_str().to_str()) == Some("src")
&& iter
.next()
@ -821,14 +811,25 @@ impl Nonterminal {
.map_or(false, |p| p.starts_with(prefix))
};
if (macro_name == sym::impl_macros && matches_prefix("time-macros-impl"))
|| (macro_name == sym::arrays && matches_prefix("js-sys"))
if (macro_name == sym::impl_macros
&& matches_prefix("time-macros-impl", "lib.rs"))
|| (macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs"))
{
let snippet = source_map.span_to_snippet(orig_span);
if snippet.as_deref() == Ok("$name") {
return Some((*ident, *is_raw));
}
}
if macro_name == sym::tuple_from_req
&& (matches_prefix("actix-web", "extract.rs")
|| matches_prefix("actori-web", "extract.rs"))
{
let snippet = source_map.span_to_snippet(orig_span);
if snippet.as_deref() == Ok("$T") {
return Some((*ident, *is_raw));
}
}
}
}
}

View file

@ -295,12 +295,6 @@ impl TokenStream {
.collect(),
))
}
pub fn map<F: FnMut(TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
TokenStream(Lrc::new(
self.0.iter().map(|(tree, is_joint)| (f(tree.clone()), *is_joint)).collect(),
))
}
}
// 99.5%+ of the time we have 1 or 2 elements in this vector.

View file

@ -231,7 +231,6 @@ impl AssocOp {
}
}
pub const PREC_RESET: i8 = -100;
pub const PREC_CLOSURE: i8 = -40;
pub const PREC_JUMP: i8 = -30;
pub const PREC_RANGE: i8 = -10;

View file

@ -985,7 +985,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
asm::InlineAsmReg::parse(
sess.asm_arch?,
|feature| sess.target_features.contains(&Symbol::intern(feature)),
&sess.target.target,
&sess.target,
s,
)
.map_err(|e| {

View file

@ -796,7 +796,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_expr(&mut self, expr: &'a Expr) {
match &expr.kind {
ExprKind::LlvmInlineAsm(..) if !self.session.target.target.options.allow_asm => {
ExprKind::LlvmInlineAsm(..) if !self.session.target.options.allow_asm => {
struct_span_err!(
self.session,
expr.span,

View file

@ -170,17 +170,11 @@ pub enum Token {
impl Token {
crate fn is_eof(&self) -> bool {
match *self {
Token::Eof => true,
_ => false,
}
matches!(self, Token::Eof)
}
pub fn is_hardbreak_tok(&self) -> bool {
match *self {
Token::Break(BreakToken { offset: 0, blank_space: bs }) if bs == SIZE_INFINITY => true,
_ => false,
}
matches!(self, Token::Break(BreakToken { offset: 0, blank_space: SIZE_INFINITY }))
}
}
@ -491,12 +485,9 @@ impl Printer {
}
fn get_top(&mut self) -> PrintStackElem {
match self.print_stack.last() {
Some(el) => *el,
None => {
PrintStackElem { offset: 0, pbreak: PrintStackBreak::Broken(Breaks::Inconsistent) }
}
}
*self.print_stack.last().unwrap_or({
&PrintStackElem { offset: 0, pbreak: PrintStackBreak::Broken(Breaks::Inconsistent) }
})
}
fn print_begin(&mut self, b: BeginToken, l: isize) {

View file

@ -0,0 +1,104 @@
#[cfg(test)]
mod tests;
pub mod state;
pub use state::{print_crate, AnnNode, Comments, PpAnn, PrintState, State};
use rustc_ast as ast;
use rustc_ast::token::{Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
pub fn nonterminal_to_string_no_extra_parens(nt: &Nonterminal) -> String {
let state = State::without_insert_extra_parens();
state.nonterminal_to_string(nt)
}
pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
State::new().nonterminal_to_string(nt)
}
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
pub fn token_kind_to_string(tok: &TokenKind) -> String {
State::new().token_kind_to_string(tok)
}
/// Print the token precisely, without converting `$crate` into its respective crate name.
pub fn token_to_string(token: &Token) -> String {
State::new().token_to_string(token)
}
pub fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
State::new().token_to_string_ext(token, convert_dollar_crate)
}
pub fn ty_to_string(ty: &ast::Ty) -> String {
State::new().ty_to_string(ty)
}
pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String {
State::new().bounds_to_string(bounds)
}
pub fn pat_to_string(pat: &ast::Pat) -> String {
State::new().pat_to_string(pat)
}
pub fn expr_to_string(e: &ast::Expr) -> String {
State::new().expr_to_string(e)
}
pub fn tt_to_string(tt: &TokenTree) -> String {
State::new().tt_to_string(tt)
}
pub fn tts_to_string(tokens: &TokenStream) -> String {
State::new().tts_to_string(tokens)
}
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
State::new().stmt_to_string(stmt)
}
pub fn item_to_string(i: &ast::Item) -> String {
State::new().item_to_string(i)
}
pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String {
State::new().generic_params_to_string(generic_params)
}
pub fn path_to_string(p: &ast::Path) -> String {
State::new().path_to_string(p)
}
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
State::new().path_segment_to_string(p)
}
pub fn vis_to_string(v: &ast::Visibility) -> String {
State::new().vis_to_string(v)
}
pub fn block_to_string(blk: &ast::Block) -> String {
State::new().block_to_string(blk)
}
pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
State::new().meta_list_item_to_string(li)
}
pub fn attr_item_to_string(ai: &ast::AttrItem) -> String {
State::new().attr_item_to_string(ai)
}
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
State::new().attribute_to_string(attr)
}
pub fn param_to_string(arg: &ast::Param) -> String {
State::new().param_to_string(arg)
}
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
State::new().to_string(f)
}

View file

@ -20,9 +20,6 @@ use rustc_span::{BytePos, FileName, Span};
use std::borrow::Cow;
#[cfg(test)]
mod tests;
pub enum MacHeader<'a> {
Path(&'a ast::Path),
Keyword(&'static str),
@ -91,6 +88,13 @@ pub struct State<'a> {
comments: Option<Comments<'a>>,
ann: &'a (dyn PpAnn + 'a),
is_expanded: bool,
// If `true`, additional parenthesis (separate from `ExprKind::Paren`)
// are inserted to ensure that proper precedence is preserved
// in the pretty-printed output.
//
// This is usually `true`, except when performing the pretty-print/reparse
// check in `nt_to_tokenstream`
insert_extra_parens: bool,
}
crate const INDENT_UNIT: usize = 4;
@ -112,6 +116,7 @@ pub fn print_crate<'a>(
comments: Some(Comments::new(sm, filename, input)),
ann,
is_expanded,
insert_extra_parens: true,
};
if is_expanded && has_injected_crate {
@ -142,13 +147,6 @@ pub fn print_crate<'a>(
s.s.eof()
}
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
let mut printer =
State { s: pp::mk_printer(), comments: None, ann: &NoAnn, is_expanded: false };
f(&mut printer);
printer.s.eof()
}
// This makes printed token streams look slightly nicer,
// and also addresses some specific regressions described in #63896 and #73345.
fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool {
@ -231,173 +229,8 @@ pub fn literal_to_string(lit: token::Lit) -> String {
out
}
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
pub fn token_kind_to_string(tok: &TokenKind) -> String {
token_kind_to_string_ext(tok, None)
}
fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) -> String {
match *tok {
token::Eq => "=".to_string(),
token::Lt => "<".to_string(),
token::Le => "<=".to_string(),
token::EqEq => "==".to_string(),
token::Ne => "!=".to_string(),
token::Ge => ">=".to_string(),
token::Gt => ">".to_string(),
token::Not => "!".to_string(),
token::Tilde => "~".to_string(),
token::OrOr => "||".to_string(),
token::AndAnd => "&&".to_string(),
token::BinOp(op) => binop_to_string(op).to_string(),
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
/* Structural symbols */
token::At => "@".to_string(),
token::Dot => ".".to_string(),
token::DotDot => "..".to_string(),
token::DotDotDot => "...".to_string(),
token::DotDotEq => "..=".to_string(),
token::Comma => ",".to_string(),
token::Semi => ";".to_string(),
token::Colon => ":".to_string(),
token::ModSep => "::".to_string(),
token::RArrow => "->".to_string(),
token::LArrow => "<-".to_string(),
token::FatArrow => "=>".to_string(),
token::OpenDelim(token::Paren) => "(".to_string(),
token::CloseDelim(token::Paren) => ")".to_string(),
token::OpenDelim(token::Bracket) => "[".to_string(),
token::CloseDelim(token::Bracket) => "]".to_string(),
token::OpenDelim(token::Brace) => "{".to_string(),
token::CloseDelim(token::Brace) => "}".to_string(),
token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => "".to_string(),
token::Pound => "#".to_string(),
token::Dollar => "$".to_string(),
token::Question => "?".to_string(),
token::SingleQuote => "'".to_string(),
/* Literals */
token::Literal(lit) => literal_to_string(lit),
/* Name components */
token::Ident(s, is_raw) => IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string(),
token::Lifetime(s) => s.to_string(),
/* Other */
token::DocComment(comment_kind, attr_style, data) => {
doc_comment_to_string(comment_kind, attr_style, data)
}
token::Eof => "<eof>".to_string(),
token::Interpolated(ref nt) => nonterminal_to_string(nt),
}
}
/// Print the token precisely, without converting `$crate` into its respective crate name.
pub fn token_to_string(token: &Token) -> String {
token_to_string_ext(token, false)
}
fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
let convert_dollar_crate = convert_dollar_crate.then_some(token.span);
token_kind_to_string_ext(&token.kind, convert_dollar_crate)
}
pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
match *nt {
token::NtExpr(ref e) => expr_to_string(e),
token::NtMeta(ref e) => attr_item_to_string(e),
token::NtTy(ref e) => ty_to_string(e),
token::NtPath(ref e) => path_to_string(e),
token::NtItem(ref e) => item_to_string(e),
token::NtBlock(ref e) => block_to_string(e),
token::NtStmt(ref e) => stmt_to_string(e),
token::NtPat(ref e) => pat_to_string(e),
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(),
token::NtLifetime(e) => e.to_string(),
token::NtLiteral(ref e) => expr_to_string(e),
token::NtTT(ref tree) => tt_to_string(tree),
token::NtVis(ref e) => vis_to_string(e),
}
}
pub fn ty_to_string(ty: &ast::Ty) -> String {
to_string(|s| s.print_type(ty))
}
pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String {
to_string(|s| s.print_type_bounds("", bounds))
}
pub fn pat_to_string(pat: &ast::Pat) -> String {
to_string(|s| s.print_pat(pat))
}
pub fn expr_to_string(e: &ast::Expr) -> String {
to_string(|s| s.print_expr(e))
}
pub fn tt_to_string(tt: &TokenTree) -> String {
to_string(|s| s.print_tt(tt, false))
}
pub fn tts_to_string(tokens: &TokenStream) -> String {
to_string(|s| s.print_tts(tokens, false))
}
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
to_string(|s| s.print_stmt(stmt))
}
pub fn item_to_string(i: &ast::Item) -> String {
to_string(|s| s.print_item(i))
}
pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String {
to_string(|s| s.print_generic_params(generic_params))
}
pub fn path_to_string(p: &ast::Path) -> String {
to_string(|s| s.print_path(p, false, 0))
}
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
to_string(|s| s.print_path_segment(p, false))
}
pub fn vis_to_string(v: &ast::Visibility) -> String {
to_string(|s| s.print_visibility(v))
}
fn block_to_string(blk: &ast::Block) -> String {
to_string(|s| {
// Containing cbox, will be closed by `print_block` at `}`.
s.cbox(INDENT_UNIT);
// Head-ibox, will be closed by `print_block` after `{`.
s.ibox(0);
s.print_block(blk)
})
}
pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
to_string(|s| s.print_meta_list_item(li))
}
fn attr_item_to_string(ai: &ast::AttrItem) -> String {
to_string(|s| s.print_attr_item(ai, ai.path.span))
}
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
to_string(|s| s.print_attribute(attr))
}
pub fn param_to_string(arg: &ast::Param) -> String {
to_string(|s| s.print_param(arg, false))
}
fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
format!("{}{}", to_string(|s| s.print_visibility(vis)), s)
format!("{}{}", State::new().to_string(|s| s.print_visibility(vis)), s)
}
impl std::ops::Deref for State<'_> {
@ -414,6 +247,7 @@ impl std::ops::DerefMut for State<'_> {
}
pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut {
fn insert_extra_parens(&self) -> bool;
fn comments(&mut self) -> &mut Option<Comments<'a>>;
fn print_ident(&mut self, ident: Ident);
fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool);
@ -679,7 +513,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
match tt {
TokenTree::Token(token) => {
self.word(token_to_string_ext(&token, convert_dollar_crate));
let token_str = self.token_to_string_ext(&token, convert_dollar_crate);
self.word(token_str);
if let token::DocComment(..) = token.kind {
self.hardbreak()
}
@ -745,14 +580,20 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
self.space();
}
}
_ => self.word(token_kind_to_string(&token::OpenDelim(delim))),
_ => {
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
self.word(token_str)
}
}
self.ibox(0);
self.print_tts(tts, convert_dollar_crate);
self.end();
match delim {
DelimToken::Brace => self.bclose(span),
_ => self.word(token_kind_to_string(&token::CloseDelim(delim))),
_ => {
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
self.word(token_str)
}
}
}
@ -818,9 +659,190 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
}
}
}
fn nonterminal_to_string(&self, nt: &Nonterminal) -> String {
match *nt {
token::NtExpr(ref e) => self.expr_to_string(e),
token::NtMeta(ref e) => self.attr_item_to_string(e),
token::NtTy(ref e) => self.ty_to_string(e),
token::NtPath(ref e) => self.path_to_string(e),
token::NtItem(ref e) => self.item_to_string(e),
token::NtBlock(ref e) => self.block_to_string(e),
token::NtStmt(ref e) => self.stmt_to_string(e),
token::NtPat(ref e) => self.pat_to_string(e),
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(),
token::NtLifetime(e) => e.to_string(),
token::NtLiteral(ref e) => self.expr_to_string(e),
token::NtTT(ref tree) => self.tt_to_string(tree),
token::NtVis(ref e) => self.vis_to_string(e),
}
}
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
fn token_kind_to_string(&self, tok: &TokenKind) -> String {
self.token_kind_to_string_ext(tok, None)
}
fn token_kind_to_string_ext(
&self,
tok: &TokenKind,
convert_dollar_crate: Option<Span>,
) -> String {
match *tok {
token::Eq => "=".to_string(),
token::Lt => "<".to_string(),
token::Le => "<=".to_string(),
token::EqEq => "==".to_string(),
token::Ne => "!=".to_string(),
token::Ge => ">=".to_string(),
token::Gt => ">".to_string(),
token::Not => "!".to_string(),
token::Tilde => "~".to_string(),
token::OrOr => "||".to_string(),
token::AndAnd => "&&".to_string(),
token::BinOp(op) => binop_to_string(op).to_string(),
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
/* Structural symbols */
token::At => "@".to_string(),
token::Dot => ".".to_string(),
token::DotDot => "..".to_string(),
token::DotDotDot => "...".to_string(),
token::DotDotEq => "..=".to_string(),
token::Comma => ",".to_string(),
token::Semi => ";".to_string(),
token::Colon => ":".to_string(),
token::ModSep => "::".to_string(),
token::RArrow => "->".to_string(),
token::LArrow => "<-".to_string(),
token::FatArrow => "=>".to_string(),
token::OpenDelim(token::Paren) => "(".to_string(),
token::CloseDelim(token::Paren) => ")".to_string(),
token::OpenDelim(token::Bracket) => "[".to_string(),
token::CloseDelim(token::Bracket) => "]".to_string(),
token::OpenDelim(token::Brace) => "{".to_string(),
token::CloseDelim(token::Brace) => "}".to_string(),
token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => "".to_string(),
token::Pound => "#".to_string(),
token::Dollar => "$".to_string(),
token::Question => "?".to_string(),
token::SingleQuote => "'".to_string(),
/* Literals */
token::Literal(lit) => literal_to_string(lit),
/* Name components */
token::Ident(s, is_raw) => {
IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string()
}
token::Lifetime(s) => s.to_string(),
/* Other */
token::DocComment(comment_kind, attr_style, data) => {
doc_comment_to_string(comment_kind, attr_style, data)
}
token::Eof => "<eof>".to_string(),
token::Interpolated(ref nt) => self.nonterminal_to_string(nt),
}
}
/// Print the token precisely, without converting `$crate` into its respective crate name.
fn token_to_string(&self, token: &Token) -> String {
self.token_to_string_ext(token, false)
}
fn token_to_string_ext(&self, token: &Token, convert_dollar_crate: bool) -> String {
let convert_dollar_crate = convert_dollar_crate.then_some(token.span);
self.token_kind_to_string_ext(&token.kind, convert_dollar_crate)
}
fn ty_to_string(&self, ty: &ast::Ty) -> String {
self.to_string(|s| s.print_type(ty))
}
fn bounds_to_string(&self, bounds: &[ast::GenericBound]) -> String {
self.to_string(|s| s.print_type_bounds("", bounds))
}
fn pat_to_string(&self, pat: &ast::Pat) -> String {
self.to_string(|s| s.print_pat(pat))
}
fn expr_to_string(&self, e: &ast::Expr) -> String {
self.to_string(|s| s.print_expr(e))
}
fn tt_to_string(&self, tt: &TokenTree) -> String {
self.to_string(|s| s.print_tt(tt, false))
}
fn tts_to_string(&self, tokens: &TokenStream) -> String {
self.to_string(|s| s.print_tts(tokens, false))
}
fn stmt_to_string(&self, stmt: &ast::Stmt) -> String {
self.to_string(|s| s.print_stmt(stmt))
}
fn item_to_string(&self, i: &ast::Item) -> String {
self.to_string(|s| s.print_item(i))
}
fn generic_params_to_string(&self, generic_params: &[ast::GenericParam]) -> String {
self.to_string(|s| s.print_generic_params(generic_params))
}
fn path_to_string(&self, p: &ast::Path) -> String {
self.to_string(|s| s.print_path(p, false, 0))
}
fn path_segment_to_string(&self, p: &ast::PathSegment) -> String {
self.to_string(|s| s.print_path_segment(p, false))
}
fn vis_to_string(&self, v: &ast::Visibility) -> String {
self.to_string(|s| s.print_visibility(v))
}
fn block_to_string(&self, blk: &ast::Block) -> String {
self.to_string(|s| {
// Containing cbox, will be closed by `print_block` at `}`.
s.cbox(INDENT_UNIT);
// Head-ibox, will be closed by `print_block` after `{`.
s.ibox(0);
s.print_block(blk)
})
}
fn meta_list_item_to_string(&self, li: &ast::NestedMetaItem) -> String {
self.to_string(|s| s.print_meta_list_item(li))
}
fn attr_item_to_string(&self, ai: &ast::AttrItem) -> String {
self.to_string(|s| s.print_attr_item(ai, ai.path.span))
}
fn attribute_to_string(&self, attr: &ast::Attribute) -> String {
self.to_string(|s| s.print_attribute(attr))
}
fn param_to_string(&self, arg: &ast::Param) -> String {
self.to_string(|s| s.print_param(arg, false))
}
fn to_string(&self, f: impl FnOnce(&mut State<'_>)) -> String {
let mut printer = State::new();
printer.insert_extra_parens = self.insert_extra_parens();
f(&mut printer);
printer.s.eof()
}
}
impl<'a> PrintState<'a> for State<'a> {
fn insert_extra_parens(&self) -> bool {
self.insert_extra_parens
}
fn comments(&mut self) -> &mut Option<Comments<'a>> {
&mut self.comments
}
@ -856,6 +878,20 @@ impl<'a> PrintState<'a> for State<'a> {
}
impl<'a> State<'a> {
pub fn new() -> State<'a> {
State {
s: pp::mk_printer(),
comments: None,
ann: &NoAnn,
is_expanded: false,
insert_extra_parens: true,
}
}
pub(super) fn without_insert_extra_parens() -> State<'a> {
State { insert_extra_parens: false, ..State::new() }
}
// Synthesizes a comment that was not textually present in the original source
// file.
pub fn synth_comment(&mut self, text: String) {
@ -1139,7 +1175,7 @@ impl<'a> State<'a> {
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
ast::ItemKind::Mod(ref _mod) => {
self.head(to_string(|s| {
self.head(self.to_string(|s| {
s.print_visibility(&item.vis);
s.print_unsafety(_mod.unsafety);
s.word("mod");
@ -1158,7 +1194,7 @@ impl<'a> State<'a> {
}
}
ast::ItemKind::ForeignMod(ref nmod) => {
self.head(to_string(|s| {
self.head(self.to_string(|s| {
s.print_unsafety(nmod.unsafety);
s.word("extern");
}));
@ -1366,7 +1402,7 @@ impl<'a> State<'a> {
ast::CrateSugar::JustCrate => self.word_nbsp("crate"),
},
ast::VisibilityKind::Restricted { ref path, .. } => {
let path = to_string(|s| s.print_path(path, false, 0));
let path = self.to_string(|s| s.print_path(path, false, 0));
if path == "self" || path == "super" {
self.word_nbsp(format!("pub({})", path))
} else {
@ -1658,7 +1694,8 @@ impl<'a> State<'a> {
}
/// Prints `expr` or `(expr)` when `needs_par` holds.
fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) {
fn print_expr_cond_paren(&mut self, expr: &ast::Expr, mut needs_par: bool) {
needs_par &= self.insert_extra_parens;
if needs_par {
self.popen();
}

View file

@ -75,6 +75,12 @@ pub enum InlineAttr {
Never,
}
#[derive(Clone, Encodable, Decodable)]
pub enum InstructionSetAttr {
ArmA32,
ArmT32,
}
#[derive(Clone, Encodable, Decodable)]
pub enum OptimizeAttr {
None,
@ -148,7 +154,7 @@ pub struct ConstStability {
}
/// The available stability levels.
#[derive(Encodable, Decodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic)]
pub enum StabilityLevel {
// Reason for the current stability level and the relevant rust-lang issue

View file

@ -81,7 +81,7 @@ fn parse_args<'a>(
} // accept trailing commas
// Parse options
if p.eat(&token::Ident(sym::options, false)) {
if p.eat_keyword(sym::options) {
parse_options(&mut p, &mut args)?;
allow_templates = false;
continue;
@ -101,19 +101,19 @@ fn parse_args<'a>(
};
let mut explicit_reg = false;
let op = if p.eat(&token::Ident(kw::In, false)) {
let op = if p.eat_keyword(kw::In) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
let expr = p.parse_expr()?;
ast::InlineAsmOperand::In { reg, expr }
} else if p.eat(&token::Ident(sym::out, false)) {
} else if p.eat_keyword(sym::out) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
ast::InlineAsmOperand::Out { reg, expr, late: false }
} else if p.eat(&token::Ident(sym::lateout, false)) {
} else if p.eat_keyword(sym::lateout) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
ast::InlineAsmOperand::Out { reg, expr, late: true }
} else if p.eat(&token::Ident(sym::inout, false)) {
} else if p.eat_keyword(sym::inout) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
let expr = p.parse_expr()?;
if p.eat(&token::FatArrow) {
@ -123,7 +123,7 @@ fn parse_args<'a>(
} else {
ast::InlineAsmOperand::InOut { reg, expr, late: false }
}
} else if p.eat(&token::Ident(sym::inlateout, false)) {
} else if p.eat_keyword(sym::inlateout) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
let expr = p.parse_expr()?;
if p.eat(&token::FatArrow) {
@ -133,10 +133,10 @@ fn parse_args<'a>(
} else {
ast::InlineAsmOperand::InOut { reg, expr, late: true }
}
} else if p.eat(&token::Ident(kw::Const, false)) {
} else if p.eat_keyword(kw::Const) {
let expr = p.parse_expr()?;
ast::InlineAsmOperand::Const { expr }
} else if p.eat(&token::Ident(sym::sym, false)) {
} else if p.eat_keyword(sym::sym) {
let expr = p.parse_expr()?;
match expr.kind {
ast::ExprKind::Path(..) => {}
@ -164,7 +164,7 @@ fn parse_args<'a>(
args.templates.push(template);
continue;
} else {
return Err(p.expect_one_of(&[], &[]).unwrap_err());
return p.unexpected();
};
allow_templates = false;
@ -333,21 +333,22 @@ fn parse_options<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> Result<(), Diagn
p.expect(&token::OpenDelim(token::DelimToken::Paren))?;
while !p.eat(&token::CloseDelim(token::DelimToken::Paren)) {
if p.eat(&token::Ident(sym::pure, false)) {
if p.eat_keyword(sym::pure) {
try_set_option(p, args, sym::pure, ast::InlineAsmOptions::PURE);
} else if p.eat(&token::Ident(sym::nomem, false)) {
} else if p.eat_keyword(sym::nomem) {
try_set_option(p, args, sym::nomem, ast::InlineAsmOptions::NOMEM);
} else if p.eat(&token::Ident(sym::readonly, false)) {
} else if p.eat_keyword(sym::readonly) {
try_set_option(p, args, sym::readonly, ast::InlineAsmOptions::READONLY);
} else if p.eat(&token::Ident(sym::preserves_flags, false)) {
} else if p.eat_keyword(sym::preserves_flags) {
try_set_option(p, args, sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS);
} else if p.eat(&token::Ident(sym::noreturn, false)) {
} else if p.eat_keyword(sym::noreturn) {
try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
} else if p.eat(&token::Ident(sym::nostack, false)) {
} else if p.eat_keyword(sym::nostack) {
try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
} else {
p.expect(&token::Ident(sym::att_syntax, false))?;
} else if p.eat_keyword(sym::att_syntax) {
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
} else {
return p.unexpected();
}
// Allow trailing commas

View file

@ -120,8 +120,7 @@ fn parse_assert<'a>(
};
if parser.token != token::Eof {
parser.expect_one_of(&[], &[])?;
unreachable!();
return parser.unexpected();
}
Ok(Assert { cond_expr, custom_message })

View file

@ -1137,12 +1137,9 @@ impl<'a> MethodDef<'a> {
/// for each of the self-args, carried in precomputed variables.
/// ```{.text}
/// let __self0_vi = unsafe {
/// std::intrinsics::discriminant_value(&self) };
/// let __self1_vi = unsafe {
/// std::intrinsics::discriminant_value(&arg1) };
/// let __self2_vi = unsafe {
/// std::intrinsics::discriminant_value(&arg2) };
/// let __self0_vi = std::intrinsics::discriminant_value(&self);
/// let __self1_vi = std::intrinsics::discriminant_value(&arg1);
/// let __self2_vi = std::intrinsics::discriminant_value(&arg2);
///
/// if __self0_vi == __self1_vi && __self0_vi == __self2_vi && ... {
/// match (...) {
@ -1325,7 +1322,7 @@ impl<'a> MethodDef<'a> {
// Since we know that all the arguments will match if we reach
// the match expression we add the unreachable intrinsics as the
// result of the catch all which should help llvm in optimizing it
Some(deriving::call_intrinsic(cx, sp, sym::unreachable, vec![]))
Some(deriving::call_unreachable(cx, sp))
}
_ => None,
};
@ -1356,12 +1353,9 @@ impl<'a> MethodDef<'a> {
// with three Self args, builds three statements:
//
// ```
// let __self0_vi = unsafe {
// std::intrinsics::discriminant_value(&self) };
// let __self1_vi = unsafe {
// std::intrinsics::discriminant_value(&arg1) };
// let __self2_vi = unsafe {
// std::intrinsics::discriminant_value(&arg2) };
// let __self0_vi = std::intrinsics::discriminant_value(&self);
// let __self1_vi = std::intrinsics::discriminant_value(&arg1);
// let __self2_vi = std::intrinsics::discriminant_value(&arg2);
// ```
let mut index_let_stmts: Vec<ast::Stmt> = Vec::with_capacity(vi_idents.len() + 1);
@ -1474,7 +1468,7 @@ impl<'a> MethodDef<'a> {
// derive Debug on such a type could here generate code
// that needs the feature gate enabled.)
deriving::call_intrinsic(cx, sp, sym::unreachable, vec![])
deriving::call_unreachable(cx, sp)
} else {
// Final wrinkle: the self_args are expressions that deref
// down to desired places, but we cannot actually deref

View file

@ -68,7 +68,14 @@ fn call_intrinsic(
) -> P<ast::Expr> {
let span = cx.with_def_site_ctxt(span);
let path = cx.std_path(&[sym::intrinsics, intrinsic]);
let call = cx.expr_call_global(span, path, args);
cx.expr_call_global(span, path, args)
}
/// Constructs an expression that calls the `unreachable` intrinsic.
fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
let span = cx.with_def_site_ctxt(span);
let path = cx.std_path(&[sym::intrinsics, sym::unreachable]);
let call = cx.expr_call_global(span, path, vec![]);
cx.expr_block(P(ast::Block {
stmts: vec![cx.stmt_expr(call)],

View file

@ -385,7 +385,7 @@ pub mod printf {
if let Start = state {
match c {
'1'..='9' => {
let end = at_next_cp_while(next, is_digit);
let end = at_next_cp_while(next, char::is_ascii_digit);
match end.next_cp() {
// Yes, this *is* the parameter.
Some(('$', end2)) => {
@ -427,7 +427,7 @@ pub mod printf {
move_to!(next);
}
'1'..='9' => {
let end = at_next_cp_while(next, is_digit);
let end = at_next_cp_while(next, char::is_ascii_digit);
state = Prec;
width = Some(Num::from_str(at.slice_between(end).unwrap(), None));
move_to!(end);
@ -441,7 +441,7 @@ pub mod printf {
}
if let WidthArg = state {
let end = at_next_cp_while(at, is_digit);
let end = at_next_cp_while(at, char::is_ascii_digit);
match end.next_cp() {
Some(('$', end2)) => {
state = Prec;
@ -473,7 +473,7 @@ pub mod printf {
if let PrecInner = state {
match c {
'*' => {
let end = at_next_cp_while(next, is_digit);
let end = at_next_cp_while(next, char::is_ascii_digit);
match end.next_cp() {
Some(('$', end2)) => {
state = Length;
@ -488,7 +488,7 @@ pub mod printf {
}
}
'0'..='9' => {
let end = at_next_cp_while(next, is_digit);
let end = at_next_cp_while(next, char::is_ascii_digit);
state = Length;
precision = Some(Num::from_str(at.slice_between(end).unwrap(), None));
move_to!(end);
@ -563,12 +563,12 @@ pub mod printf {
fn at_next_cp_while<F>(mut cur: Cur<'_>, mut pred: F) -> Cur<'_>
where
F: FnMut(char) -> bool,
F: FnMut(&char) -> bool,
{
loop {
match cur.next_cp() {
Some((c, next)) => {
if pred(c) {
if pred(&c) {
cur = next;
} else {
return cur;
@ -579,14 +579,7 @@ pub mod printf {
}
}
fn is_digit(c: char) -> bool {
match c {
'0'..='9' => true,
_ => false,
}
}
fn is_flag(c: char) -> bool {
fn is_flag(c: &char) -> bool {
match c {
'0' | '-' | '+' | ' ' | '#' | '\'' => true,
_ => false,
@ -723,17 +716,11 @@ pub mod shell {
}
fn is_ident_head(c: char) -> bool {
match c {
'a'..='z' | 'A'..='Z' | '_' => true,
_ => false,
}
c.is_ascii_alphabetic() || c == '_'
}
fn is_ident_tail(c: char) -> bool {
match c {
'0'..='9' => true,
c => is_ident_head(c),
}
c.is_ascii_alphanumeric() || c == '_'
}
#[cfg(test)]

View file

@ -37,7 +37,7 @@ struct TestCtxt<'a> {
pub fn inject(sess: &Session, resolver: &mut dyn ResolverExpand, krate: &mut ast::Crate) {
let span_diagnostic = sess.diagnostic();
let panic_strategy = sess.panic_strategy();
let platform_panic_strategy = sess.target.target.options.panic_strategy;
let platform_panic_strategy = sess.target.options.panic_strategy;
// Check for #![reexport_test_harness_main = "some_name"] which gives the
// main test function the name `some_name` without hygiene. This needs to be

View file

@ -16,10 +16,10 @@ pub(crate) unsafe fn codegen(
) {
let llcx = &*mods.llcx;
let llmod = mods.llmod();
let usize = match &tcx.sess.target.target.target_pointer_width[..] {
"16" => llvm::LLVMInt16TypeInContext(llcx),
"32" => llvm::LLVMInt32TypeInContext(llcx),
"64" => llvm::LLVMInt64TypeInContext(llcx),
let usize = match tcx.sess.target.pointer_width {
16 => llvm::LLVMInt16TypeInContext(llcx),
32 => llvm::LLVMInt32TypeInContext(llcx),
64 => llvm::LLVMInt64TypeInContext(llcx),
tws => bug!("Unsupported target word size for int: {}", tws),
};
let i8 = llvm::LLVMInt8TypeInContext(llcx);
@ -57,7 +57,7 @@ pub(crate) unsafe fn codegen(
let name = format!("__rust_{}", method.name);
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
if tcx.sess.target.target.options.default_hidden_visibility {
if tcx.sess.target.options.default_hidden_visibility {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
if tcx.sess.must_emit_unwind_tables() {
@ -98,7 +98,7 @@ pub(crate) unsafe fn codegen(
// -> ! DIFlagNoReturn
llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn);
if tcx.sess.target.target.options.default_hidden_visibility {
if tcx.sess.target.options.default_hidden_visibility {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
if tcx.sess.must_emit_unwind_tables() {

View file

@ -60,7 +60,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
// Default per-arch clobbers
// Basically what clang does
let arch_clobbers = match &self.sess().target.target.arch[..] {
let arch_clobbers = match &self.sess().target.arch[..] {
"x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"],
"mips" | "mips64" => vec!["~{$1}"],
_ => Vec::new(),
@ -259,7 +259,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {}
InlineAsmArch::Nvptx64 => {}
InlineAsmArch::Hexagon => {}
InlineAsmArch::Mips => {}
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
}
}
if !options.contains(InlineAsmOptions::NOMEM) {
@ -710,6 +710,7 @@ fn llvm_fixup_input(
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()),
Primitive::F64 => bx.bitcast(value, bx.cx.type_i64()),
_ => value,
},
_ => value,
@ -785,6 +786,7 @@ fn llvm_fixup_output(
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()),
Primitive::F64 => bx.bitcast(value, bx.cx.type_f64()),
_ => value,
},
_ => value,
@ -854,6 +856,7 @@ fn llvm_fixup_output_type(
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
Primitive::F32 => cx.type_i32(),
Primitive::F64 => cx.type_i64(),
_ => layout.llvm_type(cx),
},
_ => layout.llvm_type(cx),

View file

@ -6,7 +6,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_data_structures::const_cstr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::query::Providers;
@ -18,7 +18,7 @@ use crate::attributes;
use crate::llvm::AttributePlace::Function;
use crate::llvm::{self, Attribute};
use crate::llvm_util;
pub use rustc_attr::{InlineAttr, OptimizeAttr};
pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use crate::context::CodegenCx;
use crate::value::Value;
@ -31,7 +31,7 @@ fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) {
Hint => Attribute::InlineHint.apply_llfn(Function, val),
Always => Attribute::AlwaysInline.apply_llfn(Function, val),
Never => {
if cx.tcx().sess.target.target.arch != "amdgpu" {
if cx.tcx().sess.target.arch != "amdgpu" {
Attribute::NoInline.apply_llfn(Function, val);
}
}
@ -91,8 +91,7 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
// The function name varies on platforms.
// See test/CodeGen/mcount.c in clang.
let mcount_name =
CString::new(cx.sess().target.target.options.target_mcount.as_str().as_bytes())
.unwrap();
CString::new(cx.sess().target.options.target_mcount.as_str().as_bytes()).unwrap();
llvm::AddFunctionAttrStringValue(
llfn,
@ -106,7 +105,7 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
// Only use stack probes if the target specification indicates that we
// should be using stack probes
if !cx.sess().target.target.options.stack_probes {
if !cx.sess().target.options.stack_probes {
return;
}
@ -175,7 +174,6 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
.split(',')
.filter(|f| !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)));
sess.target
.target
.options
.features
.split(',')
@ -194,6 +192,18 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
);
}
pub fn apply_tune_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
if let Some(tune) = llvm_util::tune_cpu(cx.tcx.sess) {
let tune_cpu = SmallCStr::new(tune);
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
const_cstr!("tune-cpu"),
tune_cpu.as_c_str(),
);
}
}
/// Sets the `NonLazyBind` LLVM attribute on a given function,
/// assuming the codegen options allow skipping the PLT.
pub fn non_lazy_bind(sess: &Session, llfn: &'ll Value) {
@ -303,6 +313,9 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
// Without this, ThinLTO won't inline Rust functions into Clang generated
// functions (because Clang annotates functions this way too).
apply_target_cpu_attr(cx, llfn);
// tune-cpu is only conveyed through the attribute for our purpose.
// The target doesn't care; the subtarget reads our attribute.
apply_tune_cpu_attr(cx, llfn);
let features = llvm_target_features(cx.tcx.sess)
.map(|s| s.to_string())
@ -310,6 +323,10 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
let feature = &f.as_str();
format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
}))
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
}))
.collect::<Vec<String>>()
.join(",");
@ -326,7 +343,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
// Note that currently the `wasm-import-module` doesn't do anything, but
// eventually LLVM 7 should read this and ferry the appropriate import
// module to the output file.
if cx.tcx.sess.target.target.arch == "wasm32" {
if cx.tcx.sess.target.arch == "wasm32" {
if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) {
llvm::AddFunctionAttrStringValue(
llfn,
@ -348,23 +365,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
}
}
pub fn provide(providers: &mut Providers) {
use rustc_codegen_ssa::target_features::{all_known_features, supported_target_features};
providers.supported_target_features = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
if tcx.sess.opts.actually_rustdoc {
// rustdoc needs to be able to document functions that use all the features, so
// provide them all.
all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
} else {
supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect()
}
};
provide_extern(providers);
}
pub fn provide_extern(providers: &mut Providers) {
pub fn provide_both(providers: &mut Providers) {
providers.wasm_import_module_map = |tcx, cnum| {
// Build up a map from DefId to a `NativeLib` structure, where
// `NativeLib` internally contains information about

View file

@ -206,7 +206,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
}
fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
let kind = &*self.config.sess.target.target.options.archive_format;
let kind = &*self.config.sess.target.options.archive_format;
kind.parse().map_err(|_| kind)
}

View file

@ -2,14 +2,14 @@ use crate::back::write::{
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
};
use crate::llvm::archive_ro::ArchiveRO;
use crate::llvm::{self, False, True};
use crate::llvm::{self, build_string, False, True};
use crate::{LlvmCodegenBackend, ModuleLlvm};
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{FatalError, Handler};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
@ -22,16 +22,14 @@ use tracing::{debug, info};
use std::ffi::{CStr, CString};
use std::fs::File;
use std::io;
use std::mem;
use std::path::Path;
use std::ptr;
use std::slice;
use std::sync::Arc;
/// We keep track of past LTO imports that were used to produce the current set
/// of compiled object files that we might choose to reuse during this
/// compilation session.
pub const THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-imports.bin";
/// We keep track of the computed LTO cache keys from the previous
/// session to determine which CGUs we can reuse.
pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
match crate_type {
@ -485,31 +483,31 @@ fn thin_lto(
)
.ok_or_else(|| write::llvm_err(&diag_handler, "failed to prepare thin LTO context"))?;
let data = ThinData(data);
info!("thin LTO data created");
let (import_map_path, prev_import_map, curr_import_map) =
if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir {
let path = incr_comp_session_dir.join(THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME);
// If previous imports have been deleted, or we get an IO error
// reading the file storing them, then we'll just use `None` as the
// prev_import_map, which will force the code to be recompiled.
let prev = if path.exists() {
ThinLTOImportMaps::load_from_file(&path).ok()
} else {
None
};
let curr = ThinLTOImportMaps::from_thin_lto_data(data);
let (key_map_path, prev_key_map, curr_key_map) = if let Some(ref incr_comp_session_dir) =
cgcx.incr_comp_session_dir
{
let path = incr_comp_session_dir.join(THIN_LTO_KEYS_INCR_COMP_FILE_NAME);
// If the previous file was deleted, or we get an IO error
// reading the file, then we'll just use `None` as the
// prev_key_map, which will force the code to be recompiled.
let prev =
if path.exists() { ThinLTOKeysMap::load_from_file(&path).ok() } else { None };
let curr = ThinLTOKeysMap::from_thin_lto_modules(&data, &thin_modules, &module_names);
(Some(path), prev, curr)
} else {
// If we don't compile incrementally, we don't need to load the
// import data from LLVM.
assert!(green_modules.is_empty());
let curr = ThinLTOImportMaps::default();
let curr = ThinLTOKeysMap::default();
(None, None, curr)
};
info!("thin LTO import map loaded");
let data = ThinData(data);
info!("thin LTO cache key map loaded");
info!("prev_key_map: {:#?}", prev_key_map);
info!("curr_key_map: {:#?}", curr_key_map);
// Throw our data in an `Arc` as we'll be sharing it across threads. We
// also put all memory referenced by the C++ data (buffers, ids, etc)
@ -528,60 +526,14 @@ fn thin_lto(
info!("checking which modules can be-reused and which have to be re-optimized.");
for (module_index, module_name) in shared.module_names.iter().enumerate() {
let module_name = module_name_to_str(module_name);
// If (1.) the module hasn't changed, and (2.) none of the modules
// it imports from have changed, *and* (3.) the import and export
// sets themselves have not changed from the previous compile when
// it was last ThinLTO'ed, then we can re-use the post-ThinLTO
// version of the module. Otherwise, freshly perform LTO
// optimization.
//
// (Note that globally, the export set is just the inverse of the
// import set.)
//
// For further justification of why the above is necessary and sufficient,
// see the LLVM blog post on ThinLTO:
//
// http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html
//
// which states the following:
//
// ```quote
// any particular ThinLTO backend must be redone iff:
//
// 1. The corresponding (primary) modules bitcode changed
// 2. The list of imports into or exports from the module changed
// 3. The bitcode for any module being imported from has changed
// 4. Any global analysis result affecting either the primary module
// or anything it imports has changed.
// ```
//
// This strategy means we can always save the computed imports as
// canon: when we reuse the post-ThinLTO version, condition (3.)
// ensures that the current import set is the same as the previous
// one. (And of course, when we don't reuse the post-ThinLTO
// version, the current import set *is* the correct one, since we
// are doing the ThinLTO in this current compilation cycle.)
//
// For more discussion, see rust-lang/rust#59535 (where the import
// issue was discovered) and rust-lang/rust#69798 (where the
// analogous export issue was discovered).
if let (Some(prev_import_map), true) =
(prev_import_map.as_ref(), green_modules.contains_key(module_name))
if let (Some(prev_key_map), true) =
(prev_key_map.as_ref(), green_modules.contains_key(module_name))
{
assert!(cgcx.incr_comp_session_dir.is_some());
let prev_imports = prev_import_map.imports_of(module_name);
let curr_imports = curr_import_map.imports_of(module_name);
let prev_exports = prev_import_map.exports_of(module_name);
let curr_exports = curr_import_map.exports_of(module_name);
let imports_all_green = curr_imports
.iter()
.all(|imported_module| green_modules.contains_key(imported_module));
if imports_all_green
&& equivalent_as_sets(prev_imports, curr_imports)
&& equivalent_as_sets(prev_exports, curr_exports)
{
// If a module exists in both the current and the previous session,
// and has the same LTO cache key in both sessions, then we can re-use it
if prev_key_map.keys.get(module_name) == curr_key_map.keys.get(module_name) {
let work_product = green_modules[module_name].clone();
copy_jobs.push(work_product);
info!(" - {}: re-used", module_name);
@ -599,10 +551,10 @@ fn thin_lto(
}
// Save the current ThinLTO import information for the next compilation
// session, overwriting the previous serialized imports (if any).
if let Some(path) = import_map_path {
if let Err(err) = curr_import_map.save_to_file(&path) {
let msg = format!("Error while writing ThinLTO import data: {}", err);
// session, overwriting the previous serialized data (if any).
if let Some(path) = key_map_path {
if let Err(err) = curr_key_map.save_to_file(&path) {
let msg = format!("Error while writing ThinLTO key data: {}", err);
return Err(write::llvm_err(&diag_handler, &msg));
}
}
@ -611,24 +563,6 @@ fn thin_lto(
}
}
/// Given two slices, each with no repeat elements. returns true if and only if
/// the two slices have the same contents when considered as sets (i.e. when
/// element order is disregarded).
fn equivalent_as_sets(a: &[String], b: &[String]) -> bool {
// cheap path: unequal lengths means cannot possibly be set equivalent.
if a.len() != b.len() {
return false;
}
// fast path: before building new things, check if inputs are equivalent as is.
if a == b {
return true;
}
// slow path: general set comparison.
let a: FxHashSet<&str> = a.iter().map(|s| s.as_str()).collect();
let b: FxHashSet<&str> = b.iter().map(|s| s.as_str()).collect();
a == b
}
pub(crate) fn run_pass_manager(
cgcx: &CodegenContext<LlvmCodegenBackend>,
module: &ModuleCodegen<ModuleLlvm>,
@ -942,113 +876,56 @@ pub unsafe fn optimize_thin_module(
Ok(module)
}
/// Summarizes module import/export relationships used by LLVM's ThinLTO pass.
///
/// Note that we tend to have two such instances of `ThinLTOImportMaps` in use:
/// one loaded from a file that represents the relationships used during the
/// compilation associated with the incremetnal build artifacts we are
/// attempting to reuse, and another constructed via `from_thin_lto_data`, which
/// captures the relationships of ThinLTO in the current compilation.
/// Maps LLVM module identifiers to their corresponding LLVM LTO cache keys
#[derive(Debug, Default)]
pub struct ThinLTOImportMaps {
// key = llvm name of importing module, value = list of modules it imports from
imports: FxHashMap<String, Vec<String>>,
// key = llvm name of exporting module, value = list of modules it exports to
exports: FxHashMap<String, Vec<String>>,
pub struct ThinLTOKeysMap {
// key = llvm name of importing module, value = LLVM cache key
keys: FxHashMap<String, String>,
}
impl ThinLTOImportMaps {
/// Returns modules imported by `llvm_module_name` during some ThinLTO pass.
fn imports_of(&self, llvm_module_name: &str) -> &[String] {
self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
}
/// Returns modules exported by `llvm_module_name` during some ThinLTO pass.
fn exports_of(&self, llvm_module_name: &str) -> &[String] {
self.exports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
}
impl ThinLTOKeysMap {
fn save_to_file(&self, path: &Path) -> io::Result<()> {
use std::io::Write;
let file = File::create(path)?;
let mut writer = io::BufWriter::new(file);
for (importing_module_name, imported_modules) in &self.imports {
writeln!(writer, "{}", importing_module_name)?;
for imported_module in imported_modules {
writeln!(writer, " {}", imported_module)?;
}
writeln!(writer)?;
for (module, key) in &self.keys {
writeln!(writer, "{} {}", module, key)?;
}
Ok(())
}
fn load_from_file(path: &Path) -> io::Result<ThinLTOImportMaps> {
fn load_from_file(path: &Path) -> io::Result<Self> {
use std::io::BufRead;
let mut imports = FxHashMap::default();
let mut exports: FxHashMap<_, Vec<_>> = FxHashMap::default();
let mut current_module: Option<String> = None;
let mut current_imports: Vec<String> = vec![];
let mut keys = FxHashMap::default();
let file = File::open(path)?;
for line in io::BufReader::new(file).lines() {
let line = line?;
if line.is_empty() {
let importing_module = current_module.take().expect("Importing module not set");
for imported in &current_imports {
exports.entry(imported.clone()).or_default().push(importing_module.clone());
let mut split = line.split(" ");
let module = split.next().unwrap();
let key = split.next().unwrap();
assert_eq!(split.next(), None, "Expected two space-separated values, found {:?}", line);
keys.insert(module.to_string(), key.to_string());
}
imports.insert(importing_module, mem::replace(&mut current_imports, vec![]));
} else if line.starts_with(' ') {
// Space marks an imported module
assert_ne!(current_module, None);
current_imports.push(line.trim().to_string());
} else {
// Otherwise, beginning of a new module (must be start or follow empty line)
assert_eq!(current_module, None);
current_module = Some(line.trim().to_string());
}
}
Ok(ThinLTOImportMaps { imports, exports })
Ok(Self { keys })
}
/// Loads the ThinLTO import map from ThinLTOData.
unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImportMaps {
unsafe extern "C" fn imported_module_callback(
payload: *mut libc::c_void,
importing_module_name: *const libc::c_char,
imported_module_name: *const libc::c_char,
) {
let map = &mut *(payload as *mut ThinLTOImportMaps);
let importing_module_name = CStr::from_ptr(importing_module_name);
let importing_module_name = module_name_to_str(&importing_module_name);
let imported_module_name = CStr::from_ptr(imported_module_name);
let imported_module_name = module_name_to_str(&imported_module_name);
if !map.imports.contains_key(importing_module_name) {
map.imports.insert(importing_module_name.to_owned(), vec![]);
}
map.imports
.get_mut(importing_module_name)
.unwrap()
.push(imported_module_name.to_owned());
if !map.exports.contains_key(imported_module_name) {
map.exports.insert(imported_module_name.to_owned(), vec![]);
}
map.exports
.get_mut(imported_module_name)
.unwrap()
.push(importing_module_name.to_owned());
}
let mut map = ThinLTOImportMaps::default();
llvm::LLVMRustGetThinLTOModuleImports(
data,
imported_module_callback,
&mut map as *mut _ as *mut libc::c_void,
);
map
fn from_thin_lto_modules(
data: &ThinData,
modules: &[llvm::ThinLTOModule],
names: &[CString],
) -> Self {
let keys = modules
.iter()
.zip(names.iter())
.map(|(module, name)| {
let key = build_string(|rust_str| unsafe {
llvm::LLVMRustComputeLTOCacheKey(rust_str, module.identifier, data.0);
})
.expect("Invalid ThinLTO module key");
(name.clone().into_string().unwrap(), key)
})
.collect();
Self { keys }
}
}

View file

@ -128,40 +128,40 @@ pub fn target_machine_factory(
let (opt_level, _) = to_llvm_opt_settings(optlvl);
let use_softfp = sess.opts.cg.soft_float;
let ffunction_sections = sess.target.target.options.function_sections;
let ffunction_sections = sess.target.options.function_sections;
let fdata_sections = ffunction_sections;
let code_model = to_llvm_code_model(sess.code_model());
let features = attributes::llvm_target_features(sess).collect::<Vec<_>>();
let mut singlethread = sess.target.target.options.singlethread;
let mut singlethread = sess.target.options.singlethread;
// On the wasm target once the `atomics` feature is enabled that means that
// we're no longer single-threaded, or otherwise we don't want LLVM to
// lower atomic operations to single-threaded operations.
if singlethread
&& sess.target.target.llvm_target.contains("wasm32")
&& sess.target.llvm_target.contains("wasm32")
&& sess.target_features.contains(&sym::atomics)
{
singlethread = false;
}
let triple = SmallCStr::new(&sess.target.target.llvm_target);
let triple = SmallCStr::new(&sess.target.llvm_target);
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
let features = features.join(",");
let features = CString::new(features).unwrap();
let abi = SmallCStr::new(&sess.target.target.options.llvm_abiname);
let trap_unreachable = sess.target.target.options.trap_unreachable;
let abi = SmallCStr::new(&sess.target.options.llvm_abiname);
let trap_unreachable = sess.target.options.trap_unreachable;
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
let asm_comments = sess.asm_comments();
let relax_elf_relocations = sess.target.target.options.relax_elf_relocations;
let relax_elf_relocations = sess.target.options.relax_elf_relocations;
let use_init_array = !sess
.opts
.debugging_opts
.use_ctors_section
.unwrap_or(sess.target.target.options.use_ctors_section);
.unwrap_or(sess.target.options.use_ctors_section);
Arc::new(move || {
let tm = unsafe {

View file

@ -60,7 +60,7 @@ pub fn write_compressed_metadata<'tcx>(
unsafe { llvm::LLVMAddGlobal(metadata_llmod, common::val_ty(llconst), buf.as_ptr()) };
unsafe {
llvm::LLVMSetInitializer(llglobal, llconst);
let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
let section_name = metadata::metadata_section_name(&tcx.sess.target);
let name = SmallCStr::new(section_name);
llvm::LLVMSetSection(llglobal, name.as_ptr());

View file

@ -308,8 +308,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
use rustc_middle::ty::{Int, Uint};
let new_kind = match ty.kind() {
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.ptr_width)),
Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.ptr_width)),
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),
t @ (Uint(_) | Int(_)) => t.clone(),
_ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
};
@ -541,7 +541,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
fn range_metadata(&mut self, load: &'ll Value, range: Range<u128>) {
if self.sess().target.target.arch == "amdgpu" {
if self.sess().target.arch == "amdgpu" {
// amdgpu/LLVM does something weird and thinks a i64 value is
// split into a v2i32, halving the bitwidth LLVM expects,
// tripping an assertion. So, for now, just disable this
@ -671,7 +671,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
// WebAssembly has saturating floating point to integer casts if the
// `nontrapping-fptoint` target feature is activated. We'll use those if
// they are available.
if self.sess().target.target.arch == "wasm32"
if self.sess().target.arch == "wasm32"
&& self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
{
let src_ty = self.cx.val_ty(val);
@ -696,7 +696,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
// WebAssembly has saturating floating point to integer casts if the
// `nontrapping-fptoint` target feature is activated. We'll use those if
// they are available.
if self.sess().target.target.arch == "wasm32"
if self.sess().target.arch == "wasm32"
&& self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
{
let src_ty = self.cx.val_ty(val);
@ -1427,7 +1427,7 @@ impl Builder<'a, 'll, 'tcx> {
}
fn wasm_and_missing_nontrapping_fptoint(&self) -> bool {
self.sess().target.target.arch == "wasm32"
self.sess().target.arch == "wasm32"
&& !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
}
}

View file

@ -176,7 +176,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
// should use dllimport for functions.
if cx.use_dll_storage_attrs
&& tcx.is_dllimport_foreign_item(instance_def_id)
&& tcx.sess.target.target.target_env != "gnu"
&& tcx.sess.target.target_env != "gnu"
{
unsafe {
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);

View file

@ -92,7 +92,7 @@ fn set_global_alignment(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Alig
// The target may require greater alignment for globals than the type does.
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
// which can force it to be smaller. Rust doesn't support this yet.
if let Some(min) = cx.sess().target.target.options.min_global_align {
if let Some(min) = cx.sess().target.options.min_global_align {
match Align::from_bits(min) {
Ok(min) => align = align.max(min),
Err(err) => {
@ -283,7 +283,7 @@ impl CodegenCx<'ll, 'tcx> {
// argument validation.
debug_assert!(
!(self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
&& self.tcx.sess.target.target.options.is_like_windows
&& self.tcx.sess.target.options.is_like_windows
&& self.tcx.sess.opts.cg.prefer_dynamic)
);
@ -437,7 +437,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
// will use load-unaligned instructions instead, and thus avoiding the crash.
//
// We could remove this hack whenever we decide to drop macOS 10.10 support.
if self.tcx.sess.target.target.options.is_like_osx {
if self.tcx.sess.target.options.is_like_osx {
// The `inspect` method is okay here because we checked relocations, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).

View file

@ -118,18 +118,18 @@ pub unsafe fn create_module(
let mod_name = SmallCStr::new(mod_name);
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
let mut target_data_layout = sess.target.target.data_layout.clone();
let mut target_data_layout = sess.target.data_layout.clone();
if llvm_util::get_major_version() < 9 {
target_data_layout = strip_function_ptr_alignment(target_data_layout);
}
if llvm_util::get_major_version() < 10 {
if sess.target.target.arch == "x86" || sess.target.target.arch == "x86_64" {
if sess.target.arch == "x86" || sess.target.arch == "x86_64" {
target_data_layout = strip_x86_address_spaces(target_data_layout);
}
}
// Ensure the data-layout values hardcoded remain the defaults.
if sess.target.target.options.is_builtin {
if sess.target.options.is_builtin {
let tm = crate::back::write::create_informational_target_machine(tcx.sess);
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
llvm::LLVMRustDisposeTargetMachine(tm);
@ -160,7 +160,7 @@ pub unsafe fn create_module(
bug!(
"data-layout for builtin `{}` target, `{}`, \
differs from LLVM default, `{}`",
sess.target.target.llvm_target,
sess.target.llvm_target,
target_data_layout,
llvm_data_layout
);
@ -170,7 +170,7 @@ pub unsafe fn create_module(
let data_layout = SmallCStr::new(&target_data_layout);
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
let llvm_target = SmallCStr::new(&sess.target.llvm_target);
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
if sess.relocation_model() == RelocModel::Pic {
@ -190,7 +190,7 @@ pub unsafe fn create_module(
}
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
if sess.target.target.options.is_like_msvc {
if sess.target.options.is_like_msvc {
match sess.opts.cg.control_flow_guard {
CFGuard::Disabled => {}
CFGuard::NoChecks => {
@ -265,7 +265,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
// linker will take care of everything. Fixing this problem will likely
// require adding a few attributes to Rust itself (feature gated at the
// start) and then strongly recommending static linkage on Windows!
let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_windows;
let use_dll_storage_attrs = tcx.sess.target.options.is_like_windows;
let check_overflow = tcx.sess.overflow_checks();
@ -417,7 +417,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
fn apply_target_cpu_attr(&self, llfn: &'ll Value) {
attributes::apply_target_cpu_attr(self, llfn)
attributes::apply_target_cpu_attr(self, llfn);
attributes::apply_tune_cpu_attr(self, llfn);
}
fn create_used_variable(&self) {
@ -838,7 +839,7 @@ impl CodegenCx<'b, 'tcx> {
return eh_catch_typeinfo;
}
let tcx = self.tcx;
assert!(self.sess().target.target.options.is_like_emscripten);
assert!(self.sess().target.options.is_like_emscripten);
let eh_catch_typeinfo = match tcx.lang_items().eh_catch_typeinfo() {
Some(def_id) => self.get_static(def_id),
_ => {
@ -877,7 +878,7 @@ impl HasDataLayout for CodegenCx<'ll, 'tcx> {
impl HasTargetSpec for CodegenCx<'ll, 'tcx> {
fn target_spec(&self) -> &Target {
&self.tcx.sess.target.target
&self.tcx.sess.target
}
}

View file

@ -67,5 +67,5 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
!omit_gdb_pretty_printer_section
&& cx.sess().opts.debuginfo != DebugInfo::None
&& cx.sess().target.target.options.emit_debug_gdb_scripts
&& cx.sess().target.options.emit_debug_gdb_scripts
}

View file

@ -874,7 +874,7 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
// When targeting MSVC, emit MSVC style type names for compatibility with
// .natvis visualizers (and perhaps other existing native debuggers?)
let msvc_like_names = cx.tcx.sess.target.target.options.is_like_msvc;
let msvc_like_names = cx.tcx.sess.target.options.is_like_msvc;
let (name, encoding) = match t.kind() {
ty::Never => ("!", DW_ATE_unsigned),
@ -985,7 +985,7 @@ pub fn compile_unit_metadata(
// if multiple object files with the same `DW_AT_name` are linked together.
// As a workaround we generate unique names for each object file. Those do
// not correspond to an actual source file but that should be harmless.
if tcx.sess.target.target.options.is_like_osx {
if tcx.sess.target.options.is_like_osx {
name_in_debuginfo.push("@");
name_in_debuginfo.push(codegen_unit_name);
}
@ -1401,7 +1401,7 @@ fn prepare_union_metadata(
/// on MSVC we have to use the fallback mode, because LLVM doesn't
/// lower variant parts to PDB.
fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
cx.sess().target.target.options.is_like_msvc
cx.sess().target.options.is_like_msvc
}
// FIXME(eddyb) maybe precompute this? Right now it's computed once

View file

@ -120,14 +120,12 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
// for macOS to understand. For more info see #11352
// This can be overridden using --llvm-opts -dwarf-version,N.
// Android has the same issue (#22398)
if cx.sess().target.target.options.is_like_osx
|| cx.sess().target.target.options.is_like_android
{
llvm::LLVMRustAddModuleFlag(cx.llmod, "Dwarf Version\0".as_ptr().cast(), 2)
if let Some(version) = cx.sess().target.options.dwarf_version {
llvm::LLVMRustAddModuleFlag(cx.llmod, "Dwarf Version\0".as_ptr().cast(), version)
}
// Indicate that we want CodeView debug information on MSVC
if cx.sess().target.target.options.is_like_msvc {
if cx.sess().target.options.is_like_msvc {
llvm::LLVMRustAddModuleFlag(cx.llmod, "CodeView\0".as_ptr().cast(), 1)
}
@ -348,7 +346,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
});
// Arguments types
if cx.sess().target.target.options.is_like_msvc {
if cx.sess().target.options.is_like_msvc {
// FIXME(#42800):
// There is a bug in MSDIA that leads to a crash when it encounters
// a fixed-size array of `u8` or something zero-sized in a

View file

@ -38,7 +38,7 @@ impl CodegenCx<'ll, '_> {
// For MSVC, omit the column number.
// Otherwise, emit it. This mimics clang behaviour.
// See discussion in https://github.com/rust-lang/rust/issues/42921
if self.sess().target.target.options.is_like_msvc {
if self.sess().target.options.is_like_msvc {
DebugLoc { file, line, col: None }
} else {
DebugLoc { file, line, col }

View file

@ -42,7 +42,7 @@ fn declare_raw_fn(
// be merged.
llvm::SetUnnamedAddress(llfn, llvm::UnnamedAddr::Global);
if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.target.options.disable_redzone) {
if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.options.disable_redzone) {
llvm::Attribute::NoRedZone.apply_llfn(Function, llfn);
}

View file

@ -367,7 +367,7 @@ fn try_intrinsic(
bx.store(bx.const_i32(0), dest, ret_align);
} else if wants_msvc_seh(bx.sess()) {
codegen_msvc_try(bx, try_func, data, catch_func, dest);
} else if bx.sess().target.target.options.is_like_emscripten {
} else if bx.sess().target.options.is_like_emscripten {
codegen_emcc_try(bx, try_func, data, catch_func, dest);
} else {
codegen_gnu_try(bx, try_func, data, catch_func, dest);
@ -1722,10 +1722,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, bool)> {
match ty.kind() {
ty::Int(t) => {
Some((t.bit_width().unwrap_or(u64::from(cx.tcx.sess.target.ptr_width)), true))
Some((t.bit_width().unwrap_or(u64::from(cx.tcx.sess.target.pointer_width)), true))
}
ty::Uint(t) => {
Some((t.bit_width().unwrap_or(u64::from(cx.tcx.sess.target.ptr_width)), false))
Some((t.bit_width().unwrap_or(u64::from(cx.tcx.sess.target.pointer_width)), false))
}
_ => None,
}

View file

@ -23,18 +23,17 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_ssa::{CodegenResults, CompiledModule};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ErrorReported, FatalError, Handler};
use rustc_middle::dep_graph::{DepGraph, WorkProduct};
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
use rustc_middle::ty::{self, TyCtxt};
use rustc_serialize::json;
use rustc_session::config::{self, OptLevel, OutputFilenames, PrintRequest};
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use std::any::Any;
use std::ffi::CStr;
use std::fs;
use std::sync::Arc;
mod back {
@ -116,6 +115,9 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
llvm_util::target_cpu(sess)
}
fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str> {
llvm_util::tune_cpu(sess)
}
}
impl WriteBackendMethods for LlvmCodegenBackend {
@ -249,11 +251,11 @@ impl CodegenBackend for LlvmCodegenBackend {
}
fn provide(&self, providers: &mut ty::query::Providers) {
attributes::provide(providers);
attributes::provide_both(providers);
}
fn provide_extern(&self, providers: &mut ty::query::Providers) {
attributes::provide_extern(providers);
attributes::provide_both(providers);
}
fn codegen_crate<'tcx>(
@ -274,47 +276,27 @@ impl CodegenBackend for LlvmCodegenBackend {
&self,
ongoing_codegen: Box<dyn Any>,
sess: &Session,
dep_graph: &DepGraph,
) -> Result<Box<dyn Any>, ErrorReported> {
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
let (codegen_results, work_products) = ongoing_codegen
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>()
.expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>")
.join(sess);
if sess.opts.debugging_opts.incremental_info {
rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results);
}
sess.time("serialize_work_products", move || {
rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)
sess.time("llvm_dump_timing_file", || {
if sess.opts.debugging_opts.llvm_time_trace {
llvm_util::time_trace_profiler_finish("llvm_timings.json");
}
});
sess.compile_status()?;
Ok(Box::new(codegen_results))
Ok((codegen_results, work_products))
}
fn link(
&self,
sess: &Session,
codegen_results: Box<dyn Any>,
codegen_results: CodegenResults,
outputs: &OutputFilenames,
) -> Result<(), ErrorReported> {
let codegen_results = codegen_results
.downcast::<CodegenResults>()
.expect("Expected CodegenResults, found Box<Any>");
if sess.opts.debugging_opts.no_link {
// FIXME: use a binary format to encode the `.rlink` file
let rlink_data = json::encode(&codegen_results).map_err(|err| {
sess.fatal(&format!("failed to encode rlink: {}", err));
})?;
let rlink_file = outputs.with_extension(config::RLINK_EXT);
fs::write(&rlink_file, rlink_data).map_err(|err| {
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
})?;
return Ok(());
}
// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
sess.time("link_crate", || {
@ -331,16 +313,6 @@ impl CodegenBackend for LlvmCodegenBackend {
);
});
// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash);
sess.time("llvm_dump_timing_file", || {
if sess.opts.debugging_opts.llvm_time_trace {
llvm_util::time_trace_profiler_finish("llvm_timings.json");
}
});
Ok(())
}
}

View file

@ -2362,4 +2362,10 @@ extern "C" {
bytecode_len: usize,
) -> bool;
pub fn LLVMRustLinkerFree(linker: &'a mut Linker<'a>);
#[allow(improper_ctypes)]
pub fn LLVMRustComputeLTOCacheKey(
key_out: &RustString,
mod_id: *const c_char,
data: &ThinLTOData,
);
}

View file

@ -118,11 +118,6 @@ pub fn SetUnnamedAddress(global: &'a Value, unnamed: UnnamedAddr) {
}
}
pub fn set_thread_local(global: &'a Value, is_thread_local: bool) {
unsafe {
LLVMSetThreadLocal(global, is_thread_local as Bool);
}
}
pub fn set_thread_local_mode(global: &'a Value, mode: ThreadLocalMode) {
unsafe {
LLVMSetThreadLocalMode(global, mode);

View file

@ -46,7 +46,7 @@ fn require_inited() {
}
unsafe fn configure_llvm(sess: &Session) {
let n_args = sess.opts.cg.llvm_args.len() + sess.target.target.options.llvm_args.len();
let n_args = sess.opts.cg.llvm_args.len() + sess.target.options.llvm_args.len();
let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
let mut llvm_args = Vec::with_capacity(n_args + 1);
@ -57,7 +57,7 @@ unsafe fn configure_llvm(sess: &Session) {
}
let cg_opts = sess.opts.cg.llvm_args.iter();
let tg_opts = sess.target.target.options.llvm_args.iter();
let tg_opts = sess.target.options.llvm_args.iter();
let sess_args = cg_opts.chain(tg_opts);
let user_specified_args: FxHashSet<_> =
@ -88,7 +88,7 @@ unsafe fn configure_llvm(sess: &Session) {
.opts
.debugging_opts
.merge_functions
.unwrap_or(sess.target.target.options.merge_functions)
.unwrap_or(sess.target.options.merge_functions)
{
MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
MergeFunctions::Aliases => {
@ -96,9 +96,7 @@ unsafe fn configure_llvm(sess: &Session) {
}
}
if sess.target.target.target_os == "emscripten"
&& sess.panic_strategy() == PanicStrategy::Unwind
{
if sess.target.target_os == "emscripten" && sess.panic_strategy() == PanicStrategy::Unwind {
add("-enable-emscripten-cxx-exceptions", false);
}
@ -122,7 +120,7 @@ unsafe fn configure_llvm(sess: &Session) {
llvm::LLVMInitializePasses();
::rustc_llvm::initialize_available_targets();
rustc_llvm::initialize_available_targets();
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr());
}
@ -140,7 +138,7 @@ pub fn time_trace_profiler_finish(file_name: &str) {
// to LLVM or the feature detection code will walk past the end of the feature
// array, leading to crashes.
pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
let arch = if sess.target.target.arch == "x86_64" { "x86" } else { &*sess.target.target.arch };
let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
match (arch, s) {
("x86", "pclmulqdq") => "pclmul",
("x86", "rdrand") => "rdrnd",
@ -202,11 +200,7 @@ pub(crate) fn print(req: PrintRequest, sess: &Session) {
}
}
pub fn target_cpu(sess: &Session) -> &str {
let name = match sess.opts.cg.target_cpu {
Some(ref s) => &**s,
None => &*sess.target.target.options.cpu,
};
fn handle_native(name: &str) -> &str {
if name != "native" {
return name;
}
@ -217,3 +211,19 @@ pub fn target_cpu(sess: &Session) -> &str {
str::from_utf8(slice::from_raw_parts(ptr as *const u8, len)).unwrap()
}
}
pub fn target_cpu(sess: &Session) -> &str {
let name = match sess.opts.cg.target_cpu {
Some(ref s) => &**s,
None => &*sess.target.options.cpu,
};
handle_native(name)
}
pub fn tune_cpu(sess: &Session) -> Option<&str> {
match sess.opts.debugging_opts.tune_cpu {
Some(ref s) => Some(handle_native(&**s)),
None => None,
}
}

View file

@ -52,7 +52,7 @@ fn emit_direct_ptr_va_arg(
let next = bx.inbounds_gep(addr, &[full_direct_size]);
bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi);
if size.bytes() < slot_size.bytes() && &*bx.tcx().sess.target.target.target_endian == "big" {
if size.bytes() < slot_size.bytes() && &*bx.tcx().sess.target.target_endian == "big" {
let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
let adjusted = bx.inbounds_gep(addr, &[adjusted_size]);
(bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align)
@ -105,7 +105,7 @@ fn emit_aapcs_va_arg(
let mut end = bx.build_sibling_block("va_arg.end");
let zero = bx.const_i32(0);
let offset_align = Align::from_bytes(4).unwrap();
assert!(&*bx.tcx().sess.target.target.target_endian == "little");
assert!(&*bx.tcx().sess.target.target_endian == "little");
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
let (reg_off, reg_top_index, slot_size) = if gr_type {
@ -171,8 +171,8 @@ pub(super) fn emit_va_arg(
) -> &'ll Value {
// Determine the va_arg implementation to use. The LLVM va_arg instruction
// is lacking in some instances, so we should only use it as a fallback.
let target = &bx.cx.tcx.sess.target.target;
let arch = &bx.cx.tcx.sess.target.target.arch;
let target = &bx.cx.tcx.sess.target;
let arch = &bx.cx.tcx.sess.target.arch;
match (&**arch, target.options.is_like_windows) {
// Windows x86
("x86", true) => {

View file

@ -9,9 +9,7 @@ pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session) -> P
// times show up as foo.lib
let oslibname = format!(
"{}{}{}",
sess.target.target.options.staticlib_prefix,
name,
sess.target.target.options.staticlib_suffix
sess.target.options.staticlib_prefix, name, sess.target.options.staticlib_suffix
);
let unixlibname = format!("lib{}.a", name);

View file

@ -15,7 +15,7 @@ use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target};
use super::archive::ArchiveBuilder;
use super::command::Command;
@ -152,7 +152,7 @@ fn get_linker(
_ => match flavor {
LinkerFlavor::Lld(f) => Command::lld(linker, f),
LinkerFlavor::Msvc
if sess.opts.cg.linker.is_none() && sess.target.target.options.linker.is_none() =>
if sess.opts.cg.linker.is_none() && sess.target.options.linker.is_none() =>
{
Command::new(msvc_tool.as_ref().map(|t| t.path()).unwrap_or(linker))
}
@ -163,7 +163,7 @@ fn get_linker(
// UWP apps have API restrictions enforced during Store submissions.
// To comply with the Windows App Certification Kit,
// MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
let t = &sess.target.target;
let t = &sess.target;
if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link))
&& t.target_vendor == "uwp"
{
@ -197,7 +197,7 @@ fn get_linker(
// PATH for the child.
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained);
let mut msvc_changed_path = false;
if sess.target.target.options.is_like_msvc {
if sess.target.options.is_like_msvc {
if let Some(ref tool) = msvc_tool {
cmd.args(tool.args());
for &(ref k, ref v) in tool.env() {
@ -365,7 +365,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
// After adding all files to the archive, we need to update the
// symbol table of the archive. This currently dies on macOS (see
// #11162), and isn't necessary there anyway
if !sess.target.target.options.is_like_osx {
if !sess.target.options.is_like_osx {
ab.update_symbols();
}
}
@ -476,10 +476,10 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
linker::disable_localization(&mut cmd);
for &(ref k, ref v) in &sess.target.target.options.link_env {
for &(ref k, ref v) in &sess.target.options.link_env {
cmd.env(k, v);
}
for k in &sess.target.target.options.link_env_remove {
for k in &sess.target.options.link_env_remove {
cmd.env_remove(k);
}
@ -515,7 +515,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
// if the linker doesn't support -no-pie then it should not default to
// linking executables as pie. Different versions of gcc seem to use
// different quotes in the error message so don't check for them.
if sess.target.target.options.linker_is_gnu
if sess.target.options.linker_is_gnu
&& flavor != LinkerFlavor::Ld
&& (out.contains("unrecognized command line option")
|| out.contains("unknown argument"))
@ -535,7 +535,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
// Detect '-static-pie' used with an older version of gcc or clang not supporting it.
// Fallback from '-static-pie' to '-static' in that case.
if sess.target.target.options.linker_is_gnu
if sess.target.options.linker_is_gnu
&& flavor != LinkerFlavor::Ld
&& (out.contains("unrecognized command line option")
|| out.contains("unknown argument"))
@ -548,7 +548,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
);
// Mirror `add_(pre,post)_link_objects` to replace CRT objects.
let self_contained = crt_objects_fallback(sess, crate_type);
let opts = &sess.target.target.options;
let opts = &sess.target.options;
let pre_objects = if self_contained {
&opts.pre_link_objects_fallback
} else {
@ -670,7 +670,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
// is not a Microsoft LNK error then suggest a way to fix or
// install the Visual Studio build tools.
if let Some(code) = prog.status.code() {
if sess.target.target.options.is_like_msvc
if sess.target.options.is_like_msvc
&& flavor == LinkerFlavor::Msvc
// Respect the command line override
&& sess.opts.cg.linker.is_none()
@ -741,7 +741,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
linker_error.emit();
if sess.target.target.options.is_like_msvc && linker_not_found {
if sess.target.options.is_like_msvc && linker_not_found {
sess.note_without_error(
"the msvc targets depend on the msvc linker \
but `link.exe` was not found",
@ -758,7 +758,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
// On macOS, debuggers need this utility to get run to do some munging of
// the symbols. Note, though, that if the object files are being preserved
// for their debug information there's no need for us to run dsymutil.
if sess.target.target.options.is_like_osx
if sess.target.options.is_like_osx
&& sess.opts.debuginfo != DebugInfo::None
&& !preserve_objects_for_their_debuginfo(sess)
{
@ -776,7 +776,7 @@ fn link_sanitizers(sess: &Session, crate_type: CrateType, linker: &mut dyn Linke
let needs_runtime = match crate_type {
CrateType::Executable => true,
CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => {
sess.target.target.options.is_like_osx
sess.target.options.is_like_osx
}
CrateType::Rlib | CrateType::Staticlib => false,
};
@ -846,7 +846,7 @@ pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool
// If our target enables builtin function lowering in LLVM then the
// crates providing these functions don't participate in LTO (e.g.
// no_builtins or compiler builtins crates).
!sess.target.target.options.no_builtins
!sess.target.options.no_builtins
&& (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
}
@ -906,10 +906,10 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
} else if stem == "link" || stem == "lld-link" {
LinkerFlavor::Msvc
} else if stem == "lld" || stem == "rust-lld" {
LinkerFlavor::Lld(sess.target.target.options.lld_flavor)
LinkerFlavor::Lld(sess.target.options.lld_flavor)
} else {
// fall back to the value in the target spec
sess.target.target.linker_flavor
sess.target.linker_flavor
};
Some((linker, flavor))
@ -926,8 +926,8 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
if let Some(ret) = infer_from(
sess,
sess.target.target.options.linker.clone().map(PathBuf::from),
Some(sess.target.target.linker_flavor),
sess.target.options.linker.clone().map(PathBuf::from),
Some(sess.target.linker_flavor),
) {
return ret;
}
@ -962,7 +962,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
// Basically as a result this just means that if we're on OSX and we're
// *not* running dsymutil then the object files are the only source of truth
// for debug information, so we must preserve them.
if sess.target.target.options.is_like_osx {
if sess.target.options.is_like_osx {
return !sess.opts.debugging_opts.run_dsymutil;
}
@ -988,7 +988,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
NativeLibKind::StaticNoBundle
| NativeLibKind::Dylib
| NativeLibKind::Unspecified => {
if sess.target.target.options.is_like_msvc {
if sess.target.options.is_like_msvc {
Some(format!("{}.lib", name))
} else {
Some(format!("-l{}", name))
@ -1070,16 +1070,13 @@ fn exec_linker(
let mut args = String::new();
for arg in cmd2.take_args() {
args.push_str(
&Escape {
arg: arg.to_str().unwrap(),
is_like_msvc: sess.target.target.options.is_like_msvc,
}
&Escape { arg: arg.to_str().unwrap(), is_like_msvc: sess.target.options.is_like_msvc }
.to_string(),
);
args.push('\n');
}
let file = tmpdir.join("linker-arguments");
let bytes = if sess.target.target.options.is_like_msvc {
let bytes = if sess.target.options.is_like_msvc {
let mut out = Vec::with_capacity((1 + args.len()) * 2);
// start the stream with a UTF-16 BOM
for c in std::iter::once(0xFEFF).chain(args.encode_utf16()) {
@ -1195,7 +1192,7 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
};
// Adjust the output kind to target capabilities.
let opts = &sess.target.target.options;
let opts = &sess.target.options;
let pic_exe_supported = opts.position_independent_executables;
let static_pic_exe_supported = opts.static_position_independent_executables;
let static_dylib_supported = opts.crt_static_allows_dylibs;
@ -1236,14 +1233,14 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
return self_contained;
}
match sess.target.target.options.crt_objects_fallback {
match sess.target.options.crt_objects_fallback {
// FIXME: Find a better heuristic for "native musl toolchain is available",
// based on host and linker path, for example.
// (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
Some(CrtObjectsFallback::Mingw) => {
sess.host == sess.target.target
&& sess.target.target.target_vendor != "uwp"
sess.host == sess.target
&& sess.target.target_vendor != "uwp"
&& detect_self_contained_mingw(&sess)
}
// FIXME: Figure out cases in which WASM needs to link with a native toolchain.
@ -1259,7 +1256,7 @@ fn add_pre_link_objects(
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
let opts = &sess.target.target.options;
let opts = &sess.target.options;
let objects =
if self_contained { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
@ -1274,7 +1271,7 @@ fn add_post_link_objects(
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
let opts = &sess.target.target.options;
let opts = &sess.target.options;
let objects =
if self_contained { &opts.post_link_objects_fallback } else { &opts.post_link_objects };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
@ -1285,7 +1282,7 @@ fn add_post_link_objects(
/// Add arbitrary "pre-link" args defined by the target spec or from command line.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
if let Some(args) = sess.target.options.pre_link_args.get(&flavor) {
cmd.args(args);
}
cmd.args(&sess.opts.debugging_opts.pre_link_args);
@ -1293,13 +1290,13 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor)
/// Add a link script embedded in the target, if applicable.
fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_type: CrateType) {
match (crate_type, &sess.target.target.options.link_script) {
match (crate_type, &sess.target.options.link_script) {
(CrateType::Cdylib | CrateType::Executable, Some(script)) => {
if !sess.target.target.options.linker_is_gnu {
if !sess.target.options.linker_is_gnu {
sess.fatal("can only use link script when linking with GNU-like linker");
}
let file_name = ["rustc", &sess.target.target.llvm_target, "linkfile.ld"].join("-");
let file_name = ["rustc", &sess.target.llvm_target, "linkfile.ld"].join("-");
let path = tmpdir.join(file_name);
if let Err(e) = fs::write(&path, script) {
@ -1338,15 +1335,15 @@ fn add_late_link_args(
*ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
if any_dynamic_crate {
if let Some(args) = sess.target.target.options.late_link_args_dynamic.get(&flavor) {
if let Some(args) = sess.target.options.late_link_args_dynamic.get(&flavor) {
cmd.args(args);
}
} else {
if let Some(args) = sess.target.target.options.late_link_args_static.get(&flavor) {
if let Some(args) = sess.target.options.late_link_args_static.get(&flavor) {
cmd.args(args);
}
}
if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
if let Some(args) = sess.target.options.late_link_args.get(&flavor) {
cmd.args(args);
}
}
@ -1354,7 +1351,7 @@ fn add_late_link_args(
/// Add arbitrary "post-link" args defined by the target spec.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) {
if let Some(args) = sess.target.options.post_link_args.get(&flavor) {
cmd.args(args);
}
}
@ -1456,7 +1453,7 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained:
/// Add options making relocation sections in the produced ELF files read-only
/// and suppressing lazy binding.
fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) {
match sess.opts.debugging_opts.relro_level.unwrap_or(sess.target.target.options.relro_level) {
match sess.opts.debugging_opts.relro_level.unwrap_or(sess.target.options.relro_level) {
RelroLevel::Full => cmd.full_relro(),
RelroLevel::Partial => cmd.partial_relro(),
RelroLevel::Off => cmd.no_relro(),
@ -1487,9 +1484,9 @@ fn add_rpath_args(
let mut rpath_config = RPathConfig {
used_crates: &codegen_results.crate_info.used_crates_dynamic,
out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.target.options.has_rpath,
is_like_osx: sess.target.target.options.is_like_osx,
linker_is_gnu: sess.target.target.options.linker_is_gnu,
has_rpath: sess.target.options.has_rpath,
is_like_osx: sess.target.options.is_like_osx,
linker_is_gnu: sess.target.options.linker_is_gnu,
get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
};
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
@ -1517,7 +1514,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback);
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
// to the linker args construction.
assert!(base_cmd.get_args().is_empty() || sess.target.target.target_vendor == "uwp");
assert!(base_cmd.get_args().is_empty() || sess.target.target_vendor == "uwp");
let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor, target_cpu);
let link_output_kind = link_output_kind(sess, crate_type);
@ -1531,7 +1528,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
add_link_script(cmd, sess, tmpdir, crate_type);
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
if sess.target.target.options.is_like_fuchsia && crate_type == CrateType::Executable {
if sess.target.options.is_like_fuchsia && crate_type == CrateType::Executable {
let prefix = if sess.opts.debugging_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
"asan/"
} else {
@ -1541,7 +1538,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
}
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
if sess.target.target.options.eh_frame_header {
if sess.target.options.eh_frame_header {
cmd.add_eh_frame_header();
}
@ -1554,7 +1551,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
add_pre_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
if sess.target.target.options.is_like_emscripten {
if sess.target.options.is_like_emscripten {
cmd.arg("-s");
cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
"DISABLE_EXCEPTION_CATCHING=1"
@ -1582,7 +1579,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
cmd.output_filename(out_filename);
// OBJECT-FILES-NO, AUDIT-ORDER
if crate_type == CrateType::Executable && sess.target.target.options.is_like_windows {
if crate_type == CrateType::Executable && sess.target.options.is_like_windows {
if let Some(ref s) = codegen_results.windows_subsystem {
cmd.subsystem(s);
}
@ -1626,7 +1623,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
// OBJECT-FILES-NO, AUDIT-ORDER
// We want to prevent the compiler from accidentally leaking in any system libraries,
// so by default we tell linkers not to link to any default libraries.
if !sess.opts.cg.default_linker_libraries && sess.target.target.options.no_default_libraries {
if !sess.opts.cg.default_linker_libraries && sess.target.options.no_default_libraries {
cmd.no_default_libraries();
}
@ -1845,12 +1842,8 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
}
// Converts a library file-stem into a cc -l argument
fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
if stem.starts_with("lib") && !config.target.options.is_like_windows {
&stem[3..]
} else {
stem
}
fn unlib<'a>(target: &Target, stem: &'a str) -> &'a str {
if stem.starts_with("lib") && !target.options.is_like_windows { &stem[3..] } else { stem }
}
// Adds the static "rlib" versions of all crates to the command line.
@ -1945,7 +1938,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
// though, so we let that object file slide.
let skip_because_lto = are_upstream_rust_objects_already_included(sess)
&& is_rust_object
&& (sess.target.target.options.no_builtins
&& (sess.target.options.no_builtins
|| !codegen_results.crate_info.is_no_builtins.contains(&cnum));
if skip_because_cfg_say_so || skip_because_lto {
@ -2088,10 +2081,10 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
}
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let arch = &sess.target.target.arch;
let os = &sess.target.target.target_os;
let llvm_target = &sess.target.target.llvm_target;
if sess.target.target.target_vendor != "apple"
let arch = &sess.target.arch;
let os = &sess.target.target_os;
let llvm_target = &sess.target.llvm_target;
if sess.target.target_vendor != "apple"
|| !matches!(os.as_str(), "ios" | "tvos")
|| flavor != LinkerFlavor::Gcc
{

View file

@ -184,7 +184,7 @@ impl<'a> GccLinker<'a> {
// * On OSX they have their own linker, not binutils'
// * For WebAssembly the only functional linker is LLD, which doesn't
// support hint flags
!self.sess.target.target.options.is_like_osx && self.sess.target.target.arch != "wasm32"
!self.sess.target.options.is_like_osx && self.sess.target.arch != "wasm32"
}
// Some platforms take hints about whether a library is static or dynamic.
@ -221,10 +221,8 @@ impl<'a> GccLinker<'a> {
let opt_level = match self.sess.opts.optimize {
config::OptLevel::No => "O0",
config::OptLevel::Less => "O1",
config::OptLevel::Default => "O2",
config::OptLevel::Default | config::OptLevel::Size | config::OptLevel::SizeMin => "O2",
config::OptLevel::Aggressive => "O3",
config::OptLevel::Size => "Os",
config::OptLevel::SizeMin => "Oz",
};
self.linker_arg(&format!("-plugin-opt={}", opt_level));
@ -234,7 +232,7 @@ impl<'a> GccLinker<'a> {
fn build_dylib(&mut self, out_filename: &Path) {
// On mac we need to tell the linker to let this library be rpathed
if self.sess.target.target.options.is_like_osx {
if self.sess.target.options.is_like_osx {
self.cmd.arg("-dynamiclib");
self.linker_arg("-dylib");
@ -250,7 +248,7 @@ impl<'a> GccLinker<'a> {
}
} else {
self.cmd.arg("-shared");
if self.sess.target.target.options.is_like_windows {
if self.sess.target.options.is_like_windows {
// The output filename already contains `dll_suffix` so
// the resulting import library will have a name in the
// form of libfoo.dll.a
@ -258,9 +256,9 @@ impl<'a> GccLinker<'a> {
out_filename.file_name().and_then(|file| file.to_str()).map(|file| {
format!(
"{}{}{}",
self.sess.target.target.options.staticlib_prefix,
self.sess.target.options.staticlib_prefix,
file,
self.sess.target.target.options.staticlib_suffix
self.sess.target.options.staticlib_suffix
)
});
if let Some(implib_name) = implib_name {
@ -282,7 +280,7 @@ impl<'a> Linker for GccLinker<'a> {
fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
match output_kind {
LinkOutputKind::DynamicNoPicExe => {
if !self.is_ld && self.sess.target.target.options.linker_is_gnu {
if !self.is_ld && self.sess.target.options.linker_is_gnu {
self.cmd.arg("-no-pie");
}
}
@ -293,7 +291,7 @@ impl<'a> Linker for GccLinker<'a> {
LinkOutputKind::StaticNoPicExe => {
// `-static` works for both gcc wrapper and ld.
self.cmd.arg("-static");
if !self.is_ld && self.sess.target.target.options.linker_is_gnu {
if !self.is_ld && self.sess.target.options.linker_is_gnu {
self.cmd.arg("-no-pie");
}
}
@ -322,7 +320,7 @@ impl<'a> Linker for GccLinker<'a> {
// any `#[link]` attributes in the `libc` crate, see #72782 for details.
// FIXME: Switch to using `#[link]` attributes in the `libc` crate
// similarly to other targets.
if self.sess.target.target.target_os == "vxworks"
if self.sess.target.target_os == "vxworks"
&& matches!(
output_kind,
LinkOutputKind::StaticNoPicExe
@ -387,7 +385,7 @@ impl<'a> Linker for GccLinker<'a> {
// functions, etc.
fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]) {
self.hint_static();
let target = &self.sess.target.target;
let target = &self.sess.target;
if !target.options.is_like_osx {
self.linker_arg("--whole-archive").cmd.arg(format!("-l{}", lib));
self.linker_arg("--no-whole-archive");
@ -402,7 +400,7 @@ impl<'a> Linker for GccLinker<'a> {
fn link_whole_rlib(&mut self, lib: &Path) {
self.hint_static();
if self.sess.target.target.options.is_like_osx {
if self.sess.target.options.is_like_osx {
self.linker_arg("-force_load");
self.linker_arg(&lib);
} else {
@ -426,9 +424,9 @@ impl<'a> Linker for GccLinker<'a> {
// -dead_strip can't be part of the pre_link_args because it's also used
// for partial linking when using multiple codegen units (-r). So we
// insert it here.
if self.sess.target.target.options.is_like_osx {
if self.sess.target.options.is_like_osx {
self.linker_arg("-dead_strip");
} else if self.sess.target.target.options.is_like_solaris {
} else if self.sess.target.options.is_like_solaris {
self.linker_arg("-zignore");
// If we're building a dylib, we don't use --gc-sections because LLVM
@ -442,7 +440,7 @@ impl<'a> Linker for GccLinker<'a> {
}
fn optimize(&mut self) {
if !self.sess.target.target.options.linker_is_gnu {
if !self.sess.target.options.linker_is_gnu {
return;
}
@ -456,7 +454,7 @@ impl<'a> Linker for GccLinker<'a> {
}
fn pgo_gen(&mut self) {
if !self.sess.target.target.options.linker_is_gnu {
if !self.sess.target.options.linker_is_gnu {
return;
}
@ -506,7 +504,7 @@ impl<'a> Linker for GccLinker<'a> {
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
// Symbol visibility in object files typically takes care of this.
if crate_type == CrateType::Executable
&& self.sess.target.target.options.override_export_symbols.is_none()
&& self.sess.target.options.override_export_symbols.is_none()
{
return;
}
@ -515,7 +513,7 @@ impl<'a> Linker for GccLinker<'a> {
// The object files have far more public symbols than we actually want to export,
// so we hide them all here.
if !self.sess.target.target.options.limit_rdylib_exports {
if !self.sess.target.options.limit_rdylib_exports {
return;
}
@ -523,13 +521,13 @@ impl<'a> Linker for GccLinker<'a> {
return;
}
let is_windows = self.sess.target.target.options.is_like_windows;
let is_windows = self.sess.target.options.is_like_windows;
let mut arg = OsString::new();
let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
debug!("EXPORTED SYMBOLS:");
if self.sess.target.target.options.is_like_osx {
if self.sess.target.options.is_like_osx {
// Write a plain, newline-separated list of symbols
let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?);
@ -575,12 +573,12 @@ impl<'a> Linker for GccLinker<'a> {
}
}
if self.sess.target.target.options.is_like_osx {
if self.sess.target.options.is_like_osx {
if !self.is_ld {
arg.push("-Wl,")
}
arg.push("-exported_symbols_list,");
} else if self.sess.target.target.options.is_like_solaris {
} else if self.sess.target.options.is_like_solaris {
if !self.is_ld {
arg.push("-Wl,")
}
@ -1205,7 +1203,7 @@ impl<'a> Linker for WasmLd<'a> {
}
fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
if let Some(ref exports) = tcx.sess.target.target.options.override_export_symbols {
if let Some(ref exports) = tcx.sess.target.options.override_export_symbols {
return exports.clone();
}
@ -1295,7 +1293,7 @@ impl<'a> Linker for PtxLinker<'a> {
// Provide the linker with fallback to internal `target-cpu`.
self.cmd.arg("--fallback-arch").arg(match self.sess.opts.cg.target_cpu {
Some(ref s) => s,
None => &self.sess.target.target.options.cpu,
None => &self.sess.target.options.cpu,
});
}

View file

@ -229,8 +229,8 @@ fn exported_symbols_provider_local(
// needs to be exported.
// However, on platforms that don't allow for Rust dylibs, having
// external linkage is enough for monomorphization to be linked to.
let need_visibility = tcx.sess.target.target.options.dynamic_linking
&& !tcx.sess.target.target.options.only_cdylib;
let need_visibility =
tcx.sess.target.options.dynamic_linking && !tcx.sess.target.options.only_cdylib;
let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
@ -391,7 +391,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
if is_extern && !std_internal {
let target = &tcx.sess.target.target.llvm_target;
let target = &tcx.sess.target.llvm_target;
// WebAssembly cannot export data symbols, so reduce their export level
if target.contains("emscripten") {
if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) =

View file

@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::profiling::TimingGuard;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter;
use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
@ -140,7 +139,7 @@ impl ModuleConfig {
let emit_obj = if !should_emit_obj {
EmitObj::None
} else if sess.target.target.options.obj_is_bitcode
} else if sess.target.options.obj_is_bitcode
|| (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
{
// This case is selected if the target uses objects as bitcode, or
@ -222,11 +221,11 @@ impl ModuleConfig {
false
),
emit_obj,
bc_cmdline: sess.target.target.options.bitcode_llvm_cmdline.clone(),
bc_cmdline: sess.target.options.bitcode_llvm_cmdline.clone(),
verify_llvm_ir: sess.verify_llvm_ir(),
no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes,
no_builtins: no_builtins || sess.target.target.options.no_builtins,
no_builtins: no_builtins || sess.target.options.no_builtins,
// Exclude metadata and allocator modules from time_passes output,
// since they throw off the "LLVM passes" measurement.
@ -253,7 +252,7 @@ impl ModuleConfig {
.opts
.debugging_opts
.merge_functions
.unwrap_or(sess.target.target.options.merge_functions)
.unwrap_or(sess.target.options.merge_functions)
{
MergeFunctions::Disabled => false,
MergeFunctions::Trampolines | MergeFunctions::Aliases => {
@ -308,7 +307,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
pub allocator_module_config: Arc<ModuleConfig>,
pub tm_factory: TargetMachineFactory<B>,
pub msvc_imps_needed: bool,
pub target_pointer_width: String,
pub target_pointer_width: u32,
pub target_arch: String,
pub debuginfo: config::DebugInfo,
@ -389,7 +388,7 @@ fn need_bitcode_in_object(sess: &Session) -> bool {
let requested_for_rlib = sess.opts.cg.embed_bitcode
&& sess.crate_types().contains(&CrateType::Rlib)
&& sess.opts.output_types.contains_key(&OutputType::Exe);
let forced_by_target = sess.target.target.options.forces_embed_bitcode;
let forced_by_target = sess.target.options.forces_embed_bitcode;
requested_for_rlib || forced_by_target
}
@ -414,7 +413,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
let sess = tcx.sess;
let crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_hash = tcx.crate_hash(LOCAL_CRATE);
let no_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins);
let is_compiler_builtins =
tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins);
@ -463,7 +461,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
OngoingCodegen {
backend,
crate_name,
crate_hash,
metadata,
windows_subsystem,
linker_info,
@ -658,15 +655,6 @@ fn produce_final_output_artifacts(
// These are used in linking steps and will be cleaned up afterward.
}
pub fn dump_incremental_data(_codegen_results: &CodegenResults) {
// FIXME(mw): This does not work at the moment because the situation has
// become more complicated due to incremental LTO. Now a CGU
// can have more than two caching states.
// println!("[incremental] Re-using {} out of {} modules",
// codegen_results.modules.iter().filter(|m| m.pre_existing).count(),
// codegen_results.modules.len());
}
pub enum WorkItem<B: WriteBackendMethods> {
/// Optimize a newly codegened, totally unoptimized module.
Optimize(ModuleCodegen<B::Module>),
@ -1034,8 +1022,8 @@ fn start_executing_work<B: ExtraBackendMethods>(
tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, ol)),
total_cgus,
msvc_imps_needed: msvc_imps_needed(tcx),
target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),
target_arch: tcx.sess.target.target.arch.clone(),
target_pointer_width: tcx.sess.target.pointer_width,
target_arch: tcx.sess.target.arch.clone(),
debuginfo: tcx.sess.opts.debuginfo,
};
@ -1175,7 +1163,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
// necessary. There's already optimizations in place to avoid sending work
// back to the coordinator if LTO isn't requested.
return thread::spawn(move || {
let max_workers = ::num_cpus::get();
let max_workers = num_cpus::get();
let mut worker_id_counter = 0;
let mut free_worker_ids = Vec::new();
let mut get_worker_id = |free_worker_ids: &mut Vec<usize>| {
@ -1531,8 +1519,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
}
}
pub const CODEGEN_WORKER_ID: usize = usize::MAX;
/// `FatalError` is explicitly not `Send`.
#[must_use]
pub struct WorkerFatalError;
@ -1720,7 +1706,6 @@ impl SharedEmitterMain {
pub struct OngoingCodegen<B: ExtraBackendMethods> {
pub backend: B,
pub crate_name: Symbol,
pub crate_hash: Svh,
pub metadata: EncodedMetadata,
pub windows_subsystem: Option<String>,
pub linker_info: LinkerInfo,
@ -1766,7 +1751,6 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
(
CodegenResults {
crate_name: self.crate_name,
crate_hash: self.crate_hash,
metadata: self.metadata,
windows_subsystem: self.windows_subsystem,
linker_info: self.linker_info,
@ -1881,11 +1865,11 @@ fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool {
// something is wrong with commandline arg validation.
assert!(
!(tcx.sess.opts.cg.linker_plugin_lto.enabled()
&& tcx.sess.target.target.options.is_like_windows
&& tcx.sess.target.options.is_like_windows
&& tcx.sess.opts.cg.prefer_dynamic)
);
tcx.sess.target.target.options.is_like_windows &&
tcx.sess.target.options.is_like_windows &&
tcx.sess.crate_types().iter().any(|ct| *ct == CrateType::Rlib) &&
// ThinLTO can't handle this workaround in all cases, so we don't
// emit the `__imp_` symbols. Instead we make them unnecessary by disallowing

View file

@ -327,7 +327,7 @@ fn cast_shift_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
/// currently uses SEH-ish unwinding with DWARF info tables to the side (same as
/// 64-bit MinGW) instead of "full SEH".
pub fn wants_msvc_seh(sess: &Session) -> bool {
sess.target.target.options.is_like_msvc
sess.target.options.is_like_msvc
}
pub fn memcpy_ty<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
@ -393,7 +393,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
) -> Bx::Function {
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
// depending on whether the target needs `argc` and `argv` to be passed in.
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
let llfty = if cx.sess().target.options.main_needs_argc_argv {
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
} else {
cx.type_func(&[], cx.type_int())
@ -464,7 +464,7 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
bx: &mut Bx,
) -> (Bx::Value, Bx::Value) {
if cx.sess().target.target.options.main_needs_argc_argv {
if cx.sess().target.options.main_needs_argc_argv {
// Params from native `main()` used as args for rust start function
let param_argc = bx.get_param(0);
let param_argv = bx.get_param(1);
@ -479,8 +479,6 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}
pub const CODEGEN_WORKER_ID: usize = usize::MAX;
pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'tcx>,
@ -695,7 +693,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
total_codegen_time.into_inner(),
);
::rustc_incremental::assert_module_sources::assert_module_sources(tcx);
rustc_incremental::assert_module_sources::assert_module_sources(tcx);
symbol_names_test::report_symbol_names(tcx);
@ -754,8 +752,8 @@ impl<B: ExtraBackendMethods> Drop for AbortCodegenOnDrop<B> {
}
fn finalize_tcx(tcx: TyCtxt<'_>) {
tcx.sess.time("assert_dep_graph", || ::rustc_incremental::assert_dep_graph(tcx));
tcx.sess.time("serialize_dep_graph", || ::rustc_incremental::save_dep_graph(tcx));
tcx.sess.time("assert_dep_graph", || rustc_incremental::assert_dep_graph(tcx));
tcx.sess.time("serialize_dep_graph", || rustc_incremental::save_dep_graph(tcx));
// We assume that no queries are run past here. If there are new queries
// after this point, they'll show up as "<unknown>" in self-profiling data.

View file

@ -33,7 +33,7 @@ pub fn push_debuginfo_type_name<'tcx>(
) {
// When targeting MSVC, emit C++ style type names for compatibility with
// .natvis visualizers (and perhaps other existing native debuggers?)
let cpp_like_names = tcx.sess.target.target.options.is_like_msvc;
let cpp_like_names = tcx.sess.target.options.is_like_msvc;
match *t.kind() {
ty::Bool => output.push_str("bool"),

View file

@ -21,7 +21,6 @@ extern crate tracing;
extern crate rustc_middle;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_hir::def_id::CrateNum;
use rustc_hir::LangItem;
@ -134,7 +133,6 @@ pub struct CodegenResults {
pub modules: Vec<CompiledModule>,
pub allocator_module: Option<CompiledModule>,
pub metadata_module: Option<CompiledModule>,
pub crate_hash: Svh,
pub metadata: rustc_middle::middle::cstore::EncodedMetadata,
pub windows_subsystem: Option<String>,
pub linker_info: back::linker::LinkerInfo,
@ -144,6 +142,7 @@ pub struct CodegenResults {
pub fn provide(providers: &mut Providers) {
crate::back::symbol_export::provide(providers);
crate::base::provide_both(providers);
crate::target_features::provide(providers);
}
pub fn provide_extern(providers: &mut Providers) {

View file

@ -12,9 +12,9 @@ use crate::MemFlags;
use rustc_ast as ast;
use rustc_hir::lang_items::LangItem;
use rustc_index::vec::Idx;
use rustc_middle::mir;
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::mir::AssertKind;
use rustc_middle::mir::{self, SwitchTargets};
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
@ -24,8 +24,6 @@ use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
use rustc_target::abi::{self, LayoutOf};
use rustc_target::spec::abi::Abi;
use std::borrow::Cow;
/// Used by `FunctionCx::codegen_terminator` for emitting common patterns
/// e.g., creating a basic block, calling a function, etc.
struct TerminatorCodegenHelper<'tcx> {
@ -198,42 +196,37 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mut bx: Bx,
discr: &mir::Operand<'tcx>,
switch_ty: Ty<'tcx>,
values: &Cow<'tcx, [u128]>,
targets: &Vec<mir::BasicBlock>,
targets: &SwitchTargets,
) {
let discr = self.codegen_operand(&mut bx, &discr);
// `switch_ty` is redundant, sanity-check that.
assert_eq!(discr.layout.ty, switch_ty);
if targets.len() == 2 {
// If there are two targets, emit br instead of switch
let lltrue = helper.llblock(self, targets[0]);
let llfalse = helper.llblock(self, targets[1]);
helper.maybe_sideeffect(self.mir, &mut bx, targets.all_targets());
let mut target_iter = targets.iter();
if target_iter.len() == 1 {
// If there are two targets (one conditional, one fallback), emit br instead of switch
let (test_value, target) = target_iter.next().unwrap();
let lltrue = helper.llblock(self, target);
let llfalse = helper.llblock(self, targets.otherwise());
if switch_ty == bx.tcx().types.bool {
helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice());
// Don't generate trivial icmps when switching on bool
if let [0] = values[..] {
bx.cond_br(discr.immediate(), llfalse, lltrue);
} else {
assert_eq!(&values[..], &[1]);
bx.cond_br(discr.immediate(), lltrue, llfalse);
match test_value {
0 => bx.cond_br(discr.immediate(), llfalse, lltrue),
1 => bx.cond_br(discr.immediate(), lltrue, llfalse),
_ => bug!(),
}
} else {
let switch_llty = bx.immediate_backend_type(bx.layout_of(switch_ty));
let llval = bx.const_uint_big(switch_llty, values[0]);
let llval = bx.const_uint_big(switch_llty, test_value);
let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice());
bx.cond_br(cmp, lltrue, llfalse);
}
} else {
helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice());
let (otherwise, targets) = targets.split_last().unwrap();
bx.switch(
discr.immediate(),
helper.llblock(self, *otherwise),
values
.iter()
.zip(targets)
.map(|(&value, target)| (value, helper.llblock(self, *target))),
helper.llblock(self, targets.otherwise()),
target_iter.map(|(value, target)| (value, helper.llblock(self, target))),
);
}
}
@ -879,7 +872,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let string = match ty.kind() {
ty::Uint(_) => value.to_string(),
ty::Int(int_ty) => {
match int_ty.normalize(bx.tcx().sess.target.ptr_width) {
match int_ty.normalize(bx.tcx().sess.target.pointer_width) {
ast::IntTy::I8 => (value as i8).to_string(),
ast::IntTy::I16 => (value as i16).to_string(),
ast::IntTy::I32 => (value as i32).to_string(),
@ -975,8 +968,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
helper.funclet_br(self, &mut bx, target);
}
mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
self.codegen_switchint_terminator(helper, bx, discr, switch_ty, values, targets);
mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref targets } => {
self.codegen_switchint_terminator(helper, bx, discr, switch_ty, targets);
}
mir::TerminatorKind::Return => {

View file

@ -580,8 +580,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// stuffs.
fn int_type_width_signed(ty: Ty<'_>, tcx: TyCtxt<'_>) -> Option<(u64, bool)> {
match ty.kind() {
ty::Int(t) => Some((t.bit_width().unwrap_or(u64::from(tcx.sess.target.ptr_width)), true)),
ty::Uint(t) => Some((t.bit_width().unwrap_or(u64::from(tcx.sess.target.ptr_width)), false)),
ty::Int(t) => {
Some((t.bit_width().unwrap_or(u64::from(tcx.sess.target.pointer_width)), true))
}
ty::Uint(t) => {
Some((t.bit_width().unwrap_or(u64::from(tcx.sess.target.pointer_width)), false))
}
_ => None,
}
}

View file

@ -346,8 +346,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
..
} => {
if variant_index != dataful_variant {
if bx.cx().sess().target.target.arch == "arm"
|| bx.cx().sess().target.target.arch == "aarch64"
if bx.cx().sess().target.arch == "arm"
|| bx.cx().sess().target.arch == "aarch64"
{
// FIXME(#34427): as workaround for LLVM bug on ARM,
// use memset of 0 before assigning niche value.

View file

@ -1,3 +1,5 @@
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::query::Providers;
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::symbol::Symbol;
@ -136,7 +138,7 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol
}
pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option<Symbol>)] {
match &*sess.target.target.arch {
match &*sess.target.arch {
"arm" => ARM_ALLOWED_FEATURES,
"aarch64" => AARCH64_ALLOWED_FEATURES,
"x86" | "x86_64" => X86_ALLOWED_FEATURES,
@ -148,3 +150,16 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
_ => &[],
}
}
pub(crate) fn provide(providers: &mut Providers) {
providers.supported_target_features = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
if tcx.sess.opts.actually_rustdoc {
// rustdoc needs to be able to document functions that use all the features, so
// whitelist them all
all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
} else {
supported_target_features(tcx.sess).iter().map(|&(a, b)| (a.to_string(), b)).collect()
}
};
}

View file

@ -1,10 +1,11 @@
use super::write::WriteBackendMethods;
use super::CodegenObject;
use crate::ModuleCodegen;
use crate::{CodegenResults, ModuleCodegen};
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
use rustc_middle::ty::query::Providers;
@ -80,8 +81,7 @@ pub trait CodegenBackend {
&self,
ongoing_codegen: Box<dyn Any>,
sess: &Session,
dep_graph: &DepGraph,
) -> Result<Box<dyn Any>, ErrorReported>;
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported>;
/// This is called on the returned `Box<dyn Any>` from `join_codegen`
///
@ -91,7 +91,7 @@ pub trait CodegenBackend {
fn link(
&self,
sess: &Session,
codegen_results: Box<dyn Any>,
codegen_results: CodegenResults,
outputs: &OutputFilenames,
) -> Result<(), ErrorReported>;
}
@ -124,4 +124,5 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
opt_level: config::OptLevel,
) -> Arc<dyn Fn() -> Result<Self::TargetMachine, String> + Send + Sync>;
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>;
}

View file

@ -85,7 +85,7 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
}
pub trait HasCodegen<'tcx>:
Backend<'tcx> + ::std::ops::Deref<Target = <Self as HasCodegen<'tcx>>::CodegenCx>
Backend<'tcx> + std::ops::Deref<Target = <Self as HasCodegen<'tcx>>::CodegenCx>
{
type CodegenCx: CodegenMethods<'tcx>
+ BackendTypes<

View file

@ -51,7 +51,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
}
fn type_int(&self) -> Self::Type {
match &self.sess().target.target.target_c_int_width[..] {
match &self.sess().target.target_c_int_width[..] {
"16" => self.type_i16(),
"32" => self.type_i32(),
"64" => self.type_i64(),

View file

@ -71,8 +71,8 @@ impl Fingerprint {
}
}
impl ::std::fmt::Display for Fingerprint {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
impl std::fmt::Display for Fingerprint {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(formatter, "{:x}-{:x}", self.0, self.1)
}
}

View file

@ -129,7 +129,7 @@ pub enum ProcessResult<O, E> {
struct ObligationTreeId(usize);
type ObligationTreeIdGenerator =
::std::iter::Map<::std::ops::RangeFrom<usize>, fn(usize) -> ObligationTreeId>;
std::iter::Map<std::ops::RangeFrom<usize>, fn(usize) -> ObligationTreeId>;
pub struct ObligationForest<O: ForestObligation> {
/// The list of obligations. In between calls to `process_obligations`,

View file

@ -93,7 +93,7 @@ impl<K: Ord, V> SortedMap<K, V> {
/// Iterate over elements, sorted by key
#[inline]
pub fn iter(&self) -> ::std::slice::Iter<'_, (K, V)> {
pub fn iter(&self) -> std::slice::Iter<'_, (K, V)> {
self.data.iter()
}
@ -134,7 +134,7 @@ impl<K: Ord, V> SortedMap<K, V> {
R: RangeBounds<K>,
{
let (start, end) = self.range_slice_indices(range);
self.data.splice(start..end, ::std::iter::empty());
self.data.splice(start..end, std::iter::empty());
}
/// Mutate all keys with the given function `f`. This mutation must not
@ -241,7 +241,7 @@ impl<K: Ord, V> SortedMap<K, V> {
impl<K: Ord, V> IntoIterator for SortedMap<K, V> {
type Item = (K, V);
type IntoIter = ::std::vec::IntoIter<(K, V)>;
type IntoIter = std::vec::IntoIter<(K, V)>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()

View file

@ -20,7 +20,7 @@ pub struct StableHasher {
}
impl ::std::fmt::Debug for StableHasher {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.state)
}
}

View file

@ -14,12 +14,6 @@ pub struct WorkQueue<T: Idx> {
}
impl<T: Idx> WorkQueue<T> {
/// Creates a new work queue with all the elements from (0..len).
#[inline]
pub fn with_all(len: usize) -> Self {
WorkQueue { deque: (0..len).map(T::new).collect(), set: BitSet::new_filled(len) }
}
/// Creates a new work queue that starts empty, where elements range from (0..len).
#[inline]
pub fn with_none(len: usize) -> Self {

View file

@ -10,7 +10,7 @@ crate-type = ["dylib"]
[dependencies]
libc = "0.2"
tracing = { version = "0.1.18" }
tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
tracing-subscriber = { version = "0.2.13", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
tracing-tree = "0.1.6"
rustc_middle = { path = "../rustc_middle" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }

View file

@ -134,9 +134,52 @@ pub fn diagnostics_registry() -> Registry {
Registry::new(&rustc_error_codes::DIAGNOSTICS)
}
pub struct RunCompiler<'a, 'b> {
at_args: &'a [String],
callbacks: &'b mut (dyn Callbacks + Send),
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
emitter: Option<Box<dyn Write + Send>>,
make_codegen_backend:
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
}
impl<'a, 'b> RunCompiler<'a, 'b> {
pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self {
Self { at_args, callbacks, file_loader: None, emitter: None, make_codegen_backend: None }
}
pub fn set_make_codegen_backend(
&mut self,
make_codegen_backend: Option<
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
>,
) -> &mut Self {
self.make_codegen_backend = make_codegen_backend;
self
}
pub fn set_emitter(&mut self, emitter: Option<Box<dyn Write + Send>>) -> &mut Self {
self.emitter = emitter;
self
}
pub fn set_file_loader(
&mut self,
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
) -> &mut Self {
self.file_loader = file_loader;
self
}
pub fn run(self) -> interface::Result<()> {
run_compiler(
self.at_args,
self.callbacks,
self.file_loader,
self.emitter,
self.make_codegen_backend,
)
}
}
// Parse args and run the compiler. This is the primary entry point for rustc.
// The FileLoader provides a way to load files from sources other than the file system.
pub fn run_compiler(
fn run_compiler(
at_args: &[String],
callbacks: &mut (dyn Callbacks + Send),
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
@ -155,8 +198,7 @@ pub fn run_compiler(
),
}
}
let diagnostic_output =
emitter.map(|emitter| DiagnosticOutput::Raw(emitter)).unwrap_or(DiagnosticOutput::Default);
let diagnostic_output = emitter.map_or(DiagnosticOutput::Default, DiagnosticOutput::Raw);
let matches = match handle_options(&args) {
Some(matches) => matches,
None => return Ok(()),
@ -600,7 +642,7 @@ impl RustcDefaultCalls {
let codegen_results: CodegenResults = json::decode(&rlink_data).unwrap_or_else(|err| {
sess.fatal(&format!("failed to decode rlink: {}", err));
});
compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs)
compiler.codegen_backend().link(&sess, codegen_results, &outputs)
} else {
sess.fatal("rlink must be a file")
}
@ -628,7 +670,7 @@ impl RustcDefaultCalls {
Input::File(ref ifile) => {
let path = &(*ifile);
let mut v = Vec::new();
locator::list_file_metadata(&sess.target.target, path, metadata_loader, &mut v)
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v)
.unwrap();
println!("{}", String::from_utf8(v).unwrap());
}
@ -672,7 +714,8 @@ impl RustcDefaultCalls {
for req in &sess.opts.prints {
match *req {
TargetList => {
let mut targets = rustc_target::spec::get_targets().collect::<Vec<String>>();
let mut targets =
rustc_target::spec::TARGETS.iter().copied().collect::<Vec<_>>();
targets.sort();
println!("{}", targets.join("\n"));
}
@ -681,7 +724,7 @@ impl RustcDefaultCalls {
"{}",
sess.target_tlib_path.as_ref().unwrap_or(&sess.host_tlib_path).dir.display()
),
TargetSpec => println!("{}", sess.target.target.to_json().pretty()),
TargetSpec => println!("{}", sess.target.to_json().pretty()),
FileNames | CrateName => {
let input = input.unwrap_or_else(|| {
early_error(ErrorOutputType::default(), "no input file provided")
@ -1215,9 +1258,9 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
// If backtraces are enabled, also print the query stack
let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
if backtrace {
TyCtxt::try_print_query_stack(&handler);
}
let num_frames = if backtrace { None } else { Some(2) };
TyCtxt::try_print_query_stack(&handler, num_frames);
#[cfg(windows)]
unsafe {
@ -1285,7 +1328,7 @@ pub fn main() -> ! {
})
})
.collect::<Vec<_>>();
run_compiler(&args, &mut callbacks, None, None, None)
RunCompiler::new(&args, &mut callbacks).run()
});
// The extra `\t` is necessary to align this label with the others.
print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());

View file

@ -460,6 +460,8 @@ E0774: include_str!("./error_codes/E0774.md"),
E0775: include_str!("./error_codes/E0775.md"),
E0776: include_str!("./error_codes/E0776.md"),
E0777: include_str!("./error_codes/E0777.md"),
E0778: include_str!("./error_codes/E0778.md"),
E0779: include_str!("./error_codes/E0779.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard

View file

@ -1,3 +1,5 @@
#### Note: this error code is no longer emitted by the compiler.
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code
like the following is invalid as it requires the entire `Option<String>` to be
@ -6,11 +8,13 @@ inner `String` to be moved into a variable called `s`.
Erroneous code example:
```compile_fail,E0007
```compile_fail,E0382
#![feature(bindings_after_at)]
let x = Some("s".to_string());
match x {
op_string @ Some(s) => {}, // error: cannot bind by-move with sub-bindings
op_string @ Some(s) => {}, // error: use of moved value
None => {},
}
```

View file

@ -21,7 +21,7 @@ impl Foo {
The `self` keyword can only be used inside methods, which are associated
functions (functions defined inside of a `trait` or `impl` block) that have a
`self` receiver as its first parameter, like `self`, `&self`, `&mut self` or
`self: &mut Pin<Self>` (this last one is an example of an ["abitrary `self`
`self: &mut Pin<Self>` (this last one is an example of an ["arbitrary `self`
type"](https://github.com/rust-lang/rust/issues/44874)).
Check if the associated function's parameter list should have contained a `self`

View file

@ -3,12 +3,8 @@ An unstable feature in `const` contexts was used.
Erroneous code example:
```compile_fail,E0723
trait T {}
impl T for () {}
const fn foo() -> impl T { // error: `impl Trait` in const fn is unstable
()
const fn foo<T: Copy>(_: T) { // error!
// ...
}
```
@ -18,11 +14,7 @@ feature flag:
```
#![feature(const_fn)]
trait T {}
impl T for () {}
const fn foo() -> impl T {
()
const fn foo<T: Copy>(_: T) { // ok!
// ...
}
```

View file

@ -0,0 +1,35 @@
The `instruction_set` attribute was malformed.
Erroneous code example:
```compile_fail,E0778
#![feature(isa_attribute)]
#[instruction_set()] // error: expected one argument
pub fn something() {}
fn main() {}
```
The parenthesized `instruction_set` attribute requires the parameter to be
specified:
```
#![feature(isa_attribute)]
#[cfg_attr(target_arch="arm", instruction_set(arm::a32))]
fn something() {}
```
or:
```
#![feature(isa_attribute)]
#[cfg_attr(target_arch="arm", instruction_set(arm::t32))]
fn something() {}
```
For more information see the [`instruction_set` attribute][isa-attribute]
section of the Reference.
[isa-attribute]: https://doc.rust-lang.org/reference/attributes/codegen.html

View file

@ -0,0 +1,32 @@
An unknown argument was given to the `instruction_set` attribute.
Erroneous code example:
```compile_fail,E0779
#![feature(isa_attribute)]
#[instruction_set(intel::x64)] // error: invalid argument
pub fn something() {}
fn main() {}
```
The `instruction_set` attribute only supports two arguments currently:
* arm::a32
* arm::t32
All other arguments given to the `instruction_set` attribute will return this
error. Example:
```
#![feature(isa_attribute)]
#[cfg_attr(target_arch="arm", instruction_set(arm::a32))] // ok!
pub fn something() {}
fn main() {}
```
For more information see the [`instruction_set` attribute][isa-attribute]
section of the Reference.
[isa-attribute]: https://doc.rust-lang.org/reference/attributes/codegen.html

View file

@ -121,11 +121,6 @@ impl Diagnostic {
self.level == Level::Cancelled
}
/// Set the sorting span.
pub fn set_sort_span(&mut self, sp: Span) {
self.sort_span = sp;
}
/// Adds a span/label to be included in the resulting snippet.
///
/// This is pushed onto the [`MultiSpan`] that was created when the diagnostic
@ -535,14 +530,6 @@ impl Diagnostic {
&self.message
}
/// Used by a lint. Copies over all details *but* the "main
/// message".
pub fn copy_details_not_message(&mut self, from: &Diagnostic) {
self.span = from.span.clone();
self.code = from.code.clone();
self.children.extend(from.children.iter().cloned())
}
/// Convenience function for internal use, clients should use one of the
/// public methods above.
pub fn sub(

View file

@ -510,8 +510,6 @@ impl Emitter for SilentEmitter {
fn emit_diagnostic(&mut self, _: &Diagnostic) {}
}
/// Maximum number of lines we will print for each error; arbitrary.
pub const MAX_HIGHLIGHT_LINES: usize = 6;
/// Maximum number of lines we will print for a multiline suggestion; arbitrary.
///
/// This should be replaced with a more involved mechanism to output multiline suggestions that

View file

@ -148,17 +148,6 @@ impl Annotatable {
}
}
pub fn map_item_or<F, G>(self, mut f: F, mut or: G) -> Annotatable
where
F: FnMut(P<ast::Item>) -> P<ast::Item>,
G: FnMut(Annotatable) -> Annotatable,
{
match self {
Annotatable::Item(i) => Annotatable::Item(f(i)),
_ => or(self),
}
}
pub fn expect_trait_item(self) -> P<ast::AssocItem> {
match self {
Annotatable::TraitItem(i) => i,
@ -1052,9 +1041,6 @@ impl<'a> ExtCtxt<'a> {
.chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
.collect()
}
pub fn name_of(&self, st: &str) -> Symbol {
Symbol::intern(st)
}
pub fn check_unused_macros(&mut self) {
self.resolver.check_unused_macros();

View file

@ -139,24 +139,6 @@ impl<'a> ExtCtxt<'a> {
ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) }
}
pub fn lifetime_def(
&self,
span: Span,
ident: Ident,
attrs: Vec<ast::Attribute>,
bounds: ast::GenericBounds,
) -> ast::GenericParam {
let lifetime = self.lifetime(span, ident);
ast::GenericParam {
ident: lifetime.ident,
id: lifetime.id,
attrs: attrs.into(),
bounds,
kind: ast::GenericParamKind::Lifetime,
is_placeholder: false,
}
}
pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
ast::Stmt {
id: ast::DUMMY_NODE_ID,
@ -465,24 +447,6 @@ impl<'a> ExtCtxt<'a> {
self.pat_tuple_struct(span, path, vec![pat])
}
pub fn pat_none(&self, span: Span) -> P<ast::Pat> {
let some = self.std_path(&[sym::option, sym::Option, sym::None]);
let path = self.path_global(span, some);
self.pat_path(span, path)
}
pub fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = self.std_path(&[sym::result, sym::Result, sym::Ok]);
let path = self.path_global(span, some);
self.pat_tuple_struct(span, path, vec![pat])
}
pub fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = self.std_path(&[sym::result, sym::Result, sym::Err]);
let path = self.path_global(span, some);
self.pat_tuple_struct(span, path, vec![pat])
}
pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm {
ast::Arm {
attrs: vec![],
@ -514,26 +478,6 @@ impl<'a> ExtCtxt<'a> {
self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els))
}
pub fn lambda_fn_decl(
&self,
span: Span,
fn_decl: P<ast::FnDecl>,
body: P<ast::Expr>,
fn_decl_span: Span,
) -> P<ast::Expr> {
self.expr(
span,
ast::ExprKind::Closure(
ast::CaptureBy::Ref,
ast::Async::No,
ast::Movability::Movable,
fn_decl,
body,
fn_decl_span,
),
)
}
pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
let fn_decl = self.fn_decl(
ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
@ -610,47 +554,6 @@ impl<'a> ExtCtxt<'a> {
})
}
pub fn variant(&self, span: Span, ident: Ident, tys: Vec<P<ast::Ty>>) -> ast::Variant {
let vis_span = span.shrink_to_lo();
let fields: Vec<_> = tys
.into_iter()
.map(|ty| ast::StructField {
span: ty.span,
ty,
ident: None,
vis: ast::Visibility {
span: vis_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
is_placeholder: false,
})
.collect();
let vdata = if fields.is_empty() {
ast::VariantData::Unit(ast::DUMMY_NODE_ID)
} else {
ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID)
};
ast::Variant {
attrs: Vec::new(),
data: vdata,
disr_expr: None,
id: ast::DUMMY_NODE_ID,
ident,
vis: ast::Visibility {
span: vis_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
span,
is_placeholder: false,
}
}
pub fn item_static(
&self,
span: Span,

View file

@ -20,7 +20,7 @@ use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{struct_span_err, Applicability, PResult};
use rustc_feature::Features;
use rustc_parse::parser::Parser;
use rustc_parse::parser::{AttemptLocalParseRecovery, Parser};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
use rustc_session::lint::BuiltinLintDiagnostics;
@ -921,7 +921,7 @@ pub fn parse_ast_fragment<'a>(
let mut stmts = SmallVec::new();
// Won't make progress on a `}`.
while this.token != token::Eof && this.token != token::CloseDelim(token::Brace) {
if let Some(stmt) = this.parse_full_stmt()? {
if let Some(stmt) = this.parse_full_stmt(AttemptLocalParseRecovery::Yes)? {
stmts.push(stmt);
}
}

View file

@ -270,6 +270,9 @@ declare_features! (
(accepted, track_caller, "1.46.0", Some(47809), None),
/// Allows `#[doc(alias = "...")]`.
(accepted, doc_alias, "1.48.0", Some(50146), None),
/// Allows patterns with concurrent by-move and by-ref bindings.
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(accepted, move_ref_pattern, "1.48.0", Some(68354), None),
// -------------------------------------------------------------------------
// feature-group-end: accepted features

View file

@ -526,10 +526,6 @@ declare_features! (
/// For example, you can write `x @ Some(y)`.
(active, bindings_after_at, "1.41.0", Some(65490), None),
/// Allows patterns with concurrent by-move and by-ref bindings.
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(active, move_ref_pattern, "1.42.0", Some(68354), None),
/// Allows `impl const Trait for T` syntax.
(active, const_trait_impl, "1.42.0", Some(67792), None),
@ -596,6 +592,12 @@ declare_features! (
/// Allows rustc to inject a default alloc_error_handler
(active, default_alloc_error_handler, "1.48.0", Some(66741), None),
/// Allows argument and return position `impl Trait` in a `const fn`.
(active, const_impl_trait, "1.48.0", Some(77463), None),
/// Allows `#[instruction_set(_)]` attribute
(active, isa_attribute, "1.48.0", Some(74727), None),
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------

View file

@ -336,6 +336,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
optimize, AssumedUsed, template!(List: "size|speed"), optimize_attribute,
experimental!(optimize),
),
// RFC 2867
gated!(instruction_set, AssumedUsed, template!(List: "set"), isa_attribute, experimental!(instruction_set)),
gated!(ffi_returns_twice, AssumedUsed, template!(Word), experimental!(ffi_returns_twice)),
gated!(ffi_pure, AssumedUsed, template!(Word), experimental!(ffi_pure)),

View file

@ -75,33 +75,6 @@ pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<Li
}
}
#[derive(Debug)]
pub enum RenameOrCopyRemove {
Rename,
CopyRemove,
}
/// Rename `p` into `q`, preferring to use `rename` if possible.
/// If `rename` fails (rename may fail for reasons such as crossing
/// filesystem), fallback to copy & remove
pub fn rename_or_copy_remove<P: AsRef<Path>, Q: AsRef<Path>>(
p: P,
q: Q,
) -> io::Result<RenameOrCopyRemove> {
let p = p.as_ref();
let q = q.as_ref();
match fs::rename(p, q) {
Ok(()) => Ok(RenameOrCopyRemove::Rename),
Err(_) => match fs::copy(p, q) {
Ok(_) => {
fs::remove_file(p)?;
Ok(RenameOrCopyRemove::CopyRemove)
}
Err(e) => Err(e),
},
}
}
#[cfg(unix)]
pub fn path_to_c_string(p: &Path) -> CString {
use std::ffi::OsStr;

View file

@ -118,7 +118,7 @@ impl DefKey {
let DisambiguatedDefPathData { ref data, disambiguator } = self.disambiguated_data;
::std::mem::discriminant(data).hash(&mut hasher);
std::mem::discriminant(data).hash(&mut hasher);
if let Some(name) = data.get_opt_name() {
// Get a stable hash by considering the symbol chars rather than
// the symbol index.
@ -188,10 +188,6 @@ pub struct DefPath {
}
impl DefPath {
pub fn is_local(&self) -> bool {
self.krate == LOCAL_CRATE
}
pub fn make<FN>(krate: CrateNum, start_index: DefIndex, mut get_key: FN) -> DefPath
where
FN: FnMut(DefIndex) -> DefKey,

View file

@ -3,7 +3,6 @@ use crate::def_id::DefId;
crate use crate::hir_id::HirId;
use crate::{itemlikevisit, LangItem};
use rustc_ast::node_id::NodeMap;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
use rustc_ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
@ -306,10 +305,6 @@ impl GenericArgs<'_> {
Self { args: &[], bindings: &[], parenthesized: false }
}
pub fn is_empty(&self) -> bool {
self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
}
pub fn inputs(&self) -> &[Ty<'_>] {
if self.parenthesized {
for arg in self.args {
@ -467,23 +462,6 @@ impl Generics<'hir> {
}
}
pub fn own_counts(&self) -> GenericParamCount {
// We could cache this as a property of `GenericParamCount`, but
// the aim is to refactor this away entirely eventually and the
// presence of this method will be a constant reminder.
let mut own_counts: GenericParamCount = Default::default();
for param in self.params {
match param.kind {
GenericParamKind::Lifetime { .. } => own_counts.lifetimes += 1,
GenericParamKind::Type { .. } => own_counts.types += 1,
GenericParamKind::Const { .. } => own_counts.consts += 1,
};
}
own_counts
}
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'_>> {
for param in self.params {
if name == param.name.ident().name {
@ -2679,8 +2657,6 @@ pub struct Upvar {
pub span: Span,
}
pub type CaptureModeMap = NodeMap<CaptureBy>;
// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
// has length > 0 if the trait is found through an chain of imports, starting with the
// import/use statement in the scope where the trait is used.

View file

@ -45,5 +45,3 @@ pub const CRATE_HIR_ID: HirId = HirId {
owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
local_id: ItemLocalId::from_u32(0),
};
pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;

View file

@ -58,25 +58,6 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
}
impl hir::Pat<'_> {
pub fn is_refutable(&self) -> bool {
match self.kind {
PatKind::Lit(_)
| PatKind::Range(..)
| PatKind::Path(hir::QPath::Resolved(Some(..), _) | hir::QPath::TypeRelative(..)) => {
true
}
PatKind::Path(hir::QPath::Resolved(_, ref path))
| PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..)
| PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => match path.res {
Res::Def(DefKind::Variant, _) => true,
_ => false,
},
PatKind::Slice(..) => true,
_ => false,
}
}
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, Ident)) {
@ -117,15 +98,6 @@ impl hir::Pat<'_> {
})
}
/// Checks if the pattern contains any patterns that bind something to
/// an ident or wildcard, e.g., `foo`, or `Foo(_)`, `foo @ Bar(..)`,
pub fn contains_bindings_or_wild(&self) -> bool {
self.satisfies(|p| match p.kind {
PatKind::Binding(..) | PatKind::Wild => true,
_ => false,
})
}
/// Checks if the pattern satisfies the given predicate on some sub-pattern.
fn satisfies(&self, pred: impl Fn(&hir::Pat<'_>) -> bool) -> bool {
let mut satisfies = false;

View file

@ -44,9 +44,6 @@ pub trait PpAnn {
fn nested(&self, _state: &mut State<'_>, _nested: Nested) {}
fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {}
fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {}
fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item<'_>> {
None
}
}
pub struct NoAnn;
@ -54,9 +51,6 @@ impl PpAnn for NoAnn {}
pub const NO_ANN: &dyn PpAnn = &NoAnn;
impl PpAnn for hir::Crate<'_> {
fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item<'_>> {
Some(self.item(item))
}
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
Nested::Item(id) => state.print_item(self.item(id.id)),
@ -141,6 +135,9 @@ impl std::ops::DerefMut for State<'_> {
}
impl<'a> PrintState<'a> for State<'a> {
fn insert_extra_parens(&self) -> bool {
true
}
fn comments(&mut self) -> &mut Option<Comments<'a>> {
&mut self.comments
}

View file

@ -113,13 +113,6 @@ impl Default for RegionckMode {
}
impl RegionckMode {
pub fn suppressed(self) -> bool {
match self {
Self::Solve => false,
Self::Erase { suppress_errors } => suppress_errors,
}
}
/// Indicates that the MIR borrowck will repeat these region
/// checks, so we should ignore errors if NLL is (unconditionally)
/// enabled.
@ -420,15 +413,6 @@ pub enum SubregionOrigin<'tcx> {
#[cfg(target_arch = "x86_64")]
static_assert_size!(SubregionOrigin<'_>, 32);
/// Places that type/region parameters can appear.
#[derive(Clone, Copy, Debug)]
pub enum ParameterOrigin {
Path, // foo::bar
MethodCall, // foo.bar() <-- parameters on impl providing bar()
OverloadedOperator, // a + b when overloaded
OverloadedDeref, // *a when overloaded
}
/// Times when we replace late-bound regions with variables:
#[derive(Clone, Copy, Debug)]
pub enum LateBoundRegionConversionTime {
@ -508,21 +492,6 @@ pub enum NLLRegionVariableOrigin {
},
}
impl NLLRegionVariableOrigin {
pub fn is_universal(self) -> bool {
match self {
NLLRegionVariableOrigin::FreeRegion => true,
NLLRegionVariableOrigin::Placeholder(..) => true,
NLLRegionVariableOrigin::Existential { .. } => false,
NLLRegionVariableOrigin::RootEmptyRegion => false,
}
}
pub fn is_existential(self) -> bool {
!self.is_universal()
}
}
// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
#[derive(Copy, Clone, Debug)]
pub enum FixupError<'tcx> {

View file

@ -28,7 +28,6 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use std::fmt::Debug;
@ -119,12 +118,6 @@ pub trait TypeRelatingDelegate<'tcx> {
fn forbid_inference_vars() -> bool;
}
#[derive(Clone, Debug)]
struct ScopesAndKind<'tcx> {
scopes: Vec<BoundRegionScope<'tcx>>,
kind: GenericArg<'tcx>,
}
#[derive(Clone, Debug, Default)]
struct BoundRegionScope<'tcx> {
map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
@ -341,7 +334,7 @@ where
// been fully instantiated and hence the set of scopes we have
// doesn't matter -- just to be sure, put an empty vector
// in there.
let old_a_scopes = ::std::mem::take(pair.vid_scopes(self));
let old_a_scopes = std::mem::take(pair.vid_scopes(self));
// Relate the generalized kind to the original one.
let result = pair.relate_generalized_ty(self, generalized_ty);
@ -680,7 +673,7 @@ where
// itself occurs. Note that `'b` and `'c` must both
// include P. At the point, the call works because of
// subtyping (i.e., `&'b u32 <: &{P} u32`).
let variance = ::std::mem::replace(&mut self.ambient_variance, ty::Variance::Covariant);
let variance = std::mem::replace(&mut self.ambient_variance, ty::Variance::Covariant);
self.relate(a.skip_binder(), b.skip_binder())?;
@ -709,7 +702,7 @@ where
// Reset ambient variance to contravariance. See the
// covariant case above for an explanation.
let variance =
::std::mem::replace(&mut self.ambient_variance, ty::Variance::Contravariant);
std::mem::replace(&mut self.ambient_variance, ty::Variance::Contravariant);
self.relate(a.skip_binder(), b.skip_binder())?;

View file

@ -110,7 +110,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// Trait queries just want to pass back type obligations "as is"
pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> {
::std::mem::take(&mut self.inner.borrow_mut().region_obligations)
std::mem::take(&mut self.inner.borrow_mut().region_obligations)
}
/// Process the region obligations that must be proven (during

View file

@ -59,9 +59,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
#[cfg(target_arch = "x86_64")]
static_assert_size!(PredicateObligation<'_>, 32);
pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;

View file

@ -551,6 +551,10 @@ fn write_out_deps(
.map(|fmap| escape_dep_filename(&fmap.unmapped_path.as_ref().unwrap_or(&fmap.name)))
.collect();
if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
files.push(backend.to_string());
}
if sess.binary_dep_depinfo() {
boxed_resolver.borrow().borrow_mut().access(|resolver| {
for cnum in resolver.cstore().crates_untracked() {

View file

@ -3,6 +3,7 @@ use crate::passes::{self, BoxedResolver, QueryContext};
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::ErrorReported;
use rustc_hir::def_id::LOCAL_CRATE;
@ -13,7 +14,8 @@ use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::steal::Steal;
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
use rustc_session::config::{OutputFilenames, OutputType};
use rustc_serialize::json;
use rustc_session::config::{self, OutputFilenames, OutputType};
use rustc_session::{output::find_crate_name, Session};
use rustc_span::symbol::sym;
use std::any::Any;
@ -331,6 +333,7 @@ impl<'tcx> Queries<'tcx> {
pub fn linker(&'tcx self) -> Result<Linker> {
let dep_graph = self.dep_graph()?;
let prepare_outputs = self.prepare_outputs()?;
let crate_hash = self.global_ctxt()?.peek_mut().enter(|tcx| tcx.crate_hash(LOCAL_CRATE));
let ongoing_codegen = self.ongoing_codegen()?;
let sess = self.session().clone();
@ -340,6 +343,7 @@ impl<'tcx> Queries<'tcx> {
sess,
dep_graph: dep_graph.peek().clone(),
prepare_outputs: prepare_outputs.take(),
crate_hash,
ongoing_codegen: ongoing_codegen.take(),
codegen_backend,
})
@ -350,18 +354,31 @@ pub struct Linker {
sess: Lrc<Session>,
dep_graph: DepGraph,
prepare_outputs: OutputFilenames,
crate_hash: Svh,
ongoing_codegen: Box<dyn Any>,
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
}
impl Linker {
pub fn link(self) -> Result<()> {
let codegen_results =
self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess, &self.dep_graph)?;
let prof = self.sess.prof.clone();
let (codegen_results, work_products) =
self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess)?;
self.sess.compile_status()?;
let sess = &self.sess;
let dep_graph = self.dep_graph;
sess.time("serialize_work_products", || {
rustc_incremental::save_work_product_index(&sess, &dep_graph, work_products)
});
let prof = self.sess.prof.clone();
prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph));
// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
rustc_incremental::finalize_session_directory(&self.sess, self.crate_hash);
if !self
.sess
.opts
@ -371,6 +388,19 @@ impl Linker {
{
return Ok(());
}
if sess.opts.debugging_opts.no_link {
// FIXME: use a binary format to encode the `.rlink` file
let rlink_data = json::encode(&codegen_results).map_err(|err| {
sess.fatal(&format!("failed to encode rlink: {}", err));
})?;
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
std::fs::write(&rlink_file, rlink_data).map_err(|err| {
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
})?;
return Ok(());
}
self.codegen_backend.link(&self.sess, codegen_results, &self.prepare_outputs)
}
}

View file

@ -585,6 +585,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(symbol_mangling_version, SymbolManglingVersion::V0);
tracked!(teach, true);
tracked!(thinlto, Some(true));
tracked!(tune_cpu, Some(String::from("abc")));
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
tracked!(treat_err_as_bug, Some(1));
tracked!(unleash_the_miri_inside_of_you, true);

View file

@ -187,7 +187,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
config = config.stack_size(size);
}
let with_pool = move |pool: &rayon::ThreadPool| pool.install(move || f());
let with_pool = move |pool: &rayon::ThreadPool| pool.install(f);
rustc_span::with_session_globals(edition, || {
rustc_span::SESSION_GLOBALS.with(|session_globals| {

View file

@ -48,6 +48,7 @@ impl Token {
}
/// Enum representing common lexeme types.
// perf note: Changing all `usize` to `u32` doesn't change performance. See #77629
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum TokenKind {
// Multi-char tokens:
@ -160,6 +161,7 @@ pub enum LiteralKind {
/// - `r##~"abcde"##`: `InvalidStarter`
/// - `r###"abcde"##`: `NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)`
/// - Too many `#`s (>65535): `TooManyDelimiters`
// perf note: It doesn't matter that this makes `Token` 36 bytes bigger. See #77629
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum RawStrError {
/// Non `#` characters exist between `r` and `"` eg. `r#~"..`
@ -689,7 +691,12 @@ impl Cursor<'_> {
let mut max_hashes = 0;
// Count opening '#' symbols.
let n_start_hashes = self.eat_while(|c| c == '#');
let mut eaten = 0;
while self.first() == '#' {
eaten += 1;
self.bump();
}
let n_start_hashes = eaten;
// Check that string is started.
match self.bump() {
@ -724,16 +731,11 @@ impl Cursor<'_> {
// Note that this will not consume extra trailing `#` characters:
// `r###"abcde"####` is lexed as a `RawStr { n_hashes: 3 }`
// followed by a `#` token.
let mut hashes_left = n_start_hashes;
let is_closing_hash = |c| {
if c == '#' && hashes_left != 0 {
hashes_left -= 1;
true
} else {
false
let mut n_end_hashes = 0;
while self.first() == '#' && n_end_hashes < n_start_hashes {
n_end_hashes += 1;
self.bump();
}
};
let n_end_hashes = self.eat_while(is_closing_hash);
if n_end_hashes == n_start_hashes {
return (n_start_hashes, None);
@ -807,17 +809,9 @@ impl Cursor<'_> {
}
/// Eats symbols while predicate returns true or until the end of file is reached.
/// Returns amount of eaten symbols.
fn eat_while<F>(&mut self, mut predicate: F) -> usize
where
F: FnMut(char) -> bool,
{
let mut eaten: usize = 0;
fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
while predicate(self.first()) && !self.is_eof() {
eaten += 1;
self.bump();
}
eaten
}
}

View file

@ -711,10 +711,6 @@ impl<'tcx> LateContext<'tcx> {
}
}
pub fn current_lint_root(&self) -> hir::HirId {
self.last_node_with_lint_attrs
}
/// Check if a `DefId`'s path matches the given absolute type path usage.
///
/// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`;

View file

@ -64,8 +64,8 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS,
EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS,
EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS,
MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::Span;
@ -311,7 +311,8 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
PRIVATE_INTRA_DOC_LINKS,
INVALID_CODEBLOCK_ATTRIBUTES,
MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS
PRIVATE_DOC_TESTS,
INVALID_HTML_TAGS
);
// Register renamed and removed lints.

View file

@ -304,7 +304,7 @@ fn lint_int_literal<'tcx>(
t: ast::IntTy,
v: u128,
) {
let int_type = t.normalize(cx.sess().target.ptr_width);
let int_type = t.normalize(cx.sess().target.pointer_width);
let (min, max) = int_ty_range(int_type);
let max = max as u128;
let negative = type_limits.negated_expr_id == Some(e.hir_id);
@ -352,7 +352,7 @@ fn lint_uint_literal<'tcx>(
lit: &hir::Lit,
t: ast::UintTy,
) {
let uint_type = t.normalize(cx.sess().target.ptr_width);
let uint_type = t.normalize(cx.sess().target.pointer_width);
let (min, max) = uint_ty_range(uint_type);
let lit_val: u128 = match lit.node {
// _v is u8, within range by definition

View file

@ -70,7 +70,7 @@ fn main() {
let host = env::var("HOST").expect("HOST was not set");
let is_crossed = target != host;
let mut optional_components = vec![
let optional_components = &[
"x86",
"arm",
"aarch64",
@ -85,6 +85,7 @@ fn main() {
"sparc",
"nvptx",
"hexagon",
"riscv",
];
let mut version_cmd = Command::new(&llvm_config);
@ -94,13 +95,9 @@ fn main() {
let (major, _minor) = if let (Some(major), Some(minor)) = (parts.next(), parts.next()) {
(major, minor)
} else {
(6, 0)
(8, 0)
};
if major > 6 {
optional_components.push("riscv");
}
let required_components = &[
"ipo",
"bitreader",

Some files were not shown because too many files have changed in this diff Show more