Merge branch 'master' into dedup

This commit is contained in:
Soveu 2021-03-15 21:51:38 +01:00 committed by GitHub
commit 96d6f22a8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2312 changed files with 62987 additions and 39998 deletions

46
.github/ISSUE_TEMPLATE/diagnostics.md vendored Normal file
View File

@ -0,0 +1,46 @@
---
name: Diagnostic issue
about: Create a bug report or feature request for a change to `rustc`'s error output
labels: A-diagnostics, T-compiler
---
<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->
Given the following code: <!-- Please provide a link to play.rust-lang.org -->
```rust
<code>
```
The current output is:
```
<rustc output>
```
<!-- The following is not always necessary. -->
Ideally the output should look like:
```
<proposed output>
```
<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->
<!--
If dramatically different output is caused by small changes, consider also
adding them here.
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions. The output might also be
different depending on the Edition.
-->

View File

@ -63,7 +63,7 @@ jobs:
run: "echo \"[CI_PR_NUMBER=$num]\""
env:
num: "${{ github.event.number }}"
if: "success() && !env.SKIP_JOBS && github.event_name == 'pull_request'"
if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'"
- name: add extra environment variables
run: src/ci/scripts/setup-environment.sh
env:
@ -425,7 +425,7 @@ jobs:
run: "echo \"[CI_PR_NUMBER=$num]\""
env:
num: "${{ github.event.number }}"
if: "success() && !env.SKIP_JOBS && github.event_name == 'pull_request'"
if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'"
- name: add extra environment variables
run: src/ci/scripts/setup-environment.sh
env:
@ -532,7 +532,7 @@ jobs:
run: "echo \"[CI_PR_NUMBER=$num]\""
env:
num: "${{ github.event.number }}"
if: "success() && !env.SKIP_JOBS && github.event_name == 'pull_request'"
if: "success() && !env.SKIP_JOB && github.event_name == 'pull_request'"
- name: add extra environment variables
run: src/ci/scripts/setup-environment.sh
env:

4
.gitignore vendored
View File

@ -7,6 +7,8 @@
# configure your local ignore list.
# FIXME: This needs cleanup.
*~
*.swp
*.swo
.#*
.DS_Store
.cproject
@ -50,4 +52,6 @@ Session.vim
.cargo
!/src/test/run-make/thumb-none-qemu/example/.cargo
no_llvm_build
**node_modules
**package-lock.json
# Before adding new lines, see the comment at the top.

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-2021-01-05
branch = rustc/12.0-2021-02-03
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git

View File

@ -235,6 +235,7 @@ Philipp Matthias Schäfer <philipp.matthias.schaefer@posteo.de>
Przemysław Wesołek <jest@go.art.pl> Przemek Wesołek <jest@go.art.pl>
Rafael Ávila de Espíndola <respindola@mozilla.com> Rafael Avila de Espindola <espindola@dream.(none)>
Ralph Giles <giles@thaumas.net> Ralph Giles <giles@mozilla.com>
Ramkumar Ramachandra <r@artagnon.com> <artagnon@gmail.com>
Renato Riccieri Santos Zannon <renato@rrsz.com.br>
Richard Diamond <wichard@vitalitystudios.com> <wichard@hahbee.co>
Rob Arnold <robarnold@cs.cmu.edu>

View File

@ -1,8 +1,31 @@
# Contributing to Rust
Thank you for your interest in contributing to Rust!
Thank you for your interest in contributing to Rust! There are many ways to contribute
and we appreciate all of them.
To get started, read the [Contributing to Rust] chapter of the [rustc-dev-guide].
Documentation for contributing to Rust is located in the [Guide to Rustc Development](https://rustc-dev-guide.rust-lang.org/),
commonly known as the [rustc-dev-guide]. Despite the name, this guide documents
not just how to develop rustc (the Rust compiler), but also how to contribute to any part
of the Rust project.
To get started with contributing, please read the [Contributing to Rust] chapter of the guide.
That chapter explains how to get your development environment set up and how to get help.
## About the [rustc-dev-guide]
The [rustc-dev-guide] is meant to help document how rustc the Rust compiler works,
as well as to help new contributors get involved in rustc development. It is recommend
to read and understand the [rustc-dev-guide] before making a contribution. This guide
talks about the different bots in the Rust ecosystem, the Rust development tools,
bootstrapping, the compiler architecture, source code representation, and more.
## [Getting help](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions)
There are many ways you can get help when you're stuck. Rust has many platforms for this:
[internals], [rust-zulip], and [rust-discord]. It is recommended to ask for help on
the [rust-zulip], but any of these platforms are a great way to seek help and even
find a mentor! You can learn more about asking questions and getting help in the
[Asking Questions](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) chapter of the [rustc-dev-guide].
## Bug reports
@ -13,3 +36,6 @@ refer to [this section][contributing-bug-reports] and [open an issue][issue temp
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
[contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports
[issue template]: https://github.com/rust-lang/rust/issues/new/choose
[internals]: https://internals.rust-lang.org
[rust-discord]: http://discord.gg/rust-lang
[rust-zulip]: https://rust-lang.zulipchat.com

View File

@ -37,7 +37,7 @@ version = "0.0.0"
dependencies = [
"compiler_builtins",
"core",
"rand",
"rand 0.7.3",
"rand_xorshift",
]
@ -95,12 +95,6 @@ version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
[[package]]
name = "arc-swap"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
[[package]]
name = "array_tool"
version = "1.0.3"
@ -177,7 +171,7 @@ dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array 0.12.3",
"generic-array 0.12.4",
]
[[package]]
@ -285,7 +279,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
[[package]]
name = "cargo"
version = "0.52.0"
version = "0.53.0"
dependencies = [
"anyhow",
"atty",
@ -325,6 +319,7 @@ dependencies = [
"openssl",
"percent-encoding 2.1.0",
"pretty_env_logger",
"rand 0.8.3",
"rustc-workspace-hack",
"rustfix",
"same-file",
@ -533,13 +528,15 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.15"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi 0.3.9",
]
[[package]]
@ -565,14 +562,15 @@ dependencies = [
"cargo_metadata 0.12.0",
"clippy-mini-macro-test",
"clippy_lints",
"compiletest_rs",
"compiletest_rs 0.6.0",
"derive-new",
"regex",
"rustc-workspace-hack",
"rustc_tools_util 0.2.0",
"semver 0.11.0",
"serde",
"tempfile",
"tester",
"tester 0.9.0",
]
[[package]]
@ -584,6 +582,7 @@ name = "clippy_lints"
version = "0.1.52"
dependencies = [
"cargo_metadata 0.12.0",
"clippy_utils",
"if_chain",
"itertools 0.9.0",
"pulldown-cmark 0.8.0",
@ -600,6 +599,20 @@ dependencies = [
"url 2.1.1",
]
[[package]]
name = "clippy_utils"
version = "0.1.52"
dependencies = [
"if_chain",
"itertools 0.9.0",
"regex-syntax",
"rustc-semver",
"serde",
"smallvec 1.6.1",
"toml",
"unicode-normalization",
]
[[package]]
name = "cloudabi"
version = "0.1.0"
@ -661,6 +674,7 @@ dependencies = [
name = "compiletest"
version = "0.0.0"
dependencies = [
"colored",
"diff",
"getopts",
"glob",
@ -673,6 +687,7 @@ dependencies = [
"serde_json",
"tracing",
"tracing-subscriber",
"unified-diff",
"walkdir",
"winapi 0.3.9",
]
@ -695,7 +710,30 @@ dependencies = [
"serde_derive",
"serde_json",
"tempfile",
"tester",
"tester 0.7.0",
"winapi 0.3.9",
]
[[package]]
name = "compiletest_rs"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0086d6ad78cf409c3061618cd98e2789d5c9ce598fc9651611cf62eae0a599cb"
dependencies = [
"diff",
"filetime",
"getopts",
"lazy_static",
"libc",
"log",
"miow 0.3.6",
"regex",
"rustfix",
"serde",
"serde_derive",
"serde_json",
"tempfile",
"tester 0.9.0",
"winapi 0.3.9",
]
@ -715,7 +753,7 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
name = "core"
version = "0.0.0"
dependencies = [
"rand",
"rand 0.7.3",
]
[[package]]
@ -801,15 +839,6 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
dependencies = [
"crossbeam-utils 0.6.6",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.3"
@ -821,16 +850,6 @@ dependencies = [
"maybe-uninit",
]
[[package]]
name = "crossbeam-utils"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
dependencies = [
"cfg-if 0.1.10",
"lazy_static",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
@ -866,6 +885,16 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "cstr"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "ctor"
version = "0.1.15"
@ -953,7 +982,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array 0.12.3",
"generic-array 0.12.4",
]
[[package]]
@ -984,6 +1013,16 @@ dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if 1.0.0",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys"
version = "0.3.5"
@ -991,7 +1030,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
dependencies = [
"libc",
"redox_users",
"redox_users 0.3.4",
"winapi 0.3.9",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users 0.4.0",
"winapi 0.3.9",
]
@ -1115,7 +1165,7 @@ checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
dependencies = [
"cfg-if 0.1.10",
"libc",
"redox_syscall",
"redox_syscall 0.1.57",
"winapi 0.3.9",
]
@ -1325,9 +1375,9 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.12.3"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
@ -1589,7 +1639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
dependencies = [
"bitmaps",
"rand_core",
"rand_core 0.5.1",
"rand_xoshiro",
"sized-chunks",
"typenum",
@ -1698,7 +1748,7 @@ dependencies = [
"regex",
"serde",
"serde_json",
"shlex",
"shlex 0.1.1",
]
[[package]]
@ -1794,7 +1844,7 @@ dependencies = [
"lazy_static",
"log",
"parking_lot",
"rand",
"rand 0.7.3",
"serde",
]
@ -1839,9 +1889,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.85"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
dependencies = [
"rustc-std-workspace-core",
]
@ -2053,9 +2103,9 @@ dependencies = [
[[package]]
name = "mdbook"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d948b64449003363127ed6c6139f03273982c3fe97da4cb3dee933e38ce38f"
checksum = "28f6a882f3880ec68e96f60d6b543c34941e2f307ad10e2992e4db9acfe96529"
dependencies = [
"ammonia",
"anyhow",
@ -2073,18 +2123,21 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"shlex",
"shlex 1.0.0",
"tempfile",
"toml",
]
[[package]]
name = "measureme"
version = "9.0.0"
version = "9.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22bf8d885d073610aee20e7fa205c4341ed32a761dbde96da5fd96301a8d3e82"
checksum = "4a98e07fe802486895addb2b5467f33f205e82c426bfaf350f5d8109b137767c"
dependencies = [
"log",
"memmap",
"parking_lot",
"perf-event-open-sys",
"rustc-hash",
"smallvec 1.6.1",
]
@ -2138,9 +2191,9 @@ dependencies = [
[[package]]
name = "minifier"
version = "0.0.33"
version = "0.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70bf0db2475f5e627787da77ca52fe33c294063f49f4134b8bc662eedb5e7332"
checksum = "6cdf618de5c9c98d4a7b2e0d1f1e44f82a19196cfd94040bb203621c25d28d98"
dependencies = [
"macro-utils",
]
@ -2226,13 +2279,13 @@ name = "miri"
version = "0.1.0"
dependencies = [
"colored",
"compiletest_rs",
"compiletest_rs 0.5.0",
"env_logger 0.7.1",
"getrandom 0.2.0",
"hex 0.4.2",
"libc",
"log",
"rand",
"rand 0.7.3",
"rustc-workspace-hack",
"rustc_version",
"shell-escape",
@ -2432,7 +2485,7 @@ dependencies = [
"log",
"mio-named-pipes",
"miow 0.3.6",
"rand",
"rand 0.7.3",
"tokio",
"winapi 0.3.9",
]
@ -2458,7 +2511,7 @@ dependencies = [
"cloudabi",
"instant",
"libc",
"redox_syscall",
"redox_syscall 0.1.57",
"smallvec 1.6.1",
"winapi 0.3.9",
]
@ -2481,6 +2534,15 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "perf-event-open-sys"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce9bedf5da2c234fdf2391ede2b90fabf585355f33100689bc364a3ea558561a"
dependencies = [
"libc",
]
[[package]]
name = "pest"
version = "2.1.3"
@ -2560,7 +2622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand",
"rand 0.7.3",
]
[[package]]
@ -2807,12 +2869,24 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.14",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc 0.2.0",
"rand_pcg",
]
[[package]]
name = "rand"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
dependencies = [
"libc",
"rand_chacha 0.3.0",
"rand_core 0.6.2",
"rand_hc 0.3.0",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
@ -2820,7 +2894,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.5.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core 0.6.2",
]
[[package]]
@ -2832,13 +2916,31 @@ dependencies = [
"getrandom 0.1.14",
]
[[package]]
name = "rand_core"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
dependencies = [
"getrandom 0.2.0",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
"rand_core 0.5.1",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core 0.6.2",
]
[[package]]
@ -2847,7 +2949,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core",
"rand_core 0.5.1",
]
[[package]]
@ -2856,7 +2958,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
dependencies = [
"rand_core",
"rand_core 0.5.1",
]
[[package]]
@ -2865,7 +2967,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
dependencies = [
"rand_core",
"rand_core 0.5.1",
]
[[package]]
@ -2887,7 +2989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
dependencies = [
"crossbeam-deque",
"crossbeam-queue 0.2.3",
"crossbeam-queue",
"crossbeam-utils 0.7.2",
"lazy_static",
"num_cpus",
@ -2899,6 +3001,15 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.3.4"
@ -2906,10 +3017,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
dependencies = [
"getrandom 0.1.14",
"redox_syscall",
"redox_syscall 0.1.57",
"rust-argon2",
]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom 0.2.0",
"redox_syscall 0.2.5",
]
[[package]]
name = "regex"
version = "1.4.3"
@ -2978,7 +3099,7 @@ dependencies = [
"num_cpus",
"ordslice",
"racer",
"rand",
"rand 0.7.3",
"rayon",
"regex",
"rls-analysis",
@ -3049,7 +3170,7 @@ dependencies = [
"env_logger 0.7.1",
"futures 0.3.12",
"log",
"rand",
"rand 0.7.3",
"rls-data",
"rls-ipc",
"serde",
@ -3436,9 +3557,9 @@ dependencies = [
[[package]]
name = "rustc-rayon"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f32767f90d938f1b7199a174ef249ae1924f6e5bbdb9d112fea141e016f25b3a"
checksum = "ed7d6a39f8bfd4421ce720918234d1e672b83824c91345b47c93746839cf1629"
dependencies = [
"crossbeam-deque",
"either",
@ -3447,13 +3568,13 @@ dependencies = [
[[package]]
name = "rustc-rayon-core"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea2427831f0053ea3ea73559c8eabd893133a51b251d142bacee53c62a288cb3"
checksum = "e94187d9ea3e8c38fafdbc38acb94eafa7ce155867f6ccb13830466a0d0db8c6"
dependencies = [
"crossbeam-deque",
"crossbeam-queue 0.1.2",
"crossbeam-utils 0.6.6",
"crossbeam-queue",
"crossbeam-utils 0.7.2",
"lazy_static",
"num_cpus",
]
@ -3516,6 +3637,7 @@ dependencies = [
name = "rustc_arena"
version = "0.0.0"
dependencies = [
"rustc_data_structures",
"smallvec 1.6.1",
]
@ -3620,6 +3742,7 @@ name = "rustc_codegen_llvm"
version = "0.0.0"
dependencies = [
"bitflags",
"cstr",
"libc",
"measureme",
"rustc-demangle",
@ -3654,7 +3777,6 @@ dependencies = [
"jobserver",
"libc",
"memmap",
"num_cpus",
"pathdiff",
"rustc_apfloat",
"rustc_ast",
@ -3725,6 +3847,7 @@ dependencies = [
"rustc_metadata",
"rustc_middle",
"rustc_mir",
"rustc_mir_build",
"rustc_parse",
"rustc_plugin_impl",
"rustc_save_analysis",
@ -3732,6 +3855,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_typeck",
"tracing",
"tracing-subscriber",
"tracing-tree",
@ -3829,7 +3953,7 @@ dependencies = [
name = "rustc_incremental"
version = "0.0.0"
dependencies = [
"rand",
"rand 0.7.3",
"rustc_ast",
"rustc_data_structures",
"rustc_fs_util",
@ -3878,6 +4002,7 @@ version = "0.0.0"
dependencies = [
"libc",
"rustc-rayon",
"rustc-rayon-core",
"rustc_ast",
"rustc_ast_lowering",
"rustc_ast_passes",
@ -3890,6 +4015,7 @@ dependencies = [
"rustc_expand",
"rustc_hir",
"rustc_incremental",
"rustc_index",
"rustc_lint",
"rustc_metadata",
"rustc_middle",
@ -3899,6 +4025,7 @@ dependencies = [
"rustc_passes",
"rustc_plugin_impl",
"rustc_privacy",
"rustc_query_impl",
"rustc_resolve",
"rustc_serialize",
"rustc_session",
@ -4120,6 +4247,7 @@ name = "rustc_passes"
version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
@ -4165,6 +4293,29 @@ dependencies = [
"tracing",
]
[[package]]
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
"measureme",
"rustc-rayon-core",
"rustc_ast",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_target",
"tracing",
]
[[package]]
name = "rustc_query_system"
version = "0.0.0"
@ -4177,6 +4328,7 @@ dependencies = [
"rustc_index",
"rustc_macros",
"rustc_serialize",
"rustc_session",
"rustc_span",
"smallvec 1.6.1",
"tracing",
@ -4427,6 +4579,9 @@ dependencies = [
"serde_json",
"smallvec 1.6.1",
"tempfile",
"tracing",
"tracing-subscriber",
"tracing-tree",
]
[[package]]
@ -4434,6 +4589,7 @@ name = "rustdoc-json-types"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]
[[package]]
@ -4509,6 +4665,12 @@ dependencies = [
"unicode_categories",
]
[[package]]
name = "rustversion"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
[[package]]
name = "ryu"
version = "1.0.5"
@ -4595,7 +4757,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser 0.10.1",
"semver-parser 0.10.2",
"serde",
]
@ -4607,9 +4769,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "semver-parser"
version = "0.10.1"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ef146c2ad5e5f4b037cd6ce2ebb775401729b19a82040c1beac9d36c7d1428"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
@ -4706,9 +4868,9 @@ dependencies = [
[[package]]
name = "sharded-slab"
version = "0.0.9"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
dependencies = [
"lazy_static",
]
@ -4726,12 +4888,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
name = "signal-hook-registry"
version = "1.2.1"
name = "shlex"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
[[package]]
name = "signal-hook-registry"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
dependencies = [
"arc-swap",
"libc",
]
@ -4743,9 +4910,9 @@ checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
[[package]]
name = "sized-chunks"
version = "0.6.2"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
checksum = "65e65d6a9f13cd78f361ea5a2cf53a45d67cdda421ba0316b9be101560f3d207"
dependencies = [
"bitmaps",
"typenum",
@ -4786,7 +4953,7 @@ checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d"
dependencies = [
"cfg-if 0.1.10",
"libc",
"redox_syscall",
"redox_syscall 0.1.57",
"winapi 0.3.9",
]
@ -4828,7 +4995,7 @@ dependencies = [
"panic_abort",
"panic_unwind",
"profiler_builtins",
"rand",
"rand 0.7.3",
"rustc-demangle",
"unwind",
"wasi",
@ -4947,7 +5114,7 @@ checksum = "c8a4c1d0bee3230179544336c15eefb563cf0302955d962e456542323e8c2e8a"
dependencies = [
"filetime",
"libc",
"redox_syscall",
"redox_syscall 0.1.57",
"xattr",
]
@ -4959,8 +5126,8 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if 0.1.10",
"libc",
"rand",
"redox_syscall",
"rand 0.7.3",
"redox_syscall 0.1.57",
"remove_dir_all",
"winapi 0.3.9",
]
@ -4994,6 +5161,17 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi 0.3.9",
]
[[package]]
name = "termcolor"
version = "1.1.0"
@ -5039,6 +5217,19 @@ dependencies = [
"term 0.6.1",
]
[[package]]
name = "tester"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0639d10d8f4615f223a57275cf40f9bdb7cfbb806bcb7f7cc56e3beb55a576eb"
dependencies = [
"cfg-if 1.0.0",
"getopts",
"libc",
"num_cpus",
"term 0.7.0",
]
[[package]]
name = "textwrap"
version = "0.11.0"
@ -5172,20 +5363,21 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]]
name = "tracing"
version = "0.1.19"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
"pin-project-lite 0.2.4",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.11"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07"
dependencies = [
"proc-macro2",
"quote",
@ -5203,9 +5395,9 @@ dependencies = [
[[package]]
name = "tracing-log"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
dependencies = [
"lazy_static",
"log",
@ -5224,9 +5416,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
version = "0.2.13"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ef0a5e15477aa303afbfac3a44cba9b6430fdaad52423b1e6c0dbbe28c3eedd"
checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96"
dependencies = [
"ansi_term 0.12.1",
"chrono",
@ -5247,15 +5439,15 @@ dependencies = [
[[package]]
name = "tracing-tree"
version = "0.1.6"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43aac8afb493b08e1e1904956f7407c1e671b9c83b26a17e1bd83d6a3520e350"
checksum = "1712b40907f8d9bc2bc66763ab61dec914b7123d7149e59feb0d4e2a95fc4967"
dependencies = [
"ansi_term 0.12.1",
"atty",
"chrono",
"termcolor",
"tracing",
"tracing-log",
"tracing-subscriber",
]
@ -5360,6 +5552,15 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "unified-diff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "496a3d395ed0c30f411ceace4a91f7d93b148fb5a9b383d5d4cff7850f048d5f"
dependencies = [
"diff",
]
[[package]]
name = "unstable-book-gen"
version = "0.1.0"

View File

@ -31,7 +31,7 @@ by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild].
* `g++` 5.1 or later or `clang++` 3.5 or later
* `python` 3 or 2.7
* GNU `make` 3.81 or later
* `cmake` 3.4.3 or later
* `cmake` 3.13.4 or later
* `ninja`
* `curl`
* `git`
@ -90,7 +90,7 @@ build.
[MSYS2][msys2] can be used to easily build Rust on Windows:
[msys2]: https://msys2.github.io/
[msys2]: https://www.msys2.org/
1. Grab the latest [MSYS2 installer][msys2] and go through the installer.

View File

@ -43,6 +43,23 @@ The following previously stable methods are now `const`.
- [`IpAddr::is_ipv4`]
- [`IpAddr::is_ipv6`]
- [`IpAddr::is_unspecified`]
- [`IpAddr::is_loopback`]
- [`IpAddr::is_multicast`]
- [`Ipv4Addr::octets`]
- [`Ipv4Addr::is_loopback`]
- [`Ipv4Addr::is_private`]
- [`Ipv4Addr::is_link_local`]
- [`Ipv4Addr::is_multicast`]
- [`Ipv4Addr::is_broadcast`]
- [`Ipv4Addr::is_documentation`]
- [`Ipv4Addr::to_ipv6_compatible`]
- [`Ipv4Addr::to_ipv6_mapped`]
- [`Ipv6Addr::segments`]
- [`Ipv6Addr::is_unspecified`]
- [`Ipv6Addr::is_loopback`]
- [`Ipv6Addr::is_multicast`]
- [`Ipv6Addr::to_ipv4`]
- [`Layout::size`]
- [`Layout::align`]
- [`Layout::from_size_align`]
@ -51,7 +68,7 @@ The following previously stable methods are now `const`.
- `saturating_pow` for all integer types.
- `wrapping_pow` for all integer types.
- `next_power_of_two` for all unsigned integer types.
- `checked_power_of_two` for all unsigned integer types.
- `checked_next_power_of_two` for all unsigned integer types.
Cargo
-----------------------
@ -104,6 +121,23 @@ Compatibility Notes
[cargo/8725]: https://github.com/rust-lang/cargo/pull/8725
[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv4
[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv6
[`IpAddr::is_unspecified`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_unspecified
[`IpAddr::is_loopback`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_loopback
[`IpAddr::is_multicast`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_multicast
[`Ipv4Addr::octets`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.octets
[`Ipv4Addr::is_loopback`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_loopback
[`Ipv4Addr::is_private`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_private
[`Ipv4Addr::is_link_local`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_link_local
[`Ipv4Addr::is_multicast`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_multicast
[`Ipv4Addr::is_broadcast`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_broadcast
[`Ipv4Addr::is_documentation`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.is_documentation
[`Ipv4Addr::to_ipv6_compatible`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.to_ipv6_compatible
[`Ipv4Addr::to_ipv6_mapped`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.to_ipv6_mapped
[`Ipv6Addr::segments`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.segments
[`Ipv6Addr::is_unspecified`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_unspecified
[`Ipv6Addr::is_loopback`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_loopback
[`Ipv6Addr::is_multicast`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_multicast
[`Ipv6Addr::to_ipv4`]: https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.to_ipv4
[`Layout::align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align
[`Layout::from_size_align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.from_size_align
[`Layout::size`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.size

View File

@ -4,7 +4,7 @@ fn main() {
// Note that we're pulling in a static copy of jemalloc which means that to
// pull it in we need to actually reference its symbols for it to get
// linked. The two crates we link to here, std and rustc_driver, are both
// dynamic libraries. That means to pull in jemalloc we need to actually
// dynamic libraries. That means to pull in jemalloc we actually need to
// reference allocation symbols one way or another (as this file is the only
// object code in the rustc executable).
#[cfg(feature = "jemalloc-sys")]
@ -24,6 +24,20 @@ fn main() {
static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
#[used]
static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;
// On OSX, jemalloc doesn't directly override malloc/free, but instead
// registers itself with the allocator's zone APIs in a ctor. However,
// the linker doesn't seem to consider ctors as "used" when statically
// linking, so we need to explicitly depend on the function.
#[cfg(target_os = "macos")]
{
extern "C" {
fn _rjem_je_zone_register();
}
#[used]
static _F7: unsafe extern "C" fn() = _rjem_je_zone_register;
}
}
rustc_driver::set_sigpipe_handler();

View File

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

View File

@ -14,10 +14,10 @@
#![feature(dropck_eyepatch)]
#![feature(new_uninit)]
#![feature(maybe_uninit_slice)]
#![cfg_attr(bootstrap, feature(min_const_generics))]
#![feature(min_specialization)]
#![cfg_attr(test, feature(test))]
use rustc_data_structures::sync;
use smallvec::SmallVec;
use std::alloc::Layout;
@ -557,8 +557,19 @@ struct DropType {
obj: *mut u8,
}
unsafe fn drop_for_type<T>(to_drop: *mut u8) {
std::ptr::drop_in_place(to_drop as *mut T)
// SAFETY: we require `T: Send` before type-erasing into `DropType`.
#[cfg(parallel_compiler)]
unsafe impl sync::Send for DropType {}
impl DropType {
#[inline]
unsafe fn new<T: sync::Send>(obj: *mut T) -> Self {
unsafe fn drop_for_type<T>(to_drop: *mut u8) {
std::ptr::drop_in_place(to_drop as *mut T)
}
DropType { drop_fn: drop_for_type::<T>, obj: obj as *mut u8 }
}
}
impl Drop for DropType {
@ -586,21 +597,26 @@ pub struct DropArena {
impl DropArena {
#[inline]
pub unsafe fn alloc<T>(&self, object: T) -> &mut T {
pub unsafe fn alloc<T>(&self, object: T) -> &mut T
where
T: sync::Send,
{
let mem = self.arena.alloc_raw(Layout::new::<T>()) as *mut T;
// Write into uninitialized memory.
ptr::write(mem, object);
let result = &mut *mem;
// Record the destructor after doing the allocation as that may panic
// and would cause `object`'s destructor to run twice if it was recorded before.
self.destructors
.borrow_mut()
.push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 });
self.destructors.borrow_mut().push(DropType::new(result));
result
}
#[inline]
pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
pub unsafe fn alloc_from_iter<T, I>(&self, iter: I) -> &mut [T]
where
T: sync::Send,
I: IntoIterator<Item = T>,
{
let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
if vec.is_empty() {
return &mut [];
@ -621,8 +637,7 @@ impl DropArena {
// Record the destructors after doing the allocation as that may panic
// and would cause `object`'s destructor to run twice if it was recorded before.
for i in 0..len {
destructors
.push(DropType { drop_fn: drop_for_type::<T>, obj: start_ptr.add(i) as *mut u8 });
destructors.push(DropType::new(start_ptr.add(i)));
}
slice::from_raw_parts_mut(start_ptr, len)

View File

@ -486,8 +486,8 @@ pub struct WhereEqPredicate {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Crate {
pub module: Mod,
pub attrs: Vec<Attribute>,
pub items: Vec<P<Item>>,
pub span: Span,
/// The order of items in the HIR is unrelated to the order of
/// items in the AST. However, we generate proc macro harnesses
@ -915,16 +915,6 @@ impl Stmt {
}
}
pub fn tokens_mut(&mut self) -> Option<&mut LazyTokenStream> {
match self.kind {
StmtKind::Local(ref mut local) => local.tokens.as_mut(),
StmtKind::Item(ref mut item) => item.tokens.as_mut(),
StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => expr.tokens.as_mut(),
StmtKind::Empty => None,
StmtKind::MacCall(ref mut mac) => mac.tokens.as_mut(),
}
}
pub fn has_trailing_semicolon(&self) -> bool {
match &self.kind {
StmtKind::Semi(_) => true,
@ -1083,7 +1073,7 @@ pub struct Expr {
}
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Expr, 120);
impl Expr {
@ -1139,6 +1129,14 @@ impl Expr {
}
}
pub fn peel_parens(&self) -> &Expr {
let mut expr = self;
while let ExprKind::Paren(inner) = &expr.kind {
expr = &inner;
}
expr
}
/// Attempts to reparse as `Ty` (for diagnostic purposes).
pub fn to_ty(&self) -> Option<P<Ty>> {
let kind = match &self.kind {
@ -1979,7 +1977,7 @@ bitflags::bitflags! {
}
}
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
#[derive(Clone, PartialEq, PartialOrd, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
pub enum InlineAsmTemplatePiece {
String(String),
Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
@ -2067,7 +2065,7 @@ pub struct InlineAsm {
/// Inline assembly dialect.
///
/// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Hash, HashStable_Generic)]
pub enum LlvmAsmDialect {
Att,
Intel,
@ -2299,21 +2297,22 @@ impl FnRetTy {
}
}
/// Module declaration.
///
/// E.g., `mod foo;` or `mod foo { .. }`.
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
pub enum Inline {
Yes,
No,
}
/// Module item kind.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
/// to the last token in the external file.
pub inner: Span,
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
/// semantically by Rust.
pub unsafety: Unsafe,
pub items: Vec<P<Item>>,
/// `true` for `mod foo { .. }`; `false` for `mod foo;`.
pub inline: bool,
pub enum ModKind {
/// Module with inlined definition `mod foo { ... }`,
/// or with definition outlined to a separate file `mod foo;` and already loaded from it.
/// The inner span is from the first token past `{` to the last token until `}`,
/// or from the first to the last token in the loaded file.
Loaded(Vec<P<Item>>, Inline, Span),
/// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
Unloaded,
}
/// Foreign module declaration.
@ -2694,7 +2693,7 @@ pub enum ItemKind {
/// A use declaration item (`use`).
///
/// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
Use(P<UseTree>),
Use(UseTree),
/// A static item (`static`).
///
/// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
@ -2710,13 +2709,15 @@ pub enum ItemKind {
/// A module declaration (`mod`).
///
/// E.g., `mod foo;` or `mod foo { .. }`.
Mod(Mod),
/// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
/// semantically by Rust.
Mod(Unsafe, ModKind),
/// An external module (`extern`).
///
/// E.g., `extern {}` or `extern "C" {}`.
ForeignMod(ForeignMod),
/// Module-level inline assembly (from `global_asm!()`).
GlobalAsm(P<GlobalAsm>),
GlobalAsm(GlobalAsm),
/// A type alias (`type`).
///
/// E.g., `type Foo = Bar<u8>;`.
@ -2754,7 +2755,7 @@ pub enum ItemKind {
MacroDef(MacroDef),
}
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ItemKind, 112);
impl ItemKind {
@ -2828,7 +2829,7 @@ pub enum AssocItemKind {
MacCall(MacCall),
}
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(AssocItemKind, 72);
impl AssocItemKind {
@ -2880,7 +2881,7 @@ pub enum ForeignItemKind {
MacCall(MacCall),
}
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
impl From<ForeignItemKind> for ItemKind {
@ -2909,84 +2910,3 @@ impl TryFrom<ItemKind> for ForeignItemKind {
}
pub type ForeignItem = Item<ForeignItemKind>;
pub trait HasTokens {
/// Called by `Parser::collect_tokens` to store the collected
/// tokens inside an AST node
fn finalize_tokens(&mut self, tokens: LazyTokenStream);
}
impl<T: HasTokens + 'static> HasTokens for P<T> {
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
(**self).finalize_tokens(tokens);
}
}
impl<T: HasTokens> HasTokens for Option<T> {
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
if let Some(inner) = self {
inner.finalize_tokens(tokens);
}
}
}
impl HasTokens for Attribute {
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
match &mut self.kind {
AttrKind::Normal(_, attr_tokens) => {
if attr_tokens.is_none() {
*attr_tokens = Some(tokens);
}
}
AttrKind::DocComment(..) => {
panic!("Called finalize_tokens on doc comment attr {:?}", self)
}
}
}
}
impl HasTokens for Stmt {
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
let stmt_tokens = match self.kind {
StmtKind::Local(ref mut local) => &mut local.tokens,
StmtKind::Item(ref mut item) => &mut item.tokens,
StmtKind::Expr(ref mut expr) | StmtKind::Semi(ref mut expr) => &mut expr.tokens,
StmtKind::Empty => return,
StmtKind::MacCall(ref mut mac) => &mut mac.tokens,
};
if stmt_tokens.is_none() {
*stmt_tokens = Some(tokens);
}
}
}
macro_rules! derive_has_tokens {
($($ty:path),*) => { $(
impl HasTokens for $ty {
fn finalize_tokens(&mut self, tokens: LazyTokenStream) {
if self.tokens.is_none() {
self.tokens = Some(tokens);
}
}
}
)* }
}
derive_has_tokens! {
Item, Expr, Ty, AttrItem, Visibility, Path, Block, Pat
}
macro_rules! derive_has_attrs_no_tokens {
($($ty:path),*) => { $(
impl HasTokens for $ty {
fn finalize_tokens(&mut self, _tokens: LazyTokenStream) {}
}
)* }
}
// These ast nodes only support inert attributes, so they don't
// store tokens (since nothing can observe them)
derive_has_attrs_no_tokens! {
StructField, Arm,
Field, FieldPat, Variant, Param, GenericParam
}

View File

@ -0,0 +1,199 @@
use super::ptr::P;
use super::tokenstream::LazyTokenStream;
use super::{Arm, Field, FieldPat, GenericParam, Param, StructField, Variant};
use super::{AssocItem, Expr, ForeignItem, Item, Local};
use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
use super::{AttrVec, Attribute, Stmt, StmtKind};
/// An `AstLike` represents an AST node (or some wrapper around
/// and AST node) which stores some combination of attributes
/// and tokens.
pub trait AstLike: Sized {
fn attrs(&self) -> &[Attribute];
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>>;
}
impl<T: AstLike + 'static> AstLike for P<T> {
fn attrs(&self) -> &[Attribute] {
(**self).attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
(**self).visit_attrs(f);
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
(**self).tokens_mut()
}
}
fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec<Attribute>)) {
crate::mut_visit::visit_clobber(attrs, |attrs| {
let mut vec = attrs.into();
f(&mut vec);
vec.into()
});
}
impl AstLike for StmtKind {
fn attrs(&self) -> &[Attribute] {
match self {
StmtKind::Local(local) => local.attrs(),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.attrs(),
StmtKind::Item(item) => item.attrs(),
StmtKind::Empty => &[],
StmtKind::MacCall(mac) => &mac.attrs,
}
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
match self {
StmtKind::Local(local) => local.visit_attrs(f),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
StmtKind::Item(item) => item.visit_attrs(f),
StmtKind::Empty => {}
StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f),
}
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
Some(match self {
StmtKind::Local(local) => &mut local.tokens,
StmtKind::Item(item) => &mut item.tokens,
StmtKind::Expr(expr) | StmtKind::Semi(expr) => &mut expr.tokens,
StmtKind::Empty => return None,
StmtKind::MacCall(mac) => &mut mac.tokens,
})
}
}
impl AstLike for Stmt {
fn attrs(&self) -> &[Attribute] {
self.kind.attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
self.kind.visit_attrs(f);
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
self.kind.tokens_mut()
}
}
impl AstLike for Attribute {
fn attrs(&self) -> &[Attribute] {
&[]
}
fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
Some(match &mut self.kind {
AttrKind::Normal(_, tokens) => tokens,
kind @ AttrKind::DocComment(..) => {
panic!("Called tokens_mut on doc comment attr {:?}", kind)
}
})
}
}
impl<T: AstLike> AstLike for Option<T> {
fn attrs(&self) -> &[Attribute] {
self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[])
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
if let Some(inner) = self.as_mut() {
inner.visit_attrs(f);
}
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
self.as_mut().and_then(|inner| inner.tokens_mut())
}
}
/// Helper trait for the macros below. Abstracts over
/// the two types of attribute fields that AST nodes
/// may have (`Vec<Attribute>` or `AttrVec`)
trait VecOrAttrVec {
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
}
impl VecOrAttrVec for Vec<Attribute> {
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
f(self)
}
}
impl VecOrAttrVec for AttrVec {
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
visit_attrvec(self, f)
}
}
macro_rules! derive_has_tokens_and_attrs {
($($ty:path),*) => { $(
impl AstLike for $ty {
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
VecOrAttrVec::visit(&mut self.attrs, f)
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
Some(&mut self.tokens)
}
}
)* }
}
macro_rules! derive_has_attrs_no_tokens {
($($ty:path),*) => { $(
impl AstLike for $ty {
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
VecOrAttrVec::visit(&mut self.attrs, f)
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
None
}
}
)* }
}
macro_rules! derive_has_tokens_no_attrs {
($($ty:path),*) => { $(
impl AstLike for $ty {
fn attrs(&self) -> &[Attribute] {
&[]
}
fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
Some(&mut self.tokens)
}
}
)* }
}
// These AST nodes support both inert and active
// attributes, so they also have tokens.
derive_has_tokens_and_attrs! {
Item, Expr, Local, AssocItem, ForeignItem
}
// These ast nodes only support inert attributes, so they don't
// store tokens (since nothing can observe them)
derive_has_attrs_no_tokens! {
StructField, Arm,
Field, FieldPat, Variant, Param, GenericParam
}
// These AST nodes don't support attributes, but can
// be captured by a `macro_rules!` matcher. Therefore,
// they need to store tokens.
derive_has_tokens_no_attrs! {
Ty, Block, AttrItem, Pat, Path, Visibility
}

View File

@ -1,17 +1,15 @@
//! Functions dealing with attributes and meta items.
use crate::ast;
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
use crate::ast::{Expr, GenericParam, Item, Lit, LitKind, Local, Stmt, StmtKind};
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
use crate::ast::{Lit, LitKind};
use crate::ast::{MacArgs, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
use crate::ast::{Path, PathSegment};
use crate::mut_visit::visit_clobber;
use crate::ptr::P;
use crate::token::{self, CommentKind, Token};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree, TreeAndSpacing};
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::{BytePos, Spanned};
use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@ -36,7 +34,7 @@ impl MarkedAttrs {
}
pub fn is_known_lint_tool(m_item: Ident) -> bool {
[sym::clippy, sym::rustc].contains(&m_item.name)
[sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item.name)
}
impl NestedMetaItem {
@ -122,6 +120,7 @@ impl NestedMetaItem {
}
impl Attribute {
#[inline]
pub fn has_name(&self, name: Symbol) -> bool {
match self.kind {
AttrKind::Normal(ref item, _) => item.path == name,
@ -617,101 +616,3 @@ impl NestedMetaItem {
MetaItem::from_tokens(tokens).map(NestedMetaItem::MetaItem)
}
}
pub trait HasAttrs: Sized {
fn attrs(&self) -> &[Attribute];
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
}
impl<T: HasAttrs> HasAttrs for Spanned<T> {
fn attrs(&self) -> &[Attribute] {
self.node.attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
self.node.visit_attrs(f);
}
}
impl HasAttrs for Vec<Attribute> {
fn attrs(&self) -> &[Attribute] {
self
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
f(self)
}
}
impl HasAttrs for AttrVec {
fn attrs(&self) -> &[Attribute] {
self
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
visit_clobber(self, |this| {
let mut vec = this.into();
f(&mut vec);
vec.into()
});
}
}
impl<T: HasAttrs + 'static> HasAttrs for P<T> {
fn attrs(&self) -> &[Attribute] {
(**self).attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
(**self).visit_attrs(f);
}
}
impl HasAttrs for StmtKind {
fn attrs(&self) -> &[Attribute] {
match *self {
StmtKind::Local(ref local) => local.attrs(),
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
StmtKind::Item(ref item) => item.attrs(),
StmtKind::Empty => &[],
StmtKind::MacCall(ref mac) => mac.attrs.attrs(),
}
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
match self {
StmtKind::Local(local) => local.visit_attrs(f),
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
StmtKind::Item(item) => item.visit_attrs(f),
StmtKind::Empty => {}
StmtKind::MacCall(mac) => {
mac.attrs.visit_attrs(f);
}
}
}
}
impl HasAttrs for Stmt {
fn attrs(&self) -> &[ast::Attribute] {
self.kind.attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
self.kind.visit_attrs(f);
}
}
macro_rules! derive_has_attrs {
($($ty:path),*) => { $(
impl HasAttrs for $ty {
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
self.attrs.visit_attrs(f);
}
}
)* }
}
derive_has_attrs! {
Item, Expr, Local, ast::AssocItem, ast::ForeignItem, ast::StructField, ast::Arm,
ast::Field, ast::FieldPat, ast::Variant, ast::Param, GenericParam
}

View File

@ -40,8 +40,8 @@ pub mod util {
}
pub mod ast;
pub mod ast_like;
pub mod attr;
pub mod crate_disambiguator;
pub mod entry;
pub mod expand;
pub mod mut_visit;
@ -52,6 +52,7 @@ pub mod tokenstream;
pub mod visit;
pub use self::ast::*;
pub use self::ast_like::AstLike;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};

View File

@ -170,10 +170,6 @@ pub trait MutVisitor: Sized {
noop_visit_ty_constraint(t, self);
}
fn visit_mod(&mut self, m: &mut Mod) {
noop_visit_mod(m, self);
}
fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
noop_visit_foreign_mod(nm, self);
}
@ -917,7 +913,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
vis.visit_generics(generics);
visit_opt(body, |body| vis.visit_block(body));
}
ItemKind::Mod(m) => vis.visit_mod(m),
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
ModKind::Loaded(items, _inline, inner_span) => {
vis.visit_span(inner_span);
items.flat_map_in_place(|item| vis.flat_map_item(item));
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(_ga) => {}
ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
@ -998,14 +1000,10 @@ pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
vis.visit_asyncness(asyncness);
}
pub fn noop_visit_mod<T: MutVisitor>(module: &mut Mod, vis: &mut T) {
let Mod { inner, unsafety: _, items, inline: _ } = module;
vis.visit_span(inner);
items.flat_map_in_place(|item| vis.flat_map_item(item));
}
// FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible,
// or make crate visiting first class if necessary.
pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
visit_clobber(krate, |Crate { module, attrs, span, proc_macros }| {
visit_clobber(krate, |Crate { attrs, items, span, proc_macros }| {
let item_vis =
Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None };
let item = P(Item {
@ -1014,19 +1012,20 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
id: DUMMY_NODE_ID,
vis: item_vis,
span,
kind: ItemKind::Mod(module),
kind: ItemKind::Mod(Unsafe::No, ModKind::Loaded(items, Inline::Yes, span)),
tokens: None,
});
let items = vis.flat_map_item(item);
let len = items.len();
if len == 0 {
let module = Mod { inner: span, unsafety: Unsafe::No, items: vec![], inline: true };
Crate { module, attrs: vec![], span, proc_macros }
Crate { attrs: vec![], items: vec![], span, proc_macros }
} else if len == 1 {
let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner();
match kind {
ItemKind::Mod(module) => Crate { module, attrs, span, proc_macros },
ItemKind::Mod(_, ModKind::Loaded(items, ..)) => {
Crate { attrs, items, span, proc_macros }
}
_ => panic!("visitor converted a module to not a module"),
}
} else {

View File

@ -11,11 +11,9 @@ use crate::tokenstream::TokenTree;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_macros::HashStable_Generic;
use rustc_span::hygiene::ExpnKind;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, edition::Edition, FileName, RealFileName, Span, DUMMY_SP};
use rustc_span::{self, edition::Edition, Span, DUMMY_SP};
use std::borrow::Cow;
use std::{fmt, mem};
@ -244,7 +242,7 @@ pub enum TokenKind {
}
// `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(TokenKind, 16);
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
@ -682,7 +680,7 @@ pub enum Nonterminal {
}
// `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Nonterminal, 48);
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
@ -813,52 +811,6 @@ impl Nonterminal {
}
false
}
// See issue #74616 for details
pub fn ident_name_compatibility_hack(
&self,
orig_span: Span,
source_map: &SourceMap,
) -> Option<(Ident, bool)> {
if let NtIdent(ident, is_raw) = self {
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, 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(filename)
&& iter.next().and_then(|p| p.as_os_str().to_str()) == Some("src")
&& iter
.next()
.and_then(|p| p.as_os_str().to_str())
.map_or(false, |p| p.starts_with(prefix))
};
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));
}
}
}
}
}
None
}
}
impl PartialEq for Nonterminal {

View File

@ -189,7 +189,7 @@ pub struct TokenStream(pub(crate) Lrc<Vec<TreeAndSpacing>>);
pub type TreeAndSpacing = (TokenTree, Spacing);
// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(TokenStream, 8);
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable)]

View File

@ -74,7 +74,7 @@ impl<'a> FnKind<'a> {
/// Each method of the `Visitor` trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
/// e.g., the `visit_mod` method by default calls `visit::walk_mod`.
/// e.g., the `visit_item` method by default calls `visit::walk_item`.
///
/// If you want to ensure that your code handles every variant
/// explicitly, you need to override each method. (And you also need
@ -87,9 +87,6 @@ pub trait Visitor<'ast>: Sized {
fn visit_ident(&mut self, ident: Ident) {
walk_ident(self, ident);
}
fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _attrs: &[Attribute], _n: NodeId) {
walk_mod(self, m);
}
fn visit_foreign_item(&mut self, i: &'ast ForeignItem) {
walk_foreign_item(self, i)
}
@ -238,14 +235,10 @@ pub fn walk_ident<'a, V: Visitor<'a>>(visitor: &mut V, ident: Ident) {
}
pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) {
visitor.visit_mod(&krate.module, krate.span, &krate.attrs, CRATE_NODE_ID);
walk_list!(visitor, visit_item, &krate.items);
walk_list!(visitor, visit_attribute, &krate.attrs);
}
pub fn walk_mod<'a, V: Visitor<'a>>(visitor: &mut V, module: &'a Mod) {
walk_list!(visitor, visit_item, &module.items);
}
pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) {
for attr in local.attrs.iter() {
visitor.visit_attribute(attr);
@ -297,7 +290,12 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
visitor.visit_fn(kind, item.span, item.id)
}
ItemKind::Mod(ref module) => visitor.visit_mod(module, item.span, &item.attrs, item.id),
ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind {
ModKind::Loaded(items, _inline, _inner_span) => {
walk_list!(visitor, visit_item, items)
}
ModKind::Unloaded => {}
},
ItemKind::ForeignMod(ref foreign_module) => {
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
}

View File

@ -9,7 +9,9 @@ use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::definitions::DefPathData;
use rustc_session::parse::feature_err;
use rustc_span::hygiene::ExpnId;
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{hygiene::ForLoopLoc, DUMMY_SP};
@ -42,8 +44,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
ExprKind::Call(ref f, ref args) => {
let f = self.lower_expr(f);
hir::ExprKind::Call(f, self.lower_exprs(args))
if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args)
} else {
let f = self.lower_expr(f);
hir::ExprKind::Call(f, self.lower_exprs(args))
}
}
ExprKind::MethodCall(ref seg, ref args, span) => {
let hir_seg = self.arena.alloc(self.lower_path_segment(
@ -91,6 +97,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Let(ref pat, ref scrutinee) => {
self.lower_expr_if_let(e.span, pat, scrutinee, then, else_opt.as_deref())
}
ExprKind::Paren(ref paren) => match paren.peel_parens().kind {
ExprKind::Let(ref pat, ref scrutinee) => {
// A user has written `if (let Some(x) = foo) {`, we want to avoid
// confusing them with mentions of nightly features.
// If this logic is changed, you will also likely need to touch
// `unused::UnusedParens::check_expr`.
self.if_let_expr_with_parens(cond, &paren.peel_parens());
self.lower_expr_if_let(
e.span,
pat,
scrutinee,
then,
else_opt.as_deref(),
)
}
_ => self.lower_expr_if(cond, then, else_opt.as_deref()),
},
_ => self.lower_expr_if(cond, then, else_opt.as_deref()),
},
ExprKind::While(ref cond, ref body, opt_label) => self
@ -235,9 +258,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
ex.span = e.span;
}
// Merge attributes into the inner expression.
let mut attrs: Vec<_> = e.attrs.iter().map(|a| self.lower_attr(a)).collect();
attrs.extend::<Vec<_>>(ex.attrs.into());
ex.attrs = attrs.into();
if !e.attrs.is_empty() {
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
self.attrs.insert(
ex.hir_id,
&*self.arena.alloc_from_iter(
e.attrs
.iter()
.map(|a| self.lower_attr(a))
.chain(old_attrs.iter().cloned()),
),
);
}
return ex;
}
@ -249,12 +281,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
};
hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
}
let hir_id = self.lower_node_id(e.id);
self.lower_attrs(hir_id, &e.attrs);
hir::Expr { hir_id, kind, span: e.span }
})
}
@ -292,6 +321,73 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
fn lower_legacy_const_generics(
&mut self,
mut f: Expr,
args: Vec<AstP<Expr>>,
legacy_args_idx: &[usize],
) -> hir::ExprKind<'hir> {
let path = match f.kind {
ExprKind::Path(None, ref mut path) => path,
_ => unreachable!(),
};
// Split the arguments into const generics and normal arguments
let mut real_args = vec![];
let mut generic_args = vec![];
for (idx, arg) in args.into_iter().enumerate() {
if legacy_args_idx.contains(&idx) {
let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
let node_id = self.resolver.next_node_id();
// Add a definition for the in-band const def.
self.resolver.create_def(
parent_def_id,
node_id,
DefPathData::AnonConst,
ExpnId::root(),
arg.span,
);
let anon_const = AnonConst { id: node_id, value: arg };
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
} else {
real_args.push(arg);
}
}
// Add generic args to the last element of the path.
let last_segment = path.segments.last_mut().unwrap();
assert!(last_segment.args.is_none());
last_segment.args = Some(AstP(GenericArgs::AngleBracketed(AngleBracketedArgs {
span: DUMMY_SP,
args: generic_args,
})));
// Now lower everything as normal.
let f = self.lower_expr(&f);
hir::ExprKind::Call(f, self.lower_exprs(&real_args))
}
fn if_let_expr_with_parens(&mut self, cond: &Expr, paren: &Expr) {
let start = cond.span.until(paren.span);
let end = paren.span.shrink_to_hi().until(cond.span.shrink_to_hi());
self.sess
.struct_span_err(
vec![start, end],
"invalid parentheses around `let` expression in `if let`",
)
.multipart_suggestion(
"`if let` needs to be written without parentheses",
vec![(start, String::new()), (end, String::new())],
rustc_errors::Applicability::MachineApplicable,
)
.emit();
// Ideally, we'd remove the feature gating of a `let` expression since we are already
// complaining about it here, but `feature_gate::check_crate` has already run by now:
// self.sess.parse_sess.gated_spans.ungate_last(sym::let_chains, paren.span);
}
/// Emit an error and lower `ast::ExprKind::Let(pat, scrutinee)` into:
/// ```rust
/// match scrutinee { pats => true, _ => false }
@ -302,8 +398,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
if self.sess.opts.unstable_features.is_nightly_build() {
self.sess
.struct_span_err(span, "`let` expressions are not supported here")
.note("only supported directly in conditions of `if`- and `while`-expressions")
.note("as well as when nested within `&&` and parenthesis in those conditions")
.note(
"only supported directly without parentheses in conditions of `if`- and \
`while`-expressions, as well as in `let` chains within parentheses",
)
.emit();
} else {
self.sess
@ -347,8 +445,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::ExprKind<'hir> {
macro_rules! make_if {
($opt:expr) => {{
let cond = self.lower_expr(cond);
let then_expr = self.lower_block_expr(then);
hir::ExprKind::If(self.lower_expr(cond), self.arena.alloc(then_expr), $opt)
hir::ExprKind::If(cond, self.arena.alloc(then_expr), $opt)
}};
}
if let Some(rslt) = else_opt {
@ -525,14 +624,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Guard::If(self.lower_expr(cond))
}
});
hir::Arm {
hir_id: self.next_id(),
attrs: self.lower_attrs(&arm.attrs),
pat,
guard,
body: self.lower_expr(&arm.body),
span: arm.span,
}
let hir_id = self.next_id();
self.lower_attrs(hir_id, &arm.attrs);
hir::Arm { hir_id, pat, guard, body: self.lower_expr(&arm.body), span: arm.span }
}
/// Lower an `async` construct to a generator that is then wrapped so it implements `Future`.
@ -576,7 +670,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Ident::with_dummy_span(sym::_task_context),
hir::BindingAnnotation::Mutable,
);
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, ty_span: span, span };
let param = hir::Param { hir_id: self.next_id(), pat, ty_span: span, span };
let params = arena_vec![self; param];
let body_id = self.lower_body(move |this| {
@ -597,12 +691,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
Some(hir::Movability::Static),
);
let generator = hir::Expr {
hir_id: self.lower_node_id(closure_node_id),
kind: generator_kind,
span,
attrs: ThinVec::new(),
};
let generator =
hir::Expr { hir_id: self.lower_node_id(closure_node_id), kind: generator_kind, span };
// `future::from_generator`:
let unstable_span =
@ -756,7 +846,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: loop_hir_id,
kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop, span),
span,
attrs: ThinVec::new(),
});
// mut pinned => loop { ... }
@ -933,7 +1022,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Introduce a `let` for destructuring: `let (lhs1, lhs2) = t`.
let destructure_let = self.stmt_let_pat(
ThinVec::new(),
None,
whole_span,
Some(rhs),
pat,
@ -1692,7 +1781,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `let mut __next`
let next_let = self.stmt_let_pat(
ThinVec::new(),
None,
desugared_span,
None,
next_pat,
@ -1702,7 +1791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `let <pat> = __next`
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
None,
desugared_span,
Some(next_expr),
pat,
@ -1726,12 +1815,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::LoopSource::ForLoop,
e.span.with_hi(orig_head_span.hi()),
);
let loop_expr = self.arena.alloc(hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: ThinVec::new(),
});
let loop_expr =
self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span });
// `mut iter => { ... }`
let iter_arm = self.arm(iter_pat, loop_expr);
@ -2066,7 +2151,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind: hir::ExprKind<'hir>,
attrs: AttrVec,
) -> hir::Expr<'hir> {
hir::Expr { hir_id: self.next_id(), kind, span, attrs }
let hir_id = self.next_id();
self.lower_attrs(hir_id, &attrs);
hir::Expr { hir_id, kind, span }
}
fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> {
@ -2074,13 +2161,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn arm(&mut self, pat: &'hir hir::Pat<'hir>, expr: &'hir hir::Expr<'hir>) -> hir::Arm<'hir> {
hir::Arm {
hir_id: self.next_id(),
attrs: &[],
pat,
guard: None,
span: expr.span,
body: expr,
}
hir::Arm { hir_id: self.next_id(), pat, guard: None, span: expr.span, body: expr }
}
}

View File

@ -15,11 +15,11 @@ use rustc_span::source_map::{respan, DesugaringKind};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use rustc_target::spec::abi;
use smallvec::{smallvec, SmallVec};
use std::collections::BTreeSet;
use tracing::debug;
use std::mem;
pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
}
@ -34,32 +34,13 @@ impl ItemLowerer<'_, '_, '_> {
}
impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
let hir_id = self.lctx.lower_node_id(n);
self.lctx.modules.insert(
hir_id,
hir::ModuleItems {
items: BTreeSet::new(),
trait_items: BTreeSet::new(),
impl_items: BTreeSet::new(),
foreign_items: BTreeSet::new(),
},
);
let old = self.lctx.current_module;
self.lctx.current_module = hir_id;
visit::walk_mod(self, m);
self.lctx.current_module = old;
}
fn visit_item(&mut self, item: &'a Item) {
let mut item_hir_id = None;
self.lctx.with_hir_id_owner(item.id, |lctx| {
lctx.without_in_scope_lifetime_defs(|lctx| {
if let Some(hir_item) = lctx.lower_item(item) {
item_hir_id = Some(hir_item.hir_id);
lctx.insert_item(hir_item);
let id = lctx.insert_item(hir_item);
item_hir_id = Some(id);
}
})
});
@ -67,10 +48,18 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
if let Some(hir_id) = item_hir_id {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
if let ItemKind::Impl(box ImplKind { ref of_trait, .. }) = item.kind {
this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
} else {
visit::walk_item(this, item);
match item.kind {
ItemKind::Mod(..) => {
let def_id = this.lctx.lower_node_id(item.id).expect_owner();
let old_current_module =
mem::replace(&mut this.lctx.current_module, def_id);
visit::walk_item(this, item);
this.lctx.current_module = old_current_module;
}
ItemKind::Impl(box ImplKind { ref of_trait, .. }) => {
this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
}
_ => visit::walk_item(this, item),
}
});
}
@ -92,15 +81,15 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
AssocCtxt::Trait => {
let hir_item = lctx.lower_trait_item(item);
let id = hir::TraitItemId { hir_id: hir_item.hir_id };
let id = hir_item.trait_item_id();
lctx.trait_items.insert(id, hir_item);
lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
lctx.modules.entry(lctx.current_module).or_default().trait_items.insert(id);
}
AssocCtxt::Impl => {
let hir_item = lctx.lower_impl_item(item);
let id = hir::ImplItemId { hir_id: hir_item.hir_id };
let id = hir_item.impl_item_id();
lctx.impl_items.insert(id, hir_item);
lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
lctx.modules.entry(lctx.current_module).or_default().impl_items.insert(id);
}
});
@ -111,9 +100,9 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
self.lctx.allocate_hir_id_counter(item.id);
self.lctx.with_hir_id_owner(item.id, |lctx| {
let hir_item = lctx.lower_foreign_item(item);
let id = hir::ForeignItemId { hir_id: hir_item.hir_id };
let id = hir_item.foreign_item_id();
lctx.foreign_items.insert(id, hir_item);
lctx.modules.get_mut(&lctx.current_module).unwrap().foreign_items.insert(id);
lctx.modules.entry(lctx.current_module).or_default().foreign_items.insert(id);
});
visit::walk_foreign_item(self, item);
@ -128,14 +117,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
// only used when lowering a child item of a trait or impl.
fn with_parent_item_lifetime_defs<T>(
&mut self,
parent_hir_id: hir::HirId,
parent_hir_id: hir::ItemId,
f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
) -> T {
let old_len = self.in_scope_lifetimes.len();
let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
| hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
_ => &[],
};
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
@ -157,7 +146,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
) -> T {
let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);
let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, vec![]);
// this vector is only used when walking over impl headers,
// input types, and the like, and should not be non-empty in
@ -172,12 +161,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
res
}
pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod<'hir> {
pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
hir::Mod {
inner: m.inner,
item_ids: self
.arena
.alloc_from_iter(m.items.iter().flat_map(|x| self.lower_item_id(x))),
inner,
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_id(x))),
}
}
@ -197,7 +184,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
node_ids
.into_iter()
.map(|node_id| hir::ItemId { id: self.allocate_hir_id_counter(node_id) })
.map(|node_id| hir::ItemId {
def_id: self.allocate_hir_id_counter(node_id).expect_owner(),
})
.collect()
}
@ -228,37 +217,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
let mut ident = i.ident;
let mut vis = self.lower_visibility(&i.vis, None);
let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
let hir_id = self.lower_node_id(i.id);
self.lower_attrs(hir_id, &i.attrs);
let body = P(self.lower_mac_args(body));
self.exported_macros.push(hir::MacroDef {
ident,
vis,
attrs,
hir_id,
def_id: hir_id.expect_owner(),
span: i.span,
ast: MacroDef { body, macro_rules },
});
} else {
self.non_exported_macro_attrs.extend(attrs.iter().cloned());
for a in i.attrs.iter() {
let a = self.lower_attr(a);
self.non_exported_macro_attrs.push(a);
}
}
return None;
}
let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);
Some(hir::Item { hir_id: self.lower_node_id(i.id), ident, attrs, kind, vis, span: i.span })
let hir_id = self.lower_node_id(i.id);
let attrs = self.lower_attrs(hir_id, &i.attrs);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
Some(hir::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span })
}
fn lower_item_kind(
&mut self,
span: Span,
id: NodeId,
hir_id: hir::HirId,
ident: &mut Ident,
attrs: &'hir [Attribute],
attrs: Option<&'hir [Attribute]>,
vis: &mut hir::Visibility<'hir>,
i: &ItemKind,
) -> hir::ItemKind<'hir> {
@ -318,13 +311,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ItemKind::Fn(sig, generics, body_id)
})
}
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
ItemKind::Mod(_, ref mod_kind) => match mod_kind {
ModKind::Loaded(items, _, inner_span) => {
hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
},
ItemKind::ForeignMod(ref fm) => {
if fm.abi.is_none() {
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
self.maybe_lint_missing_abi(span, id, abi::Abi::C { unwind: false });
}
hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
abi: fm.abi.map_or(abi::Abi::C { unwind: false }, |abi| self.lower_abi(abi)),
items: self
.arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
@ -364,14 +362,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_generics(generics, ImplTraitContext::disallowed()),
),
ItemKind::Struct(ref struct_def, ref generics) => {
let struct_def = self.lower_variant_data(struct_def);
let struct_def = self.lower_variant_data(hir_id, struct_def);
hir::ItemKind::Struct(
struct_def,
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
ItemKind::Union(ref vdata, ref generics) => {
let vdata = self.lower_variant_data(vdata);
let vdata = self.lower_variant_data(hir_id, vdata);
hir::ItemKind::Union(
vdata,
self.lower_generics(generics, ImplTraitContext::disallowed()),
@ -387,8 +385,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self_ty: ref ty,
items: ref impl_items,
}) => {
let def_id = self.resolver.local_def_id(id);
// Lower the "impl header" first. This ordering is important
// for in-band lifetimes! Consider `'a` here:
//
@ -402,10 +398,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
// method, it will not be considered an in-band
// lifetime to be added, but rather a reference to a
// parent lifetime.
let lowered_trait_impl_id = self.lower_node_id(id);
let lowered_trait_def_id = self.lower_node_id(id).expect_owner();
let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
ast_generics,
def_id,
lowered_trait_def_id,
AnonymousLifetimeMode::CreateParameter,
|this, _| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
@ -417,7 +413,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.trait_impls
.entry(def_id)
.or_default()
.push(lowered_trait_impl_id);
.push(lowered_trait_def_id);
}
}
@ -506,7 +502,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
id: NodeId,
vis: &mut hir::Visibility<'hir>,
ident: &mut Ident,
attrs: &'hir [Attribute],
attrs: Option<&'hir [Attribute]>,
) -> hir::ItemKind<'hir> {
debug!("lower_use_tree(tree={:?})", tree);
debug!("lower_use_tree: vis = {:?}", vis);
@ -555,11 +551,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
let vis = this.rebuild_vis(&vis);
if let Some(attrs) = attrs {
this.attrs.insert(new_id, attrs);
}
this.insert_item(hir::Item {
hir_id: new_id,
def_id: new_id.expect_owner(),
ident,
attrs,
kind,
vis,
span,
@ -627,11 +625,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
if let Some(attrs) = attrs {
this.attrs.insert(new_hir_id, attrs);
}
this.insert_item(hir::Item {
hir_id: new_hir_id,
def_id: new_hir_id.expect_owner(),
ident,
attrs,
kind,
vis,
span: use_tree.span,
@ -700,11 +700,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
let def_id = self.resolver.local_def_id(i.id);
let hir_id = self.lower_node_id(i.id);
let def_id = hir_id.expect_owner();
self.lower_attrs(hir_id, &i.attrs);
hir::ForeignItem {
hir_id: self.lower_node_id(i.id),
def_id,
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
kind: match i.kind {
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
let fdec = &sig.decl;
@ -737,7 +738,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> {
hir::ForeignItemRef {
id: hir::ForeignItemId { hir_id: self.lower_node_id(i.id) },
id: hir::ForeignItemId { def_id: self.lower_node_id(i.id).expect_owner() },
ident: i.ident,
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
@ -749,29 +750,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let id = self.lower_node_id(v.id);
self.lower_attrs(id, &v.attrs);
hir::Variant {
attrs: self.lower_attrs(&v.attrs),
data: self.lower_variant_data(&v.data),
id,
data: self.lower_variant_data(id, &v.data),
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
id: self.lower_node_id(v.id),
ident: v.ident,
span: v.span,
}
}
fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData<'hir> {
fn lower_variant_data(
&mut self,
parent_id: hir::HirId,
vdata: &VariantData,
) -> hir::VariantData<'hir> {
match *vdata {
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
self.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
recovered,
),
VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
self.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
self.lower_node_id(id),
),
VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
VariantData::Tuple(ref fields, id) => {
let ctor_id = self.lower_node_id(id);
self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Tuple(
self.arena.alloc_from_iter(
fields.iter().enumerate().map(|f| self.lower_struct_field(f)),
),
ctor_id,
)
}
VariantData::Unit(id) => {
let ctor_id = self.lower_node_id(id);
self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Unit(ctor_id)
}
}
}
@ -788,9 +803,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
} else {
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
};
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
hir::StructField {
span: f.span,
hir_id: self.lower_node_id(f.id),
hir_id,
ident: match f.ident {
Some(ident) => ident,
// FIXME(jseyfried): positional field hygiene.
@ -798,12 +815,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
vis: self.lower_visibility(&f.vis, None),
ty,
attrs: self.lower_attrs(&f.attrs),
}
}
fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
let trait_item_def_id = self.resolver.local_def_id(i.id);
let hir_id = self.lower_node_id(i.id);
let trait_item_def_id = hir_id.expect_owner();
let (generics, kind) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => {
@ -836,14 +853,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
};
hir::TraitItem {
hir_id: self.lower_node_id(i.id),
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
generics,
kind,
span: i.span,
}
self.lower_attrs(hir_id, &i.attrs);
hir::TraitItem { def_id: trait_item_def_id, ident: i.ident, generics, kind, span: i.span }
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
@ -857,7 +868,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
AssocItemKind::MacCall(..) => unimplemented!(),
};
let id = hir::TraitItemId { hir_id: self.lower_node_id(i.id) };
let id = hir::TraitItemId { def_id: self.lower_node_id(i.id).expect_owner() };
let defaultness = hir::Defaultness::Default { has_value: has_default };
hir::TraitItemRef { id, ident: i.ident, span: i.span, defaultness, kind }
}
@ -921,10 +932,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = self.lower_node_id(i.id);
self.lower_attrs(hir_id, &i.attrs);
hir::ImplItem {
hir_id: self.lower_node_id(i.id),
def_id: hir_id.expect_owner(),
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
generics,
vis: self.lower_visibility(&i.vis, None),
defaultness,
@ -938,7 +950,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
hir::ImplItemRef {
id: hir::ImplItemId { hir_id: self.lower_node_id(i.id) },
id: hir::ImplItemId { def_id: self.lower_node_id(i.id).expect_owner() },
ident: i.ident,
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
@ -1025,9 +1037,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs);
hir::Param {
attrs: self.lower_attrs(&param.attrs),
hir_id: self.lower_node_id(param.id),
hir_id,
pat: self.lower_pat(&param.pat),
ty_span: param.ty.span,
span: param.span,
@ -1159,11 +1172,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
//
// If this is the simple case, this parameter will end up being the same as the
// original parameter, but with a different pattern id.
let mut stmt_attrs = AttrVec::new();
stmt_attrs.extend(parameter.attrs.iter().cloned());
let stmt_attrs = this.attrs.get(&parameter.hir_id).copied();
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
let new_parameter = hir::Param {
attrs: parameter.attrs,
hir_id: parameter.hir_id,
pat: new_parameter_pat,
ty_span: parameter.ty_span,
@ -1206,7 +1217,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
let move_stmt = this.stmt_let_pat(
AttrVec::new(),
None,
desugared_span,
Some(move_expr),
move_pat,
@ -1323,8 +1334,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
match ext {
Extern::None => abi::Abi::Rust,
Extern::Implicit => {
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
abi::Abi::C
self.maybe_lint_missing_abi(span, id, abi::Abi::C { unwind: false });
abi::Abi::C { unwind: false }
}
Extern::Explicit(abi) => self.lower_abi(abi),
}

View File

@ -12,7 +12,7 @@
//! For the simpler lowering steps, IDs and spans should be preserved. Unlike
//! expansion we do not preserve the process of lowering in the spans, so spans
//! should not be modified here. When creating a new node (as opposed to
//! 'folding' an existing one), then you create a new ID using `next_id()`.
//! "folding" an existing one), create a new ID using `next_id()`.
//!
//! You must ensure that IDs are unique. That means that you should only use the
//! ID from an AST node in a single HIR node (you can assume that AST node-IDs
@ -26,7 +26,7 @@
//! span and spans don't need to be kept in order, etc. Where code is preserved
//! by lowering, it should have the same span as in the AST. Where HIR nodes are
//! new it is probably best to give a span for the whole AST node being lowered.
//! All nodes should have real spans, don't use dummy spans. Tools are likely to
//! All nodes should have real spans; don't use dummy spans. Tools are likely to
//! get confused if the spans from leaf AST nodes occur in multiple places
//! in the HIR, especially for multiple identifiers.
@ -48,7 +48,7 @@ use rustc_data_structures::sync::Lrc;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_ID};
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::intravisit;
use rustc_hir::{ConstArg, GenericArg, ParamName};
@ -95,11 +95,11 @@ struct LoweringContext<'a, 'hir: 'a> {
/// librustc_middle is independent of the parser, we use dynamic dispatch here.
nt_to_tokenstream: NtToTokenstream,
/// Used to allocate HIR nodes
/// Used to allocate HIR nodes.
arena: &'hir Arena<'hir>,
/// The items being lowered are collected here.
items: BTreeMap<hir::HirId, hir::Item<'hir>>,
items: BTreeMap<hir::ItemId, hir::Item<'hir>>,
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem<'hir>>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem<'hir>>,
@ -108,12 +108,14 @@ struct LoweringContext<'a, 'hir: 'a> {
exported_macros: Vec<hir::MacroDef<'hir>>,
non_exported_macro_attrs: Vec<ast::Attribute>,
trait_impls: BTreeMap<DefId, Vec<hir::HirId>>,
trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
modules: BTreeMap<hir::HirId, hir::ModuleItems>,
modules: BTreeMap<LocalDefId, hir::ModuleItems>,
generator_kind: Option<hir::GeneratorKind>,
attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
/// When inside an `async` context, this is the `HirId` of the
/// `task_context` local bound to the resume argument of the generator.
task_context: Option<hir::HirId>,
@ -128,7 +130,7 @@ struct LoweringContext<'a, 'hir: 'a> {
is_in_trait_impl: bool,
is_in_dyn_type: bool,
/// What to do when we encounter either an "anonymous lifetime
/// What to do when we encounter an "anonymous lifetime
/// reference". The term "anonymous" is meant to encompass both
/// `'_` lifetimes as well as fully elided cases where nothing is
/// written at all (e.g., `&T` or `std::cell::Ref<T>`).
@ -158,7 +160,7 @@ struct LoweringContext<'a, 'hir: 'a> {
/// vector.
in_scope_lifetimes: Vec<ParamName>,
current_module: hir::HirId,
current_module: LocalDefId,
type_def_lifetime_params: DefIdMap<usize>,
@ -175,6 +177,8 @@ pub trait ResolverAstLowering {
fn item_generics_num_lifetimes(&self, def: DefId, sess: &Session) -> usize;
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
/// Obtains resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
@ -219,7 +223,7 @@ enum ImplTraitContext<'b, 'a> {
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
///
/// Newly generated parameters should be inserted into the given `Vec`.
Universal(&'b mut Vec<hir::GenericParam<'a>>),
Universal(&'b mut Vec<hir::GenericParam<'a>>, LocalDefId),
/// Treat `impl Trait` as shorthand for a new opaque type.
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@ -236,11 +240,13 @@ enum ImplTraitContext<'b, 'a> {
OtherOpaqueTy {
/// Set of lifetimes that this opaque type can capture, if it uses
/// them. This includes lifetimes bound since we entered this context.
/// For example, in
/// For example:
///
/// ```
/// type A<'b> = impl for<'a> Trait<'a, Out = impl Sized + 'a>;
/// ```
///
/// the inner opaque type captures `'a` because it uses it. It doesn't
/// Here the inner opaque type captures `'a` because it uses it. It doesn't
/// need to capture `'b` because it already inherits the lifetime
/// parameter from `A`.
// FIXME(impl_trait): but `required_region_bounds` will ICE later
@ -272,7 +278,7 @@ impl<'a> ImplTraitContext<'_, 'a> {
fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
use self::ImplTraitContext::*;
match self {
Universal(params) => Universal(params),
Universal(params, parent) => Universal(params, *parent),
ReturnPositionOpaqueTy { fn_def_id, origin } => {
ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin }
}
@ -305,6 +311,7 @@ pub fn lower_crate<'a, 'hir>(
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
modules: BTreeMap::new(),
attrs: BTreeMap::default(),
exported_macros: Vec::new(),
non_exported_macro_attrs: Vec::new(),
catch_scopes: Vec::new(),
@ -314,8 +321,8 @@ pub fn lower_crate<'a, 'hir>(
is_in_dyn_type: false,
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
type_def_lifetime_params: Default::default(),
current_module: hir::CRATE_HIR_ID,
current_hir_id_owner: vec![(LocalDefId { local_def_index: CRATE_DEF_INDEX }, 0)],
current_module: CRATE_DEF_ID,
current_hir_id_owner: vec![(CRATE_DEF_ID, 0)],
item_local_id_counters: Default::default(),
node_id_to_hir_id: IndexVec::new(),
generator_kind: None,
@ -468,25 +475,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
impl MiscCollector<'_, '_, '_> {
fn allocate_use_tree_hir_id_counters(&mut self, tree: &UseTree, owner: LocalDefId) {
fn allocate_use_tree_hir_id_counters(&mut self, tree: &UseTree) {
match tree.kind {
UseTreeKind::Simple(_, id1, id2) => {
for &id in &[id1, id2] {
self.lctx.resolver.create_def(
owner,
id,
DefPathData::Misc,
ExpnId::root(),
tree.prefix.span,
);
self.lctx.allocate_hir_id_counter(id);
}
}
UseTreeKind::Glob => (),
UseTreeKind::Nested(ref trees) => {
for &(ref use_tree, id) in trees {
let hir_id = self.lctx.allocate_hir_id_counter(id);
self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
self.lctx.allocate_hir_id_counter(id);
self.allocate_use_tree_hir_id_counters(use_tree);
}
}
}
@ -495,7 +495,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
impl<'tcx> Visitor<'tcx> for MiscCollector<'tcx, '_, '_> {
fn visit_item(&mut self, item: &'tcx Item) {
let hir_id = self.lctx.allocate_hir_id_counter(item.id);
self.lctx.allocate_hir_id_counter(item.id);
match item.kind {
ItemKind::Struct(_, ref generics)
@ -514,7 +514,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count);
}
ItemKind::Use(ref use_tree) => {
self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
self.allocate_use_tree_hir_id_counters(use_tree);
}
_ => {}
}
@ -560,8 +560,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
let module = self.lower_mod(&c.module);
let attrs = self.lower_attrs(&c.attrs);
let module = self.lower_mod(&c.items, c.span);
self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
let body_ids = body_ids(&self.bodies);
let proc_macros =
c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
@ -588,8 +588,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
#[cfg(debug_assertions)]
for (&id, attrs) in self.attrs.iter() {
// Verify that we do not store empty slices in the map.
if attrs.is_empty() {
panic!("Stored empty attributes for {:?}", id);
}
}
hir::Crate {
item: hir::CrateItem { module, attrs, span: c.span },
item: hir::CrateItem { module, span: c.span },
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
items: self.items,
@ -602,15 +610,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
modules: self.modules,
proc_macros,
trait_map,
attrs: self.attrs,
}
}
fn insert_item(&mut self, item: hir::Item<'hir>) {
let id = item.hir_id;
// FIXME: Use `debug_asset-rt`.
assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0));
fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId {
let id = hir::ItemId { def_id: item.def_id };
self.items.insert(id, item);
self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
self.modules.entry(self.current_module).or_default().items.insert(id);
id
}
fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {
@ -831,7 +839,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::GenericParam {
hir_id: self.lower_node_id(node_id),
name: hir_name,
attrs: &[],
bounds: &[],
span,
pure_wrt_drop: false,
@ -925,8 +932,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// `lifetimes_to_define`. If we swapped the order of these two,
// in-band-lifetimes introduced by generics or where-clauses
// wouldn't have been added yet.
let generics =
this.lower_generics_mut(generics, ImplTraitContext::Universal(&mut params));
let generics = this.lower_generics_mut(
generics,
ImplTraitContext::Universal(
&mut params,
this.current_hir_id_owner.last().unwrap().0,
),
);
let res = f(this, &mut params);
(params, (generics, res))
})
@ -964,11 +976,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ret
}
fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
if attrs.is_empty() {
None
} else {
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
debug_assert!(!ret.is_empty());
self.attrs.insert(id, ret);
Some(ret)
}
}
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
fn lower_attr(&self, attr: &Attribute) -> Attribute {
// Note that we explicitly do not walk the path. Since we don't really
// lower attributes (we use the AST version) there is nowhere to keep
// the `HirId`s. We don't actually need HIR version of attributes anyway.
@ -988,7 +1007,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
}
fn lower_mac_args(&mut self, args: &MacArgs) -> MacArgs {
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
if let Some(&a) = self.attrs.get(&target_id) {
debug_assert!(!a.is_empty());
self.attrs.insert(id, a);
}
}
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
match *args {
MacArgs::Empty => MacArgs::Empty,
MacArgs::Delimited(dspan, delim, ref tokens) => {
@ -1117,6 +1143,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
AssocTyConstraintKind::Bound { ref bounds } => {
let mut capturable_lifetimes;
let mut parent_def_id = self.current_hir_id_owner.last().unwrap().0;
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let (desugar_to_impl_trait, itctx) = match itctx {
// We are in the return position:
@ -1136,7 +1163,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// so desugar to
//
// fn foo(x: dyn Iterator<Item = impl Debug>)
ImplTraitContext::Universal(..) if self.is_in_dyn_type => (true, itctx),
ImplTraitContext::Universal(_, parent) if self.is_in_dyn_type => {
parent_def_id = parent;
(true, itctx)
}
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to
// `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
@ -1170,7 +1200,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// constructing the HIR for `impl bounds...` and then lowering that.
let impl_trait_node_id = self.resolver.next_node_id();
let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
self.resolver.create_def(
parent_def_id,
impl_trait_node_id,
@ -1423,7 +1452,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|this| this.lower_param_bounds(bounds, nested_itctx),
)
}
ImplTraitContext::Universal(in_band_ty_params) => {
ImplTraitContext::Universal(in_band_ty_params, parent_def_id) => {
// Add a definition for the in-band `Param`.
let def_id = self.resolver.local_def_id(def_node_id);
@ -1432,7 +1461,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let hir_bounds = self.with_hir_id_owner(def_node_id, |this| {
this.lower_param_bounds(
bounds,
ImplTraitContext::Universal(in_band_ty_params),
ImplTraitContext::Universal(in_band_ty_params, parent_def_id),
)
});
// Set the name to `impl Bound1 + Bound2`.
@ -1441,7 +1470,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir_id: self.lower_node_id(def_node_id),
name: ParamName::Plain(ident),
pure_wrt_drop: false,
attrs: &[],
bounds: hir_bounds,
span,
kind: hir::GenericParamKind::Type {
@ -1547,11 +1575,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
let opaque_ty_id =
lctx.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span);
lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span);
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
hir::TyKind::OpaqueDef(hir::ItemId { id: opaque_ty_id }, lifetimes)
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
})
}
@ -1559,19 +1586,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// returns the lowered node-ID for the opaque type.
fn generate_opaque_type(
&mut self,
opaque_ty_node_id: NodeId,
opaque_ty_id: LocalDefId,
opaque_ty_item: hir::OpaqueTy<'hir>,
span: Span,
opaque_ty_span: Span,
) -> hir::HirId {
) {
let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
let opaque_ty_id = self.lower_node_id(opaque_ty_node_id);
// Generate an `type Foo = impl Trait;` declaration.
trace!("registering opaque type with id {:#?}", opaque_ty_id);
let opaque_ty_item = hir::Item {
hir_id: opaque_ty_id,
def_id: opaque_ty_id,
ident: Ident::invalid(),
attrs: Default::default(),
kind: opaque_ty_item_kind,
vis: respan(span.shrink_to_lo(), hir::VisibilityKind::Inherited),
span: opaque_ty_span,
@ -1581,7 +1606,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// automatically for all AST items. But this opaque type item
// does not actually exist in the AST.
self.insert_item(opaque_ty_item);
opaque_ty_id
}
fn lifetimes_from_impl_trait_bounds(
@ -1733,7 +1757,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
name,
span: lifetime.span,
pure_wrt_drop: false,
attrs: &[],
bounds: &[],
kind: hir::GenericParamKind::Lifetime { kind },
});
@ -1790,14 +1813,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
});
let init = l.init.as_ref().map(|e| self.lower_expr(e));
let hir_id = self.lower_node_id(l.id);
self.lower_attrs(hir_id, &l.attrs);
(
hir::Local {
hir_id: self.lower_node_id(l.id),
hir_id,
ty,
pat: self.lower_pat(&l.pat),
init,
span: l.span,
attrs: l.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
source: hir::LocalSource::Normal,
},
ids,
@ -1868,7 +1892,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
this.arena.alloc_from_iter(inputs.iter().map(|param| {
if let Some((_, ibty)) = &mut in_band_ty_params {
this.lower_ty_direct(&param.ty, ImplTraitContext::Universal(ibty))
this.lower_ty_direct(
&param.ty,
ImplTraitContext::Universal(
ibty,
this.current_hir_id_owner.last().unwrap().0,
),
)
} else {
this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
}
@ -2010,7 +2040,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// grow.
let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
let (opaque_ty_id, lifetime_params) = self.with_hir_id_owner(opaque_ty_node_id, |this| {
let lifetime_params = self.with_hir_id_owner(opaque_ty_node_id, |this| {
// We have to be careful to get elision right here. The
// idea is that we create a lifetime parameter for each
// lifetime in the return type. So, given a return type
@ -2061,10 +2091,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
let opaque_ty_id =
this.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span);
this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span);
(opaque_ty_id, lifetime_params)
lifetime_params
});
// As documented above on the variable
@ -2107,12 +2136,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Foo = impl Trait` is, internally, created as a child of the
// async fn, so the *type parameters* are inherited. It's
// only the lifetime parameters that we must supply.
let opaque_ty_ref = hir::TyKind::OpaqueDef(hir::ItemId { id: opaque_ty_id }, generic_args);
let opaque_ty_ref =
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
}
/// Transforms `-> T` into `Future<Output = T>`
/// Transforms `-> T` into `Future<Output = T>`.
fn lower_async_fn_output_type_to_future_bound(
&mut self,
output: &FnRetTy,
@ -2300,12 +2330,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
};
let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs);
hir::GenericParam {
hir_id: self.lower_node_id(param.id),
hir_id,
name,
span: param.ident.span,
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
attrs: self.lower_attrs(&param.attrs),
bounds: self.arena.alloc_from_iter(bounds),
kind,
}
@ -2385,26 +2416,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_block_noalloc(&mut self, b: &Block, targeted_by_break: bool) -> hir::Block<'hir> {
let mut expr: Option<&'hir _> = None;
let stmts = self.arena.alloc_from_iter(
b.stmts
.iter()
.enumerate()
.filter_map(|(index, stmt)| {
if index == b.stmts.len() - 1 {
if let StmtKind::Expr(ref e) = stmt.kind {
expr = Some(self.lower_expr(e));
None
} else {
Some(self.lower_stmt(stmt))
}
} else {
Some(self.lower_stmt(stmt))
}
})
.flatten(),
);
let (stmts, expr) = match &*b.stmts {
[stmts @ .., Stmt { kind: StmtKind::Expr(e), .. }] => (stmts, Some(&*e)),
stmts => (stmts, None),
};
let stmts = self.arena.alloc_from_iter(stmts.iter().flat_map(|stmt| self.lower_stmt(stmt)));
let expr = expr.map(|e| self.lower_expr(e));
let rules = self.lower_block_check_mode(&b.rules);
let hir_id = self.lower_node_id(b.id);
@ -2426,19 +2443,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
let kind = match s.kind {
let (hir_id, kind) = match s.kind {
StmtKind::Local(ref l) => {
let (l, item_ids) = self.lower_local(l);
let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids
.into_iter()
.map(|item_id| {
let item_id = hir::ItemId { id: self.lower_node_id(item_id) };
let item_id = hir::ItemId {
// All the items that `lower_local` finds are `impl Trait` types.
def_id: self.lower_node_id(item_id).expect_owner(),
};
self.stmt(s.span, hir::StmtKind::Item(item_id))
})
.collect();
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, l.hir_id);
ids.push({
hir::Stmt {
hir_id: self.lower_node_id(s.id),
hir_id,
kind: hir::StmtKind::Local(self.arena.alloc(l)),
span: s.span,
}
@ -2461,12 +2483,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
})
.collect();
}
StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.lower_expr(e)),
StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.lower_expr(e)),
StmtKind::Expr(ref e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
(hir_id, hir::StmtKind::Expr(e))
}
StmtKind::Semi(ref e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
(hir_id, hir::StmtKind::Semi(e))
}
StmtKind::Empty => return smallvec![],
StmtKind::MacCall(..) => panic!("shouldn't exist here"),
};
smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }]
smallvec![hir::Stmt { hir_id, kind, span: s.span }]
}
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
@ -2510,13 +2542,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn stmt_let_pat(
&mut self,
attrs: AttrVec,
attrs: Option<&'hir [Attribute]>,
span: Span,
init: Option<&'hir hir::Expr<'hir>>,
pat: &'hir hir::Pat<'hir>,
source: hir::LocalSource,
) -> hir::Stmt<'hir> {
let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None };
let hir_id = self.next_id();
if let Some(a) = attrs {
debug_assert!(!a.is_empty());
self.attrs.insert(hir_id, a);
}
let local = hir::Local { hir_id, init, pat, source, span, ty: None };
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
}

View File

@ -1054,12 +1054,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs);
return;
}
ItemKind::Mod(Mod { inline, unsafety, .. }) => {
ItemKind::Mod(unsafety, ref mod_kind) => {
if let Unsafe::Yes(span) = unsafety {
self.err_handler().span_err(span, "module cannot be declared unsafe");
}
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
if !inline && !self.session.contains_name(&item.attrs, sym::path) {
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
&& !self.session.contains_name(&item.attrs, sym::path)
{
self.check_mod_file_item_asciionly(item.ident);
}
}

View File

@ -164,6 +164,38 @@ impl<'a> PostExpansionVisitor<'a> {
"C-cmse-nonsecure-call ABI is experimental and subject to change"
);
}
"C-unwind" => {
gate_feature_post!(
&self,
c_unwind,
span,
"C-unwind ABI is experimental and subject to change"
);
}
"stdcall-unwind" => {
gate_feature_post!(
&self,
c_unwind,
span,
"stdcall-unwind ABI is experimental and subject to change"
);
}
"system-unwind" => {
gate_feature_post!(
&self,
c_unwind,
span,
"system-unwind ABI is experimental and subject to change"
);
}
"thiscall-unwind" => {
gate_feature_post!(
&self,
c_unwind,
span,
"thiscall-unwind ABI is experimental and subject to change"
);
}
abi => self
.sess
.parse_sess
@ -638,8 +670,16 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
}
};
}
gate_all!(if_let_guard, "`if let` guards are experimental");
gate_all!(let_chains, "`let` expressions in this position are experimental");
gate_all!(
if_let_guard,
"`if let` guards are experimental",
"you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`"
);
gate_all!(
let_chains,
"`let` expressions in this position are experimental",
"you can write `matches!(<expr>, <pattern>)` instead of `let <pattern> = <expr>`"
);
gate_all!(
async_closure,
"async closures are unstable",
@ -665,6 +705,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
// involved, so we only emit errors where there are no other parsing errors.
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
}
gate_all!(pub_macro_rules, "`pub` on `macro_rules` items is unstable");
// All uses of `gate_all!` below this point were added in #65742,
// and subsequently disabled (with the non-early gating readded).

View File

@ -20,10 +20,6 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_ident(self, ident);
}
fn visit_mod(&mut self, m: &Mod, _s: Span, _a: &[Attribute], _n: NodeId) {
self.count += 1;
walk_mod(self, m)
}
fn visit_foreign_item(&mut self, i: &ForeignItem) {
self.count += 1;
walk_foreign_item(self, i)

View File

@ -9,7 +9,7 @@ use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser::{self, AssocOp, Fixity};
use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
use rustc_ast::{GenericArg, MacArgs};
use rustc_ast::{GenericArg, MacArgs, ModKind};
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
@ -87,7 +87,6 @@ pub struct State<'a> {
pub s: pp::Printer,
comments: Option<Comments<'a>>,
ann: &'a (dyn PpAnn + 'a),
is_expanded: bool,
}
crate const INDENT_UNIT: usize = 4;
@ -103,12 +102,8 @@ pub fn print_crate<'a>(
is_expanded: bool,
edition: Edition,
) -> String {
let mut s = State {
s: pp::mk_printer(),
comments: Some(Comments::new(sm, filename, input)),
ann,
is_expanded,
};
let mut s =
State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann };
if is_expanded && !krate.attrs.iter().any(|attr| attr.has_name(sym::no_core)) {
// We need to print `#![no_std]` (and its feature gate) so that
@ -132,7 +127,10 @@ pub fn print_crate<'a>(
}
}
s.print_mod(&krate.module, &krate.attrs);
s.print_inner_attributes(&krate.attrs);
for item in &krate.items {
s.print_item(item);
}
s.print_remaining_comments();
s.ann.post(&mut s, AnnNode::Crate(krate));
s.s.eof()
@ -853,7 +851,7 @@ 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 }
State { s: pp::mk_printer(), comments: None, ann: &NoAnn }
}
// Synthesizes a comment that was not textually present in the original source
@ -891,13 +889,6 @@ impl<'a> State<'a> {
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
}
pub fn print_mod(&mut self, _mod: &ast::Mod, attrs: &[ast::Attribute]) {
self.print_inner_attributes(attrs);
for item in &_mod.items {
self.print_item(item);
}
}
crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute]) {
self.print_inner_attributes(attrs);
for item in &nmod.items {
@ -914,6 +905,7 @@ impl<'a> State<'a> {
pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
self.print_ident(constraint.ident);
constraint.gen_args.as_ref().map(|args| self.print_generic_args(args, false));
self.s.space();
match &constraint.kind {
ast::AssocTyConstraintKind::Equality { ty } => {
@ -1138,23 +1130,29 @@ impl<'a> State<'a> {
let body = body.as_deref();
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
ast::ItemKind::Mod(ref _mod) => {
ast::ItemKind::Mod(unsafety, ref mod_kind) => {
self.head(self.to_string(|s| {
s.print_visibility(&item.vis);
s.print_unsafety(_mod.unsafety);
s.print_unsafety(unsafety);
s.word("mod");
}));
self.print_ident(item.ident);
if _mod.inline || self.is_expanded {
self.nbsp();
self.bopen();
self.print_mod(_mod, &item.attrs);
self.bclose(item.span);
} else {
self.s.word(";");
self.end(); // end inner head-block
self.end(); // end outer head-block
match mod_kind {
ModKind::Loaded(items, ..) => {
self.nbsp();
self.bopen();
self.print_inner_attributes(&item.attrs);
for item in items {
self.print_item(item);
}
self.bclose(item.span);
}
ModKind::Unloaded => {
self.s.word(";");
self.end(); // end inner head-block
self.end(); // end outer head-block
}
}
}
ast::ItemKind::ForeignMod(ref nmod) => {
@ -1681,7 +1679,7 @@ impl<'a> State<'a> {
self.ibox(INDENT_UNIT);
self.s.word("[");
self.print_inner_attributes_inline(attrs);
self.commasep_exprs(Inconsistent, &exprs[..]);
self.commasep_exprs(Inconsistent, exprs);
self.s.word("]");
self.end();
}
@ -1722,7 +1720,7 @@ impl<'a> State<'a> {
self.print_inner_attributes_inline(attrs);
self.commasep_cmnt(
Consistent,
&fields[..],
fields,
|s, field| {
s.print_outer_attributes(&field.attrs);
s.ibox(INDENT_UNIT);
@ -1757,7 +1755,7 @@ impl<'a> State<'a> {
fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>], attrs: &[ast::Attribute]) {
self.popen();
self.print_inner_attributes_inline(attrs);
self.commasep_exprs(Inconsistent, &exprs[..]);
self.commasep_exprs(Inconsistent, exprs);
if exprs.len() == 1 {
self.s.word(",");
}

View File

@ -176,7 +176,7 @@ pub fn find_stability(
sess: &Session,
attrs: &[Attribute],
item_sp: Span,
) -> (Option<Stability>, Option<ConstStability>) {
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>) {
find_stability_generic(sess, attrs.iter(), item_sp)
}
@ -184,15 +184,16 @@ fn find_stability_generic<'a, I>(
sess: &Session,
attrs_iter: I,
item_sp: Span,
) -> (Option<Stability>, Option<ConstStability>)
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>)
where
I: Iterator<Item = &'a Attribute>,
{
use StabilityLevel::*;
let mut stab: Option<Stability> = None;
let mut const_stab: Option<ConstStability> = None;
let mut stab: Option<(Stability, Span)> = None;
let mut const_stab: Option<(ConstStability, Span)> = None;
let mut promotable = false;
let diagnostic = &sess.parse_sess.span_diagnostic;
'outer: for attr in attrs_iter {
@ -356,10 +357,12 @@ where
}
let level = Unstable { reason, issue: issue_num, is_soft };
if sym::unstable == meta_name {
stab = Some(Stability { level, feature });
stab = Some((Stability { level, feature }, attr.span));
} else {
const_stab =
Some(ConstStability { level, feature, promotable: false });
const_stab = Some((
ConstStability { level, feature, promotable: false },
attr.span,
));
}
}
(None, _, _) => {
@ -432,10 +435,12 @@ where
(Some(feature), Some(since)) => {
let level = Stable { since };
if sym::stable == meta_name {
stab = Some(Stability { level, feature });
stab = Some((Stability { level, feature }, attr.span));
} else {
const_stab =
Some(ConstStability { level, feature, promotable: false });
const_stab = Some((
ConstStability { level, feature, promotable: false },
attr.span,
));
}
}
(None, _) => {
@ -455,7 +460,7 @@ where
// Merge the const-unstable info into the stability info
if promotable {
if let Some(ref mut stab) = const_stab {
if let Some((ref mut stab, _)) = const_stab {
stab.promotable = promotable;
} else {
struct_span_err!(
@ -1035,14 +1040,14 @@ pub fn find_transparency(
pub fn allow_internal_unstable<'a>(
sess: &'a Session,
attrs: &'a [Attribute],
) -> Option<impl Iterator<Item = Symbol> + 'a> {
) -> impl Iterator<Item = Symbol> + 'a {
allow_unstable(sess, attrs, sym::allow_internal_unstable)
}
pub fn rustc_allow_const_fn_unstable<'a>(
sess: &'a Session,
attrs: &'a [Attribute],
) -> Option<impl Iterator<Item = Symbol> + 'a> {
) -> impl Iterator<Item = Symbol> + 'a {
allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable)
}
@ -1050,7 +1055,7 @@ fn allow_unstable<'a>(
sess: &'a Session,
attrs: &'a [Attribute],
symbol: Symbol,
) -> Option<impl Iterator<Item = Symbol> + 'a> {
) -> impl Iterator<Item = Symbol> + 'a {
let attrs = sess.filter_by_name(attrs, symbol);
let list = attrs
.filter_map(move |attr| {
@ -1064,7 +1069,7 @@ fn allow_unstable<'a>(
})
.flatten();
Some(list.into_iter().filter_map(move |it| {
list.into_iter().filter_map(move |it| {
let name = it.ident().map(|ident| ident.name);
if name.is_none() {
sess.diagnostic().span_err(
@ -1073,5 +1078,5 @@ fn allow_unstable<'a>(
);
}
name
}))
})
}

View File

@ -0,0 +1,157 @@
use crate::util::check_builtin_macro_attribute;
use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AstLike};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_expand::config::StripUnconfigured;
use rustc_expand::configure;
use rustc_span::symbol::sym;
use rustc_span::Span;
use smallvec::SmallVec;
crate fn expand(
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
annotatable: Annotatable,
) -> Vec<Annotatable> {
check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval);
cfg_eval(ecx, annotatable)
}
crate fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Vec<Annotatable> {
let mut visitor = CfgEval {
cfg: StripUnconfigured { sess: ecx.sess, features: ecx.ecfg.features, modified: false },
};
let mut annotatable = visitor.configure_annotatable(annotatable);
if visitor.cfg.modified {
// Erase the tokens if cfg-stripping modified the item
// This will cause us to synthesize fake tokens
// when `nt_to_tokenstream` is called on this item.
if let Some(tokens) = annotatable.tokens_mut() {
*tokens = None;
}
}
vec![annotatable]
}
struct CfgEval<'a> {
cfg: StripUnconfigured<'a>,
}
impl CfgEval<'_> {
fn configure<T: AstLike>(&mut self, node: T) -> Option<T> {
self.cfg.configure(node)
}
fn configure_annotatable(&mut self, annotatable: Annotatable) -> Annotatable {
// Since the item itself has already been configured by the InvocationCollector,
// we know that fold result vector will contain exactly one element
match annotatable {
Annotatable::Item(item) => Annotatable::Item(self.flat_map_item(item).pop().unwrap()),
Annotatable::TraitItem(item) => {
Annotatable::TraitItem(self.flat_map_trait_item(item).pop().unwrap())
}
Annotatable::ImplItem(item) => {
Annotatable::ImplItem(self.flat_map_impl_item(item).pop().unwrap())
}
Annotatable::ForeignItem(item) => {
Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
}
Annotatable::Stmt(stmt) => {
Annotatable::Stmt(stmt.map(|stmt| self.flat_map_stmt(stmt).pop().unwrap()))
}
Annotatable::Expr(mut expr) => Annotatable::Expr({
self.visit_expr(&mut expr);
expr
}),
Annotatable::Arm(arm) => Annotatable::Arm(self.flat_map_arm(arm).pop().unwrap()),
Annotatable::Field(field) => {
Annotatable::Field(self.flat_map_field(field).pop().unwrap())
}
Annotatable::FieldPat(fp) => {
Annotatable::FieldPat(self.flat_map_field_pattern(fp).pop().unwrap())
}
Annotatable::GenericParam(param) => {
Annotatable::GenericParam(self.flat_map_generic_param(param).pop().unwrap())
}
Annotatable::Param(param) => {
Annotatable::Param(self.flat_map_param(param).pop().unwrap())
}
Annotatable::StructField(sf) => {
Annotatable::StructField(self.flat_map_struct_field(sf).pop().unwrap())
}
Annotatable::Variant(v) => {
Annotatable::Variant(self.flat_map_variant(v).pop().unwrap())
}
}
}
}
impl MutVisitor for CfgEval<'_> {
fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
self.cfg.configure_expr(expr);
mut_visit::noop_visit_expr(expr, self);
}
fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
let mut expr = configure!(self, expr);
mut_visit::noop_visit_expr(&mut expr, self);
Some(expr)
}
fn flat_map_generic_param(
&mut self,
param: ast::GenericParam,
) -> SmallVec<[ast::GenericParam; 1]> {
mut_visit::noop_flat_map_generic_param(configure!(self, param), self)
}
fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
mut_visit::noop_flat_map_stmt(configure!(self, stmt), self)
}
fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
mut_visit::noop_flat_map_item(configure!(self, item), self)
}
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
mut_visit::noop_flat_map_assoc_item(configure!(self, item), self)
}
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
mut_visit::noop_flat_map_assoc_item(configure!(self, item), self)
}
fn flat_map_foreign_item(
&mut self,
foreign_item: P<ast::ForeignItem>,
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
mut_visit::noop_flat_map_foreign_item(configure!(self, foreign_item), self)
}
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
mut_visit::noop_flat_map_arm(configure!(self, arm), self)
}
fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
mut_visit::noop_flat_map_field(configure!(self, field), self)
}
fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
mut_visit::noop_flat_map_field_pattern(configure!(self, fp), self)
}
fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
mut_visit::noop_flat_map_param(configure!(self, p), self)
}
fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
mut_visit::noop_flat_map_struct_field(configure!(self, sf), self)
}
fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
mut_visit::noop_flat_map_variant(configure!(self, variant), self)
}
}

View File

@ -1,7 +1,8 @@
use crate::cfg_eval::cfg_eval;
use rustc_ast::{self as ast, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
use rustc_errors::{struct_span_err, Applicability};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_expand::config::StripUnconfigured;
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
use rustc_session::Session;
@ -51,26 +52,7 @@ impl MultiItemModifier for Expander {
// FIXME: Try to cache intermediate results to avoid collecting same paths multiple times.
match ecx.resolver.resolve_derives(ecx.current_expansion.id, derives, ecx.force_mode) {
Ok(()) => {
let mut visitor =
StripUnconfigured { sess, features: ecx.ecfg.features, modified: false };
let mut item = visitor.fully_configure(item);
if visitor.modified {
// Erase the tokens if cfg-stripping modified the item
// This will cause us to synthesize fake tokens
// when `nt_to_tokenstream` is called on this item.
match &mut item {
Annotatable::Item(item) => item,
Annotatable::Stmt(stmt) => match &mut stmt.kind {
StmtKind::Item(item) => item,
_ => unreachable!(),
},
_ => unreachable!(),
}
.tokens = None;
}
ExpandResult::Ready(vec![item])
}
Ok(()) => ExpandResult::Ready(cfg_eval(ecx, item)),
Err(Indeterminate) => ExpandResult::Retry(item),
}
}

View File

@ -270,7 +270,7 @@ impl<'a, 'b> Context<'a, 'b> {
parse::ArgumentNamed(s) => Named(s),
};
let ty = Placeholder(match &arg.format.ty[..] {
let ty = Placeholder(match arg.format.ty {
"" => "Display",
"?" => "Debug",
"e" => "LowerExp",

View File

@ -312,7 +312,7 @@ pub mod printf {
return Some((Substitution::Escape, &s[start + 2..]));
}
Cur::new_at(&s[..], start)
Cur::new_at(s, start)
};
// This is meant to be a translation of the following regex:
@ -673,7 +673,7 @@ pub mod shell {
_ => { /* fall-through */ }
}
Cur::new_at(&s[..], start)
Cur::new_at(s, start)
};
let at = at.at_next_cp()?;

View File

@ -28,7 +28,7 @@ pub fn expand_global_asm<'cx>(
ident: Ident::invalid(),
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
kind: ast::ItemKind::GlobalAsm(P(global_asm)),
kind: ast::ItemKind::GlobalAsm(global_asm),
vis: ast::Visibility {
span: sp.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,

View File

@ -11,6 +11,7 @@
#![feature(or_patterns)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![recursion_limit = "256"]
extern crate proc_macro;
@ -24,6 +25,7 @@ mod asm;
mod assert;
mod cfg;
mod cfg_accessible;
mod cfg_eval;
mod compile_error;
mod concat;
mod concat_idents;
@ -89,6 +91,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
register_attr! {
bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander,
cfg_eval: cfg_eval::expand,
derive: derive::Expander,
global_allocator: global_allocator::expand,
test: test::expand_test,

View File

@ -91,7 +91,7 @@ pub fn inject(
}
let decls = mk_decls(&mut krate, &mut cx, &macros);
krate.module.items.push(decls);
krate.items.push(decls);
krate
}

View File

@ -4,7 +4,7 @@ use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_expand::base::{self, *};
use rustc_expand::module::DirectoryOwnership;
use rustc_expand::module::DirOwnership;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_parse::{self, new_parser_from_file};
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
@ -101,7 +101,7 @@ pub fn expand_include<'cx>(
None => return DummyResult::any(sp),
};
// The file will be added to the code map by the parser
let mut file = match cx.resolve_path(file, sp) {
let file = match cx.resolve_path(file, sp) {
Ok(f) => f,
Err(mut err) => {
err.emit();
@ -114,10 +114,9 @@ pub fn expand_include<'cx>(
// then the path of `bar.rs` should be relative to the directory of `file`.
// See https://github.com/rust-lang/rust/pull/69838/files#r395217057 for a discussion.
// `MacroExpander::fully_expand_fragment` later restores, so "stack discipline" is maintained.
file.pop();
cx.current_expansion.directory_ownership = DirectoryOwnership::Owned { relative: None };
let mod_path = cx.current_expansion.module.mod_path.clone();
cx.current_expansion.module = Rc::new(ModuleData { mod_path, directory: file });
let dir_path = file.parent().unwrap_or(&file).to_owned();
cx.current_expansion.module = Rc::new(cx.current_expansion.module.with_dir_path(dir_path));
cx.current_expansion.dir_ownership = DirOwnership::Owned { relative: None };
struct ExpandResult<'a> {
p: Parser<'a>,

View File

@ -1,9 +1,8 @@
use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::ExpansionConfig;
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::edition::Edition::*;
use rustc_span::hygiene::AstPass;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::DUMMY_SP;
@ -14,7 +13,7 @@ pub fn inject(
sess: &Session,
alt_std_name: Option<Symbol>,
) -> ast::Crate {
let rust_2018 = sess.parse_sess.edition >= Edition::Edition2018;
let edition = sess.parse_sess.edition;
// the first name in this list is the crate name of the crate with the prelude
let names: &[Symbol] = if sess.contains_name(&krate.attrs, sym::no_core) {
@ -43,8 +42,12 @@ pub fn inject(
// .rev() to preserve ordering above in combination with insert(0, ...)
for &name in names.iter().rev() {
let ident = if rust_2018 { Ident::new(name, span) } else { Ident::new(name, call_site) };
krate.module.items.insert(
let ident = if edition >= Edition2018 {
Ident::new(name, span)
} else {
Ident::new(name, call_site)
};
krate.items.insert(
0,
cx.item(
span,
@ -59,27 +62,31 @@ pub fn inject(
// the one with the prelude.
let name = names[0];
let import_path = if rust_2018 {
[name, sym::prelude, sym::v1].iter().map(|symbol| Ident::new(*symbol, span)).collect()
} else {
[kw::PathRoot, name, sym::prelude, sym::v1]
.iter()
.map(|symbol| Ident::new(*symbol, span))
.collect()
};
let root = (edition == Edition2015).then(|| kw::PathRoot);
let import_path = root
.iter()
.chain(&[name, sym::prelude])
.chain(&[match edition {
Edition2015 => sym::rust_2015,
Edition2018 => sym::rust_2018,
Edition2021 => sym::rust_2021,
}])
.map(|&symbol| Ident::new(symbol, span))
.collect();
let use_item = cx.item(
span,
Ident::invalid(),
vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
ast::ItemKind::Use(P(ast::UseTree {
ast::ItemKind::Use(ast::UseTree {
prefix: cx.path(span, import_path),
kind: ast::UseTreeKind::Glob,
span,
})),
}),
);
krate.module.items.insert(0, use_item);
krate.items.insert(0, use_item);
krate
}

View File

@ -1,10 +1,10 @@
// Code that generates a test runner to run all the tests in a crate
use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::entry::EntryPointType;
use rustc_ast::mut_visit::{ExpectOne, *};
use rustc_ast::ptr::P;
use rustc_ast::{attr, ModKind};
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
@ -89,7 +89,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
noop_visit_crate(c, self);
// Create a main function to run our tests
c.module.items.push(mk_main(&mut self.cx));
c.items.push(mk_main(&mut self.cx));
}
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
@ -103,9 +103,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
// We don't want to recurse into anything other than mods, since
// mods or tests inside of functions will break things
if let ast::ItemKind::Mod(mut module) = item.kind {
if let ast::ItemKind::Mod(..) = item.kind {
let tests = mem::take(&mut self.tests);
noop_visit_mod(&mut module, self);
noop_visit_item_kind(&mut item.kind, self);
let mut tests = mem::replace(&mut self.tests, tests);
if !tests.is_empty() {
@ -113,8 +113,12 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
if item.id == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { item.id };
// Create an identifier that will hygienically resolve the test
// case name, even in another module.
let inner_span = match item.kind {
ast::ItemKind::Mod(_, ModKind::Loaded(.., span)) => span,
_ => unreachable!(),
};
let expn_id = self.cx.ext_cx.resolver.expansion_for_ast_pass(
module.inner,
inner_span,
AstPass::TestHarness,
&[],
Some(parent),
@ -126,7 +130,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
}
self.cx.test_cases.extend(tests);
}
item.kind = ast::ItemKind::Mod(module);
}
smallvec![P(item)]
}

View File

@ -0,0 +1,25 @@
task:
name: freebsd
freebsd_instance:
image: freebsd-12-1-release-amd64
setup_rust_script:
- pkg install -y curl git bash
- curl https://sh.rustup.rs -sSf --output rustup.sh
- sh rustup.sh --default-toolchain none -y --profile=minimal
cargo_bin_cache:
folder: ~/.cargo/bin
target_cache:
folder: target
prepare_script:
- . $HOME/.cargo/env
- git config --global user.email "user@example.com"
- git config --global user.name "User"
- ./prepare.sh
test_script:
- . $HOME/.cargo/env
- # Enable backtraces for easier debugging
- export RUST_BACKTRACE=1
- # Reduce amount of benchmark runs as they are slow
- export COMPILE_RUNS=2
- export RUN_RUNS=2
- ./test.sh

View File

@ -12,9 +12,6 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
env:
- BACKEND: ""
- BACKEND: --oldbe
steps:
- uses: actions/checkout@v2
@ -54,7 +51,7 @@ jobs:
export COMPILE_RUNS=2
export RUN_RUNS=2
./test.sh $BACKEND
./test.sh
- name: Package prebuilt cg_clif
run: tar cvfJ cg_clif.tar.xz build

View File

@ -1,6 +1,6 @@
{
// source for rustc_* is not included in the rust-src component; disable the errors about this
"rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate"],
"rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "macro-error"],
"rust-analyzer.assist.importMergeBehavior": "last",
"rust-analyzer.cargo.loadOutDirsFromCheck": true,
"rust-analyzer.linkedProjects": [

View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.38"
@ -29,18 +31,6 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
[[package]]
name = "cc"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -49,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"byteorder",
"cranelift-bforest",
@ -75,8 +65,8 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"cranelift-codegen-shared",
"cranelift-entity",
@ -84,18 +74,18 @@ dependencies = [
[[package]]
name = "cranelift-codegen-shared"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
[[package]]
name = "cranelift-entity"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
[[package]]
name = "cranelift-frontend"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"cranelift-codegen",
"log",
@ -105,8 +95,8 @@ dependencies = [
[[package]]
name = "cranelift-jit"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -123,8 +113,8 @@ dependencies = [
[[package]]
name = "cranelift-module"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -135,18 +125,17 @@ dependencies = [
[[package]]
name = "cranelift-native"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"cranelift-codegen",
"raw-cpuid",
"target-lexicon",
]
[[package]]
name = "cranelift-object"
version = "0.69.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca"
version = "0.70.0"
source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -162,7 +151,7 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
"cfg-if",
]
[[package]]
@ -219,9 +208,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.82"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
[[package]]
name = "libloading"
@ -229,17 +218,17 @@ version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883"
dependencies = [
"cfg-if 1.0.0",
"cfg-if",
"winapi",
]
[[package]]
name = "log"
version = "0.4.13"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if 0.1.10",
"cfg-if",
]
[[package]]
@ -253,9 +242,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.22.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
dependencies = [
"crc32fast",
"indexmap",
@ -272,24 +261,13 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.8"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-cpuid"
version = "8.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fdf7d9dbd43f3d81d94a49c1c3df73cc2b3827995147e6cf7f89d4ec5483e73"
dependencies = [
"bitflags",
"cc",
"rustc_version",
]
[[package]]
name = "regalloc"
version = "0.0.31"
@ -337,30 +315,6 @@ dependencies = [
"target-lexicon",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "smallvec"
version = "1.6.1"
@ -369,9 +323,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
name = "syn"
version = "1.0.58"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [
"proc-macro2",
"quote",
@ -380,24 +334,24 @@ dependencies = [
[[package]]
name = "target-lexicon"
version = "0.11.1"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee5a98e506fb7231a304c3a1bd7c132a55016cf65001e0282480665870dfcb9"
checksum = "422045212ea98508ae3d28025bc5aaa2bd4a9cdaecd442a08da2ee620ee9ea95"
[[package]]
name = "thiserror"
version = "1.0.23"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.23"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
dependencies = [
"proc-macro2",
"quote",

View File

@ -9,14 +9,14 @@ crate-type = ["dylib"]
[dependencies]
# These have to be in sync with each other
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind", "x86", "x64"] }
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind", "x64"] }
cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", optional = true }
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
target-lexicon = "0.11.0"
gimli = { version = "0.23.0", default-features = false, features = ["write"]}
object = { version = "0.22.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] }
object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] }
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
indexmap = "1.0.2"
@ -38,7 +38,6 @@ smallvec = "1.6.1"
default = ["jit", "inline_asm"]
jit = ["cranelift-jit", "libloading"]
inline_asm = []
oldbe = []
[profile.dev]
# By compiling dependencies with optimizations, performing tests gets much faster.

View File

@ -1,11 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
# Settings
export CHANNEL="release"
build_sysroot="clif"
target_dir='build'
oldbe=''
while [[ $# != 0 ]]; do
case $1 in
"--debug")
@ -19,12 +18,9 @@ while [[ $# != 0 ]]; do
target_dir=$2
shift
;;
"--oldbe")
oldbe='--features oldbe'
;;
*)
echo "Unknown flag '$1'"
echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--oldbe]"
echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]"
exit 1
;;
esac
@ -34,19 +30,19 @@ done
# Build cg_clif
unset CARGO_TARGET_DIR
unamestr=$(uname)
if [[ "$unamestr" == 'Linux' ]]; then
if [[ "$unamestr" == 'Linux' || "$unamestr" == "FreeBSD" ]]; then
export RUSTFLAGS='-Clink-arg=-Wl,-rpath=$ORIGIN/../lib '$RUSTFLAGS
elif [[ "$unamestr" == 'Darwin' ]]; then
export RUSTFLAGS='-Csplit-debuginfo=unpacked -Clink-arg=-Wl,-rpath,@loader_path/../lib -Zosx-rpath-install-name '$RUSTFLAGS
dylib_ext='dylib'
else
echo "Unsupported os"
echo "Unsupported os $unamestr"
exit 1
fi
if [[ "$CHANNEL" == "release" ]]; then
cargo build $oldbe --release
cargo build --release
else
cargo build $oldbe
cargo build
fi
source scripts/ext_config.sh

View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.14.1"
@ -30,15 +32,6 @@ dependencies = [
"core",
]
[[package]]
name = "alloc_system"
version = "0.0.0"
dependencies = [
"compiler_builtins",
"core",
"libc",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@ -47,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "cc"
version = "1.0.66"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
@ -139,9 +132,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.84"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
dependencies = [
"rustc-std-workspace-core",
]
@ -258,7 +251,6 @@ name = "sysroot"
version = "0.0.0"
dependencies = [
"alloc",
"alloc_system",
"compiler_builtins",
"core",
"std",

View File

@ -9,8 +9,6 @@ alloc = { path = "./sysroot_src/library/alloc" }
std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
test = { path = "./sysroot_src/library/test" }
alloc_system = { path = "./alloc_system" }
compiler_builtins = { version = "0.1.39", default-features = false, features = ["no-asm"] }
[patch.crates-io]

View File

@ -1,13 +0,0 @@
[package]
authors = ["The Rust Project Developers", "bjorn3 (edited to be usable outside the rust source)"]
name = "alloc_system"
version = "0.0.0"
[lib]
name = "alloc_system"
path = "lib.rs"
test = false
doc = false
[dependencies]
core = { path = "../sysroot_src/library/core" }
libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
compiler_builtins = "0.1"

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Requires the CHANNEL env var to be set to `debug` or `release.`

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")"
@ -33,7 +33,7 @@ git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/
pushd compiler-builtins
git checkout -- .
git checkout 0.1.39
git apply ../../crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch
git apply ../../crate_patches/000*-compiler-builtins-*.patch
popd
echo "Successfully prepared sysroot source for building"

View File

@ -1,4 +1,4 @@
#!/bin/bash --verbose
#!/usr/bin/env bash
set -e
rm -rf target/ build/ build_sysroot/{sysroot_src/,target/,compiler-builtins/} perf.data{,.old}

View File

@ -0,0 +1,48 @@
From 1d574bf5e32d51641dcacaf8ef777e95b44f6f2a Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 18 Feb 2021 18:30:55 +0100
Subject: [PATCH] Disable 128bit atomic operations
Cranelift doesn't support them yet
---
src/mem/mod.rs | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/src/mem/mod.rs b/src/mem/mod.rs
index 107762c..2d1ae10 100644
--- a/src/mem/mod.rs
+++ b/src/mem/mod.rs
@@ -137,10 +137,6 @@ intrinsics! {
pub extern "C" fn __llvm_memcpy_element_unordered_atomic_8(dest: *mut u64, src: *const u64, bytes: usize) -> () {
memcpy_element_unordered_atomic(dest, src, bytes);
}
- #[cfg(target_has_atomic_load_store = "128")]
- pub extern "C" fn __llvm_memcpy_element_unordered_atomic_16(dest: *mut u128, src: *const u128, bytes: usize) -> () {
- memcpy_element_unordered_atomic(dest, src, bytes);
- }
#[cfg(target_has_atomic_load_store = "8")]
pub extern "C" fn __llvm_memmove_element_unordered_atomic_1(dest: *mut u8, src: *const u8, bytes: usize) -> () {
@@ -158,10 +154,6 @@ intrinsics! {
pub extern "C" fn __llvm_memmove_element_unordered_atomic_8(dest: *mut u64, src: *const u64, bytes: usize) -> () {
memmove_element_unordered_atomic(dest, src, bytes);
}
- #[cfg(target_has_atomic_load_store = "128")]
- pub extern "C" fn __llvm_memmove_element_unordered_atomic_16(dest: *mut u128, src: *const u128, bytes: usize) -> () {
- memmove_element_unordered_atomic(dest, src, bytes);
- }
#[cfg(target_has_atomic_load_store = "8")]
pub extern "C" fn __llvm_memset_element_unordered_atomic_1(s: *mut u8, c: u8, bytes: usize) -> () {
@@ -179,8 +171,4 @@ intrinsics! {
pub extern "C" fn __llvm_memset_element_unordered_atomic_8(s: *mut u64, c: u8, bytes: usize) -> () {
memset_element_unordered_atomic(s, c, bytes);
}
- #[cfg(target_has_atomic_load_store = "128")]
- pub extern "C" fn __llvm_memset_element_unordered_atomic_16(s: *mut u128, c: u8, bytes: usize) -> () {
- memset_element_unordered_atomic(s, c, bytes);
- }
}
--
2.26.2.7.g19db9cfb68

View File

@ -1,4 +1,4 @@
#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)]
#![feature(start, box_syntax, core_intrinsics, alloc_prelude, alloc_error_handler)]
#![no_std]
extern crate alloc;

View File

@ -8,66 +8,24 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![no_std]
#![allow(unused_attributes)]
#![unstable(feature = "alloc_system",
reason = "this library is unlikely to be stabilized in its current \
form or name",
issue = "32838")]
#![feature(allocator_api)]
#![feature(core_intrinsics)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(rustc_attrs)]
#![feature(alloc_layout_extra)]
#![cfg_attr(
all(target_arch = "wasm32", not(target_os = "emscripten")),
feature(integer_atomics, stdsimd)
)]
#![feature(allocator_api, rustc_private)]
#![cfg_attr(any(unix, target_os = "redox"), feature(libc))]
// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
#[cfg(all(any(target_arch = "x86",
target_arch = "arm",
target_arch = "mips",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "asmjs",
target_arch = "wasm32")))]
#[allow(dead_code)]
target_arch = "powerpc64")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "mips64",
target_arch = "s390x",
target_arch = "sparc64")))]
#[allow(dead_code)]
const MIN_ALIGN: usize = 16;
/// The default memory allocator provided by the operating system.
///
/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
/// plus related functions.
///
/// This type can be used in a `static` item
/// with the `#[global_allocator]` attribute
/// to force the global allocator to be the systems one.
/// (The default is jemalloc for executables, on some platforms.)
///
/// ```rust
/// use std::alloc::System;
///
/// #[global_allocator]
/// static A: System = System;
///
/// fn main() {
/// let a = Box::new(4); // Allocates from the system allocator.
/// println!("{}", a);
/// }
/// ```
///
/// It can also be used directly to allocate memory
/// independently of the standard librarys global allocator.
#[stable(feature = "alloc_system_type", since = "1.28.0")]
pub struct System;
#[cfg(any(windows, unix, target_os = "redox"))]
mod realloc_fallback {
@ -96,7 +54,6 @@ mod platform {
use MIN_ALIGN;
use System;
use core::alloc::{GlobalAlloc, Layout};
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
@ -221,7 +178,6 @@ mod platform {
};
ptr as *mut u8
}
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
@ -254,89 +210,3 @@ mod platform {
}
}
}
// This is an implementation of a global allocator on the wasm32 platform when
// emscripten is not in use. In that situation there's no actual runtime for us
// to lean on for allocation, so instead we provide our own!
//
// The wasm32 instruction set has two instructions for getting the current
// amount of memory and growing the amount of memory. These instructions are the
// foundation on which we're able to build an allocator, so we do so! Note that
// the instructions are also pretty "global" and this is the "global" allocator
// after all!
//
// The current allocator here is the `dlmalloc` crate which we've got included
// in the rust-lang/rust repository as a submodule. The crate is a port of
// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust"
// for now which is currently technically required (can't link with C yet).
//
// The crate itself provides a global allocator which on wasm has no
// synchronization as there are no threads!
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
mod platform {
extern crate dlmalloc;
use core::alloc::{GlobalAlloc, Layout};
use System;
static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let _lock = lock::lock();
DLMALLOC.malloc(layout.size(), layout.align())
}
#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let _lock = lock::lock();
DLMALLOC.calloc(layout.size(), layout.align())
}
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
let _lock = lock::lock();
DLMALLOC.free(ptr, layout.size(), layout.align())
}
#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
let _lock = lock::lock();
DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
}
}
#[cfg(target_feature = "atomics")]
mod lock {
use core::arch::wasm32;
use core::sync::atomic::{AtomicI32, Ordering::SeqCst};
static LOCKED: AtomicI32 = AtomicI32::new(0);
pub struct DropLock;
pub fn lock() -> DropLock {
loop {
if LOCKED.swap(1, SeqCst) == 0 {
return DropLock
}
unsafe {
let r = wasm32::atomic::wait_i32(
&LOCKED as *const AtomicI32 as *mut i32,
1, // expected value
-1, // timeout
);
debug_assert!(r == 0 || r == 1);
}
}
}
impl Drop for DropLock {
fn drop(&mut self) {
let r = LOCKED.swap(0, SeqCst);
debug_assert_eq!(r, 1);
unsafe {
wasm32::atomic::wake(
&LOCKED as *const AtomicI32 as *mut i32,
1, // only one thread
);
}
}
}
}
#[cfg(not(target_feature = "atomics"))]
mod lock {
#[inline]
pub fn lock() {} // no atomics, no threads, that's easy!
}
}

View File

@ -1,22 +1,12 @@
// Adapted from rustc run-pass test suite
#![feature(no_core, arbitrary_self_types, box_syntax)]
#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
#![feature(rustc_attrs)]
#![feature(start, lang_items)]
#![no_core]
extern crate mini_core;
use mini_core::*;
macro_rules! assert_eq {
($l:expr, $r: expr) => {
if $l != $r {
panic(stringify!($l != $r));
}
}
}
use std::{
ops::{Deref, CoerceUnsized, DispatchFromDyn},
marker::Unsize,
};
struct Ptr<T: ?Sized>(Box<T>);
@ -67,16 +57,13 @@ impl Trait for i32 {
}
}
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
let pw = Ptr(box Wrapper(5)) as Ptr<Wrapper<dyn Trait>>;
fn main() {
let pw = Ptr(Box::new(Wrapper(5))) as Ptr<Wrapper<dyn Trait>>;
assert_eq!(pw.ptr_wrapper(), 5);
let wp = Wrapper(Ptr(box 6)) as Wrapper<Ptr<dyn Trait>>;
let wp = Wrapper(Ptr(Box::new(6))) as Wrapper<Ptr<dyn Trait>>;
assert_eq!(wp.wrapper_ptr(), 6);
let wpw = Wrapper(Ptr(box Wrapper(7))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
0
}

View File

@ -365,6 +365,22 @@ impl <T: PartialEq> PartialEq for Option<T> {
}
}
#[lang = "shl"]
pub trait Shl<RHS = Self> {
type Output;
#[must_use]
fn shl(self, rhs: RHS) -> Self::Output;
}
impl Shl for u128 {
type Output = u128;
fn shl(self, rhs: u128) -> u128 {
self << rhs
}
}
#[lang = "neg"]
pub trait Neg {
type Output;

View File

@ -264,6 +264,9 @@ fn main() {
assert_eq!(f2 as i8, -128);
assert_eq!(f2 as u8, 0);
let amount = 0;
assert_eq!(1u128 << amount, 1);
static ANOTHER_STATIC: &u8 = &A_STATIC;
assert_eq!(*ANOTHER_STATIC, 42);

View File

@ -119,21 +119,5 @@ index 6609bc3..241b497 100644
#[test]
#[should_panic(expected = "index 0 greater than length of slice")]
diff --git a/library/core/tests/num/ops.rs b/library/core/tests/num/ops.rs
index 9979cc8..d5d1d83 100644
--- a/library/core/tests/num/ops.rs
+++ b/library/core/tests/num/ops.rs
@@ -238,7 +238,7 @@ macro_rules! test_shift_assign {
}
};
}
-test_shift!(test_shl_defined, Shl::shl);
-test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign);
-test_shift!(test_shr_defined, Shr::shr);
-test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign);
+//test_shift!(test_shl_defined, Shl::shl);
+//test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign);
+//test_shift!(test_shr_defined, Shr::shr);
+//test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign);
--
2.21.0 (Apple Git-122)

View File

@ -0,0 +1,103 @@
From 894e07dfec2624ba539129b1c1d63e1d7d812bda Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 18 Feb 2021 18:45:28 +0100
Subject: [PATCH] Disable 128bit atomic operations
Cranelift doesn't support them yet
---
library/core/src/sync/atomic.rs | 38 ---------------------------------
library/core/tests/atomic.rs | 4 ----
library/std/src/panic.rs | 6 ------
3 files changed, 48 deletions(-)
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 81c9e1d..65c9503 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -2228,44 +2228,6 @@ atomic_int! {
"AtomicU64::new(0)",
u64 AtomicU64 ATOMIC_U64_INIT
}
-#[cfg(target_has_atomic_load_store = "128")]
-atomic_int! {
- cfg(target_has_atomic = "128"),
- cfg(target_has_atomic_equal_alignment = "128"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
- unstable(feature = "integer_atomics", issue = "32976"),
- "i128",
- "#![feature(integer_atomics)]\n\n",
- atomic_min, atomic_max,
- 16,
- "AtomicI128::new(0)",
- i128 AtomicI128 ATOMIC_I128_INIT
-}
-#[cfg(target_has_atomic_load_store = "128")]
-atomic_int! {
- cfg(target_has_atomic = "128"),
- cfg(target_has_atomic_equal_alignment = "128"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- unstable(feature = "integer_atomics", issue = "32976"),
- rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
- unstable(feature = "integer_atomics", issue = "32976"),
- "u128",
- "#![feature(integer_atomics)]\n\n",
- atomic_umin, atomic_umax,
- 16,
- "AtomicU128::new(0)",
- u128 AtomicU128 ATOMIC_U128_INIT
-}
macro_rules! atomic_int_ptr_sized {
( $($target_pointer_width:literal $align:literal)* ) => { $(
diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs
index 2d1e449..cb6da5d 100644
--- a/library/core/tests/atomic.rs
+++ b/library/core/tests/atomic.rs
@@ -145,10 +145,6 @@ fn atomic_alignment() {
assert_eq!(align_of::<AtomicU64>(), size_of::<AtomicU64>());
#[cfg(target_has_atomic = "64")]
assert_eq!(align_of::<AtomicI64>(), size_of::<AtomicI64>());
- #[cfg(target_has_atomic = "128")]
- assert_eq!(align_of::<AtomicU128>(), size_of::<AtomicU128>());
- #[cfg(target_has_atomic = "128")]
- assert_eq!(align_of::<AtomicI128>(), size_of::<AtomicI128>());
#[cfg(target_has_atomic = "ptr")]
assert_eq!(align_of::<AtomicUsize>(), size_of::<AtomicUsize>());
#[cfg(target_has_atomic = "ptr")]
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 89a822a..779fd88 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -279,9 +279,6 @@ impl RefUnwindSafe for atomic::AtomicI32 {}
#[cfg(target_has_atomic_load_store = "64")]
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl RefUnwindSafe for atomic::AtomicI64 {}
-#[cfg(target_has_atomic_load_store = "128")]
-#[unstable(feature = "integer_atomics", issue = "32976")]
-impl RefUnwindSafe for atomic::AtomicI128 {}
#[cfg(target_has_atomic_load_store = "ptr")]
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
@@ -298,9 +295,6 @@ impl RefUnwindSafe for atomic::AtomicU32 {}
#[cfg(target_has_atomic_load_store = "64")]
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl RefUnwindSafe for atomic::AtomicU64 {}
-#[cfg(target_has_atomic_load_store = "128")]
-#[unstable(feature = "integer_atomics", issue = "32976")]
-impl RefUnwindSafe for atomic::AtomicU128 {}
#[cfg(target_has_atomic_load_store = "8")]
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
--
2.26.2.7.g19db9cfb68

View File

@ -1,4 +1,4 @@
#!/bin/bash --verbose
#!/usr/bin/env bash
set -e
rustup component add rust-src rustc-dev llvm-tools-preview

View File

@ -1 +1 @@
nightly-2021-01-30
nightly-2021-03-05

View File

@ -0,0 +1,4 @@
# Matches rustfmt.toml of rustc
version = "Two"
use_small_heuristics = "Max"
merge_derives = false

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
dir=$(dirname "$0")
source "$dir/config.sh"

View File

@ -3,7 +3,7 @@
set -e
unamestr=$(uname)
if [[ "$unamestr" == 'Linux' ]]; then
if [[ "$unamestr" == 'Linux' || "$unamestr" == 'FreeBSD' ]]; then
dylib_ext='so'
elif [[ "$unamestr" == 'Darwin' ]]; then
dylib_ext='dylib'
@ -26,7 +26,7 @@ export RUSTC=$dir"/bin/cg_clif"
export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\
'-Zcodegen-backend='$dir'/lib/librustc_codegen_cranelift.'$dylib_ext' --sysroot '$dir
# FIXME remove once the atomic shim is gone
# FIXME fix `#[linkage = "extern_weak"]` without this
if [[ "$unamestr" == 'Darwin' ]]; then
export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup"
fi

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")/../"
@ -14,21 +14,18 @@ git checkout -- .
git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')"
git apply - <<EOF
diff --git a/.gitmodules b/.gitmodules
index 984113151de..c1e9d960d56 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -34,10 +34,6 @@
[submodule "src/doc/edition-guide"]
path = src/doc/edition-guide
url = https://github.com/rust-lang/edition-guide.git
-[submodule "src/llvm-project"]
- path = src/llvm-project
- url = https://github.com/rust-lang/llvm-project.git
- 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
diff --git a/Cargo.toml b/Cargo.toml
index 5bd1147cad5..10d68a2ff14 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -111,5 +111,7 @@ rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }
rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' }
rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }
+compiler_builtins = { path = "../build_sysroot/compiler-builtins" }
+
[patch."https://github.com/rust-lang/rust-clippy"]
clippy_lints = { path = "src/tools/clippy/clippy_lints" }
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 23e689fcae7..5f077b765b6 100644
--- a/compiler/rustc_data_structures/Cargo.toml
@ -41,6 +38,19 @@ index 23e689fcae7..5f077b765b6 100644
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["fileapi", "psapi"] }
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index d95b5b7f17f..00b6f0e3635 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -8,7 +8,7 @@ edition = "2018"
[dependencies]
core = { path = "../core" }
-compiler_builtins = { version = "0.1.39", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "0.1.39", features = ['rustc-dep-of-std', 'no-asm'] }
[dev-dependencies]
rand = "0.7"
EOF
cat > config.toml <<EOF

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
@ -27,13 +27,16 @@ function no_sysroot_tests() {
$MY_RUSTC example/mini_core_hello_world.rs --crate-name mini_core_hello_world --crate-type bin -g --target "$TARGET_TRIPLE"
$RUN_WRAPPER ./target/out/mini_core_hello_world abc bcd
# (echo "break set -n main"; echo "run"; sleep 1; echo "si -c 10"; sleep 1; echo "frame variable") | lldb -- ./target/out/mini_core_hello_world abc bcd
echo "[AOT] arbitrary_self_types_pointers_and_wrappers"
$MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
$RUN_WRAPPER ./target/out/arbitrary_self_types_pointers_and_wrappers
}
function base_sysroot_tests() {
echo "[AOT] arbitrary_self_types_pointers_and_wrappers"
$MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
$RUN_WRAPPER ./target/out/arbitrary_self_types_pointers_and_wrappers
echo "[AOT] alloc_system"
$MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"
echo "[AOT] alloc_example"
$MY_RUSTC example/alloc_example.rs --crate-type bin --target "$TARGET_TRIPLE"
$RUN_WRAPPER ./target/out/alloc_example

View File

@ -10,14 +10,14 @@ use cranelift_codegen::entity::EntityRef;
use crate::prelude::*;
pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) {
pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, '_>) {
fx.add_global_comment(
"kind loc.idx param pass mode ty".to_string(),
);
}
pub(super) fn add_arg_comment<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
kind: &str,
local: Option<mir::Local>,
local_field: Option<usize>,
@ -42,11 +42,7 @@ pub(super) fn add_arg_comment<'tcx>(
[param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)),
params => Cow::Owned(format!(
"= {}",
params
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(",")
params.iter().map(ToString::to_string).collect::<Vec<_>>().join(",")
)),
};
@ -62,7 +58,7 @@ pub(super) fn add_arg_comment<'tcx>(
));
}
pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) {
pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) {
fx.add_global_comment(String::new());
fx.add_global_comment(
"kind local ty size align (abi,pref)".to_string(),
@ -70,19 +66,13 @@ pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>
}
pub(super) fn add_local_place_comments<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
place: CPlace<'tcx>,
local: Local,
) {
let TyAndLayout { ty, layout } = place.layout();
let rustc_target::abi::Layout {
size,
align,
abi: _,
variants: _,
fields: _,
largest_niche: _,
} = layout;
let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } =
layout;
let (kind, extra) = match *place.inner() {
CPlaceInner::Var(place_local, var) => {
@ -91,10 +81,7 @@ pub(super) fn add_local_place_comments<'tcx>(
}
CPlaceInner::VarPair(place_local, var1, var2) => {
assert_eq!(local, place_local);
(
"ssa",
Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())),
)
("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())))
}
CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
CPlaceInner::Addr(ptr, meta) => {
@ -104,18 +91,15 @@ pub(super) fn add_local_place_comments<'tcx>(
Cow::Borrowed("")
};
match ptr.base_and_offset() {
(crate::pointer::PointerBase::Addr(addr), offset) => (
"reuse",
format!("storage={}{}{}", addr, offset, meta).into(),
),
(crate::pointer::PointerBase::Stack(stack_slot), offset) => (
"stack",
format!("storage={}{}{}", stack_slot, offset, meta).into(),
),
(crate::pointer::PointerBase::Dangling(align), offset) => (
"zst",
format!("align={},offset={}", align.bytes(), offset).into(),
),
(crate::pointer::PointerBase::Addr(addr), offset) => {
("reuse", format!("storage={}{}{}", addr, offset, meta).into())
}
(crate::pointer::PointerBase::Stack(stack_slot), offset) => {
("stack", format!("storage={}{}{}", stack_slot, offset, meta).into())
}
(crate::pointer::PointerBase::Dangling(align), offset) => {
("zst", format!("align={},offset={}", align.bytes(), offset).into())
}
}
}
};
@ -128,11 +112,7 @@ pub(super) fn add_local_place_comments<'tcx>(
size.bytes(),
align.abi.bytes(),
align.pref.bytes(),
if extra.is_empty() {
""
} else {
" "
},
if extra.is_empty() { "" } else { " " },
extra,
));
}

View File

@ -38,25 +38,15 @@ fn clif_sig_from_fn_abi<'tcx>(
| Conv::X86VectorCall
| Conv::AmdGpuKernel
| Conv::AvrInterrupt
| Conv::AvrNonBlockingInterrupt => {
todo!("{:?}", fn_abi.conv)
}
| Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv),
};
let inputs = fn_abi
.args
.iter()
.map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter())
.flatten();
let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
// Sometimes the first param is an pointer to the place where the return value needs to be stored.
let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
Signature {
params,
returns,
call_conv,
}
Signature { params, returns, call_conv }
}
pub(crate) fn get_function_sig<'tcx>(
@ -65,34 +55,25 @@ pub(crate) fn get_function_sig<'tcx>(
inst: Instance<'tcx>,
) -> Signature {
assert!(!inst.substs.needs_infer());
clif_sig_from_fn_abi(
tcx,
triple,
&FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]),
)
clif_sig_from_fn_abi(tcx, triple, &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]))
}
/// Instance must be monomorphized
pub(crate) fn import_function<'tcx>(
tcx: TyCtxt<'tcx>,
module: &mut impl Module,
module: &mut dyn Module,
inst: Instance<'tcx>,
) -> FuncId {
let name = tcx.symbol_name(inst).name.to_string();
let sig = get_function_sig(tcx, module.isa().triple(), inst);
module
.declare_function(&name, Linkage::Import, &sig)
.unwrap()
module.declare_function(&name, Linkage::Import, &sig).unwrap()
}
impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> {
impl<'tcx> FunctionCx<'_, '_, 'tcx> {
/// Instance must be monomorphized
pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef {
let func_id = import_function(self.tcx, &mut self.cx.module, inst);
let func_ref = self
.cx
.module
.declare_func_in_func(func_id, &mut self.bcx.func);
let func_id = import_function(self.tcx, self.cx.module, inst);
let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func);
#[cfg(debug_assertions)]
self.add_comment(func_ref, format!("{:?}", inst));
@ -107,20 +88,9 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> {
returns: Vec<AbiParam>,
args: &[Value],
) -> &[Value] {
let sig = Signature {
params,
returns,
call_conv: CallConv::triple_default(self.triple()),
};
let func_id = self
.cx
.module
.declare_function(&name, Linkage::Import, &sig)
.unwrap();
let func_ref = self
.cx
.module
.declare_func_in_func(func_id, &mut self.bcx.func);
let sig = Signature { params, returns, call_conv: CallConv::triple_default(self.triple()) };
let func_id = self.cx.module.declare_function(&name, Linkage::Import, &sig).unwrap();
let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func);
let call_inst = self.bcx.ins().call(func_ref, args);
#[cfg(debug_assertions)]
{
@ -140,17 +110,12 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> {
let (input_tys, args): (Vec<_>, Vec<_>) = args
.iter()
.map(|arg| {
(
AbiParam::new(self.clif_type(arg.layout().ty).unwrap()),
arg.load_scalar(self),
)
(AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self))
})
.unzip();
let return_layout = self.layout_of(return_ty);
let return_tys = if let ty::Tuple(tup) = return_ty.kind() {
tup.types()
.map(|ty| AbiParam::new(self.clif_type(ty).unwrap()))
.collect()
tup.types().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect()
} else {
vec![AbiParam::new(self.clif_type(return_ty).unwrap())]
};
@ -169,7 +134,7 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> {
/// Make a [`CPlace`] capable of holding value of the specified type.
fn make_local_place<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
local: Local,
layout: TyAndLayout<'tcx>,
is_ssa: bool,
@ -190,10 +155,7 @@ fn make_local_place<'tcx>(
place
}
pub(crate) fn codegen_fn_prelude<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
start_block: Block,
) {
pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_block: Block) {
fx.bcx.append_block_params_for_function_params(start_block);
fx.bcx.switch_to_block(start_block);
@ -204,13 +166,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
#[cfg(debug_assertions)]
self::comments::add_args_header_comment(fx);
let mut block_params_iter = fx
.bcx
.func
.dfg
.block_params(start_block)
.to_vec()
.into_iter();
let mut block_params_iter = fx.bcx.func.dfg.block_params(start_block).to_vec().into_iter();
let ret_place =
self::returning::codegen_return_param(fx, &ssa_analyzed, &mut block_params_iter);
assert_eq!(fx.local_map.push(ret_place), RETURN_PLACE);
@ -286,10 +242,10 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
if let Some((addr, meta)) = val.try_to_ptr() {
let local_decl = &fx.mir.local_decls[local];
// v this ! is important
let internally_mutable = !val.layout().ty.is_freeze(
fx.tcx.at(local_decl.source_info.span),
ParamEnv::reveal_all(),
);
let internally_mutable = !val
.layout()
.ty
.is_freeze(fx.tcx.at(local_decl.source_info.span), ParamEnv::reveal_all());
if local_decl.mutability == mir::Mutability::Not && !internally_mutable {
// We wont mutate this argument, so it is fine to borrow the backing storage
// of this argument, to prevent a copy.
@ -321,9 +277,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
ArgKind::Spread(params) => {
for (i, param) in params.into_iter().enumerate() {
if let Some(param) = param {
place
.place_field(fx, mir::Field::new(i))
.write_cvalue(fx, param);
place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param);
}
}
}
@ -340,13 +294,11 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
assert_eq!(fx.local_map.push(place), local);
}
fx.bcx
.ins()
.jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]);
fx.bcx.ins().jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]);
}
pub(crate) fn codegen_terminator_call<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
span: Span,
current_block: Block,
func: &Operand<'tcx>,
@ -354,9 +306,8 @@ pub(crate) fn codegen_terminator_call<'tcx>(
destination: Option<(Place<'tcx>, BasicBlock)>,
) {
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
let fn_sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
let fn_sig =
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
let destination = destination.map(|(place, bb)| (codegen_place(fx, place), bb));
@ -404,20 +355,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let fn_abi = if let Some(instance) = instance {
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
} else {
FnAbi::of_fn_ptr(
&RevealAllLayoutCx(fx.tcx),
fn_ty.fn_sig(fx.tcx),
&extra_args,
)
FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args)
};
let is_cold = instance
.map(|inst| {
fx.tcx
.codegen_fn_attrs(inst.def_id())
.flags
.contains(CodegenFnAttrFlags::COLD)
})
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
.unwrap_or(false);
if is_cold {
fx.cold_blocks.insert(current_block);
@ -441,9 +383,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
args
} else {
args.iter()
.map(|arg| codegen_operand(fx, arg))
.collect::<Vec<_>>()
args.iter().map(|arg| codegen_operand(fx, arg)).collect::<Vec<_>>()
};
// | indirect call target
@ -451,10 +391,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
// v v
let (func_ref, first_arg) = match instance {
// Trait object call
Some(Instance {
def: InstanceDef::Virtual(_, idx),
..
}) => {
Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => {
#[cfg(debug_assertions)]
{
let nop_inst = fx.bcx.ins().nop();
@ -511,10 +448,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
)
.collect::<Vec<_>>();
if instance
.map(|inst| inst.def.requires_caller_location(fx.tcx))
.unwrap_or(false)
{
if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) {
// Pass the caller location for `#[track_caller]`.
let caller_location = fx.get_caller_location(span);
call_args.extend(
@ -542,7 +476,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
// FIXME find a cleaner way to support varargs
if fn_sig.c_variadic {
if fn_sig.abi != Abi::C {
if !matches!(fn_sig.abi, Abi::C { .. }) {
fx.tcx.sess.span_fatal(
span,
&format!("Variadic call for non-C abi {:?}", fn_sig.abi),
@ -555,9 +489,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let ty = fx.bcx.func.dfg.value_type(arg);
if !ty.is_int() {
// FIXME set %al to upperbound on float args once floats are supported
fx.tcx
.sess
.span_fatal(span, &format!("Non int ty {:?} for variadic call", ty));
fx.tcx.sess.span_fatal(span, &format!("Non int ty {:?} for variadic call", ty));
}
AbiParam::new(ty)
})
@ -574,7 +506,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
pub(crate) fn codegen_drop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
span: Span,
drop_place: CPlace<'tcx>,
) {
@ -611,10 +543,7 @@ pub(crate) fn codegen_drop<'tcx>(
fx,
fx.layout_of(fx.tcx.mk_ref(
&ty::RegionKind::ReErased,
TypeAndMut {
ty,
mutbl: crate::rustc_hir::Mutability::Mut,
},
TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut },
)),
);
let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0]);

View File

@ -71,12 +71,7 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
.prefix
.iter()
.flatten()
.map(|&kind| {
reg_to_abi_param(Reg {
kind,
size: cast.prefix_chunk_size,
})
})
.map(|&kind| reg_to_abi_param(Reg { kind, size: cast.prefix_chunk_size }))
.chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))
.collect::<SmallVec<_>>();
@ -98,12 +93,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
match self.mode {
PassMode::Ignore => smallvec![],
PassMode::Direct(attrs) => match &self.layout.abi {
Abi::Scalar(scalar) => {
smallvec![apply_arg_attrs_to_abi_param(
AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())),
attrs
)]
}
Abi::Scalar(scalar) => smallvec![apply_arg_attrs_to_abi_param(
AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())),
attrs
)],
Abi::Vector { .. } => {
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
smallvec![AbiParam::new(vector_ty)]
@ -122,11 +115,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
_ => unreachable!("{:?}", self.layout.abi),
},
PassMode::Cast(cast) => cast_target_to_abi_params(cast),
PassMode::Indirect {
attrs,
extra_attrs: None,
on_stack,
} => {
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
if on_stack {
let size = u32::try_from(self.layout.size.bytes()).unwrap();
smallvec![apply_arg_attrs_to_abi_param(
@ -134,17 +123,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
attrs
)]
} else {
smallvec![apply_arg_attrs_to_abi_param(
AbiParam::new(pointer_ty(tcx)),
attrs
)]
smallvec![apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)]
}
}
PassMode::Indirect {
attrs,
extra_attrs: Some(extra_attrs),
on_stack,
} => {
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
assert!(!on_stack);
smallvec![
apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs),
@ -158,10 +140,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
match self.mode {
PassMode::Ignore => (None, vec![]),
PassMode::Direct(_) => match &self.layout.abi {
Abi::Scalar(scalar) => (
None,
vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))],
),
Abi::Scalar(scalar) => {
(None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))])
}
Abi::Vector { .. } => {
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
(None, vec![AbiParam::new(vector_ty)])
@ -177,31 +158,19 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
_ => unreachable!("{:?}", self.layout.abi),
},
PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()),
PassMode::Indirect {
attrs: _,
extra_attrs: None,
on_stack,
} => {
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => {
assert!(!on_stack);
(
Some(AbiParam::special(
pointer_ty(tcx),
ArgumentPurpose::StructReturn,
)),
vec![],
)
(Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![])
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
PassMode::Indirect {
attrs: _,
extra_attrs: Some(_),
on_stack: _,
} => unreachable!("unsized return value"),
}
}
}
pub(super) fn to_casted_value<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
arg: CValue<'tcx>,
cast: CastTarget,
) -> SmallVec<[Value; 2]> {
@ -211,9 +180,7 @@ pub(super) fn to_casted_value<'tcx>(
cast_target_to_abi_params(cast)
.into_iter()
.map(|param| {
let val = ptr
.offset_i64(fx, offset)
.load(fx, param.value_type, MemFlags::new());
let val = ptr.offset_i64(fx, offset).load(fx, param.value_type, MemFlags::new());
offset += i64::from(param.value_type.bytes());
val
})
@ -221,16 +188,13 @@ pub(super) fn to_casted_value<'tcx>(
}
pub(super) fn from_casted_value<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
block_params: &[Value],
layout: TyAndLayout<'tcx>,
cast: CastTarget,
) -> CValue<'tcx> {
let abi_params = cast_target_to_abi_params(cast);
let abi_param_size: u32 = abi_params
.iter()
.map(|param| param.value_type.bytes())
.sum();
let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();
let layout_size = u32::try_from(layout.size.bytes()).unwrap();
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
@ -260,7 +224,7 @@ pub(super) fn from_casted_value<'tcx>(
/// Get a set of values to be passed as function arguments.
pub(super) fn adjust_arg_for_abi<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
arg: CValue<'tcx>,
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
) -> SmallVec<[Value; 2]> {
@ -283,7 +247,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
/// Create a [`CValue`] containing the value of a function parameter adding clif function parameters
/// as necessary.
pub(super) fn cvalue_for_param<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
#[cfg_attr(not(debug_assertions), allow(unused_variables))] local: Option<mir::Local>,
#[cfg_attr(not(debug_assertions), allow(unused_variables))] local_field: Option<usize>,
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
@ -294,10 +258,7 @@ pub(super) fn cvalue_for_param<'tcx>(
.into_iter()
.map(|abi_param| {
let block_param = block_params_iter.next().unwrap();
assert_eq!(
fx.bcx.func.dfg.value_type(block_param),
abi_param.value_type
);
assert_eq!(fx.bcx.func.dfg.value_type(block_param), abi_param.value_type);
block_param
})
.collect::<SmallVec<[_; 2]>>();
@ -321,29 +282,14 @@ pub(super) fn cvalue_for_param<'tcx>(
}
PassMode::Pair(_, _) => {
assert_eq!(block_params.len(), 2, "{:?}", block_params);
Some(CValue::by_val_pair(
block_params[0],
block_params[1],
arg_abi.layout,
))
Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout))
}
PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)),
PassMode::Indirect {
attrs: _,
extra_attrs: None,
on_stack: _,
} => {
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
assert_eq!(block_params.len(), 1, "{:?}", block_params);
Some(CValue::by_ref(
Pointer::new(block_params[0]),
arg_abi.layout,
))
Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout))
}
PassMode::Indirect {
attrs: _,
extra_attrs: Some(_),
on_stack: _,
} => {
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
assert_eq!(block_params.len(), 2, "{:?}", block_params);
Some(CValue::by_ref_unsized(
Pointer::new(block_params[0]),

View File

@ -8,14 +8,13 @@ use smallvec::{smallvec, SmallVec};
/// Can the given type be returned into an ssa var or does it need to be returned on the stack.
pub(crate) fn can_return_to_ssa_var<'tcx>(
fx: &FunctionCx<'_, 'tcx, impl Module>,
fx: &FunctionCx<'_, '_, 'tcx>,
func: &mir::Operand<'tcx>,
args: &[mir::Operand<'tcx>],
) -> bool {
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
let fn_sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
let fn_sig =
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
// Handle special calls like instrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
@ -42,11 +41,7 @@ pub(crate) fn can_return_to_ssa_var<'tcx>(
let fn_abi = if let Some(instance) = instance {
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
} else {
FnAbi::of_fn_ptr(
&RevealAllLayoutCx(fx.tcx),
fn_ty.fn_sig(fx.tcx),
&extra_args,
)
FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args)
};
match fn_abi.ret.mode {
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => true,
@ -58,15 +53,12 @@ pub(crate) fn can_return_to_ssa_var<'tcx>(
/// Return a place where the return value of the current function can be written to. If necessary
/// this adds an extra parameter pointing to where the return value needs to be stored.
pub(super) fn codegen_return_param<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>,
block_params_iter: &mut impl Iterator<Item = Value>,
) -> CPlace<'tcx> {
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode {
PassMode::Ignore => (
CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout),
smallvec![],
),
PassMode::Ignore => (CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout), smallvec![]),
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => {
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
(
@ -79,26 +71,17 @@ pub(super) fn codegen_return_param<'tcx>(
smallvec![],
)
}
PassMode::Indirect {
attrs: _,
extra_attrs: None,
on_stack: _,
} => {
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
let ret_param = block_params_iter.next().unwrap();
assert_eq!(fx.bcx.func.dfg.value_type(ret_param), pointer_ty(fx.tcx));
(
CPlace::for_ptr(
Pointer::new(ret_param),
fx.fn_abi.as_ref().unwrap().ret.layout,
),
CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout),
smallvec![ret_param],
)
}
PassMode::Indirect {
attrs: _,
extra_attrs: Some(_),
on_stack: _,
} => unreachable!("unsized return value"),
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
};
#[cfg(not(debug_assertions))]
@ -120,27 +103,21 @@ pub(super) fn codegen_return_param<'tcx>(
/// Invokes the closure with if necessary a value representing the return pointer. When the closure
/// returns the call return value(s) if any are written to the correct place.
pub(super) fn codegen_with_call_return_arg<'tcx, M: Module, T>(
fx: &mut FunctionCx<'_, 'tcx, M>,
pub(super) fn codegen_with_call_return_arg<'tcx, T>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
ret_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
ret_place: Option<CPlace<'tcx>>,
f: impl FnOnce(&mut FunctionCx<'_, 'tcx, M>, Option<Value>) -> (Inst, T),
f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option<Value>) -> (Inst, T),
) -> (Inst, T) {
let return_ptr = match ret_arg_abi.mode {
PassMode::Ignore => None,
PassMode::Indirect {
attrs: _,
extra_attrs: None,
on_stack: _,
} => match ret_place {
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => match ret_place {
Some(ret_place) => Some(ret_place.to_ptr().get_addr(fx)),
None => Some(fx.bcx.ins().iconst(fx.pointer_type, 43)), // FIXME allocate temp stack slot
},
PassMode::Indirect {
attrs: _,
extra_attrs: Some(_),
on_stack: _,
} => unreachable!("unsized return value"),
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => None,
};
@ -177,37 +154,24 @@ pub(super) fn codegen_with_call_return_arg<'tcx, M: Module, T>(
ret_place.write_cvalue(fx, result);
}
}
PassMode::Indirect {
attrs: _,
extra_attrs: None,
on_stack: _,
} => {}
PassMode::Indirect {
attrs: _,
extra_attrs: Some(_),
on_stack: _,
} => unreachable!("unsized return value"),
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
}
(call_inst, meta)
}
/// Codegen a return instruction with the right return value(s) if any.
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, impl Module>) {
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
match fx.fn_abi.as_ref().unwrap().ret.mode {
PassMode::Ignore
| PassMode::Indirect {
attrs: _,
extra_attrs: None,
on_stack: _,
} => {
PassMode::Ignore | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
fx.bcx.ins().return_(&[]);
}
PassMode::Indirect {
attrs: _,
extra_attrs: Some(_),
on_stack: _,
} => unreachable!("unsized return value"),
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
PassMode::Direct(_) => {
let place = fx.get_local_place(RETURN_PLACE);
let ret_val = place.to_cvalue(fx).load_scalar(fx);

View File

@ -66,13 +66,9 @@ fn codegen_inner(
let callee_name = kind.fn_name(method.name);
//eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);
let func_id = module
.declare_function(&caller_name, Linkage::Export, &sig)
.unwrap();
let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap();
let callee_func_id = module
.declare_function(&callee_name, Linkage::Import, &sig)
.unwrap();
let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone());
@ -96,11 +92,7 @@ fn codegen_inner(
bcx.finalize();
}
module
.define_function(
func_id,
&mut ctx,
&mut cranelift_codegen::binemit::NullTrapSink {},
)
.define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {})
.unwrap();
unwind_context.add_function(func_id, &ctx, module.isa());
}
@ -114,13 +106,10 @@ fn codegen_inner(
let callee_name = kind.fn_name(sym::oom);
//eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);
let func_id = module
.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig)
.unwrap();
let func_id =
module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap();
let callee_func_id = module
.declare_function(&callee_name, Linkage::Import, &sig)
.unwrap();
let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig);
@ -143,11 +132,7 @@ fn codegen_inner(
bcx.finalize();
}
module
.define_function(
func_id,
&mut ctx,
&mut cranelift_codegen::binemit::NullTrapSink {},
)
.define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {})
.unwrap();
unwind_context.add_function(func_id, &ctx, module.isa());
}

View File

@ -11,7 +11,7 @@ pub(crate) enum SsaKind {
Ssa,
}
pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec<Local, SsaKind> {
pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec<Local, SsaKind> {
let mut flag_map = fx
.mir
.local_decls
@ -40,12 +40,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec<Local, S
}
match &bb.terminator().kind {
TerminatorKind::Call {
destination,
func,
args,
..
} => {
TerminatorKind::Call { destination, func, args, .. } => {
if let Some((dest_place, _dest_bb)) = destination {
if !crate::abi::can_return_to_ssa_var(fx, func, args) {
not_ssa(&mut flag_map, dest_place.local)

View File

@ -12,10 +12,7 @@ use object::{Object, ObjectSymbol, SymbolKind};
#[derive(Debug)]
enum ArchiveEntry {
FromArchive {
archive_index: usize,
entry_index: usize,
},
FromArchive { archive_index: usize, entry_index: usize },
File(PathBuf),
}
@ -30,7 +27,6 @@ pub(crate) struct ArArchiveBuilder<'a> {
// Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
// the end of an archive for linkers to not get confused.
entries: Vec<(String, ArchiveEntry)>,
update_symbols: bool,
}
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
@ -46,10 +42,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
let entry = entry.unwrap();
entries.push((
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
ArchiveEntry::FromArchive {
archive_index: 0,
entry_index: i,
},
ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
));
i += 1;
}
@ -69,7 +62,6 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
src_archives,
entries,
update_symbols: false,
}
}
@ -95,14 +87,9 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) {
let location = find_library(name, &self.lib_search_paths, self.sess);
self.add_archive(location.clone(), |_| false)
.unwrap_or_else(|e| {
panic!(
"failed to add native library {}: {}",
location.to_string_lossy(),
e
);
});
self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| {
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
});
}
fn add_rlib(
@ -136,9 +123,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
})
}
fn update_symbols(&mut self) {
self.update_symbols = true;
}
fn update_symbols(&mut self) {}
fn build(mut self) {
enum BuilderKind {
@ -156,10 +141,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
// FIXME only read the symbol table of the object files to avoid having to keep all
// object files in memory at once, or read them twice.
let data = match entry {
ArchiveEntry::FromArchive {
archive_index,
entry_index,
} => {
ArchiveEntry::FromArchive { archive_index, entry_index } => {
// FIXME read symbols from symtab
use std::io::Read;
let (ref _src_archive_path, ref mut src_archive) =
@ -225,10 +207,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
err
));
}),
entries
.iter()
.map(|(name, _)| name.as_bytes().to_vec())
.collect(),
entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(),
ar::GnuSymbolTableFormat::Size32,
symbol_table,
)
@ -271,8 +250,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
.expect("Couldn't run ranlib");
if !status.success() {
self.sess
.fatal(&format!("Ranlib exited with code {:?}", status.code()));
self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
}
}
}
@ -292,13 +270,8 @@ impl<'a> ArArchiveBuilder<'a> {
let file_name = String::from_utf8(entry.header().identifier().to_vec())
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
if !skip(&file_name) {
self.entries.push((
file_name,
ArchiveEntry::FromArchive {
archive_index,
entry_index: i,
},
));
self.entries
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
}
i += 1;
}

View File

@ -1,185 +0,0 @@
//! Atomic intrinsics are implemented using a global lock for now, as Cranelift doesn't support
//! atomic operations yet.
// FIXME implement atomic instructions in Cranelift.
use crate::prelude::*;
#[cfg(all(feature = "jit", unix))]
#[no_mangle]
static mut __cg_clif_global_atomic_mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER;
pub(crate) fn init_global_lock(
module: &mut impl Module,
bcx: &mut FunctionBuilder<'_>,
use_jit: bool,
) {
if use_jit {
// When using JIT, dylibs won't find the __cg_clif_global_atomic_mutex data object defined here,
// so instead we define it in the cg_clif dylib.
return;
}
let mut data_ctx = DataContext::new();
data_ctx.define_zeroinit(1024); // 1024 bytes should be big enough on all platforms.
data_ctx.set_align(16);
let atomic_mutex = module
.declare_data(
"__cg_clif_global_atomic_mutex",
Linkage::Export,
true,
false,
)
.unwrap();
module.define_data(atomic_mutex, &data_ctx).unwrap();
let pthread_mutex_init = module
.declare_function(
"pthread_mutex_init",
Linkage::Import,
&cranelift_codegen::ir::Signature {
call_conv: module.target_config().default_call_conv,
params: vec![
AbiParam::new(
module.target_config().pointer_type(), /* *mut pthread_mutex_t */
),
AbiParam::new(
module.target_config().pointer_type(), /* *const pthread_mutex_attr_t */
),
],
returns: vec![AbiParam::new(types::I32 /* c_int */)],
},
)
.unwrap();
let pthread_mutex_init = module.declare_func_in_func(pthread_mutex_init, bcx.func);
let atomic_mutex = module.declare_data_in_func(atomic_mutex, bcx.func);
let atomic_mutex = bcx
.ins()
.global_value(module.target_config().pointer_type(), atomic_mutex);
let nullptr = bcx.ins().iconst(module.target_config().pointer_type(), 0);
bcx.ins().call(pthread_mutex_init, &[atomic_mutex, nullptr]);
}
pub(crate) fn init_global_lock_constructor(
module: &mut impl Module,
constructor_name: &str,
) -> FuncId {
let sig = Signature::new(CallConv::SystemV);
let init_func_id = module
.declare_function(constructor_name, Linkage::Export, &sig)
.unwrap();
let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig);
{
let mut func_ctx = FunctionBuilderContext::new();
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
let block = bcx.create_block();
bcx.switch_to_block(block);
crate::atomic_shim::init_global_lock(module, &mut bcx, false);
bcx.ins().return_(&[]);
bcx.seal_all_blocks();
bcx.finalize();
}
module
.define_function(
init_func_id,
&mut ctx,
&mut cranelift_codegen::binemit::NullTrapSink {},
)
.unwrap();
init_func_id
}
pub(crate) fn lock_global_lock(fx: &mut FunctionCx<'_, '_, impl Module>) {
let atomic_mutex = fx
.cx
.module
.declare_data(
"__cg_clif_global_atomic_mutex",
Linkage::Import,
true,
false,
)
.unwrap();
let pthread_mutex_lock = fx
.cx
.module
.declare_function(
"pthread_mutex_lock",
Linkage::Import,
&cranelift_codegen::ir::Signature {
call_conv: fx.cx.module.target_config().default_call_conv,
params: vec![AbiParam::new(
fx.cx.module.target_config().pointer_type(), /* *mut pthread_mutex_t */
)],
returns: vec![AbiParam::new(types::I32 /* c_int */)],
},
)
.unwrap();
let pthread_mutex_lock = fx
.cx
.module
.declare_func_in_func(pthread_mutex_lock, fx.bcx.func);
let atomic_mutex = fx.cx.module.declare_data_in_func(atomic_mutex, fx.bcx.func);
let atomic_mutex = fx
.bcx
.ins()
.global_value(fx.cx.module.target_config().pointer_type(), atomic_mutex);
fx.bcx.ins().call(pthread_mutex_lock, &[atomic_mutex]);
}
pub(crate) fn unlock_global_lock(fx: &mut FunctionCx<'_, '_, impl Module>) {
let atomic_mutex = fx
.cx
.module
.declare_data(
"__cg_clif_global_atomic_mutex",
Linkage::Import,
true,
false,
)
.unwrap();
let pthread_mutex_unlock = fx
.cx
.module
.declare_function(
"pthread_mutex_unlock",
Linkage::Import,
&cranelift_codegen::ir::Signature {
call_conv: fx.cx.module.target_config().default_call_conv,
params: vec![AbiParam::new(
fx.cx.module.target_config().pointer_type(), /* *mut pthread_mutex_t */
)],
returns: vec![AbiParam::new(types::I32 /* c_int */)],
},
)
.unwrap();
let pthread_mutex_unlock = fx
.cx
.module
.declare_func_in_func(pthread_mutex_unlock, fx.bcx.func);
let atomic_mutex = fx.cx.module.declare_data_in_func(atomic_mutex, fx.bcx.func);
let atomic_mutex = fx
.bcx
.ins()
.global_value(fx.cx.module.target_config().pointer_type(), atomic_mutex);
fx.bcx.ins().call(pthread_mutex_unlock, &[atomic_mutex]);
}

View File

@ -8,7 +8,7 @@ use rustc_session::Session;
use cranelift_module::FuncId;
use object::write::*;
use object::{RelocationEncoding, RelocationKind, SectionKind, SymbolFlags};
use object::{RelocationEncoding, SectionKind, SymbolFlags};
use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct};
@ -22,9 +22,7 @@ pub(crate) trait WriteMetadata {
impl WriteMetadata for object::write::Object {
fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, _is_like_osx: bool) {
let segment = self
.segment_name(object::write::StandardSegment::Data)
.to_vec();
let segment = self.segment_name(object::write::StandardSegment::Data).to_vec();
let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data);
let offset = self.append_section_data(section_id, &data, 1);
// For MachO and probably PE this is necessary to prevent the linker from throwing away the
@ -74,11 +72,7 @@ impl WriteDebugInfo for ObjectProduct {
let section_id = self.object.add_section(
segment,
name,
if id == SectionId::EhFrame {
SectionKind::ReadOnlyData
} else {
SectionKind::Debug
},
if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
);
self.object
.section_mut(section_id)
@ -118,49 +112,6 @@ impl WriteDebugInfo for ObjectProduct {
}
}
// FIXME remove once atomic instructions are implemented in Cranelift.
pub(crate) trait AddConstructor {
fn add_constructor(&mut self, func_id: FuncId);
}
impl AddConstructor for ObjectProduct {
fn add_constructor(&mut self, func_id: FuncId) {
let symbol = self.function_symbol(func_id);
let segment = self
.object
.segment_name(object::write::StandardSegment::Data);
let init_array_section =
self.object
.add_section(segment.to_vec(), b".init_array".to_vec(), SectionKind::Data);
let address_size = self
.object
.architecture()
.address_size()
.expect("address_size must be known")
.bytes();
self.object.append_section_data(
init_array_section,
&std::iter::repeat(0)
.take(address_size.into())
.collect::<Vec<u8>>(),
8,
);
self.object
.add_relocation(
init_array_section,
object::write::Relocation {
offset: 0,
size: address_size * 8,
kind: RelocationKind::Absolute,
encoding: RelocationEncoding::Generic,
symbol,
addend: 0,
},
)
.unwrap();
}
}
pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec<u8> {
let triple = crate::build_isa(sess).triple().clone();
@ -175,10 +126,9 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
architecture => sess.fatal(&format!(
"target architecture {:?} is unsupported",
architecture,
)),
architecture => {
sess.fatal(&format!("target architecture {:?} is unsupported", architecture,))
}
};
let endian = match triple.endianness().unwrap() {
target_lexicon::Endianness::Little => object::Endianness::Little,

View File

@ -8,7 +8,7 @@ use rustc_target::abi::call::FnAbi;
use crate::prelude::*;
pub(crate) fn codegen_fn<'tcx>(
cx: &mut crate::CodegenCx<'tcx, impl Module>,
cx: &mut crate::CodegenCx<'_, 'tcx>,
instance: Instance<'tcx>,
linkage: Linkage,
) {
@ -38,9 +38,8 @@ pub(crate) fn codegen_fn<'tcx>(
// Predefine blocks
let start_block = bcx.create_block();
let block_map: IndexVec<BasicBlock, Block> = (0..mir.basic_blocks().len())
.map(|_| bcx.create_block())
.collect();
let block_map: IndexVec<BasicBlock, Block> =
(0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
// Make FunctionCx
let pointer_type = cx.module.target_config().pointer_type();
@ -68,22 +67,23 @@ pub(crate) fn codegen_fn<'tcx>(
inline_asm_index: 0,
};
let arg_uninhabited = fx.mir.args_iter().any(|arg| {
fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty))
.abi
.is_uninhabited()
});
let arg_uninhabited = fx
.mir
.args_iter()
.any(|arg| fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
if arg_uninhabited {
fx.bcx
.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
if !crate::constant::check_constants(&mut fx) {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted");
} else if arg_uninhabited {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
crate::trap::trap_unreachable(&mut fx, "function has uninhabited argument");
} else {
tcx.sess.time("codegen clif ir", || {
tcx.sess.time("codegen prelude", || {
crate::abi::codegen_fn_prelude(&mut fx, start_block)
});
tcx.sess
.time("codegen prelude", || crate::abi::codegen_fn_prelude(&mut fx, start_block));
codegen_fn_content(&mut fx);
});
}
@ -131,11 +131,7 @@ pub(crate) fn codegen_fn<'tcx>(
let module = &mut cx.module;
tcx.sess.time("define function", || {
module
.define_function(
func_id,
context,
&mut cranelift_codegen::binemit::NullTrapSink {},
)
.define_function(func_id, context, &mut cranelift_codegen::binemit::NullTrapSink {})
.unwrap()
});
@ -149,14 +145,12 @@ pub(crate) fn codegen_fn<'tcx>(
&clif_comments,
);
if let Some(mach_compile_result) = &context.mach_compile_result {
if let Some(disasm) = &mach_compile_result.disasm {
crate::pretty_clif::write_ir_file(
tcx,
&format!("{}.vcode", tcx.symbol_name(instance).name),
|file| file.write_all(disasm.as_bytes()),
)
}
if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
crate::pretty_clif::write_ir_file(
tcx,
&format!("{}.vcode", tcx.symbol_name(instance).name),
|file| file.write_all(disasm.as_bytes()),
)
}
// Define debuginfo for function
@ -199,16 +193,13 @@ pub(crate) fn verify_func(
Some(Box::new(writer)),
err,
);
tcx.sess
.fatal(&format!("cranelift verify error:\n{}", pretty_error));
tcx.sess.fatal(&format!("cranelift verify error:\n{}", pretty_error));
}
}
});
}
fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) {
crate::constant::check_constants(fx);
fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() {
let block = fx.get_block(bb);
fx.bcx.switch_to_block(block);
@ -231,11 +222,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) {
#[cfg(debug_assertions)]
{
let mut terminator_head = "\n".to_string();
bb_data
.terminator()
.kind
.fmt_head(&mut terminator_head)
.unwrap();
bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
let inst = fx.bcx.func.layout.last_inst(block).unwrap();
fx.add_comment(inst, terminator_head);
}
@ -267,13 +254,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) {
TerminatorKind::Return => {
crate::abi::codegen_return(fx);
}
TerminatorKind::Assert {
cond,
expected,
msg,
target,
cleanup: _,
} => {
TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
if !fx.tcx.sess.overflow_checks() {
if let mir::AssertKind::OverflowNeg(_) = *msg {
let target = fx.get_block(*target);
@ -319,11 +300,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) {
}
}
TerminatorKind::SwitchInt {
discr,
switch_ty,
targets,
} => {
TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
let discr = codegen_operand(fx, discr).load_scalar(fx);
let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind()
@ -433,11 +410,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) {
| TerminatorKind::GeneratorDrop => {
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
}
TerminatorKind::Drop {
place,
target,
unwind: _,
} => {
TerminatorKind::Drop { place, target, unwind: _ } => {
let drop_place = codegen_place(fx, *place);
crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place);
@ -452,7 +425,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) {
}
fn codegen_stmt<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
#[allow(unused_variables)] cur_block: Block,
stmt: &Statement<'tcx>,
) {
@ -470,10 +443,7 @@ fn codegen_stmt<'tcx>(
}
match &stmt.kind {
StatementKind::SetDiscriminant {
place,
variant_index,
} => {
StatementKind::SetDiscriminant { place, variant_index } => {
let place = codegen_place(fx, **place);
crate::discriminant::codegen_set_discriminant(fx, place, *variant_index);
}
@ -494,14 +464,14 @@ fn codegen_stmt<'tcx>(
let val = crate::constant::codegen_tls_ref(fx, def_id, lval.layout());
lval.write_cvalue(fx, val);
}
Rvalue::BinaryOp(bin_op, ref lhs, ref rhs) => {
Rvalue::BinaryOp(bin_op, box (ref lhs, ref rhs)) => {
let lhs = codegen_operand(fx, lhs);
let rhs = codegen_operand(fx, rhs);
let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs);
lval.write_cvalue(fx, res);
}
Rvalue::CheckedBinaryOp(bin_op, ref lhs, ref rhs) => {
Rvalue::CheckedBinaryOp(bin_op, box (ref lhs, ref rhs)) => {
let lhs = codegen_operand(fx, lhs);
let rhs = codegen_operand(fx, rhs);
@ -594,19 +564,11 @@ fn codegen_stmt<'tcx>(
let from_ty = operand.layout().ty;
let to_ty = fx.monomorphize(to_ty);
fn is_fat_ptr<'tcx>(
fx: &FunctionCx<'_, 'tcx, impl Module>,
ty: Ty<'tcx>,
) -> bool {
fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
ty.builtin_deref(true)
.map(
|ty::TypeAndMut {
ty: pointee_ty,
mutbl: _,
}| {
has_ptr_meta(fx.tcx, pointee_ty)
},
)
.map(|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| {
has_ptr_meta(fx.tcx, pointee_ty)
})
.unwrap_or(false)
}
@ -626,50 +588,22 @@ fn codegen_stmt<'tcx>(
ty::Uint(_) | ty::Int(_) => {}
_ => unreachable!("cast adt {} -> {}", from_ty, to_ty),
}
let to_clif_ty = fx.clif_type(to_ty).unwrap();
use rustc_target::abi::{Int, TagEncoding, Variants};
let discriminant = crate::discriminant::codegen_get_discriminant(
fx,
operand,
fx.layout_of(operand.layout().ty.discriminant_ty(fx.tcx)),
)
.load_scalar(fx);
match operand.layout().variants {
Variants::Single { index } => {
let discr = operand
.layout()
.ty
.discriminant_for_variant(fx.tcx, index)
.unwrap();
let discr = if discr.ty.is_signed() {
fx.layout_of(discr.ty).size.sign_extend(discr.val)
} else {
discr.val
};
let discr = discr.into();
let discr = CValue::const_val(fx, fx.layout_of(to_ty), discr);
lval.write_cvalue(fx, discr);
}
Variants::Multiple {
ref tag,
tag_field,
tag_encoding: TagEncoding::Direct,
variants: _,
} => {
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
// Read the tag/niche-encoded discriminant from memory.
let encoded_discr =
operand.value_field(fx, mir::Field::new(tag_field));
let encoded_discr = encoded_discr.load_scalar(fx);
// Decode the discriminant (specifically if it's niche-encoded).
let signed = match tag.value {
Int(_, signed) => signed,
_ => false,
};
let val = clif_intcast(fx, encoded_discr, cast_to, signed);
let val = CValue::by_val(val, dest_layout);
lval.write_cvalue(fx, val);
}
Variants::Multiple { .. } => unreachable!(),
}
let res = crate::cast::clif_intcast(
fx,
discriminant,
to_clif_ty,
to_ty.is_signed(),
);
lval.write_cvalue(fx, CValue::by_val(res, dest_layout));
} else {
let to_clif_ty = fx.clif_type(to_ty).unwrap();
let from = operand.load_scalar(fx);
@ -730,8 +664,7 @@ fn codegen_stmt<'tcx>(
// FIXME use emit_small_memset where possible
let addr = lval.to_ptr().get_addr(fx);
let val = operand.load_scalar(fx);
fx.bcx
.call_memset(fx.cx.module.target_config(), addr, val, times);
fx.bcx.call_memset(fx.cx.module.target_config(), addr, val, times);
} else {
let loop_block = fx.bcx.create_block();
let loop_block2 = fx.bcx.create_block();
@ -766,25 +699,19 @@ fn codegen_stmt<'tcx>(
let content_ty = fx.monomorphize(content_ty);
let layout = fx.layout_of(content_ty);
let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64);
let llalign = fx
.bcx
.ins()
.iconst(usize_type, layout.align.abi.bytes() as i64);
let llalign = fx.bcx.ins().iconst(usize_type, layout.align.abi.bytes() as i64);
let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
// Allocate space:
let def_id = match fx
.tcx
.lang_items()
.require(rustc_hir::LangItem::ExchangeMalloc)
{
Ok(id) => id,
Err(s) => {
fx.tcx
.sess
.fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
}
};
let def_id =
match fx.tcx.lang_items().require(rustc_hir::LangItem::ExchangeMalloc) {
Ok(id) => id,
Err(s) => {
fx.tcx
.sess
.fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
}
};
let instance = ty::Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
let func_ref = fx.get_function_ref(instance);
let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]);
@ -792,10 +719,11 @@ fn codegen_stmt<'tcx>(
lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
}
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
assert!(lval
.layout()
.ty
.is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all()));
assert!(
lval.layout()
.ty
.is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())
);
let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes();
let val =
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into());
@ -823,11 +751,7 @@ fn codegen_stmt<'tcx>(
StatementKind::LlvmInlineAsm(asm) => {
use rustc_span::symbol::Symbol;
let LlvmInlineAsm {
asm,
outputs,
inputs,
} = &**asm;
let LlvmInlineAsm { asm, outputs, inputs } = &**asm;
let rustc_hir::LlvmInlineAsmInner {
asm: asm_code, // Name
outputs: output_names, // Vec<LlvmInlineAsmOutput>
@ -843,15 +767,9 @@ fn codegen_stmt<'tcx>(
// Black box
}
"mov %rbx, %rsi\n cpuid\n xchg %rbx, %rsi" => {
assert_eq!(
input_names,
&[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]
);
assert_eq!(input_names, &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]);
assert_eq!(output_names.len(), 4);
for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"])
.iter()
.enumerate()
{
for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]).iter().enumerate() {
assert_eq!(&output_names[i].constraint.as_str(), c);
assert!(!output_names[i].is_rw);
assert!(!output_names[i].is_indirect);
@ -897,12 +815,7 @@ fn codegen_stmt<'tcx>(
crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported");
}
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
_ if fx
.tcx
.symbol_name(fx.instance)
.name
.starts_with("___chkstk") =>
{
_ if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") => {
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
}
_ if fx.tcx.symbol_name(fx.instance).name == "__alloca" => {
@ -919,30 +832,45 @@ fn codegen_stmt<'tcx>(
}
}
StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"),
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
src,
dst,
count,
}) => {
let dst = codegen_operand(fx, dst);
let pointee = dst
.layout()
.pointee_info_at(fx, rustc_target::abi::Size::ZERO)
.expect("Expected pointer");
let dst = dst.load_scalar(fx);
let src = codegen_operand(fx, src).load_scalar(fx);
let count = codegen_operand(fx, count).load_scalar(fx);
let elem_size: u64 = pointee.size.bytes();
let bytes = if elem_size != 1 {
fx.bcx.ins().imul_imm(count, elem_size as i64)
} else {
count
};
fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes);
}
}
}
fn codegen_array_len<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
place: CPlace<'tcx>,
) -> Value {
fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value {
match *place.layout().ty.kind() {
ty::Array(_elem_ty, len) => {
let len = fx
.monomorphize(len)
.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64;
let len = fx.monomorphize(len).eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64;
fx.bcx.ins().iconst(fx.pointer_type, len)
}
ty::Slice(_elem_ty) => place
.to_ptr_maybe_unsized()
.1
.expect("Length metadata for slice place"),
ty::Slice(_elem_ty) => {
place.to_ptr_maybe_unsized().1.expect("Length metadata for slice place")
}
_ => bug!("Rvalue::Len({:?})", place),
}
}
pub(crate) fn codegen_place<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
place: Place<'tcx>,
) -> CPlace<'tcx> {
let mut cplace = fx.get_local_place(place.local);
@ -959,11 +887,7 @@ pub(crate) fn codegen_place<'tcx>(
let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx);
cplace = cplace.place_index(fx, index);
}
PlaceElem::ConstantIndex {
offset,
min_length: _,
from_end,
} => {
PlaceElem::ConstantIndex { offset, min_length: _, from_end } => {
let offset: u64 = offset;
let index = if !from_end {
fx.bcx.ins().iconst(fx.pointer_type, offset as i64)
@ -1014,7 +938,7 @@ pub(crate) fn codegen_place<'tcx>(
}
pub(crate) fn codegen_operand<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
operand: &Operand<'tcx>,
) -> CValue<'tcx> {
match operand {
@ -1026,34 +950,24 @@ pub(crate) fn codegen_operand<'tcx>(
}
}
pub(crate) fn codegen_panic<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
msg_str: &str,
span: Span,
) {
pub(crate) fn codegen_panic<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, span: Span) {
let location = fx.get_caller_location(span).load_scalar(fx);
let msg_ptr = fx.anonymous_str("assert", msg_str);
let msg_len = fx
.bcx
.ins()
.iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
let args = [msg_ptr, msg_len, location];
codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span);
}
pub(crate) fn codegen_panic_inner<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
lang_item: rustc_hir::LangItem,
args: &[Value],
span: Span,
) {
let def_id = fx
.tcx
.lang_items()
.require(lang_item)
.unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s));
let def_id =
fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s));
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
let symbol_name = fx.tcx.symbol_name(instance).name;

View File

@ -27,13 +27,7 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
config.opts.cg.panic = Some(PanicStrategy::Abort);
config.opts.debugging_opts.panic_abort_tests = true;
config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| {
std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.to_owned()
std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned()
}));
}
}

View File

@ -46,15 +46,8 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
config.opts.cg.panic = Some(PanicStrategy::Abort);
config.opts.debugging_opts.panic_abort_tests = true;
config.opts.maybe_sysroot = Some(
std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.to_owned(),
);
config.opts.maybe_sysroot =
Some(std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned());
}
}

View File

@ -3,7 +3,7 @@
use crate::prelude::*;
pub(crate) fn clif_intcast(
fx: &mut FunctionCx<'_, '_, impl Module>,
fx: &mut FunctionCx<'_, '_, '_>,
val: Value,
to: Type,
signed: bool,
@ -40,18 +40,14 @@ pub(crate) fn clif_intcast(
// reduce
(types::I128, _) => {
let (lsb, _msb) = fx.bcx.ins().isplit(val);
if to == types::I64 {
lsb
} else {
fx.bcx.ins().ireduce(to, lsb)
}
if to == types::I64 { lsb } else { fx.bcx.ins().ireduce(to, lsb) }
}
(_, _) => fx.bcx.ins().ireduce(to, val),
}
}
pub(crate) fn clif_int_or_float_cast(
fx: &mut FunctionCx<'_, '_, impl Module>,
fx: &mut FunctionCx<'_, '_, '_>,
from: Value,
from_signed: bool,
to_ty: Type,
@ -87,11 +83,7 @@ pub(crate) fn clif_int_or_float_cast(
},
);
let from_rust_ty = if from_signed {
fx.tcx.types.i128
} else {
fx.tcx.types.u128
};
let from_rust_ty = if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
let to_rust_ty = match to_ty {
types::F32 => fx.tcx.types.f32,
@ -100,11 +92,7 @@ pub(crate) fn clif_int_or_float_cast(
};
return fx
.easy_call(
&name,
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
to_rust_ty,
)
.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
.load_scalar(fx);
}
@ -138,18 +126,10 @@ pub(crate) fn clif_int_or_float_cast(
_ => unreachable!(),
};
let to_rust_ty = if to_signed {
fx.tcx.types.i128
} else {
fx.tcx.types.u128
};
let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
return fx
.easy_call(
&name,
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
to_rust_ty,
)
.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
.load_scalar(fx);
}

View File

@ -5,13 +5,17 @@ use cranelift_codegen::ir::ArgumentPurpose;
use crate::prelude::*;
pub(crate) fn maybe_codegen<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
checked: bool,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
) -> Option<CValue<'tcx>> {
if lhs.layout().ty != fx.tcx.types.u128 && lhs.layout().ty != fx.tcx.types.i128 {
if lhs.layout().ty != fx.tcx.types.u128
&& lhs.layout().ty != fx.tcx.types.i128
&& rhs.layout().ty != fx.tcx.types.u128
&& rhs.layout().ty != fx.tcx.types.i128
{
return None;
}
@ -27,11 +31,7 @@ pub(crate) fn maybe_codegen<'tcx>(
}
BinOp::Add | BinOp::Sub if !checked => None,
BinOp::Mul if !checked => {
let val_ty = if is_signed {
fx.tcx.types.i128
} else {
fx.tcx.types.u128
};
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
}
BinOp::Add | BinOp::Sub | BinOp::Mul => {
@ -43,11 +43,7 @@ pub(crate) fn maybe_codegen<'tcx>(
AbiParam::new(types::I128),
AbiParam::new(types::I128),
];
let args = [
out_place.to_ptr().get_addr(fx),
lhs.load_scalar(fx),
rhs.load_scalar(fx),
];
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
let name = match (bin_op, is_signed) {
(BinOp::Add, false) => "__rust_u128_addo",
(BinOp::Add, true) => "__rust_i128_addo",
@ -97,70 +93,23 @@ pub(crate) fn maybe_codegen<'tcx>(
None
};
// Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit
// integer into its lsb and msb.
// https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217
if resolve_value_imm(fx.bcx.func, rhs_val) == Some(64) {
let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val);
let all_zeros = fx.bcx.ins().iconst(types::I64, 0);
let val = match (bin_op, is_signed) {
(BinOp::Shr, false) => {
let val = fx.bcx.ins().iconcat(lhs_msb, all_zeros);
Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.u128)))
}
(BinOp::Shr, true) => {
let sign = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, lhs_msb, 0);
let all_ones = fx.bcx.ins().iconst(types::I64, u64::MAX as i64);
let all_sign_bits = fx.bcx.ins().select(sign, all_zeros, all_ones);
let val = fx.bcx.ins().iconcat(lhs_msb, all_sign_bits);
Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.i128)))
}
(BinOp::Shl, _) => {
let val_ty = if is_signed {
fx.tcx.types.i128
} else {
fx.tcx.types.u128
};
let val = fx.bcx.ins().iconcat(all_zeros, lhs_lsb);
Some(CValue::by_val(val, fx.layout_of(val_ty)))
}
_ => None,
};
if let Some(val) = val {
if let Some(is_overflow) = is_overflow {
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
let val = val.load_scalar(fx);
return Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty)));
} else {
return Some(val);
}
}
}
let truncated_rhs = clif_intcast(fx, rhs_val, types::I32, false);
let truncated_rhs = CValue::by_val(truncated_rhs, fx.layout_of(fx.tcx.types.u32));
let val = match (bin_op, is_signed) {
(BinOp::Shl, false) => {
fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.u128)
let val = match bin_op {
BinOp::Shl => fx.bcx.ins().ishl(lhs_val, truncated_rhs),
BinOp::Shr => {
if is_signed {
fx.bcx.ins().sshr(lhs_val, truncated_rhs)
} else {
fx.bcx.ins().ushr(lhs_val, truncated_rhs)
}
}
(BinOp::Shl, true) => {
fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.i128)
}
(BinOp::Shr, false) => {
fx.easy_call("__lshrti3", &[lhs, truncated_rhs], fx.tcx.types.u128)
}
(BinOp::Shr, true) => {
fx.easy_call("__ashrti3", &[lhs, truncated_rhs], fx.tcx.types.i128)
}
(_, _) => unreachable!(),
_ => unreachable!(),
};
if let Some(is_overflow) = is_overflow {
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
let val = val.load_scalar(fx);
Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty)))
} else {
Some(val)
Some(CValue::by_val(val, lhs.layout()))
}
}
}

View File

@ -3,8 +3,6 @@ use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Integer, Primitive};
use rustc_target::spec::{HasTargetSpec, Target};
use cranelift_codegen::ir::{InstructionData, Opcode, ValueDef};
use crate::prelude::*;
pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type {
@ -56,11 +54,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
FloatTy::F64 => types::F64,
},
ty::FnPtr(_) => pointer_ty(tcx),
ty::RawPtr(TypeAndMut {
ty: pointee_ty,
mutbl: _,
})
| ty::Ref(_, pointee_ty, _) => {
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
if has_ptr_meta(tcx, pointee_ty) {
return None;
} else {
@ -99,11 +93,7 @@ fn clif_pair_type_from_ty<'tcx>(
}
(a, b)
}
ty::RawPtr(TypeAndMut {
ty: pointee_ty,
mutbl: _,
})
| ty::Ref(_, pointee_ty, _) => {
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
if has_ptr_meta(tcx, pointee_ty) {
(pointer_ty(tcx), pointer_ty(tcx))
} else {
@ -116,15 +106,8 @@ fn clif_pair_type_from_ty<'tcx>(
/// Is a pointer to this type a fat ptr?
pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
let ptr_ty = tcx.mk_ptr(TypeAndMut {
ty,
mutbl: rustc_hir::Mutability::Not,
});
match &tcx
.layout_of(ParamEnv::reveal_all().and(ptr_ty))
.unwrap()
.abi
{
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc_hir::Mutability::Not });
match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi {
Abi::Scalar(_) => false,
Abi::ScalarPair(_, _) => true,
abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi),
@ -132,7 +115,7 @@ pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
}
pub(crate) fn codegen_icmp_imm(
fx: &mut FunctionCx<'_, '_, impl Module>,
fx: &mut FunctionCx<'_, '_, '_>,
intcc: IntCC,
lhs: Value,
rhs: i128,
@ -175,51 +158,6 @@ pub(crate) fn codegen_icmp_imm(
}
}
fn resolve_normal_value_imm(func: &Function, val: Value) -> Option<i64> {
if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) {
if let InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm,
} = func.dfg[inst]
{
Some(imm.into())
} else {
None
}
} else {
None
}
}
fn resolve_128bit_value_imm(func: &Function, val: Value) -> Option<u128> {
let (lsb, msb) = if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) {
if let InstructionData::Binary {
opcode: Opcode::Iconcat,
args: [lsb, msb],
} = func.dfg[inst]
{
(lsb, msb)
} else {
return None;
}
} else {
return None;
};
let lsb = u128::from(resolve_normal_value_imm(func, lsb)? as u64);
let msb = u128::from(resolve_normal_value_imm(func, msb)? as u64);
Some(msb << 64 | lsb)
}
pub(crate) fn resolve_value_imm(func: &Function, val: Value) -> Option<u128> {
if func.dfg.value_type(val) == types::I128 {
resolve_128bit_value_imm(func, val)
} else {
resolve_normal_value_imm(func, val).map(|imm| u128::from(imm as u64))
}
}
pub(crate) fn type_min_max_value(
bcx: &mut FunctionBuilder<'_>,
ty: Type,
@ -288,8 +226,8 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool {
}
}
pub(crate) struct FunctionCx<'clif, 'tcx, M: Module> {
pub(crate) cx: &'clif mut crate::CodegenCx<'tcx, M>,
pub(crate) struct FunctionCx<'m, 'clif, 'tcx> {
pub(crate) cx: &'clif mut crate::CodegenCx<'m, 'tcx>,
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) pointer_type: Type, // Cached from module
@ -316,7 +254,7 @@ pub(crate) struct FunctionCx<'clif, 'tcx, M: Module> {
pub(crate) inline_asm_index: u32,
}
impl<'tcx, M: Module> LayoutOf for FunctionCx<'_, 'tcx, M> {
impl<'tcx> LayoutOf for FunctionCx<'_, '_, 'tcx> {
type Ty = Ty<'tcx>;
type TyAndLayout = TyAndLayout<'tcx>;
@ -325,31 +263,31 @@ impl<'tcx, M: Module> LayoutOf for FunctionCx<'_, 'tcx, M> {
}
}
impl<'tcx, M: Module> layout::HasTyCtxt<'tcx> for FunctionCx<'_, 'tcx, M> {
impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx
}
}
impl<'tcx, M: Module> rustc_target::abi::HasDataLayout for FunctionCx<'_, 'tcx, M> {
impl<'tcx> rustc_target::abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> {
fn data_layout(&self) -> &rustc_target::abi::TargetDataLayout {
&self.tcx.data_layout
}
}
impl<'tcx, M: Module> layout::HasParamEnv<'tcx> for FunctionCx<'_, 'tcx, M> {
impl<'tcx> layout::HasParamEnv<'tcx> for FunctionCx<'_, '_, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> {
ParamEnv::reveal_all()
}
}
impl<'tcx, M: Module> HasTargetSpec for FunctionCx<'_, 'tcx, M> {
impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> {
fn target_spec(&self) -> &Target {
&self.tcx.sess.target
}
}
impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> {
impl<'tcx> FunctionCx<'_, '_, 'tcx> {
pub(crate) fn monomorphize<T>(&self, value: T) -> T
where
T: TypeFoldable<'tcx> + Copy,
@ -416,12 +354,7 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> {
let msg_id = self
.cx
.module
.declare_data(
&format!("__{}_{:08x}", prefix, msg_hash),
Linkage::Local,
false,
false,
)
.declare_data(&format!("__{}_{:08x}", prefix, msg_hash), Linkage::Local, false, false)
.unwrap();
// Ignore DuplicateDefinition error, as the data will be the same
@ -444,15 +377,13 @@ impl<'tcx> LayoutOf for RevealAllLayoutCx<'tcx> {
fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> {
assert!(!ty.still_further_specializable());
self.0
.layout_of(ParamEnv::reveal_all().and(&ty))
.unwrap_or_else(|e| {
if let layout::LayoutError::SizeOverflow(_) = e {
self.0.sess.fatal(&e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
}
})
self.0.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap_or_else(|e| {
if let layout::LayoutError::SizeOverflow(_) = e {
self.0.sess.fatal(&e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
}
})
}
}

View File

@ -28,7 +28,7 @@ enum TodoItem {
}
impl ConstantCx {
pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut impl Module) {
pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) {
//println!("todo {:?}", self.todo);
define_all_allocs(tcx, module, &mut self);
//println!("done {:?}", self.done);
@ -36,21 +36,20 @@ impl ConstantCx {
}
}
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) {
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
let mut all_constants_ok = true;
for constant in &fx.mir.required_consts {
let const_ = fx.monomorphize(constant.literal);
match const_.val {
ConstKind::Value(_) => {}
ConstKind::Unevaluated(def, ref substs, promoted) => {
if let Err(err) =
fx.tcx
.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
{
all_constants_ok = false;
match err {
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {
fx.tcx
.sess
.span_err(constant.span, "erroneous constant encountered");
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
}
ErrorHandled::TooGeneric => {
span_bug!(
@ -69,6 +68,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) {
| ConstKind::Error(_) => unreachable!("{:?}", const_),
}
}
all_constants_ok
}
pub(crate) fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) {
@ -76,11 +76,11 @@ pub(crate) fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) {
}
pub(crate) fn codegen_tls_ref<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
def_id: DefId,
layout: TyAndLayout<'tcx>,
) -> CValue<'tcx> {
let data_id = data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false);
let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false);
let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
#[cfg(debug_assertions)]
fx.add_comment(local_data_id, format!("tls {:?}", def_id));
@ -89,11 +89,11 @@ pub(crate) fn codegen_tls_ref<'tcx>(
}
fn codegen_static_ref<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
def_id: DefId,
layout: TyAndLayout<'tcx>,
) -> CPlace<'tcx> {
let data_id = data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false);
let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false);
let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
#[cfg(debug_assertions)]
fx.add_comment(local_data_id, format!("{:?}", def_id));
@ -110,7 +110,7 @@ fn codegen_static_ref<'tcx>(
}
pub(crate) fn codegen_constant<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
constant: &Constant<'tcx>,
) -> CValue<'tcx> {
let const_ = fx.monomorphize(constant.literal);
@ -128,20 +128,10 @@ pub(crate) fn codegen_constant<'tcx>(
.to_cvalue(fx);
}
ConstKind::Unevaluated(def, ref substs, promoted) => {
match fx
.tcx
.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
{
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
Ok(const_val) => const_val,
Err(_) => {
fx.tcx
.sess
.span_err(constant.span, "erroneous constant encountered");
return crate::trap::trap_unreachable_ret_value(
fx,
fx.layout_of(const_.ty),
"erroneous constant encountered",
);
span_bug!(constant.span, "erroneous constant not captured by required_consts");
}
}
}
@ -156,7 +146,7 @@ pub(crate) fn codegen_constant<'tcx>(
}
pub(crate) fn codegen_const_value<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
const_val: ConstValue<'tcx>,
ty: Ty<'tcx>,
) -> CValue<'tcx> {
@ -172,9 +162,7 @@ pub(crate) fn codegen_const_value<'tcx>(
if fx.clif_type(layout.ty).is_none() {
let (size, align) = (layout.size, layout.align.pref);
let mut alloc = Allocation::from_bytes(
std::iter::repeat(0)
.take(size.bytes_usize())
.collect::<Vec<u8>>(),
std::iter::repeat(0).take(size.bytes_usize()).collect::<Vec<u8>>(),
align,
);
let ptr = Pointer::new(AllocId(!0), Size::ZERO); // The alloc id is never used
@ -190,11 +178,8 @@ pub(crate) fn codegen_const_value<'tcx>(
let base_addr = match alloc_kind {
Some(GlobalAlloc::Memory(alloc)) => {
fx.cx.constants_cx.todo.push(TodoItem::Alloc(ptr.alloc_id));
let data_id = data_id_for_alloc_id(
&mut fx.cx.module,
ptr.alloc_id,
alloc.mutability,
);
let data_id =
data_id_for_alloc_id(fx.cx.module, ptr.alloc_id, alloc.mutability);
let local_data_id =
fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
#[cfg(debug_assertions)]
@ -203,15 +188,14 @@ pub(crate) fn codegen_const_value<'tcx>(
}
Some(GlobalAlloc::Function(instance)) => {
let func_id =
crate::abi::import_function(fx.tcx, &mut fx.cx.module, instance);
crate::abi::import_function(fx.tcx, fx.cx.module, instance);
let local_func_id =
fx.cx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
}
Some(GlobalAlloc::Static(def_id)) => {
assert!(fx.tcx.is_static(def_id));
let data_id =
data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false);
let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false);
let local_data_id =
fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
#[cfg(debug_assertions)]
@ -221,9 +205,7 @@ pub(crate) fn codegen_const_value<'tcx>(
None => bug!("missing allocation {:?}", ptr.alloc_id),
};
let val = if ptr.offset.bytes() != 0 {
fx.bcx
.ins()
.iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
} else {
base_addr
};
@ -240,22 +222,22 @@ pub(crate) fn codegen_const_value<'tcx>(
let ptr = pointer_for_allocation(fx, data)
.offset_i64(fx, i64::try_from(start).unwrap())
.get_addr(fx);
let len = fx.bcx.ins().iconst(
fx.pointer_type,
i64::try_from(end.checked_sub(start).unwrap()).unwrap(),
);
let len = fx
.bcx
.ins()
.iconst(fx.pointer_type, i64::try_from(end.checked_sub(start).unwrap()).unwrap());
CValue::by_val_pair(ptr, len, layout)
}
}
}
fn pointer_for_allocation<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
alloc: &'tcx Allocation,
) -> crate::pointer::Pointer {
let alloc_id = fx.tcx.create_memory_alloc(alloc);
fx.cx.constants_cx.todo.push(TodoItem::Alloc(alloc_id));
let data_id = data_id_for_alloc_id(&mut fx.cx.module, alloc_id, alloc.mutability);
let data_id = data_id_for_alloc_id(fx.cx.module, alloc_id, alloc.mutability);
let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
#[cfg(debug_assertions)]
@ -265,7 +247,7 @@ fn pointer_for_allocation<'tcx>(
}
fn data_id_for_alloc_id(
module: &mut impl Module,
module: &mut dyn Module,
alloc_id: AllocId,
mutability: rustc_hir::Mutability,
) -> DataId {
@ -281,7 +263,7 @@ fn data_id_for_alloc_id(
fn data_id_for_static(
tcx: TyCtxt<'_>,
module: &mut impl Module,
module: &mut dyn Module,
def_id: DefId,
definition: bool,
) -> DataId {
@ -304,12 +286,7 @@ fn data_id_for_static(
} else {
!ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all())
};
let align = tcx
.layout_of(ParamEnv::reveal_all().and(ty))
.unwrap()
.align
.pref
.bytes();
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
let attrs = tcx.codegen_fn_attrs(def_id);
@ -332,17 +309,11 @@ fn data_id_for_static(
// zero.
let ref_name = format!("_rust_extern_with_linkage_{}", symbol_name);
let ref_data_id = module
.declare_data(&ref_name, Linkage::Local, false, false)
.unwrap();
let ref_data_id = module.declare_data(&ref_name, Linkage::Local, false, false).unwrap();
let mut data_ctx = DataContext::new();
data_ctx.set_align(align);
let data = module.declare_data_in_data(data_id, &mut data_ctx);
data_ctx.define(
std::iter::repeat(0)
.take(pointer_ty(tcx).bytes() as usize)
.collect(),
);
data_ctx.define(std::iter::repeat(0).take(pointer_ty(tcx).bytes() as usize).collect());
data_ctx.write_data_addr(0, data, 0);
match module.define_data(ref_data_id, &data_ctx) {
// Every time the static is referenced there will be another definition of this global,
@ -356,7 +327,7 @@ fn data_id_for_static(
}
}
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut ConstantCx) {
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) {
while let Some(todo_item) = cx.todo.pop() {
let (data_id, alloc, section_name) = match todo_item {
TodoItem::Alloc(alloc_id) => {
@ -371,10 +342,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan
TodoItem::Static(def_id) => {
//println!("static {:?}", def_id);
let section_name = tcx
.codegen_fn_attrs(def_id)
.link_section
.map(|s| s.as_str());
let section_name = tcx.codegen_fn_attrs(def_id).link_section.map(|s| s.as_str());
let alloc = tcx.eval_static_initializer(def_id).unwrap();
@ -396,9 +364,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan
data_ctx.set_segment_section("", &*section_name);
}
let bytes = alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
.to_vec();
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
data_ctx.define(bytes.into_boxed_slice());
for &(offset, (_tag, reloc)) in alloc.relocations().iter() {
@ -426,10 +392,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan
data_id_for_alloc_id(module, reloc, target_alloc.mutability)
}
GlobalAlloc::Static(def_id) => {
if tcx
.codegen_fn_attrs(def_id)
.flags
.contains(CodegenFnAttrFlags::THREAD_LOCAL)
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
{
tcx.sess.fatal(&format!(
"Allocation {:?} contains reference to TLS value {:?}",
@ -457,14 +420,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan
}
pub(crate) fn mir_operand_get_const_val<'tcx>(
fx: &FunctionCx<'_, 'tcx, impl Module>,
fx: &FunctionCx<'_, '_, 'tcx>,
operand: &Operand<'tcx>,
) -> Option<&'tcx Const<'tcx>> {
match operand {
Operand::Copy(_) | Operand::Move(_) => None,
Operand::Constant(const_) => Some(
fx.monomorphize(const_.literal)
.eval(fx.tcx, ParamEnv::reveal_all()),
),
Operand::Constant(const_) => {
Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all()))
}
}
}

View File

@ -14,10 +14,7 @@ impl DebugContext<'_> {
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
let root = self.dwarf.unit.root();
let root = self.dwarf.unit.get_mut(root);
root.set(
gimli::DW_AT_ranges,
AttributeValue::RangeListRef(unit_range_list_id),
);
root.set(gimli::DW_AT_ranges, AttributeValue::RangeListRef(unit_range_list_id));
let mut sections = Sections::new(WriterRelocate::new(self.endian));
self.dwarf.write(&mut sections).unwrap();
@ -66,10 +63,7 @@ pub(super) struct WriterRelocate {
impl WriterRelocate {
pub(super) fn new(endian: RunTimeEndian) -> Self {
WriterRelocate {
relocs: Vec::new(),
writer: EndianVec::new(endian),
}
WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endian) }
}
/// Perform the collected relocations to be usable for JIT usage.
@ -85,9 +79,7 @@ impl WriterRelocate {
cranelift_module::FuncId::from_u32(sym.try_into().unwrap()),
);
let val = (addr as u64 as i64 + reloc.addend) as u64;
self.writer
.write_udata_at(reloc.offset as usize, val, reloc.size)
.unwrap();
self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap();
}
}
}

View File

@ -53,11 +53,7 @@ pub(crate) fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
if hash.kind == SourceFileHashAlgorithm::Md5 {
let mut buf = [0u8; MD5_LEN];
buf.copy_from_slice(hash.hash_bytes());
Some(FileInfo {
timestamp: 0,
size: 0,
md5: buf,
})
Some(FileInfo { timestamp: 0, size: 0, md5: buf })
} else {
None
}
@ -112,24 +108,14 @@ impl<'tcx> DebugContext<'tcx> {
let entry = self.dwarf.unit.get_mut(entry_id);
entry.set(
gimli::DW_AT_decl_file,
AttributeValue::FileIndex(Some(file_id)),
);
entry.set(
gimli::DW_AT_decl_line,
AttributeValue::Udata(loc.line as u64),
);
entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(loc.line as u64));
// FIXME: probably omit this
entry.set(
gimli::DW_AT_decl_column,
AttributeValue::Udata(loc.col.to_usize() as u64),
);
entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(loc.col.to_usize() as u64));
}
pub(super) fn create_debug_lines(
&mut self,
isa: &dyn cranelift_codegen::isa::TargetIsa,
symbol: usize,
entry_id: UnitEntryId,
context: &Context,
@ -138,7 +124,6 @@ impl<'tcx> DebugContext<'tcx> {
) -> CodeOffset {
let tcx = self.tcx;
let line_program = &mut self.dwarf.unit.line_program;
let func = &context.func;
let line_strings = &mut self.dwarf.line_strings;
let mut last_span = None;
@ -202,43 +187,22 @@ impl<'tcx> DebugContext<'tcx> {
let mut func_end = 0;
if let Some(ref mcr) = &context.mach_compile_result {
for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() {
line_program.row().address_offset = u64::from(start);
if !loc.is_default() {
let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap();
create_row_for_span(line_program, source_info.span);
} else {
create_row_for_span(line_program, function_span);
}
func_end = end;
let mcr = context.mach_compile_result.as_ref().unwrap();
for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() {
line_program.row().address_offset = u64::from(start);
if !loc.is_default() {
let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap();
create_row_for_span(line_program, source_info.span);
} else {
create_row_for_span(line_program, function_span);
}
line_program.end_sequence(u64::from(func_end));
func_end = mcr.buffer.total_size();
} else {
let encinfo = isa.encoding_info();
let mut blocks = func.layout.blocks().collect::<Vec<_>>();
blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase
for block in blocks {
for (offset, inst, size) in func.inst_offsets(block, &encinfo) {
let srcloc = func.srclocs[inst];
line_program.row().address_offset = u64::from(offset);
if !srcloc.is_default() {
let source_info =
*source_info_set.get_index(srcloc.bits() as usize).unwrap();
create_row_for_span(line_program, source_info.span);
} else {
create_row_for_span(line_program, function_span);
}
func_end = offset + size;
}
}
line_program.end_sequence(u64::from(func_end));
func_end = end;
}
line_program.end_sequence(u64::from(func_end));
let func_end = mcr.buffer.total_size();
assert_ne!(func_end, 0);
let entry = self.dwarf.unit.get_mut(entry_id);
@ -246,10 +210,7 @@ impl<'tcx> DebugContext<'tcx> {
gimli::DW_AT_low_pc,
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
);
entry.set(
gimli::DW_AT_high_pc,
AttributeValue::Udata(u64::from(func_end)),
);
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
self.emit_location(entry_id, function_span);

View File

@ -9,7 +9,7 @@ use crate::prelude::*;
use rustc_index::vec::IndexVec;
use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc};
use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::ValueLocRange;
@ -39,7 +39,6 @@ pub(crate) struct DebugContext<'tcx> {
dwarf: DwarfUnit,
unit_range_list: RangeList,
clif_types: FxHashMap<Type, UnitEntryId>,
types: FxHashMap<Ty<'tcx>, UnitEntryId>,
}
@ -91,20 +90,11 @@ impl<'tcx> DebugContext<'tcx> {
let root = dwarf.unit.root();
let root = dwarf.unit.get_mut(root);
root.set(
gimli::DW_AT_producer,
AttributeValue::StringRef(dwarf.strings.add(producer)),
);
root.set(
gimli::DW_AT_language,
AttributeValue::Language(gimli::DW_LANG_Rust),
);
root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer)));
root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust));
root.set(gimli::DW_AT_name, AttributeValue::StringRef(name));
root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir));
root.set(
gimli::DW_AT_low_pc,
AttributeValue::Address(Address::Constant(0)),
);
root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0)));
}
DebugContext {
@ -115,48 +105,10 @@ impl<'tcx> DebugContext<'tcx> {
dwarf,
unit_range_list: RangeList(Vec::new()),
clif_types: FxHashMap::default(),
types: FxHashMap::default(),
}
}
fn dwarf_ty_for_clif_ty(&mut self, ty: Type) -> UnitEntryId {
if let Some(type_id) = self.clif_types.get(&ty) {
return *type_id;
}
let new_entry = |dwarf: &mut DwarfUnit, tag| dwarf.unit.add(dwarf.unit.root(), tag);
let primitive = |dwarf: &mut DwarfUnit, ate| {
let type_id = new_entry(dwarf, gimli::DW_TAG_base_type);
let type_entry = dwarf.unit.get_mut(type_id);
type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(ate));
type_id
};
let type_id = if ty.is_bool() {
primitive(&mut self.dwarf, gimli::DW_ATE_boolean)
} else if ty.is_int() {
primitive(&mut self.dwarf, gimli::DW_ATE_address)
} else if ty.is_float() {
primitive(&mut self.dwarf, gimli::DW_ATE_float)
} else {
new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type)
};
let type_entry = self.dwarf.unit.get_mut(type_id);
type_entry.set(
gimli::DW_AT_name,
AttributeValue::String(format!("{}", ty).replace('i', "u").into_bytes()),
);
type_entry.set(
gimli::DW_AT_byte_size,
AttributeValue::Udata(u64::from(ty.bytes())),
);
type_id
}
fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId {
if let Some(type_id) = self.types.get(ty) {
return *type_id;
@ -181,10 +133,7 @@ impl<'tcx> DebugContext<'tcx> {
ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed),
ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float),
ty::Ref(_, pointee_ty, _mutbl)
| ty::RawPtr(ty::TypeAndMut {
ty: pointee_ty,
mutbl: _mutbl,
}) => {
| ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl: _mutbl }) => {
let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type);
// Ensure that type is inserted before recursing to avoid duplicates
@ -211,10 +160,7 @@ impl<'tcx> DebugContext<'tcx> {
let field_offset = layout.fields.offset(field_idx);
let field_layout = layout
.field(
&layout::LayoutCx {
tcx: self.tcx,
param_env: ParamEnv::reveal_all(),
},
&layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
field_idx,
)
.unwrap();
@ -243,10 +189,7 @@ impl<'tcx> DebugContext<'tcx> {
let type_entry = self.dwarf.unit.get_mut(type_id);
type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
type_entry.set(
gimli::DW_AT_byte_size,
AttributeValue::Udata(layout.size.bytes()),
);
type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
self.types.insert(ty, type_id);
@ -286,23 +229,15 @@ impl<'tcx> DebugContext<'tcx> {
let name_id = self.dwarf.strings.add(name);
// Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
entry.set(
gimli::DW_AT_linkage_name,
AttributeValue::StringRef(name_id),
);
entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id));
let end =
self.create_debug_lines(isa, symbol, entry_id, context, mir.span, source_info_set);
let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set);
self.unit_range_list.0.push(Range::StartLength {
begin: Address::Symbol { symbol, addend: 0 },
length: u64::from(end),
});
if isa.get_mach_backend().is_some() {
return; // Not yet implemented for the AArch64 backend.
}
let func_entry = self.dwarf.unit.get_mut(entry_id);
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
func_entry.set(
@ -312,51 +247,6 @@ impl<'tcx> DebugContext<'tcx> {
// Using Udata for DW_AT_high_pc requires at least DWARF4
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
// FIXME Remove once actual debuginfo for locals works.
for (i, (param, &val)) in context
.func
.signature
.params
.iter()
.zip(
context
.func
.dfg
.block_params(context.func.layout.entry_block().unwrap()),
)
.enumerate()
{
use cranelift_codegen::ir::ArgumentPurpose;
let base_name = match param.purpose {
ArgumentPurpose::Normal => "arg",
ArgumentPurpose::StructArgument(_) => "struct_arg",
ArgumentPurpose::StructReturn => "sret",
ArgumentPurpose::Link
| ArgumentPurpose::FramePointer
| ArgumentPurpose::CalleeSaved => continue,
ArgumentPurpose::VMContext
| ArgumentPurpose::SignatureId
| ArgumentPurpose::CallerTLS
| ArgumentPurpose::CalleeTLS
| ArgumentPurpose::StackLimit => unreachable!(),
};
let name = format!("{}{}", base_name, i);
let dw_ty = self.dwarf_ty_for_clif_ty(param.value_type);
let loc =
translate_loc(isa, context.func.locations[val], &context.func.stack_slots).unwrap();
let arg_id = self
.dwarf
.unit
.add(entry_id, gimli::DW_TAG_formal_parameter);
let var_entry = self.dwarf.unit.get_mut(arg_id);
var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
var_entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(loc));
}
// FIXME make it more reliable and implement scopes before re-enabling this.
if false {
let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
@ -376,10 +266,7 @@ impl<'tcx> DebugContext<'tcx> {
context,
&local_map,
&value_labels_ranges,
Place {
local,
projection: ty::List::empty(),
},
Place { local, projection: ty::List::empty() },
);
let var_entry = self.dwarf.unit.get_mut(var_id);
@ -417,10 +304,7 @@ fn place_location<'tcx>(
symbol,
addend: i64::from(value_loc_range.start),
},
end: Address::Symbol {
symbol,
addend: i64::from(value_loc_range.end),
},
end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
data: translate_loc(
isa,
value_loc_range.loc,
@ -463,17 +347,17 @@ fn place_location<'tcx>(
// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
fn translate_loc(
isa: &dyn TargetIsa,
loc: ValueLoc,
loc: LabelValueLoc,
stack_slots: &StackSlots,
) -> Option<Expression> {
match loc {
ValueLoc::Reg(reg) => {
LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => {
let machine_reg = isa.map_dwarf_register(reg).unwrap();
let mut expr = Expression::new();
expr.op_reg(gimli::Register(machine_reg));
Some(expr)
}
ValueLoc::Stack(ss) => {
LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => {
if let Some(ss_offset) = stack_slots[ss].offset {
let mut expr = Expression::new();
expr.op_breg(X86_64::RBP, i64::from(ss_offset) + 16);
@ -482,6 +366,17 @@ fn translate_loc(
None
}
}
_ => None,
LabelValueLoc::ValueLoc(ValueLoc::Unassigned) => unreachable!(),
LabelValueLoc::Reg(reg) => {
let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
let mut expr = Expression::new();
expr.op_reg(gimli::Register(machine_reg));
Some(expr)
}
LabelValueLoc::SPOffset(offset) => {
let mut expr = Expression::new();
expr.op_breg(X86_64::RSP, offset);
Some(expr)
}
}
}

View File

@ -28,11 +28,7 @@ impl<'tcx> UnwindContext<'tcx> {
None
};
UnwindContext {
tcx,
frame_table,
cie_id,
}
UnwindContext { tcx, frame_table, cie_id }
}
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
@ -46,10 +42,8 @@ impl<'tcx> UnwindContext<'tcx> {
UnwindInfo::SystemV(unwind_info) => {
self.frame_table.add_fde(
self.cie_id.unwrap(),
unwind_info.to_fde(Address::Symbol {
symbol: func_id.as_u32() as usize,
addend: 0,
}),
unwind_info
.to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }),
);
}
UnwindInfo::WindowsX64(_) => {
@ -60,9 +54,8 @@ impl<'tcx> UnwindContext<'tcx> {
}
pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(
self.tcx,
)));
let mut eh_frame =
EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
if !eh_frame.0.writer.slice().is_empty() {
@ -82,9 +75,8 @@ impl<'tcx> UnwindContext<'tcx> {
self,
jit_module: &cranelift_jit::JITModule,
) -> Option<UnwindRegistry> {
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(
self.tcx,
)));
let mut eh_frame =
EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
if eh_frame.0.writer.slice().is_empty() {
@ -130,10 +122,7 @@ impl<'tcx> UnwindContext<'tcx> {
registrations.push(ptr as usize);
}
Some(UnwindRegistry {
_frame_table: eh_frame,
registrations,
})
Some(UnwindRegistry { _frame_table: eh_frame, registrations })
}
}

View File

@ -7,7 +7,7 @@ use rustc_target::abi::{Int, TagEncoding, Variants};
use crate::prelude::*;
pub(crate) fn codegen_set_discriminant<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
place: CPlace<'tcx>,
variant_index: VariantIdx,
) {
@ -26,11 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
variants: _,
} => {
let ptr = place.place_field(fx, mir::Field::new(tag_field));
let to = layout
.ty
.discriminant_for_variant(fx.tcx, variant_index)
.unwrap()
.val;
let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val;
let to = if ptr.layout().abi.is_signed() {
ty::ScalarInt::try_from_int(
ptr.layout().size.sign_extend(to) as i128,
@ -46,12 +42,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
Variants::Multiple {
tag: _,
tag_field,
tag_encoding:
TagEncoding::Niche {
dataful_variant,
ref niche_variants,
niche_start,
},
tag_encoding: TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
variants: _,
} => {
if variant_index != dataful_variant {
@ -70,7 +61,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
}
pub(crate) fn codegen_get_discriminant<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
value: CValue<'tcx>,
dest_layout: TyAndLayout<'tcx>,
) -> CValue<'tcx> {
@ -101,12 +92,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
};
return CValue::const_val(fx, dest_layout, discr_val);
}
Variants::Multiple {
tag,
tag_field,
tag_encoding,
variants: _,
} => (tag, *tag_field, tag_encoding),
Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => {
(tag, *tag_field, tag_encoding)
}
};
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
@ -125,11 +113,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
let val = clif_intcast(fx, tag, cast_to, signed);
CValue::by_val(val, dest_layout)
}
TagEncoding::Niche {
dataful_variant,
ref niche_variants,
niche_start,
} => {
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
// Rebase from niche values to discriminants, and check
// whether the result is in range for the niche variants.
@ -146,9 +130,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
tag
} else {
// FIXME handle niche_start > i64::MAX
fx.bcx
.ins()
.iadd_imm(tag, -i64::try_from(niche_start).unwrap())
fx.bcx.ins().iadd_imm(tag, -i64::try_from(niche_start).unwrap())
};
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
let is_niche = {
@ -176,15 +158,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
} else {
clif_intcast(fx, relative_discr, cast_to, false)
};
fx.bcx
.ins()
.iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
};
let dataful_variant = fx
.bcx
.ins()
.iconst(cast_to, i64::from(dataful_variant.as_u32()));
let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
CValue::by_val(discr, dest_layout)
}

View File

@ -12,11 +12,9 @@ use rustc_middle::mir::mono::{CodegenUnit, MonoItem};
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{DebugInfo, OutputType};
use cranelift_object::{ObjectModule, ObjectProduct};
use cranelift_object::ObjectModule;
use crate::prelude::*;
use crate::backend::AddConstructor;
use crate::{prelude::*, BackendConfig};
fn new_module(tcx: TyCtxt<'_>, name: String) -> ObjectModule {
let module = crate::backend::make_module(tcx.sess, name);
@ -39,7 +37,6 @@ fn emit_module(
module: ObjectModule,
debug: Option<DebugContext<'_>>,
unwind_context: UnwindContext<'_>,
map_product: impl FnOnce(ObjectProduct) -> ObjectProduct,
) -> ModuleCodegenResult {
let mut product = module.finish();
@ -49,15 +46,10 @@ fn emit_module(
unwind_context.emit(&mut product);
let product = map_product(product);
let tmp_file = tcx
.output_filenames(LOCAL_CRATE)
.temp_path(OutputType::Object, Some(&name));
let tmp_file = tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(&name));
let obj = product.object.write().unwrap();
if let Err(err) = std::fs::write(&tmp_file, obj) {
tcx.sess
.fatal(&format!("error writing object file: {}", err));
tcx.sess.fatal(&format!("error writing object file: {}", err));
}
let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() {
@ -71,13 +63,7 @@ fn emit_module(
};
ModuleCodegenResult(
CompiledModule {
name,
kind,
object: Some(tmp_file),
dwarf_object: None,
bytecode: None,
},
CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None },
work_product,
)
}
@ -117,55 +103,33 @@ fn reuse_workproduct_for_cgu(
}
}
fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodegenResult {
fn module_codegen(
tcx: TyCtxt<'_>,
(backend_config, cgu_name): (BackendConfig, rustc_span::Symbol),
) -> ModuleCodegenResult {
let cgu = tcx.codegen_unit(cgu_name);
let mono_items = cgu.items_in_deterministic_order(tcx);
let mut module = new_module(tcx, cgu_name.as_str().to_string());
// Initialize the global atomic mutex using a constructor for proc-macros.
// FIXME implement atomic instructions in Cranelift.
let mut init_atomics_mutex_from_constructor = None;
if tcx
.sess
.crate_types()
.contains(&rustc_session::config::CrateType::ProcMacro)
{
if mono_items.iter().any(|(mono_item, _)| match mono_item {
rustc_middle::mir::mono::MonoItem::Static(def_id) => tcx
.symbol_name(Instance::mono(tcx, *def_id))
.name
.contains("__rustc_proc_macro_decls_"),
_ => false,
}) {
init_atomics_mutex_from_constructor =
Some(crate::atomic_shim::init_global_lock_constructor(
&mut module,
&format!("{}_init_atomics_mutex", cgu_name.as_str()),
));
}
}
let mut cx = crate::CodegenCx::new(
tcx,
module,
backend_config,
&mut module,
tcx.sess.opts.debuginfo != DebugInfo::None,
true,
);
super::predefine_mono_items(&mut cx, &mono_items);
for (mono_item, (linkage, visibility)) in mono_items {
let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility);
match mono_item {
MonoItem::Fn(inst) => {
cx.tcx.sess.time("codegen fn", || {
crate::base::codegen_fn(&mut cx, inst, linkage)
});
cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage));
}
MonoItem::Static(def_id) => {
crate::constant::codegen_static(&mut cx.constants_cx, def_id)
}
MonoItem::GlobalAsm(hir_id) => {
let item = cx.tcx.hir().expect_item(hir_id);
MonoItem::GlobalAsm(item_id) => {
let item = cx.tcx.hir().item(item_id);
if let rustc_hir::ItemKind::GlobalAsm(rustc_hir::GlobalAsm { asm }) = item.kind {
cx.global_asm.push_str(&*asm.as_str());
cx.global_asm.push_str("\n\n");
@ -175,9 +139,9 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
}
}
}
let (mut module, global_asm, debug, mut unwind_context) =
let (global_asm, debug, mut unwind_context) =
tcx.sess.time("finalize CodegenCx", || cx.finalize());
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context, false);
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context);
let codegen_result = emit_module(
tcx,
@ -186,13 +150,6 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
module,
debug,
unwind_context,
|mut product| {
if let Some(func_id) = init_atomics_mutex_from_constructor {
product.add_constructor(func_id);
}
product
},
);
codegen_global_asm(tcx, &cgu.name().as_str(), &global_asm);
@ -202,6 +159,7 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
pub(super) fn run_aot(
tcx: TyCtxt<'_>,
backend_config: BackendConfig,
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)> {
@ -225,9 +183,7 @@ pub(super) fn run_aot(
cgus.iter()
.map(|cgu| {
let cgu_reuse = determine_cgu_reuse(tcx, cgu);
tcx.sess
.cgu_reuse_tracker
.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
match cgu_reuse {
_ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {}
@ -242,7 +198,7 @@ pub(super) fn run_aot(
let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task(
dep_node,
tcx,
cgu.name(),
(backend_config, cgu.name()),
module_codegen,
rustc_middle::dep_graph::hash_result,
);
@ -271,7 +227,6 @@ pub(super) fn run_aot(
allocator_module,
None,
allocator_unwind_context,
|product| product,
);
if let Some((id, product)) = work_product {
work_products.insert(id, product);
@ -301,8 +256,7 @@ pub(super) fn run_aot(
});
if let Err(err) = std::fs::write(&tmp_file, obj) {
tcx.sess
.fatal(&format!("error writing metadata object file: {}", err));
tcx.sess.fatal(&format!("error writing metadata object file: {}", err));
}
(metadata_cgu_name, tmp_file)
@ -356,8 +310,7 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
);
} else {
tcx.sess
.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
}
}
@ -367,19 +320,12 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
// Remove all LLVM style comments
let global_asm = global_asm
.lines()
.map(|line| {
if let Some(index) = line.find("//") {
&line[0..index]
} else {
line
}
})
.map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
.collect::<Vec<_>>()
.join("\n");
let output_object_file = tcx
.output_filenames(LOCAL_CRATE)
.temp_path(OutputType::Object, Some(cgu_name));
let output_object_file =
tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(cgu_name));
// Assemble `global_asm`
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
@ -389,16 +335,10 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
.stdin(Stdio::piped())
.spawn()
.expect("Failed to spawn `as`.");
child
.stdin
.take()
.unwrap()
.write_all(global_asm.as_bytes())
.unwrap();
child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
let status = child.wait().expect("Failed to wait for `as`.");
if !status.success() {
tcx.sess
.fatal(&format!("Failed to assemble `{}`", global_asm));
tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm));
}
// Link the global asm and main object file together
@ -442,11 +382,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
}
let work_product_id = &cgu.work_product_id();
if tcx
.dep_graph
.previous_work_product(work_product_id)
.is_none()
{
if tcx.dep_graph.previous_work_product(work_product_id).is_none() {
// We don't have anything cached for this CGU. This can happen
// if the CGU did not exist in the previous session.
return CguReuse::No;
@ -465,9 +401,5 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
cgu.name()
);
if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() {
CguReuse::PreLto
} else {
CguReuse::No
}
if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No }
}

View File

@ -10,43 +10,24 @@ use rustc_middle::mir::mono::MonoItem;
use cranelift_jit::{JITBuilder, JITModule};
use crate::prelude::*;
use crate::{prelude::*, BackendConfig};
use crate::{CodegenCx, CodegenMode};
thread_local! {
pub static BACKEND_CONFIG: RefCell<Option<BackendConfig>> = RefCell::new(None);
pub static CURRENT_MODULE: RefCell<Option<JITModule>> = RefCell::new(None);
}
pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! {
pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
if !tcx.sess.opts.output_types.should_codegen() {
tcx.sess.fatal("JIT mode doesn't work with `cargo check`.");
}
#[cfg(unix)]
unsafe {
// When not using our custom driver rustc will open us without the RTLD_GLOBAL flag, so
// __cg_clif_global_atomic_mutex will not be exported. We fix this by opening ourself again
// as global.
// FIXME remove once atomic_shim is gone
let mut dl_info: libc::Dl_info = std::mem::zeroed();
assert_ne!(
libc::dladdr(run_jit as *const libc::c_void, &mut dl_info),
0
);
assert_ne!(
libc::dlopen(dl_info.dli_fname, libc::RTLD_NOW | libc::RTLD_GLOBAL),
std::ptr::null_mut(),
);
}
let imported_symbols = load_imported_symbols_for_jit(tcx);
let mut jit_builder = JITBuilder::with_isa(
crate::build_isa(tcx.sess),
cranelift_module::default_libcall_names(),
);
jit_builder.hotswap(matches!(codegen_mode, CodegenMode::JitLazy));
let mut jit_builder =
JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names());
jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy));
jit_builder.symbols(imported_symbols);
let mut jit_module = JITModule::new(jit_builder);
assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type());
@ -56,14 +37,10 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! {
AbiParam::new(jit_module.target_config().pointer_type()),
AbiParam::new(jit_module.target_config().pointer_type()),
],
returns: vec![AbiParam::new(
jit_module.target_config().pointer_type(), /*isize*/
)],
returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
};
let main_func_id = jit_module
.declare_function("main", Linkage::Import, &sig)
.unwrap();
let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap();
let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
let mono_items = cgus
@ -74,35 +51,34 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! {
.into_iter()
.collect::<Vec<(_, (_, _))>>();
let mut cx = crate::CodegenCx::new(tcx, jit_module, false, false);
let mut cx = crate::CodegenCx::new(tcx, backend_config, &mut jit_module, false);
super::time(tcx, "codegen mono items", || {
super::predefine_mono_items(&mut cx, &mono_items);
for (mono_item, (linkage, visibility)) in mono_items {
let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility);
match mono_item {
MonoItem::Fn(inst) => match codegen_mode {
MonoItem::Fn(inst) => match backend_config.codegen_mode {
CodegenMode::Aot => unreachable!(),
CodegenMode::Jit => {
cx.tcx.sess.time("codegen fn", || {
crate::base::codegen_fn(&mut cx, inst, linkage)
});
cx.tcx
.sess
.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage));
}
CodegenMode::JitLazy => codegen_shim(&mut cx, inst),
},
MonoItem::Static(def_id) => {
crate::constant::codegen_static(&mut cx.constants_cx, def_id);
}
MonoItem::GlobalAsm(hir_id) => {
let item = cx.tcx.hir().expect_item(hir_id);
tcx.sess
.span_fatal(item.span, "Global asm is not supported in JIT mode");
MonoItem::GlobalAsm(item_id) => {
let item = cx.tcx.hir().item(item_id);
tcx.sess.span_fatal(item.span, "Global asm is not supported in JIT mode");
}
}
}
});
let (mut jit_module, global_asm, _debug, mut unwind_context) =
let (global_asm, _debug, mut unwind_context) =
tcx.sess.time("finalize CodegenCx", || cx.finalize());
jit_module.finalize_definitions();
@ -110,7 +86,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! {
tcx.sess.fatal("Inline asm is not supported in JIT mode");
}
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context, true);
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context);
crate::allocator::codegen(tcx, &mut jit_module, &mut unwind_context);
tcx.sess.abort_if_errors();
@ -121,7 +97,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! {
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
println!("Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed");
println!(
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
);
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
unsafe { ::std::mem::transmute(finalized_main) };
@ -137,6 +115,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! {
// useful as some dynamic linkers use it as a marker to jump over.
argv.push(std::ptr::null());
BACKEND_CONFIG.with(|tls_backend_config| {
assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none())
});
CURRENT_MODULE
.with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none()));
@ -154,21 +135,19 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8
CURRENT_MODULE.with(|jit_module| {
let mut jit_module = jit_module.borrow_mut();
let jit_module = jit_module.as_mut().unwrap();
let mut cx = crate::CodegenCx::new(tcx, jit_module, false, false);
let backend_config =
BACKEND_CONFIG.with(|backend_config| backend_config.borrow().clone().unwrap());
let name = tcx.symbol_name(instance).name.to_string();
let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), instance);
let func_id = cx
.module
.declare_function(&name, Linkage::Export, &sig)
.unwrap();
cx.module.prepare_for_function_redefine(func_id).unwrap();
let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
let func_id = jit_module.declare_function(&name, Linkage::Export, &sig).unwrap();
jit_module.prepare_for_function_redefine(func_id).unwrap();
tcx.sess.time("codegen fn", || {
crate::base::codegen_fn(&mut cx, instance, Linkage::Export)
});
let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false);
tcx.sess
.time("codegen fn", || crate::base::codegen_fn(&mut cx, instance, Linkage::Export));
let (jit_module, global_asm, _debug_context, unwind_context) = cx.finalize();
let (global_asm, _debug_context, unwind_context) = cx.finalize();
assert!(global_asm.is_empty());
jit_module.finalize_definitions();
std::mem::forget(unsafe { unwind_context.register_jit(&jit_module) });
@ -195,9 +174,8 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Linkage::Static => {
let name = tcx.crate_name(cnum);
let mut err = tcx
.sess
.struct_err(&format!("Can't load static lib {}", name.as_str()));
let mut err =
tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
err.emit();
}
@ -218,6 +196,11 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
if name.is_empty() || !symbol.is_global() || symbol.is_undefined() {
return None;
}
if name.starts_with("rust_metadata_") {
// The metadata is part of a section that is not loaded by the dynamic linker in
// case of cg_llvm.
return None;
}
let dlsym_name = if cfg!(target_os = "macos") {
// On macOS `dlsym` expects the name without leading `_`.
assert!(name.starts_with('_'), "{:?}", name);
@ -237,17 +220,14 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
imported_symbols
}
pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx, impl Module>, inst: Instance<'tcx>) {
pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) {
let tcx = cx.tcx;
let pointer_type = cx.module.target_config().pointer_type();
let name = tcx.symbol_name(inst).name.to_string();
let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), inst);
let func_id = cx
.module
.declare_function(&name, Linkage::Export, &sig)
.unwrap();
let func_id = cx.module.declare_function(&name, Linkage::Export, &sig).unwrap();
let instance_ptr = Box::into_raw(Box::new(inst));
@ -268,28 +248,18 @@ pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx, impl Module>, inst: In
let mut builder_ctx = FunctionBuilderContext::new();
let mut trampoline_builder = FunctionBuilder::new(&mut trampoline, &mut builder_ctx);
let jit_fn = cx
.module
.declare_func_in_func(jit_fn, trampoline_builder.func);
let jit_fn = cx.module.declare_func_in_func(jit_fn, trampoline_builder.func);
let sig_ref = trampoline_builder.func.import_signature(sig);
let entry_block = trampoline_builder.create_block();
trampoline_builder.append_block_params_for_function_params(entry_block);
let fn_args = trampoline_builder
.func
.dfg
.block_params(entry_block)
.to_vec();
let fn_args = trampoline_builder.func.dfg.block_params(entry_block).to_vec();
trampoline_builder.switch_to_block(entry_block);
let instance_ptr = trampoline_builder
.ins()
.iconst(pointer_type, instance_ptr as u64 as i64);
let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64);
let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]);
let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0];
let call_inst = trampoline_builder
.ins()
.call_indirect(sig_ref, jitted_fn, &fn_args);
let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args);
let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();
trampoline_builder.ins().return_(&ret_vals);

