Merge from rustc
This commit is contained in:
commit
f655289d49
209 changed files with 2057 additions and 1024 deletions
4
.github/workflows/ghcr.yml
vendored
4
.github/workflows/ghcr.yml
vendored
|
|
@ -53,9 +53,9 @@ jobs:
|
|||
run: |
|
||||
# List of DockerHub images to mirror to ghcr.io
|
||||
images=(
|
||||
# Mirrored because used by the mingw-check-tidy, which doesn't cache Docker images
|
||||
# Mirrored because used by the tidy job, which doesn't cache Docker images
|
||||
"ubuntu:22.04"
|
||||
# Mirrored because used by all linux CI jobs, including mingw-check-tidy
|
||||
# Mirrored because used by all linux CI jobs, including tidy
|
||||
"moby/buildkit:buildx-stable-1"
|
||||
# Mirrored because used when CI is running inside a Docker container
|
||||
"alpine:3.4"
|
||||
|
|
|
|||
23
.github/workflows/spellcheck.yml
vendored
Normal file
23
.github/workflows/spellcheck.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# This workflow runs spellcheck job
|
||||
|
||||
name: Spellcheck
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
jobs:
|
||||
spellcheck:
|
||||
name: run spellchecker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: check typos
|
||||
# sync version with src/tools/tidy/src/ext_tool_checks.rs in spellcheck_runner
|
||||
uses: crate-ci/typos@v1.34.0
|
||||
with:
|
||||
# sync target files with src/tools/tidy/src/ext_tool_checks.rs in check_impl
|
||||
files: ./compiler ./library ./src/bootstrap ./src/librustdoc
|
||||
config: ./typos.toml
|
||||
206
Cargo.lock
206
Cargo.lock
|
|
@ -128,9 +128,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle-svg"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c681338396641f4e32a29f045d0c70950da7207b4376685b51396c481ee36f1a"
|
||||
checksum = "0a43964079ef399480603125d5afae2b219aceffb77478956e25f17b9bc3435c"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-lossy",
|
||||
|
|
@ -204,7 +204,7 @@ dependencies = [
|
|||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -221,9 +221,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
|
|
@ -341,9 +341,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.18.1"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
|
|
@ -546,7 +546,7 @@ dependencies = [
|
|||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -579,7 +579,7 @@ dependencies = [
|
|||
"rustc_tools_util 0.4.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"tempfile",
|
||||
"termize",
|
||||
"tokio",
|
||||
|
|
@ -673,7 +673,7 @@ dependencies = [
|
|||
"eyre",
|
||||
"indenter",
|
||||
"once_cell",
|
||||
"owo-colors 4.2.1",
|
||||
"owo-colors 4.2.2",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
|
|
@ -695,7 +695,7 @@ dependencies = [
|
|||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -705,7 +705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"owo-colors 4.2.1",
|
||||
"owo-colors 4.2.2",
|
||||
"tracing-core",
|
||||
"tracing-error",
|
||||
]
|
||||
|
|
@ -922,7 +922,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -933,7 +933,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
|||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -959,13 +959,13 @@ version = "0.1.90"
|
|||
|
||||
[[package]]
|
||||
name = "derive-where"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e73f2692d4bd3cac41dca28934a39894200c9fabf49586d77d0e5954af1d7902"
|
||||
checksum = "510c292c8cf384b1a340b816a9a6cf2599eb8f566a44949024af88418000c50b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -986,7 +986,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -996,7 +996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1008,7 +1008,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1098,7 +1098,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1168,12 +1168,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
|
||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1378,7 +1378,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1812,7 +1812,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1878,9 +1878,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
|
|
@ -2008,7 +2008,7 @@ checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2152,9 +2152,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
|||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
|
@ -2279,7 +2279,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2691,9 +2691,9 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
|||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "4.2.1"
|
||||
version = "4.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec"
|
||||
checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e"
|
||||
|
||||
[[package]]
|
||||
name = "pad"
|
||||
|
|
@ -2770,9 +2770,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6"
|
||||
checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror 2.0.12",
|
||||
|
|
@ -2781,9 +2781,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5"
|
||||
checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
|
|
@ -2791,24 +2791,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841"
|
||||
checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0"
|
||||
checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha2",
|
||||
]
|
||||
|
|
@ -2994,9 +2993,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
|
|
@ -3218,14 +3217,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-build-sysroot"
|
||||
version = "0.5.8"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc"
|
||||
checksum = "fdb13874a0e55baf4ac3d49d38206aecb31a55b75d6c4d04fd850b53942c8cc8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"regex",
|
||||
"rustc_version",
|
||||
"tempfile",
|
||||
"toml 0.8.23",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
|
|
@ -3814,7 +3813,7 @@ dependencies = [
|
|||
"fluent-syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
|
|
@ -3963,7 +3962,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4110,7 +4109,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -4629,6 +4628,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_attr_data_structures",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
|
|
@ -4722,7 +4722,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -4813,7 +4813,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4950,7 +4950,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5025,12 +5025,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
|||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
|
|
@ -5190,9 +5187,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.103"
|
||||
version = "2.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -5207,7 +5204,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5340,7 +5337,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5351,7 +5348,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5481,7 +5478,20 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
"toml_edit 0.19.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5506,6 +5516,26 @@ dependencies = [
|
|||
"winnow 0.5.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_write",
|
||||
"winnow 0.7.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_write"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
|
|
@ -5520,13 +5550,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.29"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
|
||||
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5703,7 +5733,7 @@ checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5"
|
|||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
|
|
@ -5915,7 +5945,7 @@ dependencies = [
|
|||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -5937,7 +5967,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -6205,7 +6235,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6216,7 +6246,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6227,7 +6257,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6238,7 +6268,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6612,9 +6642,9 @@ version = "0.1.1"
|
|||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"
|
||||
checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rustix",
|
||||
|
|
@ -6670,7 +6700,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6682,28 +6712,28 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.25"
|
||||
version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
|
||||
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.25"
|
||||
version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
|
||||
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6723,7 +6753,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6768,7 +6798,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6779,5 +6809,5 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.103",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ path = [
|
|||
"rustfmt.toml",
|
||||
"rust-bors.toml",
|
||||
"triagebot.toml",
|
||||
"typos.toml",
|
||||
"x",
|
||||
"x.ps1",
|
||||
"x.py",
|
||||
|
|
|
|||
|
|
@ -1341,7 +1341,7 @@ impl Expr {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an expression with (when possible) *one* outter brace removed
|
||||
/// Returns an expression with (when possible) *one* outer brace removed
|
||||
pub fn maybe_unwrap_block(&self) -> &Expr {
|
||||
if let ExprKind::Block(block, None) = &self.kind
|
||||
&& let [stmt] = block.stmts.as_slice()
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
)?
|
||||
|
||||
// Methods in this trait have one of three forms, with the last two forms
|
||||
// only occuring on `MutVisitor`:
|
||||
// only occurring on `MutVisitor`:
|
||||
//
|
||||
// fn visit_t(&mut self, t: &mut T); // common
|
||||
// fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::AssocCtxt;
|
||||
use rustc_ast::*;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
|
||||
use rustc_hir::def::{DefKind, PerNS, Res};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||
|
|
@ -1621,7 +1622,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let safety = self.lower_safety(h.safety, default_safety);
|
||||
|
||||
// Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
|
||||
let safety = if attrs.iter().any(|attr| attr.has_name(sym::target_feature))
|
||||
let safety = if find_attr!(attrs, AttributeKind::TargetFeature { .. })
|
||||
&& safety.is_safe()
|
||||
&& !self.tcx.sess.target.is_like_wasm
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
ast_passes_abi_cannot_be_coroutine =
|
||||
functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`
|
||||
.suggestion = remove the `{$coroutine_kind_str}` keyword from this definiton
|
||||
.suggestion = remove the `{$coroutine_kind_str}` keyword from this definition
|
||||
|
||||
ast_passes_abi_custom_safe_foreign_function =
|
||||
foreign functions with the "custom" ABI cannot be safe
|
||||
|
|
|
|||
|
|
@ -198,10 +198,10 @@ pub enum AttributeKind {
|
|||
Align { align: Align, span: Span },
|
||||
|
||||
/// Represents `#[rustc_allow_const_fn_unstable]`.
|
||||
AllowConstFnUnstable(ThinVec<Symbol>),
|
||||
AllowConstFnUnstable(ThinVec<Symbol>, Span),
|
||||
|
||||
/// Represents `#[allow_internal_unstable]`.
|
||||
AllowInternalUnstable(ThinVec<(Symbol, Span)>),
|
||||
AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span),
|
||||
|
||||
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
||||
AsPtr(Span),
|
||||
|
|
@ -309,6 +309,9 @@ pub enum AttributeKind {
|
|||
span: Span,
|
||||
},
|
||||
|
||||
/// Represents `#[target_feature(enable = "...")]`
|
||||
TargetFeature(ThinVec<(Symbol, Span)>, Span),
|
||||
|
||||
/// Represents `#[track_caller]`
|
||||
TrackCaller(Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ impl AttributeKind {
|
|||
RustcLayoutScalarValidRangeStart(..) => Yes,
|
||||
RustcObjectLifetimeDefault => No,
|
||||
SkipDuringMethodDispatch { .. } => No,
|
||||
TargetFeature(..) => No,
|
||||
TrackCaller(..) => Yes,
|
||||
Used { .. } => No,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ pub(crate) struct AllowInternalUnstableParser;
|
|||
impl<S: Stage> CombineAttributeParser<S> for AllowInternalUnstableParser {
|
||||
const PATH: &[Symbol] = &[sym::allow_internal_unstable];
|
||||
type Item = (Symbol, Span);
|
||||
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowInternalUnstable;
|
||||
const CONVERT: ConvertFn<Self::Item> =
|
||||
|items, span| AttributeKind::AllowInternalUnstable(items, span);
|
||||
const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ...");
|
||||
|
||||
fn extend<'c>(
|
||||
|
|
@ -30,7 +31,8 @@ pub(crate) struct AllowConstFnUnstableParser;
|
|||
impl<S: Stage> CombineAttributeParser<S> for AllowConstFnUnstableParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_allow_const_fn_unstable];
|
||||
type Item = Symbol;
|
||||
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowConstFnUnstable;
|
||||
const CONVERT: ConvertFn<Self::Item> =
|
||||
|items, first_span| AttributeKind::AllowConstFnUnstable(items, first_span);
|
||||
const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ...");
|
||||
|
||||
fn extend<'c>(
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use crate::{fluent_generated, parse_version};
|
|||
|
||||
/// Emitter of a builtin lint from `cfg_matches`.
|
||||
///
|
||||
/// Used to support emiting a lint (currently on check-cfg), either:
|
||||
/// Used to support emitting a lint (currently on check-cfg), either:
|
||||
/// - as an early buffered lint (in `rustc`)
|
||||
/// - or has a "normal" lint from HIR (in `rustdoc`)
|
||||
pub trait CfgMatchesLintEmitter {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use rustc_session::parse::feature_err;
|
|||
use rustc_span::{Span, Symbol, sym};
|
||||
|
||||
use super::{
|
||||
AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,
|
||||
SingleAttributeParser,
|
||||
AcceptMapping, AttributeOrder, AttributeParser, CombineAttributeParser, ConvertFn,
|
||||
NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
|
||||
};
|
||||
use crate::context::{AcceptContext, FinalizeContext, Stage};
|
||||
use crate::parser::ArgParser;
|
||||
|
|
@ -280,3 +280,53 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TargetFeatureParser;
|
||||
|
||||
impl<S: Stage> CombineAttributeParser<S> for TargetFeatureParser {
|
||||
type Item = (Symbol, Span);
|
||||
const PATH: &[Symbol] = &[sym::target_feature];
|
||||
const CONVERT: ConvertFn<Self::Item> = |items, span| AttributeKind::TargetFeature(items, span);
|
||||
const TEMPLATE: AttributeTemplate = template!(List: "enable = \"feat1, feat2\"");
|
||||
|
||||
fn extend<'c>(
|
||||
cx: &'c mut AcceptContext<'_, '_, S>,
|
||||
args: &'c ArgParser<'_>,
|
||||
) -> impl IntoIterator<Item = Self::Item> + 'c {
|
||||
let mut features = Vec::new();
|
||||
let ArgParser::List(list) = args else {
|
||||
cx.expected_list(cx.attr_span);
|
||||
return features;
|
||||
};
|
||||
for item in list.mixed() {
|
||||
let Some(name_value) = item.meta_item() else {
|
||||
cx.expected_name_value(item.span(), Some(sym::enable));
|
||||
return features;
|
||||
};
|
||||
|
||||
// Validate name
|
||||
let Some(name) = name_value.path().word_sym() else {
|
||||
cx.expected_name_value(name_value.path().span(), Some(sym::enable));
|
||||
return features;
|
||||
};
|
||||
if name != sym::enable {
|
||||
cx.expected_name_value(name_value.path().span(), Some(sym::enable));
|
||||
return features;
|
||||
}
|
||||
|
||||
// Use value
|
||||
let Some(name_value) = name_value.args().name_value() else {
|
||||
cx.expected_name_value(item.span(), Some(sym::enable));
|
||||
return features;
|
||||
};
|
||||
let Some(value_str) = name_value.value_as_str() else {
|
||||
cx.expected_string_literal(name_value.value_span, Some(name_value.value_as_lit()));
|
||||
return features;
|
||||
};
|
||||
for feature in value_str.as_str().split(",") {
|
||||
features.push((Symbol::intern(feature), item.span()));
|
||||
}
|
||||
}
|
||||
features
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for Without
|
|||
}
|
||||
}
|
||||
|
||||
type ConvertFn<E> = fn(ThinVec<E>) -> AttributeKind;
|
||||
type ConvertFn<E> = fn(ThinVec<E>, Span) -> AttributeKind;
|
||||
|
||||
/// Alternative to [`AttributeParser`] that automatically handles state management.
|
||||
/// If multiple attributes appear on an element, combines the values of each into a
|
||||
|
|
@ -295,14 +295,21 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static {
|
|||
|
||||
/// Use in combination with [`CombineAttributeParser`].
|
||||
/// `Combine<T: CombineAttributeParser>` implements [`AttributeParser`].
|
||||
pub(crate) struct Combine<T: CombineAttributeParser<S>, S: Stage>(
|
||||
PhantomData<(S, T)>,
|
||||
ThinVec<<T as CombineAttributeParser<S>>::Item>,
|
||||
);
|
||||
pub(crate) struct Combine<T: CombineAttributeParser<S>, S: Stage> {
|
||||
phantom: PhantomData<(S, T)>,
|
||||
/// A list of all items produced by parsing attributes so far. One attribute can produce any amount of items.
|
||||
items: ThinVec<<T as CombineAttributeParser<S>>::Item>,
|
||||
/// The full span of the first attribute that was encountered.
|
||||
first_span: Option<Span>,
|
||||
}
|
||||
|
||||
impl<T: CombineAttributeParser<S>, S: Stage> Default for Combine<T, S> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default(), Default::default())
|
||||
Self {
|
||||
phantom: Default::default(),
|
||||
items: Default::default(),
|
||||
first_span: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -310,10 +317,18 @@ impl<T: CombineAttributeParser<S>, S: Stage> AttributeParser<S> for Combine<T, S
|
|||
const ATTRIBUTES: AcceptMapping<Self, S> = &[(
|
||||
T::PATH,
|
||||
<T as CombineAttributeParser<S>>::TEMPLATE,
|
||||
|group: &mut Combine<T, S>, cx, args| group.1.extend(T::extend(cx, args)),
|
||||
|group: &mut Combine<T, S>, cx, args| {
|
||||
// Keep track of the span of the first attribute, for diagnostics
|
||||
group.first_span.get_or_insert(cx.attr_span);
|
||||
group.items.extend(T::extend(cx, args))
|
||||
},
|
||||
)];
|
||||
|
||||
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
if self.1.is_empty() { None } else { Some(T::CONVERT(self.1)) }
|
||||
if let Some(first_span) = self.first_span {
|
||||
Some(T::CONVERT(self.items, first_span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub(crate) struct ReprParser;
|
|||
impl<S: Stage> CombineAttributeParser<S> for ReprParser {
|
||||
type Item = (ReprAttr, Span);
|
||||
const PATH: &[Symbol] = &[sym::repr];
|
||||
const CONVERT: ConvertFn<Self::Item> = AttributeKind::Repr;
|
||||
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::Repr(items);
|
||||
// FIXME(jdonszelmann): never used
|
||||
const TEMPLATE: AttributeTemplate =
|
||||
template!(List: "C | Rust | align(...) | packed(...) | <integer type> | transparent");
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
|||
|
||||
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
|
||||
use crate::attributes::codegen_attrs::{
|
||||
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TrackCallerParser,
|
||||
UsedParser,
|
||||
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser,
|
||||
TrackCallerParser, UsedParser,
|
||||
};
|
||||
use crate::attributes::confusables::ConfusablesParser;
|
||||
use crate::attributes::deprecation::DeprecationParser;
|
||||
|
|
@ -118,6 +118,7 @@ attribute_parsers!(
|
|||
Combine<AllowConstFnUnstableParser>,
|
||||
Combine<AllowInternalUnstableParser>,
|
||||
Combine<ReprParser>,
|
||||
Combine<TargetFeatureParser>,
|
||||
// tidy-alphabetical-end
|
||||
|
||||
// tidy-alphabetical-start
|
||||
|
|
@ -189,7 +190,7 @@ impl Stage for Late {
|
|||
}
|
||||
}
|
||||
|
||||
/// used when parsing attributes for miscelaneous things *before* ast lowering
|
||||
/// used when parsing attributes for miscellaneous things *before* ast lowering
|
||||
pub struct Early;
|
||||
/// used when parsing attributes during ast lowering
|
||||
pub struct Late;
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ mod llvm_enzyme {
|
|||
/// so instead we manually build something that should pass the type checker.
|
||||
/// We also add a inline_asm line, as one more barrier for rustc to prevent inlining
|
||||
/// or const propagation. inline_asm will also triggers an Enzyme crash if due to another
|
||||
/// bug would ever try to accidentially differentiate this placeholder function body.
|
||||
/// bug would ever try to accidentally differentiate this placeholder function body.
|
||||
/// Finally, we also add back_box usages of all input arguments, to prevent rustc
|
||||
/// from optimizing any arguments away.
|
||||
fn gen_enzyme_body(
|
||||
|
|
@ -606,7 +606,7 @@ mod llvm_enzyme {
|
|||
return body;
|
||||
}
|
||||
|
||||
// Everything from here onwards just tries to fullfil the return type. Fun!
|
||||
// Everything from here onwards just tries to fulfil the return type. Fun!
|
||||
|
||||
// having an active-only return means we'll drop the original return type.
|
||||
// So that can be treated identical to not having one in the first place.
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ fn call_simple_intrinsic<'ll, 'tcx>(
|
|||
sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
|
||||
sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
|
||||
// There are issues on x86_64 and aarch64 with the f128 variant,
|
||||
// let's instead use the instrinsic fallback body.
|
||||
// let's instead use the intrinsic fallback body.
|
||||
// sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
|
||||
sym::maxnumf16 => ("llvm.maxnum", &[bx.type_f16()]),
|
||||
sym::maxnumf32 => ("llvm.maxnum", &[bx.type_f32()]),
|
||||
|
|
@ -118,7 +118,7 @@ fn call_simple_intrinsic<'ll, 'tcx>(
|
|||
sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
|
||||
sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]),
|
||||
// There are issues on x86_64 and aarch64 with the f128 variant,
|
||||
// let's instead use the instrinsic fallback body.
|
||||
// let's instead use the intrinsic fallback body.
|
||||
// sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]),
|
||||
sym::copysignf16 => ("llvm.copysign", &[bx.type_f16()]),
|
||||
sym::copysignf32 => ("llvm.copysign", &[bx.type_f32()]),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ unsafe extern "C" {
|
|||
pub(crate) fn LLVMDumpValue(V: &Value);
|
||||
pub(crate) fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
|
||||
pub(crate) fn LLVMGetReturnType(T: &Type) -> &Type;
|
||||
pub(crate) fn LLVMGetParams(Fnc: &Value, parms: *mut &Value);
|
||||
pub(crate) fn LLVMGetParams(Fnc: &Value, params: *mut &Value);
|
||||
pub(crate) fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> Option<&Value>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -861,7 +861,7 @@ fn emit_xtensa_va_arg<'ll, 'tcx>(
|
|||
|
||||
// On big-endian, for values smaller than the slot size we'd have to align the read to the end
|
||||
// of the slot rather than the start. While the ISA and GCC support big-endian, all the Xtensa
|
||||
// targets supported by rustc are litte-endian so don't worry about it.
|
||||
// targets supported by rustc are little-endian so don't worry about it.
|
||||
|
||||
// if from_regsave {
|
||||
// unsafe { *regsave_value_ptr }
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
|
|||
|
||||
codegen_ssa_failed_to_write = failed to write {$path}: {$error}
|
||||
|
||||
codegen_ssa_feature_not_valid = the feature named `{$feature}` is not valid for this target
|
||||
.label = `{$feature}` is not valid for this target
|
||||
.help = consider removing the leading `+` in the feature name
|
||||
|
||||
codegen_ssa_field_associated_value_expected = associated value expected for `{$name}`
|
||||
|
||||
codegen_ssa_forbidden_ctarget_feature =
|
||||
|
|
@ -289,7 +293,7 @@ codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executab
|
|||
|
||||
codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}`
|
||||
|
||||
codegen_ssa_thorin_mixed_input_encodings = input objects haved mixed encodings
|
||||
codegen_ssa_thorin_mixed_input_encodings = input objects have mixed encodings
|
||||
|
||||
codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections
|
||||
|
||||
|
|
|
|||
|
|
@ -2767,7 +2767,7 @@ fn add_upstream_rust_crates(
|
|||
|
||||
if sess.target.is_like_aix {
|
||||
// Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
|
||||
// the dependency name when outputing a shared library. Thus, `ld` will
|
||||
// the dependency name when outputting a shared library. Thus, `ld` will
|
||||
// use the full path to shared libraries as the dependency if passed it
|
||||
// by default unless `noipath` is passed.
|
||||
// https://www.ibm.com/docs/en/aix/7.3?topic=l-ld-command.
|
||||
|
|
@ -3051,7 +3051,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
|||
// Supported architecture names can be found in the source:
|
||||
// https://github.com/apple-oss-distributions/ld64/blob/ld64-951.9/src/abstraction/MachOFileAbstraction.hpp#L578-L648
|
||||
//
|
||||
// Intentially verbose to ensure that the list always matches correctly
|
||||
// Intentionally verbose to ensure that the list always matches correctly
|
||||
// with the list in the source above.
|
||||
let ld64_arch = match llvm_arch {
|
||||
"armv7k" => "armv7k",
|
||||
|
|
@ -3118,7 +3118,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
|||
// We do not currently know the actual SDK version though, so we have a few options:
|
||||
// 1. Use the minimum version supported by rustc.
|
||||
// 2. Use the same as the deployment target.
|
||||
// 3. Use an arbitary recent version.
|
||||
// 3. Use an arbitrary recent version.
|
||||
// 4. Omit the version.
|
||||
//
|
||||
// The first option is too low / too conservative, and means that users will not get the
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
|
|||
"n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2,
|
||||
"n64" if !is_32bit => {}
|
||||
"" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
|
||||
"" => sess.dcx().fatal("LLVM ABI must be specifed for 64-bit MIPS targets"),
|
||||
"" => sess.dcx().fatal("LLVM ABI must be specified for 64-bit MIPS targets"),
|
||||
s if is_32bit => {
|
||||
sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 32-bit MIPS target", s))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,49 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
});
|
||||
}
|
||||
}
|
||||
AttributeKind::TargetFeature(features, attr_span) => {
|
||||
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
|
||||
tcx.dcx().span_delayed_bug(*attr_span, "target_feature applied to non-fn");
|
||||
continue;
|
||||
};
|
||||
let safe_target_features =
|
||||
matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
|
||||
codegen_fn_attrs.safe_target_features = safe_target_features;
|
||||
if safe_target_features {
|
||||
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
||||
// The `#[target_feature]` attribute is allowed on
|
||||
// WebAssembly targets on all functions. Prior to stabilizing
|
||||
// the `target_feature_11` feature, `#[target_feature]` was
|
||||
// only permitted on unsafe functions because on most targets
|
||||
// execution of instructions that are not supported is
|
||||
// considered undefined behavior. For WebAssembly which is a
|
||||
// 100% safe target at execution time it's not possible to
|
||||
// execute undefined instructions, and even if a future
|
||||
// feature was added in some form for this it would be a
|
||||
// deterministic trap. There is no undefined behavior when
|
||||
// executing WebAssembly so `#[target_feature]` is allowed
|
||||
// on safe functions (but again, only for WebAssembly)
|
||||
//
|
||||
// Note that this is also allowed if `actually_rustdoc` so
|
||||
// if a target is documenting some wasm-specific code then
|
||||
// it's not spuriously denied.
|
||||
//
|
||||
// Now that `#[target_feature]` is permitted on safe functions,
|
||||
// this exception must still exist for allowing the attribute on
|
||||
// `main`, `start`, and other functions that are not usually
|
||||
// allowed.
|
||||
} else {
|
||||
check_target_feature_trait_unsafe(tcx, did, *attr_span);
|
||||
}
|
||||
}
|
||||
from_target_feature_attr(
|
||||
tcx,
|
||||
did,
|
||||
features,
|
||||
rust_target_features,
|
||||
&mut codegen_fn_attrs.target_features,
|
||||
);
|
||||
}
|
||||
AttributeKind::TrackCaller(attr_span) => {
|
||||
let is_closure = tcx.is_closure_like(did.to_def_id());
|
||||
|
||||
|
|
@ -190,49 +233,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
|
||||
}
|
||||
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
|
||||
sym::target_feature => {
|
||||
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
|
||||
tcx.dcx().span_delayed_bug(attr.span(), "target_feature applied to non-fn");
|
||||
continue;
|
||||
};
|
||||
let safe_target_features =
|
||||
matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
|
||||
codegen_fn_attrs.safe_target_features = safe_target_features;
|
||||
if safe_target_features {
|
||||
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
||||
// The `#[target_feature]` attribute is allowed on
|
||||
// WebAssembly targets on all functions. Prior to stabilizing
|
||||
// the `target_feature_11` feature, `#[target_feature]` was
|
||||
// only permitted on unsafe functions because on most targets
|
||||
// execution of instructions that are not supported is
|
||||
// considered undefined behavior. For WebAssembly which is a
|
||||
// 100% safe target at execution time it's not possible to
|
||||
// execute undefined instructions, and even if a future
|
||||
// feature was added in some form for this it would be a
|
||||
// deterministic trap. There is no undefined behavior when
|
||||
// executing WebAssembly so `#[target_feature]` is allowed
|
||||
// on safe functions (but again, only for WebAssembly)
|
||||
//
|
||||
// Note that this is also allowed if `actually_rustdoc` so
|
||||
// if a target is documenting some wasm-specific code then
|
||||
// it's not spuriously denied.
|
||||
//
|
||||
// Now that `#[target_feature]` is permitted on safe functions,
|
||||
// this exception must still exist for allowing the attribute on
|
||||
// `main`, `start`, and other functions that are not usually
|
||||
// allowed.
|
||||
} else {
|
||||
check_target_feature_trait_unsafe(tcx, did, attr.span());
|
||||
}
|
||||
}
|
||||
from_target_feature_attr(
|
||||
tcx,
|
||||
did,
|
||||
attr,
|
||||
rust_target_features,
|
||||
&mut codegen_fn_attrs.target_features,
|
||||
);
|
||||
}
|
||||
sym::linkage => {
|
||||
if let Some(val) = attr.value_str() {
|
||||
let linkage = Some(linkage_by_name(tcx, did, val.as_str()));
|
||||
|
|
@ -536,10 +536,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
.map(|features| (features.name.as_str(), true))
|
||||
.collect(),
|
||||
) {
|
||||
let span = tcx
|
||||
.get_attrs(did, sym::target_feature)
|
||||
.next()
|
||||
.map_or_else(|| tcx.def_span(did), |a| a.span());
|
||||
let span =
|
||||
find_attr!(tcx.get_all_attrs(did), AttributeKind::TargetFeature(_, span) => *span)
|
||||
.unwrap_or_else(|| tcx.def_span(did));
|
||||
|
||||
tcx.dcx()
|
||||
.create_err(errors::TargetFeatureDisableOrEnable {
|
||||
features,
|
||||
|
|
|
|||
|
|
@ -1292,3 +1292,14 @@ pub(crate) struct NoMangleNameless {
|
|||
pub span: Span,
|
||||
pub definition: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_feature_not_valid)]
|
||||
pub(crate) struct FeatureNotValid<'a> {
|
||||
pub feature: &'a str,
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[help]
|
||||
pub plus_hint: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -571,6 +571,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
|||
pub(crate) fn builder(
|
||||
layout: TyAndLayout<'tcx>,
|
||||
) -> Option<OperandRef<'tcx, Result<V, abi::Scalar>>> {
|
||||
// Uninhabited types are weird, because for example `Result<!, !>`
|
||||
// shows up as `FieldsShape::Primitive` and we need to be able to write
|
||||
// a field into `(u32, !)`. We'll do that in an `alloca` instead.
|
||||
if layout.uninhabited {
|
||||
return None;
|
||||
}
|
||||
|
||||
let val = match layout.backend_repr {
|
||||
BackendRepr::Memory { .. } if layout.is_zst() => OperandValue::ZeroSized,
|
||||
BackendRepr::Scalar(s) => OperandValue::Immediate(Err(s)),
|
||||
|
|
@ -640,16 +647,46 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, Result<V, abi::Scalar>> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Insert the immediate value `imm` for field `f` in the *type itself*,
|
||||
/// rather than into one of the variants.
|
||||
///
|
||||
/// Most things want [`OperandRef::insert_field`] instead, but this one is
|
||||
/// necessary for writing things like enum tags that aren't in any variant.
|
||||
pub(super) fn insert_imm(&mut self, f: FieldIdx, imm: V) {
|
||||
let field_offset = self.layout.fields.offset(f.as_usize());
|
||||
let is_zero_offset = field_offset == Size::ZERO;
|
||||
match &mut self.val {
|
||||
OperandValue::Immediate(val @ Err(_)) if is_zero_offset => {
|
||||
*val = Ok(imm);
|
||||
}
|
||||
OperandValue::Pair(fst @ Err(_), _) if is_zero_offset => {
|
||||
*fst = Ok(imm);
|
||||
}
|
||||
OperandValue::Pair(_, snd @ Err(_)) if !is_zero_offset => {
|
||||
*snd = Ok(imm);
|
||||
}
|
||||
_ => bug!("Tried to insert {imm:?} into field {f:?} of {self:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// After having set all necessary fields, this converts the
|
||||
/// `OperandValue<Result<V, _>>` (as obtained from [`OperandRef::builder`])
|
||||
/// to the normal `OperandValue<V>`.
|
||||
///
|
||||
/// ICEs if any required fields were not set.
|
||||
pub fn build(&self) -> OperandRef<'tcx, V> {
|
||||
pub fn build(&self, cx: &impl CodegenMethods<'tcx, Value = V>) -> OperandRef<'tcx, V> {
|
||||
let OperandRef { val, layout } = *self;
|
||||
|
||||
// For something like `Option::<u32>::None`, it's expected that the
|
||||
// payload scalar will not actually have been set, so this converts
|
||||
// unset scalars to corresponding `undef` values so long as the scalar
|
||||
// from the layout allows uninit.
|
||||
let unwrap = |r: Result<V, abi::Scalar>| match r {
|
||||
Ok(v) => v,
|
||||
Err(s) if s.is_uninit_valid() => {
|
||||
let bty = cx.type_from_scalar(s);
|
||||
cx.const_undef(bty)
|
||||
}
|
||||
Err(_) => bug!("OperandRef::build called while fields are missing {self:?}"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use rustc_abi::{Align, BackendRepr, FieldsShape, Size, TagEncoding, VariantIdx, Variants};
|
||||
use rustc_abi::{
|
||||
Align, BackendRepr, FieldIdx, FieldsShape, Size, TagEncoding, VariantIdx, Variants,
|
||||
};
|
||||
use rustc_middle::mir::PlaceTy;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
|
|
@ -239,53 +241,17 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
|||
bx: &mut Bx,
|
||||
variant_index: VariantIdx,
|
||||
) {
|
||||
if self.layout.for_variant(bx.cx(), variant_index).is_uninhabited() {
|
||||
// We play it safe by using a well-defined `abort`, but we could go for immediate UB
|
||||
// if that turns out to be helpful.
|
||||
bx.abort();
|
||||
return;
|
||||
}
|
||||
match self.layout.variants {
|
||||
Variants::Empty => unreachable!("we already handled uninhabited types"),
|
||||
Variants::Single { index } => assert_eq!(index, variant_index),
|
||||
|
||||
Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => {
|
||||
let ptr = self.project_field(bx, tag_field.as_usize());
|
||||
let to =
|
||||
self.layout.ty.discriminant_for_variant(bx.tcx(), variant_index).unwrap().val;
|
||||
bx.store_to_place(
|
||||
bx.cx().const_uint_big(bx.cx().backend_type(ptr.layout), to),
|
||||
ptr.val,
|
||||
);
|
||||
match codegen_tag_value(bx.cx(), variant_index, self.layout) {
|
||||
Err(UninhabitedVariantError) => {
|
||||
// We play it safe by using a well-defined `abort`, but we could go for immediate UB
|
||||
// if that turns out to be helpful.
|
||||
bx.abort();
|
||||
}
|
||||
Variants::Multiple {
|
||||
tag_encoding:
|
||||
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
|
||||
tag_field,
|
||||
..
|
||||
} => {
|
||||
if variant_index != untagged_variant {
|
||||
let niche = self.project_field(bx, tag_field.as_usize());
|
||||
let niche_llty = bx.cx().immediate_backend_type(niche.layout);
|
||||
let BackendRepr::Scalar(scalar) = niche.layout.backend_repr else {
|
||||
bug!("expected a scalar placeref for the niche");
|
||||
};
|
||||
// We are supposed to compute `niche_value.wrapping_add(niche_start)` wrapping
|
||||
// around the `niche`'s type.
|
||||
// The easiest way to do that is to do wrapping arithmetic on `u128` and then
|
||||
// masking off any extra bits that occur because we did the arithmetic with too many bits.
|
||||
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
|
||||
let niche_value = (niche_value as u128).wrapping_add(niche_start);
|
||||
let niche_value = niche_value & niche.layout.size.unsigned_int_max();
|
||||
|
||||
let niche_llval = bx.cx().scalar_to_backend(
|
||||
Scalar::from_uint(niche_value, niche.layout.size),
|
||||
scalar,
|
||||
niche_llty,
|
||||
);
|
||||
OperandValue::Immediate(niche_llval).store(bx, niche);
|
||||
}
|
||||
Ok(Some((tag_field, imm))) => {
|
||||
let tag_place = self.project_field(bx, tag_field.as_usize());
|
||||
OperandValue::Immediate(imm).store(bx, tag_place);
|
||||
}
|
||||
Ok(None) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -471,3 +437,73 @@ fn round_up_const_value_to_alignment<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
let offset = bx.and(neg_value, align_minus_1);
|
||||
bx.add(value, offset)
|
||||
}
|
||||
|
||||
/// Calculates the value that needs to be stored to mark the discriminant.
|
||||
///
|
||||
/// This might be `None` for a `struct` or a niched variant (like `Some(&3)`).
|
||||
///
|
||||
/// If it's `Some`, it returns the value to store and the field in which to
|
||||
/// store it. Note that this value is *not* the same as the discriminant, in
|
||||
/// general, as it might be a niche value or have a different size.
|
||||
///
|
||||
/// It might also be an `Err` because the variant is uninhabited.
|
||||
pub(super) fn codegen_tag_value<'tcx, V>(
|
||||
cx: &impl CodegenMethods<'tcx, Value = V>,
|
||||
variant_index: VariantIdx,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
) -> Result<Option<(FieldIdx, V)>, UninhabitedVariantError> {
|
||||
// By checking uninhabited-ness first we don't need to worry about types
|
||||
// like `(u32, !)` which are single-variant but weird.
|
||||
if layout.for_variant(cx, variant_index).is_uninhabited() {
|
||||
return Err(UninhabitedVariantError);
|
||||
}
|
||||
|
||||
Ok(match layout.variants {
|
||||
Variants::Empty => unreachable!("we already handled uninhabited types"),
|
||||
Variants::Single { index } => {
|
||||
assert_eq!(index, variant_index);
|
||||
None
|
||||
}
|
||||
|
||||
Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => {
|
||||
let discr = layout.ty.discriminant_for_variant(cx.tcx(), variant_index);
|
||||
let to = discr.unwrap().val;
|
||||
let tag_layout = layout.field(cx, tag_field.as_usize());
|
||||
let tag_llty = cx.immediate_backend_type(tag_layout);
|
||||
let imm = cx.const_uint_big(tag_llty, to);
|
||||
Some((tag_field, imm))
|
||||
}
|
||||
Variants::Multiple {
|
||||
tag_encoding: TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start },
|
||||
tag_field,
|
||||
..
|
||||
} => {
|
||||
if variant_index != untagged_variant {
|
||||
let niche_layout = layout.field(cx, tag_field.as_usize());
|
||||
let niche_llty = cx.immediate_backend_type(niche_layout);
|
||||
let BackendRepr::Scalar(scalar) = niche_layout.backend_repr else {
|
||||
bug!("expected a scalar placeref for the niche");
|
||||
};
|
||||
// We are supposed to compute `niche_value.wrapping_add(niche_start)` wrapping
|
||||
// around the `niche`'s type.
|
||||
// The easiest way to do that is to do wrapping arithmetic on `u128` and then
|
||||
// masking off any extra bits that occur because we did the arithmetic with too many bits.
|
||||
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
|
||||
let niche_value = (niche_value as u128).wrapping_add(niche_start);
|
||||
let niche_value = niche_value & niche_layout.size.unsigned_int_max();
|
||||
|
||||
let niche_llval = cx.scalar_to_backend(
|
||||
Scalar::from_uint(niche_value, niche_layout.size),
|
||||
scalar,
|
||||
niche_llty,
|
||||
);
|
||||
Some((tag_field, niche_llval))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct UninhabitedVariantError;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use rustc_span::{DUMMY_SP, Span};
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
use super::operand::{OperandRef, OperandValue};
|
||||
use super::place::PlaceRef;
|
||||
use super::place::{PlaceRef, codegen_tag_value};
|
||||
use super::{FunctionCx, LocalRef};
|
||||
use crate::common::IntPredicate;
|
||||
use crate::traits::*;
|
||||
|
|
@ -694,7 +694,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
|
||||
mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"),
|
||||
mir::Rvalue::Aggregate(_, ref fields) => {
|
||||
mir::Rvalue::Aggregate(ref kind, ref fields) => {
|
||||
let (variant_index, active_field_index) = match **kind {
|
||||
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
|
||||
(variant_index, active_field_index)
|
||||
}
|
||||
_ => (FIRST_VARIANT, None),
|
||||
};
|
||||
|
||||
let ty = rvalue.ty(self.mir, self.cx.tcx());
|
||||
let ty = self.monomorphize(ty);
|
||||
let layout = self.cx.layout_of(ty);
|
||||
|
|
@ -706,10 +713,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
};
|
||||
for (field_idx, field) in fields.iter_enumerated() {
|
||||
let op = self.codegen_operand(bx, field);
|
||||
builder.insert_field(bx, FIRST_VARIANT, field_idx, op);
|
||||
let fi = active_field_index.unwrap_or(field_idx);
|
||||
builder.insert_field(bx, variant_index, fi, op);
|
||||
}
|
||||
|
||||
builder.build()
|
||||
let tag_result = codegen_tag_value(self.cx, variant_index, layout);
|
||||
match tag_result {
|
||||
Err(super::place::UninhabitedVariantError) => {
|
||||
// Like codegen_set_discr we use a sound abort, but could
|
||||
// potentially `unreachable` or just return the poison for
|
||||
// more optimizability, if that turns out to be helpful.
|
||||
bx.abort();
|
||||
let val = OperandValue::poison(bx, layout);
|
||||
OperandRef { val, layout }
|
||||
}
|
||||
Ok(maybe_tag_value) => {
|
||||
if let Some((tag_field, tag_imm)) = maybe_tag_value {
|
||||
builder.insert_imm(tag_field, tag_imm);
|
||||
}
|
||||
builder.build(bx.cx())
|
||||
}
|
||||
}
|
||||
}
|
||||
mir::Rvalue::ShallowInitBox(ref operand, content_ty) => {
|
||||
let operand = self.codegen_operand(bx, operand);
|
||||
|
|
@ -1037,28 +1061,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
// Arrays are always aggregates, so it's not worth checking anything here.
|
||||
// (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.)
|
||||
mir::Rvalue::Repeat(..) => false,
|
||||
mir::Rvalue::Aggregate(ref kind, _) => {
|
||||
let allowed_kind = match **kind {
|
||||
// This always produces a `ty::RawPtr`, so will be Immediate or Pair
|
||||
mir::AggregateKind::RawPtr(..) => true,
|
||||
mir::AggregateKind::Array(..) => false,
|
||||
mir::AggregateKind::Tuple => true,
|
||||
mir::AggregateKind::Adt(def_id, ..) => {
|
||||
let adt_def = self.cx.tcx().adt_def(def_id);
|
||||
adt_def.is_struct() && !adt_def.repr().simd()
|
||||
}
|
||||
mir::AggregateKind::Closure(..) => true,
|
||||
// FIXME: Can we do this for simple coroutines too?
|
||||
mir::AggregateKind::Coroutine(..) | mir::AggregateKind::CoroutineClosure(..) => false,
|
||||
};
|
||||
allowed_kind && {
|
||||
mir::Rvalue::Aggregate(..) => {
|
||||
let ty = rvalue.ty(self.mir, self.cx.tcx());
|
||||
let ty = self.monomorphize(ty);
|
||||
let layout = self.cx.spanned_layout_of(ty, span);
|
||||
OperandRef::<Bx::Value>::builder(layout).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (*) this is only true if the type is suitable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use rustc_attr_data_structures::InstructionSetAttr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||
|
|
@ -12,110 +10,85 @@ use rustc_session::Session;
|
|||
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_target::target_features::{self, RUSTC_SPECIFIC_FEATURES, Stability};
|
||||
use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::errors;
|
||||
use crate::errors::FeatureNotValid;
|
||||
use crate::{errors, target_features};
|
||||
|
||||
/// Compute the enabled target features from the `#[target_feature]` function attribute.
|
||||
/// Enabled target features are added to `target_features`.
|
||||
pub(crate) fn from_target_feature_attr(
|
||||
tcx: TyCtxt<'_>,
|
||||
did: LocalDefId,
|
||||
attr: &hir::Attribute,
|
||||
features: &[(Symbol, Span)],
|
||||
rust_target_features: &UnordMap<String, target_features::Stability>,
|
||||
target_features: &mut Vec<TargetFeature>,
|
||||
) {
|
||||
let Some(list) = attr.meta_item_list() else { return };
|
||||
let bad_item = |span| {
|
||||
let msg = "malformed `target_feature` attribute input";
|
||||
let code = "enable = \"..\"";
|
||||
tcx.dcx()
|
||||
.struct_span_err(span, msg)
|
||||
.with_span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders)
|
||||
.emit();
|
||||
};
|
||||
let rust_features = tcx.features();
|
||||
let abi_feature_constraints = tcx.sess.target.abi_required_features();
|
||||
for item in list {
|
||||
// Only `enable = ...` is accepted in the meta-item list.
|
||||
if !item.has_name(sym::enable) {
|
||||
bad_item(item.span());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Must be of the form `enable = "..."` (a string).
|
||||
let Some(value) = item.value_str() else {
|
||||
bad_item(item.span());
|
||||
for &(feature, feature_span) in features {
|
||||
let feature_str = feature.as_str();
|
||||
let Some(stability) = rust_target_features.get(feature_str) else {
|
||||
let plus_hint = feature_str
|
||||
.strip_prefix('+')
|
||||
.is_some_and(|stripped| rust_target_features.contains_key(stripped));
|
||||
tcx.dcx().emit_err(FeatureNotValid {
|
||||
feature: feature_str,
|
||||
span: feature_span,
|
||||
plus_hint,
|
||||
});
|
||||
continue;
|
||||
};
|
||||
|
||||
// We allow comma separation to enable multiple features.
|
||||
for feature in value.as_str().split(',') {
|
||||
let Some(stability) = rust_target_features.get(feature) else {
|
||||
let msg = format!("the feature named `{feature}` is not valid for this target");
|
||||
let mut err = tcx.dcx().struct_span_err(item.span(), msg);
|
||||
err.span_label(item.span(), format!("`{feature}` is not valid for this target"));
|
||||
if let Some(stripped) = feature.strip_prefix('+') {
|
||||
let valid = rust_target_features.contains_key(stripped);
|
||||
if valid {
|
||||
err.help("consider removing the leading `+` in the feature name");
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
continue;
|
||||
};
|
||||
|
||||
// Only allow target features whose feature gates have been enabled
|
||||
// and which are permitted to be toggled.
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: item.span(),
|
||||
feature,
|
||||
reason,
|
||||
});
|
||||
} else if let Some(nightly_feature) = stability.requires_nightly()
|
||||
&& !rust_features.enabled(nightly_feature)
|
||||
{
|
||||
feature_err(
|
||||
&tcx.sess,
|
||||
nightly_feature,
|
||||
item.span(),
|
||||
format!("the target feature `{feature}` is currently unstable"),
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
// Add this and the implied features.
|
||||
let feature_sym = Symbol::intern(feature);
|
||||
for &name in tcx.implied_target_features(feature_sym) {
|
||||
// But ensure the ABI does not forbid enabling this.
|
||||
// Here we do assume that the backend doesn't add even more implied features
|
||||
// we don't know about, at least no features that would have ABI effects!
|
||||
// We skip this logic in rustdoc, where we want to allow all target features of
|
||||
// all targets, so we can't check their ABI compatibility and anyway we are not
|
||||
// generating code so "it's fine".
|
||||
if !tcx.sess.opts.actually_rustdoc {
|
||||
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
||||
// For "neon" specifically, we emit an FCW instead of a hard error.
|
||||
// See <https://github.com/rust-lang/rust/issues/134375>.
|
||||
if tcx.sess.target.arch == "aarch64" && name.as_str() == "neon" {
|
||||
tcx.emit_node_span_lint(
|
||||
AARCH64_SOFTFLOAT_NEON,
|
||||
tcx.local_def_id_to_hir_id(did),
|
||||
item.span(),
|
||||
errors::Aarch64SoftfloatNeon,
|
||||
);
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: item.span(),
|
||||
feature: name.as_str(),
|
||||
reason: "this feature is incompatible with the target ABI",
|
||||
});
|
||||
}
|
||||
// Only allow target features whose feature gates have been enabled
|
||||
// and which are permitted to be toggled.
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: feature_span,
|
||||
feature: feature_str,
|
||||
reason,
|
||||
});
|
||||
} else if let Some(nightly_feature) = stability.requires_nightly()
|
||||
&& !rust_features.enabled(nightly_feature)
|
||||
{
|
||||
feature_err(
|
||||
&tcx.sess,
|
||||
nightly_feature,
|
||||
feature_span,
|
||||
format!("the target feature `{feature}` is currently unstable"),
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
// Add this and the implied features.
|
||||
for &name in tcx.implied_target_features(feature) {
|
||||
// But ensure the ABI does not forbid enabling this.
|
||||
// Here we do assume that the backend doesn't add even more implied features
|
||||
// we don't know about, at least no features that would have ABI effects!
|
||||
// We skip this logic in rustdoc, where we want to allow all target features of
|
||||
// all targets, so we can't check their ABI compatibility and anyway we are not
|
||||
// generating code so "it's fine".
|
||||
if !tcx.sess.opts.actually_rustdoc {
|
||||
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
||||
// For "neon" specifically, we emit an FCW instead of a hard error.
|
||||
// See <https://github.com/rust-lang/rust/issues/134375>.
|
||||
if tcx.sess.target.arch == "aarch64" && name.as_str() == "neon" {
|
||||
tcx.emit_node_span_lint(
|
||||
AARCH64_SOFTFLOAT_NEON,
|
||||
tcx.local_def_id_to_hir_id(did),
|
||||
feature_span,
|
||||
errors::Aarch64SoftfloatNeon,
|
||||
);
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: feature_span,
|
||||
feature: name.as_str(),
|
||||
reason: "this feature is incompatible with the target ABI",
|
||||
});
|
||||
}
|
||||
}
|
||||
target_features.push(TargetFeature { name, implied: name != feature_sym })
|
||||
}
|
||||
target_features.push(TargetFeature { name, implied: name != feature })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -457,7 +430,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
// one, just keep it.
|
||||
}
|
||||
_ => {
|
||||
// Overwrite stabilite.
|
||||
// Overwrite stability.
|
||||
occupied_entry.insert(stability);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
//
|
||||
// This function is opt-in for back ends.
|
||||
//
|
||||
// The default implementation calls `self.expect()` before emiting the branch
|
||||
// The default implementation calls `self.expect()` before emitting the branch
|
||||
// by calling `self.cond_br()`
|
||||
fn cond_br_with_expect(
|
||||
&mut self,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ pub fn rustc_allow_const_fn_unstable(
|
|||
) -> bool {
|
||||
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));
|
||||
|
||||
attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate))
|
||||
attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms, _) if syms.contains(&feature_gate))
|
||||
}
|
||||
|
||||
/// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable".
|
||||
|
|
|
|||
|
|
@ -572,7 +572,7 @@ where
|
|||
Right((local, offset, locals_addr, layout)) => {
|
||||
if offset.is_some() {
|
||||
// This has been projected to a part of this local, or had the type changed.
|
||||
// FIMXE: there are cases where we could still avoid allocating an mplace.
|
||||
// FIXME: there are cases where we could still avoid allocating an mplace.
|
||||
Left(place.force_mplace(self)?)
|
||||
} else {
|
||||
debug_assert_eq!(locals_addr, self.frame().locals_addr());
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
|||
fn add_data_range(&mut self, ptr: Pointer<Option<M::Provenance>>, size: Size) {
|
||||
if let Some(data_bytes) = self.data_bytes.as_mut() {
|
||||
// We only have to store the offset, the rest is the same for all pointers here.
|
||||
// The logic is agnostic to wether the offset is relative or absolute as long as
|
||||
// The logic is agnostic to whether the offset is relative or absolute as long as
|
||||
// it is consistent.
|
||||
let (_prov, offset) = ptr.into_raw_parts();
|
||||
// Add this.
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ fn check_validity_requirement_strict<'tcx>(
|
|||
// require dereferenceability also require non-null, we don't actually get any false negatives
|
||||
// due to this.
|
||||
// The value we are validating is temporary and discarded at the end of this function, so
|
||||
// there is no point in reseting provenance and padding.
|
||||
// there is no point in resetting provenance and padding.
|
||||
cx.validate_operand(
|
||||
&allocated.into(),
|
||||
/*recursive*/ false,
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ unsafe impl<K: Idx, #[may_dangle] V, I> Drop for VecCache<K, V, I> {
|
|||
// we are also guaranteed to just need to deallocate any large arrays (not iterate over
|
||||
// contents).
|
||||
//
|
||||
// Confirm no need to deallocate invidual entries. Note that `V: Copy` is asserted on
|
||||
// Confirm no need to deallocate individual entries. Note that `V: Copy` is asserted on
|
||||
// insert/lookup but not necessarily construction, primarily to avoid annoyingly propagating
|
||||
// the bounds into struct definitions everywhere.
|
||||
assert!(!std::mem::needs_drop::<K>());
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ fn normalize<'a>(MdStream(stream): MdStream<'a>, linkdefs: &mut Vec<MdTree<'a>>)
|
|||
let new_defs = stream.iter().filter(|tt| matches!(tt, MdTree::LinkDef { .. }));
|
||||
linkdefs.extend(new_defs.cloned());
|
||||
|
||||
// Run plaintest expansions on types that need it, call this function on nested types
|
||||
// Run plaintext expansions on types that need it, call this function on nested types
|
||||
for item in stream {
|
||||
match item {
|
||||
MdTree::PlainText(txt) => expand_plaintext(txt, &mut new_stream, MdTree::PlainText),
|
||||
|
|
|
|||
|
|
@ -880,7 +880,7 @@ impl SyntaxExtension {
|
|||
is_local: bool,
|
||||
) -> SyntaxExtension {
|
||||
let allow_internal_unstable =
|
||||
find_attr!(attrs, AttributeKind::AllowInternalUnstable(i) => i)
|
||||
find_attr!(attrs, AttributeKind::AllowInternalUnstable(i, _) => i)
|
||||
.map(|i| i.as_slice())
|
||||
.unwrap_or_default();
|
||||
// FIXME(jdonszelman): allow_internal_unsafe isn't yet new-style
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ impl server::Span for Rustc<'_, '_> {
|
|||
.lookup_char_pos(span.lo())
|
||||
.file
|
||||
.name
|
||||
.prefer_remapped_unconditionaly()
|
||||
.prefer_remapped_unconditionally()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ impl<'hir> ConstArg<'hir, AmbigArg> {
|
|||
}
|
||||
|
||||
impl<'hir> ConstArg<'hir> {
|
||||
/// Converts a `ConstArg` in an unambigous position to one in an ambiguous position. This is
|
||||
/// Converts a `ConstArg` in an unambiguous position to one in an ambiguous position. This is
|
||||
/// fallible as the [`ConstArgKind::Infer`] variant is not present in ambiguous positions.
|
||||
///
|
||||
/// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
|
||||
|
|
@ -508,7 +508,7 @@ pub enum GenericArg<'hir> {
|
|||
Lifetime(&'hir Lifetime),
|
||||
Type(&'hir Ty<'hir, AmbigArg>),
|
||||
Const(&'hir ConstArg<'hir, AmbigArg>),
|
||||
/// Inference variables in [`GenericArg`] are always represnted by
|
||||
/// Inference variables in [`GenericArg`] are always represented by
|
||||
/// `GenericArg::Infer` instead of the `Infer` variants on [`TyKind`] and
|
||||
/// [`ConstArgKind`] as it is not clear until hir ty lowering whether a
|
||||
/// `_` argument is a type or const argument.
|
||||
|
|
@ -3323,7 +3323,7 @@ impl<'hir> Ty<'hir, AmbigArg> {
|
|||
}
|
||||
|
||||
impl<'hir> Ty<'hir> {
|
||||
/// Converts a `Ty` in an unambigous position to one in an ambiguous position. This is
|
||||
/// Converts a `Ty` in an unambiguous position to one in an ambiguous position. This is
|
||||
/// fallible as the [`TyKind::Infer`] variant is not present in ambiguous positions.
|
||||
///
|
||||
/// Functions accepting ambiguous types will not handle the [`TyKind::Infer`] variant, if
|
||||
|
|
@ -4224,7 +4224,7 @@ impl fmt::Display for Constness {
|
|||
}
|
||||
}
|
||||
|
||||
/// The actualy safety specified in syntax. We may treat
|
||||
/// The actual safety specified in syntax. We may treat
|
||||
/// its safety different within the type system to create a
|
||||
/// "sound by default" system that needs checking this enum
|
||||
/// explicitly to allow unsafe operations.
|
||||
|
|
|
|||
|
|
@ -1088,7 +1088,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
// FIXME(#97583): Print associated item bindings properly (i.e., not as equality
|
||||
// predicates!).
|
||||
// FIXME: Turn this into a structured, translateable & more actionable suggestion.
|
||||
// FIXME: Turn this into a structured, translatable & more actionable suggestion.
|
||||
let mut where_bounds = vec![];
|
||||
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
|
||||
let bound_id = bound.def_id();
|
||||
|
|
@ -1588,7 +1588,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&infcx_
|
||||
};
|
||||
|
||||
tcx.all_traits()
|
||||
tcx.all_traits_including_private()
|
||||
.filter(|trait_def_id| {
|
||||
// Consider only traits with the associated type
|
||||
tcx.associated_items(*trait_def_id)
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
Err(SelectionError::TraitDynIncompatible(_)) => {
|
||||
// Dyn compatibility errors in coercion will *always* be due to the
|
||||
// fact that the RHS of the coercion is a non-dyn compatible `dyn Trait`
|
||||
// writen in source somewhere (otherwise we will never have lowered
|
||||
// written in source somewhere (otherwise we will never have lowered
|
||||
// the dyn trait from HIR to middle).
|
||||
//
|
||||
// There's no reason to emit yet another dyn compatibility error,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
// We want to emit an error if the const is not structurally resolveable
|
||||
// We want to emit an error if the const is not structurally resolvable
|
||||
// as otherwise we can wind up conservatively proving `Copy` which may
|
||||
// infer the repeat expr count to something that never required `Copy` in
|
||||
// the first place.
|
||||
|
|
@ -2461,7 +2461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
spans.push_span_label(param.param.span(), "");
|
||||
}
|
||||
}
|
||||
// Highligh each parameter being depended on for a generic type.
|
||||
// Highlight each parameter being depended on for a generic type.
|
||||
for ((&(_, param), deps), &(_, expected_ty)) in
|
||||
params_with_generics.iter().zip(&dependants).zip(formal_and_expected_inputs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
let def_id = pick.item.def_id;
|
||||
let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args);
|
||||
|
||||
debug!("method_predicates after instantitation = {:?}", method_predicates);
|
||||
debug!("method_predicates after instantiation = {:?}", method_predicates);
|
||||
|
||||
let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args);
|
||||
debug!("type scheme instantiated, sig={:?}", sig);
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// type parameters or early-bound regions.
|
||||
let tcx = self.tcx;
|
||||
// We use `Ident::with_dummy_span` since no built-in operator methods have
|
||||
// any macro-specific hygeine, so the span's context doesn't really matter.
|
||||
// any macro-specific hygiene, so the span's context doesn't really matter.
|
||||
let Some(method_item) =
|
||||
self.associated_value(trait_def_id, Ident::with_dummy_span(method_name))
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -1725,7 +1725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if unsatisfied_predicates.is_empty()
|
||||
// ...or if we already suggested that name because of `rustc_confusable` annotation
|
||||
&& Some(similar_candidate.name()) != confusable_suggested
|
||||
// and if the we aren't in an expansion.
|
||||
// and if we aren't in an expansion.
|
||||
&& !span.from_expansion()
|
||||
{
|
||||
self.find_likely_intended_associated_item(
|
||||
|
|
@ -3481,9 +3481,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
item_name: Ident,
|
||||
valid_out_of_scope_traits: Vec<DefId>,
|
||||
mut valid_out_of_scope_traits: Vec<DefId>,
|
||||
explain: bool,
|
||||
) -> bool {
|
||||
valid_out_of_scope_traits.retain(|id| self.tcx.is_user_visible_dep(id.krate));
|
||||
if !valid_out_of_scope_traits.is_empty() {
|
||||
let mut candidates = valid_out_of_scope_traits;
|
||||
candidates.sort_by_key(|id| self.tcx.def_path_str(id));
|
||||
|
|
@ -4388,7 +4389,7 @@ pub(crate) struct TraitInfo {
|
|||
/// Retrieves all traits in this crate and any dependent crates,
|
||||
/// and wraps them into `TraitInfo` for custom sorting.
|
||||
pub(crate) fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
|
||||
tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
|
||||
tcx.all_traits_including_private().map(|def_id| TraitInfo { def_id }).collect()
|
||||
}
|
||||
|
||||
fn print_disambiguation_help<'tcx>(
|
||||
|
|
|
|||
|
|
@ -723,7 +723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// This is maximally flexible, allowing e.g., `Some(mut x) | &Some(mut x)`.
|
||||
// In that example, `Some(mut x)` results in `Peel` whereas `&Some(mut x)` in `Reset`.
|
||||
| PatKind::Or(_)
|
||||
// Like or-patterns, guard patterns just propogate to their subpatterns.
|
||||
// Like or-patterns, guard patterns just propagate to their subpatterns.
|
||||
| PatKind::Guard(..) => AdjustMode::Pass,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -566,7 +566,7 @@ impl Cursor<'_> {
|
|||
}
|
||||
|
||||
if !found {
|
||||
// recovery strategy: a closing statement might have precending whitespace/newline
|
||||
// recovery strategy: a closing statement might have preceding whitespace/newline
|
||||
// but not have enough dashes to properly close. In this case, we eat until there,
|
||||
// and report a mismatch in the parser.
|
||||
let mut rest = self.as_str();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ declare_lint! {
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Otherwise try to find an alternative way to achive your goals using only raw pointers:
|
||||
/// Otherwise try to find an alternative way to achieve your goals using only raw pointers:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::ptr;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
|
|||
// }
|
||||
// }
|
||||
// where `something()` would have to be a call or path.
|
||||
// We have nothing meaninful to do with this.
|
||||
// We have nothing meaningful to do with this.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ impl IfLetRescope {
|
|||
}
|
||||
}
|
||||
}
|
||||
// At this point, any `if let` fragment in the cascade is definitely preceeded by `else`,
|
||||
// At this point, any `if let` fragment in the cascade is definitely preceded by `else`,
|
||||
// so a opening bracket is mandatory before each `match`.
|
||||
add_bracket_to_match_head = true;
|
||||
if let Some(alt) = alt {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
|
|||
let init = cx.expr_or_init(e);
|
||||
let orig_cast = if init.span != e.span { Some(init.span) } else { None };
|
||||
|
||||
// small cache to avoid recomputing needlesly computing peel_casts of init
|
||||
// small cache to avoid recomputing needlessly computing peel_casts of init
|
||||
let mut peel_casts = {
|
||||
let mut peel_casts_cache = None;
|
||||
move || *peel_casts_cache.get_or_insert_with(|| peel_casts(cx, init))
|
||||
|
|
|
|||
|
|
@ -1224,7 +1224,7 @@ declare_lint! {
|
|||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// A public `use` declaration should not be used to publicly re-export a
|
||||
/// A public `use` declaration should not be used to publically re-export a
|
||||
/// private `extern crate`. `pub extern crate` should be used instead.
|
||||
///
|
||||
/// This was historically allowed, but is not the intended behavior
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ decl_derive! {
|
|||
[PrintAttribute] =>
|
||||
/// Derives `PrintAttribute` for `AttributeKind`.
|
||||
/// This macro is pretty specific to `rustc_attr_data_structures` and likely not that useful in
|
||||
/// other places. It's deriving something close to `Debug` without printing some extraenous
|
||||
/// other places. It's deriving something close to `Debug` without printing some extraneous
|
||||
/// things like spans.
|
||||
print_attribute::print_attribute
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,8 +273,8 @@ fn add_query_desc_cached_impl(
|
|||
// macro producing a higher order macro that has all its token in the macro declaration we lose
|
||||
// any meaningful spans, resulting in rust-analyzer being unable to make the connection between
|
||||
// the query name and the corresponding providers field. The trick to fix this is to have
|
||||
// `rustc_queries` emit a field access with the given name's span which allows it to succesfully
|
||||
// show references / go to definition to the correspondig provider assignment which is usually
|
||||
// `rustc_queries` emit a field access with the given name's span which allows it to successfully
|
||||
// show references / go to definition to the corresponding provider assignment which is usually
|
||||
// the more interesting place.
|
||||
let ra_hint = quote! {
|
||||
let crate::query::Providers { #name: _, .. };
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ use rustc_middle::ty::data_structures::IndexSet;
|
|||
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
|
||||
use rustc_proc_macro::bridge::client::ProcMacro;
|
||||
use rustc_session::config::{
|
||||
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
|
||||
TargetModifier,
|
||||
CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers, TargetModifier,
|
||||
};
|
||||
use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
|
||||
use rustc_session::lint::{self, BuiltinLintDiag};
|
||||
|
|
@ -33,11 +32,11 @@ use rustc_session::output::validate_crate_name;
|
|||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
|
||||
use rustc_target::spec::{PanicStrategy, Target, TargetTuple};
|
||||
use rustc_target::spec::{PanicStrategy, Target};
|
||||
use tracing::{debug, info, trace};
|
||||
|
||||
use crate::errors;
|
||||
use crate::locator::{CrateError, CrateLocator, CratePaths};
|
||||
use crate::locator::{CrateError, CrateLocator, CratePaths, CrateRejections};
|
||||
use crate::rmeta::{
|
||||
CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob, TargetModifiers,
|
||||
};
|
||||
|
|
@ -684,61 +683,67 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
fn load_proc_macro<'b>(
|
||||
&self,
|
||||
locator: &mut CrateLocator<'b>,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
path_kind: PathKind,
|
||||
host_hash: Option<Svh>,
|
||||
) -> Result<Option<(LoadResult, Option<Library>)>, CrateError>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
// Use a new crate locator so trying to load a proc macro doesn't affect the error
|
||||
// message we emit
|
||||
let mut proc_macro_locator = locator.clone();
|
||||
if self.sess.opts.unstable_opts.dual_proc_macros {
|
||||
// Use a new crate locator and crate rejections so trying to load a proc macro doesn't
|
||||
// affect the error message we emit
|
||||
let mut proc_macro_locator = locator.clone();
|
||||
|
||||
// Try to load a proc macro
|
||||
proc_macro_locator.is_proc_macro = true;
|
||||
// Try to load a proc macro
|
||||
proc_macro_locator.for_target_proc_macro(self.sess, path_kind);
|
||||
|
||||
// Load the proc macro crate for the target
|
||||
let target_result =
|
||||
match self.load(&mut proc_macro_locator, &mut CrateRejections::default())? {
|
||||
Some(LoadResult::Previous(cnum)) => {
|
||||
return Ok(Some((LoadResult::Previous(cnum), None)));
|
||||
}
|
||||
Some(LoadResult::Loaded(library)) => Some(LoadResult::Loaded(library)),
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
// Use the existing crate_rejections as we want the error message to be affected by
|
||||
// loading the host proc macro.
|
||||
*crate_rejections = CrateRejections::default();
|
||||
|
||||
// Load the proc macro crate for the host
|
||||
locator.for_proc_macro(self.sess, path_kind);
|
||||
|
||||
// Load the proc macro crate for the target
|
||||
let (locator, target_result) = if self.sess.opts.unstable_opts.dual_proc_macros {
|
||||
proc_macro_locator.reset();
|
||||
let result = match self.load(&mut proc_macro_locator)? {
|
||||
Some(LoadResult::Previous(cnum)) => {
|
||||
return Ok(Some((LoadResult::Previous(cnum), None)));
|
||||
}
|
||||
Some(LoadResult::Loaded(library)) => Some(LoadResult::Loaded(library)),
|
||||
None => return Ok(None),
|
||||
};
|
||||
locator.hash = host_hash;
|
||||
// Use the locator when looking for the host proc macro crate, as that is required
|
||||
// so we want it to affect the error message
|
||||
(locator, result)
|
||||
} else {
|
||||
(&mut proc_macro_locator, None)
|
||||
};
|
||||
|
||||
// Load the proc macro crate for the host
|
||||
let Some(host_result) = self.load(locator, crate_rejections)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
locator.reset();
|
||||
locator.is_proc_macro = true;
|
||||
locator.target = &self.sess.host;
|
||||
locator.tuple = TargetTuple::from_tuple(config::host_tuple());
|
||||
locator.filesearch = self.sess.host_filesearch();
|
||||
locator.path_kind = path_kind;
|
||||
|
||||
let Some(host_result) = self.load(locator)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
Ok(Some(if self.sess.opts.unstable_opts.dual_proc_macros {
|
||||
let host_result = match host_result {
|
||||
LoadResult::Previous(..) => {
|
||||
panic!("host and target proc macros must be loaded in lock-step")
|
||||
}
|
||||
LoadResult::Loaded(library) => library,
|
||||
};
|
||||
(target_result.unwrap(), Some(host_result))
|
||||
Ok(Some((target_result.unwrap(), Some(host_result))))
|
||||
} else {
|
||||
(host_result, None)
|
||||
}))
|
||||
// Use a new crate locator and crate rejections so trying to load a proc macro doesn't
|
||||
// affect the error message we emit
|
||||
let mut proc_macro_locator = locator.clone();
|
||||
|
||||
// Load the proc macro crate for the host
|
||||
proc_macro_locator.for_proc_macro(self.sess, path_kind);
|
||||
|
||||
let Some(host_result) =
|
||||
self.load(&mut proc_macro_locator, &mut CrateRejections::default())?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
Ok(Some((host_result, None)))
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_crate(
|
||||
|
|
@ -799,15 +804,21 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
extra_filename,
|
||||
path_kind,
|
||||
);
|
||||
let mut crate_rejections = CrateRejections::default();
|
||||
|
||||
match self.load(&mut locator)? {
|
||||
match self.load(&mut locator, &mut crate_rejections)? {
|
||||
Some(res) => (res, None),
|
||||
None => {
|
||||
info!("falling back to loading proc_macro");
|
||||
dep_kind = CrateDepKind::MacrosOnly;
|
||||
match self.load_proc_macro(&mut locator, path_kind, host_hash)? {
|
||||
match self.load_proc_macro(
|
||||
&mut locator,
|
||||
&mut crate_rejections,
|
||||
path_kind,
|
||||
host_hash,
|
||||
)? {
|
||||
Some(res) => res,
|
||||
None => return Err(locator.into_error(dep_root.cloned())),
|
||||
None => return Err(locator.into_error(crate_rejections, dep_root.cloned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -837,8 +848,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn load(&self, locator: &mut CrateLocator<'_>) -> Result<Option<LoadResult>, CrateError> {
|
||||
let Some(library) = locator.maybe_load_library_crate()? else {
|
||||
fn load(
|
||||
&self,
|
||||
locator: &CrateLocator<'_>,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
) -> Result<Option<LoadResult>, CrateError> {
|
||||
let Some(library) = locator.maybe_load_library_crate(crate_rejections)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -224,11 +224,11 @@ use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
|
|||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_fs_util::try_canonicalize;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::cstore::CrateSource;
|
||||
use rustc_session::filesearch::FileSearch;
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::utils::CanonicalizedPath;
|
||||
use rustc_session::{Session, config};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::spec::{Target, TargetTuple};
|
||||
use tempfile::Builder as TempFileBuilder;
|
||||
|
|
@ -251,14 +251,11 @@ pub(crate) struct CrateLocator<'a> {
|
|||
exact_paths: Vec<CanonicalizedPath>,
|
||||
pub hash: Option<Svh>,
|
||||
extra_filename: Option<&'a str>,
|
||||
pub target: &'a Target,
|
||||
pub tuple: TargetTuple,
|
||||
pub filesearch: &'a FileSearch,
|
||||
pub is_proc_macro: bool,
|
||||
|
||||
pub path_kind: PathKind,
|
||||
// Mutable in-progress state or output.
|
||||
crate_rejections: CrateRejections,
|
||||
target: &'a Target,
|
||||
tuple: TargetTuple,
|
||||
filesearch: &'a FileSearch,
|
||||
is_proc_macro: bool,
|
||||
path_kind: PathKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -346,34 +343,46 @@ impl<'a> CrateLocator<'a> {
|
|||
filesearch: sess.target_filesearch(),
|
||||
path_kind,
|
||||
is_proc_macro: false,
|
||||
crate_rejections: CrateRejections::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn reset(&mut self) {
|
||||
self.crate_rejections.via_hash.clear();
|
||||
self.crate_rejections.via_triple.clear();
|
||||
self.crate_rejections.via_kind.clear();
|
||||
self.crate_rejections.via_version.clear();
|
||||
self.crate_rejections.via_filename.clear();
|
||||
self.crate_rejections.via_invalid.clear();
|
||||
pub(crate) fn for_proc_macro(&mut self, sess: &'a Session, path_kind: PathKind) {
|
||||
self.is_proc_macro = true;
|
||||
self.target = &sess.host;
|
||||
self.tuple = TargetTuple::from_tuple(config::host_tuple());
|
||||
self.filesearch = sess.host_filesearch();
|
||||
self.path_kind = path_kind;
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_load_library_crate(&mut self) -> Result<Option<Library>, CrateError> {
|
||||
pub(crate) fn for_target_proc_macro(&mut self, sess: &'a Session, path_kind: PathKind) {
|
||||
self.is_proc_macro = true;
|
||||
self.target = &sess.target;
|
||||
self.tuple = sess.opts.target_triple.clone();
|
||||
self.filesearch = sess.target_filesearch();
|
||||
self.path_kind = path_kind;
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_load_library_crate(
|
||||
&self,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
) -> Result<Option<Library>, CrateError> {
|
||||
if !self.exact_paths.is_empty() {
|
||||
return self.find_commandline_library();
|
||||
return self.find_commandline_library(crate_rejections);
|
||||
}
|
||||
let mut seen_paths = FxHashSet::default();
|
||||
if let Some(extra_filename) = self.extra_filename {
|
||||
if let library @ Some(_) = self.find_library_crate(extra_filename, &mut seen_paths)? {
|
||||
if let library @ Some(_) =
|
||||
self.find_library_crate(crate_rejections, extra_filename, &mut seen_paths)?
|
||||
{
|
||||
return Ok(library);
|
||||
}
|
||||
}
|
||||
self.find_library_crate("", &mut seen_paths)
|
||||
self.find_library_crate(crate_rejections, "", &mut seen_paths)
|
||||
}
|
||||
|
||||
fn find_library_crate(
|
||||
&mut self,
|
||||
&self,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
extra_prefix: &str,
|
||||
seen_paths: &mut FxHashSet<PathBuf>,
|
||||
) -> Result<Option<Library>, CrateError> {
|
||||
|
|
@ -437,8 +446,8 @@ impl<'a> CrateLocator<'a> {
|
|||
let (rlibs, rmetas, dylibs, interfaces) =
|
||||
candidates.entry(hash).or_default();
|
||||
{
|
||||
// As a perforamnce optimisation we canonicalize the path and skip
|
||||
// ones we've already seeen. This allows us to ignore crates
|
||||
// As a performance optimisation we canonicalize the path and skip
|
||||
// ones we've already seen. This allows us to ignore crates
|
||||
// we know are exactual equal to ones we've already found.
|
||||
// Going to the same crate through different symlinks does not change the result.
|
||||
let path = try_canonicalize(&spf.path)
|
||||
|
|
@ -465,7 +474,7 @@ impl<'a> CrateLocator<'a> {
|
|||
.flatten()
|
||||
{
|
||||
for (_, spf) in static_matches {
|
||||
self.crate_rejections.via_kind.push(CrateMismatch {
|
||||
crate_rejections.via_kind.push(CrateMismatch {
|
||||
path: spf.path.to_path_buf(),
|
||||
got: "static".to_string(),
|
||||
});
|
||||
|
|
@ -483,7 +492,9 @@ impl<'a> CrateLocator<'a> {
|
|||
// search is being performed for.
|
||||
let mut libraries = FxIndexMap::default();
|
||||
for (_hash, (rlibs, rmetas, dylibs, interfaces)) in candidates {
|
||||
if let Some((svh, lib)) = self.extract_lib(rlibs, rmetas, dylibs, interfaces)? {
|
||||
if let Some((svh, lib)) =
|
||||
self.extract_lib(crate_rejections, rlibs, rmetas, dylibs, interfaces)?
|
||||
{
|
||||
libraries.insert(svh, lib);
|
||||
}
|
||||
}
|
||||
|
|
@ -495,13 +506,11 @@ impl<'a> CrateLocator<'a> {
|
|||
0 => Ok(None),
|
||||
1 => Ok(Some(libraries.into_iter().next().unwrap().1)),
|
||||
_ => {
|
||||
let mut libraries: Vec<_> = libraries.into_values().collect();
|
||||
|
||||
libraries.sort_by_cached_key(|lib| lib.source.paths().next().unwrap().clone());
|
||||
let candidates = libraries
|
||||
.iter()
|
||||
let mut candidates: Vec<PathBuf> = libraries
|
||||
.into_values()
|
||||
.map(|lib| lib.source.paths().next().unwrap().clone())
|
||||
.collect::<Vec<_>>();
|
||||
.collect();
|
||||
candidates.sort();
|
||||
|
||||
Err(CrateError::MultipleCandidates(
|
||||
self.crate_name,
|
||||
|
|
@ -514,7 +523,8 @@ impl<'a> CrateLocator<'a> {
|
|||
}
|
||||
|
||||
fn extract_lib(
|
||||
&mut self,
|
||||
&self,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
rlibs: FxIndexMap<PathBuf, PathKind>,
|
||||
rmetas: FxIndexMap<PathBuf, PathKind>,
|
||||
dylibs: FxIndexMap<PathBuf, PathKind>,
|
||||
|
|
@ -526,10 +536,11 @@ impl<'a> CrateLocator<'a> {
|
|||
// Make sure there's at most one rlib and at most one dylib.
|
||||
//
|
||||
// See comment in `extract_one` below.
|
||||
let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot)?;
|
||||
let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot)?;
|
||||
let sdylib_interface = self.extract_one(interfaces, CrateFlavor::SDylib, &mut slot)?;
|
||||
let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot)?;
|
||||
let rmeta = self.extract_one(crate_rejections, rmetas, CrateFlavor::Rmeta, &mut slot)?;
|
||||
let rlib = self.extract_one(crate_rejections, rlibs, CrateFlavor::Rlib, &mut slot)?;
|
||||
let sdylib_interface =
|
||||
self.extract_one(crate_rejections, interfaces, CrateFlavor::SDylib, &mut slot)?;
|
||||
let dylib = self.extract_one(crate_rejections, dylibs, CrateFlavor::Dylib, &mut slot)?;
|
||||
|
||||
if sdylib_interface.is_some() && dylib.is_none() {
|
||||
return Err(CrateError::FullMetadataNotFound(self.crate_name, CrateFlavor::SDylib));
|
||||
|
|
@ -563,7 +574,8 @@ impl<'a> CrateLocator<'a> {
|
|||
//
|
||||
// The `PathBuf` in `slot` will only be used for diagnostic purposes.
|
||||
fn extract_one(
|
||||
&mut self,
|
||||
&self,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
m: FxIndexMap<PathBuf, PathKind>,
|
||||
flavor: CrateFlavor,
|
||||
slot: &mut Option<(Svh, MetadataBlob, PathBuf, CrateFlavor)>,
|
||||
|
|
@ -605,7 +617,7 @@ impl<'a> CrateLocator<'a> {
|
|||
Some(self.crate_name),
|
||||
) {
|
||||
Ok(blob) => {
|
||||
if let Some(h) = self.crate_matches(&blob, &lib) {
|
||||
if let Some(h) = self.crate_matches(crate_rejections, &blob, &lib) {
|
||||
(h, blob)
|
||||
} else {
|
||||
info!("metadata mismatch");
|
||||
|
|
@ -620,7 +632,7 @@ impl<'a> CrateLocator<'a> {
|
|||
"Rejecting via version: expected {} got {}",
|
||||
expected_version, found_version
|
||||
);
|
||||
self.crate_rejections
|
||||
crate_rejections
|
||||
.via_version
|
||||
.push(CrateMismatch { path: lib, got: found_version });
|
||||
continue;
|
||||
|
|
@ -635,7 +647,7 @@ impl<'a> CrateLocator<'a> {
|
|||
// The file was present and created by the same compiler version, but we
|
||||
// couldn't load it for some reason. Give a hard error instead of silently
|
||||
// ignoring it, but only if we would have given an error anyway.
|
||||
self.crate_rejections.via_invalid.push(CrateMismatch { path: lib, got: err });
|
||||
crate_rejections.via_invalid.push(CrateMismatch { path: lib, got: err });
|
||||
continue;
|
||||
}
|
||||
Err(err @ MetadataError::NotPresent(_)) => {
|
||||
|
|
@ -713,7 +725,12 @@ impl<'a> CrateLocator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
|
||||
fn crate_matches(
|
||||
&self,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
metadata: &MetadataBlob,
|
||||
libpath: &Path,
|
||||
) -> Option<Svh> {
|
||||
let header = metadata.get_header();
|
||||
if header.is_proc_macro_crate != self.is_proc_macro {
|
||||
info!(
|
||||
|
|
@ -730,7 +747,7 @@ impl<'a> CrateLocator<'a> {
|
|||
|
||||
if header.triple != self.tuple {
|
||||
info!("Rejecting via crate triple: expected {} got {}", self.tuple, header.triple);
|
||||
self.crate_rejections.via_triple.push(CrateMismatch {
|
||||
crate_rejections.via_triple.push(CrateMismatch {
|
||||
path: libpath.to_path_buf(),
|
||||
got: header.triple.to_string(),
|
||||
});
|
||||
|
|
@ -741,7 +758,7 @@ impl<'a> CrateLocator<'a> {
|
|||
if let Some(expected_hash) = self.hash {
|
||||
if hash != expected_hash {
|
||||
info!("Rejecting via hash: expected {} got {}", expected_hash, hash);
|
||||
self.crate_rejections
|
||||
crate_rejections
|
||||
.via_hash
|
||||
.push(CrateMismatch { path: libpath.to_path_buf(), got: hash.to_string() });
|
||||
return None;
|
||||
|
|
@ -751,7 +768,10 @@ impl<'a> CrateLocator<'a> {
|
|||
Some(hash)
|
||||
}
|
||||
|
||||
fn find_commandline_library(&mut self) -> Result<Option<Library>, CrateError> {
|
||||
fn find_commandline_library(
|
||||
&self,
|
||||
crate_rejections: &mut CrateRejections,
|
||||
) -> Result<Option<Library>, CrateError> {
|
||||
// First, filter out all libraries that look suspicious. We only accept
|
||||
// files which actually exist that have the correct naming scheme for
|
||||
// rlibs/dylibs.
|
||||
|
|
@ -796,24 +816,28 @@ impl<'a> CrateLocator<'a> {
|
|||
dylibs.insert(loc_canon.clone(), PathKind::ExternFlag);
|
||||
continue;
|
||||
}
|
||||
self.crate_rejections
|
||||
crate_rejections
|
||||
.via_filename
|
||||
.push(CrateMismatch { path: loc_orig.clone(), got: String::new() });
|
||||
}
|
||||
|
||||
// Extract the dylib/rlib/rmeta triple.
|
||||
self.extract_lib(rlibs, rmetas, dylibs, sdylib_interfaces)
|
||||
self.extract_lib(crate_rejections, rlibs, rmetas, dylibs, sdylib_interfaces)
|
||||
.map(|opt| opt.map(|(_, lib)| lib))
|
||||
}
|
||||
|
||||
pub(crate) fn into_error(self, dep_root: Option<CratePaths>) -> CrateError {
|
||||
pub(crate) fn into_error(
|
||||
self,
|
||||
crate_rejections: CrateRejections,
|
||||
dep_root: Option<CratePaths>,
|
||||
) -> CrateError {
|
||||
CrateError::LocatorCombined(Box::new(CombinedLocatorError {
|
||||
crate_name: self.crate_name,
|
||||
dep_root,
|
||||
triple: self.tuple,
|
||||
dll_prefix: self.target.dll_prefix.to_string(),
|
||||
dll_suffix: self.target.dll_suffix.to_string(),
|
||||
crate_rejections: self.crate_rejections,
|
||||
crate_rejections,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
@ -993,7 +1017,7 @@ struct CrateMismatch {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct CrateRejections {
|
||||
pub(crate) struct CrateRejections {
|
||||
via_hash: Vec<CrateMismatch>,
|
||||
via_triple: Vec<CrateMismatch>,
|
||||
via_kind: Vec<CrateMismatch>,
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ impl<'tcx> From<ErrorHandled> for ValTreeCreationError<'tcx> {
|
|||
|
||||
impl<'tcx> From<InterpErrorInfo<'tcx>> for ValTreeCreationError<'tcx> {
|
||||
fn from(err: InterpErrorInfo<'tcx>) -> Self {
|
||||
// An error ocurred outside the const-eval query, as part of constructing the valtree. We
|
||||
// An error occurred outside the const-eval query, as part of constructing the valtree. We
|
||||
// don't currently preserve the details of this error, since `InterpErrorInfo` cannot be put
|
||||
// into a query result and it can only be access of some mutable or external memory.
|
||||
let (_kind, backtrace) = err.into_parts();
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ pub struct Body<'tcx> {
|
|||
/// us to see the difference and forego optimization on the inlined promoted items.
|
||||
pub phase: MirPhase,
|
||||
|
||||
/// How many passses we have executed since starting the current phase. Used for debug output.
|
||||
/// How many passes we have executed since starting the current phase. Used for debug output.
|
||||
pub pass_count: usize,
|
||||
|
||||
pub source: MirSource<'tcx>,
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ pub enum StatementKind<'tcx> {
|
|||
/// computing these locals.
|
||||
///
|
||||
/// If the local is already allocated, calling `StorageLive` again will implicitly free the
|
||||
/// local and then allocate fresh uninitilized memory. If a local is already deallocated,
|
||||
/// local and then allocate fresh uninitialized memory. If a local is already deallocated,
|
||||
/// calling `StorageDead` again is a NOP.
|
||||
StorageLive(Local),
|
||||
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ rustc_queries! {
|
|||
/// Returns whether the type alias given by `DefId` is lazy.
|
||||
///
|
||||
/// I.e., if the type alias expands / ought to expand to a [free] [alias type]
|
||||
/// instead of the underyling aliased type.
|
||||
/// instead of the underlying aliased type.
|
||||
///
|
||||
/// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -2287,7 +2287,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// All traits in the crate graph, including those not visible to the user.
|
||||
pub fn all_traits(self) -> impl Iterator<Item = DefId> {
|
||||
pub fn all_traits_including_private(self) -> impl Iterator<Item = DefId> {
|
||||
iter::once(LOCAL_CRATE)
|
||||
.chain(self.crates(()).iter().copied())
|
||||
.flat_map(move |cnum| self.traits(cnum).iter().copied())
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pub enum InstanceKind<'tcx> {
|
|||
/// - coroutines
|
||||
Item(DefId),
|
||||
|
||||
/// An intrinsic `fn` item (with`#[rustc_instrinsic]`).
|
||||
/// An intrinsic `fn` item (with`#[rustc_intrinsic]`).
|
||||
///
|
||||
/// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
|
||||
/// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
|
||||
|
|
@ -445,10 +445,10 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// async_drop_in_place<T>::coroutine.poll, when T is a standart coroutine,
|
||||
// async_drop_in_place<T>::coroutine.poll, when T is a standard coroutine,
|
||||
// should be resolved to this coroutine's future_drop_poll (through FutureDropPollShim proxy).
|
||||
// async_drop_in_place<async_drop_in_place<T>::coroutine>::coroutine.poll,
|
||||
// when T is a standart coroutine, should be resolved to this coroutine's future_drop_poll.
|
||||
// when T is a standard coroutine, should be resolved to this coroutine's future_drop_poll.
|
||||
// async_drop_in_place<async_drop_in_place<T>::coroutine>::coroutine.poll,
|
||||
// when T is not a coroutine, should be resolved to the innermost
|
||||
// async_drop_in_place<T>::coroutine's poll function (through FutureDropPollShim proxy)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ fn true_significant_drop_ty<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the list of types with a "potentially sigificant" that may be dropped
|
||||
/// Returns the list of types with a "potentially significant" that may be dropped
|
||||
/// by dropping a value of type `ty`.
|
||||
#[instrument(level = "trace", skip(tcx, typing_env))]
|
||||
pub fn extract_component_raw<'tcx>(
|
||||
|
|
|
|||
|
|
@ -1676,7 +1676,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
/// This is particularly useful for getting the type of the result of
|
||||
/// [`UnOp::PtrMetadata`](crate::mir::UnOp::PtrMetadata).
|
||||
///
|
||||
/// Panics if `self` is not dereferencable.
|
||||
/// Panics if `self` is not dereferenceable.
|
||||
#[track_caller]
|
||||
pub fn pointee_metadata_ty_or_projection(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
let Some(pointee_ty) = self.builtin_deref(true) else {
|
||||
|
|
|
|||
|
|
@ -365,11 +365,11 @@ fn extend_type_not_partial_eq<'tcx>(
|
|||
struct UsedParamsNeedInstantiationVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structual.
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structural.
|
||||
adts_with_manual_partialeq: FxHashSet<Span>,
|
||||
/// The type has no `PartialEq` implementation, neither manual or derived.
|
||||
adts_without_partialeq: FxHashSet<Span>,
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structual,
|
||||
/// The user has written `impl PartialEq for Ty` which means it's non-structural,
|
||||
/// but we don't have a span to point at, so we'll just add them as a `note`.
|
||||
manual: FxHashSet<Ty<'tcx>>,
|
||||
/// The type has no `PartialEq` implementation, neither manual or derived, but
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ fn insert_discr_cast_to_u128<'tcx>(
|
|||
StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))),
|
||||
));
|
||||
|
||||
// Cast the discriminant to a u128 (base for comparisions of enum discriminants).
|
||||
// Cast the discriminant to a u128 (base for comparisons of enum discriminants).
|
||||
let const_u128 = Ty::new_uint(tcx, ty::UintTy::U128);
|
||||
let rvalue = Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr_in_discr_ty), const_u128);
|
||||
let discr = local_decls.push(LocalDecl::with_source_info(const_u128, source_info)).into();
|
||||
|
|
@ -467,7 +467,7 @@ fn insert_niche_check<'tcx>(
|
|||
source_info,
|
||||
);
|
||||
|
||||
// Compare the discriminant agains the valid_range.
|
||||
// Compare the discriminant against the valid_range.
|
||||
let start_const = Operand::Constant(Box::new(ConstOperand {
|
||||
span: source_info.span,
|
||||
user_ty: None,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
//! _b = some other value // also has VnIndex i
|
||||
//! ```
|
||||
//!
|
||||
//! We consider it to be replacable by:
|
||||
//! We consider it to be replaceable by:
|
||||
//! ```ignore (MIR)
|
||||
//! _a = some value // has VnIndex i
|
||||
//! // some MIR
|
||||
|
|
|
|||
|
|
@ -982,14 +982,16 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
|
|||
// Insert all of the (mapped) parts of the callee body into the caller.
|
||||
caller_body.local_decls.extend(callee_body.drain_vars_and_temps());
|
||||
caller_body.source_scopes.append(&mut callee_body.source_scopes);
|
||||
|
||||
// only "full" debug promises any variable-level information
|
||||
if tcx
|
||||
.sess
|
||||
.opts
|
||||
.unstable_opts
|
||||
.inline_mir_preserve_debug
|
||||
.unwrap_or(tcx.sess.opts.debuginfo != DebugInfo::None)
|
||||
.unwrap_or(tcx.sess.opts.debuginfo == DebugInfo::Full)
|
||||
{
|
||||
// Note that we need to preserve these in the standard library so that
|
||||
// -Zinline-mir-preserve-debug is enabled when building the standard library, so that
|
||||
// people working on rust can build with or without debuginfo while
|
||||
// still getting consistent results from the mir-opt tests.
|
||||
caller_body.var_debug_info.append(&mut callee_body.var_debug_info);
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ struct LocalLabel<'a> {
|
|||
/// A custom `Subdiagnostic` implementation so that the notes are delivered in a specific order
|
||||
impl Subdiagnostic for LocalLabel<'_> {
|
||||
fn add_to_diag<G: rustc_errors::EmissionGuarantee>(self, diag: &mut rustc_errors::Diag<'_, G>) {
|
||||
// Becuase parent uses this field , we need to remove it delay before adding it.
|
||||
// Because parent uses this field , we need to remove it delay before adding it.
|
||||
diag.remove_arg("name");
|
||||
diag.arg("name", self.name);
|
||||
diag.remove_arg("is_generated_name");
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ fn compute_replacement<'tcx>(
|
|||
// reborrowed references.
|
||||
let mut storage_to_remove = DenseBitSet::new_empty(body.local_decls.len());
|
||||
|
||||
let fully_replacable_locals = fully_replacable_locals(ssa);
|
||||
let fully_replaceable_locals = fully_replaceable_locals(ssa);
|
||||
|
||||
// Returns true iff we can use `place` as a pointee.
|
||||
//
|
||||
|
|
@ -204,7 +204,7 @@ fn compute_replacement<'tcx>(
|
|||
let needs_unique = ty.is_mutable_ptr();
|
||||
|
||||
// If this a mutable reference that we cannot fully replace, mark it as unknown.
|
||||
if needs_unique && !fully_replacable_locals.contains(local) {
|
||||
if needs_unique && !fully_replaceable_locals.contains(local) {
|
||||
debug!("not fully replaceable");
|
||||
continue;
|
||||
}
|
||||
|
|
@ -303,7 +303,7 @@ fn compute_replacement<'tcx>(
|
|||
|
||||
// This a reborrow chain, recursively allow the replacement.
|
||||
//
|
||||
// This also allows to detect cases where `target.local` is not replacable,
|
||||
// This also allows to detect cases where `target.local` is not replaceable,
|
||||
// and mark it as such.
|
||||
if let &[PlaceElem::Deref] = &target.projection[..] {
|
||||
assert!(perform_opt);
|
||||
|
|
@ -313,7 +313,7 @@ fn compute_replacement<'tcx>(
|
|||
} else if perform_opt {
|
||||
self.allowed_replacements.insert((target.local, loc));
|
||||
} else if needs_unique {
|
||||
// This mutable reference is not fully replacable, so drop it.
|
||||
// This mutable reference is not fully replaceable, so drop it.
|
||||
self.targets[place.local] = Value::Unknown;
|
||||
}
|
||||
}
|
||||
|
|
@ -326,22 +326,22 @@ fn compute_replacement<'tcx>(
|
|||
|
||||
/// Compute the set of locals that can be fully replaced.
|
||||
///
|
||||
/// We consider a local to be replacable iff it's only used in a `Deref` projection `*_local` or
|
||||
/// We consider a local to be replaceable iff it's only used in a `Deref` projection `*_local` or
|
||||
/// non-use position (like storage statements and debuginfo).
|
||||
fn fully_replacable_locals(ssa: &SsaLocals) -> DenseBitSet<Local> {
|
||||
let mut replacable = DenseBitSet::new_empty(ssa.num_locals());
|
||||
fn fully_replaceable_locals(ssa: &SsaLocals) -> DenseBitSet<Local> {
|
||||
let mut replaceable = DenseBitSet::new_empty(ssa.num_locals());
|
||||
|
||||
// First pass: for each local, whether its uses can be fully replaced.
|
||||
for local in ssa.locals() {
|
||||
if ssa.num_direct_uses(local) == 0 {
|
||||
replacable.insert(local);
|
||||
replaceable.insert(local);
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: a local can only be fully replaced if all its copies can.
|
||||
ssa.meet_copy_equivalence(&mut replacable);
|
||||
ssa.meet_copy_equivalence(&mut replaceable);
|
||||
|
||||
replacable
|
||||
replaceable
|
||||
}
|
||||
|
||||
/// Utility to help performing substitution of `*pattern` by `target`.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub(super) fn provide(providers: &mut Providers) {
|
|||
providers.mir_shims = make_shim;
|
||||
}
|
||||
|
||||
// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> acceses
|
||||
// Replace Pin<&mut ImplCoroutine> accesses (_1.0) into Pin<&mut ProxyCoroutine> accesses
|
||||
struct FixProxyFutureDropVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
replace_to: Local,
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ fn collect_items_rec<'tcx>(
|
|||
});
|
||||
}
|
||||
// Only updating `usage_map` for used items as otherwise we may be inserting the same item
|
||||
// multiple times (if it is first 'mentioned' and then later actuall used), and the usage map
|
||||
// multiple times (if it is first 'mentioned' and then later actually used), and the usage map
|
||||
// logic does not like that.
|
||||
// This is part of the output of collection and hence only relevant for "used" items.
|
||||
// ("Mentioned" items are only considered internally during collection.)
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ fn mono_item_visibility<'tcx>(
|
|||
// * First is weak lang items. These are basically mechanisms for
|
||||
// libcore to forward-reference symbols defined later in crates like
|
||||
// the standard library or `#[panic_handler]` definitions. The
|
||||
// definition of these weak lang items needs to be referencable by
|
||||
// definition of these weak lang items needs to be referenceable by
|
||||
// libcore, so we're no longer a candidate for internalization.
|
||||
// Removal of these functions can't be done by LLVM but rather must be
|
||||
// done by the linker as it's a non-local decision.
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ where
|
|||
/// Register additional assumptions for aliases corresponding to `[const]` item bounds.
|
||||
///
|
||||
/// Unlike item bounds, they are not simply implied by the well-formedness of the alias.
|
||||
/// Instead, they only hold if the const conditons on the alias also hold. This is why
|
||||
/// Instead, they only hold if the const conditions on the alias also hold. This is why
|
||||
/// we also register the const conditions of the alias after matching the goal against
|
||||
/// the assumption.
|
||||
fn consider_additional_alias_assumptions(
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ where
|
|||
/// This takes the `shallow_certainty` which represents whether we're confident
|
||||
/// that the final result of the current goal only depends on the nested goals.
|
||||
///
|
||||
/// In case this is `Certainy::Maybe`, there may still be additional nested goals
|
||||
/// In case this is `Certainty::Maybe`, there may still be additional nested goals
|
||||
/// or inference constraints required for this candidate to be hold. The candidate
|
||||
/// always requires all already added constraints and nested goals.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ where
|
|||
// Right now this includes both the impl and the assoc item where bounds,
|
||||
// and I don't think the assoc item where-bounds are allowed to be coinductive.
|
||||
//
|
||||
// Projecting to the IAT also "steps out the impl contructor", so we would have
|
||||
// Projecting to the IAT also "steps out the impl constructor", so we would have
|
||||
// to be very careful when changing the impl where-clauses to be productive.
|
||||
self.add_goals(
|
||||
GoalSource::Misc,
|
||||
|
|
|
|||
|
|
@ -1301,7 +1301,7 @@ where
|
|||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// FIXME(#57893): For backwards compatability with the old trait solver implementation,
|
||||
/// FIXME(#57893): For backwards compatibility with the old trait solver implementation,
|
||||
/// we need to handle overlap between builtin and user-written impls for trait objects.
|
||||
///
|
||||
/// This overlap is unsound in general and something which we intend to fix separately.
|
||||
|
|
|
|||
|
|
@ -298,6 +298,8 @@ fn emit_malformed_attribute(
|
|||
| sym::deprecated
|
||||
| sym::optimize
|
||||
| sym::cold
|
||||
| sym::target_feature
|
||||
| sym::rustc_allow_const_fn_unstable
|
||||
| sym::naked
|
||||
| sym::no_mangle
|
||||
| sym::must_use
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ passes_no_sanitize =
|
|||
`#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
|
||||
.label = not {$accepted_kind}
|
||||
|
||||
passes_non_exaustive_with_default_field_values =
|
||||
passes_non_exhaustive_with_default_field_values =
|
||||
`#[non_exhaustive]` can't be used to annotate items with default field values
|
||||
.label = this struct has default field values
|
||||
|
||||
|
|
|
|||
|
|
@ -146,20 +146,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::ConstContinue(attr_span)) => {
|
||||
self.check_const_continue(hir_id, *attr_span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self
|
||||
.check_allow_internal_unstable(
|
||||
hir_id,
|
||||
syms.first().unwrap().1,
|
||||
span,
|
||||
target,
|
||||
attrs,
|
||||
),
|
||||
Attribute::Parsed(AttributeKind::AllowConstFnUnstable { .. }) => {
|
||||
self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target)
|
||||
Attribute::Parsed(AttributeKind::AllowInternalUnstable(_, first_span)) => {
|
||||
self.check_allow_internal_unstable(hir_id, *first_span, span, target, attrs)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AllowConstFnUnstable(_, first_span)) => {
|
||||
self.check_rustc_allow_const_fn_unstable(hir_id, *first_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Deprecation { .. }) => {
|
||||
self.check_deprecated(hir_id, attr, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::TargetFeature(_, attr_span)) => {
|
||||
self.check_target_feature(hir_id, *attr_span, span, target, attrs)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */
|
||||
|
|
@ -230,9 +228,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item),
|
||||
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
|
||||
[sym::target_feature, ..] => {
|
||||
self.check_target_feature(hir_id, attr, span, target, attrs)
|
||||
}
|
||||
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
|
||||
[sym::doc, ..] => self.check_doc_attrs(
|
||||
attr,
|
||||
|
|
@ -816,7 +811,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
fn check_target_feature(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
|
|
@ -834,7 +829,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
|
||||
|
||||
self.dcx().emit_err(errors::LangItemWithTargetFeature {
|
||||
attr_span: attr.span(),
|
||||
attr_span,
|
||||
name: lang_item,
|
||||
sig_span: sig.span,
|
||||
});
|
||||
|
|
@ -846,7 +841,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
attr_span,
|
||||
errors::TargetFeatureOnStatement,
|
||||
);
|
||||
}
|
||||
|
|
@ -855,11 +850,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "target_feature");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "target_feature");
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
|
||||
attr_span: attr.span(),
|
||||
attr_span,
|
||||
defn_span: span,
|
||||
on_crate: hir_id == CRATE_HIR_ID,
|
||||
});
|
||||
|
|
@ -2169,7 +2164,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
fn check_rustc_allow_const_fn_unstable(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
attr_span: Span,
|
||||
span: Span,
|
||||
target: Target,
|
||||
) {
|
||||
|
|
@ -2181,15 +2176,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => self
|
||||
.inline_attr_str_error_with_macro_def(
|
||||
hir_id,
|
||||
attr.span(),
|
||||
"allow_internal_unstable",
|
||||
),
|
||||
.inline_attr_str_error_with_macro_def(hir_id, attr_span, "allow_internal_unstable"),
|
||||
_ => {
|
||||
self.tcx
|
||||
.dcx()
|
||||
.emit_err(errors::RustcAllowConstFnUnstable { attr_span: attr.span(), span });
|
||||
self.tcx.dcx().emit_err(errors::RustcAllowConstFnUnstable { attr_span, span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2323,8 +2312,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
return;
|
||||
}
|
||||
AttributeKind::TargetFeature(features, span) if features.len() == 0 => {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
*span,
|
||||
errors::Unused {
|
||||
attr_span: *span,
|
||||
note: errors::UnusedNote::EmptyList { name: sym::target_feature },
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Warn on useless empty attributes.
|
||||
|
|
@ -2336,7 +2337,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
sym::deny,
|
||||
sym::forbid,
|
||||
sym::feature,
|
||||
sym::target_feature,
|
||||
]) && attr.meta_item_list().is_some_and(|list| list.is_empty())
|
||||
{
|
||||
errors::UnusedNote::EmptyList { name: attr.name().unwrap() }
|
||||
|
|
|
|||
|
|
@ -1199,7 +1199,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
|
|||
let def_kind = tcx.def_kind(item.owner_id);
|
||||
|
||||
let mut dead_codes = Vec::new();
|
||||
// Only diagnose unused assoc items in inherient impl and used trait,
|
||||
// Only diagnose unused assoc items in inherent impl and used trait,
|
||||
// for unused assoc items in impls of trait,
|
||||
// we have diagnosed them in the trait if they are unused,
|
||||
// for unused assoc items in unused trait,
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ pub(crate) struct NonExhaustiveWrongLocation {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_non_exaustive_with_default_field_values)]
|
||||
#[diag(passes_non_exhaustive_with_default_field_values)]
|
||||
pub(crate) struct NonExhaustiveWithDefaultFieldValues {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
//! # Constructors and fields
|
||||
//!
|
||||
//! In the value `Pair(Some(0), true)`, `Pair` is called the constructor of the value, and `Some(0)`
|
||||
//! and `true` are its fields. Every matcheable value can be decomposed in this way. Examples of
|
||||
//! and `true` are its fields. Every matchable value can be decomposed in this way. Examples of
|
||||
//! constructors are: `Some`, `None`, `(,)` (the 2-tuple constructor), `Foo {..}` (the constructor
|
||||
//! for a struct `Foo`), and `2` (the constructor for the number `2`).
|
||||
//!
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
//! [`Constructor::is_covered_by`].
|
||||
//!
|
||||
//! Note 1: variable bindings (like the `x` in `Some(x)`) match anything, so we treat them as wildcards.
|
||||
//! Note 2: this only applies to matcheable values. For example a value of type `Rc<u64>` can't be
|
||||
//! Note 2: this only applies to matchable values. For example a value of type `Rc<u64>` can't be
|
||||
//! deconstructed that way.
|
||||
//!
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -1342,7 +1342,7 @@ impl DepNodeColorMap {
|
|||
|
||||
/// This tries to atomically mark a node green and assign `index` as the new
|
||||
/// index. This returns `Ok` if `index` gets assigned, otherwise it returns
|
||||
/// the alreadly allocated index in `Err`.
|
||||
/// the already allocated index in `Err`.
|
||||
#[inline]
|
||||
pub(super) fn try_mark_green(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -878,12 +878,12 @@ pub(crate) struct MacroExpandedExternCrateCannotShadowExternArguments {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_elided_anonymous_lifetime_report_error, code = E0637)]
|
||||
pub(crate) struct ElidedAnonymousLivetimeReportError {
|
||||
pub(crate) struct ElidedAnonymousLifetimeReportError {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) suggestion: Option<ElidedAnonymousLivetimeReportErrorSuggestion>,
|
||||
pub(crate) suggestion: Option<ElidedAnonymousLifetimeReportErrorSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
@ -897,7 +897,7 @@ pub(crate) struct LendingIteratorReportError {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_anonymous_lifetime_non_gat_report_error)]
|
||||
pub(crate) struct AnonymousLivetimeNonGatReportError {
|
||||
pub(crate) struct AnonymousLifetimeNonGatReportError {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) lifetime: Span,
|
||||
|
|
@ -908,7 +908,7 @@ pub(crate) struct AnonymousLivetimeNonGatReportError {
|
|||
resolve_elided_anonymous_lifetime_report_error_suggestion,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct ElidedAnonymousLivetimeReportErrorSuggestion {
|
||||
pub(crate) struct ElidedAnonymousLifetimeReportErrorSuggestion {
|
||||
#[suggestion_part(code = "for<'a> ")]
|
||||
pub(crate) lo: Span,
|
||||
#[suggestion_part(code = "'a ")]
|
||||
|
|
@ -917,7 +917,7 @@ pub(crate) struct ElidedAnonymousLivetimeReportErrorSuggestion {
|
|||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_explicit_anonymous_lifetime_report_error, code = E0637)]
|
||||
pub(crate) struct ExplicitAnonymousLivetimeReportError {
|
||||
pub(crate) struct ExplicitAnonymousLifetimeReportError {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
|
|
|
|||
|
|
@ -1892,7 +1892,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
..
|
||||
} = rib.kind
|
||||
{
|
||||
Some(errors::ElidedAnonymousLivetimeReportErrorSuggestion {
|
||||
Some(errors::ElidedAnonymousLifetimeReportErrorSuggestion {
|
||||
lo: span.shrink_to_lo(),
|
||||
hi: lifetime.ident.span.shrink_to_hi(),
|
||||
})
|
||||
|
|
@ -1918,18 +1918,18 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
ty: ty.span,
|
||||
});
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
|
||||
self.r.dcx().emit_err(errors::AnonymousLifetimeNonGatReportError {
|
||||
lifetime: lifetime.ident.span,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
|
||||
self.r.dcx().emit_err(errors::ElidedAnonymousLifetimeReportError {
|
||||
span: lifetime.ident.span,
|
||||
suggestion,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError {
|
||||
self.r.dcx().emit_err(errors::ExplicitAnonymousLifetimeReportError {
|
||||
span: lifetime.ident.span,
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ pub fn source_span_for_markdown_range_inner(
|
|||
let fragment = &fragments[i];
|
||||
let sp = fragment.span;
|
||||
// we need to calculate the span start,
|
||||
// then use that in our calulations for the span end
|
||||
// then use that in our calculations for the span end
|
||||
let lo = sp.lo() + BytePos(match_start as u32);
|
||||
return Some((
|
||||
sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)),
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use thin_vec::ThinVec;
|
|||
/// [utf8]: https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=1058865525#Codepage_layout
|
||||
const STR_SENTINEL: u8 = 0xC1;
|
||||
|
||||
/// For byte strings there are no bytes that canot occur. Just use this value
|
||||
/// For byte strings there are no bytes that cannot occur. Just use this value
|
||||
/// as a best-effort sentinel. There is no validation skipped so the potential
|
||||
/// for badness is lower than in the `STR_SENTINEL` case.
|
||||
const BYTE_STR_SENTINEL: u8 = 0xC2;
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ pub struct CoverageOptions {
|
|||
/// to keep supporting this flag, remove it.
|
||||
pub no_mir_spans: bool,
|
||||
|
||||
/// `-Zcoverage-options=discard-all-spans-in-codegen`: During codgen,
|
||||
/// `-Zcoverage-options=discard-all-spans-in-codegen`: During codegen,
|
||||
/// discard all coverage spans as though they were invalid. Needed by
|
||||
/// regression tests for #133606, because we don't have an easy way to
|
||||
/// reproduce it from actual source code.
|
||||
|
|
|
|||
|
|
@ -1545,7 +1545,7 @@ impl RemapFileNameExt for rustc_span::FileName {
|
|||
"one and only one scope should be passed to for_scope"
|
||||
);
|
||||
if sess.opts.unstable_opts.remap_path_scope.contains(scope) {
|
||||
self.prefer_remapped_unconditionaly()
|
||||
self.prefer_remapped_unconditionally()
|
||||
} else {
|
||||
self.prefer_local()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,11 @@ impl<'tcx> SmirCtxt<'tcx> {
|
|||
|
||||
pub fn all_trait_decls(&self) -> stable_mir::TraitDecls {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
|
||||
tables
|
||||
.tcx
|
||||
.all_traits_including_private()
|
||||
.map(|trait_def_id| tables.trait_def(trait_def_id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls {
|
||||
|
|
|
|||
|
|
@ -1600,7 +1600,7 @@ pub struct VariantIdx(usize);
|
|||
index_impl!(VariantIdx);
|
||||
|
||||
crate_def! {
|
||||
/// Hold infomation about an Opaque definition, particularly useful in `RPITIT`.
|
||||
/// Hold information about an Opaque definition, particularly useful in `RPITIT`.
|
||||
#[derive(Serialize)]
|
||||
pub OpaqueDef;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ impl FileName {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn prefer_remapped_unconditionaly(&self) -> FileNameDisplay<'_> {
|
||||
pub fn prefer_remapped_unconditionally(&self) -> FileNameDisplay<'_> {
|
||||
FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Remapped }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2397,7 +2397,7 @@ pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, s
|
|||
#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
|
||||
pub struct Ident {
|
||||
// `name` should never be the empty symbol. If you are considering that,
|
||||
// you are probably conflating "empty identifer with "no identifier" and
|
||||
// you are probably conflating "empty identifier with "no identifier" and
|
||||
// you should use `Option<Ident>` instead.
|
||||
pub name: Symbol,
|
||||
pub span: Span,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ where
|
|||
}
|
||||
|
||||
if arg.layout.is_single_vector_element(cx, size) {
|
||||
// pass non-transparant wrappers around a vector as `PassMode::Cast`
|
||||
// pass non-transparent wrappers around a vector as `PassMode::Cast`
|
||||
arg.cast_to(Reg { kind: RegKind::Vector, size });
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ edition = "2024"
|
|||
itertools = "0.12"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_attr_data_structures = {path = "../rustc_attr_data_structures"}
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{Diag, MultiSpan, pluralize};
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -8,7 +9,7 @@ use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
|||
use rustc_middle::ty::print::{FmtPrinter, Printer};
|
||||
use rustc_middle::ty::{self, Ty, suggest_constraining_type_param};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{BytePos, Span, Symbol, sym};
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
|
|
@ -535,8 +536,7 @@ impl<T> Trait<T> for X {
|
|||
}
|
||||
}
|
||||
TypeError::TargetFeatureCast(def_id) => {
|
||||
let target_spans =
|
||||
tcx.get_attrs(def_id, sym::target_feature).map(|attr| attr.span());
|
||||
let target_spans = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TargetFeature(.., span) => *span);
|
||||
diag.note(
|
||||
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1855,7 +1855,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let trait_def_id = trait_pred.def_id();
|
||||
let trait_name = self.tcx.item_name(trait_def_id);
|
||||
let crate_name = self.tcx.crate_name(trait_def_id.krate);
|
||||
if let Some(other_trait_def_id) = self.tcx.all_traits().find(|def_id| {
|
||||
if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| {
|
||||
trait_name == self.tcx.item_name(trait_def_id)
|
||||
&& trait_def_id.krate != def_id.krate
|
||||
&& crate_name == self.tcx.crate_name(def_id.krate)
|
||||
|
|
|
|||
|
|
@ -4432,7 +4432,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
candidate_impls: &[ImplCandidate<'tcx>],
|
||||
span: Span,
|
||||
) {
|
||||
// We can only suggest the slice coersion for function and binary operation arguments,
|
||||
// We can only suggest the slice coercion for function and binary operation arguments,
|
||||
// since the suggestion would make no sense in turbofish or call
|
||||
let (ObligationCauseCode::BinOp { .. } | ObligationCauseCode::FunctionArg { .. }) =
|
||||
obligation.cause.code()
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
// Do not suggest constraining the `&self` param, but rather the return type.
|
||||
// If that is wrong (because it is not sufficient), a follow up error will tell the
|
||||
// user to fix it. This way we lower the chances of *over* constraining, but still
|
||||
// get the cake of "correctly" contrained in two steps.
|
||||
// get the cake of "correctly" constrained in two steps.
|
||||
visitor.visit_ty_unambig(self.ty_sup);
|
||||
}
|
||||
visitor.visit_ty_unambig(self.ty_sub);
|
||||
|
|
|
|||
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