Auto merge of #3706 - rust-lang:rustup-2024-06-24, r=oli-obk
Automatic Rustup
This commit is contained in:
commit
b8e1d7ef6f
433 changed files with 10940 additions and 5596 deletions
186
Cargo.lock
186
Cargo.lock
|
|
@ -266,7 +266,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -601,9 +601,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.5"
|
||||
version = "4.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4"
|
||||
checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
|
@ -617,7 +617,7 @@ dependencies = [
|
|||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -644,7 +644,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rustc_tools_util",
|
||||
"serde",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"tempfile",
|
||||
"termize",
|
||||
"tokio",
|
||||
|
|
@ -755,7 +755,7 @@ dependencies = [
|
|||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -991,7 +991,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1002,7 +1002,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
|||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1028,7 +1028,7 @@ version = "0.1.81"
|
|||
dependencies = [
|
||||
"itertools",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1069,7 +1069,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1079,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1090,7 +1090,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1102,7 +1102,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1180,13 +1180,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1506,7 +1506,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1739,7 +1739,7 @@ dependencies = [
|
|||
"markup5ever",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1780,18 +1780,6 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_list"
|
||||
version = "1.5.0"
|
||||
|
|
@ -1845,51 +1833,6 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"smallvec",
|
||||
"utf16_iter",
|
||||
"utf8_iter",
|
||||
"write16",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_locid_transform",
|
||||
"icu_properties_data",
|
||||
"icu_provider",
|
||||
"tinystr",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "1.5.0"
|
||||
|
|
@ -1928,7 +1871,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1939,14 +1882,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
|||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.0.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed"
|
||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||
dependencies = [
|
||||
"icu_normalizer",
|
||||
"icu_properties",
|
||||
"smallvec",
|
||||
"utf8_iter",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2146,9 +2087,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "leb128"
|
||||
|
|
@ -2521,9 +2462,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"compiler_builtins",
|
||||
|
|
@ -2949,7 +2890,7 @@ dependencies = [
|
|||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3141,9 +3082,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.85"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
|
@ -4045,7 +3986,7 @@ dependencies = [
|
|||
"fluent-syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
|
|
@ -4179,7 +4120,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4326,7 +4267,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -4905,7 +4846,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -5003,7 +4944,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5153,7 +5094,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5446,9 +5387,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.66"
|
||||
version = "2.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||
checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -5463,7 +5404,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5640,7 +5581,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5678,6 +5619,7 @@ dependencies = [
|
|||
name = "tidy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"build_helper",
|
||||
"cargo_metadata 0.15.4",
|
||||
"fluent-syntax",
|
||||
"ignore",
|
||||
|
|
@ -5854,7 +5796,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6054,7 +5996,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
|
|||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
|
|
@ -6074,6 +6016,12 @@ dependencies = [
|
|||
"ucd-parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
|
|
@ -6175,9 +6123,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.1"
|
||||
version = "2.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56"
|
||||
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
|
|
@ -6190,24 +6138,12 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
|
||||
|
||||
[[package]]
|
||||
name = "utf8_iter"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
|
|
@ -6292,7 +6228,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -6314,7 +6250,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -6395,7 +6331,7 @@ dependencies = [
|
|||
"rayon",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"windows-metadata",
|
||||
]
|
||||
|
||||
|
|
@ -6571,12 +6507,6 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
|
@ -6647,7 +6577,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6668,7 +6598,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6688,7 +6618,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6711,5 +6641,5 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
pub use BinOpToken::*;
|
||||
pub use LitKind::*;
|
||||
pub use Nonterminal::*;
|
||||
pub use NtExprKind::*;
|
||||
pub use NtPatKind::*;
|
||||
pub use TokenKind::*;
|
||||
|
||||
use crate::ast;
|
||||
|
|
@ -871,6 +873,27 @@ impl PartialEq<TokenKind> for Token {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
|
||||
pub enum NtPatKind {
|
||||
// Matches or-patterns. Was written using `pat` in edition 2021 or later.
|
||||
PatWithOr,
|
||||
// Doesn't match or-patterns.
|
||||
// - `inferred`: was written using `pat` in edition 2015 or 2018.
|
||||
// - `!inferred`: was written using `pat_param`.
|
||||
PatParam { inferred: bool },
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
|
||||
pub enum NtExprKind {
|
||||
// Matches expressions using the post-edition 2024. Was written using
|
||||
// `expr` in edition 2024 or later.
|
||||
Expr,
|
||||
// Matches expressions using the pre-edition 2024 rules.
|
||||
// - `inferred`: was written using `expr` in edition 2021 or earlier.
|
||||
// - `!inferred`: was written using `expr_2021`.
|
||||
Expr2021 { inferred: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable)]
|
||||
/// For interpolation during macro expansion.
|
||||
pub enum Nonterminal {
|
||||
|
|
@ -892,19 +915,8 @@ pub enum NonterminalKind {
|
|||
Item,
|
||||
Block,
|
||||
Stmt,
|
||||
PatParam {
|
||||
/// Keep track of whether the user used `:pat_param` or `:pat` and we inferred it from the
|
||||
/// edition of the span. This is used for diagnostics.
|
||||
inferred: bool,
|
||||
},
|
||||
PatWithOr,
|
||||
Expr,
|
||||
/// Matches an expression using the rules from edition 2021 and earlier.
|
||||
Expr2021 {
|
||||
/// Keep track of whether the user used `:expr` or `:expr_2021` and we inferred it from the
|
||||
/// edition of the span. This is used for diagnostics AND feature gating.
|
||||
inferred: bool,
|
||||
},
|
||||
Pat(NtPatKind),
|
||||
Expr(NtExprKind),
|
||||
Ty,
|
||||
Ident,
|
||||
Lifetime,
|
||||
|
|
@ -926,20 +938,22 @@ impl NonterminalKind {
|
|||
sym::item => NonterminalKind::Item,
|
||||
sym::block => NonterminalKind::Block,
|
||||
sym::stmt => NonterminalKind::Stmt,
|
||||
sym::pat => match edition() {
|
||||
Edition::Edition2015 | Edition::Edition2018 => {
|
||||
NonterminalKind::PatParam { inferred: true }
|
||||
sym::pat => {
|
||||
if edition().at_least_rust_2021() {
|
||||
NonterminalKind::Pat(PatWithOr)
|
||||
} else {
|
||||
NonterminalKind::Pat(PatParam { inferred: true })
|
||||
}
|
||||
Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
|
||||
},
|
||||
sym::pat_param => NonterminalKind::PatParam { inferred: false },
|
||||
sym::expr => match edition() {
|
||||
Edition::Edition2015 | Edition::Edition2018 | Edition::Edition2021 => {
|
||||
NonterminalKind::Expr2021 { inferred: true }
|
||||
}
|
||||
sym::pat_param => NonterminalKind::Pat(PatParam { inferred: false }),
|
||||
sym::expr => {
|
||||
if edition().at_least_rust_2024() {
|
||||
NonterminalKind::Expr(Expr)
|
||||
} else {
|
||||
NonterminalKind::Expr(Expr2021 { inferred: true })
|
||||
}
|
||||
Edition::Edition2024 => NonterminalKind::Expr,
|
||||
},
|
||||
sym::expr_2021 => NonterminalKind::Expr2021 { inferred: false },
|
||||
}
|
||||
sym::expr_2021 => NonterminalKind::Expr(Expr2021 { inferred: false }),
|
||||
sym::ty => NonterminalKind::Ty,
|
||||
sym::ident => NonterminalKind::Ident,
|
||||
sym::lifetime => NonterminalKind::Lifetime,
|
||||
|
|
@ -951,15 +965,16 @@ impl NonterminalKind {
|
|||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
fn symbol(self) -> Symbol {
|
||||
match self {
|
||||
NonterminalKind::Item => sym::item,
|
||||
NonterminalKind::Block => sym::block,
|
||||
NonterminalKind::Stmt => sym::stmt,
|
||||
NonterminalKind::PatParam { inferred: false } => sym::pat_param,
|
||||
NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat,
|
||||
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: true } => sym::expr,
|
||||
NonterminalKind::Expr2021 { inferred: false } => sym::expr_2021,
|
||||
NonterminalKind::Pat(PatParam { inferred: true } | PatWithOr) => sym::pat,
|
||||
NonterminalKind::Pat(PatParam { inferred: false }) => sym::pat_param,
|
||||
NonterminalKind::Expr(Expr2021 { inferred: true } | Expr) => sym::expr,
|
||||
NonterminalKind::Expr(Expr2021 { inferred: false }) => sym::expr_2021,
|
||||
NonterminalKind::Ty => sym::ty,
|
||||
NonterminalKind::Ident => sym::ident,
|
||||
NonterminalKind::Lifetime => sym::lifetime,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim
|
|||
.label = {ast_passes_auto_super_lifetime}
|
||||
.suggestion = remove the super traits or lifetime bounds
|
||||
|
||||
ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||
ast_passes_bad_c_variadic = only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
|
||||
|
||||
ast_passes_bare_fn_invalid_safety = function pointers cannot be declared with `safe` safety qualifier
|
||||
.suggestion = remove safe from this item
|
||||
|
|
|
|||
|
|
@ -637,6 +637,7 @@ impl<'a> AstValidator<'a> {
|
|||
(Some(FnCtxt::Foreign), _) => return,
|
||||
(Some(FnCtxt::Free), Some(header)) => match header.ext {
|
||||
Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }, _)
|
||||
| Extern::Explicit(StrLit { symbol_unescaped: sym::C_dash_unwind, .. }, _)
|
||||
| Extern::Implicit(_)
|
||||
if matches!(header.safety, Safety::Unsafe(_)) =>
|
||||
{
|
||||
|
|
@ -898,7 +899,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
|
|||
|
||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_attribute(&mut self, attr: &Attribute) {
|
||||
validate_attr::check_attr(&self.session.psess, attr);
|
||||
validate_attr::check_attr(&self.features, &self.session.psess, attr);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ impl<'tcx> BorrowSet<'tcx> {
|
|||
) -> Self {
|
||||
let mut visitor = GatherBorrows {
|
||||
tcx,
|
||||
body: body,
|
||||
body,
|
||||
location_map: Default::default(),
|
||||
activation_map: Default::default(),
|
||||
local_map: Default::default(),
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
|
|||
via(msg_old),
|
||||
);
|
||||
|
||||
if msg_new == "" {
|
||||
if msg_new.is_empty() {
|
||||
// If `msg_new` is empty, then this isn't a borrow of a union field.
|
||||
err.span_label(span, format!("{kind_new} borrow occurs here"));
|
||||
err.span_label(old_span, format!("{kind_old} borrow occurs here"));
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock) {
|
||||
state.borrows.clone_from(&self.borrows.entry_set_for_block(block));
|
||||
state.uninits.clone_from(&self.uninits.entry_set_for_block(block));
|
||||
state.ever_inits.clone_from(&self.ever_inits.entry_set_for_block(block));
|
||||
state.borrows.clone_from(self.borrows.entry_set_for_block(block));
|
||||
state.uninits.clone_from(self.uninits.entry_set_for_block(block));
|
||||
state.ever_inits.clone_from(self.ever_inits.entry_set_for_block(block));
|
||||
}
|
||||
|
||||
fn reconstruct_before_statement_effect(
|
||||
|
|
|
|||
|
|
@ -895,7 +895,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
for alias_ty in alias_tys {
|
||||
if alias_ty.span.desugaring_kind().is_some() {
|
||||
// Skip `async` desugaring `impl Future`.
|
||||
()
|
||||
}
|
||||
if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
|
||||
if lt.ident.name == kw::Empty {
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
}
|
||||
|
||||
// Otherwise, let's descend into the referent types.
|
||||
search_stack.push((*referent_ty, &referent_hir_ty.ty));
|
||||
search_stack.push((*referent_ty, referent_hir_ty.ty));
|
||||
}
|
||||
|
||||
// Match up something like `Foo<'1>`
|
||||
|
|
@ -558,7 +558,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
}
|
||||
|
||||
(ty::RawPtr(mut_ty, _), hir::TyKind::Ptr(mut_hir_ty)) => {
|
||||
search_stack.push((*mut_ty, &mut_hir_ty.ty));
|
||||
search_stack.push((*mut_ty, mut_hir_ty.ty));
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
|
@ -652,7 +652,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?;
|
||||
let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
|
||||
self.infcx.tcx,
|
||||
&self.upvars,
|
||||
self.upvars,
|
||||
upvar_index,
|
||||
);
|
||||
let region_name = self.synthesize_region_name();
|
||||
|
|
@ -717,7 +717,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
.output;
|
||||
span = output.span();
|
||||
if let hir::FnRetTy::Return(ret) = output {
|
||||
hir_ty = Some(self.get_future_inner_return_ty(*ret));
|
||||
hir_ty = Some(self.get_future_inner_return_ty(ret));
|
||||
}
|
||||
" of async function"
|
||||
}
|
||||
|
|
@ -958,7 +958,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
{
|
||||
let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
|
||||
self.infcx.tcx,
|
||||
&self.upvars,
|
||||
self.upvars,
|
||||
upvar_index,
|
||||
);
|
||||
let region_name = self.synthesize_region_name();
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
|||
move_data,
|
||||
elements,
|
||||
upvars,
|
||||
polonius_input,
|
||||
);
|
||||
|
||||
// Create the region inference context, taking ownership of the
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ pub(crate) fn emit_facts<'tcx>(
|
|||
emit_universal_region_facts(
|
||||
all_facts,
|
||||
borrow_set,
|
||||
&universal_regions,
|
||||
&universal_region_relations,
|
||||
universal_regions,
|
||||
universal_region_relations,
|
||||
);
|
||||
emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set);
|
||||
emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set);
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
|
|||
|
||||
for (reg_var_idx, scc_idx) in sccs.scc_indices().iter().enumerate() {
|
||||
let reg_var = ty::RegionVid::from_usize(reg_var_idx);
|
||||
let origin = var_to_origin.get(®_var).unwrap_or_else(|| &RegionCtxt::Unknown);
|
||||
let origin = var_to_origin.get(®_var).unwrap_or(&RegionCtxt::Unknown);
|
||||
components[scc_idx.as_usize()].insert((reg_var, *origin));
|
||||
}
|
||||
|
||||
|
|
@ -2216,7 +2216,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// #114907 where this happens via liveness and dropck outlives results.
|
||||
// Therefore, we return a default value in case that happens, which should at worst emit a
|
||||
// suboptimal error, instead of the ICE.
|
||||
self.universe_causes.get(&universe).cloned().unwrap_or_else(|| UniverseInfo::other())
|
||||
self.universe_causes.get(&universe).cloned().unwrap_or_else(UniverseInfo::other)
|
||||
}
|
||||
|
||||
/// Tries to find the terminator of the loop in which the region 'r' resides.
|
||||
|
|
|
|||
|
|
@ -418,9 +418,7 @@ fn check_opaque_type_parameter_valid<'tcx>(
|
|||
let opaque_param = opaque_generics.param_at(i, tcx);
|
||||
let kind = opaque_param.kind.descr();
|
||||
|
||||
if let Err(guar) = opaque_env.param_is_error(i) {
|
||||
return Err(guar);
|
||||
}
|
||||
opaque_env.param_is_error(i)?;
|
||||
|
||||
return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
|
||||
ty: arg,
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@ use rustc_mir_dataflow::ResultsCursor;
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::{
|
||||
constraints::OutlivesConstraintSet,
|
||||
facts::{AllFacts, AllFactsExt},
|
||||
region_infer::values::LivenessValues,
|
||||
constraints::OutlivesConstraintSet, region_infer::values::LivenessValues,
|
||||
universal_regions::UniversalRegions,
|
||||
};
|
||||
|
||||
|
|
@ -38,7 +36,6 @@ pub(super) fn generate<'mir, 'tcx>(
|
|||
elements: &Rc<DenseLocationMap>,
|
||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
use_polonius: bool,
|
||||
) {
|
||||
debug!("liveness::generate");
|
||||
|
||||
|
|
@ -49,11 +46,8 @@ pub(super) fn generate<'mir, 'tcx>(
|
|||
);
|
||||
let (relevant_live_locals, boring_locals) =
|
||||
compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
|
||||
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
|
||||
|
||||
if facts_enabled {
|
||||
polonius::populate_access_facts(typeck, body, move_data);
|
||||
};
|
||||
polonius::populate_access_facts(typeck, body, move_data);
|
||||
|
||||
trace::trace(
|
||||
typeck,
|
||||
|
|
|
|||
|
|
@ -87,10 +87,10 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
|
|||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
) {
|
||||
debug!("populate_access_facts()");
|
||||
let location_table = typeck.borrowck_context.location_table;
|
||||
|
||||
if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
|
||||
debug!("populate_access_facts()");
|
||||
let location_table = typeck.borrowck_context.location_table;
|
||||
|
||||
let mut extractor = UseFactsExtractor {
|
||||
var_defined_at: &mut facts.var_defined_at,
|
||||
var_used_at: &mut facts.var_used_at,
|
||||
|
|
|
|||
|
|
@ -217,35 +217,52 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||
/// Add facts for all locals with free regions, since regions may outlive
|
||||
/// the function body only at certain nodes in the CFG.
|
||||
fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> {
|
||||
let drop_used = self
|
||||
.cx
|
||||
.typeck
|
||||
.borrowck_context
|
||||
.all_facts
|
||||
.as_ref()
|
||||
.map(|facts| facts.var_dropped_at.clone())?;
|
||||
// This collect is more necessary than immediately apparent
|
||||
// because these facts go into `add_drop_live_facts_for()`,
|
||||
// which also writes to `all_facts`, and so this is genuinely
|
||||
// a simulatneous overlapping mutable borrow.
|
||||
// FIXME for future hackers: investigate whether this is
|
||||
// actually necessary; these facts come from Polonius
|
||||
// and probably maybe plausibly does not need to go back in.
|
||||
// It may be necessary to just pick out the parts of
|
||||
// `add_drop_live_facts_for()` that make sense.
|
||||
let facts_to_add: Vec<_> = {
|
||||
let drop_used = &self.cx.typeck.borrowck_context.all_facts.as_ref()?.var_dropped_at;
|
||||
|
||||
let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect();
|
||||
let relevant_live_locals: FxIndexSet<_> =
|
||||
relevant_live_locals.iter().copied().collect();
|
||||
|
||||
let locations = IntervalSet::new(self.cx.elements.num_points());
|
||||
drop_used
|
||||
.iter()
|
||||
.filter_map(|(local, location_index)| {
|
||||
let local_ty = self.cx.body.local_decls[*local].ty;
|
||||
if relevant_live_locals.contains(local) || !local_ty.has_free_regions() {
|
||||
return None;
|
||||
}
|
||||
|
||||
for (local, location_index) in drop_used {
|
||||
if !relevant_live_locals.contains(&local) {
|
||||
let local_ty = self.cx.body.local_decls[local].ty;
|
||||
if local_ty.has_free_regions() {
|
||||
let location = match self
|
||||
.cx
|
||||
.typeck
|
||||
.borrowck_context
|
||||
.location_table
|
||||
.to_location(location_index)
|
||||
.to_location(*location_index)
|
||||
{
|
||||
RichLocation::Start(l) => l,
|
||||
RichLocation::Mid(l) => l,
|
||||
};
|
||||
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
|
||||
}
|
||||
}
|
||||
|
||||
Some((*local, local_ty, location))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
// FIXME: these locations seem to have a special meaning (e.g. everywhere, at the end, ...), but I don't know which one. Please help me rename it to something descriptive!
|
||||
// Also, if this IntervalSet is used in many places, it maybe should have a newtype'd
|
||||
// name with a description of what it means for future mortals passing by.
|
||||
let locations = IntervalSet::new(self.cx.elements.num_points());
|
||||
|
||||
for (local, local_ty, location) in facts_to_add {
|
||||
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
move_data: &MoveData<'tcx>,
|
||||
elements: &Rc<DenseLocationMap>,
|
||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||
use_polonius: bool,
|
||||
) -> MirTypeckResults<'tcx> {
|
||||
let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
|
||||
let mut constraints = MirTypeckRegionConstraints {
|
||||
|
|
@ -189,7 +188,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
checker.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
|
||||
checker.check_signature_annotation(body);
|
||||
|
||||
liveness::generate(&mut checker, body, elements, flow_inits, move_data, use_polonius);
|
||||
liveness::generate(&mut checker, body, elements, flow_inits, move_data);
|
||||
|
||||
translate_outlives_facts(&mut checker);
|
||||
let opaque_type_values = infcx.take_opaque_types();
|
||||
|
|
|
|||
|
|
@ -271,9 +271,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn TargetIs
|
|||
flags_builder.set("enable_verifier", enable_verifier).unwrap();
|
||||
flags_builder.set("regalloc_checker", enable_verifier).unwrap();
|
||||
|
||||
let preserve_frame_pointer = sess.target.options.frame_pointer
|
||||
!= rustc_target::spec::FramePointer::MayOmit
|
||||
|| matches!(sess.opts.cg.force_frame_pointers, Some(true));
|
||||
let mut frame_ptr = sess.target.options.frame_pointer.clone();
|
||||
frame_ptr.ratchet(sess.opts.cg.force_frame_pointers);
|
||||
let preserve_frame_pointer = frame_ptr != rustc_target::spec::FramePointer::MayOmit;
|
||||
flags_builder
|
||||
.set("preserve_frame_pointers", if preserve_frame_pointer { "true" } else { "false" })
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -108,9 +108,10 @@ pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attr
|
|||
let opts = &cx.sess().opts;
|
||||
// "mcount" function relies on stack pointer.
|
||||
// See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.
|
||||
if opts.unstable_opts.instrument_mcount || matches!(opts.cg.force_frame_pointers, Some(true)) {
|
||||
fp = FramePointer::Always;
|
||||
if opts.unstable_opts.instrument_mcount {
|
||||
fp.ratchet(FramePointer::Always);
|
||||
}
|
||||
fp.ratchet(opts.cg.force_frame_pointers);
|
||||
let attr_value = match fp {
|
||||
FramePointer::Always => "all",
|
||||
FramePointer::NonLeaf => "non-leaf",
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ const_eval_exact_div_has_remainder =
|
|||
|
||||
const_eval_extern_static =
|
||||
cannot access extern static ({$did})
|
||||
const_eval_extern_type_field = `extern type` field does not have a known offset
|
||||
|
||||
const_eval_fn_ptr_call =
|
||||
function pointers need an RFC before allowed to be called in {const_eval_const_context}s
|
||||
const_eval_for_loop_into_iter_non_const =
|
||||
|
|
|
|||
|
|
@ -386,33 +386,8 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
|
|||
CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
|
||||
);
|
||||
let res = ecx.load_mir(cid.instance.def, cid.promoted);
|
||||
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)).map_err(|error| {
|
||||
let (error, backtrace) = error.into_parts();
|
||||
backtrace.print_backtrace();
|
||||
|
||||
let (kind, instance) = if ecx.tcx.is_static(cid.instance.def_id()) {
|
||||
("static", String::new())
|
||||
} else {
|
||||
// If the current item has generics, we'd like to enrich the message with the
|
||||
// instance and its args: to show the actual compile-time values, in addition to
|
||||
// the expression, leading to the const eval error.
|
||||
let instance = &cid.instance;
|
||||
if !instance.args.is_empty() {
|
||||
let instance = with_no_trimmed_paths!(instance.to_string());
|
||||
("const_with_path", instance)
|
||||
} else {
|
||||
("const", String::new())
|
||||
}
|
||||
};
|
||||
|
||||
super::report(
|
||||
*ecx.tcx,
|
||||
error,
|
||||
DUMMY_SP,
|
||||
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|
||||
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
|
||||
)
|
||||
})
|
||||
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
|
||||
.map_err(|error| report_eval_error(&ecx, cid, error))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
@ -438,23 +413,60 @@ fn const_validate_mplace<'tcx>(
|
|||
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
|
||||
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targeted
|
||||
// error about the validation failure.
|
||||
.map_err(|error| report_validation_error(&ecx, error, alloc_id))?;
|
||||
.map_err(|error| report_validation_error(&ecx, cid, error, alloc_id))?;
|
||||
inner = true;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn report_validation_error<'tcx>(
|
||||
#[inline(never)]
|
||||
fn report_eval_error<'tcx>(
|
||||
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
|
||||
cid: GlobalId<'tcx>,
|
||||
error: InterpErrorInfo<'tcx>,
|
||||
alloc_id: AllocId,
|
||||
) -> ErrorHandled {
|
||||
let (error, backtrace) = error.into_parts();
|
||||
backtrace.print_backtrace();
|
||||
|
||||
let ub_note = matches!(error, InterpError::UndefinedBehavior(_)).then(|| {});
|
||||
let (kind, instance) = if ecx.tcx.is_static(cid.instance.def_id()) {
|
||||
("static", String::new())
|
||||
} else {
|
||||
// If the current item has generics, we'd like to enrich the message with the
|
||||
// instance and its args: to show the actual compile-time values, in addition to
|
||||
// the expression, leading to the const eval error.
|
||||
let instance = &cid.instance;
|
||||
if !instance.args.is_empty() {
|
||||
let instance = with_no_trimmed_paths!(instance.to_string());
|
||||
("const_with_path", instance)
|
||||
} else {
|
||||
("const", String::new())
|
||||
}
|
||||
};
|
||||
|
||||
super::report(
|
||||
*ecx.tcx,
|
||||
error,
|
||||
DUMMY_SP,
|
||||
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|
||||
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn report_validation_error<'tcx>(
|
||||
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
|
||||
cid: GlobalId<'tcx>,
|
||||
error: InterpErrorInfo<'tcx>,
|
||||
alloc_id: AllocId,
|
||||
) -> ErrorHandled {
|
||||
if !matches!(error.kind(), InterpError::UndefinedBehavior(_)) {
|
||||
// Some other error happened during validation, e.g. an unsupported operation.
|
||||
return report_eval_error(ecx, cid, error);
|
||||
}
|
||||
|
||||
let (error, backtrace) = error.into_parts();
|
||||
backtrace.print_backtrace();
|
||||
|
||||
let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
|
||||
let (size, align, _) = ecx.get_alloc_info(alloc_id);
|
||||
|
|
@ -465,6 +477,6 @@ fn report_validation_error<'tcx>(
|
|||
error,
|
||||
DUMMY_SP,
|
||||
|| crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
|
||||
move |span, frames| errors::ValidationFailure { span, ub_note, frames, raw_bytes },
|
||||
move |span, frames| errors::ValidationFailure { span, ub_note: (), frames, raw_bytes },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ pub struct ValidationFailure {
|
|||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[note(const_eval_validation_failure_note)]
|
||||
pub ub_note: Option<()>,
|
||||
pub ub_note: (),
|
||||
#[subdiagnostic]
|
||||
pub frames: Vec<FrameNote>,
|
||||
#[subdiagnostic]
|
||||
|
|
@ -825,6 +825,7 @@ impl ReportErrorExt for UnsupportedOpInfo {
|
|||
use crate::fluent_generated::*;
|
||||
match self {
|
||||
UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
|
||||
UnsupportedOpInfo::ExternTypeField => const_eval_extern_type_field,
|
||||
UnsupportedOpInfo::UnsizedLocal => const_eval_unsized_local,
|
||||
UnsupportedOpInfo::OverwritePartialPointer(_) => const_eval_partial_pointer_overwrite,
|
||||
UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_copy,
|
||||
|
|
@ -845,7 +846,10 @@ impl ReportErrorExt for UnsupportedOpInfo {
|
|||
// `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to
|
||||
// be further processed by validity checking which then turns it into something nice to
|
||||
// print. So it's not worth the effort of having diagnostics that can print the `info`.
|
||||
UnsizedLocal | Unsupported(_) | ReadPointerAsInt(_) => {}
|
||||
UnsizedLocal
|
||||
| UnsupportedOpInfo::ExternTypeField
|
||||
| Unsupported(_)
|
||||
| ReadPointerAsInt(_) => {}
|
||||
OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => {
|
||||
diag.arg("ptr", ptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc_target::abi::{self, VariantIdx};
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
use super::{
|
||||
throw_ub, throw_unsup_format, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
|
||||
throw_ub, throw_unsup, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
|
||||
Provenance, Scalar,
|
||||
};
|
||||
|
||||
|
|
@ -186,8 +186,8 @@ where
|
|||
(base_meta, offset)
|
||||
}
|
||||
None => {
|
||||
// We don't know the alignment of this field, so we cannot adjust.
|
||||
throw_unsup_format!("`extern type` does not have a known offset")
|
||||
// We cannot know the alignment of this field, so we cannot adjust.
|
||||
throw_unsup!(ExternTypeField)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
//! to be const-safe.
|
||||
|
||||
use std::fmt::Write;
|
||||
use std::hash::Hash;
|
||||
use std::num::NonZero;
|
||||
|
||||
use either::{Left, Right};
|
||||
|
|
@ -17,7 +18,8 @@ use rustc_hir as hir;
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::interpret::{
|
||||
ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, Provenance,
|
||||
ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*,
|
||||
UnsupportedOpInfo, ValidationErrorInfo,
|
||||
ValidationErrorKind::{self, *},
|
||||
};
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
|
@ -26,8 +28,6 @@ use rustc_target::abi::{
|
|||
Abi, FieldIdx, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange,
|
||||
};
|
||||
|
||||
use std::hash::Hash;
|
||||
|
||||
use super::{
|
||||
err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, AllocKind, CheckInAllocMsg,
|
||||
GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
|
||||
|
|
@ -1028,7 +1028,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
Err(err)
|
||||
if matches!(
|
||||
err.kind(),
|
||||
err_ub!(ValidationError { .. }) | InterpError::InvalidProgram(_)
|
||||
err_ub!(ValidationError { .. })
|
||||
| InterpError::InvalidProgram(_)
|
||||
| InterpError::Unsupported(UnsupportedOpInfo::ExternTypeField)
|
||||
) =>
|
||||
{
|
||||
Err(err)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ expand_feature_removed =
|
|||
expand_glob_delegation_outside_impls =
|
||||
glob delegation is only supported in impls
|
||||
|
||||
expand_glob_delegation_traitless_qpath =
|
||||
qualified path without a trait in glob delegation
|
||||
|
||||
expand_helper_attribute_name_invalid =
|
||||
`{$name}` cannot be a name of derive helper attribute
|
||||
|
||||
|
|
|
|||
|
|
@ -449,6 +449,13 @@ pub(crate) struct GlobDelegationOutsideImpls {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(expand_glob_delegation_traitless_qpath)]
|
||||
pub(crate) struct GlobDelegationTraitlessQpath {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
// This used to be the `proc_macro_back_compat` lint (#83125). It was later
|
||||
// turned into a hard error.
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use crate::base::*;
|
||||
use crate::config::StripUnconfigured;
|
||||
use crate::errors::{
|
||||
EmptyDelegationMac, GlobDelegationOutsideImpls, IncompleteParse, RecursionLimitReached,
|
||||
RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue, WrongFragmentKind,
|
||||
EmptyDelegationMac, GlobDelegationOutsideImpls, GlobDelegationTraitlessQpath, IncompleteParse,
|
||||
RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
|
||||
WrongFragmentKind,
|
||||
};
|
||||
use crate::mbe::diagnostics::annotate_err_with_kind;
|
||||
use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
|
||||
|
|
@ -1882,7 +1883,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
let mut span: Option<Span> = None;
|
||||
while let Some(attr) = attrs.next() {
|
||||
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
|
||||
validate_attr::check_attr(&self.cx.sess.psess, attr);
|
||||
validate_attr::check_attr(features, &self.cx.sess.psess, attr);
|
||||
|
||||
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
|
||||
span = Some(current_span);
|
||||
|
|
@ -1989,6 +1990,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
}
|
||||
None if let Some((deleg, item)) = node.delegation() => {
|
||||
let Some(suffixes) = &deleg.suffixes else {
|
||||
let traitless_qself =
|
||||
matches!(&deleg.qself, Some(qself) if qself.position == 0);
|
||||
let item = match node.to_annotatable() {
|
||||
Annotatable::ImplItem(item) => item,
|
||||
ann @ (Annotatable::Item(_)
|
||||
|
|
@ -2000,6 +2003,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if traitless_qself {
|
||||
let span = item.span;
|
||||
self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
|
||||
return Default::default();
|
||||
}
|
||||
return self.collect_glob_delegation(item, Node::KIND).make_ast::<Node>();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ use crate::mbe::transcribe::transcribe;
|
|||
|
||||
use ast::token::IdentIsRaw;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, NonterminalKind, NtPatKind::*, Token, TokenKind, TokenKind::*,
|
||||
};
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
||||
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
||||
use rustc_ast_pretty::pprust;
|
||||
|
|
@ -1145,14 +1147,17 @@ fn check_matcher_core<'tt>(
|
|||
// Macros defined in the current crate have a real node id,
|
||||
// whereas macros from an external crate have a dummy id.
|
||||
if def.id != DUMMY_NODE_ID
|
||||
&& matches!(kind, NonterminalKind::PatParam { inferred: true })
|
||||
&& matches!(next_token, TokenTree::Token(token) if token.kind == BinOp(token::BinOpToken::Or))
|
||||
&& matches!(kind, NonterminalKind::Pat(PatParam { inferred: true }))
|
||||
&& matches!(
|
||||
next_token,
|
||||
TokenTree::Token(token) if token.kind == BinOp(token::BinOpToken::Or)
|
||||
)
|
||||
{
|
||||
// It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param.
|
||||
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
|
||||
span,
|
||||
name,
|
||||
Some(NonterminalKind::PatParam { inferred: false }),
|
||||
Some(NonterminalKind::Pat(PatParam { inferred: false })),
|
||||
));
|
||||
sess.psess.buffer_lint(
|
||||
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
|
||||
|
|
@ -1185,14 +1190,14 @@ fn check_matcher_core<'tt>(
|
|||
);
|
||||
err.span_label(sp, format!("not allowed after `{kind}` fragments"));
|
||||
|
||||
if kind == NonterminalKind::PatWithOr
|
||||
if kind == NonterminalKind::Pat(PatWithOr)
|
||||
&& sess.psess.edition.at_least_rust_2021()
|
||||
&& next_token.is_token(&BinOp(token::BinOpToken::Or))
|
||||
{
|
||||
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
|
||||
span,
|
||||
name,
|
||||
Some(NonterminalKind::PatParam { inferred: false }),
|
||||
Some(NonterminalKind::Pat(PatParam { inferred: false })),
|
||||
));
|
||||
err.span_suggestion(
|
||||
span,
|
||||
|
|
@ -1292,9 +1297,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
// maintain
|
||||
IsInFollow::Yes
|
||||
}
|
||||
NonterminalKind::Stmt
|
||||
| NonterminalKind::Expr
|
||||
| NonterminalKind::Expr2021 { inferred: _ } => {
|
||||
NonterminalKind::Stmt | NonterminalKind::Expr(_) => {
|
||||
const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
|
||||
match tok {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
|
|
@ -1304,7 +1307,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
}
|
||||
NonterminalKind::PatParam { .. } => {
|
||||
NonterminalKind::Pat(PatParam { .. }) => {
|
||||
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
|
||||
match tok {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
|
|
@ -1317,7 +1320,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
}
|
||||
NonterminalKind::PatWithOr => {
|
||||
NonterminalKind::Pat(PatWithOr) => {
|
||||
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`in`"];
|
||||
match tok {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::errors;
|
|||
use crate::mbe::macro_parser::count_metavar_decls;
|
||||
use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};
|
||||
|
||||
use rustc_ast::token::{self, Delimiter, IdentIsRaw, Token};
|
||||
use rustc_ast::token::{self, Delimiter, IdentIsRaw, NonterminalKind, NtExprKind::*, Token};
|
||||
use rustc_ast::{tokenstream, NodeId};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_feature::Features;
|
||||
|
|
@ -85,36 +85,31 @@ pub(super) fn parse(
|
|||
span.edition()
|
||||
}
|
||||
};
|
||||
let kind =
|
||||
token::NonterminalKind::from_symbol(fragment.name, edition)
|
||||
.unwrap_or_else(|| {
|
||||
let help = match fragment.name {
|
||||
sym::expr_2021 => {
|
||||
format!(
|
||||
"fragment specifier `expr_2021` \
|
||||
requires Rust 2021 or later\n\
|
||||
{VALID_FRAGMENT_NAMES_MSG}"
|
||||
)
|
||||
}
|
||||
_ if edition().at_least_rust_2021()
|
||||
&& features
|
||||
.expr_fragment_specifier_2024 =>
|
||||
{
|
||||
VALID_FRAGMENT_NAMES_MSG_2021.into()
|
||||
}
|
||||
_ => VALID_FRAGMENT_NAMES_MSG.into(),
|
||||
};
|
||||
sess.dcx().emit_err(
|
||||
errors::InvalidFragmentSpecifier {
|
||||
span,
|
||||
fragment,
|
||||
help,
|
||||
},
|
||||
);
|
||||
token::NonterminalKind::Ident
|
||||
let kind = NonterminalKind::from_symbol(fragment.name, edition)
|
||||
.unwrap_or_else(|| {
|
||||
let help = match fragment.name {
|
||||
sym::expr_2021 => {
|
||||
format!(
|
||||
"fragment specifier `expr_2021` \
|
||||
requires Rust 2021 or later\n\
|
||||
{VALID_FRAGMENT_NAMES_MSG}"
|
||||
)
|
||||
}
|
||||
_ if edition().at_least_rust_2021()
|
||||
&& features.expr_fragment_specifier_2024 =>
|
||||
{
|
||||
VALID_FRAGMENT_NAMES_MSG_2021.into()
|
||||
}
|
||||
_ => VALID_FRAGMENT_NAMES_MSG.into(),
|
||||
};
|
||||
sess.dcx().emit_err(errors::InvalidFragmentSpecifier {
|
||||
span,
|
||||
fragment,
|
||||
help,
|
||||
});
|
||||
if kind
|
||||
== (token::NonterminalKind::Expr2021 { inferred: false })
|
||||
NonterminalKind::Ident
|
||||
});
|
||||
if kind == NonterminalKind::Expr(Expr2021 { inferred: false })
|
||||
&& !features.expr_fragment_specifier_2024
|
||||
{
|
||||
rustc_session::parse::feature_err(
|
||||
|
|
|
|||
|
|
@ -1145,10 +1145,6 @@ pub fn is_valid_for_get_attr(name: Symbol) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn is_unsafe_attr(name: Symbol) -> bool {
|
||||
BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| attr.safety == AttributeSafety::Unsafe)
|
||||
}
|
||||
|
||||
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
|
||||
LazyLock::new(|| {
|
||||
let mut map = FxHashMap::default();
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ pub use accepted::ACCEPTED_FEATURES;
|
|||
pub use builtin_attrs::AttributeDuplicates;
|
||||
pub use builtin_attrs::{
|
||||
deprecated_attributes, encode_cross_crate, find_gated_cfg, is_builtin_attr_name,
|
||||
is_unsafe_attr, is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType,
|
||||
is_valid_for_get_attr, AttributeGate, AttributeSafety, AttributeTemplate, AttributeType,
|
||||
BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
||||
};
|
||||
pub use removed::REMOVED_FEATURES;
|
||||
|
|
|
|||
|
|
@ -629,7 +629,7 @@ declare_features! (
|
|||
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
|
||||
(unstable, unsafe_extern_blocks, "1.80.0", Some(123743)),
|
||||
/// Allows unsized fn parameters.
|
||||
(unstable, unsized_fn_params, "1.49.0", Some(48055)),
|
||||
(internal, unsized_fn_params, "1.49.0", Some(48055)),
|
||||
/// Allows unsized rvalues at arguments and parameters.
|
||||
(incomplete, unsized_locals, "1.30.0", Some(48055)),
|
||||
/// Allows unsized tuple coercion.
|
||||
|
|
|
|||
|
|
@ -26,10 +26,8 @@ use rustc_middle::lint::in_external_macro;
|
|||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{
|
||||
self, suggest_constraining_type_params, Article, Binder, IsSuggestable, Ty, TypeVisitableExt,
|
||||
Upcast,
|
||||
};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Article, Binder};
|
||||
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
|
|
@ -1111,12 +1109,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
|
||||
)
|
||||
{
|
||||
err.multipart_suggestion(
|
||||
// When the expr is in a match arm's body, we shouldn't add semicolon ';' at the end.
|
||||
// For example:
|
||||
// fn mismatch_types() -> i32 {
|
||||
// match 1 {
|
||||
// x => dbg!(x),
|
||||
// }
|
||||
// todo!()
|
||||
// }
|
||||
// -------------^^^^^^^-
|
||||
// Don't add semicolon `;` at the end of `dbg!(x)` expr
|
||||
fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
|
||||
for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
|
||||
match node {
|
||||
hir::Node::Block(block) => {
|
||||
if let Some(ret) = block.expr
|
||||
&& ret.hir_id == expr.hir_id
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
hir::Node::Arm(arm) => {
|
||||
if let hir::ExprKind::Block(block, _) = arm.body.kind
|
||||
&& let Some(ret) = block.expr
|
||||
&& ret.hir_id == expr.hir_id
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
hir::Node::Expr(e) if let hir::ExprKind::Block(block, _) = e.kind => {
|
||||
if let Some(ret) = block.expr
|
||||
&& ret.hir_id == expr.hir_id
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
let mut suggs = vec![(span.shrink_to_lo(), "return ".to_string())];
|
||||
if !is_in_arm(expr, self.tcx) {
|
||||
suggs.push((span.shrink_to_hi(), ";".to_string()));
|
||||
}
|
||||
err.multipart_suggestion_verbose(
|
||||
"you might have meant to return this value",
|
||||
vec![
|
||||
(span.shrink_to_lo(), "return ".to_string()),
|
||||
(span.shrink_to_hi(), ";".to_string()),
|
||||
],
|
||||
suggs,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
|
|||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{FileName, SourceFileHashAlgorithm};
|
||||
use rustc_target::spec::{
|
||||
CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
|
||||
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
|
||||
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, WasmCAbi,
|
||||
};
|
||||
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::num::NonZero;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
@ -605,7 +605,7 @@ fn test_codegen_options_tracking_hash() {
|
|||
tracked!(debug_assertions, Some(true));
|
||||
tracked!(debuginfo, DebugInfo::Limited);
|
||||
tracked!(embed_bitcode, false);
|
||||
tracked!(force_frame_pointers, Some(false));
|
||||
tracked!(force_frame_pointers, FramePointer::Always);
|
||||
tracked!(force_unwind_tables, Some(true));
|
||||
tracked!(inline_threshold, Some(0xf007ba11));
|
||||
tracked!(instrument_coverage, InstrumentCoverage::Yes);
|
||||
|
|
|
|||
|
|
@ -825,6 +825,10 @@ lint_unnameable_test_items = cannot test inner items
|
|||
lint_unnecessary_qualification = unnecessary qualification
|
||||
.suggestion = remove the unnecessary path segments
|
||||
|
||||
lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
|
||||
.label = usage of unsafe attribute
|
||||
lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
|
||||
|
||||
lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´
|
||||
|
||||
lint_untranslatable_diag = diagnostics should be created using translatable messages
|
||||
|
|
|
|||
|
|
@ -319,6 +319,16 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
|
|||
BuiltinLintDiag::UnusedQualifications { removal_span } => {
|
||||
lints::UnusedQualifications { removal_span }.decorate_lint(diag);
|
||||
}
|
||||
BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span,
|
||||
sugg_spans: (left, right),
|
||||
} => {
|
||||
lints::UnsafeAttrOutsideUnsafe {
|
||||
span: attribute_name_span,
|
||||
suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },
|
||||
}
|
||||
.decorate_lint(diag);
|
||||
}
|
||||
BuiltinLintDiag::AssociatedConstElidedLifetime {
|
||||
elided,
|
||||
span: lt_span,
|
||||
|
|
|
|||
|
|
@ -2890,3 +2890,24 @@ pub struct RedundantImportVisibility {
|
|||
pub import_vis: String,
|
||||
pub max_vis: String,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_unsafe_attr_outside_unsafe)]
|
||||
pub struct UnsafeAttrOutsideUnsafe {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
lint_unsafe_attr_outside_unsafe_suggestion,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub struct UnsafeAttrOutsideUnsafeSuggestion {
|
||||
#[suggestion_part(code = "unsafe(")]
|
||||
pub left: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub right: Span,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ declare_lint_pass! {
|
|||
UNNAMEABLE_TYPES,
|
||||
UNREACHABLE_CODE,
|
||||
UNREACHABLE_PATTERNS,
|
||||
UNSAFE_ATTR_OUTSIDE_UNSAFE,
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
UNSTABLE_NAME_COLLISIONS,
|
||||
UNSTABLE_SYNTAX_PRE_EXPANSION,
|
||||
|
|
@ -4902,3 +4903,45 @@ declare_lint! {
|
|||
reference: "issue #123743 <https://github.com/rust-lang/rust/issues/123743>",
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `unsafe_attr_outside_unsafe` lint detects a missing unsafe keyword
|
||||
/// on attributes considered unsafe.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(unsafe_attributes)]
|
||||
/// #![warn(unsafe_attr_outside_unsafe)]
|
||||
///
|
||||
/// #[no_mangle]
|
||||
/// extern "C" fn foo() {}
|
||||
///
|
||||
/// fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Some attributes (e.g. `no_mangle`, `export_name`, `link_section` -- see
|
||||
/// [issue #82499] for a more complete list) are considered "unsafe" attributes.
|
||||
/// An unsafe attribute must only be used inside unsafe(...).
|
||||
///
|
||||
/// This lint can automatically wrap the attributes in `unsafe(...)` , but this
|
||||
/// obviously cannot verify that the preconditions of the `unsafe`
|
||||
/// attributes are fulfilled, so that is still up to the user.
|
||||
///
|
||||
/// The lint is currently "allow" by default, but that might change in the
|
||||
/// future.
|
||||
///
|
||||
/// [editions]: https://doc.rust-lang.org/edition-guide/
|
||||
/// [issue #82499]: https://github.com/rust-lang/rust/issues/82499
|
||||
pub UNSAFE_ATTR_OUTSIDE_UNSAFE,
|
||||
Allow,
|
||||
"detects unsafe attributes outside of unsafe",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
|
||||
reference: "issue #123757 <https://github.com/rust-lang/rust/issues/123757>",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -691,6 +691,10 @@ pub enum BuiltinLintDiag {
|
|||
/// The span of the unnecessarily-qualified path to remove.
|
||||
removal_span: Span,
|
||||
},
|
||||
UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: Span,
|
||||
sugg_spans: (Span, Span),
|
||||
},
|
||||
AssociatedConstElidedLifetime {
|
||||
elided: bool,
|
||||
span: Span,
|
||||
|
|
|
|||
|
|
@ -520,6 +520,8 @@ pub enum UnsupportedOpInfo {
|
|||
Unsupported(String),
|
||||
/// Unsized local variables.
|
||||
UnsizedLocal,
|
||||
/// Extern type field with an indeterminate offset.
|
||||
ExternTypeField,
|
||||
//
|
||||
// The variants below are only reachable from CTFE/const prop, miri will never emit them.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1047,6 +1047,12 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
|||
let b = other.eval_bits(ty, tcx, param_env);
|
||||
|
||||
match ty.kind() {
|
||||
ty::Float(ty::FloatTy::F16) => {
|
||||
use rustc_apfloat::Float;
|
||||
let a = rustc_apfloat::ieee::Half::from_bits(a);
|
||||
let b = rustc_apfloat::ieee::Half::from_bits(b);
|
||||
a.partial_cmp(&b)
|
||||
}
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
use rustc_apfloat::Float;
|
||||
let a = rustc_apfloat::ieee::Single::from_bits(a);
|
||||
|
|
@ -1059,6 +1065,12 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
|||
let b = rustc_apfloat::ieee::Double::from_bits(b);
|
||||
a.partial_cmp(&b)
|
||||
}
|
||||
ty::Float(ty::FloatTy::F128) => {
|
||||
use rustc_apfloat::Float;
|
||||
let a = rustc_apfloat::ieee::Quad::from_bits(a);
|
||||
let b = rustc_apfloat::ieee::Quad::from_bits(b);
|
||||
a.partial_cmp(&b)
|
||||
}
|
||||
ty::Int(ity) => {
|
||||
let size = rustc_target::abi::Integer::from_int_ty(&tcx, *ity).size();
|
||||
let a = size.sign_extend(a) as i128;
|
||||
|
|
|
|||
|
|
@ -1196,7 +1196,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
/// Returns the minimum and maximum values for the given numeric type (including `char`s) or
|
||||
/// returns `None` if the type is not numeric.
|
||||
pub fn numeric_min_and_max_as_bits(self, tcx: TyCtxt<'tcx>) -> Option<(u128, u128)> {
|
||||
use rustc_apfloat::ieee::{Double, Single};
|
||||
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
|
||||
Some(match self.kind() {
|
||||
ty::Int(_) | ty::Uint(_) => {
|
||||
let (size, signed) = self.int_size_and_signed(tcx);
|
||||
|
|
@ -1206,12 +1206,14 @@ impl<'tcx> Ty<'tcx> {
|
|||
(min, max)
|
||||
}
|
||||
ty::Char => (0, std::char::MAX as u128),
|
||||
ty::Float(ty::FloatTy::F16) => ((-Half::INFINITY).to_bits(), Half::INFINITY.to_bits()),
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
((-Single::INFINITY).to_bits(), Single::INFINITY.to_bits())
|
||||
}
|
||||
ty::Float(ty::FloatTy::F64) => {
|
||||
((-Double::INFINITY).to_bits(), Double::INFINITY.to_bits())
|
||||
}
|
||||
ty::Float(ty::FloatTy::F128) => ((-Quad::INFINITY).to_bits(), Quad::INFINITY.to_bits()),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,10 +369,10 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||
ty::Float(flt) => {
|
||||
let v = cv.unwrap_leaf();
|
||||
let is_nan = match flt {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F16 => v.to_f16().is_nan(),
|
||||
ty::FloatTy::F32 => v.to_f32().is_nan(),
|
||||
ty::FloatTy::F64 => v.to_f64().is_nan(),
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F128 => v.to_f128().is_nan(),
|
||||
};
|
||||
if is_nan {
|
||||
// NaNs are not ever equal to anything so they make no sense as patterns.
|
||||
|
|
|
|||
|
|
@ -366,6 +366,10 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment
|
|||
.label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item}
|
||||
.sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style
|
||||
|
||||
parse_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
|
||||
.suggestion = remove the `unsafe(...)`
|
||||
.note = extraneous unsafe is not allowed in attributes
|
||||
|
||||
parse_invalid_block_macro_segment = cannot use a `block` macro fragment here
|
||||
.label = the `block` fragment is within this context
|
||||
.suggestion = wrap this in another block
|
||||
|
|
@ -866,6 +870,11 @@ parse_unmatched_angle_brackets = {$num_extra_brackets ->
|
|||
*[other] remove extra angle brackets
|
||||
}
|
||||
|
||||
parse_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
|
||||
.label = usage of unsafe attribute
|
||||
parse_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
|
||||
|
||||
|
||||
parse_unskipped_whitespace = whitespace symbol '{$ch}' is not skipped
|
||||
.label = {parse_unskipped_whitespace}
|
||||
|
||||
|
|
|
|||
|
|
@ -2997,3 +2997,34 @@ pub(crate) struct DotDotRangeAttribute {
|
|||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_invalid_attr_unsafe)]
|
||||
#[note]
|
||||
pub struct InvalidAttrUnsafe {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Path,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_unsafe_attr_outside_unsafe)]
|
||||
pub struct UnsafeAttrOutsideUnsafe {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
parse_unsafe_attr_outside_unsafe_suggestion,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub struct UnsafeAttrOutsideUnsafeSuggestion {
|
||||
#[suggestion_part(code = "unsafe(")]
|
||||
pub left: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub right: Span,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Nonterminal::*, NonterminalKind, Token};
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, Nonterminal::*, NonterminalKind, NtExprKind::*, NtPatKind::*, Token,
|
||||
};
|
||||
use rustc_ast::HasTokens;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
|
@ -36,14 +38,14 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
match kind {
|
||||
NonterminalKind::Expr2021 { inferred: _ } => {
|
||||
NonterminalKind::Expr(Expr2021 { .. }) => {
|
||||
token.can_begin_expr()
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Let)
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Const)
|
||||
}
|
||||
NonterminalKind::Expr => {
|
||||
NonterminalKind::Expr(Expr) => {
|
||||
token.can_begin_expr()
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Let)
|
||||
|
|
@ -74,7 +76,7 @@ impl<'a> Parser<'a> {
|
|||
token::Interpolated(nt) => may_be_ident(nt),
|
||||
_ => false,
|
||||
},
|
||||
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => match &token.kind {
|
||||
NonterminalKind::Pat(pat_kind) => match &token.kind {
|
||||
// box, ref, mut, and other identifiers (can stricten)
|
||||
token::Ident(..) | token::NtIdent(..) |
|
||||
token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern
|
||||
|
|
@ -89,7 +91,7 @@ impl<'a> Parser<'a> {
|
|||
token::Lt | // path (UFCS constant)
|
||||
token::BinOp(token::Shl) => true, // path (double UFCS)
|
||||
// leading vert `|` or-pattern
|
||||
token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr),
|
||||
token::BinOp(token::Or) => matches!(pat_kind, PatWithOr),
|
||||
token::Interpolated(nt) => may_be_ident(nt),
|
||||
_ => false,
|
||||
},
|
||||
|
|
@ -135,31 +137,25 @@ impl<'a> Parser<'a> {
|
|||
.create_err(UnexpectedNonterminal::Statement(self.token.span)));
|
||||
}
|
||||
},
|
||||
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => {
|
||||
NtPat(self.collect_tokens_no_attrs(|this| match kind {
|
||||
NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None, None),
|
||||
NonterminalKind::PatWithOr => this.parse_pat_allow_top_alt(
|
||||
NonterminalKind::Pat(pat_kind) => {
|
||||
NtPat(self.collect_tokens_no_attrs(|this| match pat_kind {
|
||||
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
|
||||
PatWithOr => this.parse_pat_allow_top_alt(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
})?)
|
||||
}
|
||||
|
||||
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: _ } => {
|
||||
NtExpr(self.parse_expr_force_collect()?)
|
||||
}
|
||||
NonterminalKind::Expr(_) => NtExpr(self.parse_expr_force_collect()?),
|
||||
NonterminalKind::Literal => {
|
||||
// The `:literal` matcher does not support attributes
|
||||
NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?)
|
||||
}
|
||||
|
||||
NonterminalKind::Ty => {
|
||||
NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?)
|
||||
}
|
||||
|
||||
// this could be handled like a token, since it is one
|
||||
NonterminalKind::Ident => {
|
||||
return if let Some((ident, is_raw)) = get_macro_ident(&self.token) {
|
||||
|
|
|
|||
|
|
@ -5,21 +5,73 @@ use crate::{errors, parse_in};
|
|||
use rustc_ast::token::Delimiter;
|
||||
use rustc_ast::tokenstream::DelimSpan;
|
||||
use rustc_ast::MetaItemKind;
|
||||
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem};
|
||||
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety};
|
||||
use rustc_errors::{Applicability, FatalError, PResult};
|
||||
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_feature::{
|
||||
AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
|
||||
};
|
||||
use rustc_session::errors::report_lit_error;
|
||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE};
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_span::{sym, BytePos, Span, Symbol};
|
||||
|
||||
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
|
||||
pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
|
||||
if attr.is_doc_comment() {
|
||||
return;
|
||||
}
|
||||
|
||||
let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
|
||||
let attr_item = attr.get_normal_item();
|
||||
|
||||
let is_unsafe_attr = attr_info.is_some_and(|attr| attr.safety == AttributeSafety::Unsafe);
|
||||
|
||||
if features.unsafe_attributes {
|
||||
if is_unsafe_attr {
|
||||
if let ast::Safety::Default = attr_item.unsafety {
|
||||
let path_span = attr_item.path.span;
|
||||
|
||||
// If the `attr_item`'s span is not from a macro, then just suggest
|
||||
// wrapping it in `unsafe(...)`. Otherwise, we suggest putting the
|
||||
// `unsafe(`, `)` right after and right before the opening and closing
|
||||
// square bracket respectively.
|
||||
let diag_span = if attr_item.span().can_be_used_for_suggestions() {
|
||||
attr_item.span()
|
||||
} else {
|
||||
attr.span
|
||||
.with_lo(attr.span.lo() + BytePos(2))
|
||||
.with_hi(attr.span.hi() - BytePos(1))
|
||||
};
|
||||
|
||||
if attr.span.at_least_rust_2024() {
|
||||
psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe {
|
||||
span: path_span,
|
||||
suggestion: errors::UnsafeAttrOutsideUnsafeSuggestion {
|
||||
left: diag_span.shrink_to_lo(),
|
||||
right: diag_span.shrink_to_hi(),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
psess.buffer_lint(
|
||||
UNSAFE_ATTR_OUTSIDE_UNSAFE,
|
||||
path_span,
|
||||
ast::CRATE_NODE_ID,
|
||||
BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: path_span,
|
||||
sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
|
||||
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
|
||||
span: unsafe_span,
|
||||
name: attr_item.path.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check input tokens for built-in and key-value attributes.
|
||||
match attr_info {
|
||||
|
|
@ -32,7 +84,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ if let AttrArgs::Eq(..) = attr.get_normal_item().args => {
|
||||
_ if let AttrArgs::Eq(..) = attr_item.args => {
|
||||
// All key-value attributes are restricted to meta-item syntax.
|
||||
match parse_meta(psess, attr) {
|
||||
Ok(_) => {}
|
||||
|
|
|
|||
|
|
@ -384,10 +384,6 @@ passes_invalid_attr_at_crate_level =
|
|||
passes_invalid_attr_at_crate_level_item =
|
||||
the inner attribute doesn't annotate this {$kind}
|
||||
|
||||
passes_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
|
||||
.suggestion = remove the `unsafe(...)`
|
||||
.note = extraneous unsafe is not allowed in attributes
|
||||
|
||||
passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
|
||||
|
||||
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem};
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Applicability, IntoDiagArg, MultiSpan};
|
||||
use rustc_errors::{DiagCtxtHandle, StashKey};
|
||||
use rustc_feature::{
|
||||
is_unsafe_attr, AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP,
|
||||
};
|
||||
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_hir::def_id::LocalModDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{self as hir};
|
||||
|
|
@ -116,8 +114,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
let mut seen = FxHashMap::default();
|
||||
let attrs = self.tcx.hir().attrs(hir_id);
|
||||
for attr in attrs {
|
||||
self.check_unsafe_attr(attr);
|
||||
|
||||
match attr.path().as_slice() {
|
||||
[sym::diagnostic, sym::do_not_recommend] => {
|
||||
self.check_do_not_recommend(attr.span, hir_id, target)
|
||||
|
|
@ -312,21 +308,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
true
|
||||
}
|
||||
|
||||
/// Checks if `unsafe()` is applied to an invalid attribute.
|
||||
fn check_unsafe_attr(&self, attr: &Attribute) {
|
||||
if !attr.is_doc_comment() {
|
||||
let attr_item = attr.get_normal_item();
|
||||
if let ast::Safety::Unsafe(unsafe_span) = attr_item.unsafety {
|
||||
if !is_unsafe_attr(attr.name_or_empty()) {
|
||||
self.dcx().emit_err(errors::InvalidAttrUnsafe {
|
||||
span: unsafe_span,
|
||||
name: attr_item.path.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition
|
||||
fn check_diagnostic_on_unimplemented(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
};
|
||||
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_ast::{ast, Label};
|
||||
use rustc_ast::Label;
|
||||
use rustc_errors::{
|
||||
codes::*, Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee,
|
||||
Level, MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
||||
|
|
@ -863,15 +863,6 @@ pub struct InvalidAttrAtCrateLevel {
|
|||
pub item: Option<ItemFollowingInnerAttr>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_invalid_attr_unsafe)]
|
||||
#[note]
|
||||
pub struct InvalidAttrUnsafe {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: ast::Path,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ItemFollowingInnerAttr {
|
||||
pub span: Span,
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ use std::iter::once;
|
|||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS};
|
||||
use rustc_apfloat::ieee::{DoubleS, HalfS, IeeeFloat, QuadS, SingleS};
|
||||
use rustc_index::bit_set::{BitSet, GrowableBitSet};
|
||||
use rustc_index::IndexVec;
|
||||
|
||||
|
|
@ -692,8 +692,10 @@ pub enum Constructor<Cx: PatCx> {
|
|||
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
|
||||
IntRange(IntRange),
|
||||
/// Ranges of floating-point literal values (`2.0..=5.2`).
|
||||
F16Range(IeeeFloat<HalfS>, IeeeFloat<HalfS>, RangeEnd),
|
||||
F32Range(IeeeFloat<SingleS>, IeeeFloat<SingleS>, RangeEnd),
|
||||
F64Range(IeeeFloat<DoubleS>, IeeeFloat<DoubleS>, RangeEnd),
|
||||
F128Range(IeeeFloat<QuadS>, IeeeFloat<QuadS>, RangeEnd),
|
||||
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
|
||||
Str(Cx::StrLit),
|
||||
/// Constants that must not be matched structurally. They are treated as black boxes for the
|
||||
|
|
@ -735,8 +737,10 @@ impl<Cx: PatCx> Clone for Constructor<Cx> {
|
|||
Constructor::UnionField => Constructor::UnionField,
|
||||
Constructor::Bool(b) => Constructor::Bool(*b),
|
||||
Constructor::IntRange(range) => Constructor::IntRange(*range),
|
||||
Constructor::F16Range(lo, hi, end) => Constructor::F16Range(lo.clone(), *hi, *end),
|
||||
Constructor::F32Range(lo, hi, end) => Constructor::F32Range(lo.clone(), *hi, *end),
|
||||
Constructor::F64Range(lo, hi, end) => Constructor::F64Range(lo.clone(), *hi, *end),
|
||||
Constructor::F128Range(lo, hi, end) => Constructor::F128Range(lo.clone(), *hi, *end),
|
||||
Constructor::Str(value) => Constructor::Str(value.clone()),
|
||||
Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
|
||||
Constructor::Or => Constructor::Or,
|
||||
|
|
@ -812,6 +816,14 @@ impl<Cx: PatCx> Constructor<Cx> {
|
|||
(Bool(self_b), Bool(other_b)) => self_b == other_b,
|
||||
|
||||
(IntRange(self_range), IntRange(other_range)) => self_range.is_subrange(other_range),
|
||||
(F16Range(self_from, self_to, self_end), F16Range(other_from, other_to, other_end)) => {
|
||||
self_from.ge(other_from)
|
||||
&& match self_to.partial_cmp(other_to) {
|
||||
Some(Ordering::Less) => true,
|
||||
Some(Ordering::Equal) => other_end == self_end,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(F32Range(self_from, self_to, self_end), F32Range(other_from, other_to, other_end)) => {
|
||||
self_from.ge(other_from)
|
||||
&& match self_to.partial_cmp(other_to) {
|
||||
|
|
@ -828,6 +840,17 @@ impl<Cx: PatCx> Constructor<Cx> {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
(
|
||||
F128Range(self_from, self_to, self_end),
|
||||
F128Range(other_from, other_to, other_end),
|
||||
) => {
|
||||
self_from.ge(other_from)
|
||||
&& match self_to.partial_cmp(other_to) {
|
||||
Some(Ordering::Less) => true,
|
||||
Some(Ordering::Equal) => other_end == self_end,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(Str(self_val), Str(other_val)) => {
|
||||
// FIXME Once valtrees are available we can directly use the bytes
|
||||
// in the `Str` variant of the valtree for the comparison here.
|
||||
|
|
@ -906,8 +929,10 @@ impl<Cx: PatCx> Constructor<Cx> {
|
|||
Bool(b) => write!(f, "{b}")?,
|
||||
// Best-effort, will render signed ranges incorrectly
|
||||
IntRange(range) => write!(f, "{range:?}")?,
|
||||
F16Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
|
||||
F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
|
||||
F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
|
||||
F128Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
|
||||
Str(value) => write!(f, "{value:?}")?,
|
||||
Opaque(..) => write!(f, "<constant pattern>")?,
|
||||
Or => {
|
||||
|
|
|
|||
|
|
@ -247,8 +247,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
}
|
||||
_ => bug!("bad slice pattern {:?} {:?}", ctor, ty),
|
||||
},
|
||||
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
|
||||
| Never | NonExhaustive | Hidden | Missing | PrivateUninhabited | Wildcard => &[],
|
||||
Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
|
||||
| F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
|
||||
| PrivateUninhabited | Wildcard => &[],
|
||||
Or => {
|
||||
bug!("called `Fields::wildcards` on an `Or` ctor")
|
||||
}
|
||||
|
|
@ -275,8 +276,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
},
|
||||
Ref => 1,
|
||||
Slice(slice) => slice.arity(),
|
||||
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
|
||||
| Never | NonExhaustive | Hidden | Missing | PrivateUninhabited | Wildcard => 0,
|
||||
Bool(..) | IntRange(..) | F16Range(..) | F32Range(..) | F64Range(..)
|
||||
| F128Range(..) | Str(..) | Opaque(..) | Never | NonExhaustive | Hidden | Missing
|
||||
| PrivateUninhabited | Wildcard => 0,
|
||||
Or => bug!("The `Or` constructor doesn't have a fixed arity"),
|
||||
}
|
||||
}
|
||||
|
|
@ -546,6 +548,18 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F16) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
Some(bits) => {
|
||||
use rustc_apfloat::Float;
|
||||
let value = rustc_apfloat::ieee::Half::from_bits(bits);
|
||||
F16Range(value, value, RangeEnd::Included)
|
||||
}
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
Some(bits) => {
|
||||
|
|
@ -570,6 +584,18 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F128) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
Some(bits) => {
|
||||
use rustc_apfloat::Float;
|
||||
let value = rustc_apfloat::ieee::Quad::from_bits(bits);
|
||||
F128Range(value, value, RangeEnd::Included)
|
||||
}
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Ref(_, t, _) if t.is_str() => {
|
||||
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
|
||||
// with other `Deref` patterns. This could have been done in `const_to_pat`,
|
||||
|
|
@ -611,7 +637,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env));
|
||||
let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.param_env));
|
||||
match fty {
|
||||
ty::FloatTy::F16 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F16 => {
|
||||
use rustc_apfloat::ieee::Half;
|
||||
let lo = lo.map(Half::from_bits).unwrap_or(-Half::INFINITY);
|
||||
let hi = hi.map(Half::from_bits).unwrap_or(Half::INFINITY);
|
||||
F16Range(lo, hi, end)
|
||||
}
|
||||
ty::FloatTy::F32 => {
|
||||
use rustc_apfloat::ieee::Single;
|
||||
let lo = lo.map(Single::from_bits).unwrap_or(-Single::INFINITY);
|
||||
|
|
@ -624,7 +655,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
let hi = hi.map(Double::from_bits).unwrap_or(Double::INFINITY);
|
||||
F64Range(lo, hi, end)
|
||||
}
|
||||
ty::FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
ty::FloatTy::F128 => {
|
||||
use rustc_apfloat::ieee::Quad;
|
||||
let lo = lo.map(Quad::from_bits).unwrap_or(-Quad::INFINITY);
|
||||
let hi = hi.map(Quad::from_bits).unwrap_or(Quad::INFINITY);
|
||||
F128Range(lo, hi, end)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => bug!("invalid type for range pattern: {}", ty.inner()),
|
||||
|
|
@ -837,7 +873,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
"trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
|
||||
`Missing` should have been processed in `apply_constructors`"
|
||||
),
|
||||
F32Range(..) | F64Range(..) | Opaque(..) | Or => {
|
||||
F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Opaque(..) | Or => {
|
||||
bug!("can't convert to pattern: {:?}", pat)
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
|||
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
|
||||
use rustc_span::source_map::FilePathMapping;
|
||||
use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
|
||||
use rustc_target::spec::{LinkSelfContainedComponents, LinkerFeatures};
|
||||
use rustc_target::spec::{FramePointer, LinkSelfContainedComponents, LinkerFeatures};
|
||||
use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple};
|
||||
use std::collections::btree_map::{
|
||||
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
|
||||
|
|
@ -2524,6 +2524,15 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
|||
}
|
||||
}
|
||||
|
||||
if !nightly_options::is_unstable_enabled(matches)
|
||||
&& cg.force_frame_pointers == FramePointer::NonLeaf
|
||||
{
|
||||
early_dcx.early_fatal(
|
||||
"`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
|
||||
and a nightly compiler",
|
||||
)
|
||||
}
|
||||
|
||||
// For testing purposes, until we have more feedback about these options: ensure `-Z
|
||||
// unstable-options` is required when using the unstable `-C link-self-contained` and `-C
|
||||
// linker-flavor` options.
|
||||
|
|
@ -2966,10 +2975,8 @@ pub(crate) mod dep_tracking {
|
|||
use rustc_span::edition::Edition;
|
||||
use rustc_span::RealFileName;
|
||||
use rustc_target::spec::{
|
||||
CodeModel, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
|
||||
};
|
||||
use rustc_target::spec::{
|
||||
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
||||
CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
|
||||
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, WasmCAbi,
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
use std::hash::{DefaultHasher, Hash};
|
||||
|
|
@ -3023,6 +3030,7 @@ pub(crate) mod dep_tracking {
|
|||
lint::Level,
|
||||
WasiExecModel,
|
||||
u32,
|
||||
FramePointer,
|
||||
RelocModel,
|
||||
CodeModel,
|
||||
TlsModel,
|
||||
|
|
|
|||
|
|
@ -12,10 +12,9 @@ use rustc_span::edition::Edition;
|
|||
use rustc_span::RealFileName;
|
||||
use rustc_span::SourceFileHashAlgorithm;
|
||||
use rustc_target::spec::{
|
||||
CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, SanitizerSet, WasmCAbi,
|
||||
};
|
||||
use rustc_target::spec::{
|
||||
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
||||
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
|
||||
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
|
||||
WasmCAbi,
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
use std::hash::{DefaultHasher, Hasher};
|
||||
|
|
@ -374,6 +373,7 @@ mod desc {
|
|||
pub const parse_opt_comma_list: &str = parse_comma_list;
|
||||
pub const parse_number: &str = "a number";
|
||||
pub const parse_opt_number: &str = parse_number;
|
||||
pub const parse_frame_pointer: &str = "one of `true`/`yes`/`on`, `false`/`no`/`off`, or (with -Zunstable-options) `non-leaf` or `always`";
|
||||
pub const parse_threads: &str = parse_number;
|
||||
pub const parse_time_passes_format: &str = "`text` (default) or `json`";
|
||||
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
|
||||
|
|
@ -672,6 +672,18 @@ mod parse {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_frame_pointer(slot: &mut FramePointer, v: Option<&str>) -> bool {
|
||||
let mut yes = false;
|
||||
match v {
|
||||
_ if parse_bool(&mut yes, v) && yes => slot.ratchet(FramePointer::Always),
|
||||
_ if parse_bool(&mut yes, v) => slot.ratchet(FramePointer::MayOmit),
|
||||
Some("always") => slot.ratchet(FramePointer::Always),
|
||||
Some("non-leaf") => slot.ratchet(FramePointer::NonLeaf),
|
||||
_ => return false,
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some("all") => {
|
||||
|
|
@ -1479,7 +1491,7 @@ options! {
|
|||
"emit bitcode in rlibs (default: yes)"),
|
||||
extra_filename: String = (String::new(), parse_string, [UNTRACKED],
|
||||
"extra data to put in each output filename"),
|
||||
force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
force_frame_pointers: FramePointer = (FramePointer::MayOmit, parse_frame_pointer, [TRACKED],
|
||||
"force use of the frame pointers"),
|
||||
#[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
|
||||
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ symbols! {
|
|||
Break,
|
||||
C,
|
||||
CStr,
|
||||
C_dash_unwind: "C-unwind",
|
||||
CallOnceFuture,
|
||||
CallRefFuture,
|
||||
Capture,
|
||||
|
|
|
|||
|
|
@ -148,22 +148,22 @@ def_regs! {
|
|||
r11: reg = ["r11", "fp"] % frame_pointer_r11,
|
||||
r12: reg = ["r12", "ip"] % not_thumb1,
|
||||
r14: reg = ["r14", "lr"] % not_thumb1,
|
||||
s0: sreg, sreg_low16 = ["s0"],
|
||||
s1: sreg, sreg_low16 = ["s1"],
|
||||
s2: sreg, sreg_low16 = ["s2"],
|
||||
s3: sreg, sreg_low16 = ["s3"],
|
||||
s4: sreg, sreg_low16 = ["s4"],
|
||||
s5: sreg, sreg_low16 = ["s5"],
|
||||
s6: sreg, sreg_low16 = ["s6"],
|
||||
s7: sreg, sreg_low16 = ["s7"],
|
||||
s8: sreg, sreg_low16 = ["s8"],
|
||||
s9: sreg, sreg_low16 = ["s9"],
|
||||
s10: sreg, sreg_low16 = ["s10"],
|
||||
s11: sreg, sreg_low16 = ["s11"],
|
||||
s12: sreg, sreg_low16 = ["s12"],
|
||||
s13: sreg, sreg_low16 = ["s13"],
|
||||
s14: sreg, sreg_low16 = ["s14"],
|
||||
s15: sreg, sreg_low16 = ["s15"],
|
||||
s0: sreg_low16, sreg = ["s0"],
|
||||
s1: sreg_low16, sreg = ["s1"],
|
||||
s2: sreg_low16, sreg = ["s2"],
|
||||
s3: sreg_low16, sreg = ["s3"],
|
||||
s4: sreg_low16, sreg = ["s4"],
|
||||
s5: sreg_low16, sreg = ["s5"],
|
||||
s6: sreg_low16, sreg = ["s6"],
|
||||
s7: sreg_low16, sreg = ["s7"],
|
||||
s8: sreg_low16, sreg = ["s8"],
|
||||
s9: sreg_low16, sreg = ["s9"],
|
||||
s10: sreg_low16, sreg = ["s10"],
|
||||
s11: sreg_low16, sreg = ["s11"],
|
||||
s12: sreg_low16, sreg = ["s12"],
|
||||
s13: sreg_low16, sreg = ["s13"],
|
||||
s14: sreg_low16, sreg = ["s14"],
|
||||
s15: sreg_low16, sreg = ["s15"],
|
||||
s16: sreg = ["s16"],
|
||||
s17: sreg = ["s17"],
|
||||
s18: sreg = ["s18"],
|
||||
|
|
@ -180,22 +180,22 @@ def_regs! {
|
|||
s29: sreg = ["s29"],
|
||||
s30: sreg = ["s30"],
|
||||
s31: sreg = ["s31"],
|
||||
d0: dreg, dreg_low16, dreg_low8 = ["d0"],
|
||||
d1: dreg, dreg_low16, dreg_low8 = ["d1"],
|
||||
d2: dreg, dreg_low16, dreg_low8 = ["d2"],
|
||||
d3: dreg, dreg_low16, dreg_low8 = ["d3"],
|
||||
d4: dreg, dreg_low16, dreg_low8 = ["d4"],
|
||||
d5: dreg, dreg_low16, dreg_low8 = ["d5"],
|
||||
d6: dreg, dreg_low16, dreg_low8 = ["d6"],
|
||||
d7: dreg, dreg_low16, dreg_low8 = ["d7"],
|
||||
d8: dreg, dreg_low16 = ["d8"],
|
||||
d9: dreg, dreg_low16 = ["d9"],
|
||||
d10: dreg, dreg_low16 = ["d10"],
|
||||
d11: dreg, dreg_low16 = ["d11"],
|
||||
d12: dreg, dreg_low16 = ["d12"],
|
||||
d13: dreg, dreg_low16 = ["d13"],
|
||||
d14: dreg, dreg_low16 = ["d14"],
|
||||
d15: dreg, dreg_low16 = ["d15"],
|
||||
d0: dreg_low8, dreg_low16, dreg = ["d0"],
|
||||
d1: dreg_low8, dreg_low16, dreg = ["d1"],
|
||||
d2: dreg_low8, dreg_low16, dreg = ["d2"],
|
||||
d3: dreg_low8, dreg_low16, dreg = ["d3"],
|
||||
d4: dreg_low8, dreg_low16, dreg = ["d4"],
|
||||
d5: dreg_low8, dreg_low16, dreg = ["d5"],
|
||||
d6: dreg_low8, dreg_low16, dreg = ["d6"],
|
||||
d7: dreg_low8, dreg_low16, dreg = ["d7"],
|
||||
d8: dreg_low16, dreg = ["d8"],
|
||||
d9: dreg_low16, dreg = ["d9"],
|
||||
d10: dreg_low16, dreg = ["d10"],
|
||||
d11: dreg_low16, dreg = ["d11"],
|
||||
d12: dreg_low16, dreg = ["d12"],
|
||||
d13: dreg_low16, dreg = ["d13"],
|
||||
d14: dreg_low16, dreg = ["d14"],
|
||||
d15: dreg_low16, dreg = ["d15"],
|
||||
d16: dreg = ["d16"],
|
||||
d17: dreg = ["d17"],
|
||||
d18: dreg = ["d18"],
|
||||
|
|
@ -212,14 +212,14 @@ def_regs! {
|
|||
d29: dreg = ["d29"],
|
||||
d30: dreg = ["d30"],
|
||||
d31: dreg = ["d31"],
|
||||
q0: qreg, qreg_low8, qreg_low4 = ["q0"],
|
||||
q1: qreg, qreg_low8, qreg_low4 = ["q1"],
|
||||
q2: qreg, qreg_low8, qreg_low4 = ["q2"],
|
||||
q3: qreg, qreg_low8, qreg_low4 = ["q3"],
|
||||
q4: qreg, qreg_low8 = ["q4"],
|
||||
q5: qreg, qreg_low8 = ["q5"],
|
||||
q6: qreg, qreg_low8 = ["q6"],
|
||||
q7: qreg, qreg_low8 = ["q7"],
|
||||
q0: qreg_low4, qreg_low8, qreg = ["q0"],
|
||||
q1: qreg_low4, qreg_low8, qreg = ["q1"],
|
||||
q2: qreg_low4, qreg_low8, qreg = ["q2"],
|
||||
q3: qreg_low4, qreg_low8, qreg = ["q3"],
|
||||
q4: qreg_low8, qreg = ["q4"],
|
||||
q5: qreg_low8, qreg = ["q5"],
|
||||
q6: qreg_low8, qreg = ["q6"],
|
||||
q7: qreg_low8, qreg = ["q7"],
|
||||
q8: qreg = ["q8"],
|
||||
q9: qreg = ["q9"],
|
||||
q10: qreg = ["q10"],
|
||||
|
|
|
|||
|
|
@ -1413,6 +1413,20 @@ pub enum FramePointer {
|
|||
MayOmit,
|
||||
}
|
||||
|
||||
impl FramePointer {
|
||||
/// It is intended that the "force frame pointer" transition is "one way"
|
||||
/// so this convenience assures such if used
|
||||
#[inline]
|
||||
pub fn ratchet(&mut self, rhs: FramePointer) -> FramePointer {
|
||||
*self = match (*self, rhs) {
|
||||
(FramePointer::Always, _) | (_, FramePointer::Always) => FramePointer::Always,
|
||||
(FramePointer::NonLeaf, _) | (_, FramePointer::NonLeaf) => FramePointer::NonLeaf,
|
||||
_ => FramePointer::MayOmit,
|
||||
};
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for FramePointer {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, ()> {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use crate::io::{self, ErrorKind};
|
|||
pub use self::ip_addr::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::socket_addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88373")]
|
||||
pub use self::tcp::IntoIncoming;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::tcp::{Incoming, TcpListener, TcpStream};
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ pub struct Incoming<'a> {
|
|||
///
|
||||
/// [`accept`]: TcpListener::accept
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88373")]
|
||||
pub struct IntoIncoming {
|
||||
listener: TcpListener,
|
||||
}
|
||||
|
|
@ -894,7 +894,7 @@ impl TcpListener {
|
|||
/// }
|
||||
/// ```
|
||||
#[must_use = "`self` will be dropped if the result is not used"]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88373")]
|
||||
pub fn into_incoming(self) -> IntoIncoming {
|
||||
IntoIncoming { listener: self }
|
||||
}
|
||||
|
|
@ -1033,7 +1033,7 @@ impl<'a> Iterator for Incoming<'a> {
|
|||
#[stable(feature = "tcp_listener_incoming_fused_iterator", since = "1.64.0")]
|
||||
impl FusedIterator for Incoming<'_> {}
|
||||
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88373")]
|
||||
impl Iterator for IntoIncoming {
|
||||
type Item = io::Result<TcpStream>;
|
||||
fn next(&mut self) -> Option<io::Result<TcpStream>> {
|
||||
|
|
@ -1041,7 +1041,7 @@ impl Iterator for IntoIncoming {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
|
||||
#[unstable(feature = "tcplistener_into_incoming", issue = "88373")]
|
||||
impl FusedIterator for IntoIncoming {}
|
||||
|
||||
impl AsInner<net_imp::TcpListener> for TcpListener {
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ use crate::sys::time::SystemTime;
|
|||
use crate::sys::{cvt, cvt_r};
|
||||
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
||||
|
||||
#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu"))]
|
||||
use crate::sys::weak::syscall;
|
||||
#[cfg(target_os = "android")]
|
||||
use crate::sys::weak::weak;
|
||||
|
||||
use libc::{c_int, mode_t};
|
||||
|
||||
#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu"))]
|
||||
use libc::c_char;
|
||||
#[cfg(any(
|
||||
all(target_os = "linux", not(target_env = "musl")),
|
||||
|
|
@ -1891,8 +1891,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
|||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;
|
||||
|
||||
struct FreeOnDrop(libc::copyfile_state_t);
|
||||
|
|
@ -1907,39 +1905,21 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
|||
}
|
||||
}
|
||||
|
||||
// MacOS prior to 10.12 don't support `fclonefileat`
|
||||
// We store the availability in a global to avoid unnecessary syscalls
|
||||
static HAS_FCLONEFILEAT: AtomicBool = AtomicBool::new(true);
|
||||
syscall! {
|
||||
// Mirrors `libc::fclonefileat`
|
||||
fn fclonefileat(
|
||||
srcfd: libc::c_int,
|
||||
dst_dirfd: libc::c_int,
|
||||
dst: *const c_char,
|
||||
flags: libc::c_int
|
||||
) -> libc::c_int
|
||||
}
|
||||
|
||||
let (reader, reader_metadata) = open_from(from)?;
|
||||
|
||||
// Opportunistically attempt to create a copy-on-write clone of `from`
|
||||
// using `fclonefileat`.
|
||||
if HAS_FCLONEFILEAT.load(Ordering::Relaxed) {
|
||||
let clonefile_result = run_path_with_cstr(to, &|to| {
|
||||
cvt(unsafe { fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
|
||||
});
|
||||
match clonefile_result {
|
||||
Ok(_) => return Ok(reader_metadata.len()),
|
||||
Err(err) => match err.raw_os_error() {
|
||||
// `fclonefileat` will fail on non-APFS volumes, if the
|
||||
// destination already exists, or if the source and destination
|
||||
// are on different devices. In all these cases `fcopyfile`
|
||||
// should succeed.
|
||||
Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (),
|
||||
Some(libc::ENOSYS) => HAS_FCLONEFILEAT.store(false, Ordering::Relaxed),
|
||||
_ => return Err(err),
|
||||
},
|
||||
}
|
||||
let clonefile_result = run_path_with_cstr(to, &|to| {
|
||||
cvt(unsafe { libc::fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
|
||||
});
|
||||
match clonefile_result {
|
||||
Ok(_) => return Ok(reader_metadata.len()),
|
||||
Err(e) => match e.raw_os_error() {
|
||||
// `fclonefileat` will fail on non-APFS volumes, if the
|
||||
// destination already exists, or if the source and destination
|
||||
// are on different devices. In all these cases `fcopyfile`
|
||||
// should succeed.
|
||||
Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (),
|
||||
_ => return Err(e),
|
||||
},
|
||||
}
|
||||
|
||||
// Fall back to using `fcopyfile` if `fclonefileat` does not succeed.
|
||||
|
|
|
|||
|
|
@ -738,17 +738,17 @@ pub fn home_dir() -> Option<PathBuf> {
|
|||
n => n as usize,
|
||||
};
|
||||
let mut buf = Vec::with_capacity(amt);
|
||||
let mut passwd: libc::passwd = mem::zeroed();
|
||||
let mut p = mem::MaybeUninit::<libc::passwd>::uninit();
|
||||
let mut result = ptr::null_mut();
|
||||
match libc::getpwuid_r(
|
||||
libc::getuid(),
|
||||
&mut passwd,
|
||||
p.as_mut_ptr(),
|
||||
buf.as_mut_ptr(),
|
||||
buf.capacity(),
|
||||
&mut result,
|
||||
) {
|
||||
0 if !result.is_null() => {
|
||||
let ptr = passwd.pw_dir as *const _;
|
||||
let ptr = (*result).pw_dir as *const _;
|
||||
let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
|
||||
Some(OsStringExt::from_vec(bytes))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Change this file to make users of the `download-ci-llvm` configuration download
|
||||
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
|
||||
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/125141
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/126298
|
||||
|
|
|
|||
|
|
@ -1290,15 +1290,21 @@ fn needs_codegen_config(run: &RunConfig<'_>) -> bool {
|
|||
pub(crate) const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_";
|
||||
|
||||
fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool {
|
||||
if path.path.to_str().unwrap().contains(CODEGEN_BACKEND_PREFIX) {
|
||||
let path = path.path.to_str().unwrap();
|
||||
|
||||
let is_explicitly_called = |p| -> bool { run.builder.paths.contains(p) };
|
||||
let should_enforce = run.builder.kind == Kind::Dist || run.builder.kind == Kind::Install;
|
||||
|
||||
if path.contains(CODEGEN_BACKEND_PREFIX) {
|
||||
let mut needs_codegen_backend_config = true;
|
||||
for backend in run.builder.config.codegen_backends(run.target) {
|
||||
if path.path.to_str().unwrap().ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend))
|
||||
{
|
||||
if path.ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend)) {
|
||||
needs_codegen_backend_config = false;
|
||||
}
|
||||
}
|
||||
if needs_codegen_backend_config {
|
||||
if (is_explicitly_called(&PathBuf::from(path)) || should_enforce)
|
||||
&& needs_codegen_backend_config
|
||||
{
|
||||
run.builder.info(
|
||||
"WARNING: no codegen-backends config matched the requested path to build a codegen backend. \
|
||||
HELP: add backend to codegen-backends in config.toml.",
|
||||
|
|
|
|||
|
|
@ -665,6 +665,10 @@ impl Step for Std {
|
|||
}
|
||||
}
|
||||
|
||||
/// Tarball containing the compiler that gets downloaded and used by
|
||||
/// `rust.download-rustc`.
|
||||
///
|
||||
/// (Don't confuse this with [`RustDev`], without the `c`!)
|
||||
#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct RustcDev {
|
||||
pub compiler: Compiler,
|
||||
|
|
@ -1014,7 +1018,7 @@ impl Step for PlainSourceTarball {
|
|||
// perhaps it should be removed in favor of making `dist` perform the `vendor` step?
|
||||
|
||||
// Ensure we have all submodules from src and other directories checked out.
|
||||
for submodule in builder.get_all_submodules() {
|
||||
for submodule in build_helper::util::parse_gitmodules(&builder.src) {
|
||||
builder.update_submodule(Path::new(submodule));
|
||||
}
|
||||
|
||||
|
|
@ -2225,6 +2229,11 @@ impl Step for LlvmBitcodeLinker {
|
|||
/// Tarball intended for internal consumption to ease rustc/std development.
|
||||
///
|
||||
/// Should not be considered stable by end users.
|
||||
///
|
||||
/// In practice, this is the tarball that gets downloaded and used by
|
||||
/// `llvm.download-ci-llvm`.
|
||||
///
|
||||
/// (Don't confuse this with [`RustcDev`], with a `c`!)
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct RustDev {
|
||||
pub target: TargetSelection,
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
|
|||
("arm-unknown-linux-gnueabihf", false),
|
||||
("armv7-unknown-linux-gnueabihf", false),
|
||||
("loongarch64-unknown-linux-gnu", false),
|
||||
("loongarch64-unknown-linux-musl", false),
|
||||
("mips-unknown-linux-gnu", false),
|
||||
("mips64-unknown-linux-gnuabi64", false),
|
||||
("mips64el-unknown-linux-gnuabi64", false),
|
||||
|
|
|
|||
|
|
@ -1048,8 +1048,6 @@ impl Step for Tidy {
|
|||
/// Once tidy passes, this step also runs `fmt --check` if tests are being run
|
||||
/// for the `dev` or `nightly` channels.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.build.update_submodule(Path::new("src/tools/rustc-perf"));
|
||||
|
||||
let mut cmd = builder.tool_cmd(Tool::Tidy);
|
||||
cmd.arg(&builder.src);
|
||||
cmd.arg(&builder.initial_cargo);
|
||||
|
|
|
|||
|
|
@ -4,13 +4,11 @@ use std::collections::BTreeSet;
|
|||
use std::env;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt::{Debug, Write};
|
||||
use std::fs::{self, File};
|
||||
use std::fs;
|
||||
use std::hash::Hash;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::core::build_steps::tool::{self, SourceType};
|
||||
|
|
@ -274,7 +272,7 @@ impl PathSet {
|
|||
/// This is used for `StepDescription::krate`, which passes all matching crates at once to
|
||||
/// `Step::make_run`, rather than calling it many times with a single crate.
|
||||
/// See `tests.rs` for examples.
|
||||
fn intersection_removing_matches(&self, needles: &mut Vec<&Path>, module: Kind) -> PathSet {
|
||||
fn intersection_removing_matches(&self, needles: &mut Vec<PathBuf>, module: Kind) -> PathSet {
|
||||
let mut check = |p| {
|
||||
for (i, n) in needles.iter().enumerate() {
|
||||
let matched = Self::check(p, n, module);
|
||||
|
|
@ -346,7 +344,7 @@ const PATH_REMAP: &[(&str, &[&str])] = &[
|
|||
),
|
||||
];
|
||||
|
||||
fn remap_paths(paths: &mut Vec<&Path>) {
|
||||
fn remap_paths(paths: &mut Vec<PathBuf>) {
|
||||
let mut remove = vec![];
|
||||
let mut add = vec![];
|
||||
for (i, path) in paths.iter().enumerate().filter_map(|(i, path)| path.to_str().map(|s| (i, s)))
|
||||
|
|
@ -355,7 +353,7 @@ fn remap_paths(paths: &mut Vec<&Path>) {
|
|||
// Remove leading and trailing slashes so `tests/` and `tests` are equivalent
|
||||
if path.trim_matches(std::path::is_separator) == search {
|
||||
remove.push(i);
|
||||
add.extend(replace.iter().map(Path::new));
|
||||
add.extend(replace.iter().map(PathBuf::from));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -438,8 +436,25 @@ impl StepDescription {
|
|||
}
|
||||
}
|
||||
|
||||
// strip CurDir prefix if present
|
||||
let mut paths: Vec<_> = paths.iter().map(|p| p.strip_prefix(".").unwrap_or(p)).collect();
|
||||
// Attempt to resolve paths to be relative to the builder source directory.
|
||||
let mut paths: Vec<PathBuf> = paths
|
||||
.iter()
|
||||
.map(|p| {
|
||||
// If the path does not exist, it may represent the name of a Step, such as `tidy` in `x test tidy`
|
||||
if !p.exists() {
|
||||
return p.clone();
|
||||
}
|
||||
|
||||
// Make the path absolute, strip the prefix, and convert to a PathBuf.
|
||||
match std::path::absolute(p) {
|
||||
Ok(p) => p.strip_prefix(&builder.src).unwrap_or(&p).to_path_buf(),
|
||||
Err(e) => {
|
||||
eprintln!("ERROR: {:?}", e);
|
||||
panic!("Due to the above error, failed to resolve path: {:?}", p);
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
remap_paths(&mut paths);
|
||||
|
||||
|
|
@ -577,7 +592,7 @@ impl<'a> ShouldRun<'a> {
|
|||
///
|
||||
/// [`path`]: ShouldRun::path
|
||||
pub fn paths(mut self, paths: &[&str]) -> Self {
|
||||
let submodules_paths = self.builder.get_all_submodules();
|
||||
let submodules_paths = build_helper::util::parse_gitmodules(&self.builder.src);
|
||||
|
||||
self.paths.insert(PathSet::Set(
|
||||
paths
|
||||
|
|
@ -629,7 +644,7 @@ impl<'a> ShouldRun<'a> {
|
|||
/// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?)
|
||||
fn pathset_for_paths_removing_matches(
|
||||
&self,
|
||||
paths: &mut Vec<&Path>,
|
||||
paths: &mut Vec<PathBuf>,
|
||||
kind: Kind,
|
||||
) -> Vec<PathSet> {
|
||||
let mut sets = vec![];
|
||||
|
|
@ -2226,28 +2241,6 @@ impl<'a> Builder<'a> {
|
|||
out
|
||||
}
|
||||
|
||||
/// Return paths of all submodules.
|
||||
pub fn get_all_submodules(&self) -> &[String] {
|
||||
static SUBMODULES_PATHS: OnceLock<Vec<String>> = OnceLock::new();
|
||||
|
||||
let init_submodules_paths = |src: &PathBuf| {
|
||||
let file = File::open(src.join(".gitmodules")).unwrap();
|
||||
|
||||
let mut submodules_paths = vec![];
|
||||
for line in BufReader::new(file).lines().map_while(Result::ok) {
|
||||
let line = line.trim();
|
||||
if line.starts_with("path") {
|
||||
let actual_path = line.split(' ').last().expect("Couldn't get value of path");
|
||||
submodules_paths.push(actual_path.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
submodules_paths
|
||||
};
|
||||
|
||||
SUBMODULES_PATHS.get_or_init(|| init_submodules_paths(&self.src))
|
||||
}
|
||||
|
||||
/// Ensure that a given step is built *only if it's supposed to be built by default*, returning
|
||||
/// its output. This will cache the step, so it's safe (and good!) to call this as often as
|
||||
/// needed to ensure that all dependencies are build.
|
||||
|
|
|
|||
|
|
@ -122,11 +122,14 @@ fn test_intersection() {
|
|||
PathSet::Set(paths.into_iter().map(|p| TaskPath { path: p.into(), kind: None }).collect())
|
||||
};
|
||||
let library_set = set(&["library/core", "library/alloc", "library/std"]);
|
||||
let mut command_paths =
|
||||
vec![Path::new("library/core"), Path::new("library/alloc"), Path::new("library/stdarch")];
|
||||
let mut command_paths = vec![
|
||||
PathBuf::from("library/core"),
|
||||
PathBuf::from("library/alloc"),
|
||||
PathBuf::from("library/stdarch"),
|
||||
];
|
||||
let subset = library_set.intersection_removing_matches(&mut command_paths, Kind::Build);
|
||||
assert_eq!(subset, set(&["library/core", "library/alloc"]),);
|
||||
assert_eq!(command_paths, vec![Path::new("library/stdarch")]);
|
||||
assert_eq!(command_paths, vec![PathBuf::from("library/stdarch")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result<
|
|||
if config.dry_run() {
|
||||
return Ok(());
|
||||
}
|
||||
let _ = fs::remove_dir(link);
|
||||
let _ = fs::remove_dir_all(link);
|
||||
return symlink_dir_inner(original, link);
|
||||
|
||||
#[cfg(not(windows))]
|
||||
|
|
|
|||
|
|
@ -271,6 +271,22 @@ For targets: `loongarch64-unknown-linux-gnu`
|
|||
- C compiler > gcc version = 13.2.0
|
||||
- C compiler > C++ = ENABLE -- to cross compile LLVM
|
||||
|
||||
### `loongarch64-linux-musl.defconfig`
|
||||
|
||||
For targets: `loongarch64-unknown-linux-musl`
|
||||
|
||||
- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
|
||||
- Path and misc options > Use a mirror = ENABLE
|
||||
- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc
|
||||
- Target options > Target Architecture = loongarch
|
||||
- Target options > Bitness = 64-bit
|
||||
- Operating System > Target OS = linux
|
||||
- Operating System > Linux kernel version = 5.19.16
|
||||
- Binary utilities > Version of binutils = 2.41
|
||||
- C-library > musl version = 1.2.5
|
||||
- C compiler > gcc version = 13.2.0
|
||||
- C compiler > C++ = ENABLE -- to cross compile LLVM
|
||||
|
||||
### `mips-linux-gnu.defconfig`
|
||||
|
||||
For targets: `mips-unknown-linux-gnu`
|
||||
|
|
|
|||
35
src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
Normal file
35
src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
FROM ubuntu:22.04
|
||||
|
||||
COPY scripts/cross-apt-packages.sh /scripts/
|
||||
RUN sh /scripts/cross-apt-packages.sh
|
||||
|
||||
COPY scripts/crosstool-ng-git.sh /scripts/
|
||||
RUN sh /scripts/crosstool-ng-git.sh
|
||||
|
||||
COPY scripts/rustbuild-setup.sh /scripts/
|
||||
RUN sh /scripts/rustbuild-setup.sh
|
||||
WORKDIR /tmp
|
||||
|
||||
COPY scripts/crosstool-ng-build.sh /scripts/
|
||||
COPY host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig /tmp/crosstool.defconfig
|
||||
RUN /scripts/crosstool-ng-build.sh
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
ENV PATH=$PATH:/x-tools/loongarch64-unknown-linux-musl/bin
|
||||
|
||||
ENV CC_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-gcc \
|
||||
AR_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-ar \
|
||||
CXX_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-g++
|
||||
|
||||
ENV HOSTS=loongarch64-unknown-linux-musl
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--enable-extended \
|
||||
--enable-lld \
|
||||
--disable-docs \
|
||||
--set target.loongarch64-unknown-linux-musl.crt-static=false \
|
||||
--musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr
|
||||
|
||||
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
CT_CONFIG_VERSION="4"
|
||||
CT_EXPERIMENTAL=y
|
||||
CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
|
||||
CT_USE_MIRROR=y
|
||||
CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
|
||||
CT_ARCH_LOONGARCH=y
|
||||
# CT_DEMULTILIB is not set
|
||||
CT_ARCH_USE_MMU=y
|
||||
CT_ARCH_ARCH="loongarch64"
|
||||
CT_KERNEL_LINUX=y
|
||||
CT_LINUX_V_5_19=y
|
||||
CT_LIBC_MUSL=y
|
||||
CT_CC_GCC_ENABLE_DEFAULT_PIE=y
|
||||
CT_CC_LANG_CXX=y
|
||||
CT_GETTEXT_NEEDED=y
|
||||
|
|
@ -1 +1 @@
|
|||
0.17.2
|
||||
0.18.0
|
||||
17
src/ci/docker/scripts/crosstool-ng-git.sh
Normal file
17
src/ci/docker/scripts/crosstool-ng-git.sh
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
URL=https://github.com/crosstool-ng/crosstool-ng
|
||||
REV=c64500d94be92ed1bcdfdef911048a14e216a5e1
|
||||
|
||||
mkdir crosstool-ng
|
||||
cd crosstool-ng
|
||||
git init
|
||||
git fetch --depth=1 ${URL} ${REV}
|
||||
git reset --hard FETCH_HEAD
|
||||
./bootstrap
|
||||
./configure --prefix=/usr/local
|
||||
make -j$(nproc)
|
||||
make install
|
||||
cd ..
|
||||
rm -rf crosstool-ng
|
||||
|
|
@ -144,6 +144,9 @@ auto:
|
|||
- image: dist-loongarch64-linux
|
||||
<<: *job-linux-4c
|
||||
|
||||
- image: dist-loongarch64-musl
|
||||
<<: *job-linux-4c
|
||||
|
||||
- image: dist-ohos
|
||||
<<: *job-linux-4c
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ target | notes
|
|||
`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
|
||||
`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17)
|
||||
[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
|
||||
[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5)
|
||||
`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
|
||||
`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
|
||||
`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
|
||||
|
|
@ -305,7 +306,6 @@ target | std | host | notes
|
|||
`i686-uwp-windows-msvc` | ✓ | | [^x86_32-floats-return-ABI]
|
||||
[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
|
||||
`i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI]
|
||||
[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI) with musl 1.2.3
|
||||
[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux
|
||||
`mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
|
||||
`mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.3
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ This tool generates the manifests uploaded to static.rust-lang.org and used by r
|
|||
You can see a full list of all manifests at <https://static.rust-lang.org/manifests.txt>.
|
||||
This listing is updated by <https://github.com/rust-lang/generate-manifest-list> every 7 days.
|
||||
|
||||
This gets called by `promote-release` <https://github.com/rust-lang/promote-release> via `x.py dist hash-and-sign`.
|
||||
This gets called by `promote-release` <https://github.com/rust-lang/promote-release>. `promote-release` downloads a pre-built binary of `build-manifest` which is generated in the dist-x86_64-linux builder and uploaded to s3.
|
||||
|
||||
## Adding a new component
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ static HOSTS: &[&str] = &[
|
|||
"i686-pc-windows-msvc",
|
||||
"i686-unknown-linux-gnu",
|
||||
"loongarch64-unknown-linux-gnu",
|
||||
"loongarch64-unknown-linux-musl",
|
||||
"mips-unknown-linux-gnu",
|
||||
"mips64-unknown-linux-gnuabi64",
|
||||
"mips64el-unknown-linux-gnuabi64",
|
||||
|
|
@ -106,6 +107,7 @@ static TARGETS: &[&str] = &[
|
|||
"i686-unknown-redox",
|
||||
"i686-unknown-uefi",
|
||||
"loongarch64-unknown-linux-gnu",
|
||||
"loongarch64-unknown-linux-musl",
|
||||
"loongarch64-unknown-none",
|
||||
"loongarch64-unknown-none-softfloat",
|
||||
"m68k-unknown-linux-gnu",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
/// Invokes `build_helper::util::detail_exit` with `cfg!(test)`
|
||||
///
|
||||
|
|
@ -45,3 +49,27 @@ pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> Result<(), ()> {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the submodule paths from the `.gitmodules` file in the given directory.
|
||||
pub fn parse_gitmodules(target_dir: &Path) -> &[String] {
|
||||
static SUBMODULES_PATHS: OnceLock<Vec<String>> = OnceLock::new();
|
||||
let gitmodules = target_dir.join(".gitmodules");
|
||||
assert!(gitmodules.exists(), "'{}' file is missing.", gitmodules.display());
|
||||
|
||||
let init_submodules_paths = || {
|
||||
let file = File::open(gitmodules).unwrap();
|
||||
|
||||
let mut submodules_paths = vec![];
|
||||
for line in BufReader::new(file).lines().map_while(Result::ok) {
|
||||
let line = line.trim();
|
||||
if line.starts_with("path") {
|
||||
let actual_path = line.split(' ').last().expect("Couldn't get value of path");
|
||||
submodules_paths.push(actual_path.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
submodules_paths
|
||||
};
|
||||
|
||||
SUBMODULES_PATHS.get_or_init(|| init_submodules_paths())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -779,6 +779,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"ignore-haiku",
|
||||
"ignore-horizon",
|
||||
"ignore-i686-pc-windows-msvc",
|
||||
"ignore-illumos",
|
||||
"ignore-ios",
|
||||
"ignore-linux",
|
||||
"ignore-lldb",
|
||||
|
|
@ -843,6 +844,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"ignore-x32",
|
||||
"ignore-x86",
|
||||
"ignore-x86_64",
|
||||
"ignore-x86_64-apple-darwin",
|
||||
"ignore-x86_64-unknown-linux-gnu",
|
||||
"incremental",
|
||||
"known-bug",
|
||||
|
|
@ -875,6 +877,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"needs-sanitizer-shadow-call-stack",
|
||||
"needs-sanitizer-support",
|
||||
"needs-sanitizer-thread",
|
||||
"needs-symlink",
|
||||
"needs-threads",
|
||||
"needs-unwind",
|
||||
"needs-wasmtime",
|
||||
|
|
|
|||
|
|
@ -144,6 +144,11 @@ pub(super) fn handle_needs(
|
|||
condition: config.runner.as_ref().is_some_and(|r| r.contains("wasmtime")),
|
||||
ignore_reason: "ignored when wasmtime runner is not available",
|
||||
},
|
||||
Need {
|
||||
name: "needs-symlink",
|
||||
condition: cache.symlinks,
|
||||
ignore_reason: "ignored if symlinks are unavailable",
|
||||
},
|
||||
];
|
||||
|
||||
let (name, comment) = match ln.split_once([':', ' ']) {
|
||||
|
|
@ -209,6 +214,7 @@ pub(super) struct CachedNeedsConditions {
|
|||
xray: bool,
|
||||
rust_lld: bool,
|
||||
dlltool: bool,
|
||||
symlinks: bool,
|
||||
}
|
||||
|
||||
impl CachedNeedsConditions {
|
||||
|
|
@ -253,6 +259,7 @@ impl CachedNeedsConditions {
|
|||
.exists(),
|
||||
|
||||
dlltool: find_dlltool(&config),
|
||||
symlinks: has_symlinks(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -279,3 +286,22 @@ fn find_dlltool(config: &Config) -> bool {
|
|||
};
|
||||
dlltool_found
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn has_symlinks() -> bool {
|
||||
if std::env::var_os("CI").is_some() {
|
||||
return true;
|
||||
}
|
||||
let link = std::env::temp_dir().join("RUST_COMPILETEST_SYMLINK_CHECK");
|
||||
if std::os::windows::fs::symlink_file("DOES NOT EXIST", &link).is_ok() {
|
||||
std::fs::remove_file(&link).unwrap();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn has_symlinks() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
acb62737aca7045f331e7a05adc38bed213e278d
|
||||
d49994b060684af423339b55769439b2f444a7b9
|
||||
|
|
|
|||
|
|
@ -311,7 +311,9 @@ pub fn report_error<'tcx>(
|
|||
ResourceExhaustion(_) => "resource exhaustion",
|
||||
Unsupported(
|
||||
// We list only the ones that can actually happen.
|
||||
UnsupportedOpInfo::Unsupported(_) | UnsupportedOpInfo::UnsizedLocal,
|
||||
UnsupportedOpInfo::Unsupported(_)
|
||||
| UnsupportedOpInfo::UnsizedLocal
|
||||
| UnsupportedOpInfo::ExternTypeField,
|
||||
) => "unsupported operation",
|
||||
InvalidProgram(
|
||||
// We list only the ones that can actually happen.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: unsupported operation: `extern type` does not have a known offset
|
||||
error: unsupported operation: `extern type` field does not have a known offset
|
||||
--> $DIR/extern-type-field-offset.rs:LL:CC
|
||||
|
|
||||
LL | let _field = &x.a;
|
||||
| ^^^^ `extern type` does not have a known offset
|
||||
| ^^^^ `extern type` field does not have a known offset
|
||||
|
|
||||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
|
||||
= note: BACKTRACE:
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@ impl Command {
|
|||
Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) }
|
||||
}
|
||||
|
||||
pub fn set_stdin(&mut self, stdin: Box<[u8]>) {
|
||||
self.stdin = Some(stdin);
|
||||
/// Specify a stdin input
|
||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||
self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify an environment variable.
|
||||
|
|
|
|||
|
|
@ -102,6 +102,24 @@ impl LlvmReadobj {
|
|||
self
|
||||
}
|
||||
|
||||
/// Pass `--program-headers` to display program headers.
|
||||
pub fn program_headers(&mut self) -> &mut Self {
|
||||
self.cmd.arg("--program-headers");
|
||||
self
|
||||
}
|
||||
|
||||
/// Pass `--symbols` to display the symbol.
|
||||
pub fn symbols(&mut self) -> &mut Self {
|
||||
self.cmd.arg("--symbols");
|
||||
self
|
||||
}
|
||||
|
||||
/// Pass `--dynamic-table` to display the dynamic symbol table.
|
||||
pub fn dynamic_table(&mut self) -> &mut Self {
|
||||
self.cmd.arg("--dynamic-table");
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify the section to display.
|
||||
pub fn section(&mut self, section: &str) -> &mut Self {
|
||||
self.cmd.arg("--string-dump");
|
||||
|
|
@ -153,7 +171,7 @@ impl LlvmFilecheck {
|
|||
|
||||
/// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call.
|
||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||
self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice());
|
||||
self.cmd.stdin(input);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ impl Rustc {
|
|||
|
||||
/// Specify a stdin input
|
||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||
self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice());
|
||||
self.cmd.stdin(input);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ impl Rustdoc {
|
|||
|
||||
/// Specify a stdin input
|
||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||
self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice());
|
||||
self.cmd.stdin(input);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ tq = "test -- -q"
|
|||
qt = "tq"
|
||||
lint = "clippy --all-targets -- --cap-lints warn"
|
||||
codegen = "run --package xtask --bin xtask -- codegen"
|
||||
dist = "run --package xtask --bin xtask -- dist"
|
||||
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
linker = "rust-lld"
|
||||
|
|
|
|||
|
|
@ -328,6 +328,15 @@ dependencies = [
|
|||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
|
|
@ -503,6 +512,7 @@ dependencies = [
|
|||
"hir-def",
|
||||
"hir-expand",
|
||||
"hir-ty",
|
||||
"intern",
|
||||
"itertools",
|
||||
"once_cell",
|
||||
"rustc-hash",
|
||||
|
|
@ -891,9 +901,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.154"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
|
@ -1665,6 +1675,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"cfg",
|
||||
"crossbeam-channel",
|
||||
"dirs",
|
||||
"dissimilar",
|
||||
"expect-test",
|
||||
"flycheck",
|
||||
|
|
|
|||
|
|
@ -162,7 +162,11 @@ xshell = "0.2.5"
|
|||
dashmap = { version = "=5.5.3", features = ["raw-api"] }
|
||||
|
||||
[workspace.lints.rust]
|
||||
rust_2018_idioms = "warn"
|
||||
bare_trait_objects = "warn"
|
||||
elided_lifetimes_in_paths = "warn"
|
||||
ellipsis_inclusive_range_patterns = "warn"
|
||||
explicit_outlives_requirements = "warn"
|
||||
unused_extern_crates = "warn"
|
||||
unused_lifetimes = "warn"
|
||||
unreachable_pub = "warn"
|
||||
semicolon_in_expressions_from_macros = "warn"
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ impl FileChange {
|
|||
}
|
||||
|
||||
pub fn apply(self, db: &mut dyn SourceDatabaseExt) {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "FileChange::apply").entered();
|
||||
let _p = tracing::info_span!("FileChange::apply").entered();
|
||||
if let Some(roots) = self.roots {
|
||||
for (idx, root) in roots.into_iter().enumerate() {
|
||||
let root_id = SourceRootId(idx as u32);
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ impl CrateGraph {
|
|||
from: CrateId,
|
||||
dep: Dependency,
|
||||
) -> Result<(), CyclicDependenciesError> {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "add_dep").entered();
|
||||
let _p = tracing::info_span!("add_dep").entered();
|
||||
|
||||
self.check_cycle_after_dependency(from, dep.crate_id)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option<ReleaseC
|
|||
}
|
||||
|
||||
fn parse(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "parse", ?file_id).entered();
|
||||
let _p = tracing::info_span!("parse", ?file_id).entered();
|
||||
let text = db.file_text(file_id);
|
||||
// FIXME: Edition based parsing
|
||||
SourceFile::parse(&text, span::Edition::CURRENT)
|
||||
|
|
@ -187,7 +187,7 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
|
|||
}
|
||||
|
||||
fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "relevant_crates").entered();
|
||||
let _p = tracing::info_span!("relevant_crates").entered();
|
||||
let source_root = self.0.file_source_root(file_id);
|
||||
self.0.source_root_crates(source_root)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ impl FlycheckActor {
|
|||
Some(c) => c,
|
||||
None => continue,
|
||||
};
|
||||
let formatted_command = format!("{:?}", command);
|
||||
let formatted_command = format!("{command:?}");
|
||||
|
||||
tracing::debug!(?command, "will restart flycheck");
|
||||
let (sender, receiver) = unbounded();
|
||||
|
|
@ -318,8 +318,7 @@ impl FlycheckActor {
|
|||
}
|
||||
Err(error) => {
|
||||
self.report_progress(Progress::DidFailToRestart(format!(
|
||||
"Failed to run the following command: {} error={}",
|
||||
formatted_command, error
|
||||
"Failed to run the following command: {formatted_command} error={error}"
|
||||
)));
|
||||
self.status = FlycheckStatus::Finished;
|
||||
}
|
||||
|
|
@ -331,7 +330,7 @@ impl FlycheckActor {
|
|||
// Watcher finished
|
||||
let command_handle = self.command_handle.take().unwrap();
|
||||
self.command_receiver.take();
|
||||
let formatted_handle = format!("{:?}", command_handle);
|
||||
let formatted_handle = format!("{command_handle:?}");
|
||||
|
||||
let res = command_handle.join();
|
||||
if let Err(error) = &res {
|
||||
|
|
@ -387,6 +386,7 @@ impl FlycheckActor {
|
|||
"did cancel flycheck"
|
||||
);
|
||||
command_handle.cancel();
|
||||
self.command_receiver.take();
|
||||
self.report_progress(Progress::DidCancel);
|
||||
self.status = FlycheckStatus::Finished;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
||||
|
||||
pub mod builtin;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use std::{borrow::Cow, hash::Hash, ops, slice::Iter as SliceIter};
|
||||
|
||||
use base_db::CrateId;
|
||||
|
|
@ -75,7 +70,7 @@ impl Attrs {
|
|||
db: &dyn DefDatabase,
|
||||
v: VariantId,
|
||||
) -> Arc<ArenaMap<LocalFieldId, Attrs>> {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "fields_attrs_query").entered();
|
||||
let _p = tracing::info_span!("fields_attrs_query").entered();
|
||||
// FIXME: There should be some proper form of mapping between item tree field ids and hir field ids
|
||||
let mut res = ArenaMap::default();
|
||||
|
||||
|
|
@ -326,7 +321,7 @@ impl AttrsWithOwner {
|
|||
}
|
||||
|
||||
pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "attrs_query").entered();
|
||||
let _p = tracing::info_span!("attrs_query").entered();
|
||||
// FIXME: this should use `Trace` to avoid duplication in `source_map` below
|
||||
let raw_attrs = match def {
|
||||
AttrDefId::ModuleId(module) => {
|
||||
|
|
@ -646,3 +641,55 @@ pub(crate) fn fields_attrs_source_map(
|
|||
|
||||
Arc::new(res)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
//! This module contains tests for doc-expression parsing.
|
||||
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
|
||||
|
||||
use triomphe::Arc;
|
||||
|
||||
use base_db::FileId;
|
||||
use hir_expand::span_map::{RealSpanMap, SpanMap};
|
||||
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode};
|
||||
use syntax::{ast, AstNode, TextRange};
|
||||
|
||||
use crate::attr::{DocAtom, DocExpr};
|
||||
|
||||
fn assert_parse_result(input: &str, expected: DocExpr) {
|
||||
let source_file = ast::SourceFile::parse(input, span::Edition::CURRENT).ok().unwrap();
|
||||
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
|
||||
let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
|
||||
let tt = syntax_node_to_token_tree(
|
||||
tt.syntax(),
|
||||
map.as_ref(),
|
||||
map.span_for_range(TextRange::empty(0.into())),
|
||||
DocCommentDesugarMode::ProcMacro,
|
||||
);
|
||||
let cfg = DocExpr::parse(&tt);
|
||||
assert_eq!(cfg, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_doc_expr_parser() {
|
||||
assert_parse_result("#![doc(hidden)]", DocAtom::Flag("hidden".into()).into());
|
||||
|
||||
assert_parse_result(
|
||||
r#"#![doc(alias = "foo")]"#,
|
||||
DocAtom::KeyValue { key: "alias".into(), value: "foo".into() }.into(),
|
||||
);
|
||||
|
||||
assert_parse_result(r#"#![doc(alias("foo"))]"#, DocExpr::Alias(["foo".into()].into()));
|
||||
assert_parse_result(
|
||||
r#"#![doc(alias("foo", "bar", "baz"))]"#,
|
||||
DocExpr::Alias(["foo".into(), "bar".into(), "baz".into()].into()),
|
||||
);
|
||||
|
||||
assert_parse_result(
|
||||
r#"
|
||||
#[doc(alias("Bar", "Qux"))]
|
||||
struct Foo;"#,
|
||||
DocExpr::Alias(["Bar".into(), "Qux".into()].into()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
//! This module contains tests for doc-expression parsing.
|
||||
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
|
||||
|
||||
use triomphe::Arc;
|
||||
|
||||
use base_db::FileId;
|
||||
use hir_expand::span_map::{RealSpanMap, SpanMap};
|
||||
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode};
|
||||
use syntax::{ast, AstNode, TextRange};
|
||||
|
||||
use crate::attr::{DocAtom, DocExpr};
|
||||
|
||||
fn assert_parse_result(input: &str, expected: DocExpr) {
|
||||
let source_file = ast::SourceFile::parse(input, span::Edition::CURRENT).ok().unwrap();
|
||||
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
|
||||
let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
|
||||
let tt = syntax_node_to_token_tree(
|
||||
tt.syntax(),
|
||||
map.as_ref(),
|
||||
map.span_for_range(TextRange::empty(0.into())),
|
||||
DocCommentDesugarMode::ProcMacro,
|
||||
);
|
||||
let cfg = DocExpr::parse(&tt);
|
||||
assert_eq!(cfg, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_doc_expr_parser() {
|
||||
assert_parse_result("#![doc(hidden)]", DocAtom::Flag("hidden".into()).into());
|
||||
|
||||
assert_parse_result(
|
||||
r#"#![doc(alias = "foo")]"#,
|
||||
DocAtom::KeyValue { key: "alias".into(), value: "foo".into() }.into(),
|
||||
);
|
||||
|
||||
assert_parse_result(r#"#![doc(alias("foo"))]"#, DocExpr::Alias(["foo".into()].into()));
|
||||
assert_parse_result(
|
||||
r#"#![doc(alias("foo", "bar", "baz"))]"#,
|
||||
DocExpr::Alias(["foo".into(), "bar".into(), "baz".into()].into()),
|
||||
);
|
||||
|
||||
assert_parse_result(
|
||||
r#"
|
||||
#[doc(alias("Bar", "Qux"))]
|
||||
struct Foo;"#,
|
||||
DocExpr::Alias(["Bar".into(), "Qux".into()].into()),
|
||||
);
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ impl Body {
|
|||
db: &dyn DefDatabase,
|
||||
def: DefWithBodyId,
|
||||
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "body_with_source_map_query").entered();
|
||||
let _p = tracing::info_span!("body_with_source_map_query").entered();
|
||||
let mut params = None;
|
||||
|
||||
let mut is_async_fn = false;
|
||||
|
|
@ -395,6 +395,12 @@ impl BodySourceMap {
|
|||
self.expr_map.get(&src).copied()
|
||||
}
|
||||
|
||||
pub fn expansions(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&InFile<AstPtr<ast::MacroCall>>, &MacroFileId)> {
|
||||
self.expansions.iter()
|
||||
}
|
||||
|
||||
pub fn implicit_format_args(
|
||||
&self,
|
||||
node: InFile<&ast::FormatArgsExpr>,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use intern::Interned;
|
|||
use rustc_hash::FxHashMap;
|
||||
use smallvec::SmallVec;
|
||||
use span::AstIdMap;
|
||||
use stdx::never;
|
||||
use syntax::{
|
||||
ast::{
|
||||
self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasLoopBody, HasName,
|
||||
|
|
@ -480,7 +481,8 @@ impl ExprCollector<'_> {
|
|||
} else if e.const_token().is_some() {
|
||||
Mutability::Shared
|
||||
} else {
|
||||
unreachable!("parser only remaps to raw_token() if matching mutability token follows")
|
||||
never!("parser only remaps to raw_token() if matching mutability token follows");
|
||||
Mutability::Shared
|
||||
}
|
||||
} else {
|
||||
Mutability::from_mutable(e.mut_token().is_some())
|
||||
|
|
@ -963,7 +965,7 @@ impl ExprCollector<'_> {
|
|||
.resolve_path(
|
||||
self.db,
|
||||
module,
|
||||
&path,
|
||||
path,
|
||||
crate::item_scope::BuiltinShadowMode::Other,
|
||||
Some(MacroSubNs::Bang),
|
||||
)
|
||||
|
|
@ -1006,9 +1008,9 @@ impl ExprCollector<'_> {
|
|||
Some((mark, expansion)) => {
|
||||
// Keep collecting even with expansion errors so we can provide completions and
|
||||
// other services in incomplete macro expressions.
|
||||
self.source_map
|
||||
.expansions
|
||||
.insert(macro_call_ptr, self.expander.current_file_id().macro_file().unwrap());
|
||||
if let Some(macro_file) = self.expander.current_file_id().macro_file() {
|
||||
self.source_map.expansions.insert(macro_call_ptr, macro_file);
|
||||
}
|
||||
let prev_ast_id_map = mem::replace(
|
||||
&mut self.ast_id_map,
|
||||
self.db.ast_id_map(self.expander.current_file_id()),
|
||||
|
|
|
|||
|
|
@ -48,21 +48,30 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
|
|||
let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false };
|
||||
if let DefWithBodyId::FunctionId(it) = owner {
|
||||
p.buf.push('(');
|
||||
let params = &db.function_data(it).params;
|
||||
let mut params = params.iter();
|
||||
let function_data = &db.function_data(it);
|
||||
let (mut params, ret_type) = (function_data.params.iter(), &function_data.ret_type);
|
||||
if let Some(self_param) = body.self_param {
|
||||
p.print_binding(self_param);
|
||||
p.buf.push(':');
|
||||
p.buf.push_str(": ");
|
||||
if let Some(ty) = params.next() {
|
||||
p.print_type_ref(ty);
|
||||
p.buf.push_str(", ");
|
||||
}
|
||||
}
|
||||
body.params.iter().zip(params).for_each(|(¶m, ty)| {
|
||||
p.print_pat(param);
|
||||
p.buf.push(':');
|
||||
p.buf.push_str(": ");
|
||||
p.print_type_ref(ty);
|
||||
p.buf.push_str(", ");
|
||||
});
|
||||
// remove the last ", " in param list
|
||||
if body.params.len() > 0 {
|
||||
p.buf.truncate(p.buf.len() - 2);
|
||||
}
|
||||
p.buf.push(')');
|
||||
// return type
|
||||
p.buf.push_str(" -> ");
|
||||
p.print_type_ref(ret_type);
|
||||
p.buf.push(' ');
|
||||
}
|
||||
p.print_expr(body.body_expr);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue