commit
e9d50f4c57
995 changed files with 8695 additions and 5362 deletions
2
.github/ISSUE_TEMPLATE/bootstrap.md
vendored
2
.github/ISSUE_TEMPLATE/bootstrap.md
vendored
|
@ -32,7 +32,7 @@ Describe what you expected to happen.
|
|||
Describe what actually happened.
|
||||
-->
|
||||
|
||||
### Bootstrap configuration (config.toml)
|
||||
### Bootstrap configuration (bootstrap.toml)
|
||||
```toml
|
||||
<config>
|
||||
```
|
||||
|
|
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
|
@ -68,6 +68,7 @@ jobs:
|
|||
timeout-minutes: 360
|
||||
env:
|
||||
CI_JOB_NAME: ${{ matrix.name }}
|
||||
CI_JOB_DOC_URL: ${{ matrix.doc_url }}
|
||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||
# commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
@ -190,8 +191,20 @@ jobs:
|
|||
CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=../../../build/citool cargo build
|
||||
|
||||
- name: run the build
|
||||
# Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
|
||||
run: src/ci/scripts/run-build-from-ci.sh 2>&1
|
||||
run: |
|
||||
set +e
|
||||
# Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
|
||||
src/ci/scripts/run-build-from-ci.sh 2>&1
|
||||
STATUS=$?
|
||||
set -e
|
||||
|
||||
if [[ "$STATUS" -ne 0 && -n "$CI_JOB_DOC_URL" ]]; then
|
||||
echo "****************************************************************************"
|
||||
echo "To find more information about this job, visit the following URL:"
|
||||
echo "$CI_JOB_DOC_URL"
|
||||
echo "****************************************************************************"
|
||||
fi
|
||||
exit ${STATUS}
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}
|
||||
|
|
7
.github/workflows/post-merge.yml
vendored
7
.github/workflows/post-merge.yml
vendored
|
@ -35,8 +35,13 @@ jobs:
|
|||
|
||||
cd src/ci/citool
|
||||
|
||||
echo "Post-merge analysis result" > output.log
|
||||
printf "*This is an experimental post-merge analysis report. You can ignore it.*\n\n" > output.log
|
||||
printf "<details>\n<summary>Post-merge report</summary>\n\n" >> output.log
|
||||
|
||||
cargo run --release post-merge-report ${PARENT_COMMIT} ${{ github.sha }} >> output.log
|
||||
|
||||
printf "</details>\n" >> output.log
|
||||
|
||||
cat output.log
|
||||
|
||||
gh pr comment ${HEAD_PR} -F output.log
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
|||
# This file should only ignore things that are generated during a `x.py` build,
|
||||
# generated by common IDEs, and optional files controlled by the user that
|
||||
# affect the build (such as config.toml).
|
||||
# affect the build (such as bootstrap.toml).
|
||||
# In particular, things like `mir_dump` should not be listed here; they are only
|
||||
# created during manual debugging and many people like to clean up instead of
|
||||
# having git ignore such leftovers. You can use `.git/info/exclude` to
|
||||
|
@ -34,6 +34,7 @@ Session.vim
|
|||
!/tests/run-make/thumb-none-qemu/example/.cargo
|
||||
|
||||
## Configuration
|
||||
/bootstrap.toml
|
||||
/config.toml
|
||||
/Makefile
|
||||
config.mk
|
||||
|
|
3
.ignore
3
.ignore
|
@ -1,2 +1,3 @@
|
|||
# Make vscode *not* count `config.toml` as ignored, so it is included in search
|
||||
# Make vscode *not* count `bootstrap.toml` and `config.toml` as ignored, so it is included in search
|
||||
!/bootstrap.toml
|
||||
!/config.toml
|
||||
|
|
134
Cargo.lock
134
Cargo.lock
|
@ -1548,16 +1548,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.27.0"
|
||||
version = "0.29.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4"
|
||||
checksum = "9b958f80f0fde8601dc6c08685adc743eecaa046181cebd5a57551468dfc2ddc"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mac",
|
||||
"markup5ever",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
"match_token",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2023,7 +2021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2084,6 +2082,13 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
||||
|
||||
[[package]]
|
||||
name = "literal-escaper"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-std 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lld-wrapper"
|
||||
version = "0.1.0"
|
||||
|
@ -2134,9 +2139,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
|||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.12.1"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45"
|
||||
checksum = "03a7b81dfb91586d0677086d40a6d755070e0799b71bb897485bac408dfd5c69"
|
||||
dependencies = [
|
||||
"log",
|
||||
"phf",
|
||||
|
@ -2146,6 +2151,17 @@ dependencies = [
|
|||
"tendril",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "match_token"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
|
@ -2179,6 +2195,20 @@ dependencies = [
|
|||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "measureme"
|
||||
version = "12.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "570a507d8948a66a97f42cbbaf8a6bb9516a51017d4ee949502ad7a10a864395"
|
||||
dependencies = [
|
||||
"log",
|
||||
"memmap2",
|
||||
"parking_lot",
|
||||
"perf-event-open-sys",
|
||||
"rustc-hash 1.1.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
|
@ -2262,7 +2292,7 @@ dependencies = [
|
|||
"libc",
|
||||
"libffi",
|
||||
"libloading",
|
||||
"measureme",
|
||||
"measureme 11.0.1",
|
||||
"rand 0.9.0",
|
||||
"regex",
|
||||
"rustc_version",
|
||||
|
@ -2628,7 +2658,7 @@ version = "0.11.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.3",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2637,18 +2667,8 @@ version = "0.11.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.3",
|
||||
"phf_shared 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||
dependencies = [
|
||||
"phf_shared 0.10.0",
|
||||
"rand 0.8.5",
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2657,26 +2677,17 @@ version = "0.11.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.3",
|
||||
"phf_shared",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
|
||||
dependencies = [
|
||||
"siphasher 0.3.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||
dependencies = [
|
||||
"siphasher 1.0.1",
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3045,13 +3056,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "run_make_support"
|
||||
version = "0.2.0"
|
||||
|
@ -3151,6 +3155,12 @@ version = "1.0.1"
|
|||
name = "rustc-std-workspace-std"
|
||||
version = "1.0.1"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-std"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aba676a20abe46e5b0f1b0deae474aaaf31407e6c71147159890574599da04ef"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_abi"
|
||||
version = "0.0.0"
|
||||
|
@ -3189,6 +3199,7 @@ name = "rustc_ast"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"literal-escaper",
|
||||
"memchr",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
|
@ -3378,7 +3389,7 @@ dependencies = [
|
|||
"gimli 0.30.0",
|
||||
"itertools",
|
||||
"libc",
|
||||
"measureme",
|
||||
"measureme 12.0.1",
|
||||
"object 0.36.7",
|
||||
"rustc-demangle",
|
||||
"rustc_abi",
|
||||
|
@ -3447,7 +3458,6 @@ dependencies = [
|
|||
"rustc_symbol_mangling",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
"tempfile",
|
||||
|
@ -3480,7 +3490,6 @@ dependencies = [
|
|||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -3497,7 +3506,7 @@ dependencies = [
|
|||
"indexmap",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"measureme",
|
||||
"measureme 12.0.1",
|
||||
"memmap2",
|
||||
"parking_lot",
|
||||
"portable-atomic",
|
||||
|
@ -3743,7 +3752,6 @@ dependencies = [
|
|||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -3782,7 +3790,6 @@ dependencies = [
|
|||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -3902,6 +3909,7 @@ name = "rustc_lexer"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"expect-test",
|
||||
"literal-escaper",
|
||||
"memchr",
|
||||
"unicode-properties",
|
||||
"unicode-xid",
|
||||
|
@ -3929,7 +3937,6 @@ dependencies = [
|
|||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
"unicode-security",
|
||||
|
@ -4005,7 +4012,6 @@ dependencies = [
|
|||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_type_ir",
|
||||
"tempfile",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -4121,7 +4127,6 @@ dependencies = [
|
|||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -4167,6 +4172,7 @@ name = "rustc_parse"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"literal-escaper",
|
||||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
"rustc_data_structures",
|
||||
|
@ -4189,6 +4195,7 @@ dependencies = [
|
|||
name = "rustc_parse_format"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"literal-escaper",
|
||||
"rustc_index",
|
||||
"rustc_lexer",
|
||||
]
|
||||
|
@ -4264,8 +4271,7 @@ dependencies = [
|
|||
name = "rustc_query_impl"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"measureme",
|
||||
"rustc_attr_data_structures",
|
||||
"measureme 12.0.1",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_hashes",
|
||||
|
@ -4545,7 +4551,6 @@ dependencies = [
|
|||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -4876,12 +4881,6 @@ version = "2.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
|
@ -4996,26 +4995,25 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.7"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
|
||||
checksum = "938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe"
|
||||
dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"phf_shared 0.10.0",
|
||||
"phf_shared",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_codegen"
|
||||
version = "0.5.2"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
|
||||
checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
|
||||
dependencies = [
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
@ -6445,6 +6443,10 @@ version = "0.5.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "x"
|
||||
version = "0.1.1"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.4.0"
|
||||
|
|
67
Cargo.toml
67
Cargo.toml
|
@ -1,51 +1,53 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
# tidy-alphabetical-start
|
||||
"compiler/rustc",
|
||||
"src/build_helper",
|
||||
"src/etc/test-float-parse",
|
||||
"src/rustc-std-workspace/rustc-std-workspace-core",
|
||||
"src/rustc-std-workspace/rustc-std-workspace-alloc",
|
||||
"src/rustc-std-workspace/rustc-std-workspace-core",
|
||||
"src/rustc-std-workspace/rustc-std-workspace-std",
|
||||
"src/rustdoc-json-types",
|
||||
"src/tools/build-manifest",
|
||||
"src/tools/bump-stage0",
|
||||
"src/tools/cargotest",
|
||||
"src/tools/clippy",
|
||||
"src/tools/clippy/clippy_dev",
|
||||
"src/tools/collect-license-metadata",
|
||||
"src/tools/compiletest",
|
||||
"src/tools/run-make-support",
|
||||
"src/tools/linkchecker",
|
||||
"src/tools/lint-docs",
|
||||
"src/tools/miropt-test-tools",
|
||||
"src/tools/unstable-book-gen",
|
||||
"src/tools/tidy",
|
||||
"src/tools/tier-check",
|
||||
"src/tools/build-manifest",
|
||||
"src/tools/remote-test-client",
|
||||
"src/tools/remote-test-server",
|
||||
"src/tools/rust-installer",
|
||||
"src/tools/rustdoc",
|
||||
"src/tools/rls",
|
||||
"src/tools/rustfmt",
|
||||
"src/tools/miri",
|
||||
"src/tools/miri/cargo-miri",
|
||||
"src/tools/rustdoc-themes",
|
||||
"src/tools/unicode-table-generator",
|
||||
"src/tools/coverage-dump",
|
||||
"src/tools/features-status-dump",
|
||||
"src/tools/generate-copyright",
|
||||
"src/tools/generate-windows-sys",
|
||||
"src/tools/html-checker",
|
||||
"src/tools/jsondocck",
|
||||
"src/tools/jsondoclint",
|
||||
"src/tools/llvm-bitcode-linker",
|
||||
"src/tools/html-checker",
|
||||
"src/tools/bump-stage0",
|
||||
"src/tools/replace-version-placeholder",
|
||||
"src/tools/linkchecker",
|
||||
"src/tools/lint-docs",
|
||||
"src/tools/lld-wrapper",
|
||||
"src/tools/collect-license-metadata",
|
||||
"src/tools/generate-copyright",
|
||||
"src/tools/suggest-tests",
|
||||
"src/tools/generate-windows-sys",
|
||||
"src/tools/rustdoc-gui-test",
|
||||
"src/tools/llvm-bitcode-linker",
|
||||
"src/tools/miri",
|
||||
"src/tools/miri/cargo-miri",
|
||||
"src/tools/miropt-test-tools",
|
||||
"src/tools/opt-dist",
|
||||
"src/tools/coverage-dump",
|
||||
"src/tools/remote-test-client",
|
||||
"src/tools/remote-test-server",
|
||||
"src/tools/replace-version-placeholder",
|
||||
"src/tools/run-make-support",
|
||||
"src/tools/rust-installer",
|
||||
"src/tools/rustdoc",
|
||||
"src/tools/rustdoc-gui-test",
|
||||
"src/tools/rustdoc-themes",
|
||||
"src/tools/rustfmt",
|
||||
"src/tools/suggest-tests",
|
||||
"src/tools/tidy",
|
||||
"src/tools/tier-check",
|
||||
"src/tools/unicode-table-generator",
|
||||
"src/tools/unstable-book-gen",
|
||||
"src/tools/wasm-component-ld",
|
||||
"src/tools/features-status-dump",
|
||||
"src/tools/x",
|
||||
# tidy-alphabetical-end
|
||||
]
|
||||
|
||||
exclude = [
|
||||
|
@ -56,11 +58,6 @@ exclude = [
|
|||
"tests/rustdoc-gui",
|
||||
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
|
||||
"obj",
|
||||
# The `x` binary is a thin wrapper that calls `x.py`, which initializes
|
||||
# submodules, before which workspace members cannot be invoked because
|
||||
# not all `Cargo.toml` files are available, so we exclude the `x` binary,
|
||||
# so it can be invoked before the current checkout is set up.
|
||||
"src/tools/x",
|
||||
]
|
||||
|
||||
[profile.release.package.rustc-rayon-core]
|
||||
|
|
10
INSTALL.md
10
INSTALL.md
|
@ -6,9 +6,9 @@ If you just want to install Rust, check out the [README.md](README.md) instead.*
|
|||
|
||||
The Rust build system uses a Python script called `x.py` to build the compiler,
|
||||
which manages the bootstrapping process. It lives at the root of the project.
|
||||
It also uses a file named `config.toml` to determine various configuration
|
||||
It also uses a file named `bootstrap.toml` to determine various configuration
|
||||
settings for the build. You can see a full list of options in
|
||||
`config.example.toml`.
|
||||
`bootstrap.example.toml`.
|
||||
|
||||
The `x.py` command can be run directly on most Unix systems in the following
|
||||
format:
|
||||
|
@ -115,7 +115,7 @@ See [the rustc-dev-guide for more info][sysllvm].
|
|||
|
||||
This project provides a configure script and makefile (the latter of which just
|
||||
invokes `x.py`). `./configure` is the recommended way to programmatically
|
||||
generate a `config.toml`. `make` is not recommended (we suggest using `x.py`
|
||||
generate a `bootstrap.toml`. `make` is not recommended (we suggest using `x.py`
|
||||
directly), but it is supported and we try not to break it unnecessarily.
|
||||
|
||||
```sh
|
||||
|
@ -123,7 +123,7 @@ directly), but it is supported and we try not to break it unnecessarily.
|
|||
make && sudo make install
|
||||
```
|
||||
|
||||
`configure` generates a `config.toml` which can also be used with normal `x.py`
|
||||
`configure` generates a `bootstrap.toml` which can also be used with normal `x.py`
|
||||
invocations.
|
||||
|
||||
## Building on Windows
|
||||
|
@ -255,7 +255,7 @@ Windows build triples are:
|
|||
- `x86_64-pc-windows-msvc`
|
||||
|
||||
The build triple can be specified by either specifying `--build=<triple>` when
|
||||
invoking `x.py` commands, or by creating a `config.toml` file (as described in
|
||||
invoking `x.py` commands, or by creating a `bootstrap.toml` file (as described in
|
||||
[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing
|
||||
`--set build.build=<triple>` to `./configure`.
|
||||
|
||||
|
|
|
@ -67,11 +67,11 @@ See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and
|
|||
trademarks and logos (the "Rust Trademarks").
|
||||
|
||||
If you want to use these names or brands, please read the
|
||||
[media guide][media-guide].
|
||||
[Rust language trademark policy][trademark-policy].
|
||||
|
||||
Third-party logos may be subject to third-party copyrights and trademarks. See
|
||||
[Licenses][policies-licenses] for details.
|
||||
|
||||
[rust-foundation]: https://foundation.rust-lang.org/
|
||||
[media-guide]: https://foundation.rust-lang.org/policies/logo-policy-and-media-guide/
|
||||
[rust-foundation]: https://rustfoundation.org/
|
||||
[trademark-policy]: https://rustfoundation.org/policy/rust-trademark-policy/
|
||||
[policies-licenses]: https://www.rust-lang.org/policies/licenses
|
||||
|
|
|
@ -2282,7 +2282,7 @@ Compatibility Notes
|
|||
- [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/)
|
||||
- [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/)
|
||||
- [The Rust distribution no longer always includes rustdoc](https://github.com/rust-lang/rust/pull/106886)
|
||||
If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By
|
||||
If `tools = [...]` is set in bootstrap.toml, we will respect a missing rustdoc in that list. By
|
||||
default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the
|
||||
list.
|
||||
|
||||
|
@ -5268,7 +5268,7 @@ related tools.
|
|||
|
||||
- [Building `rustc` from source now uses `ninja` by default over `make`.][74922]
|
||||
You can continue building with `make` by setting `ninja=false` in
|
||||
your `config.toml`.
|
||||
your `bootstrap.toml`.
|
||||
- [cg_llvm: `fewer_names` in `uncached_llvm_type`][76030]
|
||||
- [Made `ensure_sufficient_stack()` non-generic][76680]
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ path = [
|
|||
"Cargo.lock",
|
||||
"Cargo.toml",
|
||||
"CODE_OF_CONDUCT.md",
|
||||
"config.example.toml",
|
||||
"bootstrap.example.toml",
|
||||
"configure",
|
||||
"CONTRIBUTING.md",
|
||||
"COPYRIGHT",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# All options are commented out by default in this file, and they're commented
|
||||
# out with their default values. The build system by default looks for
|
||||
# `config.toml` in the current directory of a build for build configuration, but
|
||||
# `bootstrap.toml` in the current directory of a build for build configuration, but
|
||||
# a custom configuration file can also be specified with `--config` to the build
|
||||
# system.
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
# Use different pre-set defaults than the global defaults.
|
||||
#
|
||||
# See `src/bootstrap/defaults` for more information.
|
||||
# Note that this has no default value (x.py uses the defaults in `config.example.toml`).
|
||||
# Note that this has no default value (x.py uses the defaults in `bootstrap.example.toml`).
|
||||
#profile = <none>
|
||||
|
||||
# Keeps track of major changes made to this configuration.
|
||||
|
@ -346,7 +346,7 @@
|
|||
# Enable a build of the extended Rust tool set which is not only the compiler
|
||||
# but also tools such as Cargo. This will also produce "combined installers"
|
||||
# which are used to install Rust and Cargo together.
|
||||
# The `tools` (check `config.example.toml` to see its default value) option specifies
|
||||
# The `tools` (check `bootstrap.example.toml` to see its default value) option specifies
|
||||
# which tools should be built if `extended = true`.
|
||||
#
|
||||
# This is disabled by default.
|
||||
|
@ -446,6 +446,10 @@
|
|||
# a specific version.
|
||||
#ccache = false
|
||||
|
||||
# List of paths to exclude from the build and test processes.
|
||||
# For example, exclude = ["tests/ui", "src/tools/tidy"].
|
||||
#exclude = []
|
||||
|
||||
# =============================================================================
|
||||
# General install configuration options
|
||||
# =============================================================================
|
|
@ -52,7 +52,7 @@ use rustc_data_structures::stable_hasher::StableOrd;
|
|||
use rustc_hashes::Hash64;
|
||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_Generic, Encodable_Generic, HashStable_Generic};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_Generic};
|
||||
|
||||
mod callconv;
|
||||
mod layout;
|
||||
|
@ -74,7 +74,10 @@ pub use layout::{LayoutCalculator, LayoutCalculatorError};
|
|||
pub trait HashStableContext {}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
|
||||
)]
|
||||
pub struct ReprFlags(u8);
|
||||
|
||||
bitflags! {
|
||||
|
@ -106,7 +109,10 @@ impl std::fmt::Debug for ReprFlags {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
|
||||
)]
|
||||
pub enum IntegerType {
|
||||
/// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g.
|
||||
/// `Pointer(true)` means `isize`.
|
||||
|
@ -127,7 +133,10 @@ impl IntegerType {
|
|||
|
||||
/// Represents the repr options provided by the user.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
|
||||
)]
|
||||
pub struct ReprOptions {
|
||||
pub int: Option<IntegerType>,
|
||||
pub align: Option<Align>,
|
||||
|
@ -487,7 +496,10 @@ impl FromStr for Endian {
|
|||
|
||||
/// Size of a type in bytes.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
|
||||
)]
|
||||
pub struct Size {
|
||||
raw: u64,
|
||||
}
|
||||
|
@ -713,7 +725,10 @@ impl Step for Size {
|
|||
|
||||
/// Alignment of a type in bytes (always a power of two).
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
|
||||
)]
|
||||
pub struct Align {
|
||||
pow2: u8,
|
||||
}
|
||||
|
@ -802,7 +817,7 @@ impl Align {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bytes(self) -> u64 {
|
||||
pub const fn bytes(self) -> u64 {
|
||||
1 << self.pow2
|
||||
}
|
||||
|
||||
|
@ -812,7 +827,7 @@ impl Align {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bits(self) -> u64 {
|
||||
pub const fn bits(self) -> u64 {
|
||||
self.bytes() * 8
|
||||
}
|
||||
|
||||
|
@ -872,7 +887,10 @@ impl AbiAndPrefAlign {
|
|||
|
||||
/// Integers, also used for enum discriminants.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable_Generic, Decodable_Generic, HashStable_Generic))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
|
||||
)]
|
||||
pub enum Integer {
|
||||
I8,
|
||||
I16,
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2024"
|
|||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
bitflags = "2.4.1"
|
||||
literal-escaper = { path = "../../library/literal-escaper" }
|
||||
memchr = "2.7.4"
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{ascii, fmt, str};
|
||||
|
||||
use rustc_lexer::unescape::{
|
||||
use literal_escaper::{
|
||||
MixedUnit, Mode, byte_from_char, unescape_byte, unescape_char, unescape_mixed, unescape_unicode,
|
||||
};
|
||||
use rustc_span::{Span, Symbol, kw, sym};
|
||||
|
|
|
@ -12,14 +12,17 @@
|
|||
// tidy-alphabetical-end
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_NoContext};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
|
||||
pub mod visit;
|
||||
|
||||
/// The movability of a coroutine / closure literal:
|
||||
/// whether a coroutine contains self-references, causing it to be `!Unpin`.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
pub enum Movability {
|
||||
/// May contain self-references, `!Unpin`.
|
||||
Static,
|
||||
|
@ -28,7 +31,10 @@ pub enum Movability {
|
|||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
pub enum Mutability {
|
||||
// N.B. Order is deliberate, so that Not < Mut
|
||||
Not,
|
||||
|
@ -87,7 +93,10 @@ impl Mutability {
|
|||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
pub enum Pinnedness {
|
||||
Not,
|
||||
Pinned,
|
||||
|
|
|
@ -185,8 +185,6 @@ ast_lowering_underscore_expr_lhs_assign =
|
|||
ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
|
||||
ast_lowering_unstable_inline_assembly_label_operand_with_outputs =
|
||||
using both label and output operands for inline assembly is unstable
|
||||
ast_lowering_unstable_inline_assembly_label_operands =
|
||||
label operands for inline assembly are unstable
|
||||
ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
|
||||
|
||||
ast_lowering_use_angle_brackets = use angle brackets instead
|
||||
|
|
|
@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
// Inline assembly is currently only stable for these architectures.
|
||||
// (See also compiletest's `has_asm_support`.)
|
||||
let is_stable = matches!(
|
||||
asm_arch,
|
||||
asm::InlineAsmArch::X86
|
||||
|
@ -469,22 +470,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
// Feature gate checking for asm goto.
|
||||
// Feature gate checking for `asm_goto_with_outputs`.
|
||||
if let Some((_, op_sp)) =
|
||||
operands.iter().find(|(op, _)| matches!(op, hir::InlineAsmOperand::Label { .. }))
|
||||
{
|
||||
if !self.tcx.features().asm_goto() {
|
||||
feature_err(
|
||||
sess,
|
||||
sym::asm_goto,
|
||||
*op_sp,
|
||||
fluent::ast_lowering_unstable_inline_assembly_label_operands,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
// In addition, check if an output operand is used.
|
||||
// This is gated behind an additional feature.
|
||||
// Check if an output operand is used.
|
||||
let output_operand_used = operands.iter().any(|(op, _)| {
|
||||
matches!(
|
||||
op,
|
||||
|
|
|
@ -190,14 +190,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
) -> hir::FnSig<'hir> {
|
||||
let header = if let Some(local_sig_id) = sig_id.as_local() {
|
||||
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
|
||||
Some(sig) => self.lower_fn_header(
|
||||
sig.header,
|
||||
Some(sig) => {
|
||||
let parent = self.tcx.parent(sig_id);
|
||||
// HACK: we override the default safety instead of generating attributes from the ether.
|
||||
// We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
|
||||
// and here we need the hir attributes.
|
||||
if sig.target_feature { hir::Safety::Unsafe } else { hir::Safety::Safe },
|
||||
&[],
|
||||
),
|
||||
let default_safety =
|
||||
if sig.target_feature || self.tcx.def_kind(parent) == DefKind::ForeignMod {
|
||||
hir::Safety::Unsafe
|
||||
} else {
|
||||
hir::Safety::Safe
|
||||
};
|
||||
self.lower_fn_header(sig.header, default_safety, &[])
|
||||
}
|
||||
None => self.generate_header_error(),
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1720,7 +1720,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
|
||||
let bounds = self.lower_param_bounds(bounds, itctx);
|
||||
|
||||
let ident = self.lower_ident(ident);
|
||||
let param_span = ident.span;
|
||||
|
||||
// Reconstruct the span of the entire predicate from the individual generic bounds.
|
||||
|
@ -1739,6 +1738,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let def_id = self.local_def_id(id).to_def_id();
|
||||
let hir_id = self.next_id();
|
||||
let res = Res::Def(DefKind::TyParam, def_id);
|
||||
let ident = self.lower_ident(ident);
|
||||
let ty_path = self.arena.alloc(hir::Path {
|
||||
span: param_span,
|
||||
res,
|
||||
|
@ -1757,7 +1757,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
})
|
||||
}
|
||||
GenericParamKind::Lifetime => {
|
||||
let ident = self.lower_ident(ident);
|
||||
let lt_id = self.next_node_id();
|
||||
let lifetime = self.new_named_lifetime(id, lt_id, ident);
|
||||
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
|
||||
|
|
|
@ -1516,7 +1516,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
|
||||
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
|
||||
PatKind::Ident(_, ident, _) => self.lower_ident(ident),
|
||||
_ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
|
||||
PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
|
||||
_ => {
|
||||
self.dcx().span_delayed_bug(
|
||||
param.pat.span,
|
||||
"non-ident/wild param pat must trigger an error",
|
||||
);
|
||||
Ident::new(kw::Empty, self.lower_span(param.pat.span))
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -1762,38 +1769,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
|
||||
fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
|
||||
let ident = self.lower_ident(l.ident);
|
||||
self.new_named_lifetime(l.id, l.id, ident)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn new_named_lifetime_with_res(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
ident: Ident,
|
||||
res: LifetimeRes,
|
||||
) -> &'hir hir::Lifetime {
|
||||
let res = match res {
|
||||
LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param),
|
||||
LifetimeRes::Fresh { param, .. } => {
|
||||
let param = self.local_def_id(param);
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Infer => hir::LifetimeName::Infer,
|
||||
LifetimeRes::Static { .. } => hir::LifetimeName::Static,
|
||||
LifetimeRes::Error => hir::LifetimeName::Error,
|
||||
res => panic!(
|
||||
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
|
||||
res, ident, ident.span
|
||||
),
|
||||
};
|
||||
|
||||
debug!(?res);
|
||||
self.arena.alloc(hir::Lifetime {
|
||||
hir_id: self.lower_node_id(id),
|
||||
ident: self.lower_ident(ident),
|
||||
res,
|
||||
})
|
||||
self.new_named_lifetime(l.id, l.id, l.ident)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
|
@ -1804,7 +1780,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
ident: Ident,
|
||||
) -> &'hir hir::Lifetime {
|
||||
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
|
||||
self.new_named_lifetime_with_res(new_id, ident, res)
|
||||
let res = match res {
|
||||
LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param),
|
||||
LifetimeRes::Fresh { param, .. } => {
|
||||
let param = self.local_def_id(param);
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Infer => hir::LifetimeName::Infer,
|
||||
LifetimeRes::Static { .. } => hir::LifetimeName::Static,
|
||||
LifetimeRes::Error => hir::LifetimeName::Error,
|
||||
LifetimeRes::ElidedAnchor { .. } => {
|
||||
panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
|
||||
}
|
||||
};
|
||||
|
||||
debug!(?res);
|
||||
self.arena.alloc(hir::Lifetime {
|
||||
hir_id: self.lower_node_id(new_id),
|
||||
ident: self.lower_ident(ident),
|
||||
res,
|
||||
})
|
||||
}
|
||||
|
||||
fn lower_generic_params_mut(
|
||||
|
|
|
@ -1632,8 +1632,8 @@ fn get_mut_span_in_struct_field<'tcx>(
|
|||
/// If possible, suggest replacing `ref` with `ref mut`.
|
||||
fn suggest_ref_mut(tcx: TyCtxt<'_>, span: Span) -> Option<Span> {
|
||||
let pattern_str = tcx.sess.source_map().span_to_snippet(span).ok()?;
|
||||
if pattern_str.starts_with("ref")
|
||||
&& pattern_str["ref".len()..].starts_with(rustc_lexer::is_whitespace)
|
||||
if let Some(rest) = pattern_str.strip_prefix("ref")
|
||||
&& rest.starts_with(rustc_lexer::is_whitespace)
|
||||
{
|
||||
let span = span.with_lo(span.lo() + BytePos(4)).shrink_to_lo();
|
||||
Some(span)
|
||||
|
|
|
@ -14,9 +14,8 @@ use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint};
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor,
|
||||
self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, fold_regions,
|
||||
};
|
||||
use rustc_span::{Ident, Span, kw};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
|
|
|
@ -35,8 +35,7 @@ use rustc_infer::infer::{
|
|||
};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
|
||||
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode, fold_regions};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_mir_dataflow::impls::{
|
||||
EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
|
||||
|
@ -2480,19 +2479,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
|||
let body = self.body;
|
||||
for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) {
|
||||
let local_decl = &body.local_decls[local];
|
||||
let lint_root = match &body.source_scopes[local_decl.source_info.scope].local_data {
|
||||
ClearCrossCrate::Set(data) => data.lint_root,
|
||||
_ => continue,
|
||||
let ClearCrossCrate::Set(SourceScopeLocalData { lint_root, .. }) =
|
||||
body.source_scopes[local_decl.source_info.scope].local_data
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Skip over locals that begin with an underscore or have no name
|
||||
match self.local_names[local] {
|
||||
Some(name) => {
|
||||
if name.as_str().starts_with('_') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
None => continue,
|
||||
if self.local_names[local].is_none_or(|name| name.as_str().starts_with('_')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let span = local_decl.source_info.span;
|
||||
|
|
|
@ -18,8 +18,7 @@ use rustc_middle::mir::{
|
|||
ReturnConstraint, TerminatorKind,
|
||||
};
|
||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex};
|
||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, fold_regions};
|
||||
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
|
|
|
@ -5,11 +5,9 @@ use rustc_hir::def_id::LocalDefId;
|
|||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
|
||||
TypingMode,
|
||||
TypeVisitableExt, TypingMode, fold_regions,
|
||||
};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt;
|
||||
|
|
|
@ -2,8 +2,7 @@ use rustc_index::IndexSlice;
|
|||
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||
use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, fold_regions};
|
||||
use rustc_span::Symbol;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@ use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
|||
use rustc_infer::traits::query::type_op::DeeplyNormalize;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions,
|
||||
};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||
use tracing::{debug, instrument};
|
||||
|
|
|
@ -4,8 +4,7 @@ use rustc_middle::mir::visit::{TyContext, Visitor};
|
|||
use rustc_middle::mir::{Body, Local, Location, SourceInfo};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::relate::Relate;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_mir_dataflow::ResultsCursor;
|
||||
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
||||
use rustc_mir_dataflow::move_paths::MoveData;
|
||||
|
|
|
@ -24,12 +24,10 @@ use rustc_middle::mir::*;
|
|||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::cast::CastTy;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
|
||||
Dynamic, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserArgs,
|
||||
UserTypeAnnotationIndex,
|
||||
Dynamic, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt,
|
||||
TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_mir_dataflow::ResultsCursor;
|
||||
|
@ -1773,6 +1771,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
{
|
||||
span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
|
||||
}
|
||||
} else if let Const::Ty(_, ct) = constant.const_
|
||||
&& let ty::ConstKind::Param(p) = ct.kind()
|
||||
{
|
||||
let body_def_id = self.universal_regions.defining_ty.def_id();
|
||||
let const_param = tcx.generics_of(body_def_id).const_param(p, tcx);
|
||||
self.ascribe_user_type(
|
||||
constant.const_.ty(),
|
||||
ty::UserType::new(ty::UserTypeKind::TypeOf(
|
||||
const_param.def_id,
|
||||
UserArgs {
|
||||
args: self.universal_regions.defining_ty.args(),
|
||||
user_self_ty: None,
|
||||
},
|
||||
)),
|
||||
locations.span(self.body),
|
||||
);
|
||||
}
|
||||
|
||||
if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {
|
||||
|
|
|
@ -2,10 +2,9 @@ use std::iter;
|
|||
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgKind, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor, fold_regions,
|
||||
};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
|
|
|
@ -10,9 +10,8 @@ use rustc_middle::mir::ConstraintCategory;
|
|||
use rustc_middle::span_bug;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::ty::fold::FnMutDelegate;
|
||||
use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, FnMutDelegate, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
|
@ -27,11 +27,10 @@ use rustc_hir::lang_items::LangItem;
|
|||
use rustc_index::IndexVec;
|
||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, fold_regions};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty,
|
||||
TyCtxt, TypeVisitableExt,
|
||||
TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{ErrorGuaranteed, kw, sym};
|
||||
|
@ -184,6 +183,20 @@ impl<'tcx> DefiningTy<'tcx> {
|
|||
| DefiningTy::GlobalAsm(def_id) => def_id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the args of the `DefiningTy`. These are equivalent to the identity
|
||||
/// substs of the body, but replaced with region vids.
|
||||
pub(crate) fn args(&self) -> ty::GenericArgsRef<'tcx> {
|
||||
match *self {
|
||||
DefiningTy::Closure(_, args)
|
||||
| DefiningTy::Coroutine(_, args)
|
||||
| DefiningTy::CoroutineClosure(_, args)
|
||||
| DefiningTy::FnDef(_, args)
|
||||
| DefiningTy::Const(_, args)
|
||||
| DefiningTy::InlineConst(_, args) => args,
|
||||
DefiningTy::GlobalAsm(_) => ty::List::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From ad7ffe71baba46865f2e65266ab025920dfdc20b Mon Sep 17 00:00:00 2001
|
||||
From 5d7c709608b01301d4628d2159265936d4440b67 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
|
||||
|
@ -7,11 +7,10 @@ Cranelift doesn't support them yet
|
|||
---
|
||||
library/core/src/panic/unwind_safe.rs | 6 -----
|
||||
library/core/src/sync/atomic.rs | 38 ---------------------------
|
||||
library/core/tests/atomic.rs | 4 ---
|
||||
4 files changed, 4 insertions(+), 50 deletions(-)
|
||||
2 files changed, 44 deletions(-)
|
||||
|
||||
diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs
|
||||
index 092b7cf..158cf71 100644
|
||||
index a60f0799c0e..af056fbf41f 100644
|
||||
--- a/library/core/src/panic/unwind_safe.rs
|
||||
+++ b/library/core/src/panic/unwind_safe.rs
|
||||
@@ -216,9 +216,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicI32 {}
|
||||
|
@ -35,10 +34,10 @@ index 092b7cf..158cf71 100644
|
|||
#[cfg(target_has_atomic_load_store = "8")]
|
||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
|
||||
index d9de37e..8293fce 100644
|
||||
index bf2b6d59f88..d5ccce03bbf 100644
|
||||
--- a/library/core/src/sync/atomic.rs
|
||||
+++ b/library/core/src/sync/atomic.rs
|
||||
@@ -2996,44 +2996,6 @@ atomic_int! {
|
||||
@@ -3585,44 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type {
|
||||
8,
|
||||
u64 AtomicU64
|
||||
}
|
||||
|
@ -54,7 +53,7 @@ index d9de37e..8293fce 100644
|
|||
- unstable(feature = "integer_atomics", issue = "99069"),
|
||||
- rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
|
||||
- rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
|
||||
- cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"),
|
||||
- rustc_diagnostic_item = "AtomicI128",
|
||||
- "i128",
|
||||
- "#![feature(integer_atomics)]\n\n",
|
||||
- atomic_min, atomic_max,
|
||||
|
@ -73,7 +72,7 @@ index d9de37e..8293fce 100644
|
|||
- unstable(feature = "integer_atomics", issue = "99069"),
|
||||
- rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
|
||||
- rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
|
||||
- cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"),
|
||||
- rustc_diagnostic_item = "AtomicU128",
|
||||
- "u128",
|
||||
- "#![feature(integer_atomics)]\n\n",
|
||||
- atomic_umin, atomic_umax,
|
||||
|
@ -83,7 +82,6 @@ index d9de37e..8293fce 100644
|
|||
|
||||
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||
macro_rules! atomic_int_ptr_sized {
|
||||
( $($target_pointer_width:literal $align:literal)* ) => { $(
|
||||
--
|
||||
2.26.2.7.g19db9cfb68
|
||||
2.48.1
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use rustc_ast::expand::allocator::{
|
|||
};
|
||||
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
|
||||
use rustc_session::config::OomStrategy;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
@ -14,6 +15,7 @@ use crate::prelude::*;
|
|||
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
|
||||
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
|
||||
codegen_inner(
|
||||
tcx,
|
||||
module,
|
||||
kind,
|
||||
tcx.alloc_error_handler_kind(()).unwrap(),
|
||||
|
@ -23,6 +25,7 @@ pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
|
|||
}
|
||||
|
||||
fn codegen_inner(
|
||||
tcx: TyCtxt<'_>,
|
||||
module: &mut dyn Module,
|
||||
kind: AllocatorKind,
|
||||
alloc_error_handler_kind: AllocatorKind,
|
||||
|
@ -62,8 +65,8 @@ fn codegen_inner(
|
|||
crate::common::create_wrapper_function(
|
||||
module,
|
||||
sig,
|
||||
&global_fn_name(method.name),
|
||||
&default_fn_name(method.name),
|
||||
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
|
||||
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -76,19 +79,32 @@ fn codegen_inner(
|
|||
crate::common::create_wrapper_function(
|
||||
module,
|
||||
sig,
|
||||
"__rust_alloc_error_handler",
|
||||
&alloc_error_handler_name(alloc_error_handler_kind),
|
||||
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
|
||||
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
|
||||
);
|
||||
|
||||
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();
|
||||
let data_id = module
|
||||
.declare_data(
|
||||
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
Linkage::Export,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let mut data = DataDescription::new();
|
||||
data.set_align(1);
|
||||
let val = oom_strategy.should_panic();
|
||||
data.define(Box::new([val]));
|
||||
module.define_data(data_id, &data).unwrap();
|
||||
|
||||
let data_id =
|
||||
module.declare_data(NO_ALLOC_SHIM_IS_UNSTABLE, Linkage::Export, false, false).unwrap();
|
||||
let data_id = module
|
||||
.declare_data(
|
||||
&mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
|
||||
Linkage::Export,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let mut data = DataDescription::new();
|
||||
data.set_align(1);
|
||||
data.define(Box::new([0]));
|
||||
|
|
|
@ -1031,7 +1031,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
|
||||
let layout = src.layout();
|
||||
match layout.ty.kind() {
|
||||
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
|
||||
ty::Int(_) => {}
|
||||
_ => {
|
||||
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
|
||||
return Ok(());
|
||||
|
@ -1052,7 +1052,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
|
||||
let layout = src.layout();
|
||||
match layout.ty.kind() {
|
||||
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
|
||||
ty::Uint(_) => {}
|
||||
_ => {
|
||||
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
|
||||
return Ok(());
|
||||
|
@ -1073,7 +1073,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
|
||||
let layout = src.layout();
|
||||
match layout.ty.kind() {
|
||||
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
|
||||
ty::Int(_) => {}
|
||||
_ => {
|
||||
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
|
||||
return Ok(());
|
||||
|
@ -1094,7 +1094,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
|
||||
let layout = src.layout();
|
||||
match layout.ty.kind() {
|
||||
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
|
||||
ty::Uint(_) => {}
|
||||
_ => {
|
||||
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
|
||||
return Ok(());
|
||||
|
|
|
@ -26,6 +26,7 @@ extern crate rustc_index;
|
|||
extern crate rustc_metadata;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
extern crate rustc_symbol_mangling;
|
||||
extern crate rustc_target;
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
|
|
@ -8,6 +8,7 @@ use rustc_ast::expand::allocator::{
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::OomStrategy;
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
|
||||
use crate::GccContext;
|
||||
#[cfg(feature = "master")]
|
||||
|
@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen(
|
|||
panic!("invalid allocator output")
|
||||
}
|
||||
};
|
||||
let from_name = global_fn_name(method.name);
|
||||
let to_name = default_fn_name(method.name);
|
||||
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
|
||||
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
|
||||
|
||||
create_wrapper_function(tcx, context, &from_name, &to_name, &types, output);
|
||||
}
|
||||
|
@ -64,13 +65,13 @@ pub(crate) unsafe fn codegen(
|
|||
create_wrapper_function(
|
||||
tcx,
|
||||
context,
|
||||
"__rust_alloc_error_handler",
|
||||
alloc_error_handler_name(alloc_error_handler_kind),
|
||||
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
|
||||
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
|
||||
&[usize, usize],
|
||||
None,
|
||||
);
|
||||
|
||||
let name = OomStrategy::SYMBOL.to_string();
|
||||
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
|
||||
let global = context.new_global(None, GlobalKind::Exported, i8, name);
|
||||
#[cfg(feature = "master")]
|
||||
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
|
||||
|
@ -80,7 +81,7 @@ pub(crate) unsafe fn codegen(
|
|||
let value = context.new_rvalue_from_int(i8, value as i32);
|
||||
global.global_set_initializer_rvalue(value);
|
||||
|
||||
let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
|
||||
let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE);
|
||||
let global = context.new_global(None, GlobalKind::Exported, i8, name);
|
||||
#[cfg(feature = "master")]
|
||||
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
|
||||
|
|
|
@ -52,6 +52,7 @@ extern crate rustc_metadata;
|
|||
extern crate rustc_middle;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
extern crate rustc_symbol_mangling;
|
||||
extern crate rustc_target;
|
||||
|
||||
// This prevents duplicating functions and statics that are already part of the host rustc process.
|
||||
|
|
|
@ -14,7 +14,7 @@ bitflags = "2.4.1"
|
|||
gimli = "0.30"
|
||||
itertools = "0.12"
|
||||
libc = "0.2"
|
||||
measureme = "11"
|
||||
measureme = "12.0.1"
|
||||
object = { version = "0.36.3", default-features = false, features = ["std", "read"] }
|
||||
rustc-demangle = "0.1.21"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
|
|
|
@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{DebugInfo, OomStrategy};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
|
||||
use crate::builder::SBuilder;
|
||||
use crate::declare::declare_simple_fn;
|
||||
|
@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen(
|
|||
}
|
||||
};
|
||||
|
||||
let from_name = global_fn_name(method.name);
|
||||
let to_name = default_fn_name(method.name);
|
||||
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
|
||||
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
|
||||
|
||||
create_wrapper_function(tcx, &cx, &from_name, &to_name, &args, output, false);
|
||||
}
|
||||
|
@ -64,8 +65,8 @@ pub(crate) unsafe fn codegen(
|
|||
create_wrapper_function(
|
||||
tcx,
|
||||
&cx,
|
||||
"__rust_alloc_error_handler",
|
||||
alloc_error_handler_name(alloc_error_handler_kind),
|
||||
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
|
||||
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
|
||||
&[usize, usize], // size, align
|
||||
None,
|
||||
true,
|
||||
|
@ -73,15 +74,15 @@ pub(crate) unsafe fn codegen(
|
|||
|
||||
unsafe {
|
||||
// __rust_alloc_error_handler_should_panic
|
||||
let name = OomStrategy::SYMBOL;
|
||||
let ll_g = cx.declare_global(name, i8);
|
||||
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
|
||||
let ll_g = cx.declare_global(&name, i8);
|
||||
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
||||
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
|
||||
let llval = llvm::LLVMConstInt(i8, val as u64, False);
|
||||
llvm::set_initializer(ll_g, llval);
|
||||
|
||||
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
|
||||
let ll_g = cx.declare_global(name, i8);
|
||||
let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE);
|
||||
let ll_g = cx.declare_global(&name, i8);
|
||||
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
|
||||
let llval = llvm::LLVMConstInt(i8, 0, False);
|
||||
llvm::set_initializer(ll_g, llval);
|
||||
|
|
|
@ -5,6 +5,7 @@ use rustc_abi::{
|
|||
};
|
||||
use rustc_codegen_ssa::common;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||
|
@ -12,9 +13,9 @@ use rustc_middle::mir::interpret::{
|
|||
Allocation, ConstAllocation, ErrorHandled, InitChunk, Pointer, Scalar as InterpScalar,
|
||||
read_target_uint,
|
||||
};
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::mir::mono::{Linkage, MonoItem};
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::{self, Instance};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
|
@ -171,8 +172,27 @@ fn check_and_apply_linkage<'ll, 'tcx>(
|
|||
if let Some(linkage) = attrs.import_linkage {
|
||||
debug!("get_static: sym={} linkage={:?}", sym, linkage);
|
||||
|
||||
// Declare a symbol `foo` with the desired linkage.
|
||||
let g1 = cx.declare_global(sym, cx.type_i8());
|
||||
// Declare a symbol `foo`. If `foo` is an extern_weak symbol, we declare
|
||||
// an extern_weak function, otherwise a global with the desired linkage.
|
||||
let g1 = if matches!(attrs.import_linkage, Some(Linkage::ExternalWeak)) {
|
||||
// An `extern_weak` function is represented as an `Option<unsafe extern ...>`,
|
||||
// we extract the function signature and declare it as an extern_weak function
|
||||
// instead of an extern_weak i8.
|
||||
let instance = Instance::mono(cx.tcx, def_id);
|
||||
if let ty::Adt(struct_def, args) = instance.ty(cx.tcx, cx.typing_env()).kind()
|
||||
&& cx.tcx.is_lang_item(struct_def.did(), LangItem::Option)
|
||||
&& let ty::FnPtr(sig, header) = args.type_at(0).kind()
|
||||
{
|
||||
let fn_sig = sig.with(*header);
|
||||
|
||||
let fn_abi = cx.fn_abi_of_fn_ptr(fn_sig, ty::List::empty());
|
||||
cx.declare_fn(sym, &fn_abi, None)
|
||||
} else {
|
||||
cx.declare_global(sym, cx.type_i8())
|
||||
}
|
||||
} else {
|
||||
cx.declare_global(sym, cx.type_i8())
|
||||
};
|
||||
llvm::set_linkage(g1, base::linkage_to_llvm(linkage));
|
||||
|
||||
// Declare an internal global `extern_with_linkage_foo` which
|
||||
|
|
|
@ -27,6 +27,7 @@ use rustc_session::config::{
|
|||
};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
|
@ -1199,7 +1200,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
Some(def_id) => self.get_static(def_id),
|
||||
_ => {
|
||||
let ty = self.type_struct(&[self.type_ptr(), self.type_ptr()], false);
|
||||
self.declare_global("rust_eh_catch_typeinfo", ty)
|
||||
self.declare_global(&mangle_internal_symbol(self.tcx, "rust_eh_catch_typeinfo"), ty)
|
||||
}
|
||||
};
|
||||
self.eh_catch_typeinfo.set(Some(eh_catch_typeinfo));
|
||||
|
|
|
@ -14,6 +14,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
|
|||
use rustc_middle::ty::{self, GenericArgsRef, Ty};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::callconv::{FnAbi, PassMode};
|
||||
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
|
||||
use tracing::debug;
|
||||
|
@ -812,7 +813,10 @@ fn codegen_msvc_try<'ll>(
|
|||
let type_name = bx.const_bytes(b"rust_panic\0");
|
||||
let type_info =
|
||||
bx.const_struct(&[type_info_vtable, bx.const_null(bx.type_ptr()), type_name], false);
|
||||
let tydesc = bx.declare_global("__rust_panic_type_info", bx.val_ty(type_info));
|
||||
let tydesc = bx.declare_global(
|
||||
&mangle_internal_symbol(bx.tcx, "__rust_panic_type_info"),
|
||||
bx.val_ty(type_info),
|
||||
);
|
||||
|
||||
llvm::set_linkage(tydesc, llvm::Linkage::LinkOnceODRLinkage);
|
||||
if bx.cx.tcx.sess.target.supports_comdat() {
|
||||
|
|
|
@ -40,7 +40,6 @@ rustc_span = { path = "../rustc_span" }
|
|||
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
rustc_type_ir = { path = "../rustc_type_ir" }
|
||||
serde_json = "1.0.59"
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
tempfile = "3.2"
|
||||
|
|
|
@ -137,17 +137,40 @@ impl Command {
|
|||
/// Returns a `true` if we're pretty sure that this'll blow OS spawn limits,
|
||||
/// or `false` if we should attempt to spawn and see what the OS says.
|
||||
pub(crate) fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
|
||||
// We mostly only care about Windows in this method, on Unix the limits
|
||||
// can be gargantuan anyway so we're pretty unlikely to hit them
|
||||
if cfg!(unix) {
|
||||
#[cfg(not(any(windows, unix)))]
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Right now LLD doesn't support the `@` syntax of passing an argument
|
||||
// through files, so regardless of the platform we try to go to the OS
|
||||
// on this one.
|
||||
if let Program::Lld(..) = self.program {
|
||||
return false;
|
||||
// On Unix the limits can be gargantuan anyway so we're pretty
|
||||
// unlikely to hit them, but might still exceed it.
|
||||
// We consult ARG_MAX here to get an estimate.
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let ptr_size = mem::size_of::<usize>();
|
||||
// arg + \0 + pointer
|
||||
let args_size = self.args.iter().fold(0usize, |acc, a| {
|
||||
let arg = a.as_encoded_bytes().len();
|
||||
let nul = 1;
|
||||
acc.saturating_add(arg).saturating_add(nul).saturating_add(ptr_size)
|
||||
});
|
||||
// key + `=` + value + \0 + pointer
|
||||
let envs_size = self.env.iter().fold(0usize, |acc, (k, v)| {
|
||||
let k = k.as_encoded_bytes().len();
|
||||
let eq = 1;
|
||||
let v = v.as_encoded_bytes().len();
|
||||
let nul = 1;
|
||||
acc.saturating_add(k)
|
||||
.saturating_add(eq)
|
||||
.saturating_add(v)
|
||||
.saturating_add(nul)
|
||||
.saturating_add(ptr_size)
|
||||
});
|
||||
let arg_max = match unsafe { libc::sysconf(libc::_SC_ARG_MAX) } {
|
||||
-1 => return false, // Go to OS anyway.
|
||||
max => max as usize,
|
||||
};
|
||||
return args_size.saturating_add(envs_size) > arg_max;
|
||||
}
|
||||
|
||||
// Ok so on Windows to spawn a process is 32,768 characters in its
|
||||
|
@ -172,9 +195,14 @@ impl Command {
|
|||
//
|
||||
// [1]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
|
||||
// [2]: https://devblogs.microsoft.com/oldnewthing/?p=41553
|
||||
|
||||
let estimated_command_line_len = self.args.iter().map(|a| a.len()).sum::<usize>();
|
||||
estimated_command_line_len > 1024 * 6
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let estimated_command_line_len = self
|
||||
.args
|
||||
.iter()
|
||||
.fold(0usize, |acc, a| acc.saturating_add(a.as_encoded_bytes().len()));
|
||||
return estimated_command_line_len > 1024 * 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
|
|||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_macros::LintDiagnostic;
|
||||
use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
|
||||
use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
|
||||
use rustc_metadata::{
|
||||
NativeLibSearchFallback, find_native_static_library, walk_native_lib_search_dirs,
|
||||
};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::lint::lint_level;
|
||||
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
|
||||
|
@ -1286,8 +1288,7 @@ fn link_sanitizer_runtime(
|
|||
if path.exists() {
|
||||
sess.target_tlib_path.dir.clone()
|
||||
} else {
|
||||
let default_sysroot =
|
||||
filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
|
||||
let default_sysroot = filesearch::get_or_default_sysroot();
|
||||
let default_tlib =
|
||||
filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.tuple());
|
||||
default_tlib
|
||||
|
@ -1537,8 +1538,13 @@ fn print_native_static_libs(
|
|||
}
|
||||
let stem = path.file_stem().unwrap().to_str().unwrap();
|
||||
// Convert library file-stem into a cc -l argument.
|
||||
let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 };
|
||||
let lib = &stem[prefix..];
|
||||
let lib = if let Some(lib) = stem.strip_prefix("lib")
|
||||
&& !sess.target.is_like_windows
|
||||
{
|
||||
lib
|
||||
} else {
|
||||
stem
|
||||
};
|
||||
let path = parent.unwrap_or_else(|| Path::new(""));
|
||||
if sess.target.is_like_msvc {
|
||||
// When producing a dll, the MSVC linker may not actually emit a
|
||||
|
@ -2129,19 +2135,15 @@ fn add_library_search_dirs(
|
|||
return;
|
||||
}
|
||||
|
||||
walk_native_lib_search_dirs(
|
||||
sess,
|
||||
self_contained_components,
|
||||
apple_sdk_root,
|
||||
|dir, is_framework| {
|
||||
if is_framework {
|
||||
cmd.framework_path(dir);
|
||||
} else {
|
||||
cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
|
||||
}
|
||||
ControlFlow::<()>::Continue(())
|
||||
},
|
||||
);
|
||||
let fallback = Some(NativeLibSearchFallback { self_contained_components, apple_sdk_root });
|
||||
let _ = walk_native_lib_search_dirs(sess, fallback, |dir, is_framework| {
|
||||
if is_framework {
|
||||
cmd.framework_path(dir);
|
||||
} else {
|
||||
cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
|
||||
}
|
||||
ControlFlow::<()>::Continue(())
|
||||
});
|
||||
}
|
||||
|
||||
/// Add options making relocation sections in the produced ELF files read-only
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::hash_map::Entry::*;
|
||||
|
||||
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE};
|
||||
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name};
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId};
|
||||
|
@ -13,6 +13,7 @@ use rustc_middle::query::LocalCrate;
|
|||
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt};
|
||||
use rustc_middle::util::Providers;
|
||||
use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::callconv::Conv;
|
||||
use rustc_target::spec::{SanitizerSet, TlsModel};
|
||||
use tracing::debug;
|
||||
|
@ -219,8 +220,11 @@ fn exported_symbols_provider_local(
|
|||
if allocator_kind_for_codegen(tcx).is_some() {
|
||||
for symbol_name in ALLOCATOR_METHODS
|
||||
.iter()
|
||||
.map(|method| format!("__rust_{}", method.name))
|
||||
.chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()])
|
||||
.map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
|
||||
.chain([
|
||||
mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
|
||||
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
|
||||
])
|
||||
{
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
|
||||
|
||||
|
@ -234,8 +238,10 @@ fn exported_symbols_provider_local(
|
|||
));
|
||||
}
|
||||
|
||||
let exported_symbol =
|
||||
ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE));
|
||||
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(
|
||||
tcx,
|
||||
&mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
|
||||
));
|
||||
symbols.push((
|
||||
exported_symbol,
|
||||
SymbolExportInfo {
|
||||
|
|
|
@ -28,6 +28,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
|||
use rustc_session::Session;
|
||||
use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
|
||||
use rustc_span::{DUMMY_SP, Symbol, sym};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
||||
use tracing::{debug, info};
|
||||
|
@ -989,7 +990,12 @@ impl CrateInfo {
|
|||
.for_each(|(_, linked_symbols)| {
|
||||
let mut symbols = missing_weak_lang_items
|
||||
.iter()
|
||||
.map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text))
|
||||
.map(|item| {
|
||||
(
|
||||
format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())),
|
||||
SymbolExportKind::Text,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
symbols.sort_unstable_by(|a, b| a.0.cmp(&b.0));
|
||||
linked_symbols.extend(symbols);
|
||||
|
@ -1002,7 +1008,13 @@ impl CrateInfo {
|
|||
// errors.
|
||||
linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
|
||||
(
|
||||
format!("{prefix}{}", global_fn_name(method.name).as_str()),
|
||||
format!(
|
||||
"{prefix}{}",
|
||||
mangle_internal_symbol(
|
||||
tcx,
|
||||
global_fn_name(method.name).as_str()
|
||||
)
|
||||
),
|
||||
SymbolExportKind::Text,
|
||||
)
|
||||
}));
|
||||
|
|
|
@ -601,25 +601,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
// strippable by the linker.
|
||||
//
|
||||
// Additionally weak lang items have predetermined symbol names.
|
||||
if WEAK_LANG_ITEMS.iter().any(|&l| tcx.lang_items().get(l) == Some(did.to_def_id())) {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
|
||||
}
|
||||
if let Some((name, _)) = lang_items::extract(attrs)
|
||||
&& let Some(lang_item) = LangItem::from_name(name)
|
||||
&& let Some(link_name) = lang_item.link_name()
|
||||
{
|
||||
codegen_fn_attrs.export_name = Some(link_name);
|
||||
codegen_fn_attrs.link_name = Some(link_name);
|
||||
if WEAK_LANG_ITEMS.iter().any(|&l| l == lang_item) {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
|
||||
}
|
||||
if let Some(link_name) = lang_item.link_name() {
|
||||
codegen_fn_attrs.export_name = Some(link_name);
|
||||
codegen_fn_attrs.link_name = Some(link_name);
|
||||
}
|
||||
}
|
||||
check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span);
|
||||
|
||||
// Internal symbols to the standard library all have no_mangle semantics in
|
||||
// that they have defined symbol names present in the function name. This
|
||||
// also applies to weak symbols where they all have known symbol names.
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
||||
}
|
||||
|
||||
// Any linkage to LLVM intrinsics for now forcibly marks them all as never
|
||||
// unwinds since LLVM sometimes can't handle codegen which `invoke`s
|
||||
// intrinsic functions.
|
||||
|
|
|
@ -12,10 +12,9 @@ use rustc_errors::{
|
|||
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::LayoutError;
|
||||
use rustc_middle::ty::{FloatTy, Ty};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_type_ir::FloatTy;
|
||||
|
||||
use crate::assert_module_sources::CguReuse;
|
||||
use crate::back::command::Command;
|
||||
|
|
|
@ -205,7 +205,12 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer
|
|||
| PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
|
||||
|
||||
PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
|
||||
NonMutatingUseContext::Copy
|
||||
| NonMutatingUseContext::Move
|
||||
// Inspect covers things like `PtrMetadata` and `Discriminant`
|
||||
// which we can treat similar to `Copy` use for the purpose of
|
||||
// whether we can use SSA variables for things.
|
||||
| NonMutatingUseContext::Inspect,
|
||||
) => match &mut self.locals[local] {
|
||||
LocalKind::ZST => {}
|
||||
LocalKind::Memory => {}
|
||||
|
@ -229,8 +234,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer
|
|||
| MutatingUseContext::Projection,
|
||||
)
|
||||
| PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Inspect
|
||||
| NonMutatingUseContext::SharedBorrow
|
||||
NonMutatingUseContext::SharedBorrow
|
||||
| NonMutatingUseContext::FakeBorrow
|
||||
| NonMutatingUseContext::RawBorrow
|
||||
| NonMutatingUseContext::Projection,
|
||||
|
|
|
@ -43,7 +43,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
mir::Const::Ty(_, c) => match c.kind() {
|
||||
// A constant that came from a const generic but was then used as an argument to
|
||||
// old-style simd_shuffle (passing as argument instead of as a generic param).
|
||||
rustc_type_ir::ConstKind::Value(cv) => return Ok(Ok(cv.valtree)),
|
||||
ty::ConstKind::Value(cv) => return Ok(Ok(cv.valtree)),
|
||||
other => span_bug!(constant.span, "{other:#?}"),
|
||||
},
|
||||
// We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
|
||||
|
|
|
@ -62,7 +62,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let callee_ty = instance.ty(bx.tcx(), bx.typing_env());
|
||||
|
||||
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||
bug!("expected fn item type, found {}", callee_ty);
|
||||
span_bug!(span, "expected fn item type, found {}", callee_ty);
|
||||
};
|
||||
|
||||
let sig = callee_ty.fn_sig(bx.tcx());
|
||||
|
@ -325,14 +325,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
}
|
||||
|
||||
sym::discriminant_value => {
|
||||
if ret_ty.is_integral() {
|
||||
args[0].deref(bx.cx()).codegen_get_discr(bx, ret_ty)
|
||||
} else {
|
||||
span_bug!(span, "Invalid discriminant type for `{:?}`", arg_tys[0])
|
||||
}
|
||||
}
|
||||
|
||||
// This requires that atomic intrinsics follow a specific naming pattern:
|
||||
// "atomic_<operation>[_<ordering>]"
|
||||
name if let Some(atomic) = name_str.strip_prefix("atomic_") => {
|
||||
|
@ -441,6 +433,40 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
|
||||
// These are all AtomicRMW ops
|
||||
"max" | "min" => {
|
||||
let atom_op = if instruction == "max" {
|
||||
AtomicRmwBinOp::AtomicMax
|
||||
} else {
|
||||
AtomicRmwBinOp::AtomicMin
|
||||
};
|
||||
|
||||
let ty = fn_args.type_at(0);
|
||||
if matches!(ty.kind(), ty::Int(_)) {
|
||||
let ptr = args[0].immediate();
|
||||
let val = args[1].immediate();
|
||||
bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
|
||||
} else {
|
||||
invalid_monomorphization(ty);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
"umax" | "umin" => {
|
||||
let atom_op = if instruction == "umax" {
|
||||
AtomicRmwBinOp::AtomicUMax
|
||||
} else {
|
||||
AtomicRmwBinOp::AtomicUMin
|
||||
};
|
||||
|
||||
let ty = fn_args.type_at(0);
|
||||
if matches!(ty.kind(), ty::Uint(_)) {
|
||||
let ptr = args[0].immediate();
|
||||
let val = args[1].immediate();
|
||||
bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
|
||||
} else {
|
||||
invalid_monomorphization(ty);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
op => {
|
||||
let atom_op = match op {
|
||||
"xchg" => AtomicRmwBinOp::AtomicXchg,
|
||||
|
@ -450,10 +476,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
"nand" => AtomicRmwBinOp::AtomicNand,
|
||||
"or" => AtomicRmwBinOp::AtomicOr,
|
||||
"xor" => AtomicRmwBinOp::AtomicXor,
|
||||
"max" => AtomicRmwBinOp::AtomicMax,
|
||||
"min" => AtomicRmwBinOp::AtomicMin,
|
||||
"umax" => AtomicRmwBinOp::AtomicUMax,
|
||||
"umin" => AtomicRmwBinOp::AtomicUMin,
|
||||
_ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOperation),
|
||||
};
|
||||
|
||||
|
|
|
@ -125,7 +125,8 @@ fn prefix_and_suffix<'tcx>(
|
|||
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
|
||||
// if no alignment is specified, an alignment of 4 bytes is used.
|
||||
let min_function_alignment = tcx.sess.opts.unstable_opts.min_function_alignment;
|
||||
let align = Ord::max(min_function_alignment, attrs.alignment).map(|a| a.bytes()).unwrap_or(4);
|
||||
let align_bytes =
|
||||
Ord::max(min_function_alignment, attrs.alignment).map(|a| a.bytes()).unwrap_or(4);
|
||||
|
||||
// In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`.
|
||||
let (arch_prefix, arch_suffix) = if is_arm {
|
||||
|
@ -157,12 +158,16 @@ fn prefix_and_suffix<'tcx>(
|
|||
}
|
||||
Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => {
|
||||
match asm_binary_format {
|
||||
BinaryFormat::Elf
|
||||
| BinaryFormat::Coff
|
||||
| BinaryFormat::Wasm
|
||||
| BinaryFormat::Xcoff => {
|
||||
BinaryFormat::Elf | BinaryFormat::Coff | BinaryFormat::Wasm => {
|
||||
writeln!(w, ".weak {asm_name}")?;
|
||||
}
|
||||
BinaryFormat::Xcoff => {
|
||||
// FIXME: there is currently no way of defining a weak symbol in inline assembly
|
||||
// for AIX. See https://github.com/llvm/llvm-project/issues/130269
|
||||
emit_fatal(
|
||||
"cannot create weak symbols from inline assembly for this target",
|
||||
)
|
||||
}
|
||||
BinaryFormat::MachO => {
|
||||
writeln!(w, ".globl {asm_name}")?;
|
||||
writeln!(w, ".weak_definition {asm_name}")?;
|
||||
|
@ -189,7 +194,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
let mut begin = String::new();
|
||||
let mut end = String::new();
|
||||
match asm_binary_format {
|
||||
BinaryFormat::Elf | BinaryFormat::Xcoff => {
|
||||
BinaryFormat::Elf => {
|
||||
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
|
||||
|
||||
let progbits = match is_arm {
|
||||
|
@ -203,7 +208,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
};
|
||||
|
||||
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
|
||||
writeln!(begin, ".balign {align}").unwrap();
|
||||
writeln!(begin, ".balign {align_bytes}").unwrap();
|
||||
write_linkage(&mut begin).unwrap();
|
||||
if let Visibility::Hidden = item_data.visibility {
|
||||
writeln!(begin, ".hidden {asm_name}").unwrap();
|
||||
|
@ -224,7 +229,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
BinaryFormat::MachO => {
|
||||
let section = link_section.unwrap_or("__TEXT,__text".to_string());
|
||||
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
|
||||
writeln!(begin, ".balign {align}").unwrap();
|
||||
writeln!(begin, ".balign {align_bytes}").unwrap();
|
||||
write_linkage(&mut begin).unwrap();
|
||||
if let Visibility::Hidden = item_data.visibility {
|
||||
writeln!(begin, ".private_extern {asm_name}").unwrap();
|
||||
|
@ -240,12 +245,12 @@ fn prefix_and_suffix<'tcx>(
|
|||
BinaryFormat::Coff => {
|
||||
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
|
||||
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
|
||||
writeln!(begin, ".balign {align}").unwrap();
|
||||
writeln!(begin, ".balign {align_bytes}").unwrap();
|
||||
write_linkage(&mut begin).unwrap();
|
||||
writeln!(begin, ".def {asm_name}").unwrap();
|
||||
writeln!(begin, ".scl 2").unwrap();
|
||||
writeln!(begin, ".type 32").unwrap();
|
||||
writeln!(begin, ".endef {asm_name}").unwrap();
|
||||
writeln!(begin, ".endef").unwrap();
|
||||
writeln!(begin, "{asm_name}:").unwrap();
|
||||
|
||||
writeln!(end).unwrap();
|
||||
|
@ -279,6 +284,33 @@ fn prefix_and_suffix<'tcx>(
|
|||
// .size is ignored for function symbols, so we can skip it
|
||||
writeln!(end, "end_function").unwrap();
|
||||
}
|
||||
BinaryFormat::Xcoff => {
|
||||
// the LLVM XCOFFAsmParser is extremely incomplete and does not implement many of the
|
||||
// documented directives.
|
||||
//
|
||||
// - https://github.com/llvm/llvm-project/blob/1b25c0c4da968fe78921ce77736e5baef4db75e3/llvm/lib/MC/MCParser/XCOFFAsmParser.cpp
|
||||
// - https://www.ibm.com/docs/en/ssw_aix_71/assembler/assembler_pdf.pdf
|
||||
//
|
||||
// Consequently, we try our best here but cannot do as good a job as for other binary
|
||||
// formats.
|
||||
|
||||
// FIXME: start a section. `.csect` is not currently implemented in LLVM
|
||||
|
||||
// fun fact: according to the assembler documentation, .align takes an exponent,
|
||||
// but LLVM only accepts powers of 2 (but does emit the exponent)
|
||||
// so when we hand `.align 32` to LLVM, the assembly output will contain `.align 5`
|
||||
writeln!(begin, ".align {}", align_bytes).unwrap();
|
||||
|
||||
write_linkage(&mut begin).unwrap();
|
||||
if let Visibility::Hidden = item_data.visibility {
|
||||
// FIXME apparently `.globl {asm_name}, hidden` is valid
|
||||
// but due to limitations with `.weak` (see above) we can't really use that in general yet
|
||||
}
|
||||
writeln!(begin, "{asm_name}:").unwrap();
|
||||
|
||||
writeln!(end).unwrap();
|
||||
// FIXME: end the section?
|
||||
}
|
||||
}
|
||||
|
||||
(begin, end)
|
||||
|
|
|
@ -3,16 +3,17 @@ use std::fmt;
|
|||
use arrayvec::ArrayVec;
|
||||
use either::Either;
|
||||
use rustc_abi as abi;
|
||||
use rustc_abi::{Align, BackendRepr, Size};
|
||||
use rustc_abi::{Align, BackendRepr, FIRST_VARIANT, Primitive, Size, TagEncoding, Variants};
|
||||
use rustc_middle::mir::interpret::{Pointer, Scalar, alloc_range};
|
||||
use rustc_middle::mir::{self, ConstValue};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use tracing::debug;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::place::{PlaceRef, PlaceValue};
|
||||
use super::{FunctionCx, LocalRef};
|
||||
use crate::common::IntPredicate;
|
||||
use crate::traits::*;
|
||||
use crate::{MemFlags, size_of_val};
|
||||
|
||||
|
@ -415,6 +416,149 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
|||
|
||||
OperandRef { val, layout: field }
|
||||
}
|
||||
|
||||
/// Obtain the actual discriminant of a value.
|
||||
#[instrument(level = "trace", skip(fx, bx))]
|
||||
pub fn codegen_get_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
self,
|
||||
fx: &mut FunctionCx<'a, 'tcx, Bx>,
|
||||
bx: &mut Bx,
|
||||
cast_to: Ty<'tcx>,
|
||||
) -> V {
|
||||
let dl = &bx.tcx().data_layout;
|
||||
let cast_to_layout = bx.cx().layout_of(cast_to);
|
||||
let cast_to = bx.cx().immediate_backend_type(cast_to_layout);
|
||||
|
||||
// We check uninhabitedness separately because a type like
|
||||
// `enum Foo { Bar(i32, !) }` is still reported as `Variants::Single`,
|
||||
// *not* as `Variants::Empty`.
|
||||
if self.layout.is_uninhabited() {
|
||||
return bx.cx().const_poison(cast_to);
|
||||
}
|
||||
|
||||
let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants {
|
||||
Variants::Empty => unreachable!("we already handled uninhabited types"),
|
||||
Variants::Single { index } => {
|
||||
let discr_val =
|
||||
if let Some(discr) = self.layout.ty.discriminant_for_variant(bx.tcx(), index) {
|
||||
discr.val
|
||||
} else {
|
||||
// This arm is for types which are neither enums nor coroutines,
|
||||
// and thus for which the only possible "variant" should be the first one.
|
||||
assert_eq!(index, FIRST_VARIANT);
|
||||
// There's thus no actual discriminant to return, so we return
|
||||
// what it would have been if this was a single-variant enum.
|
||||
0
|
||||
};
|
||||
return bx.cx().const_uint_big(cast_to, discr_val);
|
||||
}
|
||||
Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
|
||||
(tag, tag_encoding, tag_field)
|
||||
}
|
||||
};
|
||||
|
||||
// Read the tag/niche-encoded discriminant from memory.
|
||||
let tag_op = match self.val {
|
||||
OperandValue::ZeroSized => bug!(),
|
||||
OperandValue::Immediate(_) | OperandValue::Pair(_, _) => {
|
||||
self.extract_field(fx, bx, tag_field)
|
||||
}
|
||||
OperandValue::Ref(place) => {
|
||||
let tag = place.with_type(self.layout).project_field(bx, tag_field);
|
||||
bx.load_operand(tag)
|
||||
}
|
||||
};
|
||||
let tag_imm = tag_op.immediate();
|
||||
|
||||
// Decode the discriminant (specifically if it's niche-encoded).
|
||||
match *tag_encoding {
|
||||
TagEncoding::Direct => {
|
||||
let signed = match tag_scalar.primitive() {
|
||||
// We use `i1` for bytes that are always `0` or `1`,
|
||||
// e.g., `#[repr(i8)] enum E { A, B }`, but we can't
|
||||
// let LLVM interpret the `i1` as signed, because
|
||||
// then `i1 1` (i.e., `E::B`) is effectively `i8 -1`.
|
||||
Primitive::Int(_, signed) => !tag_scalar.is_bool() && signed,
|
||||
_ => false,
|
||||
};
|
||||
bx.intcast(tag_imm, cast_to, signed)
|
||||
}
|
||||
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
|
||||
// Cast to an integer so we don't have to treat a pointer as a
|
||||
// special case.
|
||||
let (tag, tag_llty) = match tag_scalar.primitive() {
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Primitive::Pointer(_) => {
|
||||
let t = bx.type_from_integer(dl.ptr_sized_integer());
|
||||
let tag = bx.ptrtoint(tag_imm, t);
|
||||
(tag, t)
|
||||
}
|
||||
_ => (tag_imm, bx.cx().immediate_backend_type(tag_op.layout)),
|
||||
};
|
||||
|
||||
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
|
||||
|
||||
// We have a subrange `niche_start..=niche_end` inside `range`.
|
||||
// If the value of the tag is inside this subrange, it's a
|
||||
// "niche value", an increment of the discriminant. Otherwise it
|
||||
// indicates the untagged variant.
|
||||
// A general algorithm to extract the discriminant from the tag
|
||||
// is:
|
||||
// relative_tag = tag - niche_start
|
||||
// is_niche = relative_tag <= (ule) relative_max
|
||||
// discr = if is_niche {
|
||||
// cast(relative_tag) + niche_variants.start()
|
||||
// } else {
|
||||
// untagged_variant
|
||||
// }
|
||||
// However, we will likely be able to emit simpler code.
|
||||
let (is_niche, tagged_discr, delta) = if relative_max == 0 {
|
||||
// Best case scenario: only one tagged variant. This will
|
||||
// likely become just a comparison and a jump.
|
||||
// The algorithm is:
|
||||
// is_niche = tag == niche_start
|
||||
// discr = if is_niche {
|
||||
// niche_start
|
||||
// } else {
|
||||
// untagged_variant
|
||||
// }
|
||||
let niche_start = bx.cx().const_uint_big(tag_llty, niche_start);
|
||||
let is_niche = bx.icmp(IntPredicate::IntEQ, tag, niche_start);
|
||||
let tagged_discr =
|
||||
bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64);
|
||||
(is_niche, tagged_discr, 0)
|
||||
} else {
|
||||
// The special cases don't apply, so we'll have to go with
|
||||
// the general algorithm.
|
||||
let relative_discr = bx.sub(tag, bx.cx().const_uint_big(tag_llty, niche_start));
|
||||
let cast_tag = bx.intcast(relative_discr, cast_to, false);
|
||||
let is_niche = bx.icmp(
|
||||
IntPredicate::IntULE,
|
||||
relative_discr,
|
||||
bx.cx().const_uint(tag_llty, relative_max as u64),
|
||||
);
|
||||
(is_niche, cast_tag, niche_variants.start().as_u32() as u128)
|
||||
};
|
||||
|
||||
let tagged_discr = if delta == 0 {
|
||||
tagged_discr
|
||||
} else {
|
||||
bx.add(tagged_discr, bx.cx().const_uint_big(cast_to, delta))
|
||||
};
|
||||
|
||||
let discr = bx.select(
|
||||
is_niche,
|
||||
tagged_discr,
|
||||
bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
|
||||
);
|
||||
|
||||
// In principle we could insert assumes on the possible range of `discr`, but
|
||||
// currently in LLVM this seems to be a pessimization.
|
||||
|
||||
discr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use rustc_abi::Primitive::{Int, Pointer};
|
||||
use rustc_abi::{Align, BackendRepr, FieldsShape, Size, TagEncoding, VariantIdx, Variants};
|
||||
use rustc_middle::mir::PlaceTy;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
|
@ -233,129 +232,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
|||
val.with_type(field)
|
||||
}
|
||||
|
||||
/// Obtain the actual discriminant of a value.
|
||||
#[instrument(level = "trace", skip(bx))]
|
||||
pub fn codegen_get_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
self,
|
||||
bx: &mut Bx,
|
||||
cast_to: Ty<'tcx>,
|
||||
) -> V {
|
||||
let dl = &bx.tcx().data_layout;
|
||||
let cast_to_layout = bx.cx().layout_of(cast_to);
|
||||
let cast_to = bx.cx().immediate_backend_type(cast_to_layout);
|
||||
if self.layout.is_uninhabited() {
|
||||
return bx.cx().const_poison(cast_to);
|
||||
}
|
||||
let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants {
|
||||
Variants::Empty => unreachable!("we already handled uninhabited types"),
|
||||
Variants::Single { index } => {
|
||||
let discr_val = self
|
||||
.layout
|
||||
.ty
|
||||
.discriminant_for_variant(bx.cx().tcx(), index)
|
||||
.map_or(index.as_u32() as u128, |discr| discr.val);
|
||||
return bx.cx().const_uint_big(cast_to, discr_val);
|
||||
}
|
||||
Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
|
||||
(tag, tag_encoding, tag_field)
|
||||
}
|
||||
};
|
||||
|
||||
// Read the tag/niche-encoded discriminant from memory.
|
||||
let tag = self.project_field(bx, tag_field);
|
||||
let tag_op = bx.load_operand(tag);
|
||||
let tag_imm = tag_op.immediate();
|
||||
|
||||
// Decode the discriminant (specifically if it's niche-encoded).
|
||||
match *tag_encoding {
|
||||
TagEncoding::Direct => {
|
||||
let signed = match tag_scalar.primitive() {
|
||||
// We use `i1` for bytes that are always `0` or `1`,
|
||||
// e.g., `#[repr(i8)] enum E { A, B }`, but we can't
|
||||
// let LLVM interpret the `i1` as signed, because
|
||||
// then `i1 1` (i.e., `E::B`) is effectively `i8 -1`.
|
||||
Int(_, signed) => !tag_scalar.is_bool() && signed,
|
||||
_ => false,
|
||||
};
|
||||
bx.intcast(tag_imm, cast_to, signed)
|
||||
}
|
||||
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
|
||||
// Cast to an integer so we don't have to treat a pointer as a
|
||||
// special case.
|
||||
let (tag, tag_llty) = match tag_scalar.primitive() {
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Pointer(_) => {
|
||||
let t = bx.type_from_integer(dl.ptr_sized_integer());
|
||||
let tag = bx.ptrtoint(tag_imm, t);
|
||||
(tag, t)
|
||||
}
|
||||
_ => (tag_imm, bx.cx().immediate_backend_type(tag_op.layout)),
|
||||
};
|
||||
|
||||
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
|
||||
|
||||
// We have a subrange `niche_start..=niche_end` inside `range`.
|
||||
// If the value of the tag is inside this subrange, it's a
|
||||
// "niche value", an increment of the discriminant. Otherwise it
|
||||
// indicates the untagged variant.
|
||||
// A general algorithm to extract the discriminant from the tag
|
||||
// is:
|
||||
// relative_tag = tag - niche_start
|
||||
// is_niche = relative_tag <= (ule) relative_max
|
||||
// discr = if is_niche {
|
||||
// cast(relative_tag) + niche_variants.start()
|
||||
// } else {
|
||||
// untagged_variant
|
||||
// }
|
||||
// However, we will likely be able to emit simpler code.
|
||||
let (is_niche, tagged_discr, delta) = if relative_max == 0 {
|
||||
// Best case scenario: only one tagged variant. This will
|
||||
// likely become just a comparison and a jump.
|
||||
// The algorithm is:
|
||||
// is_niche = tag == niche_start
|
||||
// discr = if is_niche {
|
||||
// niche_start
|
||||
// } else {
|
||||
// untagged_variant
|
||||
// }
|
||||
let niche_start = bx.cx().const_uint_big(tag_llty, niche_start);
|
||||
let is_niche = bx.icmp(IntPredicate::IntEQ, tag, niche_start);
|
||||
let tagged_discr =
|
||||
bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64);
|
||||
(is_niche, tagged_discr, 0)
|
||||
} else {
|
||||
// The special cases don't apply, so we'll have to go with
|
||||
// the general algorithm.
|
||||
let relative_discr = bx.sub(tag, bx.cx().const_uint_big(tag_llty, niche_start));
|
||||
let cast_tag = bx.intcast(relative_discr, cast_to, false);
|
||||
let is_niche = bx.icmp(
|
||||
IntPredicate::IntULE,
|
||||
relative_discr,
|
||||
bx.cx().const_uint(tag_llty, relative_max as u64),
|
||||
);
|
||||
(is_niche, cast_tag, niche_variants.start().as_u32() as u128)
|
||||
};
|
||||
|
||||
let tagged_discr = if delta == 0 {
|
||||
tagged_discr
|
||||
} else {
|
||||
bx.add(tagged_discr, bx.cx().const_uint_big(cast_to, delta))
|
||||
};
|
||||
|
||||
let discr = bx.select(
|
||||
is_niche,
|
||||
tagged_discr,
|
||||
bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
|
||||
);
|
||||
|
||||
// In principle we could insert assumes on the possible range of `discr`, but
|
||||
// currently in LLVM this seems to be a pessimization.
|
||||
|
||||
discr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the discriminant for a new value of the given case of the given
|
||||
/// representation.
|
||||
pub fn codegen_set_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
|
|
|
@ -706,7 +706,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
mir::Rvalue::Discriminant(ref place) => {
|
||||
let discr_ty = rvalue.ty(self.mir, bx.tcx());
|
||||
let discr_ty = self.monomorphize(discr_ty);
|
||||
let discr = self.codegen_place(bx, place.as_ref()).codegen_get_discr(bx, discr_ty);
|
||||
let operand = self.codegen_consume(bx, place.as_ref());
|
||||
let discr = operand.codegen_get_discr(self, bx, discr_ty);
|
||||
OperandRef {
|
||||
val: OperandValue::Immediate(discr),
|
||||
layout: self.cx.layout_of(discr_ty),
|
||||
|
@ -746,7 +747,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let tcx = self.cx.tcx();
|
||||
OperandRef {
|
||||
val: OperandValue::Immediate(val),
|
||||
layout: self.cx.layout_of(tcx.types.usize),
|
||||
layout: self.cx.layout_of(null_op.ty(tcx)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,5 @@ rustc_session = { path = "../rustc_session" }
|
|||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
rustc_type_ir = { path = "../rustc_type_ir" }
|
||||
tracing = "0.1"
|
||||
# tidy-alphabetical-end
|
||||
|
|
|
@ -9,7 +9,6 @@ use rustc_middle::ty::adjustment::PointerCoercion;
|
|||
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, FloatTy, Ty};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_type_ir::TyKind::*;
|
||||
use tracing::trace;
|
||||
|
||||
use super::util::ensure_monomorphic_enough;
|
||||
|
@ -182,9 +181,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
src: &ImmTy<'tcx, M::Provenance>,
|
||||
cast_to: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
||||
use rustc_type_ir::TyKind::*;
|
||||
|
||||
let Float(fty) = src.layout.ty.kind() else {
|
||||
let ty::Float(fty) = src.layout.ty.kind() else {
|
||||
bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty)
|
||||
};
|
||||
let val = match fty {
|
||||
|
@ -277,19 +274,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let signed = src_layout.backend_repr.is_signed(); // Also asserts that abi is `Scalar`.
|
||||
|
||||
let v = match src_layout.ty.kind() {
|
||||
Uint(_) | RawPtr(..) | FnPtr(..) => scalar.to_uint(src_layout.size)?,
|
||||
Int(_) => scalar.to_int(src_layout.size)? as u128, // we will cast back to `i128` below if the sign matters
|
||||
Bool => scalar.to_bool()?.into(),
|
||||
Char => scalar.to_char()?.into(),
|
||||
ty::Uint(_) | ty::RawPtr(..) | ty::FnPtr(..) => scalar.to_uint(src_layout.size)?,
|
||||
ty::Int(_) => scalar.to_int(src_layout.size)? as u128, // we will cast back to `i128` below if the sign matters
|
||||
ty::Bool => scalar.to_bool()?.into(),
|
||||
ty::Char => scalar.to_char()?.into(),
|
||||
_ => span_bug!(self.cur_span(), "invalid int-like cast from {}", src_layout.ty),
|
||||
};
|
||||
|
||||
interp_ok(match *cast_ty.kind() {
|
||||
// int -> int
|
||||
Int(_) | Uint(_) => {
|
||||
ty::Int(_) | ty::Uint(_) => {
|
||||
let size = match *cast_ty.kind() {
|
||||
Int(t) => Integer::from_int_ty(self, t).size(),
|
||||
Uint(t) => Integer::from_uint_ty(self, t).size(),
|
||||
ty::Int(t) => Integer::from_int_ty(self, t).size(),
|
||||
ty::Uint(t) => Integer::from_uint_ty(self, t).size(),
|
||||
_ => bug!(),
|
||||
};
|
||||
let v = size.truncate(v);
|
||||
|
@ -297,7 +294,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
|
||||
// signed int -> float
|
||||
Float(fty) if signed => {
|
||||
ty::Float(fty) if signed => {
|
||||
let v = v as i128;
|
||||
match fty {
|
||||
FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value),
|
||||
|
@ -307,7 +304,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
}
|
||||
}
|
||||
// unsigned int -> float
|
||||
Float(fty) => match fty {
|
||||
ty::Float(fty) => match fty {
|
||||
FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value),
|
||||
FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),
|
||||
FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),
|
||||
|
@ -315,7 +312,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
},
|
||||
|
||||
// u8 -> char
|
||||
Char => Scalar::from_u32(u8::try_from(v).unwrap().into()),
|
||||
ty::Char => Scalar::from_u32(u8::try_from(v).unwrap().into()),
|
||||
|
||||
// Casts to bool are not permitted by rustc, no need to handle them here.
|
||||
_ => span_bug!(self.cur_span(), "invalid int to {} cast", cast_ty),
|
||||
|
@ -332,11 +329,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
+ FloatConvert<Double>
|
||||
+ FloatConvert<Quad>,
|
||||
{
|
||||
use rustc_type_ir::TyKind::*;
|
||||
|
||||
match *dest_ty.kind() {
|
||||
// float -> uint
|
||||
Uint(t) => {
|
||||
ty::Uint(t) => {
|
||||
let size = Integer::from_uint_ty(self, t).size();
|
||||
// `to_u128` is a saturating cast, which is what we need
|
||||
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
|
||||
|
@ -345,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
Scalar::from_uint(v, size)
|
||||
}
|
||||
// float -> int
|
||||
Int(t) => {
|
||||
ty::Int(t) => {
|
||||
let size = Integer::from_int_ty(self, t).size();
|
||||
// `to_i128` is a saturating cast, which is what we need
|
||||
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
|
||||
|
@ -353,7 +348,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
Scalar::from_int(v, size)
|
||||
}
|
||||
// float -> float
|
||||
Float(fty) => match fty {
|
||||
ty::Float(fty) => match fty {
|
||||
FloatTy::F16 => {
|
||||
Scalar::from_f16(self.adjust_nan(f.convert(&mut false).value, &[f]))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::hash::Hash;
|
|||
|
||||
use rustc_abi::{Align, Size};
|
||||
use rustc_apfloat::{Float, FloatConvert};
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
|
@ -21,7 +20,6 @@ use super::{
|
|||
AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation,
|
||||
CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind,
|
||||
Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup,
|
||||
throw_unsup_format,
|
||||
};
|
||||
|
||||
/// Data returned by [`Machine::after_stack_pop`], and consumed by
|
||||
|
@ -361,6 +359,19 @@ pub trait Machine<'tcx>: Sized {
|
|||
size: i64,
|
||||
) -> Option<(AllocId, Size, Self::ProvenanceExtra)>;
|
||||
|
||||
/// Return a "root" pointer for the given allocation: the one that is used for direct
|
||||
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
||||
///
|
||||
/// Not called on `extern` or thread-local statics (those use the methods above).
|
||||
///
|
||||
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when
|
||||
/// it's a global and `GLOBAL_KIND` is `None`.
|
||||
fn adjust_alloc_root_pointer(
|
||||
ecx: &InterpCx<'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// Called to adjust global allocations to the Provenance and AllocExtra of this machine.
|
||||
///
|
||||
/// If `alloc` contains pointers, then they are all pointing to globals.
|
||||
|
@ -375,11 +386,12 @@ pub trait Machine<'tcx>: Sized {
|
|||
alloc: &'b Allocation,
|
||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
|
||||
|
||||
/// Initialize the extra state of an allocation.
|
||||
/// Initialize the extra state of an allocation local to this machine.
|
||||
///
|
||||
/// This is guaranteed to be called exactly once on all allocations that are accessed by the
|
||||
/// program.
|
||||
fn init_alloc_extra(
|
||||
/// This is guaranteed to be called exactly once on all allocations local to this machine.
|
||||
/// It will not be called automatically for global allocations; `adjust_global_allocation`
|
||||
/// has to do that itself if that is desired.
|
||||
fn init_local_allocation(
|
||||
ecx: &InterpCx<'tcx, Self>,
|
||||
id: AllocId,
|
||||
kind: MemoryKind<Self::MemoryKind>,
|
||||
|
@ -387,34 +399,6 @@ pub trait Machine<'tcx>: Sized {
|
|||
align: Align,
|
||||
) -> InterpResult<'tcx, Self::AllocExtra>;
|
||||
|
||||
/// Return a "root" pointer for the given allocation: the one that is used for direct
|
||||
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
||||
///
|
||||
/// Not called on `extern` or thread-local statics (those use the methods above).
|
||||
///
|
||||
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when
|
||||
/// it's a global and `GLOBAL_KIND` is `None`.
|
||||
fn adjust_alloc_root_pointer(
|
||||
ecx: &InterpCx<'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// Evaluate the inline assembly.
|
||||
///
|
||||
/// This should take care of jumping to the next block (one of `targets`) when asm goto
|
||||
/// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
|
||||
/// naked_asm! or `InlineAsmOptions::NORETURN` being set.
|
||||
fn eval_inline_asm(
|
||||
_ecx: &mut InterpCx<'tcx, Self>,
|
||||
_template: &'tcx [InlineAsmTemplatePiece],
|
||||
_operands: &[mir::InlineAsmOperand<'tcx>],
|
||||
_options: InlineAsmOptions,
|
||||
_targets: &[mir::BasicBlock],
|
||||
) -> InterpResult<'tcx> {
|
||||
throw_unsup_format!("inline assembly is not supported")
|
||||
}
|
||||
|
||||
/// Hook for performing extra checks on a memory read access.
|
||||
///
|
||||
/// This will *not* be called during validation!
|
||||
|
@ -699,7 +683,7 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
|
|||
interp_ok(Cow::Borrowed(alloc))
|
||||
}
|
||||
|
||||
fn init_alloc_extra(
|
||||
fn init_local_allocation(
|
||||
_ecx: &InterpCx<$tcx, Self>,
|
||||
_id: AllocId,
|
||||
_kind: MemoryKind<Self::MemoryKind>,
|
||||
|
|
|
@ -263,9 +263,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
M::GLOBAL_KIND.map(MemoryKind::Machine),
|
||||
"dynamically allocating global memory"
|
||||
);
|
||||
// We have set things up so we don't need to call `adjust_from_tcx` here,
|
||||
// so we avoid copying the entire allocation contents.
|
||||
let extra = M::init_alloc_extra(self, id, kind, alloc.size(), alloc.align)?;
|
||||
// This cannot be merged with the `adjust_global_allocation` code path
|
||||
// since here we have an allocation that already uses `M::Bytes`.
|
||||
let extra = M::init_local_allocation(self, id, kind, alloc.size(), alloc.align)?;
|
||||
let alloc = alloc.with_extra(extra);
|
||||
self.memory.alloc_map.insert(id, (kind, alloc));
|
||||
M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
|
||||
|
|
|
@ -14,7 +14,7 @@ use tracing::{info, instrument, trace};
|
|||
|
||||
use super::{
|
||||
FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
|
||||
Projectable, Scalar, interp_ok, throw_ub,
|
||||
Projectable, Scalar, interp_ok, throw_ub, throw_unsup_format,
|
||||
};
|
||||
use crate::util;
|
||||
|
||||
|
@ -590,8 +590,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
terminator.kind
|
||||
),
|
||||
|
||||
InlineAsm { template, ref operands, options, ref targets, .. } => {
|
||||
M::eval_inline_asm(self, template, operands, options, targets)?;
|
||||
InlineAsm { .. } => {
|
||||
throw_unsup_format!("inline assembly is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ elsa = "1.11.0"
|
|||
ena = "0.14.3"
|
||||
indexmap = "2.4.0"
|
||||
jobserver_crate = { version = "0.1.28", package = "jobserver" }
|
||||
measureme = "11"
|
||||
measureme = "12.0.1"
|
||||
rustc-hash = "2.0.0"
|
||||
rustc-rayon = { version = "0.5.1", features = ["indexmap"] }
|
||||
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::fmt::Debug;
|
|||
use std::mem;
|
||||
use std::ops::{Bound, Index, IndexMut, RangeBounds};
|
||||
|
||||
use rustc_macros::{Decodable_Generic, Encodable_Generic};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
|
||||
|
||||
use crate::stable_hasher::{HashStable, StableHasher, StableOrd};
|
||||
|
||||
|
@ -20,7 +20,7 @@ pub use index_map::SortedIndexMultiMap;
|
|||
/// stores data in a more compact way. It also supports accessing contiguous
|
||||
/// ranges of elements as a slice, and slices of already sorted elements can be
|
||||
/// inserted efficiently.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable_Generic, Decodable_Generic)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable_NoContext, Decodable_NoContext)]
|
||||
pub struct SortedMap<K, V> {
|
||||
data: Vec<(K, V)>,
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use rustc_macros::{Decodable_Generic, Encodable_Generic};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
|
||||
|
||||
use crate::fingerprint::Fingerprint;
|
||||
use crate::stable_hasher;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable_Generic, Decodable_Generic, Hash)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable_NoContext, Decodable_NoContext, Hash)]
|
||||
pub struct Svh {
|
||||
hash: Fingerprint,
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::iter::{Product, Sum};
|
|||
use std::ops::Index;
|
||||
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustc_macros::{Decodable_Generic, Encodable_Generic};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
|
||||
|
||||
use crate::fingerprint::Fingerprint;
|
||||
use crate::stable_hasher::{HashStable, StableCompare, StableHasher, ToStableHashKey};
|
||||
|
@ -224,7 +224,7 @@ trait UnordCollection {}
|
|||
///
|
||||
/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
|
||||
/// for more information.
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Encodable_Generic, Decodable_Generic)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Encodable_NoContext, Decodable_NoContext)]
|
||||
pub struct UnordSet<V: Eq + Hash> {
|
||||
inner: FxHashSet<V>,
|
||||
}
|
||||
|
@ -259,6 +259,12 @@ impl<V: Eq + Hash> UnordSet<V> {
|
|||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
/// If the set has only one element, returns it, otherwise returns `None`.
|
||||
#[inline]
|
||||
pub fn get_only(&self) -> Option<&V> {
|
||||
if self.inner.len() == 1 { self.inner.iter().next() } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn insert(&mut self, v: V) -> bool {
|
||||
self.inner.insert(v)
|
||||
|
@ -415,7 +421,7 @@ impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordSet<V> {
|
|||
///
|
||||
/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
|
||||
/// for more information.
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Encodable_Generic, Decodable_Generic)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Encodable_NoContext, Decodable_NoContext)]
|
||||
pub struct UnordMap<K: Eq + Hash, V> {
|
||||
inner: FxHashMap<K, V>,
|
||||
}
|
||||
|
@ -639,7 +645,7 @@ impl<HCX, K: Hash + Eq + HashStable<HCX>, V: HashStable<HCX>> HashStable<HCX> fo
|
|||
///
|
||||
/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
|
||||
/// for more information.
|
||||
#[derive(Default, Debug, Eq, PartialEq, Clone, Encodable_Generic, Decodable_Generic)]
|
||||
#[derive(Default, Debug, Eq, PartialEq, Clone, Encodable_NoContext, Decodable_NoContext)]
|
||||
pub struct UnordBag<V> {
|
||||
inner: Vec<V>,
|
||||
}
|
||||
|
|
|
@ -457,8 +457,7 @@ pub enum Compilation {
|
|||
fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) {
|
||||
// Allow "E0123" or "0123" form.
|
||||
let upper_cased_code = code.to_ascii_uppercase();
|
||||
let start = if upper_cased_code.starts_with('E') { 1 } else { 0 };
|
||||
if let Ok(code) = upper_cased_code[start..].parse::<u32>()
|
||||
if let Ok(code) = upper_cased_code.strip_prefix('E').unwrap_or(&upper_cased_code).parse::<u32>()
|
||||
&& let Ok(description) = registry.try_find_description(ErrCode::from_u32(code))
|
||||
{
|
||||
let mut is_in_code_block = false;
|
||||
|
@ -649,10 +648,10 @@ fn print_crate_info(
|
|||
HostTuple => println_info!("{}", rustc_session::config::host_tuple()),
|
||||
Sysroot => println_info!("{}", sess.sysroot.display()),
|
||||
TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
|
||||
TargetSpec => {
|
||||
TargetSpecJson => {
|
||||
println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
|
||||
}
|
||||
AllTargetSpecs => {
|
||||
AllTargetSpecsJson => {
|
||||
let mut targets = BTreeMap::new();
|
||||
for name in rustc_target::spec::TARGETS {
|
||||
let triple = TargetTuple::from_tuple(name);
|
||||
|
|
|
@ -106,8 +106,8 @@ impl From<Vec<FluentError>> for TranslationBundleError {
|
|||
/// (overriding any conflicting messages).
|
||||
#[instrument(level = "trace")]
|
||||
pub fn fluent_bundle(
|
||||
mut user_provided_sysroot: Option<PathBuf>,
|
||||
mut sysroot_candidates: Vec<PathBuf>,
|
||||
sysroot: PathBuf,
|
||||
sysroot_candidates: Vec<PathBuf>,
|
||||
requested_locale: Option<LanguageIdentifier>,
|
||||
additional_ftl_path: Option<&Path>,
|
||||
with_directionality_markers: bool,
|
||||
|
@ -141,7 +141,7 @@ pub fn fluent_bundle(
|
|||
// If the user requests the default locale then don't try to load anything.
|
||||
if let Some(requested_locale) = requested_locale {
|
||||
let mut found_resources = false;
|
||||
for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) {
|
||||
for mut sysroot in Some(sysroot).into_iter().chain(sysroot_candidates.into_iter()) {
|
||||
sysroot.push("share");
|
||||
sysroot.push("locale");
|
||||
sysroot.push(requested_locale.to_string());
|
||||
|
|
|
@ -297,7 +297,9 @@ pub trait Emitter: Translate {
|
|||
// are some which do actually involve macros.
|
||||
ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
|
||||
|
||||
ExpnKind::Macro(macro_kind, name) => Some((macro_kind, name)),
|
||||
ExpnKind::Macro(macro_kind, name) => {
|
||||
Some((macro_kind, name, expn_data.hide_backtrace))
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -309,13 +311,17 @@ pub trait Emitter: Translate {
|
|||
self.render_multispans_macro_backtrace(span, children, backtrace);
|
||||
|
||||
if !backtrace {
|
||||
if let Some((macro_kind, name)) = has_macro_spans.first() {
|
||||
// Skip builtin macros, as their expansion isn't relevant to the end user. This includes
|
||||
// actual intrinsics, like `asm!`.
|
||||
if let Some((macro_kind, name, _)) = has_macro_spans.first()
|
||||
&& let Some((_, _, false)) = has_macro_spans.last()
|
||||
{
|
||||
// Mark the actual macro this originates from
|
||||
let and_then = if let Some((macro_kind, last_name)) = has_macro_spans.last()
|
||||
let and_then = if let Some((macro_kind, last_name, _)) = has_macro_spans.last()
|
||||
&& last_name != name
|
||||
{
|
||||
let descr = macro_kind.descr();
|
||||
format!(" which comes from the expansion of the {descr} `{last_name}`",)
|
||||
format!(" which comes from the expansion of the {descr} `{last_name}`")
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
|
|
@ -889,16 +889,16 @@ impl SyntaxExtension {
|
|||
})
|
||||
.unwrap_or_else(|| (None, helper_attrs));
|
||||
|
||||
let stability = find_attr!(attrs, AttributeKind::Stability{stability, ..} => *stability);
|
||||
let stability = find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability);
|
||||
|
||||
// FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
|
||||
if let Some(sp) = find_attr!(attrs, AttributeKind::ConstStability{span, ..} => *span) {
|
||||
if let Some(sp) = find_attr!(attrs, AttributeKind::ConstStability { span, .. } => *span) {
|
||||
sess.dcx().emit_err(errors::MacroConstStability {
|
||||
span: sp,
|
||||
head_span: sess.source_map().guess_head_span(span),
|
||||
});
|
||||
}
|
||||
if let Some(sp) = find_attr!(attrs, AttributeKind::BodyStability{span, ..} => *span) {
|
||||
if let Some(sp) = find_attr!(attrs, AttributeKind::BodyStability{ span, .. } => *span) {
|
||||
sess.dcx().emit_err(errors::MacroBodyStability {
|
||||
span: sp,
|
||||
head_span: sess.source_map().guess_head_span(span),
|
||||
|
@ -912,7 +912,10 @@ impl SyntaxExtension {
|
|||
// FIXME(jdonszelmann): avoid the into_iter/collect?
|
||||
.then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
|
||||
stability,
|
||||
deprecation: find_attr!(attrs, AttributeKind::Deprecation{deprecation, ..} => *deprecation),
|
||||
deprecation: find_attr!(
|
||||
attrs,
|
||||
AttributeKind::Deprecation { deprecation, .. } => *deprecation
|
||||
),
|
||||
helper_attrs,
|
||||
edition,
|
||||
builtin_name,
|
||||
|
@ -1000,6 +1003,7 @@ impl SyntaxExtension {
|
|||
self.allow_internal_unsafe,
|
||||
self.local_inner_macros,
|
||||
self.collapse_debuginfo,
|
||||
self.builtin_name.is_some(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,8 +394,8 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
|
|||
symbol,
|
||||
suffix,
|
||||
span,
|
||||
}) if symbol.as_str().starts_with('-') => {
|
||||
let symbol = Symbol::intern(&symbol.as_str()[1..]);
|
||||
}) if let Some(symbol) = symbol.as_str().strip_prefix('-') => {
|
||||
let symbol = Symbol::intern(symbol);
|
||||
let integer = TokenKind::lit(token::Integer, symbol, suffix);
|
||||
let a = tokenstream::TokenTree::token_joint_hidden(Minus, span);
|
||||
let b = tokenstream::TokenTree::token_alone(integer, span);
|
||||
|
@ -406,8 +406,8 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
|
|||
symbol,
|
||||
suffix,
|
||||
span,
|
||||
}) if symbol.as_str().starts_with('-') => {
|
||||
let symbol = Symbol::intern(&symbol.as_str()[1..]);
|
||||
}) if let Some(symbol) = symbol.as_str().strip_prefix('-') => {
|
||||
let symbol = Symbol::intern(symbol);
|
||||
let float = TokenKind::lit(token::Float, symbol, suffix);
|
||||
let a = tokenstream::TokenTree::token_joint_hidden(Minus, span);
|
||||
let b = tokenstream::TokenTree::token_alone(float, span);
|
||||
|
|
|
@ -62,6 +62,8 @@ declare_features! (
|
|||
(accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553)),
|
||||
/// Allows using `const` operands in inline assembly.
|
||||
(accepted, asm_const, "1.82.0", Some(93332)),
|
||||
/// Allows using `label` operands in inline assembly.
|
||||
(accepted, asm_goto, "CURRENT_RUSTC_VERSION", Some(119364)),
|
||||
/// Allows using `sym` operands in inline assembly.
|
||||
(accepted, asm_sym, "1.66.0", Some(93333)),
|
||||
/// Allows the definition of associated constants in `trait` or `impl` blocks.
|
||||
|
|
|
@ -372,8 +372,6 @@ declare_features! (
|
|||
(unstable, asm_experimental_arch, "1.58.0", Some(93335)),
|
||||
/// Enables experimental register support in inline assembly.
|
||||
(unstable, asm_experimental_reg, "1.85.0", Some(133416)),
|
||||
/// Allows using `label` operands in inline assembly.
|
||||
(unstable, asm_goto, "1.78.0", Some(119364)),
|
||||
/// Allows using `label` operands in inline assembly together with output operands.
|
||||
(unstable, asm_goto_with_outputs, "1.85.0", Some(119364)),
|
||||
/// Allows the `may_unwind` option in inline assembly.
|
||||
|
|
|
@ -3373,13 +3373,16 @@ pub struct OpaqueTy<'hir> {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub enum PreciseCapturingArg<'hir> {
|
||||
Lifetime(&'hir Lifetime),
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum PreciseCapturingArgKind<T, U> {
|
||||
Lifetime(T),
|
||||
/// Non-lifetime argument (type or const)
|
||||
Param(PreciseCapturingNonLifetimeArg),
|
||||
Param(U),
|
||||
}
|
||||
|
||||
pub type PreciseCapturingArg<'hir> =
|
||||
PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;
|
||||
|
||||
impl PreciseCapturingArg<'_> {
|
||||
pub fn hir_id(self) -> HirId {
|
||||
match self {
|
||||
|
|
|
@ -28,7 +28,6 @@ rustc_session = { path = "../rustc_session" }
|
|||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
rustc_type_ir = { path = "../rustc_type_ir" }
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
tracing = "0.1"
|
||||
# tidy-alphabetical-end
|
||||
|
|
|
@ -18,18 +18,17 @@ use rustc_middle::hir::nested_filter;
|
|||
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::ty::error::TypeErrorToStringExt;
|
||||
use rustc_middle::ty::fold::{BottomUpFolder, fold_regions};
|
||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
use rustc_middle::ty::{
|
||||
AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
AdtDef, BottomUpFolder, GenericArgKind, RegionKind, TypeFoldable, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, fold_regions,
|
||||
};
|
||||
use rustc_session::lint::builtin::UNINHABITED_STATIC;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
use tracing::{debug, instrument};
|
||||
use ty::TypingMode;
|
||||
use {rustc_attr_parsing as attr, rustc_hir as hir};
|
||||
|
@ -1715,7 +1714,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, opaque_def_id: LocalDefId) -> ErrorG
|
|||
opaques: Vec<DefId>,
|
||||
closures: Vec<DefId>,
|
||||
}
|
||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
|
||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||
match *t.kind() {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
|
||||
|
|
|
@ -12,10 +12,9 @@ use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisi
|
|||
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::util::ExplicitSelf;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
|
||||
self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
|
||||
TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
|
|
|
@ -84,6 +84,7 @@ use rustc_infer::infer::{self, TyCtxtInferExt as _};
|
|||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::print::with_types_for_signature;
|
||||
use rustc_middle::ty::{self, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypingMode};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::parse::feature_err;
|
||||
|
@ -152,10 +153,9 @@ pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDef
|
|||
}
|
||||
|
||||
// If `#[link_section]` is missing, then nothing to verify
|
||||
let attrs = tcx.codegen_fn_attrs(id);
|
||||
if attrs.link_section.is_none() {
|
||||
let Some(link_section) = tcx.codegen_fn_attrs(id).link_section else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// For the wasm32 target statics with `#[link_section]` other than `.init_array`
|
||||
// are placed into custom sections of the final output file, but this isn't like
|
||||
|
@ -181,11 +181,8 @@ pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDef
|
|||
// continue to work, but would no longer be necessary.
|
||||
|
||||
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
|
||||
&& alloc.inner().provenance().ptrs().len() != 0
|
||||
&& attrs
|
||||
.link_section
|
||||
.map(|link_section| !link_section.as_str().starts_with(".init_array"))
|
||||
.unwrap()
|
||||
&& !alloc.inner().provenance().ptrs().is_empty()
|
||||
&& !link_section.as_str().starts_with(".init_array")
|
||||
{
|
||||
let msg = "statics with a custom `#[link_section]` must be a \
|
||||
simple list of bytes on the wasm target with no \
|
||||
|
@ -240,11 +237,11 @@ fn missing_items_err(
|
|||
(Vec::new(), Vec::new(), Vec::new());
|
||||
|
||||
for &trait_item in missing_items {
|
||||
let snippet = suggestion_signature(
|
||||
let snippet = with_types_for_signature!(suggestion_signature(
|
||||
tcx,
|
||||
trait_item,
|
||||
tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(),
|
||||
);
|
||||
));
|
||||
let code = format!("{padding}{snippet}\n{padding}");
|
||||
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
|
||||
missing_trait_item_label
|
||||
|
|
|
@ -16,10 +16,12 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION;
|
|||
use rustc_macros::LintDiagnostic;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::traits::solve::NoSolution;
|
||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
|
||||
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
|
||||
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags,
|
||||
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
|
||||
Upcast,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::parse::feature_err;
|
||||
|
@ -34,8 +36,6 @@ use rustc_trait_selection::traits::{
|
|||
self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||
WellFormedLoc,
|
||||
};
|
||||
use rustc_type_ir::TypeFlags;
|
||||
use rustc_type_ir::solve::NoSolution;
|
||||
use tracing::{debug, instrument};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
|
@ -1520,7 +1520,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
|||
struct CountParams {
|
||||
params: FxHashSet<u32>,
|
||||
}
|
||||
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for CountParams {
|
||||
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for CountParams {
|
||||
type Result = ControlFlow<()>;
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||
if let ty::Param(param) = t.kind() {
|
||||
|
|
|
@ -250,13 +250,16 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
// trait, they *do* satisfy the repr(transparent) rules, and then we assume that everything else
|
||||
// in the compiler (in particular, all the call ABI logic) will treat them as repr(transparent)
|
||||
// even if they do not carry that attribute.
|
||||
use rustc_type_ir::TyKind::*;
|
||||
match (source.kind(), target.kind()) {
|
||||
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if r_a == *r_b && mutbl_a == *mutbl_b => {
|
||||
(&ty::Ref(r_a, _, mutbl_a), ty::Ref(r_b, _, mutbl_b))
|
||||
if r_a == *r_b && mutbl_a == *mutbl_b =>
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
||||
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
||||
(&ty::RawPtr(_, a_mutbl), &ty::RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
||||
(&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
|
||||
if def_a.is_struct() && def_b.is_struct() =>
|
||||
{
|
||||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.did());
|
||||
let target_path = tcx.def_path_str(def_b.did());
|
||||
|
|
|
@ -10,10 +10,9 @@ use rustc_errors::struct_span_code_err;
|
|||
use rustc_hir::LangItem;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, elaborate};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{ErrorGuaranteed, sym};
|
||||
use rustc_type_ir::elaborate;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::check::always_applicable;
|
||||
|
|
|
@ -28,14 +28,13 @@ use rustc_errors::{
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
|
||||
use rustc_hir::{self as hir, GenericParamKind, HirId, Node};
|
||||
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode};
|
||||
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode, fold_regions};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
|
||||
|
@ -1791,7 +1790,7 @@ fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueT
|
|||
fn rendered_precise_capturing_args<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> Option<&'tcx [Symbol]> {
|
||||
) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
|
||||
if let Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
|
||||
tcx.opt_rpitit_info(def_id.to_def_id())
|
||||
{
|
||||
|
@ -1800,7 +1799,12 @@ fn rendered_precise_capturing_args<'tcx>(
|
|||
|
||||
tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
|
||||
hir::GenericBound::Use(args, ..) => {
|
||||
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
|
||||
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| match arg {
|
||||
PreciseCapturingArgKind::Lifetime(_) => {
|
||||
PreciseCapturingArgKind::Lifetime(arg.name())
|
||||
}
|
||||
PreciseCapturingArgKind::Param(_) => PreciseCapturingArgKind::Param(arg.name()),
|
||||
})))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::fold::shift_vars;
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
Upcast, shift_vars,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_type_ir::Upcast;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::ItemCtxt;
|
||||
|
|
|
@ -5,10 +5,9 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||
use rustc_hir::intravisit::VisitorExt;
|
||||
use rustc_hir::{self as hir, AmbigArg, HirId};
|
||||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span};
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
|
|
|
@ -7,10 +7,10 @@ use std::assert_matches::debug_assert_matches;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
|
||||
type RemapTable = FxHashMap<u32, u32>;
|
||||
|
||||
|
|
|
@ -8,10 +8,12 @@ use rustc_hir::HirId;
|
|||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt, Upcast};
|
||||
use rustc_middle::ty::{
|
||||
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
TypeVisitor, Upcast,
|
||||
};
|
||||
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use smallvec::SmallVec;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
|
@ -4,15 +4,14 @@ use rustc_errors::struct_span_code_err;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::elaborate::ClauseWithSupertraitSpan;
|
||||
use rustc_middle::ty::{
|
||||
self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
|
||||
self, BottomUpFolder, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
|
||||
TypeVisitableExt, Upcast,
|
||||
};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
|
||||
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
|
||||
use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
|
@ -901,12 +901,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.iter()
|
||||
.map(|(item, _)| format!("{} = Type", item.name))
|
||||
.collect();
|
||||
let code = if snippet.ends_with('>') {
|
||||
let code = if let Some(snippet) = snippet.strip_suffix('>') {
|
||||
// The user wrote `Trait<'a>` or similar and we don't have a type we can
|
||||
// suggest, but at least we can clue them to the correct syntax
|
||||
// `Trait<'a, Item = Type>` while accounting for the `<'a>` in the
|
||||
// suggestion.
|
||||
format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", "))
|
||||
format!("{}, {}>", snippet, types.join(", "))
|
||||
} else if in_expr_or_pat {
|
||||
// The user wrote `Iterator`, so we don't have a type we can suggest, but at
|
||||
// least we can clue them to the correct syntax `Iterator::<Item = Type>`.
|
||||
|
|
|
@ -411,14 +411,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
Applicability::MachineApplicable,
|
||||
);
|
||||
if !is_dyn_compatible {
|
||||
diag.note(format!("`{trait_name}` it is dyn-incompatible, so it can't be `dyn`"));
|
||||
diag.note(format!(
|
||||
"`{trait_name}` is dyn-incompatible, otherwise a trait object could be used"
|
||||
));
|
||||
} else {
|
||||
// No ampersand in suggestion if it's borrowed already
|
||||
let (dyn_str, paren_dyn_str) =
|
||||
if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") };
|
||||
|
||||
let sugg = if let hir::TyKind::TraitObject([_, _, ..], _) = self_ty.kind {
|
||||
// There are more than one trait bound, we need surrounding parentheses.
|
||||
// There is more than one trait bound, we need surrounding parentheses.
|
||||
vec![
|
||||
(self_ty.span.shrink_to_lo(), paren_dyn_str.to_string()),
|
||||
(self_ty.span.shrink_to_hi(), ")".to_string()),
|
||||
|
|
|
@ -36,11 +36,10 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
|||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::middle::stability::AllowUnstable;
|
||||
use rustc_middle::mir::interpret::LitToConstInput;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
|
||||
use rustc_middle::ty::{
|
||||
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
|
||||
TypeVisitableExt, TypingMode,
|
||||
TypeVisitableExt, TypingMode, Upcast, fold_regions,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||
|
@ -50,7 +49,6 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
|||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use rustc_type_ir::Upcast;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use self::errors::assoc_kind_str;
|
||||
|
|
|
@ -4,8 +4,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
|||
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::fold::fold_regions;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypingMode};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypingMode, fold_regions};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use tracing::debug;
|
||||
|
|
|
@ -252,7 +252,9 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
|||
// def-ID that will be used to determine the traits/predicates in
|
||||
// scope. This is derived from the enclosing item-like thing.
|
||||
let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id);
|
||||
collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty)
|
||||
collect::ItemCtxt::new(tcx, env_def_id.def_id)
|
||||
.lowerer()
|
||||
.lower_ty_maybe_return_type_notation(hir_ty)
|
||||
}
|
||||
|
||||
/// This is for rustdoc.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_middle::ty::outlives::{Component, push_outlives_components};
|
||||
use rustc_middle::ty::{self, GenericArg, GenericArgKind, Region, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::outlives::{Component, push_outlives_components};
|
||||
use smallvec::smallvec;
|
||||
|
||||
/// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
|
||||
|
|
|
@ -2148,9 +2148,11 @@ impl<'a> State<'a> {
|
|||
s.print_implicit_self(&decl.implicit_self);
|
||||
} else {
|
||||
if let Some(arg_name) = arg_names.get(i) {
|
||||
s.word(arg_name.to_string());
|
||||
s.word(":");
|
||||
s.space();
|
||||
if arg_name.name != kw::Empty {
|
||||
s.word(arg_name.to_string());
|
||||
s.word(":");
|
||||
s.space();
|
||||
}
|
||||
} else if let Some(body_id) = body_id {
|
||||
s.ann.nested(s, Nested::BodyParamPat(body_id, i));
|
||||
s.word(":");
|
||||
|
|
|
@ -23,7 +23,6 @@ rustc_middle = { path = "../rustc_middle" }
|
|||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
rustc_type_ir = { path = "../rustc_type_ir" }
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
tracing = "0.1"
|
||||
# tidy-alphabetical-end
|
||||
|
|
|
@ -32,6 +32,7 @@ use rustc_ast::util::parser::ExprPrecedence;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{self as hir, ExprKind};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||
|
@ -39,13 +40,12 @@ use rustc_middle::mir::Mutability;
|
|||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::cast::{CastKind, CastTy};
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef, elaborate};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::{DUMMY_SP, Span, sym};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_type_ir::elaborate;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::FnCtxt;
|
||||
|
@ -155,7 +155,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
enum CastError<'tcx> {
|
||||
ErrorGuaranteed(ErrorGuaranteed),
|
||||
|
||||
|
@ -182,6 +182,7 @@ enum CastError<'tcx> {
|
|||
/// when we're typechecking a type parameter with a ?Sized bound.
|
||||
IntToWideCast(Option<&'static str>),
|
||||
ForeignNonExhaustiveAdt,
|
||||
PtrPtrAddingAutoTrait(Vec<DefId>),
|
||||
}
|
||||
|
||||
impl From<ErrorGuaranteed> for CastError<'_> {
|
||||
|
@ -596,6 +597,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
.with_note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate")
|
||||
.emit();
|
||||
}
|
||||
CastError::PtrPtrAddingAutoTrait(added) => {
|
||||
fcx.dcx().emit_err(errors::PtrCastAddAutoToObject {
|
||||
span: self.span,
|
||||
traits_len: added.len(),
|
||||
traits: {
|
||||
let mut traits: Vec<_> = added
|
||||
.into_iter()
|
||||
.map(|trait_did| fcx.tcx.def_path_str(trait_did))
|
||||
.collect();
|
||||
|
||||
traits.sort();
|
||||
traits.into()
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,19 +956,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
if !added.is_empty() {
|
||||
tcx.dcx().emit_err(errors::PtrCastAddAutoToObject {
|
||||
span: self.span,
|
||||
traits_len: added.len(),
|
||||
traits: {
|
||||
let mut traits: Vec<_> = added
|
||||
.into_iter()
|
||||
.map(|trait_did| tcx.def_path_str(trait_did))
|
||||
.collect();
|
||||
|
||||
traits.sort();
|
||||
traits.into()
|
||||
},
|
||||
});
|
||||
return Err(CastError::PtrPtrAddingAutoTrait(added));
|
||||
}
|
||||
|
||||
Ok(CastKind::PtrPtrCast)
|
||||
|
|
|
@ -12,13 +12,14 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk,
|
|||
use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
|
||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_middle::ty::{
|
||||
self, ClosureKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::ArgKind;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_type_ir::ClosureKind;
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use super::{CoroutineTypes, Expectation, FnCtxt, check_fn};
|
||||
|
|
|
@ -55,8 +55,7 @@ use rustc_middle::ty::adjustment::{
|
|||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
|
||||
};
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, AliasTy, GenericArgsRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, AliasTy, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue