mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
+100
-266
@@ -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
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -430,6 +430,7 @@ pub fn ctxt(&self) -> Option<FnCtxt> {
|
||||
Defaultness,
|
||||
Delegation,
|
||||
DelegationMac,
|
||||
DelegationSuffixes,
|
||||
DelimArgs,
|
||||
DelimSpan,
|
||||
EnumDef,
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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("*/")
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,5 @@
|
||||
#![feature(negative_impls)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
mod helpers;
|
||||
pub mod pp;
|
||||
pub mod pprust;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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> {}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user