Merge pull request #2840 from rust-lang/rustc-pull

Rustc pull update
This commit is contained in:
Tshepang Mbambo
2026-04-20 07:37:17 +02:00
committed by GitHub
1486 changed files with 334141 additions and 19382 deletions
+100 -266
View File
@@ -199,7 +199,7 @@ dependencies = [
"rustc-hash 2.1.1",
"serde",
"serde_derive",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -257,7 +257,7 @@ dependencies = [
"miniz_oxide",
"object 0.36.7",
"rustc-demangle",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@@ -396,7 +396,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -573,7 +573,6 @@ checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
"iana-time-zone",
"num-traits",
"serde",
"windows-link 0.2.1",
]
@@ -635,10 +634,10 @@ version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
dependencies = [
"heck 0.5.0",
"heck",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -649,11 +648,11 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]]
name = "clippy"
version = "0.1.96"
version = "0.1.97"
dependencies = [
"anstream",
"askama",
"cargo_metadata 0.18.1",
"cargo_metadata 0.23.1",
"clippy_config",
"clippy_lints",
"clippy_lints_internal",
@@ -676,7 +675,7 @@ dependencies = [
[[package]]
name = "clippy_config"
version = "0.1.96"
version = "0.1.97"
dependencies = [
"clippy_utils",
"itertools",
@@ -700,10 +699,10 @@ dependencies = [
[[package]]
name = "clippy_lints"
version = "0.1.96"
version = "0.1.97"
dependencies = [
"arrayvec",
"cargo_metadata 0.18.1",
"cargo_metadata 0.23.1",
"clippy_config",
"clippy_utils",
"declare_clippy_lint",
@@ -732,7 +731,7 @@ dependencies = [
[[package]]
name = "clippy_utils"
version = "0.1.96"
version = "0.1.97"
dependencies = [
"arrayvec",
"itertools",
@@ -757,7 +756,7 @@ checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681"
dependencies = [
"serde",
"termcolor",
"unicode-width 0.2.2",
"unicode-width 0.1.14",
]
[[package]]
@@ -768,7 +767,6 @@ dependencies = [
"serde",
"serde_json",
"similar",
"spdx-rs",
]
[[package]]
@@ -804,7 +802,7 @@ dependencies = [
"nom",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -827,21 +825,11 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "colored"
version = "2.2.0"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
dependencies = [
"lazy_static",
"windows-sys 0.59.0",
]
[[package]]
name = "colored"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -857,7 +845,7 @@ dependencies = [
"anstyle-svg",
"build_helper",
"camino",
"colored 2.2.0",
"colored",
"diff",
"getopts",
"glob",
@@ -881,15 +869,14 @@ dependencies = [
[[package]]
name = "console"
version = "0.15.11"
version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width 0.2.2",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -1047,7 +1034,7 @@ dependencies = [
"proc-macro2",
"quote",
"scratch",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1061,7 +1048,7 @@ dependencies = [
"indexmap",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1079,7 +1066,7 @@ dependencies = [
"indexmap",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1103,7 +1090,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1114,7 +1101,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1123,20 +1110,9 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
[[package]]
name = "dbus"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190b6255e8ab55a7b568df5a883e9497edc3e4821c06396612048b430e5ad1e9"
dependencies = [
"libc",
"libdbus-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "declare_clippy_lint"
version = "0.1.96"
version = "0.1.97"
[[package]]
name = "derive-where"
@@ -1146,7 +1122,7 @@ checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1167,7 +1143,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1177,7 +1153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1189,7 +1165,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1264,7 +1240,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -1404,14 +1380,13 @@ dependencies = [
[[package]]
name = "filetime"
version = "0.2.26"
version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db"
dependencies = [
"cfg-if",
"libc",
"libredox",
"windows-sys 0.60.2",
]
[[package]]
@@ -1678,10 +1653,13 @@ dependencies = [
]
[[package]]
name = "heck"
version = "0.4.1"
name = "hashbrown"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
dependencies = [
"foldhash 0.2.0",
]
[[package]]
name = "heck"
@@ -1953,26 +1931,26 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
[[package]]
name = "indexmap"
version = "2.13.0"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
"hashbrown 0.17.0",
"serde",
"serde_core",
]
[[package]]
name = "indicatif"
version = "0.17.11"
version = "0.18.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb"
dependencies = [
"console",
"number_prefix",
"portable-atomic",
"unicode-width 0.2.2",
"unit-prefix",
"web-time",
]
@@ -2083,7 +2061,7 @@ checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -2180,16 +2158,6 @@ version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "libdbus-sys"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cbe856efeb50e4681f010e9aaa2bf0a644e10139e54cde10fc83a307c23bd9f"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "libffi"
version = "5.1.0"
@@ -2380,7 +2348,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -2483,7 +2451,7 @@ dependencies = [
"capstone",
"chrono",
"chrono-tz",
"colored 3.0.0",
"colored",
"directories",
"genmc-sys",
"getrandom 0.3.3",
@@ -2525,7 +2493,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -2657,12 +2625,6 @@ dependencies = [
"libc",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "objc2"
version = "0.6.3"
@@ -2749,14 +2711,13 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "opener"
version = "0.7.2"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0812e5e4df08da354c851a3376fead46db31c2214f849d3de356d774d057681"
checksum = "a2fa337e0cf13357c13ef1dc108df1333eb192f75fc170bea03fcf1fd404c2ee"
dependencies = [
"bstr",
"dbus",
"normpath",
"windows-sys 0.59.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -2906,7 +2867,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -3000,9 +2961,9 @@ dependencies = [
[[package]]
name = "portable-atomic"
version = "1.11.1"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
[[package]]
name = "portable-atomic-util"
@@ -3116,7 +3077,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -3307,7 +3268,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -3400,7 +3361,7 @@ checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -3806,7 +3767,7 @@ dependencies = [
"either",
"elsa",
"ena",
"hashbrown 0.16.1",
"hashbrown 0.17.0",
"indexmap",
"jobserver",
"libc",
@@ -3995,6 +3956,7 @@ dependencies = [
"rustc_ast_pretty",
"rustc_data_structures",
"rustc_error_messages",
"rustc_errors",
"rustc_hashes",
"rustc_hir_id",
"rustc_index",
@@ -4115,7 +4077,7 @@ version = "0.0.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -4261,7 +4223,7 @@ dependencies = [
"fluent-syntax",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
"synstructure",
]
@@ -4569,7 +4531,6 @@ name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
"measureme",
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
@@ -4843,7 +4804,7 @@ version = "0.0.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
"synstructure",
]
@@ -4943,7 +4904,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5060,7 +5021,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5146,7 +5107,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5157,7 +5118,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5271,12 +5232,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.6.1"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys 0.60.2",
"windows-sys 0.61.2",
]
[[package]]
@@ -5290,35 +5251,6 @@ dependencies = [
"color-eyre",
]
[[package]]
name = "spdx-expression"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d7ac03c67c572d85049d6db815e20a4a19b41b3d5cca732ac582342021ad77"
dependencies = [
"nom",
"serde",
"thiserror 1.0.69",
"tracing",
]
[[package]]
name = "spdx-rs"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990870190ec8d8c64ba66e4a6746243d6e57d99353991e0e6092334833f429b1"
dependencies = [
"chrono",
"log",
"nom",
"serde",
"spdx-expression",
"strum",
"strum_macros",
"thiserror 1.0.69",
"uuid",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.1"
@@ -5384,36 +5316,6 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
[[package]]
name = "strum_macros"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"rustversion",
"syn 1.0.109",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.110"
@@ -5433,7 +5335,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5570,7 +5472,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5581,7 +5483,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5823,7 +5725,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -5956,9 +5858,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "ui_test"
version = "0.30.3"
version = "0.30.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44eb652e1a8799d4e47f20851370e86247cbc5270ce677ab1e9409a6d45a9649"
checksum = "ada249620d81f010b9a1472b63a5077ac7c722dd0f4bacf6528b313d0b8c15d8"
dependencies = [
"annotate-snippets 0.11.5",
"anyhow",
@@ -5966,7 +5868,7 @@ dependencies = [
"cargo-platform 0.1.9",
"cargo_metadata 0.18.1",
"color-eyre",
"colored 3.0.0",
"colored",
"comma",
"crossbeam-channel",
"indicatif",
@@ -6019,7 +5921,7 @@ checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5"
dependencies = [
"proc-macro-hack",
"quote",
"syn 2.0.110",
"syn",
"unic-langid-impl",
]
@@ -6106,6 +6008,12 @@ dependencies = [
"diff",
]
[[package]]
name = "unit-prefix"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3"
[[package]]
name = "unstable-book-gen"
version = "0.1.0"
@@ -6257,7 +6165,7 @@ dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
"wasm-bindgen-shared",
]
@@ -6514,7 +6422,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -6525,7 +6433,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -6602,16 +6510,7 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.5",
"windows-targets",
]
[[package]]
@@ -6629,31 +6528,14 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link 0.2.1",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
@@ -6680,96 +6562,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.5.40"
@@ -6895,7 +6729,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
"synstructure",
]
@@ -6916,7 +6750,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
@@ -6936,7 +6770,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
"synstructure",
]
@@ -6971,7 +6805,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.110",
"syn",
]
[[package]]
+17 -11
View File
@@ -1,5 +1,5 @@
Version 1.95 (2026-04-16)
==========================
Version 1.95.0 (2026-04-16)
===========================
<a id="1.95-Language"></a>
@@ -18,8 +18,9 @@ Language
Compiler
--------
- [Stabilize `--remap-path-scope` for controlling the scoping of how paths get remapped in the resulting binary](https://github.com/rust-lang/rust/pull/147611)
- [Stabilize `--remap-path-scope` for controlling the scoping of how paths get remapped in the resulting binary](https://github.com/rust-lang/rust/pull/147611)
- [Apply patches for CVE-2026-6042 and CVE-2026-40200 to vendored musl](https://github.com/rust-lang/rust/pull/155171)
<a id="1.95-Platform-Support"></a>
@@ -78,7 +79,17 @@ Stabilized APIs
- [`<*const T>::as_ref_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked)
- [`<*mut T>::as_ref_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_ref_unchecked-1)
- [`<*mut T>::as_mut_unchecked`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_mut_unchecked)
- [`Vec::push_mut`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.push_mut)
- [`Vec::insert_mut`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.insert_mut)
- [`VecDeque::push_front_mut`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.push_front_mut)
- [`VecDeque::push_back_mut`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.push_back_mut)
- [`VecDeque::insert_mut`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.insert_mut)
- [`LinkedList::push_front_mut`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.push_front_mut)
- [`LinkedList::push_back_mut`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.push_back_mut)
- [`Layout::dangling_ptr`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.dangling_ptr)
- [`Layout::repeat`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.repeat)
- [`Layout::repeat_packed`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.repeat_packed)
- [`Layout::extend_packed`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.extend_packed)
These previously stable APIs are now stable in const contexts:
@@ -86,17 +97,13 @@ These previously stable APIs are now stable in const contexts:
- [`ControlFlow::is_break`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_break)
- [`ControlFlow::is_continue`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.is_continue)
<a id="1.95-Cargo"></a>
Cargo
-----
- [docs(report): enhance man pages for `cargo report *`](https://github.com/rust-lang/cargo/pull/16430/)<a id="1.95-Rustdoc"></a>
<a id="1.95-Rustdoc"></a>
Rustdoc
-----
- [In search results, rank unstable items lower](https://github.com/rust-lang/rust/pull/149460)
- [Add new "hide deprecated items" setting in rustdoc](https://github.com/rust-lang/rust/pull/151091)
<a id="1.95-Compatibility-Notes"></a>
Compatibility Notes
@@ -116,7 +123,6 @@ Compatibility Notes
- [JSON target specs](https://doc.rust-lang.org/rustc/targets/custom.html) have been destabilized and now require `-Z unstable-options` to use. Previously, they could not be used without the standard library, which has no stable build mechanism. In preparation for the `build-std` project adding that support, JSON target specs are being proactively gated to ensure they remain unstable even if `build-std` is stabilized. Cargo now includes the `-Z json-target-spec` CLI flag to automatically pass `-Z unstable-options` to the compiler when needed. See [#150151](https://github.com/rust-lang/rust/pull/150151), [#151534](https://github.com/rust-lang/rust/pull/150151), and [rust-lang/cargo#16557](https://github.com/rust-lang/cargo/pull/16557).
- [The arguments of `#[feature]` attributes on invalid targets are now checked](https://github.com/rust-lang/rust/issues/153764)
<a id="1.95-Internal-Changes"></a>
Internal Changes
+3 -2
View File
@@ -75,10 +75,11 @@ pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, H
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
}
BackendRepr::SimdVector { .. } => {
BackendRepr::SimdVector { element, count: _ } => {
assert!(!self.is_zst());
Ok(HomogeneousAggregate::Homogeneous(Reg {
kind: RegKind::Vector,
kind: RegKind::Vector { hint_vector_elem: element.primitive() },
size: self.size,
}))
}
+14 -3
View File
@@ -1,14 +1,19 @@
#[cfg(feature = "nightly")]
use rustc_macros::HashStable_Generic;
use crate::{Align, HasDataLayout, Size};
use crate::{Align, HasDataLayout, Integer, Primitive, Size};
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum RegKind {
Integer,
Float,
Vector,
Vector {
/// The `hint_vector_elem` is strictly for optimization purposes. E.g. it can be used by
/// a codegen backend to prevent extra bitcasts that obscure a pattern. Alternatively,
/// it can be safely ignored by always picking i8.
hint_vector_elem: Primitive,
},
}
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
@@ -36,6 +41,12 @@ impl Reg {
reg_ctor!(f32, Float, 32);
reg_ctor!(f64, Float, 64);
reg_ctor!(f128, Float, 128);
/// A vector of the given size with an unknown (and irrelevant) element type.
pub fn opaque_vector(size: Size) -> Reg {
// Default to an i8 vector of the given size.
Reg { kind: RegKind::Vector { hint_vector_elem: Primitive::Int(Integer::I8, true) }, size }
}
}
impl Reg {
@@ -58,7 +69,7 @@ pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
128 => dl.f128_align,
_ => panic!("unsupported float: {self:?}"),
},
RegKind::Vector => dl.llvmlike_vector_align(self.size),
RegKind::Vector { .. } => dl.llvmlike_vector_align(self.size),
}
}
}
+23
View File
@@ -131,6 +131,29 @@ pub const fn as_str(&self) -> &'static str {
$($e_name::$variant $( { unwind: $uw } )* => $tok,)*
}
}
// FIXME(FnSigKind): when PartialEq is stably const, use it instead
const fn internal_const_eq(&self, other: &Self) -> bool {
match (self, other) {
$( ( $e_name::$variant $( { unwind: $uw } )* , $e_name::$variant $( { unwind: $uw } )* ) => true,)*
_ => false,
}
}
// ALL_VARIANTS.iter().position(|v| v == self), but const
pub const fn as_packed(&self) -> u8 {
let mut index = 0;
while index < $e_name::ALL_VARIANTS.len() {
if self.internal_const_eq(&$e_name::ALL_VARIANTS[index]) {
return index as u8;
}
index += 1;
}
panic!("unreachable: invalid ExternAbi variant");
}
pub const fn from_packed(index: u8) -> Self {
let index = index as usize;
assert!(index < $e_name::ALL_VARIANTS.len(), "invalid ExternAbi index");
$e_name::ALL_VARIANTS[index]
}
}
impl ::core::str::FromStr for $e_name {
+12 -24
View File
@@ -140,25 +140,19 @@ impl<T> TypedArena<T> {
/// Allocates an object in the `TypedArena`, returning a reference to it.
#[inline]
pub fn alloc(&self, object: T) -> &mut T {
assert!(size_of::<T>() != 0);
if self.ptr == self.end {
self.grow(1)
}
unsafe {
if size_of::<T>() == 0 {
self.ptr.set(self.ptr.get().wrapping_byte_add(1));
let ptr = ptr::NonNull::<T>::dangling().as_ptr();
// Don't drop the object. This `write` is equivalent to `forget`.
ptr::write(ptr, object);
&mut *ptr
} else {
let ptr = self.ptr.get();
// Advance the pointer.
self.ptr.set(self.ptr.get().add(1));
// Write into uninitialized memory.
ptr::write(ptr, object);
&mut *ptr
}
let ptr = self.ptr.get();
// Advance the pointer.
self.ptr.set(self.ptr.get().add(1));
// Write into uninitialized memory.
ptr::write(ptr, object);
&mut *ptr
}
}
@@ -302,16 +296,10 @@ fn clear_last_chunk(&self, last_chunk: &mut ArenaChunk<T>) {
let end = self.ptr.get().addr();
// We then calculate the number of elements to be dropped in the last chunk,
// which is the filled area's length.
let diff = if size_of::<T>() == 0 {
// `T` is ZST. It can't have a drop flag, so the value here doesn't matter. We get
// the number of zero-sized values in the last and only chunk, just out of caution.
// Recall that `end` was incremented for each allocated value.
end - start
} else {
// FIXME: this should *likely* use `offset_from`, but more
// investigation is needed (including running tests in miri).
(end - start) / size_of::<T>()
};
assert_ne!(size_of::<T>(), 0);
// FIXME: this should *likely* use `offset_from`, but more
// investigation is needed (including running tests in miri).
let diff = (end - start) / size_of::<T>();
// Pass that to the `destroy` method.
unsafe {
last_chunk.destroy(diff);
+3 -15
View File
@@ -22,7 +22,6 @@ fn clear(&mut self) {
if let Some(last_chunk) = chunks_borrow.last_mut() {
self.clear_last_chunk(last_chunk);
let len = chunks_borrow.len();
// If `T` is ZST, code below has no effect.
for mut chunk in chunks_borrow.drain(..len - 1) {
chunk.destroy(chunk.entries);
}
@@ -117,18 +116,6 @@ fn test_noncopy() {
}
}
#[test]
fn test_typed_arena_zero_sized() {
let arena = TypedArena::default();
#[cfg(not(miri))]
const N: usize = 100000;
#[cfg(miri)]
const N: usize = 1000;
for _ in 0..N {
arena.alloc(());
}
}
#[test]
fn test_typed_arena_clear() {
let mut arena = TypedArena::default();
@@ -207,7 +194,8 @@ fn test_typed_arena_drop_on_clear() {
static DROP_COUNTER: Cell<u32> = Cell::new(0)
}
struct SmallDroppable;
#[allow(unused)]
struct SmallDroppable(u8);
impl Drop for SmallDroppable {
fn drop(&mut self) {
@@ -222,7 +210,7 @@ fn test_typed_arena_drop_small_count() {
let arena: TypedArena<SmallDroppable> = TypedArena::default();
for _ in 0..100 {
// Allocate something with drop glue to make sure it doesn't leak.
arena.alloc(SmallDroppable);
arena.alloc(SmallDroppable(0));
}
// dropping
};
+7 -2
View File
@@ -3901,12 +3901,17 @@ pub struct Delegation {
pub from_glob: bool,
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum DelegationSuffixes {
List(ThinVec<(Ident, Option<Ident>)>),
Glob(Span),
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct DelegationMac {
pub qself: Option<Box<QSelf>>,
pub prefix: Path,
// Some for list delegation, and None for glob delegation.
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
pub suffixes: DelegationSuffixes,
pub body: Option<Box<Block>>,
}
+1
View File
@@ -430,6 +430,7 @@ pub fn ctxt(&self) -> Option<FnCtxt> {
Defaultness,
Delegation,
DelegationMac,
DelegationSuffixes,
DelimArgs,
DelimSpan,
EnumDef,
+8 -14
View File
@@ -46,9 +46,9 @@
use rustc_ast::*;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::attrs::{AttributeKind, InlineAttr};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, FnDeclFlags};
use rustc_middle::span_bug;
use rustc_middle::ty::Asyncness;
use rustc_span::symbol::kw;
@@ -271,7 +271,7 @@ fn get_resolution_id(&self, node_id: NodeId) -> Option<DefId> {
// Function parameter count, including C variadic `...` if present.
fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) {
let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();
(sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic)
(sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic())
}
fn lower_delegation_decl(
@@ -309,9 +309,9 @@ fn lower_delegation_decl(
self.arena.alloc(hir::FnDecl {
inputs,
output: hir::FnRetTy::Return(output),
c_variadic,
lifetime_elision_allowed: true,
implicit_self: hir::ImplicitSelfKind::None,
fn_decl_kind: FnDeclFlags::default()
.set_lifetime_elision_allowed(true)
.set_c_variadic(c_variadic),
})
}
@@ -331,11 +331,11 @@ fn lower_delegation_sig(
safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features {
hir::HeaderSafety::SafeTargetFeatures
} else {
hir::HeaderSafety::Normal(sig.safety)
hir::HeaderSafety::Normal(sig.safety())
},
constness: self.tcx.constness(sig_id),
asyncness,
abi: sig.abi,
abi: sig.abi(),
};
hir::FnSig { decl, header, span }
@@ -603,13 +603,7 @@ fn generate_delegation_error(
span: Span,
delegation: &Delegation,
) -> DelegationResults<'hir> {
let decl = self.arena.alloc(hir::FnDecl {
inputs: &[],
output: hir::FnRetTy::DefaultReturn(span),
c_variadic: false,
lifetime_elision_allowed: true,
implicit_self: hir::ImplicitSelfKind::None,
});
let decl = self.arena.alloc(hir::FnDecl::dummy(span));
let header = self.generate_header_error();
let sig = hir::FnSig { decl, header, span };
@@ -295,10 +295,9 @@ fn uplift_delegation_generic_params(
let param_ident = Ident::new(p.name, span);
let def_name = Some(param_ident.name);
let path_data = def_kind.def_path_data(def_name);
let node_id = self.next_node_id();
let def_id = self.create_def(node_id, def_name, def_kind, path_data, span);
let def_id = self.create_def(node_id, def_name, def_kind, span);
let kind = match p.kind {
GenericParamDefKind::Lifetime => {
+15 -24
View File
@@ -8,7 +8,6 @@
use rustc_errors::msg;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::definitions::DefPathData;
use rustc_hir::{HirId, Target, find_attr};
use rustc_middle::span_bug;
use rustc_middle::ty::TyCtxt;
@@ -29,7 +28,7 @@
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope};
struct WillCreateDefIdsVisitor {}
pub(super) struct WillCreateDefIdsVisitor;
impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor {
type Result = ControlFlow<Span>;
@@ -472,25 +471,19 @@ fn lower_legacy_const_generics(
for (idx, arg) in args.iter().cloned().enumerate() {
if legacy_args_idx.contains(&idx) {
let node_id = self.next_node_id();
self.create_def(
node_id,
None,
DefKind::AnonConst,
DefPathData::LateAnonConst,
f.span,
);
let mut visitor = WillCreateDefIdsVisitor {};
let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
Box::new(Expr {
id: self.next_node_id(),
kind: ExprKind::Err(invalid_expr_error(self.tcx, span)),
span: f.span,
attrs: [].into(),
tokens: None,
})
} else {
arg
};
self.create_def(node_id, None, DefKind::AnonConst, f.span);
let const_value =
if let ControlFlow::Break(span) = WillCreateDefIdsVisitor.visit_expr(&arg) {
Box::new(Expr {
id: self.next_node_id(),
kind: ExprKind::Err(invalid_expr_error(self.tcx, span)),
span: f.span,
attrs: [].into(),
tokens: None,
})
} else {
arg
};
let anon_const = AnonConst {
id: node_id,
@@ -762,9 +755,7 @@ pub(super) fn make_desugared_coroutine_expr(
let fn_decl = self.arena.alloc(hir::FnDecl {
inputs,
output,
c_variadic: false,
implicit_self: hir::ImplicitSelfKind::None,
lifetime_elision_allowed: false,
fn_decl_kind: hir::FnDeclFlags::default(),
});
let body = self.lower_body(move |this| {
+70 -46
View File
@@ -39,8 +39,9 @@
use std::sync::Arc;
use rustc_ast::node_id::NodeMap;
use rustc_ast::visit::Visitor;
use rustc_ast::{self as ast, *};
use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
use rustc_attr_parsing::{AttributeParser, EmitAttribute, Late, OmitDoc};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::sorted_map::SortedMap;
@@ -50,8 +51,8 @@
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
use rustc_hir::lints::{AttributeLint, DelayedLint};
use rustc_hir::definitions::PerParentDisambiguatorState;
use rustc_hir::lints::{AttributeLint, DelayedLint, DynAttribute};
use rustc_hir::{
self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,
@@ -93,7 +94,7 @@ macro_rules! arena_vec {
struct LoweringContext<'a, 'hir, R> {
tcx: TyCtxt<'hir>,
resolver: &'a mut R,
disambiguator: DisambiguatorState,
disambiguator: PerParentDisambiguatorState,
/// Used to allocate HIR nodes.
arena: &'hir hir::Arena<'hir>,
@@ -158,7 +159,7 @@ fn new(tcx: TyCtxt<'hir>, resolver: &'a mut R) -> Self {
Self {
tcx,
resolver,
disambiguator: DisambiguatorState::new(),
disambiguator: Default::default(),
arena: tcx.hir_arena,
// HirId handling.
@@ -301,6 +302,10 @@ fn trait_candidates(&self, node_id: NodeId) -> Option<&'tcx [hir::TraitCandidate
fn next_node_id(&mut self) -> NodeId {
next_node_id(&mut self.next_node_id)
}
fn steal_or_create_disambiguator(&self, parent: LocalDefId) -> PerParentDisambiguatorState {
self.base.steal_or_create_disambiguator(parent)
}
}
fn next_node_id(current_id: &mut NodeId) -> NodeId {
@@ -403,6 +408,10 @@ fn trait_candidates(&self, node_id: NodeId) -> Option<&'tcx [hir::TraitCandidate
fn next_node_id(&mut self) -> NodeId {
next_node_id(&mut self.next_node_id)
}
fn steal_or_create_disambiguator(&self, parent: LocalDefId) -> PerParentDisambiguatorState {
self.per_parent_disambiguators.get(&parent).map(|s| s.steal()).unwrap_or_default()
}
}
/// How relaxed bounds `?Trait` should be treated.
@@ -716,7 +725,6 @@ fn create_def(
node_id: ast::NodeId,
name: Option<Symbol>,
def_kind: DefKind,
def_path_data: DefPathData,
span: Span,
) -> LocalDefId {
let parent = self.current_hir_id_owner.def_id;
@@ -732,7 +740,7 @@ fn create_def(
let def_id = self
.tcx
.at(span)
.create_def(parent, name, def_kind, Some(def_path_data), &mut self.disambiguator)
.create_def(parent, name, def_kind, None, &mut self.disambiguator)
.def_id();
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
@@ -773,6 +781,8 @@ fn with_hir_id_owner(
) {
let owner_id = self.owner_id(owner);
let new_disambig = self.resolver.steal_or_create_disambiguator(owner_id.def_id);
let disambiguator = std::mem::replace(&mut self.disambiguator, new_disambig);
let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies);
let current_define_opaque = std::mem::take(&mut self.define_opaque);
@@ -807,6 +817,7 @@ fn with_hir_id_owner(
assert!(self.impl_trait_bounds.is_empty());
let info = self.make_owner_info(item);
self.disambiguator = disambiguator;
self.attrs = current_attrs;
self.bodies = current_bodies;
self.define_opaque = current_define_opaque;
@@ -846,14 +857,12 @@ fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInf
let bodies = SortedMap::from_presorted_elements(bodies);
// Don't hash unless necessary, because it's expensive.
let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash, delayed_lints_hash } =
self.tcx.hash_owner_nodes(node, &bodies, &attrs, &delayed_lints, define_opaque);
let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash } =
self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);
let num_nodes = self.item_local_id_counter.as_usize();
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
let delayed_lints =
hir::lints::DelayedLints { lints: delayed_lints, opt_hash: delayed_lints_hash };
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, delayed_lints })
}
@@ -1014,7 +1023,6 @@ fn lifetime_res_to_generic_param(
param,
Some(kw::UnderscoreLifetime),
DefKind::LifetimeParam,
DefPathData::DesugaredAnonymousLifetime,
ident.span,
);
debug!(?_def_id);
@@ -1166,13 +1174,23 @@ fn lower_attrs_vec(
target,
OmitDoc::Lower,
|s| l.lower(s),
|lint_id, span, kind| {
self.delayed_lints.push(DelayedLint::AttributeParsing(AttributeLint {
lint_id,
id: target_hir_id,
span,
kind,
}));
|lint_id, span, kind| match kind {
EmitAttribute::Static(attr_kind) => {
self.delayed_lints.push(DelayedLint::AttributeParsing(AttributeLint {
lint_id,
id: target_hir_id,
span,
kind: attr_kind,
}));
}
EmitAttribute::Dynamic(callback) => {
self.delayed_lints.push(DelayedLint::Dynamic(DynAttribute {
lint_id,
id: target_hir_id,
span,
callback,
}));
}
},
)
}
@@ -1831,7 +1849,7 @@ fn lower_fn_decl(
// as they are not explicit in HIR/Ty function signatures.
// (instead, the `c_variadic` flag is set to `true`)
let mut inputs = &decl.inputs[..];
if c_variadic {
if decl.c_variadic() {
inputs = &inputs[..inputs.len() - 1];
}
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
@@ -1894,12 +1912,8 @@ fn lower_fn_decl(
},
};
self.arena.alloc(hir::FnDecl {
inputs,
output,
c_variadic,
lifetime_elision_allowed: self.resolver.lifetime_elision_allowed(fn_node_id),
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
let fn_decl_kind = hir::FnDeclFlags::default()
.set_implicit_self(decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
let is_mutable_pat = matches!(
arg.pat.kind,
PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
@@ -1921,8 +1935,11 @@ fn lower_fn_decl(
}
_ => hir::ImplicitSelfKind::None,
}
}),
})
}))
.set_lifetime_elision_allowed(self.resolver.lifetime_elision_allowed(fn_node_id))
.set_c_variadic(c_variadic);
self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind })
}
// Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
@@ -2219,14 +2236,22 @@ fn lower_generic_param_kind(
// since later compiler stages cannot handle them (and shouldn't need to be able to).
let default = default
.as_ref()
.filter(|_| match source {
.filter(|anon_const| match source {
hir::GenericParamSource::Generics => true,
hir::GenericParamSource::Binder => {
self.dcx().emit_err(errors::GenericParamDefaultInBinder {
span: param.span(),
});
false
let err = errors::GenericParamDefaultInBinder { span: param.span() };
if expr::WillCreateDefIdsVisitor
.visit_expr(&anon_const.value)
.is_break()
{
// FIXME(mgca): make this non-fatal once we have a better way
// to handle nested items in anno const from binder
// Issue: https://github.com/rust-lang/rust/issues/123629
self.dcx().emit_fatal(err)
} else {
self.dcx().emit_err(err);
false
}
}
})
.map(|def| self.lower_anon_const_to_const_arg_and_alloc(def));
@@ -2495,13 +2520,7 @@ fn lower_const_path_to_const_arg(
// We're lowering a const argument that was originally thought to be a type argument,
// so the def collector didn't create the def ahead of time. That's why we have to do
// it here.
let def_id = self.create_def(
node_id,
None,
DefKind::AnonConst,
DefPathData::LateAnonConst,
span,
);
let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
let hir_id = self.lower_node_id(node_id);
let path_expr = Expr {
@@ -2563,12 +2582,17 @@ fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir>
let span = self.lower_span(expr.span);
let overly_complex_const = |this: &mut Self| {
let e = this.dcx().struct_span_err(
expr.span,
"complex const arguments must be placed inside of a `const` block",
);
let msg = "complex const arguments must be placed inside of a `const` block";
let e = if expr::WillCreateDefIdsVisitor.visit_expr(expr).is_break() {
// FIXME(mgca): make this non-fatal once we have a better way to handle
// nested items in const args
// Issue: https://github.com/rust-lang/rust/issues/154539
this.dcx().struct_span_fatal(expr.span, msg).emit()
} else {
this.dcx().struct_span_err(expr.span, msg).emit()
};
ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e.emit()), span }
ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e), span }
};
match &expr.kind {
+1 -3
View File
@@ -3,7 +3,6 @@
use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::definitions::DefPathData;
use rustc_hir::{self as hir, LangItem, Target};
use rustc_middle::span_bug;
use rustc_span::{DesugaringKind, Ident, Span, Spanned, respan};
@@ -538,8 +537,7 @@ fn lower_ty_pat_range_end(
// We're generating a range end that didn't exist in the AST,
// so the def collector didn't create the def ahead of time. That's why we have to do
// it here.
let def_id =
self.create_def(node_id, None, DefKind::AnonConst, DefPathData::LateAnonConst, span);
let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
let hir_id = self.lower_node_id(node_id);
let unstable_span = self.mark_span_with_reason(
@@ -7,7 +7,7 @@
use rustc_hir::attrs::AttributeKind;
use rustc_session::Session;
use rustc_session::parse::{feature_err, feature_warn};
use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, sym};
use rustc_span::{Span, Spanned, Symbol, sym};
use thin_vec::ThinVec;
use crate::errors;
@@ -646,14 +646,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
let mut errored = false;
if let Some(Attribute::Parsed(AttributeKind::Feature(feature_idents, first_span))) =
AttributeParser::parse_limited(
sess,
&krate.attrs,
&[sym::feature],
DUMMY_SP,
krate.id,
Some(&features),
)
AttributeParser::parse_limited(sess, &krate.attrs, &[sym::feature])
{
// `feature(...)` used on non-nightly. This is definitely an error.
let mut err = errors::FeatureOnNonNightly {
-49
View File
@@ -1,49 +0,0 @@
use std::borrow::Cow;
use crate::pp::Printer;
impl Printer {
pub fn word_space<W: Into<Cow<'static, str>>>(&mut self, w: W) {
self.word(w);
self.space();
}
pub fn popen(&mut self) {
self.word("(");
}
pub fn pclose(&mut self) {
self.word(")");
}
pub fn hardbreak_if_not_bol(&mut self) {
if !self.is_beginning_of_line() {
self.hardbreak()
}
}
pub fn space_if_not_bol(&mut self) {
if !self.is_beginning_of_line() {
self.space();
}
}
pub fn nbsp(&mut self) {
self.word(" ")
}
pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) {
self.word(w);
self.nbsp()
}
/// Synthesizes a comment that was not textually present in the original
/// source file.
pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) {
self.word("/*");
self.space();
self.word(text);
self.space();
self.word("*/")
}
}
-1
View File
@@ -3,6 +3,5 @@
#![feature(negative_impls)]
// tidy-alphabetical-end
mod helpers;
pub mod pp;
pub mod pprust;
+134 -1
View File
@@ -132,7 +132,6 @@
//! methods called `Printer::scan_*`, and the 'PRINT' process is the
//! method called `Printer::print`.
mod convenience;
mod ring;
use std::borrow::Cow;
@@ -188,6 +187,12 @@ pub(crate) enum Token {
End,
}
impl Token {
pub(crate) fn is_hardbreak_tok(&self) -> bool {
*self == Printer::hardbreak_tok_offset(0)
}
}
#[derive(Copy, Clone)]
enum PrintFrame {
Fits,
@@ -479,4 +484,132 @@ fn print_string(&mut self, string: &str) {
self.out.push_str(string);
self.space -= string.len() as isize;
}
/// Synthesizes a comment that was not textually present in the original
/// source file.
pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) {
self.word("/*");
self.space();
self.word(text);
self.space();
self.word("*/")
}
/// "raw box"
pub fn rbox(&mut self, indent: isize, breaks: Breaks) -> BoxMarker {
self.scan_begin(BeginToken { indent: IndentStyle::Block { offset: indent }, breaks })
}
/// Inconsistent breaking box
pub fn ibox(&mut self, indent: isize) -> BoxMarker {
self.rbox(indent, Breaks::Inconsistent)
}
/// Consistent breaking box
pub fn cbox(&mut self, indent: isize) -> BoxMarker {
self.rbox(indent, Breaks::Consistent)
}
pub fn visual_align(&mut self) -> BoxMarker {
self.scan_begin(BeginToken { indent: IndentStyle::Visual, breaks: Breaks::Consistent })
}
pub fn break_offset(&mut self, n: usize, off: isize) {
self.scan_break(BreakToken {
offset: off,
blank_space: n as isize,
..BreakToken::default()
});
}
pub fn end(&mut self, b: BoxMarker) {
self.scan_end(b)
}
pub fn eof(mut self) -> String {
self.scan_eof();
self.out
}
pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) {
let string = wrd.into();
self.scan_string(string)
}
pub fn word_space<W: Into<Cow<'static, str>>>(&mut self, w: W) {
self.word(w);
self.space();
}
pub fn nbsp(&mut self) {
self.word(" ")
}
pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) {
self.word(w);
self.nbsp()
}
fn spaces(&mut self, n: usize) {
self.break_offset(n, 0)
}
pub fn zerobreak(&mut self) {
self.spaces(0)
}
pub fn space(&mut self) {
self.spaces(1)
}
pub fn popen(&mut self) {
self.word("(");
}
pub fn pclose(&mut self) {
self.word(")");
}
pub fn hardbreak(&mut self) {
self.spaces(SIZE_INFINITY as usize)
}
pub fn is_beginning_of_line(&self) -> bool {
match self.last_token() {
Some(last_token) => last_token.is_hardbreak_tok(),
None => true,
}
}
pub fn hardbreak_if_not_bol(&mut self) {
if !self.is_beginning_of_line() {
self.hardbreak()
}
}
pub fn space_if_not_bol(&mut self) {
if !self.is_beginning_of_line() {
self.space();
}
}
pub(crate) fn hardbreak_tok_offset(off: isize) -> Token {
Token::Break(BreakToken {
offset: off,
blank_space: SIZE_INFINITY,
..BreakToken::default()
})
}
pub fn trailing_comma(&mut self) {
self.scan_break(BreakToken { pre_break: Some(','), ..BreakToken::default() });
}
pub fn trailing_comma_or_space(&mut self) {
self.scan_break(BreakToken {
blank_space: 1,
pre_break: Some(','),
..BreakToken::default()
});
}
}
@@ -1,97 +0,0 @@
use std::borrow::Cow;
use crate::pp::{
BeginToken, BoxMarker, BreakToken, Breaks, IndentStyle, Printer, SIZE_INFINITY, Token,
};
impl Printer {
/// "raw box"
pub fn rbox(&mut self, indent: isize, breaks: Breaks) -> BoxMarker {
self.scan_begin(BeginToken { indent: IndentStyle::Block { offset: indent }, breaks })
}
/// Inconsistent breaking box
pub fn ibox(&mut self, indent: isize) -> BoxMarker {
self.rbox(indent, Breaks::Inconsistent)
}
/// Consistent breaking box
pub fn cbox(&mut self, indent: isize) -> BoxMarker {
self.rbox(indent, Breaks::Consistent)
}
pub fn visual_align(&mut self) -> BoxMarker {
self.scan_begin(BeginToken { indent: IndentStyle::Visual, breaks: Breaks::Consistent })
}
pub fn break_offset(&mut self, n: usize, off: isize) {
self.scan_break(BreakToken {
offset: off,
blank_space: n as isize,
..BreakToken::default()
});
}
pub fn end(&mut self, b: BoxMarker) {
self.scan_end(b)
}
pub fn eof(mut self) -> String {
self.scan_eof();
self.out
}
pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) {
let string = wrd.into();
self.scan_string(string)
}
fn spaces(&mut self, n: usize) {
self.break_offset(n, 0)
}
pub fn zerobreak(&mut self) {
self.spaces(0)
}
pub fn space(&mut self) {
self.spaces(1)
}
pub fn hardbreak(&mut self) {
self.spaces(SIZE_INFINITY as usize)
}
pub fn is_beginning_of_line(&self) -> bool {
match self.last_token() {
Some(last_token) => last_token.is_hardbreak_tok(),
None => true,
}
}
pub(crate) fn hardbreak_tok_offset(off: isize) -> Token {
Token::Break(BreakToken {
offset: off,
blank_space: SIZE_INFINITY,
..BreakToken::default()
})
}
pub fn trailing_comma(&mut self) {
self.scan_break(BreakToken { pre_break: Some(','), ..BreakToken::default() });
}
pub fn trailing_comma_or_space(&mut self) {
self.scan_break(BreakToken {
blank_space: 1,
pre_break: Some(','),
..BreakToken::default()
});
}
}
impl Token {
pub(crate) fn is_hardbreak_tok(&self) -> bool {
*self == Printer::hardbreak_tok_offset(0)
}
}
@@ -444,7 +444,10 @@ pub(crate) fn print_item(&mut self, item: &ast::Item) {
&item.vis,
&deleg.qself,
&deleg.prefix,
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
match &deleg.suffixes {
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
},
&deleg.body,
),
}
@@ -651,7 +654,10 @@ pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) {
vis,
&deleg.qself,
&deleg.prefix,
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
match &deleg.suffixes {
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
},
&deleg.body,
),
}
@@ -8,8 +8,8 @@
use rustc_span::{Symbol, sym};
use thin_vec::ThinVec;
use crate::attributes::SingleAttributeParser;
use crate::attributes::prelude::Allow;
use crate::attributes::{OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::parser::{ArgParser, MetaItemOrLitParser};
use crate::target_checking::AllowedTargets;
@@ -18,7 +18,6 @@
impl<S: Stage> SingleAttributeParser<S> for RustcAutodiffParser {
const PATH: &[Symbol] = &[sym::rustc_autodiff];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -6,7 +6,6 @@
impl<S: Stage> NoArgsAttributeParser<S> for CoroutineParser {
const PATH: &[Symbol] = &[sym::coroutine];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
const CREATE: fn(rustc_span::Span) -> AttributeKind = |span| AttributeKind::Coroutine(span);
}
@@ -19,6 +19,7 @@
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
use thin_vec::ThinVec;
use crate::attributes::AttributeSafety;
use crate::context::{AcceptContext, ShouldEmit, Stage};
use crate::parser::{
AllowExprMetavar, ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser,
@@ -410,6 +411,7 @@ fn parse_cfg_attr_internal<'a>(
attribute.style,
AttrPath { segments: attribute.path().into_boxed_slice(), span: attribute.span },
Some(attribute.get_normal_item().unsafety),
AttributeSafety::Normal,
ParsedDescription::Attribute,
pred_span,
lint_node_id,
@@ -12,6 +12,7 @@
use rustc_session::lint::builtin::UNREACHABLE_CFG_SELECT_PREDICATES;
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
use crate::attributes::AttributeSafety;
use crate::parser::{AllowExprMetavar, MetaItemOrLitParser};
use crate::{AttributeParser, ParsedDescription, ShouldEmit, errors, parse_cfg_entry};
@@ -105,6 +106,7 @@ pub fn parse_cfg_select(
AttrStyle::Inner,
AttrPath { segments: vec![sym::cfg_select].into_boxed_slice(), span: cfg_span },
None,
AttributeSafety::Normal,
ParsedDescription::Macro,
cfg_span,
lint_node_id,
@@ -8,7 +8,6 @@ impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser {
Allow(Target::Enum),
Allow(Target::Union),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
@@ -1,7 +1,9 @@
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition::Edition2024;
use super::prelude::*;
use crate::attributes::AttributeSafety;
use crate::session_diagnostics::{
NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass, NullOnObjcSelector,
ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
@@ -12,7 +14,6 @@
impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
const PATH: &[Symbol] = &[sym::optimize];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Closure),
@@ -60,7 +61,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ColdParser {
impl<S: Stage> SingleAttributeParser<S> for CoverageParser {
const PATH: &[Symbol] = &[sym::coverage];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Closure),
@@ -103,6 +103,7 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {
const PATH: &[rustc_span::Symbol] = &[sym::export_name];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Static),
Allow(Target::Fn),
@@ -140,7 +141,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcObjcClassParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName");
@@ -172,7 +172,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcObjcSelectorParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName");
@@ -220,6 +219,7 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
this.span = Some(cx.attr_span);
}
})];
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -340,6 +340,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for TrackCallerParser {
impl<S: Stage> NoArgsAttributeParser<S> for NoMangleParser {
const PATH: &[Symbol] = &[sym::no_mangle];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
Allow(Target::Fn),
Allow(Target::Static),
@@ -542,6 +543,7 @@ fn extend(
impl<S: Stage> CombineAttributeParser<S> for ForceTargetFeatureParser {
type Item = (Symbol, Span);
const PATH: &[Symbol] = &[sym::force_target_feature];
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
const CONVERT: ConvertFn<Self::Item> = |items, span| AttributeKind::TargetFeature {
features: items,
attr_span: span,
@@ -585,8 +587,6 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
r#"realtime = "nonblocking|blocking|caller""#,
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(list) = args.list() else {
let attr_span = cx.attr_span;
@@ -689,7 +689,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for ThreadLocalParser {
const PATH: &[Symbol] = &[sym::thread_local];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal;
@@ -699,7 +698,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ThreadLocalParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcPassIndirectlyInNonRusticAbisParser {
const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis;
}
@@ -708,7 +706,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcPassIndirectlyInNonRusticAbisPa
impl<S: Stage> NoArgsAttributeParser<S> for RustcEiiForeignItemParser {
const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem;
@@ -718,7 +715,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEiiForeignItemParser {
impl<S: Stage> SingleAttributeParser<S> for PatchableFunctionEntryParser {
const PATH: &[Symbol] = &[sym::patchable_function_entry];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
@@ -44,9 +44,6 @@ fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
return None;
}
Some(AttributeKind::RustcConfusables {
symbols: self.confusables,
first_span: self.first_span.unwrap(),
})
Some(AttributeKind::RustcConfusables { confusables: self.confusables })
}
}
@@ -108,7 +108,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for MoveSizeLimitParser {
const PATH: &[Symbol] = &[sym::move_size_limit];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
@@ -154,7 +153,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
const PATH: &[Symbol] = &[sym::pattern_complexity_limit];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
@@ -177,7 +175,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
const PATH: &[Symbol] = &[sym::no_core];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
}
@@ -204,7 +201,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for NoMainParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser {
const PATH: &[Symbol] = &[sym::rustc_coherence_is_core];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore;
}
@@ -247,7 +243,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for PanicRuntimeParser {
const PATH: &[Symbol] = &[sym::panic_runtime];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PanicRuntime;
}
@@ -256,7 +251,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for PanicRuntimeParser {
impl<S: Stage> NoArgsAttributeParser<S> for NeedsPanicRuntimeParser {
const PATH: &[Symbol] = &[sym::needs_panic_runtime];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsPanicRuntime;
}
@@ -265,7 +259,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for NeedsPanicRuntimeParser {
impl<S: Stage> NoArgsAttributeParser<S> for ProfilerRuntimeParser {
const PATH: &[Symbol] = &[sym::profiler_runtime];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProfilerRuntime;
}
@@ -283,7 +276,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for NoBuiltinsParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcPreserveUbChecksParser {
const PATH: &[Symbol] = &[sym::rustc_preserve_ub_checks];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks;
}
@@ -292,7 +284,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcPreserveUbChecksParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitBoundsParser {
const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds;
}
@@ -301,7 +292,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitBoundsParser {
impl<S: Stage> NoArgsAttributeParser<S> for DefaultLibAllocatorParser {
const PATH: &[Symbol] = &[sym::default_lib_allocator];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::DefaultLibAllocator;
}
@@ -34,7 +34,6 @@ fn get<S: Stage>(
pub(crate) struct DeprecatedParser;
impl<S: Stage> SingleAttributeParser<S> for DeprecatedParser {
const PATH: &[Symbol] = &[sym::deprecated];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
Allow(Target::Fn),
Allow(Target::Mod),
@@ -40,6 +40,45 @@ pub(crate) enum Mode {
DiagnosticOnUnknown,
}
impl Mode {
fn as_str(&self) -> &'static str {
match self {
Self::RustcOnUnimplemented => "rustc_on_unimplemented",
Self::DiagnosticOnUnimplemented => "diagnostic::on_unimplemented",
Self::DiagnosticOnConst => "diagnostic::on_const",
Self::DiagnosticOnMove => "diagnostic::on_move",
Self::DiagnosticOnUnknown => "diagnostic::on_unknown",
}
}
fn expected_options(&self) -> &'static str {
const DEFAULT: &str =
"at least one of the `message`, `note` and `label` options are expected";
match self {
Self::RustcOnUnimplemented => {
"see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>"
}
Self::DiagnosticOnUnimplemented => DEFAULT,
Self::DiagnosticOnConst => DEFAULT,
Self::DiagnosticOnMove => DEFAULT,
Self::DiagnosticOnUnknown => DEFAULT,
}
}
fn allowed_options(&self) -> &'static str {
const DEFAULT: &str = "only `message`, `note` and `label` are allowed as options";
match self {
Self::RustcOnUnimplemented => {
"see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>"
}
Self::DiagnosticOnUnimplemented => DEFAULT,
Self::DiagnosticOnConst => DEFAULT,
Self::DiagnosticOnMove => DEFAULT,
Self::DiagnosticOnUnknown => DEFAULT,
}
}
}
fn merge_directives<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
first: &mut Option<(Span, Directive)>,
@@ -83,6 +122,49 @@ fn merge<T, S: Stage>(
}
}
fn parse_list<'p, S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
args: &'p ArgParser,
mode: Mode,
) -> Option<&'p MetaItemListParser> {
let span = cx.attr_span;
match args {
ArgParser::List(items) if items.len() != 0 => return Some(items),
ArgParser::List(list) => {
// We're dealing with `#[diagnostic::attr()]`.
// This can be because that is what the user typed, but that's also what we'd see
// if the user used non-metaitem syntax. See `ArgParser::from_attr_args`.
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::NonMetaItemDiagnosticAttribute,
list.span,
);
}
ArgParser::NoArgs => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MissingOptionsForDiagnosticAttribute {
attribute: mode.as_str(),
options: mode.expected_options(),
},
span,
);
}
ArgParser::NameValue(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalFormedDiagnosticAttribute {
attribute: mode.as_str(),
options: mode.allowed_options(),
span,
},
span,
);
}
}
None
}
fn parse_directive_items<'p, S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
mode: Mode,
@@ -100,39 +182,15 @@ fn parse_directive_items<'p, S: Stage>(
let span = item.span();
macro malformed() {{
match mode {
Mode::RustcOnUnimplemented => {
cx.emit_err(NoValueInOnUnimplemented { span: item.span() });
}
Mode::DiagnosticOnUnimplemented => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnUnimplementedAttr { span },
span,
);
}
Mode::DiagnosticOnConst => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnConstAttr { span },
span,
);
}
Mode::DiagnosticOnMove => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnMoveAttr { span },
span,
);
}
Mode::DiagnosticOnUnknown => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnUnknownAttr { span },
span,
);
}
}
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalFormedDiagnosticAttribute {
attribute: mode.as_str(),
options: mode.allowed_options(),
span,
},
span,
);
continue;
}}
@@ -146,22 +204,15 @@ fn parse_directive_items<'p, S: Stage>(
}}
macro duplicate($name: ident, $($first_span:tt)*) {{
match mode {
Mode::RustcOnUnimplemented => {
cx.emit_err(NoValueInOnUnimplemented { span: item.span() });
}
Mode::DiagnosticOnUnimplemented |Mode::DiagnosticOnConst | Mode::DiagnosticOnMove | Mode::DiagnosticOnUnknown => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::IgnoredDiagnosticOption {
first_span: $($first_span)*,
later_span: span,
option_name: $name,
},
span,
);
}
}
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::IgnoredDiagnosticOption {
first_span: $($first_span)*,
later_span: span,
option_name: $name,
},
span,
);
}}
let item: &MetaItemParser = or_malformed!(item.meta_item()?);
@@ -540,15 +591,6 @@ pub(crate) enum InvalidOnClause {
},
}
#[derive(Diagnostic)]
#[diag("this attribute must have a value", code = E0232)]
#[note("e.g. `#[rustc_on_unimplemented(message=\"foo\")]`")]
pub(crate) struct NoValueInOnUnimplemented {
#[primary_span]
#[label("expected value here")]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(
"using multiple `rustc_on_unimplemented` (or mixing it with `diagnostic::on_unimplemented`) is not supported"
@@ -1,6 +1,4 @@
use rustc_hir::attrs::diagnostic::Directive;
use rustc_hir::lints::AttributeLintKind;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
@@ -23,30 +21,11 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
let span = cx.attr_span;
this.span = Some(span);
let mode = Mode::DiagnosticOnConst;
let items = match args {
ArgParser::List(items) if items.len() != 0 => items,
ArgParser::NoArgs | ArgParser::List(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MissingOptionsForOnConst,
span,
);
return;
}
ArgParser::NameValue(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnConstAttr { span },
span,
);
return;
}
};
let Some(items) = parse_list(cx, args, mode) else { return };
let Some(directive) =
parse_directive_items(cx, Mode::DiagnosticOnConst, items.mixed(), true)
else {
let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) else {
return;
};
merge_directives(cx, &mut this.directive, (span, directive));
@@ -1,7 +1,5 @@
use rustc_feature::template;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_span::sym;
use crate::attributes::diagnostic::*;
@@ -30,25 +28,10 @@ fn parse<'sess, S: Stage>(
let span = cx.attr_span;
self.span = Some(span);
let Some(list) = args.list() else {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MissingOptionsForOnMove,
span,
);
return;
};
if list.is_empty() {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::OnMoveMalformedAttrExpectedLiteralOrDelimiter,
list.span,
);
return;
}
let Some(items) = parse_list(cx, args, mode) else { return };
if let Some(directive) = parse_directive_items(cx, mode, list.mixed(), true) {
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
merge_directives(cx, &mut self.directive, (span, directive));
}
}
@@ -1,6 +1,4 @@
use rustc_hir::attrs::diagnostic::Directive;
use rustc_hir::lints::AttributeLintKind;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
@@ -29,25 +27,7 @@ fn parse<'sess, S: Stage>(
return;
}
let items = match args {
ArgParser::List(items) if items.len() != 0 => items,
ArgParser::NoArgs | ArgParser::List(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MissingOptionsForOnUnimplemented,
span,
);
return;
}
ArgParser::NameValue(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnUnimplementedAttr { span },
span,
);
return;
}
};
let Some(items) = parse_list(cx, args, mode) else { return };
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
merge_directives(cx, &mut self.directive, (span, directive));
@@ -1,5 +1,4 @@
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
@@ -17,32 +16,16 @@ fn parse<'sess, S: Stage>(
args: &ArgParser,
mode: Mode,
) {
if !cx.features().diagnostic_on_unknown() {
if let Some(features) = cx.features
&& !features.diagnostic_on_unknown()
{
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
return;
}
let span = cx.attr_span;
self.span = Some(span);
let items = match args {
ArgParser::List(items) if !items.is_empty() => items,
ArgParser::NoArgs | ArgParser::List(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MissingOptionsForOnUnknown,
span,
);
return;
}
ArgParser::NameValue(_) => {
cx.emit_lint(
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
AttributeLintKind::MalformedOnUnknownAttr { span },
span,
);
return;
}
};
let Some(items) = parse_list(cx, args, mode) else { return };
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
merge_directives(cx, &mut self.directive, (span, directive));
@@ -1,5 +1,5 @@
use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit};
use rustc_errors::msg;
use rustc_errors::{Diagnostic, msg};
use rustc_feature::template;
use rustc_hir::Target;
use rustc_hir::attrs::{
@@ -13,6 +13,7 @@
use super::prelude::{ALL_TARGETS, AllowedTargets};
use super::{AcceptMapping, AttributeParser};
use crate::context::{AcceptContext, FinalizeContext, Stage};
use crate::errors::{DocAliasDuplicated, DocAutoCfgExpectsHideOrShow, IllFormedAttributeInput};
use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser};
use crate::session_diagnostics::{
DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttrNotCrateLevel,
@@ -171,12 +172,15 @@ fn parse_single_test_doc_attr_item<S: Stage>(
if let Some(used_span) = self.attribute.no_crate_inject {
let unused_span = path.span();
cx.emit_lint(
cx.emit_dyn_lint(
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
AttributeLintKind::UnusedDuplicate {
this: unused_span,
other: used_span,
warning: true,
move |dcx, level| {
rustc_errors::lints::UnusedDuplicate {
this: unused_span,
other: used_span,
warning: true,
}
.into_diag(dcx, level)
},
unused_span,
);
@@ -252,9 +256,9 @@ fn add_alias<S: Stage>(
}
if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() {
cx.emit_lint(
cx.emit_dyn_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
AttributeLintKind::DuplicateDocAlias { first_definition },
move |dcx, level| DocAliasDuplicated { first_definition }.into_diag(dcx, level),
span,
);
}
@@ -340,9 +344,9 @@ fn parse_auto_cfg<S: Stage>(
ArgParser::List(list) => {
for meta in list.mixed() {
let MetaItemOrLitParser::MetaItemParser(item) = meta else {
cx.emit_lint(
cx.emit_dyn_lint(
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
AttributeLintKind::DocAutoCfgExpectsHideOrShow,
|dcx, level| DocAutoCfgExpectsHideOrShow.into_diag(dcx, level),
meta.span(),
);
continue;
@@ -351,9 +355,9 @@ fn parse_auto_cfg<S: Stage>(
Some(sym::hide) => (HideOrShow::Hide, sym::hide),
Some(sym::show) => (HideOrShow::Show, sym::show),
_ => {
cx.emit_lint(
cx.emit_dyn_lint(
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
AttributeLintKind::DocAutoCfgExpectsHideOrShow,
|dcx, level| DocAutoCfgExpectsHideOrShow.into_diag(dcx, level),
item.span(),
);
continue;
@@ -663,12 +667,10 @@ fn accept_single_doc_attr<S: Stage>(
ArgParser::NoArgs => {
let suggestions = cx.adcx().suggestions();
let span = cx.attr_span;
cx.emit_lint(
cx.emit_dyn_lint(
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
AttributeLintKind::IllFormedAttributeInput {
suggestions,
docs: None,
help: None,
move |dcx, level| {
IllFormedAttributeInput::new(&suggestions, None, None).into_diag(dcx, level)
},
span,
);
@@ -67,7 +67,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
const PATH: &[Symbol] = &[sym::rustc_force_inline];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -15,7 +15,6 @@ impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser {
Allow(Target::Method(MethodKind::Trait { body: true })),
]);
const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute");
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
@@ -5,11 +5,13 @@
use rustc_session::Session;
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition::Edition2024;
use rustc_span::kw;
use rustc_target::spec::{Arch, BinaryFormat};
use super::prelude::*;
use super::util::parse_single_integer;
use crate::attributes::AttributeSafety;
use crate::attributes::cfg::parse_cfg_entry;
use crate::session_diagnostics::{
AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic,
@@ -463,6 +465,7 @@ fn parse_link_import_name_type<S: Stage>(
impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
const PATH: &[Symbol] = &[sym::link_section];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
Allow(Target::Static),
Allow(Target::Fn),
@@ -499,7 +502,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
pub(crate) struct ExportStableParser;
impl<S: Stage> NoArgsAttributeParser<S> for ExportStableParser {
const PATH: &[Symbol] = &[sym::export_stable];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
}
@@ -507,7 +509,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for ExportStableParser {
pub(crate) struct FfiConstParser;
impl<S: Stage> NoArgsAttributeParser<S> for FfiConstParser {
const PATH: &[Symbol] = &[sym::ffi_const];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst;
}
@@ -515,7 +517,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for FfiConstParser {
pub(crate) struct FfiPureParser;
impl<S: Stage> NoArgsAttributeParser<S> for FfiPureParser {
const PATH: &[Symbol] = &[sym::ffi_pure];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;
}
@@ -523,7 +525,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for FfiPureParser {
pub(crate) struct RustcStdInternalSymbolParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcStdInternalSymbolParser {
const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::ForeignFn),
@@ -537,7 +538,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcStdInternalSymbolParser {
impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser {
const PATH: &[Symbol] = &[sym::link_ordinal];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
@@ -578,7 +578,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for LinkageParser {
const PATH: &[Symbol] = &[sym::linkage];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -661,7 +660,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for NeedsAllocatorParser {
const PATH: &[Symbol] = &[sym::needs_allocator];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator;
}
@@ -670,7 +668,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for NeedsAllocatorParser {
impl<S: Stage> NoArgsAttributeParser<S> for CompilerBuiltinsParser {
const PATH: &[Symbol] = &[sym::compiler_builtins];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CompilerBuiltins;
}
@@ -3,7 +3,6 @@
pub(crate) struct RustcAsPtrParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcAsPtrParser {
const PATH: &[Symbol] = &[sym::rustc_as_ptr];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -17,7 +16,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcAsPtrParser {
pub(crate) struct RustcPubTransparentParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcPubTransparentParser {
const PATH: &[Symbol] = &[sym::rustc_pub_transparent];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
@@ -29,7 +27,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcPubTransparentParser {
pub(crate) struct RustcPassByValueParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcPassByValueParser {
const PATH: &[Symbol] = &[sym::rustc_pass_by_value];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
@@ -41,7 +38,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcPassByValueParser {
pub(crate) struct RustcShouldNotBeCalledOnConstItemsParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcShouldNotBeCalledOnConstItemsParser {
const PATH: &[Symbol] = &[sym::rustc_should_not_be_called_on_const_items];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::TraitImpl)),
@@ -3,7 +3,6 @@
pub(crate) struct LoopMatchParser;
impl<S: Stage> NoArgsAttributeParser<S> for LoopMatchParser {
const PATH: &[Symbol] = &[sym::loop_match];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Expression)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch;
}
@@ -11,7 +10,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for LoopMatchParser {
pub(crate) struct ConstContinueParser;
impl<S: Stage> NoArgsAttributeParser<S> for ConstContinueParser {
const PATH: &[Symbol] = &[sym::const_continue];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Expression)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue;
}
@@ -167,7 +167,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for CollapseDebugInfoParser {
const PATH: &[Symbol] = &[sym::collapse_debuginfo];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(
List: &["no", "external", "yes"],
"https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
@@ -203,7 +202,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcProcMacroDeclsParser {
const PATH: &[Symbol] = &[sym::rustc_proc_macro_decls];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls;
}
@@ -18,6 +18,7 @@
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::edition::Edition;
use rustc_span::{Span, Symbol};
use thin_vec::ThinVec;
@@ -97,6 +98,7 @@ pub(crate) trait AttributeParser<S: Stage>: Default + 'static {
/// If an attribute has this symbol, the `accept` function will be called on it.
const ATTRIBUTES: AcceptMapping<Self, S>;
const ALLOWED_TARGETS: AllowedTargets;
const SAFETY: AttributeSafety = AttributeSafety::Normal;
/// The parser has gotten a chance to accept the attributes on an item,
/// here it can produce an attribute.
@@ -126,7 +128,8 @@ pub(crate) trait SingleAttributeParser<S: Stage>: 'static {
/// Configures what to do when when the same attribute is
/// applied more than once on the same syntax node.
const ON_DUPLICATE: OnDuplicate<S>;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const SAFETY: AttributeSafety = AttributeSafety::Normal;
const ALLOWED_TARGETS: AllowedTargets;
@@ -158,13 +161,14 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
if let Some(pa) = T::convert(cx, args) {
if let Some((_, used)) = group.1 {
T::ON_DUPLICATE.exec::<T>(cx, used, cx.attr_span);
} else {
group.1 = Some((pa, cx.attr_span));
}
group.1 = Some((pa, cx.attr_span));
}
},
)];
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
const SAFETY: AttributeSafety = T::SAFETY;
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
Some(self.1?.0)
@@ -217,6 +221,18 @@ fn exec<P: SingleAttributeParser<S>>(
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum AttributeSafety {
/// Normal attribute that does not need `#[unsafe(...)]`
Normal,
/// Unsafe attribute that requires safety obligations to be discharged.
///
/// An error is emitted when `#[unsafe(...)]` is omitted, except when the attribute's edition
/// is less than the one stored in `unsafe_since`. This handles attributes that were safe in
/// earlier editions, but become unsafe in later ones.
Unsafe { unsafe_since: Option<Edition> },
}
/// An even simpler version of [`SingleAttributeParser`]:
/// now automatically check that there are no arguments provided to the attribute.
///
@@ -224,8 +240,9 @@ fn exec<P: SingleAttributeParser<S>>(
//
pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static {
const PATH: &[Symbol];
const ON_DUPLICATE: OnDuplicate<S>;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets;
const SAFETY: AttributeSafety = AttributeSafety::Normal;
/// Create the [`AttributeKind`] given attribute's [`Span`].
const CREATE: fn(Span) -> AttributeKind;
@@ -242,6 +259,7 @@ fn default() -> Self {
impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for WithoutArgs<T, S> {
const PATH: &[Symbol] = T::PATH;
const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE;
const SAFETY: AttributeSafety = T::SAFETY;
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
const TEMPLATE: AttributeTemplate = template!(Word);
@@ -271,6 +289,7 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static {
/// For example, individual representations from `#[repr(...)]` attributes into an `AttributeKind::Repr(x)`,
/// where `x` is a vec of these individual reprs.
const CONVERT: ConvertFn<Self::Item>;
const SAFETY: AttributeSafety = AttributeSafety::Normal;
const ALLOWED_TARGETS: AllowedTargets;
@@ -312,6 +331,7 @@ impl<T: CombineAttributeParser<S>, S: Stage> AttributeParser<S> for Combine<T, S
group.items.extend(T::extend(cx, args))
})];
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
const SAFETY: AttributeSafety = T::SAFETY;
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
if let Some(first_span) = self.first_span {
@@ -4,7 +4,6 @@
impl<S: Stage> SingleAttributeParser<S> for MustNotSuspendParser {
const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
@@ -2,7 +2,7 @@
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
use crate::attributes::NoArgsAttributeParser;
use crate::context::Stage;
use crate::target_checking::AllowedTargets;
use crate::target_checking::Policy::Allow;
@@ -11,7 +11,6 @@
impl<S: Stage> NoArgsAttributeParser<S> for PinV2Parser {
const PATH: &[Symbol] = &[sym::pin_v2];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Enum),
Allow(Target::Struct),
@@ -9,7 +9,6 @@
pub(crate) struct ProcMacroParser;
impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroParser {
const PATH: &[Symbol] = &[sym::proc_macro];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacro;
}
@@ -17,7 +16,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroParser {
pub(crate) struct ProcMacroAttributeParser;
impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroAttributeParser {
const PATH: &[Symbol] = &[sym::proc_macro_attribute];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacroAttribute;
}
@@ -25,7 +23,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroAttributeParser {
pub(crate) struct ProcMacroDeriveParser;
impl<S: Stage> SingleAttributeParser<S> for ProcMacroDeriveParser {
const PATH: &[Symbol] = &[sym::proc_macro_derive];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS;
const TEMPLATE: AttributeTemplate = template!(
List: &["TraitName", "TraitName, attributes(name1, name2, ...)"],
@@ -45,7 +42,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
pub(crate) struct RustcBuiltinMacroParser;
impl<S: Stage> SingleAttributeParser<S> for RustcBuiltinMacroParser {
const PATH: &[Symbol] = &[sym::rustc_builtin_macro];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
const TEMPLATE: AttributeTemplate =
template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]);
@@ -5,7 +5,6 @@
use rustc_hir::attrs::{AttributeKind, MirDialect, MirPhase};
use rustc_span::{Span, Symbol, sym};
use super::OnDuplicate;
use crate::attributes::SingleAttributeParser;
use crate::context::{AcceptContext, Stage};
use crate::parser::ArgParser;
@@ -18,8 +17,6 @@
impl<S: Stage> SingleAttributeParser<S> for CustomMirParser {
const PATH: &[rustc_span::Symbol] = &[sym::custom_mir];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]);
@@ -4,7 +4,6 @@
impl<S: Stage> NoArgsAttributeParser<S> for RustcAllocatorParser {
const PATH: &[Symbol] = &[sym::rustc_allocator];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator;
@@ -14,7 +13,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcAllocatorParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcAllocatorZeroedParser {
const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed;
@@ -24,7 +22,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcAllocatorZeroedParser {
impl<S: Stage> SingleAttributeParser<S> for RustcAllocatorZeroedVariantParser {
const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed_variant];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function");
@@ -43,7 +40,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcDeallocatorParser {
const PATH: &[Symbol] = &[sym::rustc_deallocator];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator;
@@ -53,7 +49,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDeallocatorParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcReallocatorParser {
const PATH: &[Symbol] = &[sym::rustc_reallocator];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcReallocator;
@@ -10,7 +10,6 @@
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpUserArgsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_user_args];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
}
@@ -19,7 +18,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpUserArgsParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpDefParentsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_def_parents];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
}
@@ -37,7 +35,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDumpDefPathParser {
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
@@ -52,7 +49,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpHiddenTypeOfOpaquesParser {
const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques;
}
@@ -61,7 +57,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpHiddenTypeOfOpaquesParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpInferredOutlivesParser {
const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
@@ -75,7 +70,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpInferredOutlivesParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpItemBoundsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
}
@@ -148,7 +142,6 @@ fn extend(
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpObjectLifetimeDefaultsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::AssocConst),
Allow(Target::AssocTy),
@@ -175,7 +168,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpObjectLifetimeDefaultsParse
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpPredicatesParser {
const PATH: &[Symbol] = &[sym::rustc_dump_predicates];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::AssocConst),
Allow(Target::AssocTy),
@@ -212,7 +204,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDumpSymbolNameParser {
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
@@ -227,7 +218,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesParser {
const PATH: &[Symbol] = &[sym::rustc_dump_variances];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Enum),
Allow(Target::Fn),
@@ -245,7 +235,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesOfOpaquesParser {
const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques;
}
@@ -254,7 +243,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesOfOpaquesParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVtableParser {
const PATH: &[Symbol] = &[sym::rustc_dump_vtable];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Impl { of_trait: true }),
Allow(Target::TyAlias),
@@ -6,11 +6,11 @@
BorrowckGraphvizFormatKind, CguFields, CguKind, DivergingBlockBehavior,
DivergingFallbackBehavior, RustcCleanAttribute, RustcCleanQueries, RustcMirKind,
};
use rustc_session::errors;
use rustc_span::Symbol;
use super::prelude::*;
use super::util::parse_single_integer;
use crate::errors;
use crate::session_diagnostics::{
AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, UnknownLangItem,
};
@@ -19,7 +19,6 @@
impl<S: Stage> NoArgsAttributeParser<S> for RustcMainParser {
const PATH: &[Symbol] = &[sym::rustc_main];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain;
}
@@ -28,7 +27,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcMainParser {
impl<S: Stage> SingleAttributeParser<S> for RustcMustImplementOneOfParser {
const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
@@ -74,7 +72,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcNeverReturnsNullPtrParser {
const PATH: &[Symbol] = &[sym::rustc_never_returns_null_ptr];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -88,7 +85,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNeverReturnsNullPtrParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitAutorefsParser {
const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -104,7 +100,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNoImplicitAutorefsParser {
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStartParser {
const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_start];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const TEMPLATE: AttributeTemplate = template!(List: &["start"]);
@@ -118,7 +113,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEndParser {
const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_end];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const TEMPLATE: AttributeTemplate = template!(List: &["end"]);
@@ -132,7 +126,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {
const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const TEMPLATE: AttributeTemplate = template!(List: &["N"]);
@@ -176,7 +169,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcInheritOverflowChecksParser {
const PATH: &[Symbol] = &[sym::rustc_inherit_overflow_checks];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -190,7 +182,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcInheritOverflowChecksParser {
impl<S: Stage> SingleAttributeParser<S> for RustcLintOptDenyFieldAccessParser {
const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]);
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
@@ -210,7 +201,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintOptTyParser {
const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy;
}
@@ -359,7 +349,6 @@ fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
impl<S: Stage> SingleAttributeParser<S> for RustcDeprecatedSafe2024Parser {
const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -400,7 +389,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcConversionSuggestionParser {
const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -415,7 +403,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcConversionSuggestionParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcCaptureAnalysisParser {
const PATH: &[Symbol] = &[sym::rustc_capture_analysis];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis;
}
@@ -424,7 +411,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcCaptureAnalysisParser {
impl<S: Stage> SingleAttributeParser<S> for RustcNeverTypeOptionsParser {
const PATH: &[Symbol] = &[sym::rustc_never_type_options];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const TEMPLATE: AttributeTemplate = template!(List: &[
r#"fallback = "unit", "never", "no""#,
@@ -507,7 +493,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcTrivialFieldReadsParser {
const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads;
}
@@ -516,7 +501,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcTrivialFieldReadsParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcNoMirInlineParser {
const PATH: &[Symbol] = &[sym::rustc_no_mir_inline];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -527,11 +511,25 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNoMirInlineParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoMirInline;
}
pub(crate) struct RustcNoWritableParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcNoWritableParser {
const PATH: &[Symbol] = &[sym::rustc_no_writable];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Closure),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Trait { body: true })),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoWritable;
}
pub(crate) struct RustcLintQueryInstabilityParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintQueryInstabilityParser {
const PATH: &[Symbol] = &[sym::rustc_lint_query_instability];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -546,7 +544,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcLintQueryInstabilityParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcRegionsParser {
const PATH: &[Symbol] = &[sym::rustc_regions];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -562,7 +559,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcRegionsParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcLintUntrackedQueryInformationParser {
const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -578,7 +574,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcLintUntrackedQueryInformationPa
impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser {
const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
@@ -596,7 +591,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcScalableVectorParser {
const PATH: &[Symbol] = &[sym::rustc_scalable_vector];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);
@@ -621,7 +615,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for LangParser {
const PATH: &[Symbol] = &[sym::lang];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
@@ -647,7 +640,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcHasIncoherentInherentImplsParser {
const PATH: &[Symbol] = &[sym::rustc_has_incoherent_inherent_impls];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Trait),
Allow(Target::Struct),
@@ -662,7 +654,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcHasIncoherentInherentImplsParse
impl<S: Stage> NoArgsAttributeParser<S> for PanicHandlerParser {
const PATH: &[Symbol] = &[sym::panic_handler];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::Lang(LangItem::PanicImpl, span);
}
@@ -671,7 +662,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for PanicHandlerParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcNounwindParser {
const PATH: &[Symbol] = &[sym::rustc_nounwind];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::ForeignFn),
@@ -686,7 +676,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNounwindParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcOffloadKernelParser {
const PATH: &[Symbol] = &[sym::rustc_offload_kernel];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel;
}
@@ -785,7 +774,6 @@ fn extend(
impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
const PATH: &[Symbol] = &[sym::rustc_non_const_trait_method];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::Trait { body: false })),
@@ -904,8 +892,6 @@ fn extend(
impl<S: Stage> SingleAttributeParser<S> for RustcIfThisChangedParser {
const PATH: &[Symbol] = &[sym::rustc_if_this_changed];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
// tidy-alphabetical-start
Allow(Target::AssocConst),
@@ -1015,7 +1001,6 @@ fn extend(
impl<S: Stage> NoArgsAttributeParser<S> for RustcInsignificantDtorParser {
const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Enum),
Allow(Target::Struct),
@@ -1028,7 +1013,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcInsignificantDtorParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
const PATH: &[Symbol] = &[sym::rustc_effective_visibility];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Use),
Allow(Target::Static),
@@ -1067,7 +1051,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
impl<S: Stage> SingleAttributeParser<S> for RustcDiagnosticItemParser {
const PATH: &[Symbol] = &[sym::rustc_diagnostic_item];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Trait),
Allow(Target::Struct),
@@ -1106,7 +1089,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcDoNotConstCheckParser {
const PATH: &[Symbol] = &[sym::rustc_do_not_const_check];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -1121,7 +1103,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDoNotConstCheckParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcNonnullOptimizationGuaranteedParser {
const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed;
}
@@ -1130,7 +1111,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNonnullOptimizationGuaranteedPa
impl<S: Stage> NoArgsAttributeParser<S> for RustcStrictCoherenceParser {
const PATH: &[Symbol] = &[sym::rustc_strict_coherence];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Trait),
Allow(Target::Struct),
@@ -1145,7 +1125,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcStrictCoherenceParser {
impl<S: Stage> SingleAttributeParser<S> for RustcReservationImplParser {
const PATH: &[Symbol] = &[sym::rustc_reservation_impl];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]);
@@ -1171,7 +1150,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for PreludeImportParser {
const PATH: &[Symbol] = &[sym::prelude_import];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport;
}
@@ -1180,7 +1158,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for PreludeImportParser {
impl<S: Stage> SingleAttributeParser<S> for RustcDocPrimitiveParser {
const PATH: &[Symbol] = &[sym::rustc_doc_primitive];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
@@ -1204,7 +1181,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcIntrinsicParser {
const PATH: &[Symbol] = &[sym::rustc_intrinsic];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic;
}
@@ -1213,7 +1189,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcIntrinsicParser {
impl<S: Stage> NoArgsAttributeParser<S> for RustcIntrinsicConstStableIndirectParser {
const PATH: &'static [Symbol] = &[sym::rustc_intrinsic_const_stable_indirect];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect;
}
@@ -1222,7 +1197,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcIntrinsicConstStableIndirectPar
impl<S: Stage> NoArgsAttributeParser<S> for RustcExhaustiveParser {
const PATH: &'static [Symbol] = &[sym::rustc_must_match_exhaustively];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Enum)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively;
}
@@ -3,7 +3,6 @@
pub(crate) struct MayDangleParser;
impl<S: Stage> NoArgsAttributeParser<S> for MayDangleParser {
const PATH: &[Symbol] = &[sym::may_dangle];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
}
@@ -102,7 +102,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for ReexportTestHarnessMainParser {
const PATH: &[Symbol] = &[sym::reexport_test_harness_main];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
@@ -129,7 +128,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcAbiParser {
const PATH: &[Symbol] = &[sym::rustc_abi];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::TyAlias),
@@ -179,7 +177,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> NoArgsAttributeParser<S> for RustcDelayedBugFromInsideQueryParser {
const PATH: &[Symbol] = &[sym::rustc_delayed_bug_from_inside_query];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery;
}
@@ -188,7 +185,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDelayedBugFromInsideQueryParser
impl<S: Stage> NoArgsAttributeParser<S> for RustcEvaluateWhereClausesParser {
const PATH: &[Symbol] = &[sym::rustc_evaluate_where_clauses];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
@@ -203,7 +199,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEvaluateWhereClausesParser {
impl<S: Stage> SingleAttributeParser<S> for TestRunnerParser {
const PATH: &[Symbol] = &[sym::test_runner];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const TEMPLATE: AttributeTemplate = template!(List: &["path"]);
@@ -223,7 +218,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
impl<S: Stage> SingleAttributeParser<S> for RustcTestMarkerParser {
const PATH: &[Symbol] = &[sym::rustc_test_marker];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Const),
Allow(Target::Fn),
@@ -1,16 +1,15 @@
use std::mem;
use super::prelude::*;
use crate::attributes::{NoArgsAttributeParser, OnDuplicate, SingleAttributeParser};
use crate::attributes::{NoArgsAttributeParser, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::parser::ArgParser;
use crate::target_checking::AllowedTargets;
use crate::target_checking::Policy::{Allow, Warn};
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
pub(crate) struct RustcSkipDuringMethodDispatchParser;
impl<S: Stage> SingleAttributeParser<S> for RustcSkipDuringMethodDispatchParser {
const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]);
@@ -60,7 +59,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
pub(crate) struct RustcParenSugarParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcParenSugarParser {
const PATH: &[Symbol] = &[sym::rustc_paren_sugar];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcParenSugar;
}
@@ -70,7 +68,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcParenSugarParser {
pub(crate) struct MarkerParser;
impl<S: Stage> NoArgsAttributeParser<S> for MarkerParser {
const PATH: &[Symbol] = &[sym::marker];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Trait),
Warn(Target::Field),
@@ -83,7 +80,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for MarkerParser {
pub(crate) struct RustcDenyExplicitImplParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcDenyExplicitImplParser {
const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDenyExplicitImpl;
}
@@ -91,7 +87,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDenyExplicitImplParser {
pub(crate) struct RustcDynIncompatibleTraitParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcDynIncompatibleTraitParser {
const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
}
@@ -101,7 +96,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDynIncompatibleTraitParser {
pub(crate) struct RustcSpecializationTraitParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcSpecializationTraitParser {
const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcSpecializationTrait;
}
@@ -109,7 +103,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcSpecializationTraitParser {
pub(crate) struct RustcUnsafeSpecializationMarkerParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcUnsafeSpecializationMarkerParser {
const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcUnsafeSpecializationMarker;
}
@@ -119,7 +112,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcUnsafeSpecializationMarkerParse
pub(crate) struct RustcCoinductiveParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcCoinductiveParser {
const PATH: &[Symbol] = &[sym::rustc_coinductive];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoinductive;
}
@@ -127,7 +119,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcCoinductiveParser {
pub(crate) struct RustcAllowIncoherentImplParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcAllowIncoherentImplParser {
const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
@@ -136,16 +127,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcAllowIncoherentImplParser {
pub(crate) struct FundamentalParser;
impl<S: Stage> NoArgsAttributeParser<S> for FundamentalParser {
const PATH: &[Symbol] = &[sym::fundamental];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
}
pub(crate) struct PointeeParser;
impl<S: Stage> NoArgsAttributeParser<S> for PointeeParser {
const PATH: &[Symbol] = &[sym::pointee];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const CREATE: fn(Span) -> AttributeKind = AttributeKind::Pointee;
}
+64 -22
View File
@@ -7,7 +7,8 @@
use private::Sealed;
use rustc_ast::{AttrStyle, MetaItemLit, NodeId};
use rustc_errors::{Diag, Diagnostic, Level, MultiSpan};
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan};
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
@@ -17,7 +18,6 @@
use rustc_session::lint::{Lint, LintId};
use rustc_span::{ErrorGuaranteed, Span, Symbol};
use crate::AttributeParser;
// Glob imports to avoid big, bitrotty import lists
use crate::attributes::allow_unstable::*;
use crate::attributes::autodiff::*;
@@ -59,13 +59,14 @@
use crate::attributes::test_attrs::*;
use crate::attributes::traits::*;
use crate::attributes::transparency::*;
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
use crate::attributes::{AttributeParser as _, AttributeSafety, Combine, Single, WithoutArgs};
use crate::parser::{ArgParser, MetaItemOrLitParser, RefPathParser};
use crate::session_diagnostics::{
AttributeParseError, AttributeParseErrorReason, AttributeParseErrorSuggestions,
ParsedDescription,
};
use crate::target_checking::AllowedTargets;
use crate::{AttributeParser, EmitAttribute};
type GroupType<S> = LazyLock<GroupTypeInner<S>>;
pub(super) struct GroupTypeInner<S: Stage> {
@@ -76,6 +77,7 @@ pub(super) struct GroupTypeInnerAccept<S: Stage> {
pub(super) template: AttributeTemplate,
pub(super) accept_fn: AcceptFn<S>,
pub(super) allowed_targets: AllowedTargets,
pub(super) safety: AttributeSafety,
pub(super) finalizer: FinalizeFn<S>,
}
@@ -126,6 +128,7 @@ mod late {
accept_fn(s, cx, args)
})
}),
safety: <$names as crate::attributes::AttributeParser<$stage>>::SAFETY,
allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS,
finalizer: Box::new(|cx| {
let state = STATE_OBJECT.take();
@@ -269,7 +272,6 @@ mod late {
Single<WithoutArgs<PanicHandlerParser>>,
Single<WithoutArgs<PanicRuntimeParser>>,
Single<WithoutArgs<PinV2Parser>>,
Single<WithoutArgs<PointeeParser>>,
Single<WithoutArgs<PreludeImportParser>>,
Single<WithoutArgs<ProcMacroAttributeParser>>,
Single<WithoutArgs<ProcMacroParser>>,
@@ -315,6 +317,7 @@ mod late {
Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,
Single<WithoutArgs<RustcNoImplicitBoundsParser>>,
Single<WithoutArgs<RustcNoMirInlineParser>>,
Single<WithoutArgs<RustcNoWritableParser>>,
Single<WithoutArgs<RustcNonConstTraitMethodParser>>,
Single<WithoutArgs<RustcNonnullOptimizationGuaranteedParser>>,
Single<WithoutArgs<RustcNounwindParser>>,
@@ -459,11 +462,34 @@ pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuarant
/// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
/// must be delayed until after HIR is built. This method will take care of the details of
/// that.
pub(crate) fn emit_lint<M: Into<MultiSpan>>(
pub(crate) fn emit_lint(
&mut self,
lint: &'static Lint,
kind: AttributeLintKind,
span: M,
span: impl Into<MultiSpan>,
) {
self.emit_lint_inner(lint, EmitAttribute::Static(kind), span);
}
/// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
/// must be delayed until after HIR is built. This method will take care of the details of
/// that.
pub(crate) fn emit_dyn_lint<
F: for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static,
>(
&mut self,
lint: &'static Lint,
callback: F,
span: impl Into<MultiSpan>,
) {
self.emit_lint_inner(lint, EmitAttribute::Dynamic(Box::new(callback)), span);
}
fn emit_lint_inner(
&mut self,
lint: &'static Lint,
kind: EmitAttribute,
span: impl Into<MultiSpan>,
) {
if !matches!(
self.stage.should_emit(),
@@ -475,12 +501,15 @@ pub(crate) fn emit_lint<M: Into<MultiSpan>>(
}
pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
self.emit_lint(
self.emit_dyn_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
AttributeLintKind::UnusedDuplicate {
this: unused_span,
other: used_span,
warning: false,
move |dcx, level| {
rustc_errors::lints::UnusedDuplicate {
this: unused_span,
other: used_span,
warning: false,
}
.into_diag(dcx, level)
},
unused_span,
)
@@ -491,12 +520,15 @@ pub(crate) fn warn_unused_duplicate_future_error(
used_span: Span,
unused_span: Span,
) {
self.emit_lint(
self.emit_dyn_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
AttributeLintKind::UnusedDuplicate {
this: unused_span,
other: used_span,
warning: true,
move |dcx, level| {
rustc_errors::lints::UnusedDuplicate {
this: unused_span,
other: used_span,
warning: true,
}
.into_diag(dcx, level)
},
unused_span,
)
@@ -567,7 +599,7 @@ pub struct SharedContext<'p, 'sess, S: Stage> {
/// The second argument of the closure is a [`NodeId`] if `S` is `Early` and a [`HirId`] if `S`
/// is `Late` and is the ID of the syntactical component this attribute was applied to.
pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, AttributeLintKind),
pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, EmitAttribute),
}
/// Context given to every attribute parser during finalization.
@@ -865,11 +897,18 @@ pub(crate) fn expected_specific_argument_strings(
}
pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
let attr_path = self.attr_path.clone().to_string();
let attr_path = self.attr_path.to_string();
let valid_without_list = self.template.word;
self.emit_lint(
self.emit_dyn_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list },
move |dcx, level| {
crate::errors::EmptyAttributeList {
attr_span: span,
attr_path: &attr_path,
valid_without_list,
}
.into_diag(dcx, level)
},
span,
);
}
@@ -884,9 +923,12 @@ pub(crate) fn warn_ill_formed_attribute_input_with_help(
) {
let suggestions = self.suggestions();
let span = self.attr_span;
self.emit_lint(
self.emit_dyn_lint(
lint,
AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None, help },
move |dcx, level| {
crate::errors::IllFormedAttributeInput::new(&suggestions, None, help.as_deref())
.into_diag(dcx, level)
},
span,
);
}
+128 -1
View File
@@ -1,4 +1,4 @@
use rustc_errors::MultiSpan;
use rustc_errors::{DiagArgValue, MultiSpan};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
@@ -50,3 +50,130 @@ pub(crate) struct UnreachableCfgSelectPredicateWildcard {
#[label("always matches")]
pub wildcard_span: Span,
}
#[derive(Diagnostic)]
#[diag("must be a name of an associated function")]
pub(crate) struct MustBeNameOfAssociatedFunction {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("unsafe attribute used without unsafe")]
pub(crate) struct UnsafeAttrOutsideUnsafeLint {
#[label("usage of unsafe attribute")]
pub span: Span,
#[subdiagnostic]
pub suggestion: Option<crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion>,
}
#[derive(Diagnostic)]
#[diag(
"{$num_suggestions ->
[1] attribute must be of the form {$suggestions}
*[other] valid forms for the attribute are {$suggestions}
}"
)]
pub(crate) struct IllFormedAttributeInput {
pub num_suggestions: usize,
pub suggestions: DiagArgValue,
#[note("for more information, visit <{$docs}>")]
pub has_docs: bool,
pub docs: &'static str,
#[subdiagnostic]
help: Option<IllFormedAttributeInputHelp>,
}
impl IllFormedAttributeInput {
pub(crate) fn new(
suggestions: &[String],
docs: Option<&'static str>,
help: Option<&str>,
) -> Self {
Self {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
),
has_docs: docs.is_some(),
docs: docs.unwrap_or(""),
help: help.map(|h| IllFormedAttributeInputHelp { lint: h.to_string() }),
}
}
}
#[derive(Subdiagnostic)]
#[help(
"if you meant to silence a warning, consider using #![allow({$lint})] or #![expect({$lint})]"
)]
struct IllFormedAttributeInputHelp {
pub lint: String,
}
#[derive(Diagnostic)]
#[diag("unused attribute")]
#[note(
"{$valid_without_list ->
[true] using `{$attr_path}` with an empty list is equivalent to not using a list at all
*[other] using `{$attr_path}` with an empty list has no effect
}"
)]
pub(crate) struct EmptyAttributeList<'a> {
#[suggestion(
"{$valid_without_list ->
[true] remove these parentheses
*[other] remove this attribute
}",
code = "",
applicability = "machine-applicable"
)]
pub attr_span: Span,
pub attr_path: &'a str,
pub valid_without_list: bool,
}
#[derive(Diagnostic)]
#[diag("`#[{$name}]` attribute cannot be used on {$target}")]
#[warning(
"this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
)]
#[help("`#[{$name}]` can {$only}be applied to {$applied}")]
pub(crate) struct InvalidTargetLint {
pub name: String,
pub target: &'static str,
pub applied: DiagArgValue,
pub only: &'static str,
#[suggestion(
"remove the attribute",
code = "",
applicability = "machine-applicable",
style = "tool-only"
)]
pub attr_span: Span,
}
#[derive(Diagnostic)]
#[diag(
"{$is_used_as_inner ->
[false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]`
*[other] the `#![{$name}]` attribute can only be used at the crate root
}"
)]
pub(crate) struct InvalidAttrStyle<'a> {
pub name: &'a str,
pub is_used_as_inner: bool,
#[note("this attribute does not have an `!`, which means it is applied to this {$target}")]
pub target_span: Option<Span>,
pub target: &'static str,
}
#[derive(Diagnostic)]
#[diag("doc alias is duplicated")]
pub(crate) struct DocAliasDuplicated {
#[label("first defined here")]
pub first_definition: Span,
}
#[derive(Diagnostic)]
#[diag("only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`")]
pub(crate) struct DocAutoCfgExpectsHideOrShow;
+60 -21
View File
@@ -2,8 +2,9 @@
use rustc_ast as ast;
use rustc_ast::token::DocFragmentKind;
use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety};
use rustc_errors::{DiagCtxtHandle, MultiSpan};
use rustc_ast::{AttrItemKind, AttrStyle, CRATE_NODE_ID, NodeId, Safety};
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_errors::{Diag, DiagCtxtHandle, Level, MultiSpan};
use rustc_feature::{AttributeTemplate, Features};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
@@ -12,12 +13,22 @@
use rustc_session::lint::LintId;
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
use crate::attributes::AttributeSafety;
use crate::context::{AcceptContext, FinalizeContext, FinalizeFn, SharedContext, Stage};
use crate::early_parsed::{EARLY_PARSED_ATTRIBUTES, EarlyParsedState};
use crate::parser::{AllowExprMetavar, ArgParser, PathParser, RefPathParser};
use crate::session_diagnostics::ParsedDescription;
use crate::{Early, Late, OmitDoc, ShouldEmit};
pub enum EmitAttribute {
Static(AttributeLintKind),
Dynamic(
Box<
dyn for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static,
>,
),
}
/// Context created once, for example as part of the ast lowering
/// context, through which all attributes can be lowered.
pub struct AttributeParser<'sess, S: Stage = Late> {
@@ -51,18 +62,16 @@ pub fn parse_limited(
sess: &'sess Session,
attrs: &[ast::Attribute],
sym: &'static [Symbol],
target_span: Span,
target_node_id: NodeId,
features: Option<&'sess Features>,
) -> Option<Attribute> {
Self::parse_limited_should_emit(
sess,
attrs,
sym,
target_span,
target_node_id,
Target::Crate, // Does not matter, we're not going to emit errors anyways
features,
// Because we're not emitting warnings/errors, the target should not matter
DUMMY_SP,
CRATE_NODE_ID,
Target::Crate,
None,
ShouldEmit::Nothing,
)
}
@@ -118,7 +127,14 @@ pub fn parse_limited_all(
target,
OmitDoc::Skip,
std::convert::identity,
|lint_id, span, kind| sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind),
|lint_id, span, kind| match kind {
EmitAttribute::Static(kind) => {
sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind)
}
EmitAttribute::Dynamic(callback) => {
sess.psess.dyn_buffer_lint(lint_id.lint, span, target_node_id, callback)
}
},
)
}
@@ -135,6 +151,7 @@ pub fn parse_single<T>(
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser) -> Option<T>,
template: &AttributeTemplate,
allow_expr_metavar: AllowExprMetavar,
expected_safety: AttributeSafety,
) -> Option<T> {
let ast::AttrKind::Normal(normal_attr) = &attr.kind else {
panic!("parse_single called on a doc attr")
@@ -157,6 +174,7 @@ pub fn parse_single<T>(
attr.style,
path,
Some(normal_attr.item.unsafety),
expected_safety,
ParsedDescription::Attribute,
target_span,
target_node_id,
@@ -178,6 +196,7 @@ pub fn parse_single_args<T, I>(
attr_style: AttrStyle,
attr_path: AttrPath,
attr_safety: Option<Safety>,
expected_safety: AttributeSafety,
parsed_description: ParsedDescription,
target_span: Span,
target_node_id: NodeId,
@@ -195,11 +214,22 @@ pub fn parse_single_args<T, I>(
sess,
stage: Early { emit_errors },
};
let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: AttributeLintKind| {
sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind)
let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: EmitAttribute| match kind {
EmitAttribute::Static(kind) => {
sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind)
}
EmitAttribute::Dynamic(callback) => {
sess.psess.dyn_buffer_lint(lint_id.lint, span, target_node_id, callback)
}
};
if let Some(safety) = attr_safety {
parser.check_attribute_safety(&attr_path, inner_span, safety, &mut emit_lint)
parser.check_attribute_safety(
&attr_path,
inner_span,
safety,
expected_safety,
&mut emit_lint,
);
}
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
shared: SharedContext {
@@ -256,7 +286,7 @@ pub fn parse_attribute_list(
target: Target,
omit_doc: OmitDoc,
lower_span: impl Copy + Fn(Span) -> Span,
mut emit_lint: impl FnMut(LintId, MultiSpan, AttributeLintKind),
mut emit_lint: impl FnMut(LintId, MultiSpan, EmitAttribute),
) -> Vec<Attribute> {
let mut attributes = Vec::new();
// We store the attributes we intend to discard at the end of this function in order to
@@ -314,17 +344,18 @@ pub fn parse_attribute_list(
}
};
self.check_attribute_safety(
&attr_path,
lower_span(n.item.span()),
n.item.unsafety,
&mut emit_lint,
);
let parts =
n.item.path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>();
if let Some(accept) = S::parsers().accepters.get(parts.as_slice()) {
self.check_attribute_safety(
&attr_path,
lower_span(n.item.span()),
n.item.unsafety,
accept.safety,
&mut emit_lint,
);
let Some(args) = ArgParser::from_attr_args(
args,
&parts,
@@ -397,6 +428,14 @@ pub fn parse_attribute_list(
span: attr_span,
};
self.check_attribute_safety(
&attr_path,
lower_span(n.item.span()),
n.item.unsafety,
AttributeSafety::Normal,
&mut emit_lint,
);
if !matches!(self.stage.should_emit(), ShouldEmit::Nothing)
&& target == Target::Crate
{
+2 -1
View File
@@ -106,11 +106,12 @@
mod target_checking;
pub mod validate_attr;
pub use attributes::AttributeSafety;
pub use attributes::cfg::{
CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, parse_cfg_entry,
};
pub use attributes::cfg_select::*;
pub use attributes::util::{is_builtin_attr, parse_version};
pub use context::{Early, Late, OmitDoc, ShouldEmit};
pub use interface::AttributeParser;
pub use interface::{AttributeParser, EmitAttribute};
pub use session_diagnostics::ParsedDescription;
+22 -25
View File
@@ -1,14 +1,13 @@
use rustc_ast::Safety;
use rustc_errors::MultiSpan;
use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP};
use rustc_errors::{Diagnostic, MultiSpan};
use rustc_hir::AttrPath;
use rustc_hir::lints::AttributeLintKind;
use rustc_session::lint::LintId;
use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE;
use rustc_span::Span;
use crate::attributes::AttributeSafety;
use crate::context::Stage;
use crate::{AttributeParser, ShouldEmit};
use crate::{AttributeParser, EmitAttribute, ShouldEmit, errors};
impl<'sess, S: Stage> AttributeParser<'sess, S> {
pub fn check_attribute_safety(
@@ -16,28 +15,23 @@ pub fn check_attribute_safety(
attr_path: &AttrPath,
attr_span: Span,
attr_safety: Safety,
emit_lint: &mut impl FnMut(LintId, MultiSpan, AttributeLintKind),
expected_safety: AttributeSafety,
emit_lint: &mut impl FnMut(LintId, MultiSpan, EmitAttribute),
) {
if matches!(self.stage.should_emit(), ShouldEmit::Nothing) {
return;
}
let name = (attr_path.segments.len() == 1).then_some(attr_path.segments[0]);
// FIXME: We should retrieve this information from the attribute parsers instead of from `BUILTIN_ATTRIBUTE_MAP`
let builtin_attr_info = name.and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name));
let builtin_attr_safety = builtin_attr_info.map(|x| x.safety);
match (builtin_attr_safety, attr_safety) {
match (expected_safety, attr_safety) {
// - Unsafe builtin attribute
// - User wrote `#[unsafe(..)]`, which is permitted on any edition
(Some(AttributeSafety::Unsafe { .. }), Safety::Unsafe(..)) => {
(AttributeSafety::Unsafe { .. }, Safety::Unsafe(..)) => {
// OK
}
// - Unsafe builtin attribute
// - User did not write `#[unsafe(..)]`
(Some(AttributeSafety::Unsafe { unsafe_since }), Safety::Default) => {
(AttributeSafety::Unsafe { unsafe_since }, Safety::Default) => {
let path_span = attr_path.span;
// If the `attr_item`'s span is not from a macro, then just suggest
@@ -85,18 +79,24 @@ pub fn check_attribute_safety(
emit_lint(
LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE),
path_span.into(),
AttributeLintKind::UnsafeAttrOutsideUnsafe {
attribute_name_span: path_span,
sugg_spans: not_from_proc_macro
.then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())),
},
EmitAttribute::Dynamic(Box::new(move |dcx, level| {
errors::UnsafeAttrOutsideUnsafeLint {
span: path_span,
suggestion: not_from_proc_macro
.then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()))
.map(|(left, right)| {
crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion { left, right }
}),
}
.into_diag(dcx, level)
})),
)
}
}
// - Normal builtin attribute
// - Writing `#[unsafe(..)]` is not permitted on normal builtin attributes
(None | Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => {
(AttributeSafety::Normal, Safety::Unsafe(unsafe_span)) => {
self.stage.emit_err(
self.sess,
crate::session_diagnostics::InvalidAttrUnsafe {
@@ -108,14 +108,11 @@ pub fn check_attribute_safety(
// - Normal builtin attribute
// - No explicit `#[unsafe(..)]` written.
(None | Some(AttributeSafety::Normal), Safety::Default) => {
(AttributeSafety::Normal, Safety::Default) => {
// OK
}
(
Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None,
Safety::Safe(..),
) => {
(_, Safety::Safe(..)) => {
self.sess.dcx().span_delayed_bug(
attr_span,
"`check_attribute_safety` does not expect `Safety::Safe` on attributes",
@@ -1,17 +1,17 @@
use std::borrow::Cow;
use rustc_ast::AttrStyle;
use rustc_errors::{DiagArgValue, MultiSpan, StashKey};
use rustc_errors::{DiagArgValue, Diagnostic, MultiSpan, StashKey};
use rustc_feature::Features;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
use rustc_hir::{AttrItem, Attribute, MethodKind, Target};
use rustc_span::{BytePos, Span, Symbol, sym};
use crate::AttributeParser;
use crate::context::{AcceptContext, Stage};
use crate::errors::{
InvalidAttrAtCrateLevel, ItemFollowingInnerAttr, UnsupportedAttributesInWhere,
InvalidAttrAtCrateLevel, InvalidTargetLint, ItemFollowingInnerAttr,
UnsupportedAttributesInWhere,
};
use crate::session_diagnostics::InvalidTarget;
use crate::target_checking::Policy::Allow;
@@ -142,14 +142,19 @@ pub(crate) fn check_target(
};
let attr_span = cx.attr_span;
cx.emit_lint(
cx.emit_dyn_lint(
lint,
AttributeLintKind::InvalidTarget {
name: name.to_string(),
target: target.plural_name(),
only: if only { "only " } else { "" },
applied,
attr_span,
move |dcx, level| {
InvalidTargetLint {
name: name.to_string(),
target: target.plural_name(),
only: if only { "only " } else { "" },
applied: DiagArgValue::StrListSepByAnd(
applied.iter().map(|i| Cow::Owned(i.to_string())).collect(),
),
attr_span,
}
.into_diag(dcx, level)
},
attr_span,
);
@@ -176,15 +181,24 @@ pub(crate) fn check_crate_level(target: Target, cx: &mut AcceptContext<'_, 'sess
return;
}
let kind = AttributeLintKind::InvalidStyle {
name: cx.attr_path.to_string(),
is_used_as_inner: cx.attr_style == AttrStyle::Inner,
target: target.name(),
target_span: cx.target_span,
};
let name = cx.attr_path.to_string();
let is_used_as_inner = cx.attr_style == AttrStyle::Inner;
let target_span = cx.target_span;
let attr_span = cx.attr_span;
cx.emit_lint(rustc_session::lint::builtin::UNUSED_ATTRIBUTES, kind, attr_span);
cx.emit_dyn_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
move |dcx, level| {
crate::errors::InvalidAttrStyle {
name: &name,
is_used_as_inner,
target_span: (!is_used_as_inner).then_some(target_span),
target: target.name(),
}
.into_diag(dcx, level)
},
attr_span,
);
}
// FIXME: Fix "Cannot determine resolution" error and remove built-in macros
@@ -8,10 +8,9 @@
use rustc_ast::{
self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
};
use rustc_errors::{Applicability, FatalError, PResult};
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
use rustc_errors::{Applicability, Diagnostic, PResult};
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, template};
use rustc_hir::AttrPath;
use rustc_hir::lints::AttributeLintKind;
use rustc_parse::parse_in;
use rustc_session::errors::report_lit_error;
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
@@ -30,15 +29,22 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
// Check input tokens for built-in and key-value attributes.
match builtin_attr_info {
// `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
Some(BuiltinAttribute { name, template, .. }) => {
Some(BuiltinAttribute { name, .. }) => {
if AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(&name)) {
return;
}
match parse_meta(psess, attr) {
// Don't check safety again, we just did that
Ok(meta) => {
check_builtin_meta_item(psess, &meta, attr.style, *name, *template, false)
// FIXME The only unparsed builtin attributes that are left are the lint attributes, so we can hardcode the template here
let lint_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
assert!(lint_attrs.contains(name));
let template = template!(
List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
"https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
);
check_builtin_meta_item(psess, &meta, attr.style, *name, template, false)
}
Err(err) => {
err.emit();
@@ -169,7 +175,7 @@ pub fn check_builtin_meta_item(
}
}
fn emit_malformed_attribute(
pub fn emit_malformed_attribute(
psess: &ParseSess,
style: ast::AttrStyle,
span: Span,
@@ -203,14 +209,14 @@ fn emit_malformed_attribute(
suggestions.clear();
}
if should_warn(name) {
psess.buffer_lint(
let suggestions = suggestions.clone();
psess.dyn_buffer_lint(
ILL_FORMED_ATTRIBUTE_INPUT,
span,
ast::CRATE_NODE_ID,
AttributeLintKind::IllFormedAttributeInput {
suggestions: suggestions.clone(),
docs: template.docs,
help: None,
move |dcx, level| {
crate::errors::IllFormedAttributeInput::new(&suggestions, template.docs, None)
.into_diag(dcx, level)
},
);
} else {
@@ -231,15 +237,3 @@ fn emit_malformed_attribute(
err.emit();
}
}
pub fn emit_fatal_malformed_builtin_attribute(
psess: &ParseSess,
attr: &Attribute,
name: Symbol,
) -> ! {
let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").template;
emit_malformed_attribute(psess, attr.style, attr.span, name, template);
// This is fatal, otherwise it will likely cause a cascade of other errors
// (and an error here is expected to be very rare).
FatalError.raise()
}
@@ -14,7 +14,7 @@
};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex,
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, Unnormalized,
};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -275,7 +275,7 @@ fn nice_error<'infcx>(
// the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs`
// test. Check after #85499 lands to see if its fixes have erased this difference.
let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.normalize(&cause, param_env, value.value);
let _ = ocx.normalize(&cause, param_env, Unnormalized::new_wip(value.value));
let diag = try_extract_error_from_fulfill_cx(
&ocx,
@@ -322,7 +322,7 @@ fn nice_error<'infcx>(
let ocx = ObligationCtxt::new(&infcx);
let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.deeply_normalize(&cause, param_env, value.value);
let _ = ocx.deeply_normalize(&cause, param_env, Unnormalized::new_wip(value.value));
let diag = try_extract_error_from_fulfill_cx(
&ocx,
@@ -451,7 +451,7 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
(RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
_ => a_region == b_region,
};
let mut check = |c: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match c.kind {
let mut check = |c: Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match c.kind {
ConstraintKind::RegSubReg
if ((exact && c.sup == placeholder_region)
|| (!exact && regions_the_same(c.sup, placeholder_region)))
@@ -467,13 +467,23 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
{
Some((c.sub, cause.clone()))
}
_ => None,
ConstraintKind::VarSubVar
| ConstraintKind::RegSubVar
| ConstraintKind::VarSubReg
| ConstraintKind::RegSubReg => None,
ConstraintKind::VarEqVar | ConstraintKind::VarEqReg | ConstraintKind::RegEqReg => {
unreachable!()
}
};
let mut find_culprit = |exact_match: bool| {
region_constraints
.constraints
.iter()
.flat_map(|(constraint, cause)| {
constraint.iter_outlives().map(move |constraint| (constraint, cause))
})
.find_map(|(constraint, cause)| check(constraint, cause, exact_match))
};
@@ -754,19 +754,19 @@ fn suggest_borrow_generic_arg(
}
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
clauses.instantiate(tcx, new_args).predicates.iter().all(|clause| {
// Normalize before testing to see through type aliases and projections.
if let Ok(normalized) = tcx.try_normalize_erasing_regions(
self.infcx.typing_env(self.infcx.param_env),
clause,
) {
clause = normalized;
}
let normalized = tcx
.try_normalize_erasing_regions(
self.infcx.typing_env(self.infcx.param_env),
*clause,
)
.unwrap_or_else(|_| clause.skip_norm_wip());
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
tcx,
ObligationCause::dummy(),
self.infcx.param_env,
clause,
normalized,
))
})
}) {
@@ -4040,23 +4040,74 @@ pub(crate) fn report_illegal_reassignment(
if let Some(decl) = local_decl
&& decl.can_be_made_mutable()
{
let is_for_loop = matches!(
decl.local_info(),
LocalInfo::User(BindingForm::Var(VarBindingForm {
opt_match_place: Some((_, match_span)),
..
})) if matches!(match_span.desugaring_kind(), Some(DesugaringKind::ForLoop))
);
let message = if is_for_loop
let mut is_for_loop = false;
let mut is_ref_pattern = false;
if let LocalInfo::User(BindingForm::Var(VarBindingForm {
opt_match_place: Some((_, match_span)),
..
})) = *decl.local_info()
{
if matches!(match_span.desugaring_kind(), Some(DesugaringKind::ForLoop)) {
is_for_loop = true;
if let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(self.mir_def_id()) {
struct RefPatternFinder<'tcx> {
tcx: TyCtxt<'tcx>,
binding_span: Span,
is_ref_pattern: bool,
}
impl<'tcx> Visitor<'tcx> for RefPatternFinder<'tcx> {
type NestedFilter = OnlyBodies;
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
self.tcx
}
fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
if !self.is_ref_pattern
&& let hir::PatKind::Binding(_, _, ident, _) = pat.kind
&& ident.span == self.binding_span
{
self.is_ref_pattern =
self.tcx.hir_parent_iter(pat.hir_id).any(|(_, node)| {
matches!(
node,
hir::Node::Pat(hir::Pat {
kind: hir::PatKind::Ref(..),
..
})
)
});
}
hir::intravisit::walk_pat(self, pat);
}
}
let mut finder = RefPatternFinder {
tcx: self.infcx.tcx,
binding_span: decl.source_info.span,
is_ref_pattern: false,
};
finder.visit_body(body);
is_ref_pattern = finder.is_ref_pattern;
}
}
}
let (span, message) = if is_for_loop
&& is_ref_pattern
&& let Ok(binding_name) =
self.infcx.tcx.sess.source_map().span_to_snippet(decl.source_info.span)
{
format!("(mut {}) ", binding_name)
(decl.source_info.span, format!("(mut {})", binding_name))
} else {
"mut ".to_string()
(decl.source_info.span.shrink_to_lo(), "mut ".to_string())
};
err.span_suggestion_verbose(
decl.source_info.span.shrink_to_lo(),
span,
"consider making this binding mutable",
message,
Applicability::MachineApplicable,
@@ -4171,11 +4222,20 @@ fn annotate_argument_and_return_for_borrow(
if is_closure {
None
} else {
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
let ty = self
.infcx
.tcx
.type_of(self.mir_def_id())
.instantiate_identity()
.skip_norm_wip();
match ty.kind() {
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
self.mir_def_id(),
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
self.infcx
.tcx
.fn_sig(self.mir_def_id())
.instantiate_identity()
.skip_norm_wip(),
),
_ => None,
}
+10 -4
View File
@@ -1366,9 +1366,12 @@ fn explain_captures(
let parent_self_ty =
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
.then_some(parent_did)
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(def, ..) => Some(def.did()),
_ => None,
.and_then(|did| {
match tcx.type_of(did).instantiate_identity().skip_norm_wip().kind()
{
ty::Adt(def, ..) => Some(def.did()),
_ => None,
}
});
let is_option_or_result = parent_self_ty.is_some_and(|def_id| {
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
@@ -1445,7 +1448,10 @@ fn explain_captures(
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span,
BoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
tcx.fn_sig(method_did)
.instantiate(tcx, method_args)
.skip_norm_wip()
.input(0),
)
&& self.infcx.can_eq(self.infcx.param_env, ty, self_ty)
{
@@ -640,8 +640,9 @@ fn get_closure_bound_clause_span(
// Check whether one of the where-bounds requires the closure to impl `Fn[Mut]`
// or `AsyncFn[Mut]`.
for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) {
let pred = pred.skip_norm_wip();
let dominated_by_fn_trait = self
.closure_clause_kind(*pred, def_id, asyncness)
.closure_clause_kind(pred, def_id, asyncness)
.is_some_and(|kind| matches!(kind, ty::ClosureKind::Fn | ty::ClosureKind::FnMut));
if dominated_by_fn_trait {
// Found `<TyOfCapturingClosure as FnMut>` or
@@ -678,7 +679,7 @@ fn closure_clause_kind(
fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span: Span) {
match error {
GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => {
self.add_borrow_suggestions(err, span);
self.add_borrow_suggestions(err, span, !binds_to.is_empty());
if binds_to.is_empty() {
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
let place_desc = match self.describe_place(move_from.as_ref()) {
@@ -787,29 +788,67 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span
}
}
fn add_borrow_suggestions(&self, err: &mut Diag<'_>, span: Span) {
fn add_borrow_suggestions(
&self,
err: &mut Diag<'_>,
span: Span,
is_destructuring_pattern_move: bool,
) {
match self.infcx.tcx.sess.source_map().span_to_snippet(span) {
Ok(snippet) if snippet.starts_with('*') => {
let sp = span.with_lo(span.lo() + BytePos(1));
let inner = self.find_expr(sp);
let mut is_raw_ptr = false;
let mut is_ref = false;
let mut is_destructuring_assignment = false;
let mut is_nested_deref = false;
if let Some(inner) = inner {
is_nested_deref =
matches!(inner.kind, hir::ExprKind::Unary(hir::UnOp::Deref, _));
let typck_result = self.infcx.tcx.typeck(self.mir_def_id());
if let Some(inner_type) = typck_result.node_type_opt(inner.hir_id) {
if matches!(inner_type.kind(), ty::RawPtr(..)) {
is_raw_ptr = true;
} else if matches!(inner_type.kind(), ty::Ref(..)) {
is_ref = true;
}
}
is_destructuring_assignment =
self.infcx.tcx.hir_parent_iter(inner.hir_id).any(|(_, node)| {
matches!(
node,
hir::Node::LetStmt(&hir::LetStmt {
source: hir::LocalSource::AssignDesugar,
..
})
)
});
}
// If the `inner` is a raw pointer, do not suggest removing the "*", see #126863
// FIXME: need to check whether the assigned object can be a raw pointer, see `tests/ui/borrowck/issue-20801.rs`.
if !is_raw_ptr {
if is_raw_ptr {
return;
}
if !is_destructuring_pattern_move || is_ref {
err.span_suggestion_verbose(
span.with_hi(span.lo() + BytePos(1)),
"consider removing the dereference here",
String::new(),
Applicability::MaybeIncorrect,
);
} else if !is_destructuring_assignment && !is_nested_deref {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider borrowing here",
'&',
Applicability::MaybeIncorrect,
);
} else {
err.span_help(
span,
"destructuring assignment cannot borrow from this expression; consider using a `let` binding instead",
);
}
}
_ => {
@@ -493,7 +493,7 @@ pub(crate) fn report_mutability_error(
for (_, node) in self.infcx.tcx.hir_parent_iter(upvar_hir_id) {
if let Some(fn_decl) = node.fn_decl() {
if !matches!(
fn_decl.implicit_self,
fn_decl.implicit_self(),
hir::ImplicitSelfKind::RefImm | hir::ImplicitSelfKind::RefMut
) {
err.span_suggestion_verbose(
@@ -810,7 +810,7 @@ fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>) {
&& let Some(ty) = sig.decl.inputs.get(local.index() - 1)
&& let hir::TyKind::Ref(_, mut_ty) = ty.kind
&& let hir::Mutability::Not = mut_ty.mutbl
&& sig.decl.implicit_self.has_implicit_self()
&& sig.decl.implicit_self().has_implicit_self()
{
Some(ty.span)
} else {
@@ -1147,7 +1147,7 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
arg_pos
.and_then(|pos| {
sig.decl.inputs.get(
pos + if sig.decl.implicit_self.has_implicit_self() {
pos + if sig.decl.implicit_self().has_implicit_self() {
1
} else {
0
@@ -1410,9 +1410,20 @@ fn suggest_make_local_mut(&self, err: &mut Diag<'_>, local: Local, name: Symbol)
(span, " mut".to_owned(), true)
// If there is already a binding, we modify it to be `mut`.
} else if binding_exists {
// Shrink the span to just after the `&` in `&variable`.
let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
(span, "mut ".to_owned(), true)
// Replace the sigil with the mutable version. We may be dealing
// with parser recovery here and cannot assume the user actually
// typed `&` or `*const`, so we compute the prefix from the snippet.
let Ok(src) = self.infcx.tcx.sess.source_map().span_to_snippet(span) else {
return;
};
let (prefix_len, replacement) = if local_decl.ty.is_ref() {
(src.chars().next().map_or(0, char::len_utf8), "&mut ")
} else {
(src.find("const").map_or(1, |i| i + "const".len()), "*mut ")
};
let ws_len = src[prefix_len..].len() - src[prefix_len..].trim_start().len();
let span = span.with_hi(span.lo() + BytePos((prefix_len + ws_len) as u32));
(span, replacement.to_owned(), true)
} else {
// Otherwise, suggest that the user annotates the binding; We provide the
// type of the local.
@@ -9,6 +9,7 @@
use rustc_middle::mir::{self, ConstraintCategory, Location};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
Unnormalized,
};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
@@ -282,6 +283,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
.tcx
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, args)
.map(Unnormalized::skip_norm_wip)
{
bound.visit_with(self)?;
}
@@ -15,7 +15,8 @@
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint};
use rustc_middle::ty::{
self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, fold_regions,
self, FnSigKind, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor,
fold_regions,
};
use rustc_span::{Ident, Span, kw};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -595,7 +596,7 @@ fn report_fnmut_error(
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()
};
debug!("report_fnmut_error: output_ty={:?}", output_ty);
@@ -686,6 +687,8 @@ fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<
|| (*category == ConstraintCategory::Assignment
&& self.regioncx.universal_regions().defining_ty.is_fn_def())
|| self.regioncx.universal_regions().defining_ty.is_const()
|| (fr_name_and_span.is_none()
&& self.regioncx.universal_regions().defining_ty.is_fn_def())
{
return self.report_general_error(errci);
}
@@ -930,7 +933,7 @@ fn maybe_suggest_constrain_dyn_trait_impl(
debug!(?fn_did, ?args);
// Only suggest this on function calls, not closures
let ty = tcx.type_of(fn_did).instantiate_identity();
let ty = tcx.type_of(fn_did).instantiate_identity().skip_norm_wip();
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
if let ty::Closure(_, _) = ty.kind() {
return;
@@ -1050,7 +1053,8 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
else {
return;
};
let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind()
let ty::Closure(_, args) =
*tcx.type_of(closure_def_id).instantiate_identity().skip_norm_wip().kind()
else {
return;
};
@@ -1081,14 +1085,14 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
}
// Build a new closure where the return type is an owned value, instead of a ref.
let fn_sig_kind =
FnSigKind::default().set_safe(true).set_c_variadic(liberated_sig.c_variadic());
let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
liberated_sig.inputs().iter().copied(),
peeled_ty,
liberated_sig.c_variadic,
hir::Safety::Safe,
rustc_abi::ExternAbi::Rust,
fn_sig_kind,
)),
);
let closure_ty = Ty::new_closure(
@@ -1148,7 +1152,13 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
let ocx = ObligationCtxt::new(&self.infcx);
ocx.register_obligations(preds.iter().map(|(pred, span)| {
trace!(?pred);
Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred)
Obligation::misc(
tcx,
span,
self.mir_def_id(),
self.infcx.param_env,
pred.skip_norm_wip(),
)
}));
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 {
@@ -6,7 +6,7 @@
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty};
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -418,7 +418,7 @@ fn give_name_if_we_can_match_upvar_args(
// Get the parent fn's signature with liberated late-bound regions,
// so we have `ReLateParam` instead of `ReBound`.
let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity();
let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity().skip_norm_wip();
let liberated_sig = tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig);
let parent_param_ty = *liberated_sig.inputs().get(param_index)?;
@@ -1023,10 +1023,10 @@ fn give_name_if_anonymous_region_appears_in_impl_signature(
return None;
};
let found = tcx
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
r.kind() == ty::ReEarlyParam(region)
});
let found = tcx.any_free_region_meets(
&tcx.type_of(region_parent).instantiate_identity().skip_norm_wip(),
|r| r.kind() == ty::ReEarlyParam(region),
);
Some(RegionName {
name: self.synthesize_region_name(),
@@ -1051,12 +1051,15 @@ fn give_name_if_anonymous_region_appears_in_arg_position_impl_trait(
return None;
};
let predicates = self
let predicates: Vec<_> = self
.infcx
.tcx
.predicates_of(self.body.source.def_id())
.instantiate_identity(self.infcx.tcx)
.predicates;
.predicates
.into_iter()
.map(Unnormalized::skip_norm_wip)
.collect();
if let Some(upvar_index) = self
.regioncx
@@ -2,7 +2,7 @@
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::ty::{
self, GenericArgsRef, Region, RegionVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
self, Flags, GenericArgsRef, Region, RegionVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitor,
};
use tracing::{debug, instrument};
@@ -10,9 +10,9 @@
use rustc_macros::extension;
use rustc_middle::mir::{Body, ConstraintCategory};
use rustc_middle::ty::{
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg,
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, Flags, GenericArg,
GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt,
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions,
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions,
};
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::Span;
@@ -569,16 +569,17 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
};
// We erase all non-member region of the opaque and need to treat these as existentials.
let expected_ty =
ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| {
match re.kind() {
ty::ReErased => infcx.next_nll_region_var(
NllRegionVariableOrigin::Existential { name: None },
|| crate::RegionCtxt::Existential(None),
),
_ => re,
}
});
let expected_ty = ty::fold_regions(
tcx,
expected.ty.instantiate(tcx, key.args).skip_norm_wip(),
|re, _dbi| match re.kind() {
ty::ReErased => infcx.next_nll_region_var(
NllRegionVariableOrigin::Existential { name: None },
|| crate::RegionCtxt::Existential(None),
),
_ => re,
},
);
// We now simply equate the expected with the actual hidden type.
let locations = Locations::All(hidden_type.span);
@@ -598,8 +599,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
body.source.def_id().expect_local(),
);
// We need to normalize both types in the old solver before equatingt them.
let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty);
let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty);
let actual_ty = ocx.normalize(
&cause,
infcx.param_env,
Unnormalized::new_wip(hidden_type.ty),
);
let expected_ty =
ocx.normalize(&cause, infcx.param_env, Unnormalized::new_wip(expected_ty));
ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution)
},
"equating opaque types",
@@ -5,7 +5,7 @@
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_middle::bug;
use rustc_middle::mir::{Body, ConstraintCategory};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_trait_selection::solve::NoSolution;
@@ -189,7 +189,11 @@ pub(super) fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation
where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{
self.normalize_with_category(value, location, ConstraintCategory::Boring)
self.normalize_with_category(
Unnormalized::new_wip(value),
location,
ConstraintCategory::Boring,
)
}
pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
@@ -207,13 +211,14 @@ pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeL
#[instrument(skip(self), level = "debug")]
pub(super) fn normalize_with_category<T>(
&mut self,
value: T,
value: Unnormalized<'tcx, T>,
location: impl NormalizeLocation,
category: ConstraintCategory<'tcx>,
) -> T
where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{
let value = value.skip_normalization();
let param_env = self.infcx.param_env;
let result: Result<_, ErrorGuaranteed> = self.fully_perform_op(
location.to_locations(),
@@ -246,11 +251,7 @@ pub(super) fn struct_tail(
CustomTypeOp::new(
|ocx| {
let structurally_normalize = |ty| {
ocx.structurally_normalize_ty(
&cause,
param_env,
ty,
)
ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty))
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
};
@@ -295,7 +296,7 @@ pub(super) fn structurally_resolve(
body.source.def_id().expect_local(),
),
param_env,
ty,
Unnormalized::new_wip(ty),
)
.map_err(|_| NoSolution)
},
@@ -364,7 +365,7 @@ pub(super) fn ascribe_user_type_skip_wf(
// obligation for the unnormalized user_ty here. This is
// where the "incorrectly skips the WF checks we normally do"
// happens
let user_ty = ocx.normalize(&cause, param_env, user_ty);
let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty));
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
Ok(())
},
@@ -70,12 +70,14 @@ pub(crate) fn new(
#[instrument(skip(self), level = "debug")]
pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) {
let QueryRegionConstraints { outlives, assumptions } = query_constraints;
let QueryRegionConstraints { constraints, assumptions } = query_constraints;
let assumptions =
elaborate::elaborate_outlives_assumptions(self.infcx.tcx, assumptions.iter().copied());
for &(predicate, constraint_category) in outlives {
self.convert(predicate, constraint_category, &assumptions);
for &(constraint, constraint_category) in constraints {
constraint.iter_outlives().for_each(|predicate| {
self.convert(predicate, constraint_category, &assumptions);
});
}
}
@@ -292,8 +294,12 @@ fn normalize_and_add_type_outlives_constraints(
) {
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
// FIXME(higher_ranked_auto): What should we do with the assumptions here?
if let Some(QueryRegionConstraints { outlives, assumptions: _ }) = constraints {
next_outlives_predicates.extend(outlives.iter().copied());
if let Some(QueryRegionConstraints { constraints, assumptions: _ }) = constraints {
next_outlives_predicates.extend(constraints.iter().flat_map(
|(constraint, category)| {
constraint.iter_outlives().map(|outlives| (outlives, *category))
},
));
}
ty
}
@@ -32,6 +32,15 @@ pub(super) fn check_signature_annotation(&mut self) {
return;
}
// If the MIR body was constructed via `construct_error` (because an
// earlier pass like match checking failed), its args may not match
// the user-provided signature (e.g. a coroutine with too many
// parameters). Bail out as this can cause panic,
// see <https://github.com/rust-lang/rust/issues/139570>.
if self.body.tainted_by_errors.is_some() {
return;
}
let user_provided_poly_sig = self.tcx().closure_user_provided_sig(mir_def_id);
// Instantiate the canonicalized variables from user-provided signature
@@ -94,9 +103,7 @@ pub(super) fn check_signature_annotation(&mut self) {
user_provided_sig = self.tcx().mk_fn_sig(
user_provided_sig.inputs().iter().copied(),
output_ty,
user_provided_sig.c_variadic,
user_provided_sig.safety,
user_provided_sig.abi,
user_provided_sig.fn_sig_kind,
);
}
@@ -1015,7 +1015,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
if let ty::FnDef(def_id, _) = *src_ty.kind()
&& let ty::FnPtr(_, target_hdr) = *ty.kind()
&& tcx.codegen_fn_attrs(def_id).safe_target_features
&& target_hdr.safety.is_safe()
&& target_hdr.safety().is_safe()
&& let Some(safe_sig) = tcx.adjust_target_feature_sig(
def_id,
src_sig,
@@ -1759,7 +1759,8 @@ fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Locat
);
}
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
let unnormalized_ty =
tcx.type_of(static_def_id).instantiate_identity().skip_norm_wip();
let normalized_ty = self.normalize(unnormalized_ty, locations);
let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
@@ -1971,7 +1972,8 @@ fn check_call_inputs(
term_location: Location,
call_source: CallSource,
) {
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic())
{
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
}
@@ -585,7 +585,7 @@ fn defining_ty(&self) -> DefiningTy<'tcx> {
match tcx.hir_body_owner_kind(self.mir_def) {
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
let defining_ty = tcx.type_of(self.mir_def).instantiate_identity();
let defining_ty = tcx.type_of(self.mir_def).instantiate_identity().skip_norm_wip();
debug!("defining_ty (pre-replacement): {:?}", defining_ty);
@@ -780,7 +780,7 @@ fn compute_inputs_and_output(
}
DefiningTy::FnDef(def_id, _) => {
let sig = tcx.fn_sig(def_id).instantiate_identity();
let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let sig = indices.fold_to_region_vids(tcx, sig);
let inputs_and_output = sig.inputs_and_output();
@@ -804,7 +804,8 @@ fn compute_inputs_and_output(
.infcx
.tcx
.type_of(va_list_did)
.instantiate(self.infcx.tcx, &[region.into()]);
.instantiate(self.infcx.tcx, &[region.into()])
.skip_norm_wip();
// The signature needs to follow the order [input_tys, va_list_ty, output_ty]
return inputs_and_output.map_bound(|tys| {
@@ -822,7 +823,7 @@ fn compute_inputs_and_output(
// For a constant body, there are no inputs, and one
// "output" (the type of the constant).
assert_eq!(self.mir_def.to_def_id(), def_id);
let ty = tcx.type_of(self.mir_def).instantiate_identity();
let ty = tcx.type_of(self.mir_def).instantiate_identity().skip_norm_wip();
let ty = indices.fold_to_region_vids(tcx, ty);
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
@@ -834,9 +835,9 @@ fn compute_inputs_and_output(
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
}
DefiningTy::GlobalAsm(def_id) => {
ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()]))
}
DefiningTy::GlobalAsm(def_id) => ty::Binder::dummy(
tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity().skip_norm_wip()]),
),
};
// FIXME(#129952): We probably want a more principled approach here.
@@ -974,7 +975,7 @@ fn for_each_late_bound_region_in_item<'tcx>(
// only deduced that a param in the closure signature is late-bound from a constraint
// that we discover during typeck.
DefKind::Closure => {
let ty = tcx.type_of(mir_def_id).instantiate_identity();
let ty = tcx.type_of(mir_def_id).instantiate_identity().skip_norm_wip();
match *ty.kind() {
ty::Closure(_, args) => args.as_closure().sig().bound_vars(),
ty::CoroutineClosure(_, args) => {
+3 -1
View File
@@ -6,7 +6,8 @@
use rustc_ast::{AttrStyle, token};
use rustc_attr_parsing::parser::{AllowExprMetavar, MetaItemOrLitParser};
use rustc_attr_parsing::{
self as attr, AttributeParser, CFG_TEMPLATE, ParsedDescription, ShouldEmit, parse_cfg_entry,
self as attr, AttributeParser, AttributeSafety, CFG_TEMPLATE, ParsedDescription, ShouldEmit,
parse_cfg_entry,
};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_hir::attrs::CfgEntry;
@@ -53,6 +54,7 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result<CfgEntry,
AttrStyle::Inner,
AttrPath { segments: vec![sym::cfg].into_boxed_slice(), span },
None,
AttributeSafety::Normal,
ParsedDescription::Macro,
span,
cx.current_expansion.lint_node_id,
@@ -493,7 +493,7 @@ pub(crate) fn expand_ext(
match item {
Annotatable::Item(item) => {
let is_packed = matches!(
AttributeParser::parse_limited(cx.sess, &item.attrs, &[sym::repr], item.span, item.id, None),
AttributeParser::parse_limited(cx.sess, &item.attrs, &[sym::repr]),
Some(Attribute::Parsed(AttributeKind::Repr { reprs, .. })) if reprs.iter().any(|(x, _)| matches!(x, ReprPacked(..)))
);
@@ -80,6 +80,7 @@ fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> TyPat {
TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat)).collect())
}
ast::PatKind::Err(guar) => TyPatKind::Err(guar),
ast::PatKind::Paren(p) => pat_to_ty_pat(cx, *p).kind,
_ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
};
ty_pat(kind, pat.span)
@@ -1,7 +1,7 @@
use std::{mem, slice};
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{self as ast, HasNodeId, NodeId, attr};
use rustc_ast::{self as ast, NodeId, attr};
use rustc_ast_pretty::pprust;
use rustc_attr_parsing::AttributeParser;
use rustc_errors::DiagCtxtHandle;
@@ -109,9 +109,6 @@ fn collect_custom_derive(
self.session,
slice::from_ref(attr),
&[sym::proc_macro_derive],
item.span,
item.node_id(),
None,
)
else {
return;
+2 -9
View File
@@ -3,7 +3,7 @@
use std::{assert_matches, iter};
use rustc_ast::{self as ast, GenericParamKind, HasNodeId, attr, join_path_idents};
use rustc_ast::{self as ast, GenericParamKind, attr, join_path_idents};
use rustc_ast_pretty::pprust;
use rustc_attr_parsing::AttributeParser;
use rustc_errors::{Applicability, Diag, Level};
@@ -480,14 +480,7 @@ fn should_ignore_message(i: &ast::Item) -> Option<Symbol> {
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
if let Some(Attribute::Parsed(AttributeKind::ShouldPanic { reason, .. })) =
AttributeParser::parse_limited(
cx.sess,
&i.attrs,
&[sym::should_panic],
i.span,
i.node_id(),
None,
)
AttributeParser::parse_limited(cx.sess, &i.attrs, &[sym::should_panic])
{
ShouldPanic::Yes(reason)
} else {
@@ -61,7 +61,7 @@ pub fn inject(
// Do this here so that the test_runner crate attribute gets marked as used
// even in non-test builds
let test_runner = get_test_runner(sess, features, krate);
let test_runner = get_test_runner(sess, krate);
if sess.is_test_crate() {
let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) {
@@ -370,6 +370,8 @@ fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> Box<ast::Expr> {
let ecx = &cx.ext_cx;
let mut tests = cx.test_cases.clone();
// Note that this sort is load-bearing: the libtest harness uses binary search to find tests by
// name.
tests.sort_by(|a, b| a.name.as_str().cmp(b.name.as_str()));
ecx.expr_array_ref(
@@ -387,15 +389,8 @@ fn get_test_name(i: &ast::Item) -> Option<Symbol> {
attr::first_attr_value_str_by_name(&i.attrs, sym::rustc_test_marker)
}
fn get_test_runner(sess: &Session, features: &Features, krate: &ast::Crate) -> Option<ast::Path> {
match AttributeParser::parse_limited(
sess,
&krate.attrs,
&[sym::test_runner],
krate.spans.inner_span,
krate.id,
Some(features),
) {
fn get_test_runner(sess: &Session, krate: &ast::Crate) -> Option<ast::Path> {
match AttributeParser::parse_limited(sess, &krate.attrs, &[sym::test_runner]) {
Some(rustc_hir::Attribute::Parsed(AttributeKind::TestRunner(path))) => Some(path),
_ => None,
}
@@ -8,6 +8,7 @@
rustc_attrs,
rustc_private,
transparent_unions,
pattern_types,
auto_traits,
freeze_impls
)]
@@ -15,6 +16,30 @@
#![no_core]
#![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)]
#[lang = "pointee_trait"]
pub trait Pointee: PointeeSized {
#[lang = "metadata_type"]
// needed so that layout_of will return `TooGeneric` instead of `Unknown`
// when asked for the layout of `*const T`. Which is important for making
// transmutes between raw pointers (and especially pattern types of raw pointers)
// work.
type Metadata: Copy + Sync + Unpin + Freeze;
}
#[lang = "dyn_metadata"]
pub struct DynMetadata<Dyn: PointeeSized> {
_vtable_ptr: NonNull<VTable>,
_phantom: PhantomData<Dyn>,
}
unsafe extern "C" {
/// Opaque type for accessing vtables.
///
/// Private implementation detail of `DynMetadata::size_of` etc.
/// There is conceptually not actually any Abstract Machine memory behind this pointer.
type VTable;
}
#[lang = "pointee_sized"]
pub trait PointeeSized {}
@@ -105,7 +130,7 @@ unsafe impl<'a, T: PointeeSized> Sync for &'a T {}
unsafe impl<T: Sync, const N: usize> Sync for [T; N] {}
#[lang = "freeze"]
unsafe auto trait Freeze {}
pub unsafe auto trait Freeze {}
unsafe impl<T: PointeeSized> Freeze for PhantomData<T> {}
unsafe impl<T: PointeeSized> Freeze for *const T {}
@@ -570,10 +595,24 @@ pub trait Deref {
fn deref(&self) -> &Self::Target;
}
#[rustc_builtin_macro(pattern_type)]
#[macro_export]
macro_rules! pattern_type {
($($arg:tt)*) => {
/* compiler built-in */
};
}
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<pattern_type!(*const U is !null)> for pattern_type!(*const T is !null) where
T: Unsize<U>
{
}
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<pattern_type!(U is !null)> for pattern_type!(T is !null) {}
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
pub struct NonNull<T: PointeeSized>(pub *const T);
pub struct NonNull<T: PointeeSized>(pub pattern_type!(*const T is !null));
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
@@ -600,7 +639,16 @@ pub fn new(val: T) -> Box<T> {
let size = size_of::<T>();
let ptr = libc::malloc(size);
intrinsics::copy(&val as *const T as *const u8, ptr, size);
Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global)
Box(
Unique {
pointer: NonNull(intrinsics::transmute::<
*mut u8,
pattern_type!(*const T is !null),
>(ptr)),
_marker: PhantomData,
},
Global,
)
}
}
}
@@ -609,7 +657,9 @@ impl<T: ?Sized, A> Drop for Box<T, A> {
fn drop(&mut self) {
// inner value is dropped by compiler
unsafe {
libc::free(self.0.pointer.0 as *mut u8);
libc::free(intrinsics::transmute::<pattern_type!(*const T is !null), *const T>(
self.0.pointer.0,
) as *mut u8);
}
}
}
@@ -1,4 +1,13 @@
#![feature(no_core, lang_items, never_type, extern_types, thread_local, repr_simd, rustc_private)]
#![feature(
no_core,
lang_items,
never_type,
extern_types,
thread_local,
repr_simd,
pattern_types,
rustc_private
)]
#![cfg_attr(not(any(jit, target_vendor = "apple", windows)), feature(linkage))]
#![no_core]
#![allow(dead_code, non_camel_case_types, internal_features)]
@@ -153,7 +162,10 @@ extern "C" fn bool_struct_in_11(_arg0: bool_11) {}
#[allow(unreachable_code)] // FIXME false positive
fn main() {
take_unique(Unique { pointer: unsafe { NonNull(1 as *mut ()) }, _marker: PhantomData });
take_unique(Unique {
pointer: unsafe { NonNull(intrinsics::transmute(1 as *mut ())) },
_marker: PhantomData,
});
take_f32(0.1);
call_return_u128_pair();
@@ -219,7 +231,12 @@ fn main() {
let noisy_unsized_drop = const { intrinsics::needs_drop::<NoisyDropUnsized>() };
assert!(noisy_unsized_drop);
Unique { pointer: NonNull(1 as *mut &str), _marker: PhantomData } as Unique<dyn SomeTrait>;
Unique {
pointer: NonNull(intrinsics::transmute::<_, pattern_type!(*const &str is !null)>(
1 as *mut &str,
)),
_marker: PhantomData,
} as Unique<dyn SomeTrait>;
struct MyDst<T: ?Sized>(T);
@@ -26,7 +26,9 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
(RegKind::Float, 4) => types::F32,
(RegKind::Float, 8) => types::F64,
(RegKind::Float, 16) => types::F128,
(RegKind::Vector, size) => types::I8.by(u32::try_from(size).unwrap()).unwrap(),
(RegKind::Vector { hint_vector_elem: _ }, size) => {
types::I8.by(u32::try_from(size).unwrap()).unwrap()
}
_ => unreachable!("{:?}", reg),
};
AbiParam::new(clif_ty)
@@ -19,6 +19,7 @@
use rustc_codegen_ssa::debuginfo::type_names;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefIdMap;
use rustc_middle::ty::Unnormalized;
use rustc_session::Session;
use rustc_session::config::DebugInfo;
use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId};
@@ -244,7 +245,10 @@ pub(crate) fn define_function<'tcx>(
type_names::push_generic_args(
tcx,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args),
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(args),
),
&mut name,
);
@@ -1,6 +1,6 @@
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use rustc_hir::LangItem;
use rustc_middle::ty::{AssocTag, GenericArg};
use rustc_middle::ty::{AssocTag, GenericArg, Unnormalized};
use rustc_session::config::EntryFnType;
use rustc_span::{DUMMY_SP, Ident};
@@ -50,7 +50,7 @@ fn create_entry_fn(
// listing.
let main_ret_ty = tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
main_ret_ty.no_bound_vars().unwrap(),
Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()),
);
let cmain_sig = Signature {
@@ -98,7 +98,7 @@ pub(crate) fn by_val_pair(
/// Create an instance of a ZST
///
/// The is represented by a dangling pointer of suitable alignment.
/// The ZST is represented by a dangling pointer of suitable alignment.
pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> {
assert!(layout.is_zst());
CValue::by_ref(crate::Pointer::dangling(layout.align.abi), layout)
@@ -870,20 +870,10 @@ pub(crate) fn assert_assignable<'tcx>(
let from_sig = fx
.tcx
.normalize_erasing_late_bound_regions(fx.typing_env(), from_ty.fn_sig(fx.tcx));
let FnSig {
inputs_and_output: types_from,
c_variadic: c_variadic_from,
safety: unsafety_from,
abi: abi_from,
} = from_sig;
let FnSig { inputs_and_output: types_from, fn_sig_kind: fn_sig_kind_from } = from_sig;
let to_sig =
fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to_ty.fn_sig(fx.tcx));
let FnSig {
inputs_and_output: types_to,
c_variadic: c_variadic_to,
safety: unsafety_to,
abi: abi_to,
} = to_sig;
let FnSig { inputs_and_output: types_to, fn_sig_kind: fn_sig_kind_to } = to_sig;
let mut types_from = types_from.iter();
let mut types_to = types_to.iter();
loop {
@@ -894,17 +884,7 @@ pub(crate) fn assert_assignable<'tcx>(
}
}
assert_eq!(
c_variadic_from, c_variadic_to,
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
from_sig, to_sig, fx,
);
assert_eq!(
unsafety_from, unsafety_to,
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
from_sig, to_sig, fx,
);
assert_eq!(
abi_from, abi_to,
fn_sig_kind_from, fn_sig_kind_to,
"Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}",
from_sig, to_sig, fx,
);
@@ -9,6 +9,7 @@
transparent_unions,
auto_traits,
freeze_impls,
pattern_types,
thread_local
)]
#![no_core]
@@ -580,9 +581,16 @@ impl Allocator for () {}
impl Allocator for Global {}
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
pub struct NonNull<T: PointeeSized>(pub *const T);
pub struct NonNull<T: PointeeSized>(pub pattern_type!(*const T is !null));
#[rustc_builtin_macro(pattern_type)]
#[macro_export]
macro_rules! pattern_type {
($($arg:tt)*) => {
/* compiler built-in */
};
}
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
+3 -1
View File
@@ -90,7 +90,9 @@ fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, '_>) -> Type<'gcc> {
64 => cx.type_f64(),
_ => bug!("unsupported float: {:?}", self),
},
RegKind::Vector => cx.type_vector(cx.type_i8(), self.size.bytes()),
RegKind::Vector { hint_vector_elem: _ } => {
cx.type_vector(cx.type_i8(), self.size.bytes())
}
}
}
}
@@ -7,8 +7,6 @@
#[cfg(feature = "master")]
use gccjit::Type;
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
#[cfg(feature = "master")]
use rustc_abi::ExternAbi;
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::base::wants_msvc_seh;
@@ -1483,32 +1481,26 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
// `unsafe fn(*mut i8) -> ()`
let try_fn_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(
iter::once(i8p),
tcx.types.unit,
false,
rustc_hir::Safety::Unsafe,
ExternAbi::Rust,
)),
);
// `unsafe fn(*mut i8, *mut i8) -> ()`
let catch_fn_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(
[i8p, i8p].iter().cloned(),
tcx.types.unit,
false,
rustc_hir::Safety::Unsafe,
ExternAbi::Rust,
)),
);
// `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi(
[try_fn_ty, i8p, catch_fn_ty],
tcx.types.i32,
false,
rustc_hir::Safety::Unsafe,
ExternAbi::Rust,
));
let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
cx.rust_try_fn.set(Some(rust_try));
@@ -16,7 +16,7 @@
use rustc_hir as hir;
use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, Ty, Unnormalized};
use rustc_span::{Span, Symbol, sym};
use crate::builder::Builder;
@@ -539,7 +539,10 @@ macro_rules! require_simd2 {
match *in_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
bx.tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(ty),
)
});
require!(
metadata.is_unit(),
@@ -553,7 +556,10 @@ macro_rules! require_simd2 {
match *out_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
bx.tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(ty),
)
});
require!(
metadata.is_unit(),
+29 -4
View File
@@ -2,8 +2,8 @@
use libc::c_uint;
use rustc_abi::{
ArmCall, BackendRepr, CanonAbi, HasDataLayout, InterruptKind, Primitive, Reg, RegKind, Size,
X86Call,
ArmCall, BackendRepr, CanonAbi, Float, HasDataLayout, Integer, InterruptKind, Primitive, Reg,
RegKind, Size, X86Call,
};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
@@ -38,11 +38,12 @@ fn apply_attrs_to_callsite(
const ABI_AFFECTING_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 1] =
[(ArgAttribute::InReg, llvm::AttributeKind::InReg)];
const OPTIMIZATION_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 4] = [
const OPTIMIZATION_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 5] = [
(ArgAttribute::NoAlias, llvm::AttributeKind::NoAlias),
(ArgAttribute::NonNull, llvm::AttributeKind::NonNull),
(ArgAttribute::ReadOnly, llvm::AttributeKind::ReadOnly),
(ArgAttribute::NoUndef, llvm::AttributeKind::NoUndef),
(ArgAttribute::Writable, llvm::AttributeKind::Writable),
];
const CAPTURES_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 3] = [
@@ -137,7 +138,31 @@ fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
128 => cx.type_f128(),
_ => bug!("unsupported float: {:?}", self),
},
RegKind::Vector => cx.type_vector(cx.type_i8(), self.size.bytes()),
RegKind::Vector { hint_vector_elem } => {
// NOTE: it is valid to ignore the element type hint (and always pick i8).
// But providing a more accurate type means fewer casts in LLVM IR,
// which helps with optimization.
let ty = match hint_vector_elem {
Primitive::Int(integer, _) => match integer {
Integer::I8 => cx.type_ix(8),
Integer::I16 => cx.type_ix(16),
Integer::I32 => cx.type_ix(32),
Integer::I64 => cx.type_ix(64),
Integer::I128 => cx.type_ix(128),
},
Primitive::Float(float) => match float {
Float::F16 => cx.type_f16(),
Float::F32 => cx.type_f32(),
Float::F64 => cx.type_f64(),
Float::F128 => cx.type_f128(),
},
Primitive::Pointer(_) => cx.type_ptr(),
};
assert!(self.size.bytes().is_multiple_of(hint_vector_elem.size(cx).bytes()));
let len = self.size.bytes() / hint_vector_elem.size(cx).bytes();
cx.type_vector(ty, len)
}
}
}
}
@@ -16,7 +16,8 @@
HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA,
};
use rustc_middle::ty::{
self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt,
Unnormalized, Visibility,
};
use rustc_session::config::{self, DebugInfo, Lto};
use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene};
@@ -1234,7 +1235,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
}
};
assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t)));
assert!(
up_var_tys
.iter()
.all(|t| t
== cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(t)))
);
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let layout = cx.layout_of(closure_or_coroutine_ty);
@@ -1418,7 +1424,9 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
let template_params: SmallVec<_> = iter::zip(args, names)
.filter_map(|(kind, name)| {
kind.as_type().map(|ty| {
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
let actual_type = cx
.tcx
.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty));
let actual_type_di_node = type_di_node(cx, actual_type);
Some(cx.create_template_type_parameter(name.as_str(), actual_type_di_node))
})
@@ -7,7 +7,7 @@
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable;
use rustc_middle::bug;
use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt, Unnormalized};
use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use crate::common::CodegenCx;
@@ -50,14 +50,23 @@ pub(super) enum UniqueTypeId<'tcx> {
impl<'tcx> UniqueTypeId<'tcx> {
pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t));
assert_eq!(
t,
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(t)
)
);
UniqueTypeId::Ty(t, private::HiddenZst)
}
pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
assert_eq!(
enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(enum_ty)
)
);
UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
}
@@ -69,7 +78,10 @@ pub(crate) fn for_enum_variant_struct_type(
) -> Self {
assert_eq!(
enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(enum_ty)
)
);
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
}
@@ -81,7 +93,10 @@ pub(crate) fn for_enum_variant_struct_type_wrapper(
) -> Self {
assert_eq!(
enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(enum_ty)
)
);
UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
}
@@ -93,11 +108,17 @@ pub(crate) fn for_vtable_ty(
) -> Self {
assert_eq!(
self_type,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type)
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(self_type)
)
);
assert_eq!(
implemented_trait,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait)
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(implemented_trait)
)
);
UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst)
}
@@ -17,7 +17,7 @@
use rustc_index::IndexVec;
use rustc_middle::mir;
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt};
use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt, Unnormalized};
use rustc_session::Session;
use rustc_session::config::{self, DebugInfo};
use rustc_span::{
@@ -458,7 +458,7 @@ fn dbg_scope_fn(
type_names::push_generic_args(
tcx,
tcx.normalize_erasing_regions(self.typing_env(), args),
tcx.normalize_erasing_regions(self.typing_env(), Unnormalized::new_wip(args)),
&mut name,
);
@@ -595,7 +595,10 @@ fn get_template_parameters<'ll, 'tcx>(
iter::zip(args, names)
.filter_map(|(kind, name)| {
kind.as_type().map(|ty| {
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
let actual_type = cx.tcx.normalize_erasing_regions(
cx.typing_env(),
Unnormalized::new_wip(ty),
);
let actual_type_metadata = type_di_node(cx, actual_type);
Some(cx.create_template_type_parameter(
name.as_str(),
+58 -54
View File
@@ -3,7 +3,7 @@
use std::{assert_matches, iter, ptr};
use rustc_abi::{
Align, BackendRepr, ExternAbi, Float, HasDataLayout, NumScalableVectors, Primitive, Size,
Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, Size,
WrappingRange,
};
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
@@ -18,7 +18,9 @@
use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
use rustc_middle::ty::offload_meta::OffloadMetadata;
use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv};
use rustc_middle::ty::{
self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv, Unnormalized,
};
use rustc_middle::{bug, span_bug};
use rustc_session::config::CrateType;
use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC;
@@ -285,38 +287,54 @@ fn codegen_intrinsic_call(
}
sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]),
sym::va_arg => {
match result.layout.backend_repr {
BackendRepr::Scalar(scalar) => {
match scalar.primitive() {
Primitive::Int(..) => {
if self.cx().size_of(result.layout.ty).bytes() < 4 {
// `va_arg` should not be called on an integer type
// less than 4 bytes in length. If it is, promote
// the integer to an `i32` and truncate the result
// back to the smaller type.
let promoted_result = emit_va_arg(self, args[0], tcx.types.i32);
self.trunc(promoted_result, result.layout.llvm_type(self))
} else {
emit_va_arg(self, args[0], result.layout.ty)
}
}
Primitive::Float(Float::F16) => {
bug!("the va_arg intrinsic does not work with `f16`")
}
Primitive::Float(Float::F64) | Primitive::Pointer(_) => {
emit_va_arg(self, args[0], result.layout.ty)
}
// `va_arg` should never be used with the return type f32.
Primitive::Float(Float::F32) => {
bug!("the va_arg intrinsic does not work with `f32`")
}
Primitive::Float(Float::F128) => {
bug!("the va_arg intrinsic does not work with `f128`")
}
let BackendRepr::Scalar(scalar) = result.layout.backend_repr else {
bug!("the va_arg intrinsic does not support non-scalar types")
};
// We reject types that would never be passed as varargs in C because
// they get promoted to a larger type, specifically integers smaller than
// c_int and float type smaller than c_double.
match scalar.primitive() {
Primitive::Pointer(_) => {
// Pointers are always OK.
}
Primitive::Int(Integer::I128, _) => {
// FIXME: maybe we should support these? At least on 32-bit powerpc
// the logic in LLVM does not handle i128 correctly though.
bug!("the va_arg intrinsic does not support `i128`/`u128`")
}
Primitive::Int(..) => {
let int_width = self.cx().size_of(result.layout.ty).bits();
let target_c_int_width = self.cx().sess().target.options.c_int_width;
if int_width < u64::from(target_c_int_width) {
// Smaller integer types are automatically promototed and `va_arg`
// should not be called on them.
bug!(
"va_arg got i{} but needs at least c_int (an i{})",
int_width,
target_c_int_width
);
}
}
_ => bug!("the va_arg intrinsic does not work with non-scalar types"),
Primitive::Float(Float::F16) => {
bug!("the va_arg intrinsic does not support `f16`")
}
Primitive::Float(Float::F32) => {
// c_double is actually f32 on avr.
if self.cx().sess().target.arch != Arch::Avr {
bug!("the va_arg intrinsic does not support `f32` on this target")
}
}
Primitive::Float(Float::F64) => {
// 64-bit floats are always OK.
}
Primitive::Float(Float::F128) => {
// FIXME(f128) figure out whether we should support this.
bug!("the va_arg intrinsic does not support `f128`")
}
}
emit_va_arg(self, args[0], result.layout.ty)
}
sym::volatile_load | sym::unaligned_volatile_load => {
@@ -805,12 +823,12 @@ fn codegen_llvm_intrinsic_call(
let fn_ty = instance.ty(tcx, self.typing_env());
let fn_sig = match *fn_ty.kind() {
ty::FnDef(def_id, args) => {
tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args))
}
ty::FnDef(def_id, args) => tcx.instantiate_bound_regions_with_erased(
tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(),
),
_ => unreachable!(),
};
assert!(!fn_sig.c_variadic);
assert!(!fn_sig.c_variadic());
let ret_layout = self.layout_of(fn_sig.output());
let llreturn_ty = if ret_layout.is_zst() {
@@ -1654,32 +1672,18 @@ fn get_rust_try_fn<'a, 'll, 'tcx>(
// `unsafe fn(*mut i8) -> ()`
let try_fn_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
[i8p],
tcx.types.unit,
false,
hir::Safety::Unsafe,
ExternAbi::Rust,
)),
ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p], tcx.types.unit, hir::Safety::Unsafe)),
);
// `unsafe fn(*mut i8, *mut i8) -> ()`
let catch_fn_ty = Ty::new_fn_ptr(
tcx,
ty::Binder::dummy(tcx.mk_fn_sig(
[i8p, i8p],
tcx.types.unit,
false,
hir::Safety::Unsafe,
ExternAbi::Rust,
)),
ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p, i8p], tcx.types.unit, hir::Safety::Unsafe)),
);
// `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi(
[try_fn_ty, i8p, catch_fn_ty],
tcx.types.i32,
false,
hir::Safety::Unsafe,
ExternAbi::Rust,
));
let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
cx.rust_try_fn.set(Some(rust_try));
@@ -2962,7 +2966,7 @@ macro_rules! bitwise_red {
match in_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
bx.tcx.normalize_erasing_regions(bx.typing_env(), Unnormalized::new_wip(ty))
});
require!(
metadata.is_unit(),
@@ -2976,7 +2980,7 @@ macro_rules! bitwise_red {
match out_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
bx.tcx.normalize_erasing_regions(bx.typing_env(), Unnormalized::new_wip(ty))
});
require!(
metadata.is_unit(),
+12 -4
View File
@@ -27,7 +27,7 @@
use rustc_middle::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions};
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::ty::{self, Instance, PatternKind, Ty, TyCtxt, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType};
@@ -273,6 +273,13 @@ pub(crate) fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let src_ty = src.layout.ty;
let dst_ty = dst.layout.ty;
match (src_ty.kind(), dst_ty.kind()) {
(&ty::Pat(s, sp), &ty::Pat(d, dp))
if let (PatternKind::NotNull, PatternKind::NotNull) = (*sp, *dp) =>
{
let src = src.project_type(bx, s);
let dst = dst.project_type(bx, d);
coerce_unsized_into(bx, src, dst)
}
(&ty::Ref(..), &ty::Ref(..) | &ty::RawPtr(..)) | (&ty::RawPtr(..), &ty::RawPtr(..)) => {
let (base, info) = match bx.load_operand(src).val {
OperandValue::Pair(base, info) => unsize_ptr(bx, base, src_ty, dst_ty, Some(info)),
@@ -512,9 +519,10 @@ fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// late-bound regions, since late-bound
// regions must appear in the argument
// listing.
let main_ret_ty = cx
.tcx()
.normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap());
let main_ret_ty = cx.tcx().normalize_erasing_regions(
cx.typing_env(),
Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()),
);
let Some(llfn) = cx.declare_c_main(llfty) else {
// FIXME: We should be smart and show a better diagnostic here.
@@ -22,7 +22,9 @@
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability};
use rustc_middle::bug;
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::{self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt};
use rustc_middle::ty::{
self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt, Unnormalized,
};
use smallvec::SmallVec;
use crate::debuginfo::wants_c_like_enum_debuginfo;
@@ -364,10 +366,10 @@ fn push_debuginfo_type_name<'tcx>(
}
output.push_str(" (*)(");
} else {
output.push_str(sig.safety.prefix_str());
output.push_str(sig.safety().prefix_str());
if sig.abi != rustc_abi::ExternAbi::Rust {
let _ = write!(output, "extern {} ", sig.abi);
if sig.abi() != rustc_abi::ExternAbi::Rust {
let _ = write!(output, "extern {} ", sig.abi());
}
output.push_str("fn(");
@@ -381,7 +383,7 @@ fn push_debuginfo_type_name<'tcx>(
pop_arg_separator(output);
}
if sig.c_variadic {
if sig.c_variadic() {
if !sig.inputs().is_empty() {
output.push_str(", ...");
} else {
@@ -540,8 +542,10 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
}
if let Some(trait_ref) = trait_ref {
let trait_ref =
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
let trait_ref = tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(trait_ref),
);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear();
push_generic_args_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
@@ -654,7 +658,13 @@ fn push_generic_args_internal<'tcx>(
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
) -> bool {
assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args));
assert_eq!(
args,
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(args)
)
);
let mut args = args.non_erasable_generics().peekable();
if args.peek().is_none() {
return false;
+3 -3
View File
@@ -1069,7 +1069,7 @@ pub(crate) struct TargetFeatureSafeTrait {
#[derive(Diagnostic)]
#[diag("target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason}")]
pub struct ForbiddenTargetFeatureAttr<'a> {
pub(crate) struct ForbiddenTargetFeatureAttr<'a> {
#[primary_span]
pub span: Span,
pub feature: &'a str,
@@ -1211,7 +1211,7 @@ pub(crate) struct ForbiddenCTargetFeature<'a> {
pub reason: &'a str,
}
pub struct TargetFeatureDisableOrEnable<'a> {
pub(crate) struct TargetFeatureDisableOrEnable<'a> {
pub features: &'a [&'a str],
pub span: Option<Span>,
pub missing_features: Option<MissingFeatures>,
@@ -1219,7 +1219,7 @@ pub struct TargetFeatureDisableOrEnable<'a> {
#[derive(Subdiagnostic)]
#[help("add the missing features in a `target_feature` attribute")]
pub struct MissingFeatures;
pub(crate) struct MissingFeatures;
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
+55 -11
View File
@@ -8,7 +8,7 @@
use rustc_middle::{bug, ty};
use rustc_span::sym;
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
use rustc_target::spec::{Arch, BinaryFormat};
use rustc_target::spec::{Arch, BinaryFormat, Env, Os};
use crate::common;
use crate::mir::AsmCodegenMethods;
@@ -128,6 +128,8 @@ fn prefix_and_suffix<'tcx>(
let is_arm = tcx.sess.target.arch == Arch::Arm;
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
let function_sections =
tcx.sess.opts.unstable_opts.function_sections.unwrap_or(tcx.sess.target.function_sections);
// If we're compiling the compiler-builtins crate, e.g., the equivalent of
// compiler-rt, then we want to implicitly compile everything with hidden
@@ -218,8 +220,6 @@ fn prefix_and_suffix<'tcx>(
let mut end = String::new();
match asm_binary_format {
BinaryFormat::Elf => {
let section = link_section.unwrap_or_else(|| format!(".text.{asm_name}"));
let progbits = match is_arm {
true => "%progbits",
false => "@progbits",
@@ -230,7 +230,13 @@ fn prefix_and_suffix<'tcx>(
false => "@function",
};
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
if let Some(section) = &link_section {
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
} else if function_sections {
writeln!(begin, ".pushsection .text.{asm_name},\"ax\", {progbits}").unwrap();
} else {
writeln!(begin, ".text").unwrap();
}
writeln!(begin, ".balign {align_bytes}").unwrap();
write_linkage(&mut begin).unwrap();
match visibility {
@@ -249,14 +255,22 @@ fn prefix_and_suffix<'tcx>(
// pattern match on assembly generated by LLVM.
writeln!(end, ".Lfunc_end_{asm_name}:").unwrap();
writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap();
writeln!(end, ".popsection").unwrap();
if link_section.is_some() || function_sections {
writeln!(end, ".popsection").unwrap();
}
if !arch_suffix.is_empty() {
writeln!(end, "{}", arch_suffix).unwrap();
}
}
BinaryFormat::MachO => {
let section = link_section.unwrap_or_else(|| "__TEXT,__text".to_string());
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
// NOTE: LLVM ignores `-Zfunction-sections` on macos. Instead the Mach-O symbol
// subsection splitting feature is used, which can be enabled with the
// `.subsections_via_symbols` global directive. LLVM already enables this directive.
if let Some(section) = &link_section {
writeln!(begin, ".pushsection {section},regular,pure_instructions").unwrap();
} else {
writeln!(begin, ".section __TEXT,__text,regular,pure_instructions").unwrap();
}
writeln!(begin, ".balign {align_bytes}").unwrap();
write_linkage(&mut begin).unwrap();
match visibility {
@@ -267,7 +281,9 @@ fn prefix_and_suffix<'tcx>(
writeln!(end).unwrap();
writeln!(end, ".Lfunc_end_{asm_name}:").unwrap();
writeln!(end, ".popsection").unwrap();
if link_section.is_some() {
writeln!(end, ".popsection").unwrap();
}
if !arch_suffix.is_empty() {
writeln!(end, "{}", arch_suffix).unwrap();
}
@@ -278,8 +294,36 @@ fn prefix_and_suffix<'tcx>(
writeln!(begin, ".type 32").unwrap();
writeln!(begin, ".endef").unwrap();
let section = link_section.unwrap_or_else(|| format!(".text.{asm_name}"));
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
if let Some(section) = &link_section {
writeln!(begin, ".section {section},\"xr\"").unwrap()
} else if !function_sections {
// Function sections are enabled by default on MSVC and windows-gnullvm,
// but disabled by default on GNU.
writeln!(begin, ".text").unwrap();
} else {
// LLVM uses an extension to the section directive to support defining multiple
// sections with the same name and comdat. It adds `unique,<id>` at the end of the
// `.section` directive. We have no way of generating that unique ID here, so don't
// emit it.
//
// See https://llvm.org/docs/Extensions.html#id2.
match &tcx.sess.target.options.env {
Env::Gnu => {
writeln!(begin, ".section .text${asm_name},\"xr\",one_only,{asm_name}")
.unwrap();
}
Env::Msvc => {
writeln!(begin, ".section .text,\"xr\",one_only,{asm_name}").unwrap();
}
Env::Unspecified => match &tcx.sess.target.options.os {
Os::Uefi => {
writeln!(begin, ".section .text,\"xr\",one_only,{asm_name}").unwrap();
}
_ => bug!("unexpected coff target {}", tcx.sess.target.llvm_target),
},
other => bug!("unexpected coff env {other:?}"),
}
}
write_linkage(&mut begin).unwrap();
writeln!(begin, ".balign {align_bytes}").unwrap();
writeln!(begin, "{asm_name}:").unwrap();
@@ -421,7 +465,7 @@ fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_t
..=8 => "f64",
_ => ptr_type,
},
RegKind::Vector => "v128",
RegKind::Vector { .. } => "v128",
};
signature.push_str(wrapped_wasm_type);
@@ -399,8 +399,9 @@ fn revalidate_conditional_constness(
ty::BoundConstness::Const
}
};
let const_conditions =
ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions);
let const_conditions = const_conditions.into_iter().map(|(c, s)| {
(ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, c), s)
});
ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
Obligation::new(
tcx,

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