Merge from rustc

This commit is contained in:
Ralf Jung 2025-05-17 09:53:02 +02:00
commit 8f2da9b487
610 changed files with 8883 additions and 6671 deletions

View file

@ -0,0 +1,54 @@
---
name: Future Incompatibility Tracking Issue
about: A tracking issue for a future-incompatible lint
title: Tracking Issue for future-incompatibility lint XXX
labels: C-tracking-issue C-future-incompatibility T-compiler A-lints
---
<!--
Thank you for creating a future-incompatible tracking issue! 📜 These issues
are for lints that implement a future-incompatible warning.
Remember to add team labels to the tracking issue.
For something that affects the language, this would be `T-lang`, and for libs
it would be `T-libs-api`.
Also check for any `A-` labels to add.
-->
This is the **tracking issue** for the `YOUR_LINT_NAME_HERE` future-compatibility warning and other related errors. The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our [breaking change policy guidelines][guidelines].
[guidelines]: https://rustc-dev-guide.rust-lang.org/bug-fix-procedure.html
### What is the warning for?
*Describe the conditions that trigger the warning.*
### Why was this change made?
*Explain why this change was made. If there is additional context, like an MCP, link it here.*
### Example
```rust
// Include an example here.
```
### Recommendations
*Give some recommendations on how a user can avoid the lint.*
### When will this warning become a hard error?
*If known, describe the future plans. For example, how long you anticipate this being a warning, or if there are other factors that will influence the anticipated closure.*
### Steps
- [ ] Implement the lint
- [ ] Raise lint level to deny
- [ ] Make lint report in dependencies
- [ ] Switch to a hard error
### Implementation history
<!--
Include a list of all the PRs that were involved in implementing the lint.
-->

View file

