mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Merge branch 'master' into dedup
This commit is contained in:
commit
96d6f22a8e
46
.github/ISSUE_TEMPLATE/diagnostics.md
vendored
Normal file
46
.github/ISSUE_TEMPLATE/diagnostics.md
vendored
Normal 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.
|
||||
-->
|
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -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
4
.gitignore
vendored
@ -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
2
.gitmodules
vendored
@ -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
|
||||
|
1
.mailmap
1
.mailmap
@ -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>
|
||||
|
@ -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
|
||||
|
409
Cargo.lock
409
Cargo.lock
@ -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"
|
||||
|
@ -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.
|
||||
|
||||
|
36
RELEASES.md
36
RELEASES.md
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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"] }
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
199
compiler/rustc_ast/src/ast_like.rs
Normal file
199
compiler/rustc_ast/src/ast_like.rs
Normal 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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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)]
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
@ -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, ¶m.attrs);
|
||||
hir::Param {
|
||||
attrs: self.lower_attrs(¶m.attrs),
|
||||
hir_id: self.lower_node_id(param.id),
|
||||
hir_id,
|
||||
pat: self.lower_pat(¶m.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(¶meter.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),
|
||||
}
|
||||
|
@ -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(¶m.ty, ImplTraitContext::Universal(ibty))
|
||||
this.lower_ty_direct(
|
||||
¶m.ty,
|
||||
ImplTraitContext::Universal(
|
||||
ibty,
|
||||
this.current_hir_id_owner.last().unwrap().0,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
this.lower_ty_direct(¶m.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, ¶m.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(¶m.attrs, sym::may_dangle),
|
||||
attrs: self.lower_attrs(¶m.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)))
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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).
|
||||
|
@ -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)
|
||||
|
@ -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(",");
|
||||
}
|
||||
|
@ -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
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
157
compiler/rustc_builtin_macros/src/cfg_eval.rs
Normal file
157
compiler/rustc_builtin_macros/src/cfg_eval.rs
Normal 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)
|
||||
}
|
||||
}
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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()?;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -91,7 +91,7 @@ pub fn inject(
|
||||
}
|
||||
|
||||
let decls = mk_decls(&mut krate, &mut cx, ¯os);
|
||||
krate.module.items.push(decls);
|
||||
krate.items.push(decls);
|
||||
|
||||
krate
|
||||
}
|
||||
|
@ -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>,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)]
|
||||
}
|
||||
|
25
compiler/rustc_codegen_cranelift/.cirrus.yml
Normal file
25
compiler/rustc_codegen_cranelift/.cirrus.yml
Normal 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
|
@ -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
|
||||
|
@ -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": [
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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]
|
||||
|
@ -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"
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Requires the CHANNEL env var to be set to `debug` or `release.`
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 system’s 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 library’s 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!
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash --verbose
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
rustup component add rust-src rustc-dev llvm-tools-preview
|
||||
|
@ -1 +1 @@
|
||||
nightly-2021-01-30
|
||||
nightly-2021-03-05
|
||||
|
4
compiler/rustc_codegen_cranelift/rustfmt.toml
Normal file
4
compiler/rustc_codegen_cranelift/rustfmt.toml
Normal file
@ -0,0 +1,4 @@
|
||||
# Matches rustfmt.toml of rustc
|
||||
version = "Two"
|
||||
use_small_heuristics = "Max"
|
||||
merge_derives = false
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
dir=$(dirname "$0")
|
||||
source "$dir/config.sh"
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
));
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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]),
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
|
@ -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(
|
||||
|
@ -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>],
|
||||
|
@ -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) {
|
||||
|
@ -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>,
|
||||
|
@ -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`.
|
||||
|
@ -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])
|
||||
|
@ -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),
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user