View File

@ -17,33 +17,30 @@ pub(crate) fn codegen_crate(
tcx: TyCtxt<'_>,
metadata: EncodedMetadata,
need_metadata_module: bool,
config: crate::BackendConfig,
backend_config: crate::BackendConfig,
) -> Box<dyn Any> {
tcx.sess.abort_if_errors();
match config.codegen_mode {
CodegenMode::Aot => aot::run_aot(tcx, metadata, need_metadata_module),
match backend_config.codegen_mode {
CodegenMode::Aot => aot::run_aot(tcx, backend_config, metadata, need_metadata_module),
CodegenMode::Jit | CodegenMode::JitLazy => {
let is_executable = tcx
.sess
.crate_types()
.contains(&rustc_session::config::CrateType::Executable);
let is_executable =
tcx.sess.crate_types().contains(&rustc_session::config::CrateType::Executable);
if !is_executable {
tcx.sess.fatal("can't jit non-executable crate");
}
#[cfg(feature = "jit")]
let _: ! = jit::run_jit(tcx, config.codegen_mode);
let _: ! = jit::run_jit(tcx, backend_config);
#[cfg(not(feature = "jit"))]
tcx.sess
.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
}
}
}
fn predefine_mono_items<'tcx>(
cx: &mut crate::CodegenCx<'tcx, impl Module>,
cx: &mut crate::CodegenCx<'_, 'tcx>,
mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))],
) {
cx.tcx.sess.time("predefine functions", || {
@ -63,21 +60,12 @@ fn predefine_mono_items<'tcx>(
}
fn time<R>(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R {
if std::env::var("CG_CLIF_DISPLAY_CG_TIME")
.as_ref()
.map(|val| &**val)
== Ok("1")
{
if std::env::var("CG_CLIF_DISPLAY_CG_TIME").as_ref().map(|val| &**val) == Ok("1") {
println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name);
let before = std::time::Instant::now();
let res = tcx.sess.time(name, f);
let after = std::time::Instant::now();
println!(
"[{:<30}: {}] end time: {:?}",
tcx.crate_name(LOCAL_CRATE),
name,
after - before
);
println!("[{:<30}: {}] end time: {:?}", tcx.crate_name(LOCAL_CRATE), name, after - before);
res
} else {
tcx.sess.time(name, f)

View File

@ -9,7 +9,7 @@ use rustc_middle::mir::InlineAsmOperand;
use rustc_target::asm::*;
pub(crate) fn codegen_inline_asm<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
_span: Span,
template: &[InlineAsmTemplatePiece],
operands: &[InlineAsmOperand<'tcx>],
@ -53,11 +53,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
crate::base::codegen_operand(fx, value).load_scalar(fx),
));
}
InlineAsmOperand::Out {
reg,
late: _,
place,
} => {
InlineAsmOperand::Out { reg, late: _, place } => {
let reg = expect_reg(reg);
clobbered_regs.push((reg, new_slot(reg.reg_class())));
if let Some(place) = place {
@ -68,12 +64,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
));
}
}
InlineAsmOperand::InOut {
reg,
late: _,
ref in_value,
out_place,
} => {
InlineAsmOperand::InOut { reg, late: _, ref in_value, out_place } => {
let reg = expect_reg(reg);
clobbered_regs.push((reg, new_slot(reg.reg_class())));
inputs.push((
@ -97,11 +88,8 @@ pub(crate) fn codegen_inline_asm<'tcx>(
let inline_asm_index = fx.inline_asm_index;
fx.inline_asm_index += 1;
let asm_name = format!(
"{}__inline_asm_{}",
fx.tcx.symbol_name(fx.instance).name,
inline_asm_index
);
let asm_name =
format!("{}__inline_asm_{}", fx.tcx.symbol_name(fx.instance).name, inline_asm_index);
let generated_asm = generate_asm_wrapper(
&asm_name,
@ -129,12 +117,7 @@ fn generate_asm_wrapper(
let mut generated_asm = String::new();
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
writeln!(
generated_asm,
".section .text.{},\"ax\",@progbits",
asm_name
)
.unwrap();
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
writeln!(generated_asm, "{}:", asm_name).unwrap();
generated_asm.push_str(".intel_syntax noprefix\n");
@ -164,11 +147,7 @@ fn generate_asm_wrapper(
InlineAsmTemplatePiece::String(s) => {
generated_asm.push_str(s);
}
InlineAsmTemplatePiece::Placeholder {
operand_idx: _,
modifier: _,
span: _,
} => todo!(),
InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span: _ } => todo!(),
}
}
generated_asm.push('\n');
@ -203,7 +182,7 @@ fn generate_asm_wrapper(
}
fn call_inline_asm<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
asm_name: &str,
slot_size: Size,
inputs: Vec<(InlineAsmReg, Size, Value)>,
@ -230,17 +209,12 @@ fn call_inline_asm<'tcx>(
},
)
.unwrap();
let inline_asm_func = fx
.cx
.module
.declare_func_in_func(inline_asm_func, &mut fx.bcx.func);
let inline_asm_func = fx.cx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func);
#[cfg(debug_assertions)]
fx.add_comment(inline_asm_func, asm_name);
for (_reg, offset, value) in inputs {
fx.bcx
.ins()
.stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
}
let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
@ -248,10 +222,7 @@ fn call_inline_asm<'tcx>(
for (_reg, offset, place) in outputs {
let ty = fx.clif_type(place.layout().ty).unwrap();
let value = fx
.bcx
.ins()
.stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
}
}
@ -267,8 +238,7 @@ fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsm
match arch {
InlineAsmArch::X86_64 => {
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
reg.emit(generated_asm, InlineAsmArch::X86_64, None)
.unwrap();
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
generated_asm.push('\n');
}
_ => unimplemented!("save_register for {:?}", arch),
@ -284,8 +254,7 @@ fn restore_register(
match arch {
InlineAsmArch::X86_64 => {
generated_asm.push_str(" mov ");
reg.emit(generated_asm, InlineAsmArch::X86_64, None)
.unwrap();
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
}
_ => unimplemented!("restore_register for {:?}", arch),

View File

@ -6,7 +6,7 @@ use crate::prelude::*;
///
/// This emulates an intel cpu with sse and sse2 support, but which doesn't support anything else.
pub(crate) fn codegen_cpuid_call<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
leaf: Value,
_subleaf: Value,
) -> (Value, Value, Value, Value) {
@ -31,54 +31,28 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
fx.bcx.switch_to_block(leaf_0);
let max_basic_leaf = fx.bcx.ins().iconst(types::I32, 1);
let vend0 = fx
.bcx
.ins()
.iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu")));
let vend2 = fx
.bcx
.ins()
.iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI")));
let vend1 = fx
.bcx
.ins()
.iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel")));
fx.bcx
.ins()
.jump(dest, &[max_basic_leaf, vend0, vend1, vend2]);
let vend0 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu")));
let vend2 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI")));
let vend1 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel")));
fx.bcx.ins().jump(dest, &[max_basic_leaf, vend0, vend1, vend2]);
fx.bcx.switch_to_block(leaf_1);
let cpu_signature = fx.bcx.ins().iconst(types::I32, 0);
let additional_information = fx.bcx.ins().iconst(types::I32, 0);
let ecx_features = fx.bcx.ins().iconst(types::I32, 0);
let edx_features = fx
.bcx
.ins()
.iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */);
fx.bcx.ins().jump(
dest,
&[
cpu_signature,
additional_information,
ecx_features,
edx_features,
],
);
let edx_features = fx.bcx.ins().iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */);
fx.bcx.ins().jump(dest, &[cpu_signature, additional_information, ecx_features, edx_features]);
fx.bcx.switch_to_block(leaf_8000_0000);
let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0);
let zero = fx.bcx.ins().iconst(types::I32, 0);
fx.bcx
.ins()
.jump(dest, &[extended_max_basic_leaf, zero, zero, zero]);
fx.bcx.ins().jump(dest, &[extended_max_basic_leaf, zero, zero, zero]);
fx.bcx.switch_to_block(leaf_8000_0001);
let zero = fx.bcx.ins().iconst(types::I32, 0);
let proc_info_ecx = fx.bcx.ins().iconst(types::I32, 0);
let proc_info_edx = fx.bcx.ins().iconst(types::I32, 0);
fx.bcx
.ins()
.jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
fx.bcx.switch_to_block(unsupported_leaf);
crate::trap::trap_unreachable(

View File

@ -6,7 +6,7 @@ use crate::prelude::*;
use rustc_middle::ty::subst::SubstsRef;
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str,
substs: SubstsRef<'tcx>,
args: &[mir::Operand<'tcx>],

View File

@ -9,6 +9,7 @@ pub(crate) use cpuid::codegen_cpuid_call;
pub(crate) use llvm::codegen_llvm_intrinsic_call;
use crate::prelude::*;
use cranelift_codegen::ir::AtomicRmwOp;
use rustc_middle::ty::print::with_no_trimmed_paths;
macro intrinsic_pat {
@ -112,38 +113,6 @@ macro call_intrinsic_match {
}
}
macro atomic_binop_return_old($fx:expr, $op:ident<$T:ident>($ptr:ident, $src:ident) -> $ret:ident) {
crate::atomic_shim::lock_global_lock($fx);
let clif_ty = $fx.clif_type($T).unwrap();
let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0);
let new = $fx.bcx.ins().$op(old, $src);
$fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0);
$ret.write_cvalue($fx, CValue::by_val(old, $fx.layout_of($T)));
crate::atomic_shim::unlock_global_lock($fx);
}
macro atomic_minmax($fx:expr, $cc:expr, <$T:ident> ($ptr:ident, $src:ident) -> $ret:ident) {
crate::atomic_shim::lock_global_lock($fx);
// Read old
let clif_ty = $fx.clif_type($T).unwrap();
let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0);
// Compare
let is_eq = $fx.bcx.ins().icmp(IntCC::SignedGreaterThan, old, $src);
let new = $fx.bcx.ins().select(is_eq, old, $src);
// Write new
$fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0);
let ret_val = CValue::by_val(old, $ret.layout());
$ret.write_cvalue($fx, ret_val);
crate::atomic_shim::unlock_global_lock($fx);
}
macro validate_atomic_type($fx:ident, $intrinsic:ident, $span:ident, $ty:expr) {
match $ty.kind() {
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
@ -184,12 +153,12 @@ pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx
}
}
fn simd_for_each_lane<'tcx, M: Module>(
fx: &mut FunctionCx<'_, 'tcx, M>,
fn simd_for_each_lane<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
val: CValue<'tcx>,
ret: CPlace<'tcx>,
f: impl Fn(
&mut FunctionCx<'_, 'tcx, M>,
&mut FunctionCx<'_, '_, 'tcx>,
TyAndLayout<'tcx>,
TyAndLayout<'tcx>,
Value,
@ -213,13 +182,13 @@ fn simd_for_each_lane<'tcx, M: Module>(
}
}
fn simd_pair_for_each_lane<'tcx, M: Module>(
fx: &mut FunctionCx<'_, 'tcx, M>,
fn simd_pair_for_each_lane<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
x: CValue<'tcx>,
y: CValue<'tcx>,
ret: CPlace<'tcx>,
f: impl Fn(
&mut FunctionCx<'_, 'tcx, M>,
&mut FunctionCx<'_, '_, 'tcx>,
TyAndLayout<'tcx>,
TyAndLayout<'tcx>,
Value,
@ -246,11 +215,11 @@ fn simd_pair_for_each_lane<'tcx, M: Module>(
}
}
fn simd_reduce<'tcx, M: Module>(
fx: &mut FunctionCx<'_, 'tcx, M>,
fn simd_reduce<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
val: CValue<'tcx>,
ret: CPlace<'tcx>,
f: impl Fn(&mut FunctionCx<'_, 'tcx, M>, TyAndLayout<'tcx>, Value, Value) -> Value,
f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, Value, Value) -> Value,
) {
let (lane_count, lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
let lane_layout = fx.layout_of(lane_ty);
@ -258,20 +227,19 @@ fn simd_reduce<'tcx, M: Module>(
let mut res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
for lane_idx in 1..lane_count {
let lane = val
.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap()))
.load_scalar(fx);
let lane =
val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx);
res_val = f(fx, lane_layout, res_val, lane);
}
let res = CValue::by_val(res_val, lane_layout);
ret.write_cvalue(fx, res);
}
fn simd_reduce_bool<'tcx, M: Module>(
fx: &mut FunctionCx<'_, 'tcx, M>,
fn simd_reduce_bool<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
val: CValue<'tcx>,
ret: CPlace<'tcx>,
f: impl Fn(&mut FunctionCx<'_, 'tcx, M>, Value, Value) -> Value,
f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, Value, Value) -> Value,
) {
let (lane_count, _lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
assert!(ret.layout().ty.is_bool());
@ -279,9 +247,8 @@ fn simd_reduce_bool<'tcx, M: Module>(
let res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
let mut res_val = fx.bcx.ins().band_imm(res_val, 1); // mask to boolean
for lane_idx in 1..lane_count {
let lane = val
.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap()))
.load_scalar(fx);
let lane =
val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx);
let lane = fx.bcx.ins().band_imm(lane, 1); // mask to boolean
res_val = f(fx, res_val, lane);
}
@ -290,7 +257,7 @@ fn simd_reduce_bool<'tcx, M: Module>(
}
fn bool_to_zero_or_max_uint<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
layout: TyAndLayout<'tcx>,
val: Value,
) -> CValue<'tcx> {
@ -424,7 +391,7 @@ macro simd_flt_binop($fx:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) {
}
pub(crate) fn codegen_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
instance: Instance<'tcx>,
args: &[mir::Operand<'tcx>],
destination: Option<(CPlace<'tcx>, BasicBlock)>,
@ -912,136 +879,175 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
};
_ if intrinsic.starts_with("atomic_fence"), () {
crate::atomic_shim::lock_global_lock(fx);
crate::atomic_shim::unlock_global_lock(fx);
fx.bcx.ins().fence();
};
_ if intrinsic.starts_with("atomic_singlethreadfence"), () {
crate::atomic_shim::lock_global_lock(fx);
crate::atomic_shim::unlock_global_lock(fx);
// FIXME use a compiler fence once Cranelift supports it
fx.bcx.ins().fence();
};
_ if intrinsic.starts_with("atomic_load"), (c ptr) {
crate::atomic_shim::lock_global_lock(fx);
_ if intrinsic.starts_with("atomic_load"), <T> (v ptr) {
validate_atomic_type!(fx, intrinsic, span, T);
let ty = fx.clif_type(T).unwrap();
let inner_layout =
fx.layout_of(ptr.layout().ty.builtin_deref(true).unwrap().ty);
validate_atomic_type!(fx, intrinsic, span, inner_layout.ty);
let val = CValue::by_ref(Pointer::new(ptr.load_scalar(fx)), inner_layout);
let val = fx.bcx.ins().atomic_load(ty, MemFlags::trusted(), ptr);
let val = CValue::by_val(val, fx.layout_of(T));
ret.write_cvalue(fx, val);
crate::atomic_shim::unlock_global_lock(fx);
};
_ if intrinsic.starts_with("atomic_store"), (v ptr, c val) {
validate_atomic_type!(fx, intrinsic, span, val.layout().ty);
crate::atomic_shim::lock_global_lock(fx);
let val = val.load_scalar(fx);
let dest = CPlace::for_ptr(Pointer::new(ptr), val.layout());
dest.write_cvalue(fx, val);
crate::atomic_shim::unlock_global_lock(fx);
fx.bcx.ins().atomic_store(MemFlags::trusted(), val, ptr);
};
_ if intrinsic.starts_with("atomic_xchg"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, T);
_ if intrinsic.starts_with("atomic_xchg"), (v ptr, c new) {
let layout = new.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
crate::atomic_shim::lock_global_lock(fx);
let new = new.load_scalar(fx);
// Read old
let clif_ty = fx.clif_type(T).unwrap();
let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0);
ret.write_cvalue(fx, CValue::by_val(old, fx.layout_of(T)));
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xchg, ptr, new);
// Write new
let dest = CPlace::for_ptr(Pointer::new(ptr), src.layout());
dest.write_cvalue(fx, src);
crate::atomic_shim::unlock_global_lock(fx);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_cxchg"), <T> (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_*
validate_atomic_type!(fx, intrinsic, span, T);
_ if intrinsic.starts_with("atomic_cxchg"), (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_*
let layout = new.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let test_old = test_old.load_scalar(fx);
let new = new.load_scalar(fx);
crate::atomic_shim::lock_global_lock(fx);
// Read old
let clif_ty = fx.clif_type(T).unwrap();
let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0);
// Compare
let old = fx.bcx.ins().atomic_cas(MemFlags::trusted(), ptr, test_old, new);
let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old);
let new = fx.bcx.ins().select(is_eq, new, old); // Keep old if not equal to test_old
// Write new
fx.bcx.ins().store(MemFlags::new(), new, ptr, 0);
let ret_val = CValue::by_val_pair(old, fx.bcx.ins().bint(types::I8, is_eq), ret.layout());
ret.write_cvalue(fx, ret_val);
crate::atomic_shim::unlock_global_lock(fx);
ret.write_cvalue(fx, ret_val)
};
_ if intrinsic.starts_with("atomic_xadd"), <T> (v ptr, c amount) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
_ if intrinsic.starts_with("atomic_xadd"), (v ptr, c amount) {
let layout = amount.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let amount = amount.load_scalar(fx);
atomic_binop_return_old! (fx, iadd<T>(ptr, amount) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Add, ptr, amount);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_xsub"), <T> (v ptr, c amount) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
_ if intrinsic.starts_with("atomic_xsub"), (v ptr, c amount) {
let layout = amount.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let amount = amount.load_scalar(fx);
atomic_binop_return_old! (fx, isub<T>(ptr, amount) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Sub, ptr, amount);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_and"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
let src = src.load_scalar(fx);
atomic_binop_return_old! (fx, band<T>(ptr, src) -> ret);
};
_ if intrinsic.starts_with("atomic_nand"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, T);
_ if intrinsic.starts_with("atomic_and"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
crate::atomic_shim::lock_global_lock(fx);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::And, ptr, src);
let clif_ty = fx.clif_type(T).unwrap();
let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0);
let and = fx.bcx.ins().band(old, src);
let new = fx.bcx.ins().bnot(and);
fx.bcx.ins().store(MemFlags::new(), new, ptr, 0);
ret.write_cvalue(fx, CValue::by_val(old, fx.layout_of(T)));
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_or"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
crate::atomic_shim::unlock_global_lock(fx);
};
_ if intrinsic.starts_with("atomic_or"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
let src = src.load_scalar(fx);
atomic_binop_return_old! (fx, bor<T>(ptr, src) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Or, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_xor"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
_ if intrinsic.starts_with("atomic_xor"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
atomic_binop_return_old! (fx, bxor<T>(ptr, src) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xor, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_max"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
// FIXME https://github.com/bytecodealliance/wasmtime/issues/2647
_ if intrinsic.starts_with("atomic_nand"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
atomic_minmax!(fx, IntCC::SignedGreaterThan, <T> (ptr, src) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Nand, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_umax"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
_ if intrinsic.starts_with("atomic_max"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
atomic_minmax!(fx, IntCC::UnsignedGreaterThan, <T> (ptr, src) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Smax, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_min"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
_ if intrinsic.starts_with("atomic_umax"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
atomic_minmax!(fx, IntCC::SignedLessThan, <T> (ptr, src) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Umax, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_umin"), <T> (v ptr, c src) {
validate_atomic_type!(fx, intrinsic, span, ret.layout().ty);
_ if intrinsic.starts_with("atomic_min"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
atomic_minmax!(fx, IntCC::UnsignedLessThan, <T> (ptr, src) -> ret);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Smin, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
_ if intrinsic.starts_with("atomic_umin"), (v ptr, c src) {
let layout = src.layout();
validate_atomic_type!(fx, intrinsic, span, layout.ty);
let ty = fx.clif_type(layout.ty).unwrap();
let src = src.load_scalar(fx);
let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Umin, ptr, src);
let old = CValue::by_val(old, layout);
ret.write_cvalue(fx, old);
};
minnumf32, (v a, v b) {

View File

@ -4,7 +4,7 @@ use super::*;
use crate::prelude::*;
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
instance: Instance<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,

View File

@ -5,15 +5,13 @@
associated_type_bounds,
never_type,
try_blocks,
hash_drain_filter,
str_split_once
box_patterns,
hash_drain_filter
)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]
#[cfg(feature = "jit")]
extern crate libc;
extern crate snap;
#[macro_use]
extern crate rustc_middle;
@ -54,7 +52,6 @@ mod abi;
mod allocator;
mod analyze;
mod archive;
mod atomic_shim;
mod backend;
mod base;
mod cast;
@ -130,9 +127,9 @@ impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
}
}
struct CodegenCx<'tcx, M: Module> {
struct CodegenCx<'m, 'tcx: 'm> {
tcx: TyCtxt<'tcx>,
module: M,
module: &'m mut dyn Module,
global_asm: String,
constants_cx: ConstantCx,
cached_context: Context,
@ -141,14 +138,20 @@ struct CodegenCx<'tcx, M: Module> {
unwind_context: UnwindContext<'tcx>,
}
impl<'tcx, M: Module> CodegenCx<'tcx, M> {
fn new(tcx: TyCtxt<'tcx>, module: M, debug_info: bool, pic_eh_frame: bool) -> Self {
let unwind_context = UnwindContext::new(tcx, module.isa(), pic_eh_frame);
let debug_context = if debug_info {
Some(DebugContext::new(tcx, module.isa()))
} else {
None
};
impl<'m, 'tcx> CodegenCx<'m, 'tcx> {
fn new(
tcx: TyCtxt<'tcx>,
backend_config: BackendConfig,
module: &'m mut dyn Module,
debug_info: bool,
) -> Self {
let unwind_context = UnwindContext::new(
tcx,
module.isa(),
matches!(backend_config.codegen_mode, CodegenMode::Aot),
);
let debug_context =
if debug_info { Some(DebugContext::new(tcx, module.isa())) } else { None };
CodegenCx {
tcx,
module,
@ -161,14 +164,9 @@ impl<'tcx, M: Module> CodegenCx<'tcx, M> {
}
}
fn finalize(mut self) -> (M, String, Option<DebugContext<'tcx>>, UnwindContext<'tcx>) {
self.constants_cx.finalize(self.tcx, &mut self.module);
(
self.module,
self.global_asm,
self.debug_context,
self.unwind_context,
)
fn finalize(self) -> (String, Option<DebugContext<'tcx>>, UnwindContext<'tcx>) {
self.constants_cx.finalize(self.tcx, self.module);
(self.global_asm, self.debug_context, self.unwind_context)
}
}
@ -303,14 +301,7 @@ fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
flags_builder.enable("is_pic").unwrap();
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
flags_builder
.set(
"enable_verifier",
if cfg!(debug_assertions) {
"true"
} else {
"false"
},
)
.set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" })
.unwrap();
let tls_model = match target_triple.binary_format {
@ -339,11 +330,7 @@ fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
let flags = settings::Flags::new(flags_builder);
let variant = if cfg!(feature = "oldbe") {
cranelift_codegen::isa::BackendVariant::Legacy
} else {
cranelift_codegen::isa::BackendVariant::MachInst
};
let variant = cranelift_codegen::isa::BackendVariant::MachInst;
let mut isa_builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
// Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt`
// is interpreted as `bsr`.

View File

@ -9,7 +9,6 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx: TyCtxt<'_>,
module: &mut impl Module,
unwind_context: &mut UnwindContext<'_>,
use_jit: bool,
) {
let (main_def_id, use_start_lang_item) = match tcx.entry_fn(LOCAL_CRATE) {
Some((def_id, entry_ty)) => (
@ -27,14 +26,7 @@ pub(crate) fn maybe_create_entry_wrapper(
return;
}
create_entry_fn(
tcx,
module,
unwind_context,
main_def_id,
use_start_lang_item,
use_jit,
);
create_entry_fn(tcx, module, unwind_context, main_def_id, use_start_lang_item);
fn create_entry_fn(
tcx: TyCtxt<'_>,
@ -42,7 +34,6 @@ pub(crate) fn maybe_create_entry_wrapper(
unwind_context: &mut UnwindContext<'_>,
rust_main_def_id: DefId,
use_start_lang_item: bool,
use_jit: bool,
) {
let main_ret_ty = tcx.fn_sig(rust_main_def_id).output();
// Given that `main()` has no arguments,
@ -57,23 +48,17 @@ pub(crate) fn maybe_create_entry_wrapper(
AbiParam::new(m.target_config().pointer_type()),
AbiParam::new(m.target_config().pointer_type()),
],
returns: vec![AbiParam::new(
m.target_config().pointer_type(), /*isize*/
)],
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
call_conv: CallConv::triple_default(m.isa().triple()),
};
let cmain_func_id = m
.declare_function("main", Linkage::Export, &cmain_sig)
.unwrap();
let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
let main_name = tcx.symbol_name(instance).name.to_string();
let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
let main_func_id = m
.declare_function(&main_name, Linkage::Import, &main_sig)
.unwrap();
let main_func_id = m.declare_function(&main_name, Linkage::Import, &main_sig).unwrap();
let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig);
@ -86,8 +71,6 @@ pub(crate) fn maybe_create_entry_wrapper(
let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type());
let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type());
crate::atomic_shim::init_global_lock(m, &mut bcx, use_jit);
let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func);
let call_inst = if use_start_lang_item {
@ -103,9 +86,7 @@ pub(crate) fn maybe_create_entry_wrapper(
.polymorphize(tcx);
let start_func_id = import_function(tcx, m, start_instance);
let main_val = bcx
.ins()
.func_addr(m.target_config().pointer_type(), main_func_ref);
let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref);
let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func);
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv])

View File

@ -94,9 +94,7 @@ pub(crate) fn write_metadata<P: WriteMetadata>(
assert!(kind == MetadataKind::Compressed);
let mut compressed = tcx.metadata_encoding_version();
FrameEncoder::new(&mut compressed)
.write_all(&metadata.raw_data)
.unwrap();
FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
product.add_rustc_section(
rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),

View File

@ -41,7 +41,7 @@ pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option<IntCC> {
}
fn codegen_compare_bin_op<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
signed: bool,
lhs: Value,
@ -54,7 +54,7 @@ fn codegen_compare_bin_op<'tcx>(
}
pub(crate) fn codegen_binop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
@ -93,17 +93,12 @@ pub(crate) fn codegen_binop<'tcx>(
ty::Uint(_) | ty::Int(_) => crate::num::codegen_int_binop(fx, bin_op, in_lhs, in_rhs),
ty::Float(_) => crate::num::codegen_float_binop(fx, bin_op, in_lhs, in_rhs),
ty::RawPtr(..) | ty::FnPtr(..) => crate::num::codegen_ptr_binop(fx, bin_op, in_lhs, in_rhs),
_ => unreachable!(
"{:?}({:?}, {:?})",
bin_op,
in_lhs.layout().ty,
in_rhs.layout().ty
),
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty),
}
}
pub(crate) fn codegen_bool_binop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
@ -124,7 +119,7 @@ pub(crate) fn codegen_bool_binop<'tcx>(
}
pub(crate) fn codegen_int_binop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
@ -185,19 +180,14 @@ pub(crate) fn codegen_int_binop<'tcx>(
}
}
// Compare binops handles by `codegen_binop`.
_ => unreachable!(
"{:?}({:?}, {:?})",
bin_op,
in_lhs.layout().ty,
in_rhs.layout().ty
),
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty),
};
CValue::by_val(val, in_lhs.layout())
}
pub(crate) fn codegen_checked_int_binop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
@ -268,9 +258,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
let rhs = fx.bcx.ins().sextend(ty.double_width().unwrap(), rhs);
let val = fx.bcx.ins().imul(lhs, rhs);
let has_underflow =
fx.bcx
.ins()
.icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1)));
fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1)));
let has_overflow = fx.bcx.ins().icmp_imm(
IntCC::SignedGreaterThan,
val,
@ -309,10 +297,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
let val = fx.bcx.ins().ishl(lhs, actual_shift);
let ty = fx.bcx.func.dfg.value_type(val);
let max_shift = i64::from(ty.bits()) - 1;
let has_overflow = fx
.bcx
.ins()
.icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
(val, has_overflow)
}
BinOp::Shr => {
@ -326,38 +311,20 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
};
let ty = fx.bcx.func.dfg.value_type(val);
let max_shift = i64::from(ty.bits()) - 1;
let has_overflow = fx
.bcx
.ins()
.icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
(val, has_overflow)
}
_ => bug!(
"binop {:?} on checked int/uint lhs: {:?} rhs: {:?}",
bin_op,
in_lhs,
in_rhs
),
_ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs),
};
let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow);
// FIXME directly write to result place instead
let out_place = CPlace::new_stack_slot(
fx,
fx.layout_of(
fx.tcx
.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()),
),
);
let out_layout = out_place.layout();
out_place.write_cvalue(fx, CValue::by_val_pair(res, has_overflow, out_layout));
out_place.to_cvalue(fx)
let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()));
CValue::by_val_pair(res, has_overflow, out_layout)
}
pub(crate) fn codegen_float_binop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
@ -402,7 +369,7 @@ pub(crate) fn codegen_float_binop<'tcx>(
}
pub(crate) fn codegen_ptr_binop<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
@ -452,9 +419,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr);
let ptr_cmp =
fx.bcx
.ins()
.icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
let extra_cmp = fx.bcx.ins().icmp(
bin_op_to_intcc(bin_op, false).unwrap(),
lhs_extra,
@ -466,9 +431,6 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
_ => panic!("bin_op {:?} on ptr", bin_op),
};
CValue::by_val(
fx.bcx.ins().bint(types::I8, res),
fx.layout_of(fx.tcx.types.bool),
)
CValue::by_val(fx.bcx.ins().bint(types::I8, res), fx.layout_of(fx.tcx.types.bool))
}
}

View File

@ -15,10 +15,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet<Block
// bytecodealliance/cranelift#1339 is implemented.
let mut block_insts = FxHashMap::default();
for block in cold_blocks
.keys()
.filter(|&block| cold_blocks.contains(block))
{
for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) {
let insts = ctx.func.layout.block_insts(block).collect::<Vec<_>>();
for &inst in &insts {
ctx.func.layout.remove_inst(inst);
@ -28,10 +25,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet<Block
}
// And then append them at the back again.
for block in cold_blocks
.keys()
.filter(|&block| cold_blocks.contains(block))
{
for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) {
ctx.func.layout.append_block(block);
for inst in block_insts.remove(&block).unwrap() {
ctx.func.layout.append_inst(inst, block);

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