@ -216,7 +216,7 @@ dependencies = [
"memchr",
"serde",
"serde_derive",
"winnow 0.7.9",
"winnow 0.7.10",
]
[[package]]
@ -487,9 +487,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.37"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
dependencies = [
"clap_builder",
"clap_derive",
@ -507,9 +507,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.37"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [
"anstream",
"anstyle",
@ -537,7 +537,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "clippy"
version = "0.1.88"
version = "0.1.89"
dependencies = [
"anstream",
"askama",
@ -569,7 +569,7 @@ dependencies = [
[[package]]
name = "clippy_config"
version = "0.1.88"
version = "0.1.89"
dependencies = [
"clippy_utils",
"itertools",
@ -594,7 +594,7 @@ dependencies = [
[[package]]
name = "clippy_lints"
version = "0.1.88"
version = "0.1.89"
dependencies = [
"arrayvec",
"cargo_metadata 0.18.1",
@ -624,7 +624,7 @@ dependencies = [
[[package]]
name = "clippy_utils"
version = "0.1.88"
version = "0.1.89"
dependencies = [
"arrayvec",
"itertools",
@ -843,9 +843,9 @@ dependencies = [
[[package]]
name = "ctrlc"
version = "3.4.6"
version = "3.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c"
checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
dependencies = [
"nix",
"windows-sys 0.59.0",
@ -977,9 +977,9 @@ dependencies = [
[[package]]
name = "derive_setters"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d"
checksum = "d9c848e86c87e5cc305313041c5677d4d95d60baa71cf95e5f6ea2554bb629ff"
dependencies = [
"darling",
"proc-macro2",
@ -1437,9 +1437,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
@ -1601,14 +1601,15 @@ dependencies = [
[[package]]
name = "icu_collections"
version = "1.5.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
dependencies = [
"displaydoc",
"yoke",
"potential_utf",
"yoke 0.8.0",
"zerofrom",
"zerovec",
"zerovec 0.11.2",
]
[[package]]
@ -1620,9 +1621,9 @@ dependencies = [
"displaydoc",
"icu_list_data",
"icu_locid_transform",
"icu_provider",
"icu_provider 1.5.0",
"regex-automata 0.2.0",
"writeable",
"writeable 0.5.5",
]
[[package]]
@ -1631,6 +1632,19 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52b1a7fbdbf3958f1be8354cb59ac73f165b7b7082d447ff2090355c9a069120"
[[package]]
name = "icu_locale_core"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
dependencies = [
"displaydoc",
"litemap 0.8.0",
"tinystr 0.8.1",
"writeable 0.6.1",
"zerovec 0.11.2",
]
[[package]]
name = "icu_locid"
version = "1.5.0"
@ -1638,10 +1652,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
dependencies = [
"displaydoc",
"litemap",
"tinystr",
"writeable",
"zerovec",
"litemap 0.7.5",
"tinystr 0.7.6",
"writeable 0.5.5",
"zerovec 0.10.4",
]
[[package]]
@ -1653,9 +1667,9 @@ dependencies = [
"displaydoc",
"icu_locid",
"icu_locid_transform_data",
"icu_provider",
"tinystr",
"zerovec",
"icu_provider 1.5.0",
"tinystr 0.7.6",
"zerovec 0.10.4",
]
[[package]]
@ -1666,48 +1680,46 @@ checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
[[package]]
name = "icu_normalizer"
version = "1.5.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
dependencies = [
"displaydoc",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
"icu_provider",
"icu_provider 2.0.0",
"smallvec",
"utf16_iter",
"utf8_iter",
"write16",
"zerovec",
"zerovec 0.11.2",
]
[[package]]
name = "icu_normalizer_data"
version = "1.5.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
[[package]]
name = "icu_properties"
version = "1.5.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a"
dependencies = [
"displaydoc",
"icu_collections",
"icu_locid_transform",
"icu_locale_core",
"icu_properties_data",
"icu_provider",
"tinystr",
"zerovec",
"icu_provider 2.0.0",
"potential_utf",
"zerotrie",
"zerovec 0.11.2",
]
[[package]]
name = "icu_properties_data"
version = "1.5.1"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04"
[[package]]
name = "icu_provider"
@ -1719,11 +1731,28 @@ dependencies = [
"icu_locid",
"icu_provider_macros",
"stable_deref_trait",
"tinystr",
"writeable",
"yoke",
"tinystr 0.7.6",
"writeable 0.5.5",
"yoke 0.7.5",
"zerofrom",
"zerovec",
"zerovec 0.10.4",
]
[[package]]
name = "icu_provider"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
dependencies = [
"displaydoc",
"icu_locale_core",
"stable_deref_trait",
"tinystr 0.8.1",
"writeable 0.6.1",
"yoke 0.8.0",
"zerofrom",
"zerotrie",
"zerovec 0.11.2",
]
[[package]]
@ -1734,9 +1763,9 @@ checksum = "d6324dfd08348a8e0374a447ebd334044d766b1839bb8d5ccf2482a99a77c0bc"
dependencies = [
"icu_locid",
"icu_locid_transform",
"icu_provider",
"tinystr",
"zerovec",
"icu_provider 1.5.0",
"tinystr 0.7.6",
"zerovec 0.10.4",
]
[[package]]
@ -1775,9 +1804,9 @@ dependencies = [
[[package]]
name = "idna_adapter"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
dependencies = [
"icu_normalizer",
"icu_properties",
@ -1905,9 +1934,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd"
checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806"
dependencies = [
"jiff-static",
"log",
@ -1918,9 +1947,9 @@ dependencies = [
[[package]]
name = "jiff-static"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300"
checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48"
dependencies = [
"proc-macro2",
"quote",
@ -1933,7 +1962,7 @@ version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [
"getrandom 0.3.2",
"getrandom 0.3.3",
"libc",
]
@ -2033,9 +2062,9 @@ dependencies = [
[[package]]
name = "libffi"
version = "4.0.0"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
checksum = "ebfd30a67b482a08116e753d0656cb626548cf4242543e5cc005be7639d99838"
dependencies = [
"libc",
"libffi-sys",
@ -2043,28 +2072,28 @@ dependencies = [
[[package]]
name = "libffi-sys"
version = "3.2.0"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
checksum = "f003aa318c9f0ee69eb0ada7c78f5c9d2fedd2ceb274173b5c7ff475eee584a3"
dependencies = [
"cc",
]
[[package]]
name = "libloading"
version = "0.8.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.53.0",
]
[[package]]
name = "libm"
version = "0.2.13"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "libredox"
@ -2118,6 +2147,12 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
[[package]]
name = "litemap"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
[[package]]
name = "lld-wrapper"
version = "0.1.0"
@ -2279,7 +2314,7 @@ dependencies = [
"chrono-tz",
"colored",
"directories",
"getrandom 0.3.2",
"getrandom 0.3.3",
"libc",
"libffi",
"libloading",
@ -2306,9 +2341,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.29.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags",
"cfg-if",
@ -2769,6 +2804,15 @@ dependencies = [
"portable-atomic",
]
[[package]]
name = "potential_utf"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
dependencies = [
"zerovec 0.11.2",
]
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@ -2919,7 +2963,7 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.2",
"getrandom 0.3.3",
]
[[package]]
@ -3074,9 +3118,9 @@ dependencies = [
[[package]]
name = "rustc-build-sysroot"
version = "0.5.4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6d984a9db43148467059309bd1e5ad577085162f695d9fe2cf3543aeb25cd38"
checksum = "fb332121f7845c6bd016f9655cf22f03c2999df936694b624a88669a78667d98"
dependencies = [
"anyhow",
"rustc_version",
@ -3309,8 +3353,8 @@ dependencies = [
"icu_list",
"icu_locid",
"icu_locid_transform",
"icu_provider",
"zerovec",
"icu_provider 1.5.0",
"zerovec 0.10.4",
]
[[package]]
@ -5084,12 +5128,12 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.19.1"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.2",
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.59.0",
@ -5264,7 +5308,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"displaydoc",
"zerovec",
"zerovec 0.10.4",
]
[[package]]
name = "tinystr"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
dependencies = [
"displaydoc",
"zerovec 0.11.2",
]
[[package]]
@ -5284,9 +5338,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.44.2"
version = "1.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
dependencies = [
"backtrace",
"bytes",
@ -5490,9 +5544,9 @@ dependencies = [
[[package]]
name = "unic-langid"
version = "0.9.5"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44"
checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05"
dependencies = [
"unic-langid-impl",
"unic-langid-macros",
@ -5500,30 +5554,30 @@ dependencies = [
[[package]]
name = "unic-langid-impl"
version = "0.9.5"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5"
checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658"
dependencies = [
"tinystr",
"tinystr 0.8.1",
]
[[package]]
name = "unic-langid-macros"
version = "0.9.5"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0da1cd2c042d3c7569a1008806b02039e7a4a2bdf8f8e96bd3c792434a0e275e"
checksum = "d5957eb82e346d7add14182a3315a7e298f04e1ba4baac36f7f0dbfedba5fc25"
dependencies = [
"proc-macro-hack",
"tinystr",
"tinystr 0.8.1",
"unic-langid-impl",
"unic-langid-macros-impl",
]
[[package]]
name = "unic-langid-macros-impl"
version = "0.9.5"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5"
dependencies = [
"proc-macro-hack",
"quote",
@ -5639,12 +5693,6 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf16_iter"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
[[package]]
name = "utf8-width"
version = "0.1.7"
@ -5669,7 +5717,7 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
dependencies = [
"getrandom 0.3.2",
"getrandom 0.3.3",
]
[[package]]
@ -5826,6 +5874,16 @@ dependencies = [
"wasmparser 0.229.0",
]
[[package]]
name = "wasm-encoder"
version = "0.230.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4349d0943718e6e434b51b9639e876293093dca4b96384fb136ab5bd5ce6660"
dependencies = [
"leb128fmt",
"wasmparser 0.230.0",
]
[[package]]
name = "wasm-metadata"
version = "0.229.0"
@ -5871,23 +5929,34 @@ dependencies = [
]
[[package]]
name = "wast"
version = "229.0.0"
name = "wasmparser"
version = "0.230.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63fcaff613c12225696bb163f79ca38ffb40e9300eff0ff4b8aa8b2f7eadf0d9"
checksum = "808198a69b5a0535583370a51d459baa14261dfab04800c4864ee9e1a14346ed"
dependencies = [
"bitflags",
"indexmap",
"semver",
]
[[package]]
name = "wast"
version = "230.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8edac03c5fa691551531533928443faf3dc61a44f814a235c7ec5d17b7b34f1"
dependencies = [
"bumpalo",
"leb128fmt",
"memchr",
"unicode-width 0.2.0",
"wasm-encoder 0.229.0",
"wasm-encoder 0.230.0",
]
[[package]]
name = "wat"
version = "1.229.0"
version = "1.230.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4189bad08b70455a9e9e67dc126d2dcf91fac143a80f1046747a5dde6d4c33e0"
checksum = "0d77d62229e38db83eac32bacb5f61ebb952366ab0dae90cf2b3c07a65eea894"
dependencies = [
"wast",
]
@ -6311,9 +6380,9 @@ dependencies = [
[[package]]
name = "winnow"
version = "0.7.9"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
dependencies = [
"memchr",
]
@ -6370,18 +6439,18 @@ dependencies = [
"wasmparser 0.229.0",
]
[[package]]
name = "write16"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
[[package]]
name = "writeable"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "writeable"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
[[package]]
name = "x"
version = "0.1.1"
@ -6422,7 +6491,19 @@ checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive",
"yoke-derive 0.7.5",
"zerofrom",
]
[[package]]
name = "yoke"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive 0.8.0",
"zerofrom",
]
@ -6438,6 +6519,18 @@ dependencies = [
"synstructure",
]
[[package]]
name = "yoke-derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
"synstructure",
]
[[package]]
name = "zerocopy"
version = "0.8.25"
@ -6479,15 +6572,37 @@ dependencies = [
"synstructure",
]
[[package]]
name = "zerotrie"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
dependencies = [
"displaydoc",
"yoke 0.8.0",
"zerofrom",
]
[[package]]
name = "zerovec"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
dependencies = [
"yoke",
"yoke 0.7.5",
"zerofrom",
"zerovec-derive",
"zerovec-derive 0.10.3",
]
[[package]]
name = "zerovec"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
dependencies = [
"yoke 0.8.0",
"zerofrom",
"zerovec-derive 0.11.1",
]
[[package]]
@ -6500,3 +6615,14 @@ dependencies = [
"quote",
"syn 2.0.101",
]
[[package]]
name = "zerovec-derive"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]

View file

@ -6,7 +6,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(deny(warnings)))

View file

@ -32,7 +32,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
@ -896,7 +895,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ret = self.arena.alloc_from_iter(lowered_attrs);
// this is possible if an item contained syntactical attribute,
// but none of them parse succesfully or all of them were ignored
// but none of them parse successfully or all of them were ignored
// for not being built-in attributes at all. They could be remaining
// unexpanded attributes used as markers in proc-macro derives for example.
// This will have emitted some diagnostics for the misparse, but will then

View file

@ -4,7 +4,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(if_let_guard)]

View file

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end

View file

@ -77,7 +77,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![recursion_limit = "256"]

View file

@ -2,7 +2,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]

View file

@ -621,13 +621,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
&ocx, op, span,
) {
Ok(_) => ocx.select_all_or_error(),
Err(e) => {
if e.is_empty() {
ocx.select_all_or_error()
} else {
e
}
}
Err(e) => e,
};
// Could have no errors if a type lowering error, say, caused the query

View file

@ -5,7 +5,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]

View file

@ -0,0 +1 @@
Cargo.lock linguist-generated=false

View file

@ -101,9 +101,8 @@ jobs:
if: ${{ matrix.cargo_runner }}
run: |
# FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro.
# TODO: remove --skip test_mm512_stream_ps when stdarch is updated in rustc.
# TODO: remove --skip test_tile_ when it's implemented.
STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features --cfg stdarch_intel_sde" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a --skip test_mm512_stream_ps --skip test_tile_
STDARCH_TEST_SKIP_FUNCTION="xsave,xsaveopt,xsave64,xsaveopt64" STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a --skip test_tile_
# Summary job for the merge queue.
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!

View file

@ -0,0 +1,101 @@
# Contributing to rustc_codegen_gcc
Welcome to the `rustc_codegen_gcc` project! This guide will help you get started as a contributor. The project aims to provide a GCC codegen backend for rustc, allowing Rust compilation on platforms unsupported by LLVM and potentially improving runtime performance through GCC's optimizations.
## Getting Started
### Setting Up Your Development Environment
For detailed setup instructions including dependencies, build steps, and initial testing, please refer to our [README](Readme.md). The README contains the most up-to-date information on:
- Required dependencies and system packages
- Repository setup and configuration
- Build process
- Basic test verification
Once you've completed the setup process outlined in the README, you can proceed with the contributor-specific information below.
## Communication Channels
- Matrix: Join our [Matrix channel](https://matrix.to/#/#rustc_codegen_gcc:matrix.org)
- IRC: Join us on [IRC](https://web.libera.chat/#rustc_codegen_gcc)
- [GitHub Issues](https://github.com/rust-lang/rustc_codegen_gcc/issues): For bug reports and feature discussions
We encourage new contributors to join our communication channels and introduce themselves. Feel free to ask questions about where to start or discuss potential contributions.
## Understanding Core Concepts
### Common Development Tasks
#### Running Specific Tests
To run specific tests, use appropriate flags such as:
- `./y.sh test --test-libcore`
- `./y.sh test --std-tests`
- `cargo test -- <name of test>`
Additionally, you can run the tests of `libgccjit`:
```bash
# libgccjit tests
cd gcc-build/gcc
make check-jit
# For a specific test:
make check-jit RUNTESTFLAGS="-v -v -v jit.exp=jit.dg/test-asm.cc"
```
#### Debugging Tools
The project provides several environment variables for debugging:
- `CG_GCCJIT_DUMP_GIMPLE`: Dumps the GIMPLE IR
- `CG_RUSTFLAGS`: Additional Rust flags
- `CG_GCCJIT_DUMP_MODULE`: Dumps a specific module
- `CG_GCCJIT_DUMP_TO_FILE`: Creates C-like representation
Full list of debugging options can be found in the [README](Readme.md#env-vars).
## Making Contributions
### Finding Issues to Work On
1. Look for issues labeled with [`good first issue`](https://github.com/rust-lang/rustc_codegen_gcc/issues?q=is%3Aissue%20state%3Aopen%20label%3A"good%20first%20issue") or [`help wanted`](https://github.com/rust-lang/rustc_codegen_gcc/issues?q=is%3Aissue%20state%3Aopen%20label%3A"help%20wanted")
2. Check the [progress report](https://blog.antoyo.xyz/rustc_codegen_gcc-progress-report-34#state_of_rustc_codegen_gcc) for larger initiatives
3. Consider improving documentation or investigating [failing tests](https://github.com/rust-lang/rustc_codegen_gcc/tree/master/tests) (except `failing-ui-tests12.txt`)
### Pull Request Process
1. Fork the repository and create a new branch
2. Make your changes with clear commit messages
3. Add tests for new functionality
4. Update documentation as needed
5. Submit a PR with a description of your changes
### Code Style Guidelines
- Follow Rust standard coding conventions
- Ensure your code passes `rustfmt` and `clippy`
- Add comments explaining complex logic, especially in GCC interface code
## Additional Resources
- [Rustc Dev Guide](https://rustc-dev-guide.rust-lang.org/)
- [GCC Internals Documentation](https://gcc.gnu.org/onlinedocs/gccint/)
- Project-specific documentation in the `doc/` directory:
- [Common errors](doc/errors.md)
- [Debugging](doc/debugging.md)
- [Debugging libgccjit](doc/debugging-libgccjit.md)
- [Git subtree sync](doc/subtree.md)
- [List of useful commands](doc/tips.md)
- [Send a patch to GCC](doc/sending-gcc-patch.md)
## Getting Help
If you're stuck or unsure about anything:
1. Check the existing documentation in the `doc/` directory
2. Ask in the IRC or Matrix channels
3. Open a GitHub issue for technical problems
4. Comment on the issue you're working on if you need guidance
Remember that all contributions, including documentation improvements, bug reports, and feature requests, are valuable to the project.

View file

@ -56,18 +56,18 @@ dependencies = [
[[package]]
name = "gccjit"
version = "2.5.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2895ddec764de7ac76fe6c056050c4801a80109c066f177a00a9cc8dee02b29b"
checksum = "ae99a89184220d967dd300139f2d2ae7d52c1a69d632b24aacc57c54625254ce"
dependencies = [
"gccjit_sys",
]
[[package]]
name = "gccjit_sys"
version = "0.6.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac133db68db8a6a8b2c51ef4b18d8ea16682d5814c4641272fe37bbbc223d5f3"
checksum = "24edb7bfe2b7b27c6d09ed23eebfcab0b359c8fe978433f902943e6f127a0f1b"
dependencies = [
"libc",
]

View file

@ -2,7 +2,7 @@
name = "rustc_codegen_gcc"
version = "0.1.0"
authors = ["Antoni Boucher <bouanto@zoho.com>"]
edition = "2018"
edition = "2024"
license = "MIT OR Apache-2.0"
[lib]
@ -22,7 +22,7 @@ master = ["gccjit/master"]
default = ["master"]
[dependencies]
gccjit = "2.5"
gccjit = "2.7"
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs" }
# Local copy.

View file

@ -12,22 +12,38 @@ This is a GCC codegen for rustc, which means it can be loaded by the existing ru
The primary goal of this project is to be able to compile Rust code on platforms unsupported by LLVM.
A secondary goal is to check if using the gcc backend will provide any run-time speed improvement for the programs compiled using rustc.
## Getting Started
Note: **This requires a patched libgccjit in order to work.
You need to use my [fork of gcc](https://github.com/rust-lang/gcc) which already includes these patches.**
The default configuration (see below in the [Quick start](#quick-start) section) will download a `libgccjit` built in the CI that already contains these patches, so you don't need to build this fork yourself if you use the default configuration.
### Dependencies
**rustup:** Follow the instructions on the official [website](https://www.rust-lang.org/tools/install)
- rustup: follow instructions on the [official website](https://rustup.rs)
- consider to install DejaGnu which is necessary for running the libgccjit test suite. [website](https://www.gnu.org/software/dejagnu/#downloading)
- additional packages: `flex`, `libmpfr-dev`, `libgmp-dev`, `libmpc3`, `libmpc-dev`
### Quick start
**DejaGnu:** Consider to install DejaGnu which is necessary for running the libgccjit test suite. [website](https://www.gnu.org/software/dejagnu/#downloading)
1. Clone and configure the repository:
```bash
git clone https://github.com/rust-lang/rustc_codegen_gcc
cd rustc_codegen_gcc
cp config.example.toml config.toml
```
## Building
**This requires a patched libgccjit in order to work.
You need to use my [fork of gcc](https://github.com/rust-lang/gcc) which already includes these patches.**
```bash
$ cp config.example.toml config.toml
```
2. Build and test:
```bash
./y.sh prepare # downloads and patches sysroot
./y.sh build --sysroot --release
# Verify setup with a simple test
./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
# Run full test suite (expect ~100 failing UI tests)
./y.sh test --release
```
If don't need to test GCC patches you wrote in our GCC fork, then the default configuration should
be all you need. You can update the `rustc_codegen_gcc` without worrying about GCC.
@ -143,7 +159,7 @@ You can do the same manually (although we don't recommend it):
$ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs
```
## Env vars
## Environment variables
* _**CG_GCCJIT_DUMP_ALL_MODULES**_: Enables dumping of all compilation modules. When set to "1", a dump is created for each module during compilation and stored in `/tmp/reproducers/`.
* _**CG_GCCJIT_DUMP_MODULE**_: Enables dumping of a specific module. When set with the module name, e.g., `CG_GCCJIT_DUMP_MODULE=module_name`, a dump of that specific module is created in `/tmp/reproducers/`.

View file

@ -1,7 +1,7 @@
[package]
name = "y"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
boml = "0.3.1"

View file

@ -60,7 +60,9 @@ pub enum Command {
fn main() {
if env::var("RUST_BACKTRACE").is_err() {
env::set_var("RUST_BACKTRACE", "1");
unsafe {
env::set_var("RUST_BACKTRACE", "1");
}
}
let command = match env::args().nth(1).as_deref() {

View file

@ -10,7 +10,7 @@ use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus, Output};
#[cfg(unix)]
extern "C" {
unsafe extern "C" {
fn raise(signal: c_int) -> c_int;
}

View file

@ -1,6 +1,14 @@
#![feature(
no_core, lang_items, intrinsics, unboxed_closures, extern_types,
decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
no_core,
lang_items,
intrinsics,
unboxed_closures,
extern_types,
decl_macro,
rustc_attrs,
transparent_unions,
auto_traits,
freeze_impls,
thread_local
)]
#![no_core]
@ -35,13 +43,13 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
pub trait DispatchFromDyn<T> {}
// &T -> &U
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
// &mut T -> &mut U
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
// *const T -> *const U
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
// *mut T -> *mut U
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U, ()>> for Box<T, ()> {}
#[lang = "legacy_receiver"]
@ -52,8 +60,7 @@ impl<T: ?Sized> LegacyReceiver for &mut T {}
impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {}
#[lang = "receiver"]
trait Receiver {
}
trait Receiver {}
#[lang = "copy"]
pub trait Copy {}
@ -67,10 +74,13 @@ impl Copy for u16 {}
impl Copy for u32 {}
impl Copy for u64 {}
impl Copy for usize {}
impl Copy for u128 {}
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for isize {}
impl Copy for i128 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for char {}
@ -336,7 +346,6 @@ impl PartialEq for u32 {
}
}
impl PartialEq for u64 {
fn eq(&self, other: &u64) -> bool {
(*self) == (*other)
@ -523,7 +532,11 @@ fn panic_in_cleanup() -> ! {
#[track_caller]
fn panic_bounds_check(index: usize, len: usize) -> ! {
unsafe {
libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
libc::printf(
"index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8,
len,
index,
);
intrinsics::abort();
}
}
@ -551,8 +564,7 @@ pub trait Deref {
fn deref(&self) -> &Self::Target;
}
pub trait Allocator {
}
pub trait Allocator {}
impl Allocator for () {}
@ -634,6 +646,8 @@ pub union MaybeUninit<T> {
}
pub mod intrinsics {
#[rustc_intrinsic]
pub const fn black_box<T>(_dummy: T) -> T;
#[rustc_intrinsic]
pub fn abort() -> !;
#[rustc_intrinsic]
@ -711,19 +725,27 @@ pub struct VaList<'a>(&'a mut VaListImpl);
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro stringify($($t:tt)*) { /* compiler built-in */ }
pub macro stringify($($t:tt)*) {
/* compiler built-in */
}
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro file() { /* compiler built-in */ }
pub macro file() {
/* compiler built-in */
}
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro line() { /* compiler built-in */ }
pub macro line() {
/* compiler built-in */
}
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro cfg() { /* compiler built-in */ }
pub macro cfg() {
/* compiler built-in */
}
pub static A_STATIC: u8 = 42;

View file

@ -1 +1 @@
0ea98a1365b81f7488073512c850e8ee951a4afd
04ce66d8c918de9273bd7101638ad8724edf5e21

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-04-25"
channel = "nightly-2025-05-12"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View file

@ -9,9 +9,9 @@ use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf;
#[cfg(feature = "master")]
use rustc_session::config;
#[cfg(feature = "master")]
use rustc_target::callconv::Conv;
use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode};
#[cfg(feature = "master")]
use rustc_target::callconv::{Conv, RiscvInterruptKind};
use crate::builder::Builder;
use crate::context::CodegenCx;
@ -240,38 +240,57 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
#[cfg(feature = "master")]
pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option<FnAttribute<'gcc>> {
// TODO: handle the calling conventions returning None.
let attribute = match conv {
Conv::C
| Conv::Rust
| Conv::CCmseNonSecureCall
| Conv::CCmseNonSecureEntry
| Conv::RiscvInterrupt { .. } => return None,
Conv::Cold => return None,
Conv::C | Conv::Rust => return None,
Conv::CCmseNonSecureCall => {
if arch == "arm" {
FnAttribute::ArmCmseNonsecureCall
} else {
return None;
}
}
Conv::CCmseNonSecureEntry => {
if arch == "arm" {
FnAttribute::ArmCmseNonsecureEntry
} else {
return None;
}
}
Conv::Cold => FnAttribute::Cold,
// NOTE: the preserve attributes are not yet implemented in GCC:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110899
Conv::PreserveMost => return None,
Conv::PreserveAll => return None,
Conv::GpuKernel => {
// TODO(antoyo): remove clippy allow attribute when this is implemented.
#[allow(clippy::if_same_then_else)]
if arch == "amdgpu" {
return None;
FnAttribute::GcnAmdGpuHsaKernel
} else if arch == "nvptx64" {
return None;
FnAttribute::NvptxKernel
} else {
panic!("Architecture {} does not support GpuKernel calling convention", arch);
}
}
Conv::AvrInterrupt => return None,
Conv::AvrNonBlockingInterrupt => return None,
Conv::ArmAapcs => return None,
Conv::Msp430Intr => return None,
Conv::X86Fastcall => return None,
Conv::X86Intr => return None,
Conv::X86Stdcall => return None,
Conv::X86ThisCall => return None,
// TODO(antoyo): check if those AVR attributes are mapped correctly.
Conv::AvrInterrupt => FnAttribute::AvrSignal,
Conv::AvrNonBlockingInterrupt => FnAttribute::AvrInterrupt,
Conv::ArmAapcs => FnAttribute::ArmPcs("aapcs"),
Conv::Msp430Intr => FnAttribute::Msp430Interrupt,
Conv::RiscvInterrupt { kind } => {
let kind = match kind {
RiscvInterruptKind::Machine => "machine",
RiscvInterruptKind::Supervisor => "supervisor",
};
FnAttribute::RiscvInterrupt(kind)
}
Conv::X86Fastcall => FnAttribute::X86FastCall,
Conv::X86Intr => FnAttribute::X86Interrupt,
Conv::X86Stdcall => FnAttribute::X86Stdcall,
Conv::X86ThisCall => FnAttribute::X86ThisCall,
// NOTE: the vectorcall calling convention is not yet implemented in GCC:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
Conv::X86VectorCall => return None,
Conv::X86_64SysV => FnAttribute::SysvAbi,
Conv::X86_64Win64 => FnAttribute::MsAbi,
Conv::X86_64SysV => FnAttribute::X86SysvAbi,
Conv::X86_64Win64 => FnAttribute::X86MsAbi,
};
Some(attribute)
}

View file

@ -6,21 +6,69 @@ use rustc_attr_parsing::InlineAttr;
use rustc_attr_parsing::InstructionSetAttr;
#[cfg(feature = "master")]
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
#[cfg(feature = "master")]
use rustc_middle::mir::TerminatorKind;
use rustc_middle::ty;
use crate::context::CodegenCx;
use crate::gcc_util::to_gcc_features;
/// Get GCC attribute for the provided inline heuristic.
/// Checks if the function `instance` is recursively inline.
/// Returns `false` if a functions is guaranteed to be non-recursive, and `true` if it *might* be recursive.
#[cfg(feature = "master")]
fn resursively_inline<'gcc, 'tcx>(
cx: &CodegenCx<'gcc, 'tcx>,
instance: ty::Instance<'tcx>,
) -> bool {
// No body, so we can't check if this is recursively inline, so we assume it is.
if !cx.tcx.is_mir_available(instance.def_id()) {
return true;
}
// `expect_local` ought to never fail: we should be checking a function within this codegen unit.
let body = cx.tcx.optimized_mir(instance.def_id());
for block in body.basic_blocks.iter() {
let Some(ref terminator) = block.terminator else { continue };
// I assume that the recursive-inline issue applies only to functions, and not to drops.
// In principle, a recursive, `#[inline(always)]` drop could(?) exist, but I don't think it does.
let TerminatorKind::Call { ref func, .. } = terminator.kind else { continue };
let Some((def, _args)) = func.const_fn_def() else { continue };
// Check if the called function is recursively inline.
if matches!(
cx.tcx.codegen_fn_attrs(def).inline,
InlineAttr::Always | InlineAttr::Force { .. }
) {
return true;
}
}
false
}
/// Get GCC attribute for the provided inline heuristic, attached to `instance`.
#[cfg(feature = "master")]
#[inline]
fn inline_attr<'gcc, 'tcx>(
cx: &CodegenCx<'gcc, 'tcx>,
inline: InlineAttr,
instance: ty::Instance<'tcx>,
) -> Option<FnAttribute<'gcc>> {
match inline {
InlineAttr::Always => {
// We can't simply always return `always_inline` unconditionally.
// It is *NOT A HINT* and does not work for recursive functions.
//
// So, it can only be applied *if*:
// The current function does not call any functions marked `#[inline(always)]`.
//
// That prevents issues steming from recursive `#[inline(always)]` at a *relatively* small cost.
// We *only* need to check all the terminators of a function marked with this attribute.
if resursively_inline(cx, instance) {
Some(FnAttribute::Inline)
} else {
Some(FnAttribute::AlwaysInline)
}
}
InlineAttr::Hint => Some(FnAttribute::Inline),
InlineAttr::Always | InlineAttr::Force { .. } => Some(FnAttribute::AlwaysInline),
InlineAttr::Force { .. } => Some(FnAttribute::AlwaysInline),
InlineAttr::Never => {
if cx.sess().target.arch != "amdgpu" {
Some(FnAttribute::NoInline)
@ -52,7 +100,7 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
} else {
codegen_fn_attrs.inline
};
if let Some(attr) = inline_attr(cx, inline) {
if let Some(attr) = inline_attr(cx, inline, instance) {
if let FnAttribute::AlwaysInline = attr {
func.add_attribute(FnAttribute::Inline);
}
@ -88,14 +136,8 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
let target_features = function_features
.iter()
.filter_map(|feature| {
// FIXME(antoyo): for some reasons, disabling SSE results in the following error when
// compiling Rust for Linux:
// SSE register return with SSE disabled
// TODO(antoyo): support soft-float and retpoline-external-thunk.
if feature.contains("soft-float")
|| feature.contains("retpoline-external-thunk")
|| *feature == "-sse"
{
// TODO(antoyo): support soft-float.
if feature.contains("soft-float") {
return None;
}

View file

@ -593,7 +593,7 @@ fn thin_lto(
Ok((opt_jobs, copy_jobs))
}
pub unsafe fn optimize_thin_module(
pub fn optimize_thin_module(
thin_module: ThinModule<GccCodegenBackend>,
_cgcx: &CodegenContext<GccCodegenBackend>,
) -> Result<ModuleCodegen<GccContext>, FatalError> {

View file

@ -14,7 +14,7 @@ use crate::base::add_pic_option;
use crate::errors::CopyBitcode;
use crate::{GccCodegenBackend, GccContext};
pub(crate) unsafe fn codegen(
pub(crate) fn codegen(
cgcx: &CodegenContext<GccCodegenBackend>,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<GccContext>,

View file

@ -568,11 +568,28 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
) {
let mut gcc_cases = vec![];
let typ = self.val_ty(value);
for (on_val, dest) in cases {
let on_val = self.const_uint_big(typ, on_val);
gcc_cases.push(self.context.new_case(on_val, on_val, dest));
// FIXME(FractalFir): This is a workaround for a libgccjit limitation.
// Currently, libgccjit can't directly create 128 bit integers.
// Since switch cases must be values, and casts are not constant, we can't use 128 bit switch cases.
// In such a case, we will simply fall back to an if-ladder.
// This *may* be slower than a native switch, but a slow working solution is better than none at all.
if typ.is_i128(self) || typ.is_u128(self) {
for (on_val, dest) in cases {
let on_val = self.const_uint_big(typ, on_val);
let is_case =
self.context.new_comparison(self.location, ComparisonOp::Equals, value, on_val);
let next_block = self.current_func().new_block("case");
self.block.end_with_conditional(self.location, is_case, dest, next_block);
self.block = next_block;
}
self.block.end_with_jump(self.location, default_block);
} else {
for (on_val, dest) in cases {
let on_val = self.const_uint_big(typ, on_val);
gcc_cases.push(self.context.new_case(on_val, on_val, dest));
}
self.block.end_with_switch(self.location, value, default_block, &gcc_cases);
}
self.block.end_with_switch(self.location, value, default_block, &gcc_cases);
}
#[cfg(feature = "master")]

View file

@ -191,13 +191,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
// TODO(antoyo): check if it's okay that no link_section is set.
let typ = self.val_ty(cv).get_aligned(align.bytes());
let global = self.declare_private_global(&name[..], typ);
global
self.declare_private_global(&name[..], typ)
}
_ => {
let typ = self.val_ty(cv).get_aligned(align.bytes());
let global = self.declare_unnamed_global(typ);
global
self.declare_unnamed_global(typ)
}
};
global.global_set_initializer_rvalue(cv);

View file

@ -289,7 +289,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
) -> Self::DILocation {
let pos = span.lo();
let DebugLoc { file, line, col } = self.lookup_debug_loc(pos);
let loc = match file.name {
match file.name {
rustc_span::FileName::Real(ref name) => match *name {
rustc_span::RealFileName::LocalPath(ref name) => {
if let Some(name) = name.to_str() {
@ -314,7 +314,6 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
}
},
_ => Location::null(),
};
loc
}
}
}

View file

@ -157,6 +157,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
///
/// If theres a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
#[allow(clippy::let_and_return)]
fn declare_raw_fn<'gcc>(
cx: &CodegenCx<'gcc, '_>,
name: &str,

File diff suppressed because it is too large Load diff

View file

@ -4,9 +4,7 @@ mod simd;
#[cfg(feature = "master")]
use std::iter;
#[cfg(feature = "master")]
use gccjit::FunctionType;
use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp};
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp};
#[cfg(feature = "master")]
use rustc_abi::ExternAbi;
use rustc_abi::{BackendRepr, HasDataLayout};
@ -132,6 +130,72 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
Some(cx.context.get_builtin_function(gcc_name))
}
// TODO(antoyo): We can probably remove these and use the fallback intrinsic implementation.
fn get_simple_function<'gcc, 'tcx>(
cx: &CodegenCx<'gcc, 'tcx>,
name: Symbol,
) -> Option<Function<'gcc>> {
let (return_type, parameters, func_name) = match name {
sym::minimumf32 => {
let parameters = [
cx.context.new_parameter(None, cx.float_type, "a"),
cx.context.new_parameter(None, cx.float_type, "b"),
];
(cx.float_type, parameters, "fminimumf")
}
sym::minimumf64 => {
let parameters = [
cx.context.new_parameter(None, cx.double_type, "a"),
cx.context.new_parameter(None, cx.double_type, "b"),
];
(cx.double_type, parameters, "fminimum")
}
sym::minimumf128 => {
let f128_type = cx.type_f128();
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html
let parameters = [
cx.context.new_parameter(None, f128_type, "a"),
cx.context.new_parameter(None, f128_type, "b"),
];
(f128_type, parameters, "fminimumf128")
}
sym::maximumf32 => {
let parameters = [
cx.context.new_parameter(None, cx.float_type, "a"),
cx.context.new_parameter(None, cx.float_type, "b"),
];
(cx.float_type, parameters, "fmaximumf")
}
sym::maximumf64 => {
let parameters = [
cx.context.new_parameter(None, cx.double_type, "a"),
cx.context.new_parameter(None, cx.double_type, "b"),
];
(cx.double_type, parameters, "fmaximum")
}
sym::maximumf128 => {
let f128_type = cx.type_f128();
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html
let parameters = [
cx.context.new_parameter(None, f128_type, "a"),
cx.context.new_parameter(None, f128_type, "b"),
];
(f128_type, parameters, "fmaximumf128")
}
_ => return None,
};
Some(cx.context.new_function(
None,
FunctionType::Extern,
return_type,
&parameters,
func_name,
false,
))
}
impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
fn codegen_intrinsic_call(
&mut self,
@ -160,6 +224,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
let simple = get_simple_intrinsic(self, name);
let simple_func = get_simple_function(self, name);
// FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
// https://github.com/rust-lang/rust-clippy/issues/12497
@ -167,7 +232,15 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
#[allow(clippy::suspicious_else_formatting)]
let value = match name {
_ if simple.is_some() => {
let func = simple.expect("simple function");
let func = simple.expect("simple intrinsic function");
self.cx.context.new_call(
self.location,
func,
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
)
}
_ if simple_func.is_some() => {
let func = simple_func.expect("simple function");
self.cx.context.new_call(
self.location,
func,

View file

@ -16,7 +16,7 @@
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![feature(rustc_private, decl_macro, never_type, trusted_len, let_chains)]
#![feature(rustc_private, decl_macro, never_type, trusted_len)]
#![allow(broken_intra_doc_links)]
#![recursion_limit = "256"]
#![warn(rust_2018_idioms)]
@ -454,7 +454,7 @@ impl WriteBackendMethods for GccCodegenBackend {
}
/// This is the entrypoint for a hot plugged rustc_codegen_gccjit
#[no_mangle]
#[unsafe(no_mangle)]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
#[cfg(feature = "master")]
let info = {

View file

@ -10,7 +10,7 @@ tests/ui/sepcomp/sepcomp-fns-backwards.rs
tests/ui/sepcomp/sepcomp-fns.rs
tests/ui/sepcomp/sepcomp-statics.rs
tests/ui/asm/x86_64/may_unwind.rs
tests/ui/catch-unwind-bang.rs
tests/ui/panics/catch-unwind-bang.rs
tests/ui/drop/dynamic-drop-async.rs
tests/ui/cfg/cfg-panic-abort.rs
tests/ui/drop/repeat-drop.rs
@ -94,23 +94,14 @@ tests/ui/simd/intrinsic/generic-as.rs
tests/ui/backtrace/backtrace.rs
tests/ui/lifetimes/tail-expr-lock-poisoning.rs
tests/ui/runtime/rt-explody-panic-payloads.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs

View file

@ -42,7 +42,9 @@ pub fn main_inner(profile: Profile) {
.expect("failed to get absolute path of `gcc-path`")
.display()
.to_string();
env::set_var("LD_LIBRARY_PATH", gcc_path);
unsafe {
env::set_var("LD_LIBRARY_PATH", gcc_path);
}
fn rust_filter(path: &Path) -> bool {
path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs"
@ -67,15 +69,14 @@ pub fn main_inner(profile: Profile) {
.test_dir("tests/run")
.test_path_filter(filter)
.test_extract(|path| {
let lines = std::fs::read_to_string(path)
std::fs::read_to_string(path)
.expect("read file")
.lines()
.skip_while(|l| !l.starts_with("//"))
.take_while(|l| l.starts_with("//"))
.map(|l| &l[2..])
.collect::<Vec<_>>()
.join("\n");
lines
.join("\n")
})
.test_cmds(move |path| {
// Test command 1: Compile `x.rs` into `tempdir/x`.

View file

@ -0,0 +1,53 @@
// Compiler:
//
// Run-time:
// status: 0
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
use mini_core::*;
#[inline(always)]
fn fib(n: u8) -> u8 {
if n == 0 {
return 1;
}
if n == 1 {
return 1;
}
fib(n - 1) + fib(n - 2)
}
#[inline(always)]
fn fib_b(n: u8) -> u8 {
if n == 0 {
return 1;
}
if n == 1 {
return 1;
}
fib_a(n - 1) + fib_a(n - 2)
}
#[inline(always)]
fn fib_a(n: u8) -> u8 {
if n == 0 {
return 1;
}
if n == 1 {
return 1;
}
fib_b(n - 1) + fib_b(n - 2)
}
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
if fib(2) != fib_a(2) {
intrinsics::abort();
}
0
}

View file

@ -0,0 +1,37 @@
// Compiler:
//
// Run-time:
// status: 0
#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]
extern crate mini_core;
use intrinsics::black_box;
use mini_core::*;
#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
// 1st. Check that small 128 bit values work.
let val = black_box(64_u128);
match val {
0 => return 1,
1 => return 2,
64 => (),
_ => return 3,
}
// 2nd check that *large* values work.
const BIG: u128 = 0xDEAD_C0FE_BEEF_DECAF_BADD_DECAF_BEEF_u128;
let val = black_box(BIG);
match val {
0 => return 4,
1 => return 5,
// Check that we will not match on the lower u64, if the upper qword is different!
0xcafbadddecafbeef => return 6,
0xDEAD_C0FE_BEEF_DECAF_BADD_DECAF_BEEF_u128 => (),
_ => return 7,
}
0
}

View file

@ -12,7 +12,7 @@ def run_command(command, cwd=None):
sys.exit(1)
def clone_repository(repo_name, path, repo_url, sub_paths=None):
def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None):
if os.path.exists(path):
while True:
choice = input("There is already a `{}` folder, do you want to update it? [y/N]".format(path))
@ -21,7 +21,7 @@ def clone_repository(repo_name, path, repo_url, sub_paths=None):
return
elif choice.lower() == "y":
print("Updating repository...")
run_command(["git", "pull", "origin"], cwd=path)
run_command(["git", "pull", "origin", branch], cwd=path)
return
else:
print("Didn't understand answer...")
@ -209,6 +209,7 @@ def main():
"llvm-project",
llvm_path,
"https://github.com/llvm/llvm-project",
branch="main",
sub_paths=["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"],
)
clone_repository(

View file

@ -0,0 +1,7 @@
# Documentation at https://forge.rust-lang.org/triagebot/index.html
# Prevents un-canonicalized issue links (to avoid wrong issues being linked in r-l/rust)
[issue-links]
# Prevents mentions in commits to avoid users being spammed
[no-mentions]

View file

@ -14,7 +14,7 @@ use smallvec::SmallVec;
use tracing::debug;
use crate::builder::Builder;
use crate::common::{AsCCharPtr, Funclet};
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
@ -435,13 +435,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
template_str.push_str("\n.att_syntax\n");
}
unsafe {
llvm::LLVMAppendModuleInlineAsm(
self.llmod,
template_str.as_c_char_ptr(),
template_str.len(),
);
}
llvm::append_module_inline_asm(self.llmod, template_str.as_bytes());
}
fn mangled_name(&self, instance: Instance<'tcx>) -> String {
@ -482,67 +476,67 @@ pub(crate) fn inline_asm_call<'ll>(
debug!("Asm Output Type: {:?}", output);
let fty = bx.cx.type_func(&argtys, output);
// Ask LLVM to verify that the constraints are well-formed.
let constraints_ok =
unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_c_char_ptr(), cons.len()) };
let constraints_ok = unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr(), cons.len()) };
debug!("constraint verification result: {:?}", constraints_ok);
if constraints_ok {
let v = unsafe {
llvm::LLVMRustInlineAsm(
fty,
asm.as_c_char_ptr(),
asm.len(),
cons.as_c_char_ptr(),
cons.len(),
volatile,
alignstack,
dia,
can_throw,
)
};
let call = if !labels.is_empty() {
assert!(catch_funclet.is_none());
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
} else if let Some((catch, funclet)) = catch_funclet {
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
} else {
bx.call(fty, None, None, v, inputs, None, None)
};
// Store mark in a metadata node so we can map LLVM errors
// back to source locations. See #17552.
let key = "srcloc";
let kind = bx.get_md_kind_id(key);
// `srcloc` contains one 64-bit integer for each line of assembly code,
// where the lower 32 bits hold the lo byte position and the upper 32 bits
// hold the hi byte position.
let mut srcloc = vec![];
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
// LLVM inserts an extra line to add the ".intel_syntax", so add
// a dummy srcloc entry for it.
//
// Don't do this if we only have 1 line span since that may be
// due to the asm template string coming from a macro. LLVM will
// default to the first srcloc for lines that don't have an
// associated srcloc.
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
}
srcloc.extend(line_spans.iter().map(|span| {
llvm::LLVMValueAsMetadata(
bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
)
}));
let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
let md = bx.get_metadata_value(md);
llvm::LLVMSetMetadata(call, kind, md);
Some(call)
} else {
// LLVM has detected an issue with our constraints, bail out
None
if !constraints_ok {
// LLVM has detected an issue with our constraints, so bail out.
return None;
}
let v = unsafe {
llvm::LLVMGetInlineAsm(
fty,
asm.as_ptr(),
asm.len(),
cons.as_ptr(),
cons.len(),
volatile,
alignstack,
dia,
can_throw,
)
};
let call = if !labels.is_empty() {
assert!(catch_funclet.is_none());
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
} else if let Some((catch, funclet)) = catch_funclet {
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
} else {
bx.call(fty, None, None, v, inputs, None, None)
};
// Store mark in a metadata node so we can map LLVM errors
// back to source locations. See #17552.
let key = "srcloc";
let kind = bx.get_md_kind_id(key);
// `srcloc` contains one 64-bit integer for each line of assembly code,
// where the lower 32 bits hold the lo byte position and the upper 32 bits
// hold the hi byte position.
let mut srcloc = vec![];
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
// LLVM inserts an extra line to add the ".intel_syntax", so add
// a dummy srcloc entry for it.
//
// Don't do this if we only have 1 line span since that may be
// due to the asm template string coming from a macro. LLVM will
// default to the first srcloc for lines that don't have an
// associated srcloc.
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
}
srcloc.extend(line_spans.iter().map(|span| {
llvm::LLVMValueAsMetadata(
bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
)
}));
let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
let md = bx.get_metadata_value(md);
llvm::LLVMSetMetadata(call, kind, md);
Some(call)
}
/// If the register is an xmm/ymm/zmm register then return its index.

View file

@ -1148,9 +1148,9 @@ unsafe fn embed_bitcode(
// We need custom section flags, so emit module-level inline assembly.
let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_c_char_ptr(), asm.len());
llvm::append_module_inline_asm(llmod, &asm);
let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_c_char_ptr(), asm.len());
llvm::append_module_inline_asm(llmod, &asm);
}
}
}

View file

@ -6,7 +6,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]

View file

@ -1,7 +1,7 @@
//! Bindings to the LLVM-C API (`LLVM*`), and to our own `extern "C"` wrapper
//! functions around the unstable LLVM C++ API (`LLVMRust*`).
//!
//! ## Passing pointer/length strings as `*const c_uchar`
//! ## Passing pointer/length strings as `*const c_uchar` (PTR_LEN_STR)
//!
//! Normally it's a good idea for Rust-side bindings to match the corresponding
//! C-side function declarations as closely as possible. But when passing `&str`
@ -471,7 +471,7 @@ pub(crate) enum MetadataType {
MD_kcfi_type = 36,
}
/// LLVMRustAsmDialect
/// Must match the layout of `LLVMInlineAsmDialect`.
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub(crate) enum AsmDialect {
@ -1014,8 +1014,25 @@ unsafe extern "C" {
pub(crate) fn LLVMGetDataLayoutStr(M: &Module) -> *const c_char;
pub(crate) fn LLVMSetDataLayout(M: &Module, Triple: *const c_char);
/// See Module::setModuleInlineAsm.
pub(crate) fn LLVMAppendModuleInlineAsm(M: &Module, Asm: *const c_char, Len: size_t);
/// Append inline assembly to a module. See `Module::appendModuleInlineAsm`.
pub(crate) fn LLVMAppendModuleInlineAsm(
M: &Module,
Asm: *const c_uchar, // See "PTR_LEN_STR".
Len: size_t,
);
/// Create the specified uniqued inline asm string. See `InlineAsm::get()`.
pub(crate) fn LLVMGetInlineAsm<'ll>(
Ty: &'ll Type,
AsmString: *const c_uchar, // See "PTR_LEN_STR".
AsmStringSize: size_t,
Constraints: *const c_uchar, // See "PTR_LEN_STR".
ConstraintsSize: size_t,
HasSideEffects: llvm::Bool,
IsAlignStack: llvm::Bool,
Dialect: AsmDialect,
CanThrow: llvm::Bool,
) -> &'ll Value;
// Operations on integer types
pub(crate) fn LLVMInt1TypeInContext(C: &Context) -> &Type;
@ -1766,7 +1783,7 @@ unsafe extern "C" {
pub(crate) fn LLVMDIBuilderCreateNameSpace<'ll>(
Builder: &DIBuilder<'ll>,
ParentScope: Option<&'ll Metadata>,
Name: *const c_uchar,
Name: *const c_uchar, // See "PTR_LEN_STR".
NameLen: size_t,
ExportSymbols: llvm::Bool,
) -> &'ll Metadata;
@ -1994,21 +2011,9 @@ unsafe extern "C" {
/// Prints the statistics collected by `-Zprint-codegen-stats`.
pub(crate) fn LLVMRustPrintStatistics(OutStr: &RustString);
/// Prepares inline assembly.
pub(crate) fn LLVMRustInlineAsm(
Ty: &Type,
AsmString: *const c_char,
AsmStringLen: size_t,
Constraints: *const c_char,
ConstraintsLen: size_t,
SideEffects: Bool,
AlignStack: Bool,
Dialect: AsmDialect,
CanThrow: Bool,
) -> &Value;
pub(crate) fn LLVMRustInlineAsmVerify(
Ty: &Type,
Constraints: *const c_char,
Constraints: *const c_uchar, // See "PTR_LEN_STR".
ConstraintsLen: size_t,
) -> bool;

View file

@ -441,3 +441,11 @@ pub(crate) fn set_dso_local<'ll>(v: &'ll Value) {
LLVMRustSetDSOLocal(v, true);
}
}
/// Safe wrapper for `LLVMAppendModuleInlineAsm`, which delegates to
/// `Module::appendModuleInlineAsm`.
pub(crate) fn append_module_inline_asm<'ll>(llmod: &'ll Module, asm: &[u8]) {
unsafe {
LLVMAppendModuleInlineAsm(llmod, asm.as_ptr(), asm.len());
}
}

View file

@ -387,7 +387,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
[sym::arm, sym::a32 | sym::t32]
if !tcx.sess.target.has_thumb_interworking =>
{
tcx.dcx().emit_err(errors::UnsuportedInstructionSet {
tcx.dcx().emit_err(errors::UnsupportedInstructionSet {
span: attr.span(),
});
None

View file

@ -149,7 +149,7 @@ pub(crate) struct NullOnExport {
#[derive(Diagnostic)]
#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)]
pub(crate) struct UnsuportedInstructionSet {
pub(crate) struct UnsupportedInstructionSet {
#[primary_span]
pub span: Span,
}

View file

@ -2,7 +2,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]

View file

@ -1,7 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]

View file

@ -17,7 +17,7 @@ impl Drop for MaybeTempDir {
// occur.
let dir = unsafe { ManuallyDrop::take(&mut self.dir) };
if self.keep {
let _ = dir.into_path();
let _ = dir.keep();
}
}
}

View file

@ -7,7 +7,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(decl_macro)]

View file

@ -7,7 +7,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]

View file

@ -1,7 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(associated_type_defaults)]

View file

@ -96,7 +96,7 @@ declare_features! (
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
(accepted, cfg_attr_multi, "1.33.0", Some(54881)),
/// Allows the use of `#[cfg(<true/false>)]`.
(accepted, cfg_boolean_literals, "CURRENT_RUSTC_VERSION", Some(131204)),
(accepted, cfg_boolean_literals, "1.88.0", Some(131204)),
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
(accepted, cfg_doctest, "1.40.0", Some(62210)),
/// Enables `#[cfg(panic = "...")]` config key.
@ -301,7 +301,7 @@ declare_features! (
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(accepted, move_ref_pattern, "1.49.0", Some(68354)),
/// Allows using `#[naked]` on functions.
(accepted, naked_functions, "CURRENT_RUSTC_VERSION", Some(90957)),
(accepted, naked_functions, "1.88.0", Some(90957)),
/// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
(accepted, native_link_modifiers, "1.61.0", Some(81490)),
/// Allows specifying the bundle link modifier

View file

@ -143,7 +143,7 @@ declare_features! (
(removed, infer_static_outlives_requirements, "1.63.0", Some(54185),
Some("removed as it caused some confusion and discussion was inactive for years")),
/// Allow anonymous constants from an inline `const` block in pattern position
(removed, inline_const_pat, "CURRENT_RUSTC_VERSION", Some(76001),
(removed, inline_const_pat, "1.88.0", Some(76001),
Some("removed due to implementation concerns as it requires significant refactorings")),
/// Lazily evaluate constants. This allows constants to depend on type parameters.
(removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),

View file

@ -206,7 +206,7 @@ declare_features! (
/// Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind
(internal, cfg_emscripten_wasm_eh, "1.86.0", None),
/// Allows checking whether or not the backend correctly supports unstable float types.
(internal, cfg_target_has_reliable_f16_f128, "CURRENT_RUSTC_VERSION", None),
(internal, cfg_target_has_reliable_f16_f128, "1.88.0", None),
/// Allows identifying the `compiler_builtins` crate.
(internal, compiler_builtins, "1.13.0", None),
/// Allows writing custom MIR
@ -316,7 +316,7 @@ declare_features! (
// Unstable `#[target_feature]` directives.
(unstable, aarch64_unstable_target_feature, "1.82.0", Some(44839)),
(unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
(unstable, apx_target_feature, "CURRENT_RUSTC_VERSION", Some(139284)),
(unstable, apx_target_feature, "1.88.0", Some(139284)),
(unstable, arm_target_feature, "1.27.0", Some(44839)),
(unstable, avx512_target_feature, "1.27.0", Some(44839)),
(unstable, bpf_target_feature, "1.54.0", Some(44839)),
@ -327,7 +327,7 @@ declare_features! (
(unstable, loongarch_target_feature, "1.73.0", Some(44839)),
(unstable, m68k_target_feature, "1.85.0", Some(134328)),
(unstable, mips_target_feature, "1.27.0", Some(44839)),
(unstable, movrs_target_feature, "CURRENT_RUSTC_VERSION", Some(137976)),
(unstable, movrs_target_feature, "1.88.0", Some(137976)),
(unstable, powerpc_target_feature, "1.27.0", Some(44839)),
(unstable, prfchw_target_feature, "1.78.0", Some(44839)),
(unstable, riscv_target_feature, "1.45.0", Some(44839)),
@ -385,7 +385,7 @@ declare_features! (
/// Allows associated type defaults.
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
/// Allows implementing `AsyncDrop`.
(incomplete, async_drop, "CURRENT_RUSTC_VERSION", Some(126482)),
(incomplete, async_drop, "1.88.0", Some(126482)),
/// Allows async functions to be called from `dyn Trait`.
(incomplete, async_fn_in_dyn_trait, "1.85.0", Some(133119)),
/// Allows `#[track_caller]` on async functions.
@ -395,7 +395,7 @@ declare_features! (
/// Allows `async` trait bound modifier.
(unstable, async_trait_bounds, "1.85.0", Some(62290)),
/// Allows using Intel AVX10 target features and intrinsics
(unstable, avx10_target_feature, "CURRENT_RUSTC_VERSION", Some(138843)),
(unstable, avx10_target_feature, "1.88.0", Some(138843)),
/// Allows using C-variadics.
(unstable, c_variadic, "1.34.0", Some(44930)),
/// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
@ -483,11 +483,11 @@ declare_features! (
/// Allows exhaustive pattern matching on types that contain uninhabited types.
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
/// Disallows `extern` without an explicit ABI.
(unstable, explicit_extern_abis, "CURRENT_RUSTC_VERSION", Some(134986)),
(unstable, explicit_extern_abis, "1.88.0", Some(134986)),
/// Allows explicit tail calls via `become` expression.
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
/// Allows using `#[export_stable]` which indicates that an item is exportable.
(incomplete, export_stable, "CURRENT_RUSTC_VERSION", Some(139939)),
(incomplete, export_stable, "1.88.0", Some(139939)),
/// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions
/// for functions with varargs.
(unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
@ -512,7 +512,7 @@ declare_features! (
/// Allows impls for the Freeze trait.
(internal, freeze_impls, "1.78.0", Some(121675)),
/// Frontmatter `---` blocks for use by external tools.
(unstable, frontmatter, "CURRENT_RUSTC_VERSION", Some(136889)),
(unstable, frontmatter, "1.88.0", Some(136889)),
/// Allows defining gen blocks and `gen fn`.
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
@ -575,7 +575,7 @@ declare_features! (
/// Allows `mut ref` and `mut ref mut` identifier patterns.
(incomplete, mut_ref, "1.79.0", Some(123076)),
/// Allows using `#[naked]` on `extern "Rust"` functions.
(unstable, naked_functions_rustic_abi, "CURRENT_RUSTC_VERSION", Some(138997)),
(unstable, naked_functions_rustic_abi, "1.88.0", Some(138997)),
/// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions.
(unstable, naked_functions_target_feature, "1.86.0", Some(138568)),
/// Allows specifying the as-needed link modifier
@ -641,7 +641,7 @@ declare_features! (
/// Allows string patterns to dereference values to match them.
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
/// Allows `super let` statements.
(unstable, super_let, "CURRENT_RUSTC_VERSION", Some(139076)),
(unstable, super_let, "1.88.0", Some(139076)),
/// Allows subtrait items to shadow supertrait items.
(unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
/// Allows using `#[thread_local]` on `static` items.

View file

@ -25,9 +25,6 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf {
path.to_path_buf()
} else {
// `/a/b/c/foo/bar.rs` contains the current macro invocation
#[cfg(bootstrap)]
let mut source_file_path = span.source_file().path();
#[cfg(not(bootstrap))]
let mut source_file_path = span.local_file().unwrap();
// `/a/b/c/foo/`
source_file_path.pop();

View file

@ -4,7 +4,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(closure_track_caller)]

View file

@ -522,7 +522,7 @@ hir_analysis_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias_span = this alias does not contain a trait
hir_analysis_traits_with_defualt_impl = traits with a default impl, like `{$traits}`, cannot be implemented for {$problematic_kind} `{$self_ty}`
hir_analysis_traits_with_default_impl = traits with a default impl, like `{$traits}`, cannot be implemented for {$problematic_kind} `{$self_ty}`
.note = a trait object implements `{$traits}` if and only if `{$traits}` is one of the trait object's trait bounds
hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number}

View file

@ -3,7 +3,7 @@ use std::borrow::Cow;
use std::iter;
use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err};
use rustc_hir::def::{DefKind, Res};
@ -356,61 +356,14 @@ fn compare_method_predicate_entailment<'tcx>(
}
if !(impl_sig, trait_sig).references_error() {
// Select obligations to make progress on inference before processing
// the wf obligation below.
// FIXME(-Znext-solver): Not needed when the hack below is removed.
let errors = ocx.select_where_possible();
if !errors.is_empty() {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(reported);
}
// See #108544. Annoying, we can end up in cases where, because of winnowing,
// we pick param env candidates over a more general impl, leading to more
// stricter lifetime requirements than we would otherwise need. This can
// trigger the lint. Instead, let's only consider type outlives and
// region outlives obligations.
//
// FIXME(-Znext-solver): Try removing this hack again once the new
// solver is stable. We should just be able to register a WF pred for
// the fn sig.
let mut wf_args: smallvec::SmallVec<[_; 4]> =
unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
// Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
// will give back the well-formed predicate of the same array.
let mut wf_args_seen: FxHashSet<_> = wf_args.iter().copied().collect();
while let Some(term) = wf_args.pop() {
let Some(obligations) = rustc_trait_selection::traits::wf::obligations(
infcx,
param_env,
impl_m_def_id,
0,
term,
impl_m_span,
) else {
continue;
};
for obligation in obligations {
debug!(?obligation);
match obligation.predicate.kind().skip_binder() {
// We need to register Projection oblgiations too, because we may end up with
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
// If we only register the region outlives obligation, this leads to an unconstrained var.
// See `implied_bounds_entailment_alias_var.rs` test.
ty::PredicateKind::Clause(
ty::ClauseKind::RegionOutlives(..)
| ty::ClauseKind::TypeOutlives(..)
| ty::ClauseKind::Projection(..),
) => ocx.register_obligation(obligation),
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
if wf_args_seen.insert(term) {
wf_args.push(term)
}
}
_ => {}
}
}
}
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
cause,
param_env,
ty::ClauseKind::WellFormed(
Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig)).into(),
),
));
}
// Check that all obligations are satisfied by the implementation's

View file

@ -1327,7 +1327,7 @@ pub(crate) struct ImplForTyRequires {
}
#[derive(Diagnostic)]
#[diag(hir_analysis_traits_with_defualt_impl, code = E0321)]
#[diag(hir_analysis_traits_with_default_impl, code = E0321)]
#[note]
pub(crate) struct TraitsWithDefaultImpl<'a> {
#[primary_span]

View file

@ -59,7 +59,6 @@ This API is completely unstable and subject to change.
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]

View file

@ -2,7 +2,6 @@
//! the definitions in this file have equivalents in `rustc_ast_pretty`.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![recursion_limit = "256"]
// tidy-alphabetical-end

View file

@ -680,6 +680,18 @@ pub(crate) enum SuggestBoxing {
hir_typeck_suggest_boxing_when_appropriate,
applicability = "machine-applicable"
)]
ExprFieldShorthand {
#[suggestion_part(code = "{ident}: Box::new(")]
start: Span,
#[suggestion_part(code = ")")]
end: Span,
ident: Ident,
},
#[note(hir_typeck_suggest_boxing_note)]
#[multipart_suggestion(
hir_typeck_suggest_boxing_when_appropriate,
applicability = "machine-applicable"
)]
Other {
#[suggestion_part(code = "Box::new(")]
start: Span,

View file

@ -2339,7 +2339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if !mismatched_params.is_empty() {
// For each mismatched paramter, create a two-way link to each matched parameter
// For each mismatched parameter, create a two-way link to each matched parameter
// of the same type.
let mut dependants = IndexVec::<ExpectedIdx, _>::from_fn_n(
|_| SmallVec::<[u32; 4]>::new(),

View file

@ -585,6 +585,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
errors::SuggestBoxing::AsyncBody
}
_ if let Node::ExprField(expr_field) = self.tcx.parent_hir_node(hir_id)
&& expr_field.is_shorthand =>
{
errors::SuggestBoxing::ExprFieldShorthand {
start: span.shrink_to_lo(),
end: span.shrink_to_hi(),
ident: expr_field.ident,
}
}
_ => errors::SuggestBoxing::Other {
start: span.shrink_to_lo(),
end: span.shrink_to_hi(),

View file

@ -105,16 +105,26 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
}
fn assign(&mut self, span: Span, nid: HirId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
// We evaluate expressions twice occasionally in diagnostics for better
// type information or because it needs type information out-of-order.
// In order to not ICE and not lead to knock-on ambiguity errors, if we
// try to re-assign a type to a local, then just take out the previous
// type and delay a bug.
if let Some(&local) = self.fcx.locals.borrow_mut().get(&nid) {
self.fcx.dcx().span_delayed_bug(span, "evaluated expression more than once");
return local;
}
match ty_opt {
None => {
// Infer the variable's type.
let var_ty = self.fcx.next_ty_var(span);
assert_eq!(self.fcx.locals.borrow_mut().insert(nid, var_ty), None);
self.fcx.locals.borrow_mut().insert(nid, var_ty);
var_ty
}
Some(typ) => {
// Take type that the user specified.
assert_eq!(self.fcx.locals.borrow_mut().insert(nid, typ), None);
self.fcx.locals.borrow_mut().insert(nid, typ);
typ
}
}

View file

@ -1,7 +1,6 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(box_patterns)]
#![feature(if_let_guard)]

View file

@ -16,7 +16,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]

View file

@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(decl_macro)]
#![feature(file_buffered)]
#![feature(iter_intersperse)]

View file

@ -907,7 +907,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
feed.output_filenames(Arc::new(outputs));
let res = f(tcx);
// FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()?
// FIXME maybe run finish even when a fatal error occurred? or at least tcx.alloc_self_profile_query_strings()?
tcx.finish();
res
},
@ -996,10 +996,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
sess.time("MIR_borrow_checking", || {
tcx.par_hir_body_owners(|def_id| {
// Run unsafety check because it's responsible for stealing and
// deallocating THIR.
tcx.ensure_ok().check_unsafety(def_id);
if !tcx.is_typeck_child(def_id.to_def_id()) {
// Child unsafety and borrowck happens together with the parent
tcx.ensure_ok().check_unsafety(def_id);
tcx.ensure_ok().mir_borrowck(def_id)
}
});

View file

@ -362,6 +362,10 @@ lint_impl_trait_redundant_captures = all possible in-scope parameters are alread
lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
.note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
.raw_ptr = this raw pointer has type `{$raw_ptr_ty}`
.autoref = autoref is being applied to this expression, resulting in: `{$autoref_ty}`
.overloaded_deref = references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
.method_def = method calls to `{$method_name}` require a reference
.suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe

View file

@ -4,7 +4,10 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDer
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;
use crate::lints::{ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsSuggestion};
use crate::lints::{
ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin,
ImplicitUnsafeAutorefsSuggestion,
};
use crate::{LateContext, LateLintPass, LintContext};
declare_lint! {
@ -92,25 +95,37 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
&& let adjustments = peel_derefs_adjustments(&**adjustments)
// 3. An automatically inserted reference (might come from a deref).
&& let [adjustment] = adjustments
&& let Some(borrow_mutbl) = has_implicit_borrow(adjustment)
&& let Some((borrow_mutbl, through_overloaded_deref)) = has_implicit_borrow(adjustment)
&& let ExprKind::Unary(UnOp::Deref, dereferenced) =
// 2. Any number of place projections.
peel_place_mappers(inner).kind
// 1. Deref of a raw pointer.
&& typeck.expr_ty(dereferenced).is_raw_ptr()
// PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
&& match expr.kind {
ExprKind::MethodCall(..) => matches!(
cx.typeck_results().type_dependent_def_id(expr.hir_id),
Some(def_id) if cx.tcx.has_attr(def_id, sym::rustc_no_implicit_autorefs)
),
_ => true,
&& let method_did = match expr.kind {
// PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
_ => None,
}
&& method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true)
{
cx.emit_span_lint(
DANGEROUS_IMPLICIT_AUTOREFS,
expr.span.source_callsite(),
ImplicitUnsafeAutorefsDiag {
raw_ptr_span: dereferenced.span,
raw_ptr_ty: typeck.expr_ty(dereferenced),
origin: if through_overloaded_deref {
ImplicitUnsafeAutorefsOrigin::OverloadedDeref
} else {
ImplicitUnsafeAutorefsOrigin::Autoref {
autoref_span: inner.span,
autoref_ty: typeck.expr_ty_adjusted(inner),
}
},
method: method_did.map(|did| ImplicitUnsafeAutorefsMethodNote {
def_span: cx.tcx.def_span(did),
method_name: cx.tcx.item_name(did),
}),
suggestion: ImplicitUnsafeAutorefsSuggestion {
mutbl: borrow_mutbl.ref_prefix_str(),
deref: if is_coming_from_deref { "*" } else { "" },
@ -146,11 +161,12 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen
/// Test if some adjustment has some implicit borrow.
///
/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
/// Returns `Some((mutability, was_an_overloaded_deref))` if the argument adjustment is
/// an implicit borrow (or has an implicit borrow via an overloaded deref).
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<(Mutability, bool)> {
match kind {
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some(mutbl.into()),
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some((mutbl, true)),
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some((mutbl.into(), false)),
Adjust::NeverToAny
| Adjust::Pointer(..)
| Adjust::ReborrowPin(..)

View file

@ -21,7 +21,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]

View file

@ -59,11 +59,38 @@ pub(crate) enum ShadowedIntoIterDiagSub {
#[derive(LintDiagnostic)]
#[diag(lint_implicit_unsafe_autorefs)]
#[note]
pub(crate) struct ImplicitUnsafeAutorefsDiag {
pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> {
#[label(lint_raw_ptr)]
pub raw_ptr_span: Span,
pub raw_ptr_ty: Ty<'a>,
#[subdiagnostic]
pub origin: ImplicitUnsafeAutorefsOrigin<'a>,
#[subdiagnostic]
pub method: Option<ImplicitUnsafeAutorefsMethodNote>,
#[subdiagnostic]
pub suggestion: ImplicitUnsafeAutorefsSuggestion,
}
#[derive(Subdiagnostic)]
pub(crate) enum ImplicitUnsafeAutorefsOrigin<'a> {
#[note(lint_autoref)]
Autoref {
#[primary_span]
autoref_span: Span,
autoref_ty: Ty<'a>,
},
#[note(lint_overloaded_deref)]
OverloadedDeref,
}
#[derive(Subdiagnostic)]
#[note(lint_method_def)]
pub(crate) struct ImplicitUnsafeAutorefsMethodNote {
#[primary_span]
pub def_span: Span,
pub method_name: Symbol,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
pub(crate) struct ImplicitUnsafeAutorefsSuggestion {

View file

@ -622,37 +622,10 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
return wrap(SI);
}
enum class LLVMRustAsmDialect {
Att,
Intel,
};
static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
switch (Dialect) {
case LLVMRustAsmDialect::Att:
return InlineAsm::AD_ATT;
case LLVMRustAsmDialect::Intel:
return InlineAsm::AD_Intel;
default:
report_fatal_error("bad AsmDialect.");
}
}
extern "C" uint64_t LLVMRustGetArrayNumElements(LLVMTypeRef Ty) {
return unwrap(Ty)->getArrayNumElements();
}
extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
char *Constraints, size_t ConstraintsLen,
LLVMBool HasSideEffects, LLVMBool IsAlignStack,
LLVMRustAsmDialect Dialect, LLVMBool CanThrow) {
return wrap(InlineAsm::get(
unwrap<FunctionType>(Ty), StringRef(AsmString, AsmStringLen),
StringRef(Constraints, ConstraintsLen), HasSideEffects, IsAlignStack,
fromRust(Dialect), CanThrow));
}
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
size_t ConstraintsLen) {
// llvm::Error converts to true if it is an error.

View file

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(rustc::default_hash_types)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(if_let_guard)]
#![feature(never_type)]
#![feature(proc_macro_diagnostic)]

View file

@ -299,7 +299,7 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
let output = quote! {
const SYMBOL_DIGITS_BASE: u32 = #symbol_digits_base;
/// The number of predefined symbols; this is the the first index for
/// The number of predefined symbols; this is the first index for
/// extra pre-interned symbols in an Interner created via
/// [`Interner::with_extra_symbols`].
pub const PREDEFINED_SYMBOLS_COUNT: u32 = #predefined_symbols_count;

View file

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(coroutines)]

View file

@ -28,7 +28,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(allocator_api)]

View file

@ -52,6 +52,7 @@ pub use rustc_session::lint::RegisteredTools;
use rustc_span::hygiene::MacroKind;
use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet};
pub use rustc_type_ir::fast_reject::DeepRejectCtxt;
#[allow(
hidden_glob_reexports,
rustc::usage_of_type_ir_inherent,

View file

@ -1485,7 +1485,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// panic occurred (a subset of the drops in `scope`, since we sometimes elide StorageDead and other
/// instructions on unwinding)
/// * `dropline_to`, describes the drops that would occur at this point in the code if a
/// coroutine drop occured.
/// coroutine drop occurred.
/// * `storage_dead_on_unwind`, if true, then we should emit `StorageDead` even when unwinding
/// * `arg_count`, number of MIR local variables corresponding to fn arguments (used to assert that we don't drop those)
fn build_scope_drops<'tcx, F>(

View file

@ -1148,8 +1148,9 @@ impl UnsafeOpKind {
pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
// Closures and inline consts are handled by their owner, if it has a body
assert!(!tcx.is_typeck_child(def.to_def_id()));
// Also, don't safety check custom MIR
if tcx.is_typeck_child(def.to_def_id()) || tcx.has_attr(def, sym::custom_mir) {
if tcx.has_attr(def, sym::custom_mir) {
return;
}

View file

@ -3,7 +3,6 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(if_let_guard)]

View file

@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]

View file

@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]

View file

@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(file_buffered)]
#![feature(if_let_guard)]

View file

@ -2,6 +2,7 @@
pub(super) mod structural_traits;
use std::cell::Cell;
use std::ops::ControlFlow;
use derive_where::derive_where;
@ -117,24 +118,24 @@ where
) -> Result<Candidate<I>, NoSolution> {
Self::fast_reject_assumption(ecx, goal, assumption)?;
ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate {
Ok(candidate) => inspect::ProbeKind::TraitCandidate {
source: candidate.source,
result: Ok(candidate.result),
},
Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
source: CandidateSource::ParamEnv(ParamEnvSource::Global),
result: Err(NoSolution),
},
// Dealing with `ParamEnv` candidates is a bit of a mess as we need to lazily
// check whether the candidate is global while considering normalization.
//
// We need to write into `source` inside of `match_assumption`, but need to access it
// in `probe` even if the candidate does not apply before we get there. We handle this
// by using a `Cell` here. We only ever write into it inside of `match_assumption`.
let source = Cell::new(CandidateSource::ParamEnv(ParamEnvSource::Global));
ecx.probe(|result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
source: source.get(),
result: *result,
})
.enter(|ecx| {
Self::match_assumption(ecx, goal, assumption)?;
let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
Ok(Candidate {
source,
result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
Self::match_assumption(ecx, goal, assumption, |ecx| {
source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
})
.map(|result| Candidate { source: source.get(), result })
}
/// Try equating an assumption predicate against a goal's predicate. If it
@ -150,10 +151,8 @@ where
) -> Result<Candidate<I>, NoSolution> {
Self::fast_reject_assumption(ecx, goal, assumption)?;
ecx.probe_trait_candidate(source).enter(|ecx| {
Self::match_assumption(ecx, goal, assumption)?;
then(ecx)
})
ecx.probe_trait_candidate(source)
.enter(|ecx| Self::match_assumption(ecx, goal, assumption, then))
}
/// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
@ -169,7 +168,8 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution>;
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I>;
fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,

View file

@ -945,7 +945,7 @@ where
// This is quite similar to the `projection_may_match` we use in unsizing,
// but here we want to unify a projection predicate against an alias term
// so we can replace it with the the projection predicate's term.
// so we can replace it with the projection predicate's term.
let mut matching_projections = replacements
.iter()
.filter(|source_projection| self.projection_may_match(**source_projection, alias_term));

View file

@ -61,13 +61,14 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let host_clause = assumption.as_host_effect_clause().unwrap();
let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
Ok(())
then(ecx)
}
/// Register additional assumptions for aliases corresponding to `~const` item bounds.

View file

@ -129,7 +129,40 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let cx = ecx.cx();
// FIXME(generic_associated_types): Addresses aggressive inference in #92917.
//
// If this type is a GAT with currently unconstrained arguments, we do not
// want to normalize it via a candidate which only applies for a specific
// instantiation. We could otherwise keep the GAT as rigid and succeed this way.
// See tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs.
//
// This only avoids normalization if the GAT arguments are fully unconstrained.
// This is quite arbitrary but fixing it causes some ambiguity, see #125196.
match goal.predicate.alias.kind(cx) {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
for arg in goal.predicate.alias.own_args(cx).iter() {
let Some(term) = arg.as_term() else {
continue;
};
let term = ecx.structurally_normalize_term(goal.param_env, term)?;
if term.is_infer() {
return ecx.evaluate_added_goals_and_make_canonical_response(
Certainty::AMBIGUOUS,
);
}
}
}
ty::AliasTermKind::OpaqueTy
| ty::AliasTermKind::InherentTy
| ty::AliasTermKind::InherentConst
| ty::AliasTermKind::FreeTy
| ty::AliasTermKind::FreeConst
| ty::AliasTermKind::UnevaluatedConst => {}
}
let projection_pred = assumption.as_projection_clause().unwrap();
let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
@ -139,7 +172,6 @@ where
// Add GAT where clauses from the trait's definition
// FIXME: We don't need these, since these are the type's own WF obligations.
let cx = ecx.cx();
ecx.add_goals(
GoalSource::AliasWellFormed,
cx.own_predicates_of(goal.predicate.def_id())
@ -147,7 +179,7 @@ where
.map(|pred| goal.with(cx, pred)),
);
Ok(())
then(ecx)
}
fn consider_additional_alias_assumptions(

View file

@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates
use crate::solve::inspect::ProbeKind;
use crate::solve::{
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
NoSolution, ParamEnvSource,
NoSolution, ParamEnvSource, QueryResult,
};
impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
@ -150,13 +150,14 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let trait_clause = assumption.as_trait_clause().unwrap();
let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
Ok(())
then(ecx)
}
fn consider_auto_trait_candidate(

View file

@ -815,7 +815,6 @@ parse_switch_ref_box_order = switch the order of `ref` and `box`
.suggestion = swap them
parse_ternary_operator = Rust has no ternary operator
.help = use an `if-else` expression instead
parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
.suggestion = use `!` to perform bitwise not
@ -963,6 +962,8 @@ parse_use_empty_block_not_semi = expected { "`{}`" }, found `;`
parse_use_eq_instead = unexpected `==`
.suggestion = try using `=` instead
parse_use_if_else = use an `if-else` expression instead
parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
parse_use_let_not_var = write `let` instead of `var` to introduce a new variable

View file

@ -436,10 +436,28 @@ pub(crate) enum IfExpressionMissingThenBlockSub {
#[derive(Diagnostic)]
#[diag(parse_ternary_operator)]
#[help]
pub(crate) struct TernaryOperator {
#[primary_span]
pub span: Span,
/// If we have a span for the condition expression, suggest the if/else
#[subdiagnostic]
pub sugg: Option<TernaryOperatorSuggestion>,
/// Otherwise, just print the suggestion message
#[help(parse_use_if_else)]
pub no_sugg: bool,
}
#[derive(Subdiagnostic, Copy, Clone)]
#[multipart_suggestion(parse_use_if_else, applicability = "maybe-incorrect", style = "verbose")]
pub(crate) struct TernaryOperatorSuggestion {
#[suggestion_part(code = "if ")]
pub before_cond: Span,
#[suggestion_part(code = "{{")]
pub question: Span,
#[suggestion_part(code = "}} else {{")]
pub colon: Span,
#[suggestion_part(code = " }}")]
pub end: Span,
}
#[derive(Subdiagnostic)]

View file

@ -4,7 +4,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(debug_closure_helpers)]

View file

@ -41,8 +41,9 @@ use crate::errors::{
IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody,
QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
TernaryOperator, TernaryOperatorSuggestion, UnexpectedConstInGenericParam,
UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets,
UseEqInstead, WrapType,
};
use crate::parser::attr::InnerAttrPolicy;
use crate::{exp, fluent_generated as fluent};
@ -497,7 +498,7 @@ impl<'a> Parser<'a> {
// If the user is trying to write a ternary expression, recover it and
// return an Err to prevent a cascade of irrelevant diagnostics.
if self.prev_token == token::Question
&& let Err(e) = self.maybe_recover_from_ternary_operator()
&& let Err(e) = self.maybe_recover_from_ternary_operator(None)
{
return Err(e);
}
@ -1602,12 +1603,18 @@ impl<'a> Parser<'a> {
/// Rust has no ternary operator (`cond ? then : else`). Parse it and try
/// to recover from it if `then` and `else` are valid expressions. Returns
/// an err if this appears to be a ternary expression.
pub(super) fn maybe_recover_from_ternary_operator(&mut self) -> PResult<'a, ()> {
/// If we have the span of the condition, we can provide a better error span
/// and code suggestion.
pub(super) fn maybe_recover_from_ternary_operator(
&mut self,
cond: Option<Span>,
) -> PResult<'a, ()> {
if self.prev_token != token::Question {
return PResult::Ok(());
}
let lo = self.prev_token.span.lo();
let question = self.prev_token.span;
let lo = cond.unwrap_or(question).lo();
let snapshot = self.create_snapshot_for_diagnostic();
if match self.parse_expr() {
@ -1620,11 +1627,20 @@ impl<'a> Parser<'a> {
}
} {
if self.eat_noexpect(&token::Colon) {
let colon = self.prev_token.span;
match self.parse_expr() {
Ok(_) => {
return Err(self
.dcx()
.create_err(TernaryOperator { span: self.token.span.with_lo(lo) }));
Ok(expr) => {
let sugg = cond.map(|cond| TernaryOperatorSuggestion {
before_cond: cond.shrink_to_lo(),
question,
colon,
end: expr.span.shrink_to_hi(),
});
return Err(self.dcx().create_err(TernaryOperator {
span: self.prev_token.span.with_lo(lo),
sugg,
no_sugg: sugg.is_none(),
}));
}
Err(err) => {
err.cancel();

View file

@ -879,7 +879,12 @@ impl<'a> Parser<'a> {
{
// Just check for errors and recover; do not eat semicolon yet.
let expect_result = self.expect_one_of(&[], &[exp!(Semi), exp!(CloseBrace)]);
let expect_result =
if let Err(e) = self.maybe_recover_from_ternary_operator(Some(expr.span)) {
Err(e)
} else {
self.expect_one_of(&[], &[exp!(Semi), exp!(CloseBrace)])
};
// Try to both emit a better diagnostic, and avoid further errors by replacing
// the `expr` with `ExprKind::Err`.

View file

@ -6,7 +6,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(box_patterns)]

View file

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(associated_type_defaults)]

View file

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(rustc::potential_query_instability, internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]

View file

@ -10,7 +10,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]

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