Merge from rustc
This commit is contained in:
commit
fd7fb5efac
179 changed files with 4051 additions and 1392 deletions
240
Cargo.lock
240
Cargo.lock
|
|
@ -13,9 +13,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
|
|
@ -75,7 +75,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -136,7 +136,7 @@ dependencies = [
|
|||
"anstyle-lossy",
|
||||
"anstyle-parse",
|
||||
"html-escape",
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -204,7 +204,7 @@ dependencies = [
|
|||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -216,7 +216,7 @@ dependencies = [
|
|||
"memchr",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"winnow 0.7.10",
|
||||
"winnow 0.7.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -431,9 +431,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
|
|
@ -487,9 +487,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.39"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
|
||||
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -507,9 +507,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.39"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
|
||||
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -519,21 +519,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.32"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
|
||||
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.4"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
|
|
@ -558,7 +558,7 @@ dependencies = [
|
|||
"rustc_tools_util 0.4.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"tempfile",
|
||||
"termize",
|
||||
"tokio",
|
||||
|
|
@ -673,7 +673,7 @@ dependencies = [
|
|||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -748,7 +748,7 @@ dependencies = [
|
|||
"encode_unicode",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width 0.2.1",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
|
|
@ -900,7 +900,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -911,7 +911,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
|||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -939,7 +939,7 @@ checksum = "e73f2692d4bd3cac41dca28934a39894200c9fabf49586d77d0e5954af1d7902"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -960,7 +960,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -970,7 +970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -982,7 +982,7 @@ dependencies = [
|
|||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1050,7 +1050,7 @@ dependencies = [
|
|||
"libc",
|
||||
"option-ext",
|
||||
"redox_users 0.5.0",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1072,7 +1072,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1352,7 +1352,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1416,11 +1416,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.14",
|
||||
"unicode-width 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1431,7 +1431,7 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1511,9 +1511,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
|
||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
|
|
@ -1775,7 +1775,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1859,7 +1859,7 @@ dependencies = [
|
|||
"console",
|
||||
"number_prefix",
|
||||
"portable-atomic",
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width 0.2.1",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
|
|
@ -1933,9 +1933,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93"
|
||||
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
|
||||
dependencies = [
|
||||
"jiff-static",
|
||||
"log",
|
||||
|
|
@ -1946,13 +1946,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "jiff-static"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442"
|
||||
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2045,9 +2045,9 @@ checksum = "9fa0e2a1fcbe2f6be6c42e342259976206b383122fc152e872795338b5a3f3a7"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "libdbus-sys"
|
||||
|
|
@ -2085,7 +2085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.53.0",
|
||||
"windows-targets 0.53.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2223,7 +2223,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2261,9 +2261,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
|
|
@ -2276,9 +2276,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "minifier"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bfdc64e2f805f3d12965f10522000bae36e88d2cfea44112331f467d4f4bf68"
|
||||
checksum = "14f1541610994bba178cb36757e102d06a52a2d9612aa6d34c64b3b377c5d943"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
|
|
@ -2288,9 +2288,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
|
@ -2512,15 +2512,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.37.0"
|
||||
version = "0.37.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6273adb7096cf9ab4335f258e627d8230e69d40d45567d678f552dcec6245215"
|
||||
checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"hashbrown",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"wasmparser 0.232.0",
|
||||
"wasmparser 0.234.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2725,7 +2725,7 @@ dependencies = [
|
|||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3014,9 +3014,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
|
@ -3148,9 +3148,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
|
|
@ -3440,7 +3440,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"libc",
|
||||
"measureme",
|
||||
"object 0.37.0",
|
||||
"object 0.37.1",
|
||||
"rustc-demangle",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
|
|
@ -3479,7 +3479,7 @@ dependencies = [
|
|||
"cc",
|
||||
"itertools",
|
||||
"libc",
|
||||
"object 0.37.0",
|
||||
"object 0.37.1",
|
||||
"pathdiff",
|
||||
"regex",
|
||||
"rustc_abi",
|
||||
|
|
@ -3739,7 +3739,7 @@ dependencies = [
|
|||
"fluent-syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
|
|
@ -3888,7 +3888,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4035,7 +4035,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -4240,7 +4240,7 @@ dependencies = [
|
|||
"thin-vec",
|
||||
"tracing",
|
||||
"unicode-normalization",
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4489,7 +4489,7 @@ dependencies = [
|
|||
"sha1",
|
||||
"sha2",
|
||||
"tracing",
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4514,7 +4514,7 @@ name = "rustc_target"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"object 0.37.0",
|
||||
"object 0.37.1",
|
||||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
"rustc_fs_util",
|
||||
|
|
@ -4635,7 +4635,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -4726,7 +4726,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4854,7 +4854,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5094,9 +5094,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
version = "2.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -5111,7 +5111,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5244,7 +5244,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5255,7 +5255,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5272,12 +5272,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5431,7 +5430,7 @@ checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5602,7 +5601,7 @@ checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5"
|
|||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
|
|
@ -5670,9 +5669,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
|
|
@ -5773,9 +5772,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
|
|
@ -5814,7 +5813,7 @@ dependencies = [
|
|||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -5836,7 +5835,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -5899,12 +5898,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.233.0"
|
||||
version = "0.235.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9679ae3cf7cfa2ca3a327f7fab97f27f3294d402fd1a76ca8ab514e17973e4d3"
|
||||
checksum = "b3bc393c395cb621367ff02d854179882b9a351b4e0c93d1397e6090b53a5c2a"
|
||||
dependencies = [
|
||||
"leb128fmt",
|
||||
"wasmparser 0.233.0",
|
||||
"wasmparser 0.235.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5944,18 +5943,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.232.0"
|
||||
version = "0.234.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "917739b33bb1eb0e9a49bcd2637a351931be4578d0cc4d37b908d7a797784fbb"
|
||||
checksum = "be22e5a8f600afce671dd53c8d2dd26b4b7aa810fd18ae27dfc49737f3e02fc5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.233.0"
|
||||
version = "0.235.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b51cb03afce7964bbfce46602d6cb358726f36430b6ba084ac6020d8ce5bc102"
|
||||
checksum = "161296c618fa2d63f6ed5fffd1112937e803cb9ec71b32b01a76321555660917"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"indexmap",
|
||||
|
|
@ -5964,22 +5963,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "233.0.0"
|
||||
version = "235.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eaf4099d8d0c922b83bf3c90663f5666f0769db9e525184284ebbbdb1dd2180"
|
||||
checksum = "1eda4293f626c99021bb3a6fbe4fbbe90c0e31a5ace89b5f620af8925de72e13"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"leb128fmt",
|
||||
"memchr",
|
||||
"unicode-width 0.2.0",
|
||||
"wasm-encoder 0.233.0",
|
||||
"unicode-width 0.2.1",
|
||||
"wasm-encoder 0.235.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wat"
|
||||
version = "1.233.0"
|
||||
version = "1.235.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d9bc80f5e4b25ea086ef41b91ccd244adde45d931c384d94a8ff64ab8bd7d87"
|
||||
checksum = "e777e0327115793cb96ab220b98f85327ec3d11f34ec9e8d723264522ef206aa"
|
||||
dependencies = [
|
||||
"wast",
|
||||
]
|
||||
|
|
@ -6027,9 +6026,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.1"
|
||||
version = "0.61.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core",
|
||||
|
|
@ -6090,7 +6089,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6101,14 +6100,14 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
|
|
@ -6165,6 +6164,15 @@ 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.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
|
|
@ -6198,9 +6206,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.0"
|
||||
version = "0.53.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
|
||||
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
|
|
@ -6370,9 +6378,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.10"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
@ -6505,7 +6513,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6517,7 +6525,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6538,7 +6546,7 @@ checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6558,7 +6566,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -6603,7 +6611,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6614,5 +6622,5 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"syn 2.0.103",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2289,12 +2289,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
span: Span,
|
||||
elements: &'hir [hir::Expr<'hir>],
|
||||
) -> hir::Expr<'hir> {
|
||||
let addrof = hir::ExprKind::AddrOf(
|
||||
hir::BorrowKind::Ref,
|
||||
hir::Mutability::Not,
|
||||
self.arena.alloc(self.expr(span, hir::ExprKind::Array(elements))),
|
||||
);
|
||||
self.expr(span, addrof)
|
||||
let array = self.arena.alloc(self.expr(span, hir::ExprKind::Array(elements)));
|
||||
self.expr_ref(span, array)
|
||||
}
|
||||
|
||||
pub(super) fn expr_ref(&mut self, span: Span, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr))
|
||||
}
|
||||
|
||||
pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use core::ops::ControlFlow;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast::visit::Visitor;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -476,77 +474,52 @@ fn expand_format_args<'hir>(
|
|||
return hir::ExprKind::Call(new, new_args);
|
||||
}
|
||||
|
||||
// If the args array contains exactly all the original arguments once,
|
||||
// in order, we can use a simple array instead of a `match` construction.
|
||||
// However, if there's a yield point in any argument except the first one,
|
||||
// we don't do this, because an Argument cannot be kept across yield points.
|
||||
//
|
||||
// This is an optimization, speeding up compilation about 1-2% in some cases.
|
||||
// See https://github.com/rust-lang/rust/pull/106770#issuecomment-1380790609
|
||||
let use_simple_array = argmap.len() == arguments.len()
|
||||
&& argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j)
|
||||
&& arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr));
|
||||
|
||||
let args = if arguments.is_empty() {
|
||||
let (let_statements, args) = if arguments.is_empty() {
|
||||
// Generate:
|
||||
// &<core::fmt::Argument>::none()
|
||||
// []
|
||||
(vec![], ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(&[]))))
|
||||
} else if argmap.len() == 1 && arguments.len() == 1 {
|
||||
// Only one argument, so we don't need to make the `args` tuple.
|
||||
//
|
||||
// Note:
|
||||
// `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime.
|
||||
//
|
||||
// This makes sure that this still fails to compile, even when the argument is inlined:
|
||||
//
|
||||
// ```
|
||||
// let f = format_args!("{}", "a");
|
||||
// println!("{f}"); // error E0716
|
||||
// ```
|
||||
//
|
||||
// Cases where keeping the object around is allowed, such as `format_args!("a")`,
|
||||
// are handled above by the `allow_const` case.
|
||||
let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
|
||||
macsp,
|
||||
hir::LangItem::FormatArgument,
|
||||
sym::none,
|
||||
));
|
||||
let none = ctx.expr_call(macsp, none_fn, &[]);
|
||||
ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none))
|
||||
} else if use_simple_array {
|
||||
// Generate:
|
||||
// &[
|
||||
// <core::fmt::Argument>::new_display(&arg0),
|
||||
// <core::fmt::Argument>::new_lower_hex(&arg1),
|
||||
// <core::fmt::Argument>::new_debug(&arg2),
|
||||
// …
|
||||
// ]
|
||||
let elements = ctx.arena.alloc_from_iter(arguments.iter().zip(argmap).map(
|
||||
|(arg, ((_, ty), placeholder_span))| {
|
||||
// super let args = [<core::fmt::Argument>::new_display(&arg)];
|
||||
let args = ctx.arena.alloc_from_iter(argmap.iter().map(
|
||||
|(&(arg_index, ty), &placeholder_span)| {
|
||||
let arg = &arguments[arg_index];
|
||||
let placeholder_span =
|
||||
placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt());
|
||||
let arg_span = match arg.kind {
|
||||
FormatArgumentKind::Captured(_) => placeholder_span,
|
||||
_ => arg.expr.span.with_ctxt(macsp.ctxt()),
|
||||
};
|
||||
let arg = ctx.lower_expr(&arg.expr);
|
||||
let ref_arg = ctx.arena.alloc(ctx.expr(
|
||||
arg_span,
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg),
|
||||
));
|
||||
let ref_arg = ctx.arena.alloc(ctx.expr_ref(arg.span.with_ctxt(macsp.ctxt()), arg));
|
||||
make_argument(ctx, placeholder_span, ref_arg, ty)
|
||||
},
|
||||
));
|
||||
ctx.expr_array_ref(macsp, elements)
|
||||
} else {
|
||||
// Generate:
|
||||
// &match (&arg0, &arg1, &…) {
|
||||
// args => [
|
||||
// <core::fmt::Argument>::new_display(args.0),
|
||||
// <core::fmt::Argument>::new_lower_hex(args.1),
|
||||
// <core::fmt::Argument>::new_debug(args.0),
|
||||
// …
|
||||
// ]
|
||||
// }
|
||||
let args = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args)));
|
||||
let args_ident = Ident::new(sym::args, macsp);
|
||||
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
|
||||
let let_statement = ctx.stmt_super_let_pat(macsp, args_pat, Some(args));
|
||||
(vec![let_statement], ctx.arena.alloc(ctx.expr_ident_mut(macsp, args_ident, args_hir_id)))
|
||||
} else {
|
||||
// Generate:
|
||||
// super let args = (&arg0, &arg1, &…);
|
||||
let args_ident = Ident::new(sym::args, macsp);
|
||||
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
|
||||
let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| {
|
||||
let arg_expr = ctx.lower_expr(&arg.expr);
|
||||
ctx.expr(
|
||||
arg.expr.span.with_ctxt(macsp.ctxt()),
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr),
|
||||
)
|
||||
}));
|
||||
let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements)));
|
||||
let let_statement_1 = ctx.stmt_super_let_pat(macsp, args_pat, Some(args_tuple));
|
||||
|
||||
// Generate:
|
||||
// super let args = [
|
||||
// <core::fmt::Argument>::new_display(args.0),
|
||||
// <core::fmt::Argument>::new_lower_hex(args.1),
|
||||
// <core::fmt::Argument>::new_debug(args.0),
|
||||
// …
|
||||
// ];
|
||||
let args = ctx.arena.alloc_from_iter(argmap.iter().map(
|
||||
|(&(arg_index, ty), &placeholder_span)| {
|
||||
let arg = &arguments[arg_index];
|
||||
|
|
@ -567,58 +540,47 @@ fn expand_format_args<'hir>(
|
|||
make_argument(ctx, placeholder_span, arg, ty)
|
||||
},
|
||||
));
|
||||
let elements = ctx.arena.alloc_from_iter(arguments.iter().map(|arg| {
|
||||
let arg_expr = ctx.lower_expr(&arg.expr);
|
||||
ctx.expr(
|
||||
arg.expr.span.with_ctxt(macsp.ctxt()),
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg_expr),
|
||||
)
|
||||
}));
|
||||
let args_tuple = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Tup(elements)));
|
||||
let array = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args)));
|
||||
let match_arms = ctx.arena.alloc_from_iter([ctx.arm(args_pat, array)]);
|
||||
let match_expr = ctx.arena.alloc(ctx.expr_match(
|
||||
macsp,
|
||||
args_tuple,
|
||||
match_arms,
|
||||
hir::MatchSource::FormatArgs,
|
||||
));
|
||||
ctx.expr(
|
||||
macsp,
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, match_expr),
|
||||
let args = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args)));
|
||||
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
|
||||
let let_statement_2 = ctx.stmt_super_let_pat(macsp, args_pat, Some(args));
|
||||
(
|
||||
vec![let_statement_1, let_statement_2],
|
||||
ctx.arena.alloc(ctx.expr_ident_mut(macsp, args_ident, args_hir_id)),
|
||||
)
|
||||
};
|
||||
|
||||
if let Some(format_options) = format_options {
|
||||
// Generate:
|
||||
// &args
|
||||
let args = ctx.expr_ref(macsp, args);
|
||||
|
||||
let call = if let Some(format_options) = format_options {
|
||||
// Generate:
|
||||
// <core::fmt::Arguments>::new_v1_formatted(
|
||||
// lit_pieces,
|
||||
// args,
|
||||
// format_options,
|
||||
// unsafe { ::core::fmt::UnsafeArg::new() }
|
||||
// )
|
||||
// unsafe {
|
||||
// <core::fmt::Arguments>::new_v1_formatted(
|
||||
// lit_pieces,
|
||||
// args,
|
||||
// format_options,
|
||||
// )
|
||||
// }
|
||||
let new_v1_formatted = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
|
||||
macsp,
|
||||
hir::LangItem::FormatArguments,
|
||||
sym::new_v1_formatted,
|
||||
));
|
||||
let unsafe_arg_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
|
||||
macsp,
|
||||
hir::LangItem::FormatUnsafeArg,
|
||||
sym::new,
|
||||
));
|
||||
let unsafe_arg_new_call = ctx.expr_call(macsp, unsafe_arg_new, &[]);
|
||||
let args = ctx.arena.alloc_from_iter([lit_pieces, args, format_options]);
|
||||
let call = ctx.expr_call(macsp, new_v1_formatted, args);
|
||||
let hir_id = ctx.next_id();
|
||||
let unsafe_arg = ctx.expr_block(ctx.arena.alloc(hir::Block {
|
||||
stmts: &[],
|
||||
expr: Some(unsafe_arg_new_call),
|
||||
hir_id,
|
||||
rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated),
|
||||
span: macsp,
|
||||
targeted_by_break: false,
|
||||
}));
|
||||
let args = ctx.arena.alloc_from_iter([lit_pieces, args, format_options, unsafe_arg]);
|
||||
hir::ExprKind::Call(new_v1_formatted, args)
|
||||
hir::ExprKind::Block(
|
||||
ctx.arena.alloc(hir::Block {
|
||||
stmts: &[],
|
||||
expr: Some(call),
|
||||
hir_id,
|
||||
rules: hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated),
|
||||
span: macsp,
|
||||
targeted_by_break: false,
|
||||
}),
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
// Generate:
|
||||
// <core::fmt::Arguments>::new_v1(
|
||||
|
|
@ -632,37 +594,23 @@ fn expand_format_args<'hir>(
|
|||
));
|
||||
let new_args = ctx.arena.alloc_from_iter([lit_pieces, args]);
|
||||
hir::ExprKind::Call(new_v1, new_args)
|
||||
};
|
||||
|
||||
if !let_statements.is_empty() {
|
||||
// Generate:
|
||||
// {
|
||||
// super let …
|
||||
// super let …
|
||||
// <core::fmt::Arguments>::new_…(…)
|
||||
// }
|
||||
let call = ctx.arena.alloc(ctx.expr(macsp, call));
|
||||
let block = ctx.block_all(macsp, ctx.arena.alloc_from_iter(let_statements), Some(call));
|
||||
hir::ExprKind::Block(block, None)
|
||||
} else {
|
||||
call
|
||||
}
|
||||
}
|
||||
|
||||
fn may_contain_yield_point(e: &ast::Expr) -> bool {
|
||||
struct MayContainYieldPoint;
|
||||
|
||||
impl Visitor<'_> for MayContainYieldPoint {
|
||||
type Result = ControlFlow<()>;
|
||||
|
||||
fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> {
|
||||
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
visit::walk_expr(self, e)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mac_call(&mut self, _: &ast::MacCall) -> ControlFlow<()> {
|
||||
// Macros should be expanded at this point.
|
||||
unreachable!("unexpanded macro in ast lowering");
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, _: &ast::Item) -> ControlFlow<()> {
|
||||
// Do not recurse into nested items.
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
MayContainYieldPoint.visit_expr(e).is_break()
|
||||
}
|
||||
|
||||
fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) {
|
||||
for piece in template {
|
||||
let FormatArgsPiece::Placeholder(placeholder) = piece else { continue };
|
||||
|
|
|
|||
|
|
@ -2292,6 +2292,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
|
||||
}
|
||||
|
||||
fn stmt_super_let_pat(
|
||||
&mut self,
|
||||
span: Span,
|
||||
pat: &'hir hir::Pat<'hir>,
|
||||
init: Option<&'hir hir::Expr<'hir>>,
|
||||
) -> hir::Stmt<'hir> {
|
||||
let hir_id = self.next_id();
|
||||
let local = hir::LetStmt {
|
||||
super_: Some(span),
|
||||
hir_id,
|
||||
init,
|
||||
pat,
|
||||
els: None,
|
||||
source: hir::LocalSource::Normal,
|
||||
span: self.lower_span(span),
|
||||
ty: None,
|
||||
};
|
||||
self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
|
||||
}
|
||||
|
||||
fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
|
||||
self.block_all(expr.span, &[], Some(expr))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,9 @@ impl Deprecation {
|
|||
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
|
||||
pub enum AttributeKind {
|
||||
// tidy-alphabetical-start
|
||||
/// Represents `#[align(N)]`.
|
||||
Align { align: Align, span: Span },
|
||||
|
||||
/// Represents `#[rustc_allow_const_fn_unstable]`.
|
||||
AllowConstFnUnstable(ThinVec<Symbol>),
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ attr_parsing_incorrect_repr_format_packed_expect_integer =
|
|||
attr_parsing_incorrect_repr_format_packed_one_or_zero_arg =
|
||||
incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
|
||||
|
||||
attr_parsing_invalid_alignment_value =
|
||||
invalid alignment value: {$error_part}
|
||||
|
||||
attr_parsing_invalid_issue_string =
|
||||
`issue` must be a non-zero numeric string or "none"
|
||||
.must_not_be_zero = `issue` must not be "0", use "none" instead
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use rustc_attr_data_structures::{AttributeKind, IntType, ReprAttr};
|
|||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
|
||||
|
||||
use super::{CombineAttributeParser, ConvertFn};
|
||||
use super::{AcceptMapping, AttributeParser, CombineAttributeParser, ConvertFn, FinalizeContext};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::parser::{ArgParser, MetaItemListParser, MetaItemParser};
|
||||
use crate::session_diagnostics;
|
||||
|
|
@ -203,7 +203,7 @@ fn parse_repr_align<S: Stage>(
|
|||
});
|
||||
}
|
||||
Align => {
|
||||
cx.dcx().emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
||||
cx.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
||||
span: param_span,
|
||||
});
|
||||
}
|
||||
|
|
@ -266,3 +266,57 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
|
|||
Err("not an unsuffixed integer")
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse #[align(N)].
|
||||
#[derive(Default)]
|
||||
pub(crate) struct AlignParser(Option<(Align, Span)>);
|
||||
|
||||
impl AlignParser {
|
||||
const PATH: &'static [Symbol] = &[sym::align];
|
||||
const TEMPLATE: AttributeTemplate = template!(Word, List: "<alignment in bytes>");
|
||||
|
||||
fn parse<'c, S: Stage>(
|
||||
&mut self,
|
||||
cx: &'c mut AcceptContext<'_, '_, S>,
|
||||
args: &'c ArgParser<'_>,
|
||||
) {
|
||||
match args {
|
||||
ArgParser::NoArgs | ArgParser::NameValue(_) => {
|
||||
cx.expected_list(cx.attr_span);
|
||||
}
|
||||
ArgParser::List(list) => {
|
||||
let Some(align) = list.single() else {
|
||||
cx.expected_single_argument(list.span);
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(lit) = align.lit() else {
|
||||
cx.emit_err(session_diagnostics::IncorrectReprFormatExpectInteger {
|
||||
span: align.span(),
|
||||
});
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
match parse_alignment(&lit.kind) {
|
||||
Ok(literal) => self.0 = Ord::max(self.0, Some((literal, cx.attr_span))),
|
||||
Err(message) => {
|
||||
cx.emit_err(session_diagnostics::InvalidAlignmentValue {
|
||||
span: lit.span,
|
||||
error_part: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Stage> AttributeParser<S> for AlignParser {
|
||||
const ATTRIBUTES: AcceptMapping<Self, S> = &[(Self::PATH, Self::TEMPLATE, Self::parse)];
|
||||
|
||||
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
let (align, span) = self.0?;
|
||||
Some(AttributeKind::Align { align, span })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use crate::attributes::confusables::ConfusablesParser;
|
|||
use crate::attributes::deprecation::DeprecationParser;
|
||||
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
|
||||
use crate::attributes::lint_helpers::AsPtrParser;
|
||||
use crate::attributes::repr::ReprParser;
|
||||
use crate::attributes::repr::{AlignParser, ReprParser};
|
||||
use crate::attributes::stability::{
|
||||
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
|
||||
};
|
||||
|
|
@ -90,6 +90,7 @@ macro_rules! attribute_parsers {
|
|||
attribute_parsers!(
|
||||
pub(crate) static ATTRIBUTE_PARSERS = [
|
||||
// tidy-alphabetical-start
|
||||
AlignParser,
|
||||
BodyStabilityParser,
|
||||
ConfusablesParser,
|
||||
ConstStabilityParser,
|
||||
|
|
|
|||
|
|
@ -450,6 +450,14 @@ pub(crate) struct EmptyConfusables {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_invalid_alignment_value, code = E0589)]
|
||||
pub(crate) struct InvalidAlignmentValue {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub error_part: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_repr_ident, code = E0565)]
|
||||
pub(crate) struct ReprIdent {
|
||||
|
|
|
|||
|
|
@ -3201,14 +3201,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
let expr_ty: Option<Ty<'_>> =
|
||||
visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs());
|
||||
|
||||
let is_format_arguments_item = if let Some(expr_ty) = expr_ty
|
||||
&& let ty::Adt(adt, _) = expr_ty.kind()
|
||||
{
|
||||
self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if visitor.found == 0
|
||||
&& stmt.span.contains(proper_span)
|
||||
&& let Some(p) = sm.span_to_margin(stmt.span)
|
||||
|
|
@ -3236,25 +3228,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
|||
""
|
||||
};
|
||||
|
||||
if !is_format_arguments_item {
|
||||
let addition = format!(
|
||||
"let {}binding = {};\n{}",
|
||||
mutability,
|
||||
s,
|
||||
" ".repeat(p)
|
||||
);
|
||||
err.multipart_suggestion_verbose(
|
||||
msg,
|
||||
vec![
|
||||
(stmt.span.shrink_to_lo(), addition),
|
||||
(proper_span, "binding".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.note("the result of `format_args!` can only be assigned directly if no placeholders in its arguments are used");
|
||||
err.note("to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>");
|
||||
}
|
||||
let addition =
|
||||
format!("let {}binding = {};\n{}", mutability, s, " ".repeat(p));
|
||||
err.multipart_suggestion_verbose(
|
||||
msg,
|
||||
vec![
|
||||
(stmt.span.shrink_to_lo(), addition),
|
||||
(proper_span, "binding".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
||||
suggested = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use std::str::FromStr;
|
|||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
|
||||
use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
|
||||
use rustc_attr_data_structures::ReprAttr::ReprAlign;
|
||||
use rustc_attr_data_structures::{
|
||||
AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, find_attr,
|
||||
};
|
||||
|
|
@ -110,17 +109,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
};
|
||||
|
||||
if let hir::Attribute::Parsed(p) = attr {
|
||||
match p {
|
||||
AttributeKind::Repr(reprs) => {
|
||||
codegen_fn_attrs.alignment = reprs
|
||||
.iter()
|
||||
.filter_map(|(r, _)| if let ReprAlign(x) = r { Some(*x) } else { None })
|
||||
.max();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
if let hir::Attribute::Parsed(AttributeKind::Align { align, .. }) = attr {
|
||||
codegen_fn_attrs.alignment = Some(*align);
|
||||
}
|
||||
|
||||
let Some(Ident { name, .. }) = attr.ident() else {
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
||||
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
|
||||
gated!(align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(align)),
|
||||
ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
|
||||
ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
|
||||
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
|
||||
|
|
|
|||
|
|
@ -34,16 +34,22 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
|||
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode, fold_regions};
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, fold_regions,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{ObligationCtxt, hir_ty_lowering_dyn_compatibility_violations};
|
||||
use rustc_trait_selection::traits::{
|
||||
FulfillmentError, ObligationCtxt, hir_ty_lowering_dyn_compatibility_violations,
|
||||
};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::errors;
|
||||
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
|
||||
use crate::hir_ty_lowering::{
|
||||
FeedConstTy, HirTyLowerer, InherentAssocCandidate, RegionInferReason,
|
||||
};
|
||||
|
||||
pub(crate) mod dump;
|
||||
mod generics_of;
|
||||
|
|
@ -364,6 +370,58 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_ident))
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, _span), ret)]
|
||||
fn select_inherent_assoc_candidates(
|
||||
&self,
|
||||
_span: Span,
|
||||
self_ty: Ty<'tcx>,
|
||||
candidates: Vec<InherentAssocCandidate>,
|
||||
) -> (Vec<InherentAssocCandidate>, Vec<FulfillmentError<'tcx>>) {
|
||||
assert!(!self_ty.has_infer());
|
||||
|
||||
// We don't just call the normal normalization routine here as we can't provide the
|
||||
// correct `ParamEnv` and it would be wrong to invoke arbitrary trait solving under
|
||||
// the wrong `ParamEnv`. Expanding free aliases doesn't need a `ParamEnv` so we do
|
||||
// this just to make resolution a little bit smarter.
|
||||
let self_ty = self.tcx.expand_free_alias_tys(self_ty);
|
||||
debug!("select_inherent_assoc_candidates: self_ty={:?}", self_ty);
|
||||
|
||||
let candidates = candidates
|
||||
.into_iter()
|
||||
.filter(|&InherentAssocCandidate { impl_, .. }| {
|
||||
let impl_ty = self.tcx().type_of(impl_).instantiate_identity();
|
||||
|
||||
// See comment on doing this operation for `self_ty`
|
||||
let impl_ty = self.tcx.expand_free_alias_tys(impl_ty);
|
||||
debug!("select_inherent_assoc_candidates: impl_ty={:?}", impl_ty);
|
||||
|
||||
// We treat parameters in the self ty as rigid and parameters in the impl ty as infers
|
||||
// because it allows `impl<T> Foo<T>` to unify with `Foo<u8>::IAT`, while also disallowing
|
||||
// `Foo<T>::IAT` from unifying with `impl Foo<u8>`.
|
||||
//
|
||||
// We don't really care about a depth limit here because we're only working with user-written
|
||||
// types and if they wrote a type that would take hours to walk then that's kind of on them. On
|
||||
// the other hand the default depth limit is relatively low and could realistically be hit by
|
||||
// users in normal cases.
|
||||
//
|
||||
// `DeepRejectCtxt` leads to slightly worse IAT resolution than real type equality in cases
|
||||
// where the `impl_ty` has repeated uses of generic parameters. E.g. `impl<T> Foo<T, T>` would
|
||||
// be considered a valid candidate when resolving `Foo<u8, u16>::IAT`.
|
||||
//
|
||||
// Not replacing escaping bound vars in `self_ty` with placeholders also leads to slightly worse
|
||||
// resolution, but it probably won't come up in practice and it would be backwards compatible
|
||||
// to switch over to doing that.
|
||||
ty::DeepRejectCtxt::relate_rigid_infer(self.tcx).types_may_unify_with_depth(
|
||||
self_ty,
|
||||
impl_ty,
|
||||
usize::MAX,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
(candidates, vec![])
|
||||
}
|
||||
|
||||
fn lower_assoc_item_path(
|
||||
&self,
|
||||
span: Span,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ use rustc_trait_selection::traits::{
|
|||
use smallvec::SmallVec;
|
||||
use tracing::debug;
|
||||
|
||||
use super::InherentAssocCandidate;
|
||||
use crate::errors::{
|
||||
self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams,
|
||||
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
|
||||
|
|
@ -793,7 +794,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&self,
|
||||
name: Ident,
|
||||
self_ty: Ty<'tcx>,
|
||||
candidates: Vec<(DefId, (DefId, DefId))>,
|
||||
candidates: Vec<InherentAssocCandidate>,
|
||||
fulfillment_errors: Vec<FulfillmentError<'tcx>>,
|
||||
span: Span,
|
||||
assoc_tag: ty::AssocTag,
|
||||
|
|
@ -827,8 +828,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let type_candidates = candidates
|
||||
.iter()
|
||||
.take(limit)
|
||||
.map(|&(impl_, _)| {
|
||||
format!("- `{}`", tcx.at(span).type_of(impl_).instantiate_identity())
|
||||
.map(|cand| {
|
||||
format!("- `{}`", tcx.at(span).type_of(cand.impl_).instantiate_identity())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
|
|
|||
|
|
@ -33,13 +33,14 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
|||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
|
||||
use rustc_infer::traits::DynCompatibilityViolation;
|
||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::middle::stability::AllowUnstable;
|
||||
use rustc_middle::mir::interpret::LitToConstInput;
|
||||
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
|
||||
use rustc_middle::ty::{
|
||||
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
|
||||
TypeVisitableExt, TypingMode, Upcast, fold_regions,
|
||||
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
|
||||
TypingMode, Upcast, fold_regions,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||
|
|
@ -47,7 +48,7 @@ use rustc_session::parse::feature_err;
|
|||
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use rustc_trait_selection::traits::{self, FulfillmentError};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::check::check_abi_fn_ptr;
|
||||
|
|
@ -99,6 +100,13 @@ pub enum RegionInferReason<'a> {
|
|||
OutlivesBound,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Debug)]
|
||||
pub struct InherentAssocCandidate {
|
||||
pub impl_: DefId,
|
||||
pub assoc_item: DefId,
|
||||
pub scope: DefId,
|
||||
}
|
||||
|
||||
/// A context which can lower type-system entities from the [HIR][hir] to
|
||||
/// the [`rustc_middle::ty`] representation.
|
||||
///
|
||||
|
|
@ -148,6 +156,13 @@ pub trait HirTyLowerer<'tcx> {
|
|||
assoc_ident: Ident,
|
||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
|
||||
|
||||
fn select_inherent_assoc_candidates(
|
||||
&self,
|
||||
span: Span,
|
||||
self_ty: Ty<'tcx>,
|
||||
candidates: Vec<InherentAssocCandidate>,
|
||||
) -> (Vec<InherentAssocCandidate>, Vec<FulfillmentError<'tcx>>);
|
||||
|
||||
/// Lower a path to an associated item (of a trait) to a projection.
|
||||
///
|
||||
/// This method has to be defined by the concrete lowering context because
|
||||
|
|
@ -1449,48 +1464,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.filter_map(|&impl_| {
|
||||
let (item, scope) =
|
||||
self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
|
||||
Some((impl_, (item.def_id, scope)))
|
||||
Some(InherentAssocCandidate { impl_, assoc_item: item.def_id, scope })
|
||||
})
|
||||
.collect();
|
||||
|
||||
if candidates.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
let (applicable_candidates, fulfillment_errors) =
|
||||
self.select_inherent_assoc_candidates(span, self_ty, candidates.clone());
|
||||
|
||||
//
|
||||
// Select applicable inherent associated type candidates modulo regions.
|
||||
//
|
||||
let InherentAssocCandidate { impl_, assoc_item, scope: def_scope } =
|
||||
match &applicable_candidates[..] {
|
||||
&[] => Err(self.report_unresolved_inherent_assoc_item(
|
||||
name,
|
||||
self_ty,
|
||||
candidates,
|
||||
fulfillment_errors,
|
||||
span,
|
||||
assoc_tag,
|
||||
)),
|
||||
|
||||
// In contexts that have no inference context, just make a new one.
|
||||
// We do need a local variable to store it, though.
|
||||
let infcx = match self.infcx() {
|
||||
Some(infcx) => infcx,
|
||||
None => {
|
||||
assert!(!self_ty.has_infer());
|
||||
&tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis())
|
||||
}
|
||||
};
|
||||
&[applicable_candidate] => Ok(applicable_candidate),
|
||||
|
||||
// FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
|
||||
// when inside of an ADT (#108491) or where clause.
|
||||
let param_env = tcx.param_env(block.owner);
|
||||
|
||||
let mut universes = if self_ty.has_escaping_bound_vars() {
|
||||
vec![None; self_ty.outer_exclusive_binder().as_usize()]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let (impl_, (assoc_item, def_scope)) = crate::traits::with_replaced_escaping_bound_vars(
|
||||
infcx,
|
||||
&mut universes,
|
||||
self_ty,
|
||||
|self_ty| {
|
||||
self.select_inherent_assoc_candidates(
|
||||
infcx, name, span, self_ty, param_env, candidates, assoc_tag,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
&[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
|
||||
name,
|
||||
candidates.into_iter().map(|cand| cand.assoc_item).collect(),
|
||||
span,
|
||||
)),
|
||||
}?;
|
||||
|
||||
self.check_assoc_item(assoc_item, name, def_scope, block, span);
|
||||
|
||||
|
|
@ -1507,78 +1506,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
Ok(Some((assoc_item, args)))
|
||||
}
|
||||
|
||||
fn select_inherent_assoc_candidates(
|
||||
&self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
name: Ident,
|
||||
span: Span,
|
||||
self_ty: Ty<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
candidates: Vec<(DefId, (DefId, DefId))>,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
|
||||
let tcx = self.tcx();
|
||||
let mut fulfillment_errors = Vec::new();
|
||||
|
||||
let applicable_candidates: Vec<_> = candidates
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|&(impl_, _)| {
|
||||
infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
|
||||
let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
|
||||
|
||||
let impl_args = infcx.fresh_args_for_item(span, impl_);
|
||||
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
|
||||
let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
|
||||
|
||||
// Check that the self types can be related.
|
||||
if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check whether the impl imposes obligations we have to worry about.
|
||||
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
|
||||
let impl_bounds =
|
||||
ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
|
||||
let impl_obligations = traits::predicates_for_generics(
|
||||
|_, _| ObligationCause::dummy(),
|
||||
param_env,
|
||||
impl_bounds,
|
||||
);
|
||||
ocx.register_obligations(impl_obligations);
|
||||
|
||||
let mut errors = ocx.select_where_possible();
|
||||
if !errors.is_empty() {
|
||||
fulfillment_errors.append(&mut errors);
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
match &applicable_candidates[..] {
|
||||
&[] => Err(self.report_unresolved_inherent_assoc_item(
|
||||
name,
|
||||
self_ty,
|
||||
candidates,
|
||||
fulfillment_errors,
|
||||
span,
|
||||
assoc_tag,
|
||||
)),
|
||||
|
||||
&[applicable_candidate] => Ok(applicable_candidate),
|
||||
|
||||
&[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
|
||||
name,
|
||||
applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
|
||||
span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
|
||||
///
|
||||
/// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ use hir::def_id::CRATE_DEF_ID;
|
|||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir, HirId, ItemLocalMap};
|
||||
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
|
||||
use rustc_hir_analysis::hir_ty_lowering::{
|
||||
HirTyLowerer, InherentAssocCandidate, RegionInferReason,
|
||||
};
|
||||
use rustc_infer::infer;
|
||||
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
|
||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
|
||||
|
|
@ -20,7 +22,9 @@ use rustc_session::Session;
|
|||
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
|
||||
use rustc_trait_selection::error_reporting::TypeErrCtxt;
|
||||
use rustc_trait_selection::error_reporting::infer::sub_relations::SubRelations;
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||
use rustc_trait_selection::traits::{
|
||||
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||
};
|
||||
|
||||
use crate::coercion::DynamicCoerceMany;
|
||||
use crate::fallback::DivergingFallbackBehavior;
|
||||
|
|
@ -310,6 +314,67 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
|
|||
))
|
||||
}
|
||||
|
||||
fn select_inherent_assoc_candidates(
|
||||
&self,
|
||||
span: Span,
|
||||
self_ty: Ty<'tcx>,
|
||||
candidates: Vec<InherentAssocCandidate>,
|
||||
) -> (Vec<InherentAssocCandidate>, Vec<FulfillmentError<'tcx>>) {
|
||||
let tcx = self.tcx();
|
||||
let infcx = &self.infcx;
|
||||
let mut fulfillment_errors = vec![];
|
||||
|
||||
let mut filter_iat_candidate = |self_ty, impl_| {
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(self);
|
||||
let self_ty = ocx.normalize(&ObligationCause::dummy(), self.param_env, self_ty);
|
||||
|
||||
let impl_args = infcx.fresh_args_for_item(span, impl_);
|
||||
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
|
||||
let impl_ty = ocx.normalize(&ObligationCause::dummy(), self.param_env, impl_ty);
|
||||
|
||||
// Check that the self types can be related.
|
||||
if ocx.eq(&ObligationCause::dummy(), self.param_env, impl_ty, self_ty).is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check whether the impl imposes obligations we have to worry about.
|
||||
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
|
||||
let impl_bounds = ocx.normalize(&ObligationCause::dummy(), self.param_env, impl_bounds);
|
||||
let impl_obligations = traits::predicates_for_generics(
|
||||
|_, _| ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
impl_bounds,
|
||||
);
|
||||
ocx.register_obligations(impl_obligations);
|
||||
|
||||
let mut errors = ocx.select_where_possible();
|
||||
if !errors.is_empty() {
|
||||
fulfillment_errors.append(&mut errors);
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
};
|
||||
|
||||
let mut universes = if self_ty.has_escaping_bound_vars() {
|
||||
vec![None; self_ty.outer_exclusive_binder().as_usize()]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let candidates =
|
||||
traits::with_replaced_escaping_bound_vars(infcx, &mut universes, self_ty, |self_ty| {
|
||||
candidates
|
||||
.into_iter()
|
||||
.filter(|&InherentAssocCandidate { impl_, .. }| {
|
||||
infcx.probe(|_| filter_iat_candidate(self_ty, impl_))
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
|
||||
(candidates, fulfillment_errors)
|
||||
}
|
||||
|
||||
fn lower_assoc_item_path(
|
||||
&self,
|
||||
span: Span,
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ pub struct CodegenFnAttrs {
|
|||
/// be generated against a specific instruction set. Only usable on architectures which allow
|
||||
/// switching between multiple instruction sets.
|
||||
pub instruction_set: Option<InstructionSetAttr>,
|
||||
/// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be
|
||||
/// aligned to.
|
||||
/// The `#[align(...)]` attribute. Determines the alignment of the function body.
|
||||
pub alignment: Option<Align>,
|
||||
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
|
||||
/// the function entry.
|
||||
|
|
|
|||
|
|
@ -127,7 +127,9 @@ impl<'tcx> Ty<'tcx> {
|
|||
InhabitedPredicate::True
|
||||
}
|
||||
Never => InhabitedPredicate::False,
|
||||
Param(_) | Alias(ty::Projection | ty::Free, _) => InhabitedPredicate::GenericType(self),
|
||||
Param(_) | Alias(ty::Inherent | ty::Projection | ty::Free, _) => {
|
||||
InhabitedPredicate::GenericType(self)
|
||||
}
|
||||
Alias(ty::Opaque, alias_ty) => {
|
||||
match alias_ty.def_id.as_local() {
|
||||
// Foreign opaque is considered inhabited.
|
||||
|
|
@ -139,12 +141,6 @@ impl<'tcx> Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
// FIXME(inherent_associated_types): Most likely we can just map to `GenericType` like above.
|
||||
// However it's unclear if the args passed to `InhabitedPredicate::instantiate` are of the correct
|
||||
// format, i.e. don't contain parent args. If you hit this case, please verify this beforehand.
|
||||
Alias(ty::Inherent, _) => {
|
||||
bug!("unimplemented: inhabitedness checking for inherent projections")
|
||||
}
|
||||
Tuple(tys) if tys.is_empty() => InhabitedPredicate::True,
|
||||
// use a query for more complex cases
|
||||
Adt(..) | Array(..) | Tuple(_) => tcx.inhabited_predicate_type(self),
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ fn emit_malformed_attribute(
|
|||
| sym::rustc_force_inline
|
||||
| sym::rustc_confusables
|
||||
| sym::repr
|
||||
| sym::align
|
||||
| sym::deprecated
|
||||
) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ passes_abi_ne =
|
|||
passes_abi_of =
|
||||
fn_abi_of({$fn_name}) = {$fn_abi}
|
||||
|
||||
passes_align_should_be_repr_align =
|
||||
`#[align(...)]` is not supported on {$item} items
|
||||
.suggestion = use `#[repr(align(...))]` instead
|
||||
|
||||
passes_allow_incoherent_impl =
|
||||
`rustc_allow_incoherent_impl` attribute should be applied to impl items
|
||||
.label = the only currently supported targets are inherent methods
|
||||
|
|
@ -29,10 +33,6 @@ passes_attr_application_struct =
|
|||
attribute should be applied to a struct
|
||||
.label = not a struct
|
||||
|
||||
passes_attr_application_struct_enum_function_method_union =
|
||||
attribute should be applied to a struct, enum, function, associated function, or union
|
||||
.label = not a struct, enum, function, associated function, or union
|
||||
|
||||
passes_attr_application_struct_enum_union =
|
||||
attribute should be applied to a struct, enum, or union
|
||||
.label = not a struct, enum, or union
|
||||
|
|
@ -583,13 +583,14 @@ passes_remove_fields =
|
|||
*[other] fields
|
||||
}
|
||||
|
||||
passes_repr_align_function =
|
||||
`repr(align)` attributes on functions are unstable
|
||||
|
||||
passes_repr_align_greater_than_target_max =
|
||||
alignment must not be greater than `isize::MAX` bytes
|
||||
.note = `isize::MAX` is {$size} for the current target
|
||||
|
||||
passes_repr_align_should_be_align =
|
||||
`#[repr(align(...))]` is not supported on {$item} items
|
||||
.help = use `#[align(...)]` instead
|
||||
|
||||
passes_repr_conflicting =
|
||||
conflicting representation hints
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => {
|
||||
self.check_align(span, target, *align, *repr_span)
|
||||
}
|
||||
|
||||
Attribute::Parsed(
|
||||
AttributeKind::BodyStability { .. }
|
||||
| AttributeKind::ConstStabilityIndirect
|
||||
|
|
@ -643,6 +647,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
sym::naked,
|
||||
sym::instruction_set,
|
||||
sym::repr,
|
||||
sym::align,
|
||||
sym::rustc_std_internal_symbol,
|
||||
// code generation
|
||||
sym::cold,
|
||||
|
|
@ -679,7 +684,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// this check can be part of the parser and be removed here
|
||||
match other_attr {
|
||||
Attribute::Parsed(
|
||||
AttributeKind::Deprecation { .. } | AttributeKind::Repr { .. },
|
||||
AttributeKind::Deprecation { .. }
|
||||
| AttributeKind::Repr { .. }
|
||||
| AttributeKind::Align { .. },
|
||||
) => {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1964,6 +1971,28 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks if the `#[align]` attributes on `item` are valid.
|
||||
fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) {
|
||||
match target {
|
||||
Target::Fn | Target::Method(_) => {}
|
||||
Target::Struct | Target::Union | Target::Enum => {
|
||||
self.dcx().emit_err(errors::AlignShouldBeReprAlign {
|
||||
span: repr_span,
|
||||
item: target.name(),
|
||||
align_bytes: align.bytes(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
|
||||
hint_span: repr_span,
|
||||
span,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.check_align_value(align, repr_span);
|
||||
}
|
||||
|
||||
/// Checks if the `#[repr]` attributes on `item` are valid.
|
||||
fn check_repr(
|
||||
&self,
|
||||
|
|
@ -2016,23 +2045,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
match target {
|
||||
Target::Struct | Target::Union | Target::Enum => {}
|
||||
Target::Fn | Target::Method(_) => {
|
||||
if !self.tcx.features().fn_align() {
|
||||
feature_err(
|
||||
&self.tcx.sess,
|
||||
sym::fn_align,
|
||||
*repr_span,
|
||||
fluent::passes_repr_align_function,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
self.dcx().emit_err(errors::ReprAlignShouldBeAlign {
|
||||
span: *repr_span,
|
||||
item: target.name(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(
|
||||
errors::AttrApplication::StructEnumFunctionMethodUnion {
|
||||
hint_span: *repr_span,
|
||||
span,
|
||||
},
|
||||
);
|
||||
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
|
||||
hint_span: *repr_span,
|
||||
span,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2090,21 +2112,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
match target {
|
||||
Target::Struct | Target::Union | Target::Enum => continue,
|
||||
Target::Fn | Target::Method(_) => {
|
||||
feature_err(
|
||||
&self.tcx.sess,
|
||||
sym::fn_align,
|
||||
*repr_span,
|
||||
fluent::passes_repr_align_function,
|
||||
)
|
||||
.emit();
|
||||
self.dcx().emit_err(errors::ReprAlignShouldBeAlign {
|
||||
span: *repr_span,
|
||||
item: target.name(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(
|
||||
errors::AttrApplication::StructEnumFunctionMethodUnion {
|
||||
hint_span: *repr_span,
|
||||
span,
|
||||
},
|
||||
);
|
||||
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
|
||||
hint_span: *repr_span,
|
||||
span,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1308,13 +1308,6 @@ pub(crate) enum AttrApplication {
|
|||
#[label]
|
||||
span: Span,
|
||||
},
|
||||
#[diag(passes_attr_application_struct_enum_function_method_union, code = E0517)]
|
||||
StructEnumFunctionMethodUnion {
|
||||
#[primary_span]
|
||||
hint_span: Span,
|
||||
#[label]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
@ -1816,3 +1809,26 @@ pub(crate) enum UnexportableItem<'a> {
|
|||
field_name: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_repr_align_should_be_align)]
|
||||
pub(crate) struct ReprAlignShouldBeAlign {
|
||||
#[primary_span]
|
||||
#[help]
|
||||
pub span: Span,
|
||||
pub item: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_align_should_be_repr_align)]
|
||||
pub(crate) struct AlignShouldBeReprAlign {
|
||||
#[primary_span]
|
||||
#[suggestion(
|
||||
style = "verbose",
|
||||
applicability = "machine-applicable",
|
||||
code = "#[repr(align({align_bytes}))]"
|
||||
)]
|
||||
pub span: Span,
|
||||
pub item: &'static str,
|
||||
pub align_bytes: u64,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,6 +240,10 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
|
|||
self.types_may_unify_inner(lhs, rhs, Self::STARTING_DEPTH)
|
||||
}
|
||||
|
||||
pub fn types_may_unify_with_depth(self, lhs: I::Ty, rhs: I::Ty, depth_limit: usize) -> bool {
|
||||
self.types_may_unify_inner(lhs, rhs, depth_limit)
|
||||
}
|
||||
|
||||
fn args_may_unify_inner(
|
||||
self,
|
||||
obligation_args: I::GenericArgs,
|
||||
|
|
|
|||
|
|
@ -141,9 +141,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -183,38 +183,6 @@ impl Argument<'_> {
|
|||
ArgumentType::Placeholder { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by `format_args` when all arguments are gone after inlining,
|
||||
/// when using `&[]` would incorrectly allow for a bigger lifetime.
|
||||
///
|
||||
/// This fails without format argument inlining, and that shouldn't be different
|
||||
/// when the argument is inlined:
|
||||
///
|
||||
/// ```compile_fail,E0716
|
||||
/// let f = format_args!("{}", "a");
|
||||
/// println!("{f}");
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn none() -> [Self; 0] {
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct represents the unsafety of constructing an `Arguments`.
|
||||
/// It exists, rather than an unsafe function, in order to simplify the expansion
|
||||
/// of `format_args!(..)` and reduce the scope of the `unsafe` block.
|
||||
#[lang = "format_unsafe_arg"]
|
||||
pub struct UnsafeArg {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl UnsafeArg {
|
||||
/// See documentation where `UnsafeArg` is required to know when it is safe to
|
||||
/// create and use `UnsafeArg`.
|
||||
#[inline]
|
||||
pub const unsafe fn new() -> Self {
|
||||
Self { _private: () }
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by the format_args!() macro to create a fmt::Arguments object.
|
||||
|
|
@ -248,8 +216,7 @@ impl<'a> Arguments<'a> {
|
|||
|
||||
/// Specifies nonstandard formatting parameters.
|
||||
///
|
||||
/// An `rt::UnsafeArg` is required because the following invariants must be held
|
||||
/// in order for this function to be safe:
|
||||
/// SAFETY: the following invariants must be held:
|
||||
/// 1. The `pieces` slice must be at least as long as `fmt`.
|
||||
/// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
|
||||
/// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
|
||||
|
|
@ -261,11 +228,10 @@ impl<'a> Arguments<'a> {
|
|||
/// const _: () = if false { panic!("a {:1}", "a") };
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn new_v1_formatted(
|
||||
pub unsafe fn new_v1_formatted(
|
||||
pieces: &'a [&'static str],
|
||||
args: &'a [rt::Argument<'a>],
|
||||
fmt: &'a [rt::Placeholder],
|
||||
_unsafe_arg: rt::UnsafeArg,
|
||||
) -> Arguments<'a> {
|
||||
Arguments { pieces, fmt: Some(fmt), args }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,21 @@ mod builders;
|
|||
mod float;
|
||||
mod num;
|
||||
|
||||
#[test]
|
||||
fn test_lifetime() {
|
||||
// Trigger all different forms of expansion,
|
||||
// and check that each of them can be stored as a variable.
|
||||
let a = format_args!("hello");
|
||||
let a = format_args!("hello {a}");
|
||||
let a = format_args!("hello {a:1}");
|
||||
let a = format_args!("hello {a} {a:?}");
|
||||
assert_eq!(a.to_string(), "hello hello hello hello hello hello hello");
|
||||
|
||||
// Without arguments, it should also work in consts.
|
||||
const A: std::fmt::Arguments<'static> = format_args!("hello");
|
||||
assert_eq!(A.to_string(), "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_flags() {
|
||||
// No residual flags left by pointer formatting
|
||||
|
|
|
|||
|
|
@ -1316,8 +1316,17 @@ impl PathBuf {
|
|||
need_sep = false
|
||||
}
|
||||
|
||||
let need_clear = if cfg!(target_os = "cygwin") {
|
||||
// If path is absolute and its prefix is none, it is like `/foo`,
|
||||
// and will be handled below.
|
||||
path.prefix().is_some()
|
||||
} else {
|
||||
// On Unix: prefix is always None.
|
||||
path.is_absolute() || path.prefix().is_some()
|
||||
};
|
||||
|
||||
// absolute `path` replaces `self`
|
||||
if path.is_absolute() || path.prefix().is_some() {
|
||||
if need_clear {
|
||||
self.inner.truncate(0);
|
||||
|
||||
// verbatim paths need . and .. removed
|
||||
|
|
@ -3643,6 +3652,11 @@ impl Error for NormalizeError {}
|
|||
/// paths, this is currently equivalent to calling
|
||||
/// [`GetFullPathNameW`][windows-path].
|
||||
///
|
||||
/// On Cygwin, this is currently equivalent to calling [`cygwin_conv_path`][cygwin-path]
|
||||
/// with mode `CCP_WIN_A_TO_POSIX`, and then being processed like other POSIX platforms.
|
||||
/// If a Windows path is given, it will be converted to an absolute POSIX path without
|
||||
/// keeping `..`.
|
||||
///
|
||||
/// Note that these [may change in the future][changes].
|
||||
///
|
||||
/// # Errors
|
||||
|
|
@ -3700,6 +3714,7 @@ impl Error for NormalizeError {}
|
|||
/// [changes]: io#platform-specific-behavior
|
||||
/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
||||
/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
|
||||
/// [cygwin-path]: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
|
||||
#[stable(feature = "absolute_path", since = "1.79.0")]
|
||||
pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
|
|
|
|||
92
library/std/src/sys/path/cygwin.rs
Normal file
92
library/std/src/sys/path/cygwin.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
use crate::ffi::OsString;
|
||||
use crate::os::unix::ffi::OsStringExt;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::common::small_c_string::run_path_with_cstr;
|
||||
use crate::sys::cvt;
|
||||
use crate::{io, ptr};
|
||||
|
||||
#[inline]
|
||||
pub fn is_sep_byte(b: u8) -> bool {
|
||||
b == b'/' || b == b'\\'
|
||||
}
|
||||
|
||||
/// Cygwin allways prefers `/` over `\`, and it always converts all `/` to `\`
|
||||
/// internally when calling Win32 APIs. Therefore, the server component of path
|
||||
/// `\\?\UNC\localhost/share` is `localhost/share` on Win32, but `localhost`
|
||||
/// on Cygwin.
|
||||
#[inline]
|
||||
pub fn is_verbatim_sep(b: u8) -> bool {
|
||||
b == b'/' || b == b'\\'
|
||||
}
|
||||
|
||||
pub use super::windows_prefix::parse_prefix;
|
||||
|
||||
pub const MAIN_SEP_STR: &str = "/";
|
||||
pub const MAIN_SEP: char = '/';
|
||||
|
||||
unsafe extern "C" {
|
||||
// Doc: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
|
||||
// Src: https://github.com/cygwin/cygwin/blob/718a15ba50e0d01c79800bd658c2477f9a603540/winsup/cygwin/path.cc#L3902
|
||||
// Safety:
|
||||
// * `what` should be `CCP_WIN_A_TO_POSIX` here
|
||||
// * `from` is null-terminated UTF-8 path
|
||||
// * `to` is buffer, the buffer size is `size`.
|
||||
//
|
||||
// Converts a path to an absolute POSIX path, no matter the input is Win32 path or POSIX path.
|
||||
fn cygwin_conv_path(
|
||||
what: libc::c_uint,
|
||||
from: *const libc::c_char,
|
||||
to: *mut u8,
|
||||
size: libc::size_t,
|
||||
) -> libc::ssize_t;
|
||||
}
|
||||
|
||||
const CCP_WIN_A_TO_POSIX: libc::c_uint = 2;
|
||||
|
||||
/// Make a POSIX path absolute.
|
||||
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
|
||||
run_path_with_cstr(path, &|path| {
|
||||
let conv = CCP_WIN_A_TO_POSIX;
|
||||
let size = cvt(unsafe { cygwin_conv_path(conv, path.as_ptr(), ptr::null_mut(), 0) })?;
|
||||
// If success, size should not be 0.
|
||||
debug_assert!(size >= 1);
|
||||
let size = size as usize;
|
||||
let mut buffer = Vec::with_capacity(size);
|
||||
cvt(unsafe { cygwin_conv_path(conv, path.as_ptr(), buffer.as_mut_ptr(), size) })?;
|
||||
unsafe {
|
||||
buffer.set_len(size - 1);
|
||||
}
|
||||
Ok(PathBuf::from(OsString::from_vec(buffer)))
|
||||
})
|
||||
.map(|path| {
|
||||
if path.prefix().is_some() {
|
||||
return path;
|
||||
}
|
||||
|
||||
// From unix.rs
|
||||
let mut components = path.components();
|
||||
let path_os = path.as_os_str().as_encoded_bytes();
|
||||
|
||||
let mut normalized = if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
|
||||
components.next();
|
||||
PathBuf::from("//")
|
||||
} else {
|
||||
PathBuf::new()
|
||||
};
|
||||
normalized.extend(components);
|
||||
|
||||
if path_os.ends_with(b"/") {
|
||||
normalized.push("");
|
||||
}
|
||||
|
||||
normalized
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn is_absolute(path: &Path) -> bool {
|
||||
if path.as_os_str().as_encoded_bytes().starts_with(b"\\") {
|
||||
path.has_root() && path.prefix().is_some()
|
||||
} else {
|
||||
path.has_root()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "windows")] {
|
||||
mod windows;
|
||||
mod windows_prefix;
|
||||
pub use windows::*;
|
||||
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
|
||||
mod sgx;
|
||||
|
|
@ -11,6 +12,10 @@ cfg_if::cfg_if! {
|
|||
} else if #[cfg(target_os = "uefi")] {
|
||||
mod uefi;
|
||||
pub use uefi::*;
|
||||
} else if #[cfg(target_os = "cygwin")] {
|
||||
mod cygwin;
|
||||
mod windows_prefix;
|
||||
pub use cygwin::*;
|
||||
} else {
|
||||
mod unix;
|
||||
pub use unix::*;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ffi::{OsStr, OsString};
|
||||
use crate::path::{Path, PathBuf, Prefix};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::api::utf16;
|
||||
use crate::sys::pal::{c, fill_utf16_buf, os2path, to_u16s};
|
||||
use crate::{io, ptr};
|
||||
|
|
@ -7,6 +7,8 @@ use crate::{io, ptr};
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use super::windows_prefix::parse_prefix;
|
||||
|
||||
pub const MAIN_SEP_STR: &str = "\\";
|
||||
pub const MAIN_SEP: char = '\\';
|
||||
|
||||
|
|
@ -77,177 +79,6 @@ pub(crate) fn append_suffix(path: PathBuf, suffix: &OsStr) -> PathBuf {
|
|||
path.into()
|
||||
}
|
||||
|
||||
struct PrefixParser<'a, const LEN: usize> {
|
||||
path: &'a OsStr,
|
||||
prefix: [u8; LEN],
|
||||
}
|
||||
|
||||
impl<'a, const LEN: usize> PrefixParser<'a, LEN> {
|
||||
#[inline]
|
||||
fn get_prefix(path: &OsStr) -> [u8; LEN] {
|
||||
let mut prefix = [0; LEN];
|
||||
// SAFETY: Only ASCII characters are modified.
|
||||
for (i, &ch) in path.as_encoded_bytes().iter().take(LEN).enumerate() {
|
||||
prefix[i] = if ch == b'/' { b'\\' } else { ch };
|
||||
}
|
||||
prefix
|
||||
}
|
||||
|
||||
fn new(path: &'a OsStr) -> Self {
|
||||
Self { path, prefix: Self::get_prefix(path) }
|
||||
}
|
||||
|
||||
fn as_slice(&self) -> PrefixParserSlice<'a, '_> {
|
||||
PrefixParserSlice {
|
||||
path: self.path,
|
||||
prefix: &self.prefix[..LEN.min(self.path.len())],
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PrefixParserSlice<'a, 'b> {
|
||||
path: &'a OsStr,
|
||||
prefix: &'b [u8],
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> PrefixParserSlice<'a, '_> {
|
||||
fn strip_prefix(&self, prefix: &str) -> Option<Self> {
|
||||
self.prefix[self.index..]
|
||||
.starts_with(prefix.as_bytes())
|
||||
.then_some(Self { index: self.index + prefix.len(), ..*self })
|
||||
}
|
||||
|
||||
fn prefix_bytes(&self) -> &'a [u8] {
|
||||
&self.path.as_encoded_bytes()[..self.index]
|
||||
}
|
||||
|
||||
fn finish(self) -> &'a OsStr {
|
||||
// SAFETY: The unsafety here stems from converting between &OsStr and
|
||||
// &[u8] and back. This is safe to do because (1) we only look at ASCII
|
||||
// contents of the encoding and (2) new &OsStr values are produced only
|
||||
// from ASCII-bounded slices of existing &OsStr values.
|
||||
unsafe { OsStr::from_encoded_bytes_unchecked(&self.path.as_encoded_bytes()[self.index..]) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
|
||||
use Prefix::{DeviceNS, Disk, UNC, Verbatim, VerbatimDisk, VerbatimUNC};
|
||||
|
||||
let parser = PrefixParser::<8>::new(path);
|
||||
let parser = parser.as_slice();
|
||||
if let Some(parser) = parser.strip_prefix(r"\\") {
|
||||
// \\
|
||||
|
||||
// The meaning of verbatim paths can change when they use a different
|
||||
// separator.
|
||||
if let Some(parser) = parser.strip_prefix(r"?\")
|
||||
&& !parser.prefix_bytes().iter().any(|&x| x == b'/')
|
||||
{
|
||||
// \\?\
|
||||
if let Some(parser) = parser.strip_prefix(r"UNC\") {
|
||||
// \\?\UNC\server\share
|
||||
|
||||
let path = parser.finish();
|
||||
let (server, path) = parse_next_component(path, true);
|
||||
let (share, _) = parse_next_component(path, true);
|
||||
|
||||
Some(VerbatimUNC(server, share))
|
||||
} else {
|
||||
let path = parser.finish();
|
||||
|
||||
// in verbatim paths only recognize an exact drive prefix
|
||||
if let Some(drive) = parse_drive_exact(path) {
|
||||
// \\?\C:
|
||||
Some(VerbatimDisk(drive))
|
||||
} else {
|
||||
// \\?\prefix
|
||||
let (prefix, _) = parse_next_component(path, true);
|
||||
Some(Verbatim(prefix))
|
||||
}
|
||||
}
|
||||
} else if let Some(parser) = parser.strip_prefix(r".\") {
|
||||
// \\.\COM42
|
||||
let path = parser.finish();
|
||||
let (prefix, _) = parse_next_component(path, false);
|
||||
Some(DeviceNS(prefix))
|
||||
} else {
|
||||
let path = parser.finish();
|
||||
let (server, path) = parse_next_component(path, false);
|
||||
let (share, _) = parse_next_component(path, false);
|
||||
|
||||
if !server.is_empty() && !share.is_empty() {
|
||||
// \\server\share
|
||||
Some(UNC(server, share))
|
||||
} else {
|
||||
// no valid prefix beginning with "\\" recognized
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If it has a drive like `C:` then it's a disk.
|
||||
// Otherwise there is no prefix.
|
||||
parse_drive(path).map(Disk)
|
||||
}
|
||||
}
|
||||
|
||||
// Parses a drive prefix, e.g. "C:" and "C:\whatever"
|
||||
fn parse_drive(path: &OsStr) -> Option<u8> {
|
||||
// In most DOS systems, it is not possible to have more than 26 drive letters.
|
||||
// See <https://en.wikipedia.org/wiki/Drive_letter_assignment#Common_assignments>.
|
||||
fn is_valid_drive_letter(drive: &u8) -> bool {
|
||||
drive.is_ascii_alphabetic()
|
||||
}
|
||||
|
||||
match path.as_encoded_bytes() {
|
||||
[drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Parses a drive prefix exactly, e.g. "C:"
|
||||
fn parse_drive_exact(path: &OsStr) -> Option<u8> {
|
||||
// only parse two bytes: the drive letter and the drive separator
|
||||
if path.as_encoded_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
|
||||
parse_drive(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the next path component.
|
||||
//
|
||||
// Returns the next component and the rest of the path excluding the component and separator.
|
||||
// Does not recognize `/` as a separator character if `verbatim` is true.
|
||||
fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
|
||||
let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
|
||||
|
||||
match path.as_encoded_bytes().iter().position(|&x| separator(x)) {
|
||||
Some(separator_start) => {
|
||||
let separator_end = separator_start + 1;
|
||||
|
||||
let component = &path.as_encoded_bytes()[..separator_start];
|
||||
|
||||
// Panic safe
|
||||
// The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
|
||||
let path = &path.as_encoded_bytes()[separator_end..];
|
||||
|
||||
// SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
|
||||
// is encoded in a single byte, therefore `bytes[separator_start]` and
|
||||
// `bytes[separator_end]` must be code point boundaries and thus
|
||||
// `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
|
||||
unsafe {
|
||||
(
|
||||
OsStr::from_encoded_bytes_unchecked(component),
|
||||
OsStr::from_encoded_bytes_unchecked(path),
|
||||
)
|
||||
}
|
||||
}
|
||||
None => (path, OsStr::new("")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a UTF-16 encoded path capable of bypassing the legacy `MAX_PATH` limits.
|
||||
///
|
||||
/// This path may or may not have a verbatim prefix.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use super::super::windows_prefix::*;
|
||||
use super::*;
|
||||
use crate::path::Prefix;
|
||||
|
||||
#[test]
|
||||
fn test_parse_next_component() {
|
||||
|
|
|
|||
182
library/std/src/sys/path/windows_prefix.rs
Normal file
182
library/std/src/sys/path/windows_prefix.rs
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
//! Parse Windows prefixes, for both Windows and Cygwin.
|
||||
|
||||
use super::{is_sep_byte, is_verbatim_sep};
|
||||
use crate::ffi::OsStr;
|
||||
use crate::path::Prefix;
|
||||
|
||||
struct PrefixParser<'a, const LEN: usize> {
|
||||
path: &'a OsStr,
|
||||
prefix: [u8; LEN],
|
||||
}
|
||||
|
||||
impl<'a, const LEN: usize> PrefixParser<'a, LEN> {
|
||||
#[inline]
|
||||
fn get_prefix(path: &OsStr) -> [u8; LEN] {
|
||||
let mut prefix = [0; LEN];
|
||||
// SAFETY: Only ASCII characters are modified.
|
||||
for (i, &ch) in path.as_encoded_bytes().iter().take(LEN).enumerate() {
|
||||
prefix[i] = if ch == b'/' { b'\\' } else { ch };
|
||||
}
|
||||
prefix
|
||||
}
|
||||
|
||||
fn new(path: &'a OsStr) -> Self {
|
||||
Self { path, prefix: Self::get_prefix(path) }
|
||||
}
|
||||
|
||||
fn as_slice(&self) -> PrefixParserSlice<'a, '_> {
|
||||
PrefixParserSlice {
|
||||
path: self.path,
|
||||
prefix: &self.prefix[..LEN.min(self.path.len())],
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PrefixParserSlice<'a, 'b> {
|
||||
path: &'a OsStr,
|
||||
prefix: &'b [u8],
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> PrefixParserSlice<'a, '_> {
|
||||
fn strip_prefix(&self, prefix: &str) -> Option<Self> {
|
||||
self.prefix[self.index..]
|
||||
.starts_with(prefix.as_bytes())
|
||||
.then_some(Self { index: self.index + prefix.len(), ..*self })
|
||||
}
|
||||
|
||||
fn prefix_bytes(&self) -> &'a [u8] {
|
||||
&self.path.as_encoded_bytes()[..self.index]
|
||||
}
|
||||
|
||||
fn finish(self) -> &'a OsStr {
|
||||
// SAFETY: The unsafety here stems from converting between &OsStr and
|
||||
// &[u8] and back. This is safe to do because (1) we only look at ASCII
|
||||
// contents of the encoding and (2) new &OsStr values are produced only
|
||||
// from ASCII-bounded slices of existing &OsStr values.
|
||||
unsafe { OsStr::from_encoded_bytes_unchecked(&self.path.as_encoded_bytes()[self.index..]) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
|
||||
use Prefix::{DeviceNS, Disk, UNC, Verbatim, VerbatimDisk, VerbatimUNC};
|
||||
|
||||
let parser = PrefixParser::<8>::new(path);
|
||||
let parser = parser.as_slice();
|
||||
if let Some(parser) = parser.strip_prefix(r"\\") {
|
||||
// \\
|
||||
|
||||
// It's a POSIX path.
|
||||
if cfg!(target_os = "cygwin") && !path.as_encoded_bytes().iter().any(|&x| x == b'\\') {
|
||||
return None;
|
||||
}
|
||||
|
||||
// The meaning of verbatim paths can change when they use a different
|
||||
// separator.
|
||||
if let Some(parser) = parser.strip_prefix(r"?\")
|
||||
// Cygwin allows `/` in verbatim paths.
|
||||
&& (cfg!(target_os = "cygwin") || !parser.prefix_bytes().iter().any(|&x| x == b'/'))
|
||||
{
|
||||
// \\?\
|
||||
if let Some(parser) = parser.strip_prefix(r"UNC\") {
|
||||
// \\?\UNC\server\share
|
||||
|
||||
let path = parser.finish();
|
||||
let (server, path) = parse_next_component(path, true);
|
||||
let (share, _) = parse_next_component(path, true);
|
||||
|
||||
Some(VerbatimUNC(server, share))
|
||||
} else {
|
||||
let path = parser.finish();
|
||||
|
||||
// in verbatim paths only recognize an exact drive prefix
|
||||
if let Some(drive) = parse_drive_exact(path) {
|
||||
// \\?\C:
|
||||
Some(VerbatimDisk(drive))
|
||||
} else {
|
||||
// \\?\prefix
|
||||
let (prefix, _) = parse_next_component(path, true);
|
||||
Some(Verbatim(prefix))
|
||||
}
|
||||
}
|
||||
} else if let Some(parser) = parser.strip_prefix(r".\") {
|
||||
// \\.\COM42
|
||||
let path = parser.finish();
|
||||
let (prefix, _) = parse_next_component(path, false);
|
||||
Some(DeviceNS(prefix))
|
||||
} else {
|
||||
let path = parser.finish();
|
||||
let (server, path) = parse_next_component(path, false);
|
||||
let (share, _) = parse_next_component(path, false);
|
||||
|
||||
if !server.is_empty() && !share.is_empty() {
|
||||
// \\server\share
|
||||
Some(UNC(server, share))
|
||||
} else {
|
||||
// no valid prefix beginning with "\\" recognized
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If it has a drive like `C:` then it's a disk.
|
||||
// Otherwise there is no prefix.
|
||||
Some(Disk(parse_drive(path)?))
|
||||
}
|
||||
}
|
||||
|
||||
// Parses a drive prefix, e.g. "C:" and "C:\whatever"
|
||||
fn parse_drive(path: &OsStr) -> Option<u8> {
|
||||
// In most DOS systems, it is not possible to have more than 26 drive letters.
|
||||
// See <https://en.wikipedia.org/wiki/Drive_letter_assignment#Common_assignments>.
|
||||
fn is_valid_drive_letter(drive: &u8) -> bool {
|
||||
drive.is_ascii_alphabetic()
|
||||
}
|
||||
|
||||
match path.as_encoded_bytes() {
|
||||
[drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Parses a drive prefix exactly, e.g. "C:"
|
||||
fn parse_drive_exact(path: &OsStr) -> Option<u8> {
|
||||
// only parse two bytes: the drive letter and the drive separator
|
||||
if path.as_encoded_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
|
||||
parse_drive(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the next path component.
|
||||
//
|
||||
// Returns the next component and the rest of the path excluding the component and separator.
|
||||
// Does not recognize `/` as a separator character on Windows if `verbatim` is true.
|
||||
pub(crate) fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
|
||||
let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
|
||||
|
||||
match path.as_encoded_bytes().iter().position(|&x| separator(x)) {
|
||||
Some(separator_start) => {
|
||||
let separator_end = separator_start + 1;
|
||||
|
||||
let component = &path.as_encoded_bytes()[..separator_start];
|
||||
|
||||
// Panic safe
|
||||
// The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
|
||||
let path = &path.as_encoded_bytes()[separator_end..];
|
||||
|
||||
// SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
|
||||
// is encoded in a single byte, therefore `bytes[separator_start]` and
|
||||
// `bytes[separator_end]` must be code point boundaries and thus
|
||||
// `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
|
||||
unsafe {
|
||||
(
|
||||
OsStr::from_encoded_bytes_unchecked(component),
|
||||
OsStr::from_encoded_bytes_unchecked(path),
|
||||
)
|
||||
}
|
||||
}
|
||||
None => (path, OsStr::new("")),
|
||||
}
|
||||
}
|
||||
|
|
@ -1112,6 +1112,473 @@ pub fn test_decompositions_windows() {
|
|||
);
|
||||
}
|
||||
|
||||
// Unix paths are tested in `test_decompositions_unix` above.
|
||||
#[test]
|
||||
#[cfg(target_os = "cygwin")]
|
||||
pub fn test_decompositions_cygwin() {
|
||||
t!("\\",
|
||||
iter: ["/"],
|
||||
has_root: true,
|
||||
is_absolute: false,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("c:",
|
||||
iter: ["c:"],
|
||||
has_root: false,
|
||||
is_absolute: false,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("c:\\",
|
||||
iter: ["c:", "/"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("c:/",
|
||||
iter: ["c:", "/"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("a\\b\\c",
|
||||
iter: ["a", "b", "c"],
|
||||
has_root: false,
|
||||
is_absolute: false,
|
||||
parent: Some("a\\b"),
|
||||
file_name: Some("c"),
|
||||
file_stem: Some("c"),
|
||||
extension: None,
|
||||
file_prefix: Some("c")
|
||||
);
|
||||
|
||||
t!("\\a",
|
||||
iter: ["/", "a"],
|
||||
has_root: true,
|
||||
is_absolute: false,
|
||||
parent: Some("\\"),
|
||||
file_name: Some("a"),
|
||||
file_stem: Some("a"),
|
||||
extension: None,
|
||||
file_prefix: Some("a")
|
||||
);
|
||||
|
||||
t!("c:\\foo.txt",
|
||||
iter: ["c:", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("c:\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\server\\share\\foo.txt",
|
||||
iter: ["\\\\server\\share", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\server\\share\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("//server/share\\foo.txt",
|
||||
iter: ["//server/share", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//server/share\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("//server/share/foo.txt",
|
||||
iter: ["/", "server", "share", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//server/share"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\server\\share",
|
||||
iter: ["\\\\server\\share", "/"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\server",
|
||||
iter: ["/", "server"],
|
||||
has_root: true,
|
||||
is_absolute: false,
|
||||
parent: Some("\\"),
|
||||
file_name: Some("server"),
|
||||
file_stem: Some("server"),
|
||||
extension: None,
|
||||
file_prefix: Some("server")
|
||||
);
|
||||
|
||||
t!("\\\\?\\bar\\foo.txt",
|
||||
iter: ["\\\\?\\bar", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\bar\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\?\\bar",
|
||||
iter: ["\\\\?\\bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\?\\",
|
||||
iter: ["\\\\?\\"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\?\\UNC\\server\\share\\foo.txt",
|
||||
iter: ["\\\\?\\UNC\\server\\share", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\UNC\\server\\share\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\?\\UNC\\server/share\\foo.txt",
|
||||
iter: ["\\\\?\\UNC\\server/share", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\UNC\\server/share\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("//?/UNC/server\\share/foo.txt",
|
||||
iter: ["//?/UNC/server\\share", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//?/UNC/server\\share/"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("//?/UNC/server/share/foo.txt",
|
||||
iter: ["/", "?", "UNC", "server", "share", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//?/UNC/server/share"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\?\\UNC\\server",
|
||||
iter: ["\\\\?\\UNC\\server"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\?\\UNC\\",
|
||||
iter: ["\\\\?\\UNC\\"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:\\foo.txt",
|
||||
iter: ["\\\\?\\C:", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\C:\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("//?/C:\\foo.txt",
|
||||
iter: ["//?/C:", "/", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//?/C:\\"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("//?/C:/foo.txt",
|
||||
iter: ["/", "?", "C:", "foo.txt"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//?/C:"),
|
||||
file_name: Some("foo.txt"),
|
||||
file_stem: Some("foo"),
|
||||
extension: Some("txt"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:\\",
|
||||
iter: ["\\\\?\\C:", "/"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:",
|
||||
iter: ["\\\\?\\C:"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\?\\foo/bar",
|
||||
iter: ["\\\\?\\foo", "/", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\foo/"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:/foo/bar",
|
||||
iter: ["\\\\?\\C:", "/", "foo", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\C:/foo"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("\\\\.\\foo\\bar",
|
||||
iter: ["\\\\.\\foo", "/", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\.\\foo\\"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("\\\\.\\foo",
|
||||
iter: ["\\\\.\\foo", "/"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("\\\\.\\foo/bar",
|
||||
iter: ["\\\\.\\foo", "/", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\.\\foo/"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("\\\\.\\foo\\bar/baz",
|
||||
iter: ["\\\\.\\foo", "/", "bar", "baz"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\.\\foo\\bar"),
|
||||
file_name: Some("baz"),
|
||||
file_stem: Some("baz"),
|
||||
extension: None,
|
||||
file_prefix: Some("baz")
|
||||
);
|
||||
|
||||
t!("\\\\.\\",
|
||||
iter: ["\\\\.\\", "/"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: None,
|
||||
file_name: None,
|
||||
file_stem: None,
|
||||
extension: None,
|
||||
file_prefix: None
|
||||
);
|
||||
|
||||
t!("//.\\foo/bar",
|
||||
iter: ["//.\\foo", "/", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//.\\foo/"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("\\\\./foo/bar",
|
||||
iter: ["\\\\./foo", "/", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\./foo/"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("//./foo\\bar",
|
||||
iter: ["//./foo", "/", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//./foo\\"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("//./?/C:/foo/bar",
|
||||
iter: ["/", "?", "C:", "foo", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//./?/C:/foo"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("//././../././../?/C:/foo/bar",
|
||||
iter: ["/", "..", "..", "?", "C:", "foo", "bar"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("//././../././../?/C:/foo"),
|
||||
file_name: Some("bar"),
|
||||
file_stem: Some("bar"),
|
||||
extension: None,
|
||||
file_prefix: Some("bar")
|
||||
);
|
||||
|
||||
t!("\\\\?\\a\\b\\",
|
||||
iter: ["\\\\?\\a", "/", "b"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\a\\"),
|
||||
file_name: Some("b"),
|
||||
file_stem: Some("b"),
|
||||
extension: None,
|
||||
file_prefix: Some("b")
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:\\foo.txt.zip",
|
||||
iter: ["\\\\?\\C:", "/", "foo.txt.zip"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\C:\\"),
|
||||
file_name: Some("foo.txt.zip"),
|
||||
file_stem: Some("foo.txt"),
|
||||
extension: Some("zip"),
|
||||
file_prefix: Some("foo")
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:\\.foo.txt.zip",
|
||||
iter: ["\\\\?\\C:", "/", ".foo.txt.zip"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\C:\\"),
|
||||
file_name: Some(".foo.txt.zip"),
|
||||
file_stem: Some(".foo.txt"),
|
||||
extension: Some("zip"),
|
||||
file_prefix: Some(".foo")
|
||||
);
|
||||
|
||||
t!("\\\\?\\C:\\.foo",
|
||||
iter: ["\\\\?\\C:", "/", ".foo"],
|
||||
has_root: true,
|
||||
is_absolute: true,
|
||||
parent: Some("\\\\?\\C:\\"),
|
||||
file_name: Some(".foo"),
|
||||
file_stem: Some(".foo"),
|
||||
extension: None,
|
||||
file_prefix: Some(".foo")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_stem_ext() {
|
||||
t!("foo",
|
||||
|
|
@ -1227,6 +1694,11 @@ pub fn test_push() {
|
|||
tp!("/foo/bar", "/", "/");
|
||||
tp!("/foo/bar", "/baz", "/baz");
|
||||
tp!("/foo/bar", "./baz", "/foo/bar/./baz");
|
||||
|
||||
if cfg!(target_os = "cygwin") {
|
||||
tp!("c:\\", "windows", "c:\\windows");
|
||||
tp!("c:", "windows", "c:windows");
|
||||
}
|
||||
} else {
|
||||
tp!("", "foo", "foo");
|
||||
tp!("foo", "bar", r"foo\bar");
|
||||
|
|
|
|||
|
|
@ -463,12 +463,12 @@ fn oneshot_single_thread_recv_timeout() {
|
|||
fn stress_recv_timeout_two_threads() {
|
||||
let (tx, rx) = channel();
|
||||
let stress = stress_factor() + 50;
|
||||
let timeout = Duration::from_millis(5);
|
||||
let timeout = Duration::from_millis(10);
|
||||
|
||||
thread::spawn(move || {
|
||||
for i in 0..stress {
|
||||
if i % 2 == 0 {
|
||||
thread::sleep(timeout * 2);
|
||||
thread::sleep(timeout * 4);
|
||||
}
|
||||
tx.send(1usize).unwrap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,6 @@ pub struct Std {
|
|||
///
|
||||
/// [`compile::Rustc`]: crate::core::build_steps::compile::Rustc
|
||||
crates: Vec<String>,
|
||||
/// Override `Builder::kind` on cargo invocations.
|
||||
///
|
||||
/// By default, `Builder::kind` is propagated as the subcommand to the cargo invocations.
|
||||
/// However, there are cases when this is not desirable. For example, when running `x clippy $tool_name`,
|
||||
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
|
||||
/// which is not useful if we only want to lint a few crates with specific rules.
|
||||
override_build_kind: Option<Kind>,
|
||||
/// Never use this from outside calls. It is intended for internal use only within `check::Std::make_run`
|
||||
/// and `check::Std::run`.
|
||||
custom_stage: Option<u32>,
|
||||
|
|
@ -37,12 +30,7 @@ impl Std {
|
|||
const CRATE_OR_DEPS: &[&str] = &["sysroot", "coretests", "alloctests"];
|
||||
|
||||
pub fn new(target: TargetSelection) -> Self {
|
||||
Self { target, crates: vec![], override_build_kind: None, custom_stage: None }
|
||||
}
|
||||
|
||||
pub fn build_kind(mut self, kind: Option<Kind>) -> Self {
|
||||
self.override_build_kind = kind;
|
||||
self
|
||||
Self { target, crates: vec![], custom_stage: None }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,12 +56,7 @@ impl Step for Std {
|
|||
1
|
||||
};
|
||||
|
||||
run.builder.ensure(Std {
|
||||
target: run.target,
|
||||
crates,
|
||||
override_build_kind: None,
|
||||
custom_stage: Some(stage),
|
||||
});
|
||||
run.builder.ensure(Std { target: run.target, crates, custom_stage: Some(stage) });
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
|
|
@ -116,7 +99,7 @@ impl Step for Std {
|
|||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
self.override_build_kind.unwrap_or(builder.kind),
|
||||
Kind::Check,
|
||||
);
|
||||
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
|
|
@ -147,9 +130,8 @@ impl Step for Std {
|
|||
}
|
||||
drop(_guard);
|
||||
|
||||
// don't run on std twice with x.py clippy
|
||||
// don't check test dependencies if we haven't built libtest
|
||||
if builder.kind == Kind::Clippy || !self.crates.iter().any(|krate| krate == "test") {
|
||||
if !self.crates.iter().any(|krate| krate == "test") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +147,7 @@ impl Step for Std {
|
|||
Mode::Std,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
self.override_build_kind.unwrap_or(builder.kind),
|
||||
Kind::Check,
|
||||
);
|
||||
|
||||
// If we're not in stage 0, tests and examples will fail to compile
|
||||
|
|
@ -199,13 +181,6 @@ pub struct Rustc {
|
|||
///
|
||||
/// [`compile::Rustc`]: crate::core::build_steps::compile::Rustc
|
||||
crates: Vec<String>,
|
||||
/// Override `Builder::kind` on cargo invocations.
|
||||
///
|
||||
/// By default, `Builder::kind` is propagated as the subcommand to the cargo invocations.
|
||||
/// However, there are cases when this is not desirable. For example, when running `x clippy $tool_name`,
|
||||
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
|
||||
/// which is not useful if we only want to lint a few crates with specific rules.
|
||||
override_build_kind: Option<Kind>,
|
||||
}
|
||||
|
||||
impl Rustc {
|
||||
|
|
@ -215,12 +190,7 @@ impl Rustc {
|
|||
.into_iter()
|
||||
.map(|krate| krate.name.to_string())
|
||||
.collect();
|
||||
Self { target, crates, override_build_kind: None }
|
||||
}
|
||||
|
||||
pub fn build_kind(mut self, build_kind: Option<Kind>) -> Self {
|
||||
self.override_build_kind = build_kind;
|
||||
self
|
||||
Self { target, crates }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +205,7 @@ impl Step for Rustc {
|
|||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = run.make_run_crates(Alias::Compiler);
|
||||
run.builder.ensure(Rustc { target: run.target, crates, override_build_kind: None });
|
||||
run.builder.ensure(Rustc { target: run.target, crates });
|
||||
}
|
||||
|
||||
/// Builds the compiler.
|
||||
|
|
@ -256,7 +226,7 @@ impl Step for Rustc {
|
|||
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, compiler.host));
|
||||
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, target));
|
||||
} else {
|
||||
builder.ensure(Std::new(target).build_kind(self.override_build_kind));
|
||||
builder.ensure(Std::new(target));
|
||||
}
|
||||
|
||||
let mut cargo = builder::Cargo::new(
|
||||
|
|
@ -265,17 +235,11 @@ impl Step for Rustc {
|
|||
Mode::Rustc,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
self.override_build_kind.unwrap_or(builder.kind),
|
||||
Kind::Check,
|
||||
);
|
||||
|
||||
rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
|
||||
|
||||
// For ./x.py clippy, don't run with --all-targets because
|
||||
// linting tests and benchmarks can produce very noisy results
|
||||
if builder.kind != Kind::Clippy {
|
||||
cargo.arg("--all-targets");
|
||||
}
|
||||
|
||||
// Explicitly pass -p for all compiler crates -- this will force cargo
|
||||
// to also check the tests/benches/examples for these crates, rather
|
||||
// than just the leaf crate.
|
||||
|
|
@ -400,14 +364,9 @@ impl Step for RustAnalyzer {
|
|||
|
||||
cargo.allow_features(crate::core::build_steps::tool::RustAnalyzer::ALLOW_FEATURES);
|
||||
|
||||
// For ./x.py clippy, don't check those targets because
|
||||
// linting tests and benchmarks can produce very noisy results
|
||||
if builder.kind != Kind::Clippy {
|
||||
// can't use `--all-targets` because `--examples` doesn't work well
|
||||
cargo.arg("--bins");
|
||||
cargo.arg("--tests");
|
||||
cargo.arg("--benches");
|
||||
}
|
||||
cargo.arg("--bins");
|
||||
cargo.arg("--tests");
|
||||
cargo.arg("--benches");
|
||||
|
||||
// Cargo's output path in a given stage, compiled by a particular
|
||||
// compiler for the specified target.
|
||||
|
|
@ -468,11 +427,7 @@ impl Step for Compiletest {
|
|||
|
||||
cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
|
||||
|
||||
// For ./x.py clippy, don't run with --all-targets because
|
||||
// linting tests and benchmarks can produce very noisy results
|
||||
if builder.kind != Kind::Clippy {
|
||||
cargo.arg("--all-targets");
|
||||
}
|
||||
cargo.arg("--all-targets");
|
||||
|
||||
let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, self.target))
|
||||
.with_prefix("compiletest-check");
|
||||
|
|
@ -546,11 +501,7 @@ fn run_tool_check_step(
|
|||
&[],
|
||||
);
|
||||
|
||||
// For ./x.py clippy, don't run with --all-targets because
|
||||
// linting tests and benchmarks can produce very noisy results
|
||||
if builder.kind != Kind::Clippy {
|
||||
cargo.arg("--all-targets");
|
||||
}
|
||||
cargo.arg("--all-targets");
|
||||
|
||||
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
|
||||
.with_prefix(&format!("{}-check", step_type_name.to_lowercase()));
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ impl Step for Rustc {
|
|||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
} else {
|
||||
builder.ensure(check::Std::new(target).build_kind(Some(Kind::Check)));
|
||||
builder.ensure(check::Std::new(target));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +289,7 @@ macro_rules! lint_any {
|
|||
let target = self.target;
|
||||
|
||||
if !builder.download_rustc() {
|
||||
builder.ensure(check::Rustc::new(target, builder).build_kind(Some(Kind::Check)));
|
||||
builder.ensure(check::Rustc::new(target, builder));
|
||||
};
|
||||
|
||||
let cargo = prepare_tool_cargo(
|
||||
|
|
|
|||
57
src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile
Normal file
57
src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
FROM ghcr.io/rust-lang/ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
make \
|
||||
ninja-build \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
git \
|
||||
cmake \
|
||||
libssl-dev \
|
||||
sudo \
|
||||
xz-utils \
|
||||
tidy \
|
||||
\
|
||||
libc6 \
|
||||
wget \
|
||||
# libgccjit dependencies
|
||||
flex \
|
||||
libmpfr-dev \
|
||||
libgmp-dev \
|
||||
libmpc3 \
|
||||
libmpc-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
# Fix rustc_codegen_gcc lto issues.
|
||||
ENV GCC_EXEC_PREFIX="/usr/lib/gcc/"
|
||||
|
||||
COPY host-x86_64/x86_64-gnu-miri/check-miri.sh /tmp/
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=x86_64-unknown-linux-gnu \
|
||||
--enable-new-symbol-mangling
|
||||
|
||||
ENV HOST_TARGET x86_64-unknown-linux-gnu
|
||||
|
||||
# FIXME(#133381): currently rustc alt builds do *not* have rustc debug
|
||||
# assertions enabled! Therefore, we cannot force download CI rustc.
|
||||
#ENV FORCE_CI_RUSTC 1
|
||||
|
||||
COPY scripts/shared.sh /scripts/
|
||||
|
||||
# For now, we need to use `--unsafe-perm=true` to go around an issue when npm tries
|
||||
# to create a new folder. For reference:
|
||||
# https://github.com/puppeteer/puppeteer/issues/375
|
||||
#
|
||||
# We also specify the version in case we need to update it to go around cache limitations.
|
||||
#
|
||||
# The `browser-ui-test.version` file is also used by bootstrap to emit warnings in case
|
||||
# the local version of the package is different than the one used by the CI.
|
||||
ENV SCRIPT /tmp/check-miri.sh ../x.py
|
||||
62
src/ci/docker/host-x86_64/x86_64-gnu-miri/check-miri.sh
Executable file
62
src/ci/docker/host-x86_64/x86_64-gnu-miri/check-miri.sh
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/sh
|
||||
# ignore-tidy-linelength
|
||||
|
||||
set -eu
|
||||
set -x # so one can see where we are in the script
|
||||
|
||||
X_PY="$1"
|
||||
|
||||
# Testing Miri is a bit complicated.
|
||||
# We set the GC interval to the shortest possible value (0 would be off) to increase the chance
|
||||
# that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail.
|
||||
# This significantly increases the runtime of our test suite, or we'd do this in PR CI too.
|
||||
if [ -z "${PR_CI_JOB:-}" ]; then
|
||||
MIRIFLAGS=-Zmiri-provenance-gc=1 python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri
|
||||
else
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri
|
||||
fi
|
||||
# We re-run the test suite for a chance to find bugs in the intrinsic fallback bodies and in MIR
|
||||
# optimizations. This can miss UB, so we only run the "pass" tests. We need to enable debug
|
||||
# assertions as `-O` disables them but some tests rely on them. We also set a cfg flag so tests can
|
||||
# adjust their expectations if needed. This can change the output of the tests so we ignore that,
|
||||
# we only ensure that all assertions still pass.
|
||||
MIRIFLAGS="-Zmiri-force-intrinsic-fallback --cfg force_intrinsic_fallback -O -Zmir-opt-level=4 -Cdebug-assertions=yes" \
|
||||
MIRI_SKIP_UI_CHECKS=1 \
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri -- tests/pass tests/panic
|
||||
# We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
|
||||
# Also cover some other targets via cross-testing, in particular all tier 1 targets.
|
||||
case $HOST_TARGET in
|
||||
x86_64-unknown-linux-gnu)
|
||||
# Only this branch runs in PR CI.
|
||||
# Fully test all main OSes, and all main architectures.
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target aarch64-apple-darwin
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target i686-pc-windows-msvc
|
||||
# Only run "pass" tests for the remaining targets, which is quite a bit faster.
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target i686-unknown-linux-gnu --test-args pass
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-unknown-linux-gnu --test-args pass
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target s390x-unknown-linux-gnu --test-args pass
|
||||
;;
|
||||
x86_64-pc-windows-msvc)
|
||||
# Strangely, Linux targets do not work here. cargo always says
|
||||
# "error: cannot produce cdylib for ... as the target ... does not support these crate types".
|
||||
# Only run "pass" tests, which is quite a bit faster.
|
||||
#FIXME: Re-enable this once CI issues are fixed
|
||||
# See <https://github.com/rust-lang/rust/issues/127883>
|
||||
# For now, these tests are moved to `x86_64-msvc-ext2` in `src/ci/github-actions/jobs.yml`.
|
||||
#python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-apple-darwin --test-args pass
|
||||
;;
|
||||
*)
|
||||
echo "FATAL: unexpected host $HOST_TARGET"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# Also smoke-test `x.py miri`. This doesn't run any actual tests (that would take too long),
|
||||
# but it ensures that the crates build properly when tested with Miri.
|
||||
|
||||
#FIXME: Re-enable this for msvc once CI issues are fixed
|
||||
if [ "$HOST_TARGET" != "x86_64-pc-windows-msvc" ]; then
|
||||
python3 "$X_PY" miri --stage 2 library/core --test-args notest
|
||||
python3 "$X_PY" miri --stage 2 library/alloc --test-args notest
|
||||
python3 "$X_PY" miri --stage 2 library/std --test-args notest
|
||||
fi
|
||||
|
|
@ -30,58 +30,3 @@ cat /tmp/toolstate/toolstates.json
|
|||
python3 "$X_PY" test --stage 2 check-tools
|
||||
python3 "$X_PY" test --stage 2 src/tools/clippy
|
||||
python3 "$X_PY" test --stage 2 src/tools/rustfmt
|
||||
|
||||
# Testing Miri is a bit more complicated.
|
||||
# We set the GC interval to the shortest possible value (0 would be off) to increase the chance
|
||||
# that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail.
|
||||
# This significantly increases the runtime of our test suite, or we'd do this in PR CI too.
|
||||
if [ -z "${PR_CI_JOB:-}" ]; then
|
||||
MIRIFLAGS=-Zmiri-provenance-gc=1 python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri
|
||||
else
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri
|
||||
fi
|
||||
# We re-run the test suite for a chance to find bugs in the intrinsic fallback bodies and in MIR
|
||||
# optimizations. This can miss UB, so we only run the "pass" tests. We need to enable debug
|
||||
# assertions as `-O` disables them but some tests rely on them. We also set a cfg flag so tests can
|
||||
# adjust their expectations if needed. This can change the output of the tests so we ignore that,
|
||||
# we only ensure that all assertions still pass.
|
||||
MIRIFLAGS="-Zmiri-force-intrinsic-fallback --cfg force_intrinsic_fallback -O -Zmir-opt-level=4 -Cdebug-assertions=yes" \
|
||||
MIRI_SKIP_UI_CHECKS=1 \
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri -- tests/pass tests/panic
|
||||
# We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
|
||||
# Also cover some other targets via cross-testing, in particular all tier 1 targets.
|
||||
case $HOST_TARGET in
|
||||
x86_64-unknown-linux-gnu)
|
||||
# Only this branch runs in PR CI.
|
||||
# Fully test all main OSes, and all main architectures.
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target aarch64-apple-darwin
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target i686-pc-windows-msvc
|
||||
# Only run "pass" tests for the remaining targets, which is quite a bit faster.
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target i686-unknown-linux-gnu --test-args pass
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-unknown-linux-gnu --test-args pass
|
||||
python3 "$X_PY" test --stage 2 src/tools/miri --target s390x-unknown-linux-gnu --test-args pass
|
||||
;;
|
||||
x86_64-pc-windows-msvc)
|
||||
# Strangely, Linux targets do not work here. cargo always says
|
||||
# "error: cannot produce cdylib for ... as the target ... does not support these crate types".
|
||||
# Only run "pass" tests, which is quite a bit faster.
|
||||
#FIXME: Re-enable this once CI issues are fixed
|
||||
# See <https://github.com/rust-lang/rust/issues/127883>
|
||||
# For now, these tests are moved to `x86_64-msvc-ext2` in `src/ci/github-actions/jobs.yml`.
|
||||
#python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-apple-darwin --test-args pass
|
||||
;;
|
||||
*)
|
||||
echo "FATAL: unexpected host $HOST_TARGET"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# Also smoke-test `x.py miri`. This doesn't run any actual tests (that would take too long),
|
||||
# but it ensures that the crates build properly when tested with Miri.
|
||||
|
||||
#FIXME: Re-enable this for msvc once CI issues are fixed
|
||||
if [ "$HOST_TARGET" != "x86_64-pc-windows-msvc" ]; then
|
||||
python3 "$X_PY" miri --stage 2 library/core --test-args notest
|
||||
python3 "$X_PY" miri --stage 2 library/alloc --test-args notest
|
||||
python3 "$X_PY" miri --stage 2 library/std --test-args notest
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -150,7 +150,9 @@ pr:
|
|||
DOCKER_SCRIPT: stage_2_test_set2.sh
|
||||
<<: *job-aarch64-linux
|
||||
- name: x86_64-gnu-tools
|
||||
<<: *job-linux-36c-codebuild
|
||||
<<: *job-linux-4c
|
||||
- name: x86_64-gnu-miri
|
||||
<<: *job-linux-4c
|
||||
|
||||
# Jobs that run when you perform a try build (@bors try)
|
||||
# These jobs automatically inherit envs.try, to avoid repeating
|
||||
|
|
@ -425,6 +427,9 @@ auto:
|
|||
DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: x86_64-gnu-miri
|
||||
<<: *job-linux-4c
|
||||
|
||||
####################
|
||||
# macOS Builders #
|
||||
####################
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ used for many other purposes. For example, tests can also be configured to [run
|
|||
the resulting program](#controlling-passfail-expectations) to verify its
|
||||
behavior.
|
||||
|
||||
For a survey of each subdirectory's purpose under `tests/ui`, consult the
|
||||
[SUMMARY.md](https://github.com/rust-lang/rust/tree/master/tests/ui/SUMMARY.md).
|
||||
This is useful if you write a new test, and are looking for a category to
|
||||
place it in.
|
||||
|
||||
If you need to work with `#![no_std]` cross-compiling tests, consult the
|
||||
[`minicore` test auxiliary](./minicore.md) chapter.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,28 +9,35 @@ if let StmtKind::Let(local) = stmt.kind
|
|||
&& let ExprKind::Call(func, args) = e.kind
|
||||
&& paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = args[0].kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 2
|
||||
&& let ExprKind::Block(block1, None) = args[0].kind
|
||||
&& block1.stmts.len() == 1
|
||||
&& let StmtKind::Let(local1) = block1.stmts[0].kind
|
||||
&& let Some(init1) = local1.init
|
||||
&& let ExprKind::Array(elements) = init1.kind
|
||||
&& elements.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = elements[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
|
||||
&& let ExprKind::Array(elements) = inner.kind
|
||||
&& elements.len() == 2
|
||||
&& let ExprKind::Lit(ref lit) = elements[0].kind
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind
|
||||
&& name.as_str() == "args"
|
||||
&& let Some(trailing_expr) = block1.expr
|
||||
&& let ExprKind::Call(func2, args2) = trailing_expr.kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 2
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 2
|
||||
&& let ExprKind::Lit(ref lit) = elements1[0].kind
|
||||
&& let LitKind::Str(s, _) = lit.node
|
||||
&& s.as_str() == ""
|
||||
&& let ExprKind::Lit(ref lit1) = elements[1].kind
|
||||
&& let ExprKind::Lit(ref lit1) = elements1[1].kind
|
||||
&& let LitKind::Str(s1, _) = lit1.node
|
||||
&& s1.as_str() == "\n"
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 1
|
||||
&& let ExprKind::Call(func2, args2) = elements1[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind
|
||||
&& block.expr.is_none()
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind
|
||||
&& name.as_str() == "print_text"
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind
|
||||
&& name1.as_str() == "print_text"
|
||||
{
|
||||
// report your lint here
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,25 +19,32 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
|
|||
&& let ExprKind::Call(func, args) = e1.kind
|
||||
&& paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = args[0].kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 2
|
||||
&& let ExprKind::Block(block2, None) = args[0].kind
|
||||
&& block2.stmts.len() == 1
|
||||
&& let StmtKind::Let(local) = block2.stmts[0].kind
|
||||
&& let Some(init) = local.init
|
||||
&& let ExprKind::Array(elements) = init.kind
|
||||
&& elements.len() == 1
|
||||
&& let ExprKind::Call(func1, args1) = elements[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args1.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
|
||||
&& let ExprKind::Array(elements) = inner.kind
|
||||
&& elements.len() == 2
|
||||
&& let ExprKind::Lit(ref lit2) = elements[0].kind
|
||||
&& let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind
|
||||
&& name1.as_str() == "args"
|
||||
&& let Some(trailing_expr) = block2.expr
|
||||
&& let ExprKind::Call(func2, args2) = trailing_expr.kind
|
||||
&& paths::CORE_FMT_RT_NEW_V1.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 2
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[0].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 2
|
||||
&& let ExprKind::Lit(ref lit2) = elements1[0].kind
|
||||
&& let LitKind::Str(s, _) = lit2.node
|
||||
&& s.as_str() == ""
|
||||
&& let ExprKind::Lit(ref lit3) = elements[1].kind
|
||||
&& let ExprKind::Lit(ref lit3) = elements1[1].kind
|
||||
&& let LitKind::Str(s1, _) = lit3.node
|
||||
&& s1.as_str() == "\n"
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args1[1].kind
|
||||
&& let ExprKind::Array(elements1) = inner1.kind
|
||||
&& elements1.len() == 1
|
||||
&& let ExprKind::Call(func2, args2) = elements1[0].kind
|
||||
&& paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed
|
||||
&& args2.len() == 1
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
|
||||
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[1].kind
|
||||
&& block1.expr.is_none()
|
||||
&& block.expr.is_none()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ fn main() {
|
|||
});
|
||||
|
||||
let _ = [0]
|
||||
//~^ suspicious_map
|
||||
.into_iter()
|
||||
.inspect(|&x| {
|
||||
//~^ manual_inspect
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ fn main() {
|
|||
});
|
||||
|
||||
let _ = [0]
|
||||
//~^ suspicious_map
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
//~^ manual_inspect
|
||||
|
|
|
|||
|
|
@ -157,25 +157,8 @@ LL |
|
|||
LL ~ println!("{}", x);
|
||||
|
|
||||
|
||||
error: this call to `map()` won't have an effect on the call to `count()`
|
||||
--> tests/ui/manual_inspect.rs:167:13
|
||||
|
|
||||
LL | let _ = [0]
|
||||
| _____________^
|
||||
LL | |
|
||||
LL | | .into_iter()
|
||||
LL | | .map(|x| {
|
||||
... |
|
||||
LL | | })
|
||||
LL | | .count();
|
||||
| |________________^
|
||||
|
|
||||
= help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`
|
||||
= note: `-D clippy::suspicious-map` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]`
|
||||
|
||||
error: using `map` over `inspect`
|
||||
--> tests/ui/manual_inspect.rs:170:10
|
||||
--> tests/ui/manual_inspect.rs:169:10
|
||||
|
|
||||
LL | .map(|x| {
|
||||
| ^^^
|
||||
|
|
@ -188,7 +171,7 @@ LL ~ println!("{}", x);
|
|||
|
|
||||
|
||||
error: using `map` over `inspect`
|
||||
--> tests/ui/manual_inspect.rs:203:30
|
||||
--> tests/ui/manual_inspect.rs:202:30
|
||||
|
|
||||
LL | if let Some(x) = Some(1).map(|x| { println!("{x}");
|
||||
| ^^^
|
||||
|
|
@ -200,5 +183,5 @@ LL | // Do not collapse code into this comment
|
|||
LL ~ }) {
|
||||
|
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
//@compile-flags: -Zmin-function-alignment=8
|
||||
#![feature(fn_align)]
|
||||
|
||||
// When a function uses `repr(align(N))`, the function address should be a multiple of `N`.
|
||||
// When a function uses `align(N)`, the function address should be a multiple of `N`.
|
||||
|
||||
#[repr(align(256))]
|
||||
#[align(256)]
|
||||
fn foo() {}
|
||||
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
fn bar() {}
|
||||
|
||||
#[repr(align(4))]
|
||||
#[align(4)]
|
||||
fn baz() {}
|
||||
|
||||
fn main() {
|
||||
assert!((foo as usize).is_multiple_of(256));
|
||||
assert!((bar as usize).is_multiple_of(16));
|
||||
|
||||
// The maximum of `repr(align(N))` and `-Zmin-function-alignment=N` is used.
|
||||
// The maximum of `align(N)` and `-Zmin-function-alignment=N` is used.
|
||||
assert!((baz as usize).is_multiple_of(8));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use crate::command::Command;
|
|||
use crate::env::env_var;
|
||||
use crate::path_helpers::cwd;
|
||||
use crate::util::set_host_compiler_dylib_path;
|
||||
use crate::{is_aix, is_darwin, is_msvc, is_windows, uname};
|
||||
use crate::{is_aix, is_darwin, is_msvc, is_windows, target, uname};
|
||||
|
||||
/// Construct a new `rustc` invocation. This will automatically set the library
|
||||
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
|
||||
|
|
@ -27,9 +27,15 @@ pub fn bare_rustc() -> Rustc {
|
|||
#[must_use]
|
||||
pub struct Rustc {
|
||||
cmd: Command,
|
||||
target: Option<String>,
|
||||
}
|
||||
|
||||
crate::macros::impl_common_helpers!(Rustc);
|
||||
// Only fill in the target just before execution, so that it can be overridden.
|
||||
crate::macros::impl_common_helpers!(Rustc, |rustc: &mut Rustc| {
|
||||
if let Some(target) = &rustc.target {
|
||||
rustc.cmd.arg(&format!("--target={target}"));
|
||||
}
|
||||
});
|
||||
|
||||
pub fn rustc_path() -> String {
|
||||
env_var("RUSTC")
|
||||
|
|
@ -46,19 +52,22 @@ impl Rustc {
|
|||
// `rustc` invocation constructor methods
|
||||
|
||||
/// Construct a new `rustc` invocation. This will automatically set the library
|
||||
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
|
||||
/// search path as `-L cwd()` and also the compilation target.
|
||||
/// Use [`bare_rustc`] to avoid this.
|
||||
#[track_caller]
|
||||
pub fn new() -> Self {
|
||||
let mut cmd = setup_common();
|
||||
cmd.arg("-L").arg(cwd());
|
||||
Self { cmd }
|
||||
|
||||
// Automatically default to cross-compilation
|
||||
Self { cmd, target: Some(target()) }
|
||||
}
|
||||
|
||||
/// Construct a bare `rustc` invocation with no flags set.
|
||||
#[track_caller]
|
||||
pub fn bare() -> Self {
|
||||
let cmd = setup_common();
|
||||
Self { cmd }
|
||||
Self { cmd, target: None }
|
||||
}
|
||||
|
||||
// Argument provider methods
|
||||
|
|
@ -234,8 +243,9 @@ impl Rustc {
|
|||
|
||||
/// Specify the target triple, or a path to a custom target json spec file.
|
||||
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
|
||||
let target = target.as_ref();
|
||||
self.cmd.arg(format!("--target={target}"));
|
||||
// We store the target as a separate field, so that it can be specified multiple times.
|
||||
// This is in particular useful to override the default target set in Rustc::new().
|
||||
self.target = Some(target.as_ref().to_string());
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,21 +3,36 @@ use std::path::Path;
|
|||
|
||||
use crate::command::Command;
|
||||
use crate::env::env_var;
|
||||
use crate::target;
|
||||
use crate::util::set_host_compiler_dylib_path;
|
||||
|
||||
/// Construct a new `rustdoc` invocation. This will configure the host compiler runtime libs.
|
||||
/// Construct a new `rustdoc` invocation with target automatically set to cross-compile target and
|
||||
/// with host compiler runtime libs configured. Use [`bare_rustdoc`] to avoid automatically setting
|
||||
/// cross-compile target.
|
||||
#[track_caller]
|
||||
pub fn rustdoc() -> Rustdoc {
|
||||
Rustdoc::new()
|
||||
}
|
||||
|
||||
/// Bare `rustdoc` invocation, no args set.
|
||||
#[track_caller]
|
||||
pub fn bare_rustdoc() -> Rustdoc {
|
||||
Rustdoc::bare()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub struct Rustdoc {
|
||||
cmd: Command,
|
||||
target: Option<String>,
|
||||
}
|
||||
|
||||
crate::macros::impl_common_helpers!(Rustdoc);
|
||||
// Only fill in the target just before execution, so that it can be overridden.
|
||||
crate::macros::impl_common_helpers!(Rustdoc, |rustdoc: &mut Rustdoc| {
|
||||
if let Some(target) = &rustdoc.target {
|
||||
rustdoc.cmd.arg(&format!("--target={target}"));
|
||||
}
|
||||
});
|
||||
|
||||
#[track_caller]
|
||||
fn setup_common() -> Command {
|
||||
|
|
@ -28,11 +43,20 @@ fn setup_common() -> Command {
|
|||
}
|
||||
|
||||
impl Rustdoc {
|
||||
/// Construct a bare `rustdoc` invocation. This will configure the host compiler runtime libs.
|
||||
/// Construct a new `rustdoc` invocation with target automatically set to cross-compile target
|
||||
/// and with host compiler runtime libs configured. Use [`bare_rustdoc`] to avoid automatically
|
||||
/// setting cross-compile target.
|
||||
#[track_caller]
|
||||
pub fn new() -> Self {
|
||||
let cmd = setup_common();
|
||||
Self { cmd }
|
||||
Self { cmd, target: Some(target()) }
|
||||
}
|
||||
|
||||
/// Bare `rustdoc` invocation, no args set.
|
||||
#[track_caller]
|
||||
pub fn bare() -> Self {
|
||||
let cmd = setup_common();
|
||||
Self { cmd, target: None }
|
||||
}
|
||||
|
||||
/// Specify where an external library is located.
|
||||
|
|
@ -85,8 +109,9 @@ impl Rustdoc {
|
|||
|
||||
/// Specify the target triple, or a path to a custom target json spec file.
|
||||
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
|
||||
let target = target.as_ref();
|
||||
self.cmd.arg(format!("--target={target}"));
|
||||
// We store the target as a separate field, so that it can be specified multiple times.
|
||||
// This is in particular useful to override the default target set in `Rustdoc::new()`.
|
||||
self.target = Some(target.as_ref().to_string());
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ pub use llvm::{
|
|||
};
|
||||
pub use python::python_command;
|
||||
pub use rustc::{bare_rustc, rustc, rustc_path, Rustc};
|
||||
pub use rustdoc::{rustdoc, Rustdoc};
|
||||
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
|
||||
|
||||
/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -23,10 +23,16 @@
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You can pass an optional second parameter which should be a function that is passed
|
||||
/// `&mut self` just before the command is executed.
|
||||
///
|
||||
/// [`Command`]: crate::command::Command
|
||||
/// [`CompletedProcess`]: crate::command::CompletedProcess
|
||||
macro_rules! impl_common_helpers {
|
||||
($wrapper: ident) => {
|
||||
$crate::macros::impl_common_helpers!($wrapper, |_| {});
|
||||
};
|
||||
($wrapper: ident, $before_exec: expr) => {
|
||||
impl $wrapper {
|
||||
/// In very rare circumstances, you may need a e.g. `bare_rustc()` or `bare_rustdoc()`
|
||||
/// with host runtime libs configured, but want the underlying raw
|
||||
|
|
@ -130,12 +136,14 @@ macro_rules! impl_common_helpers {
|
|||
/// Run the constructed command and assert that it is successfully run.
|
||||
#[track_caller]
|
||||
pub fn run(&mut self) -> crate::command::CompletedProcess {
|
||||
$before_exec(&mut *self);
|
||||
self.cmd.run()
|
||||
}
|
||||
|
||||
/// Run the constructed command and assert that it does not successfully run.
|
||||
#[track_caller]
|
||||
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
|
||||
$before_exec(&mut *self);
|
||||
self.cmd.run_fail()
|
||||
}
|
||||
|
||||
|
|
@ -145,6 +153,7 @@ macro_rules! impl_common_helpers {
|
|||
/// whenever possible.
|
||||
#[track_caller]
|
||||
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
|
||||
$before_exec(&mut *self);
|
||||
self.cmd.run_unchecked()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ version = 4
|
|||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
|
|
@ -156,18 +156,18 @@ checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.26"
|
||||
version = "1.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
|
||||
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
|
|
@ -185,9 +185,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.39"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
|
||||
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -195,9 +195,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.39"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
|
||||
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -208,18 +208,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.52"
|
||||
version = "4.5.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a554639e42d0c838336fc4fbedb9e2df3ad1fa4acda149f9126b4ccfcd7900f"
|
||||
checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.32"
|
||||
version = "4.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
|
||||
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
|
|
@ -229,9 +229,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.4"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
|
|
@ -527,11 +527,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.14",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -768,9 +768,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93"
|
||||
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
|
||||
dependencies = [
|
||||
"jiff-static",
|
||||
"log",
|
||||
|
|
@ -781,9 +781,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "jiff-static"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442"
|
||||
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -808,9 +808,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "linereader"
|
||||
|
|
@ -966,15 +966,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
|
@ -1325,7 +1325,7 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5b8e8a7c20c600f9b98cbf46b64e63d5c9e69deb98cee1ff264de9f1dda5d"
|
||||
dependencies = [
|
||||
"unicode-width 0.2.0",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1345,9 +1345,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
|
|
@ -1548,9 +1548,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
version = "2.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1760,15 +1760,9 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.14"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
|
|
@ -1940,9 +1934,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
|
|
@ -2037,9 +2031,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.10"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -305,7 +305,6 @@ ui/borrowck/issue-104639-lifetime-order.rs
|
|||
ui/borrowck/issue-10876.rs
|
||||
ui/borrowck/issue-109271-pass-self-into-closure.rs
|
||||
ui/borrowck/issue-111554.rs
|
||||
ui/borrowck/issue-114374-invalid-help-fmt-args.rs
|
||||
ui/borrowck/issue-11493.rs
|
||||
ui/borrowck/issue-115259-suggest-iter-mut.rs
|
||||
ui/borrowck/issue-119915-bad-clone-suggestion.rs
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ extern "C" fn nop() {
|
|||
#[unsafe(naked)]
|
||||
#[linkage = "weak"]
|
||||
// wasm functions cannot be aligned, so this has no effect
|
||||
#[repr(align(32))]
|
||||
#[align(32)]
|
||||
extern "C" fn weak_aligned_nop() {
|
||||
naked_asm!("nop")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// CHECK: align 16
|
||||
#[no_mangle]
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
pub fn fn_align() {}
|
||||
|
||||
pub struct A;
|
||||
|
|
@ -13,12 +13,12 @@ pub struct A;
|
|||
impl A {
|
||||
// CHECK: align 16
|
||||
#[no_mangle]
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
pub fn method_align(self) {}
|
||||
|
||||
// CHECK: align 16
|
||||
#[no_mangle]
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
pub fn associated_fn() {}
|
||||
}
|
||||
|
||||
|
|
@ -26,19 +26,19 @@ trait T: Sized {
|
|||
fn trait_fn() {}
|
||||
|
||||
// CHECK: align 32
|
||||
#[repr(align(32))]
|
||||
#[align(32)]
|
||||
fn trait_method(self) {}
|
||||
}
|
||||
|
||||
impl T for A {
|
||||
// CHECK: align 16
|
||||
#[no_mangle]
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
fn trait_fn() {}
|
||||
|
||||
// CHECK: align 16
|
||||
#[no_mangle]
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
fn trait_method(self) {}
|
||||
}
|
||||
|
||||
|
|
@ -51,18 +51,20 @@ pub fn foo() {
|
|||
// CHECK-LABEL: align_specified_twice_1
|
||||
// CHECK-SAME: align 64
|
||||
#[no_mangle]
|
||||
#[repr(align(32), align(64))]
|
||||
#[align(32)]
|
||||
#[align(64)]
|
||||
pub fn align_specified_twice_1() {}
|
||||
|
||||
// CHECK-LABEL: align_specified_twice_2
|
||||
// CHECK-SAME: align 128
|
||||
#[no_mangle]
|
||||
#[repr(align(128), align(32))]
|
||||
#[align(128)]
|
||||
#[align(32)]
|
||||
pub fn align_specified_twice_2() {}
|
||||
|
||||
// CHECK-LABEL: align_specified_twice_3
|
||||
// CHECK-SAME: align 256
|
||||
#[no_mangle]
|
||||
#[repr(align(32))]
|
||||
#[repr(align(256))]
|
||||
#[align(32)]
|
||||
#[align(256)]
|
||||
pub fn align_specified_twice_3() {}
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@ pub fn no_explicit_align() {}
|
|||
// align16: align 16
|
||||
// align1024: align 1024
|
||||
#[no_mangle]
|
||||
#[repr(align(8))]
|
||||
#[align(8)]
|
||||
pub fn lower_align() {}
|
||||
|
||||
// the higher value of min-function-alignment and repr(align) wins out
|
||||
// the higher value of min-function-alignment and the align attribute wins out
|
||||
//
|
||||
// CHECK-LABEL: @higher_align
|
||||
// align16: align 32
|
||||
// align1024: align 1024
|
||||
#[no_mangle]
|
||||
#[repr(align(32))]
|
||||
#[align(32)]
|
||||
pub fn higher_align() {}
|
||||
|
||||
// cold functions follow the same rules as other functions
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use std::arch::naked_asm;
|
|||
|
||||
// CHECK: .balign 16
|
||||
// CHECK-LABEL: naked_empty:
|
||||
#[repr(align(16))]
|
||||
#[align(16)]
|
||||
#[no_mangle]
|
||||
#[unsafe(naked)]
|
||||
pub extern "C" fn naked_empty() {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub extern "C" fn naked_no_explicit_align() {
|
|||
|
||||
// CHECK: .balign 16
|
||||
#[no_mangle]
|
||||
#[repr(align(8))]
|
||||
#[align(8)]
|
||||
#[unsafe(naked)]
|
||||
pub extern "C" fn naked_lower_align() {
|
||||
core::arch::naked_asm!("ret")
|
||||
|
|
@ -24,7 +24,7 @@ pub extern "C" fn naked_lower_align() {
|
|||
|
||||
// CHECK: .balign 32
|
||||
#[no_mangle]
|
||||
#[repr(align(32))]
|
||||
#[align(32)]
|
||||
#[unsafe(naked)]
|
||||
pub extern "C" fn naked_higher_align() {
|
||||
core::arch::naked_asm!("ret")
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
//@ known-bug: #136678
|
||||
#![feature(inherent_associated_types)]
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct B<const A: usize>;
|
||||
|
||||
struct Test<const A: usize>;
|
||||
|
||||
impl<const A: usize> Test<A> {
|
||||
type B = B<{ A }>;
|
||||
|
||||
fn test(a: Self::B) -> Self::B {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
//@ known-bug: #138131
|
||||
#![feature(min_generic_const_args)]
|
||||
#![feature(inherent_associated_types)]
|
||||
struct Foo<'a> {
|
||||
x: &'a (),
|
||||
}
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn foo(_: [u8; Foo::X]) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -11,28 +11,29 @@
|
|||
let _9: ();
|
||||
let _10: ();
|
||||
let mut _11: std::fmt::Arguments<'_>;
|
||||
let mut _12: &[&str; 3];
|
||||
let _13: &[&str; 3];
|
||||
let _14: [&str; 3];
|
||||
let mut _15: &[core::fmt::rt::Argument<'_>; 2];
|
||||
let _16: &[core::fmt::rt::Argument<'_>; 2];
|
||||
let _17: [core::fmt::rt::Argument<'_>; 2];
|
||||
let mut _13: &std::boxed::Box<dyn std::fmt::Display>;
|
||||
let mut _14: &u32;
|
||||
let mut _16: core::fmt::rt::Argument<'_>;
|
||||
let mut _17: &std::boxed::Box<dyn std::fmt::Display>;
|
||||
let mut _18: core::fmt::rt::Argument<'_>;
|
||||
let mut _19: &std::boxed::Box<dyn std::fmt::Display>;
|
||||
let _20: &std::boxed::Box<dyn std::fmt::Display>;
|
||||
let mut _21: core::fmt::rt::Argument<'_>;
|
||||
let mut _22: &u32;
|
||||
let _23: &u32;
|
||||
let mut _25: bool;
|
||||
let mut _26: isize;
|
||||
let mut _27: isize;
|
||||
let mut _28: isize;
|
||||
+ let _29: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
|
||||
+ let _30: u32;
|
||||
let mut _19: &u32;
|
||||
let mut _20: &[&str; 3];
|
||||
let _21: &[&str; 3];
|
||||
let _22: [&str; 3];
|
||||
let mut _23: &[core::fmt::rt::Argument<'_>; 2];
|
||||
let _24: &[core::fmt::rt::Argument<'_>; 2];
|
||||
let mut _26: &std::boxed::Box<dyn std::fmt::Display>;
|
||||
let mut _27: &u32;
|
||||
let mut _28: bool;
|
||||
let mut _29: isize;
|
||||
let mut _30: isize;
|
||||
let mut _31: isize;
|
||||
+ let _32: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
|
||||
+ let _33: u32;
|
||||
scope 1 {
|
||||
- debug foo => _1;
|
||||
+ debug ((foo: Foo<T>).0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>) => _29;
|
||||
+ debug ((foo: Foo<T>).1: u32) => _30;
|
||||
+ debug ((foo: Foo<T>).0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>) => _32;
|
||||
+ debug ((foo: Foo<T>).1: u32) => _33;
|
||||
let _5: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>;
|
||||
scope 2 {
|
||||
debug x => _5;
|
||||
|
|
@ -42,17 +43,29 @@
|
|||
scope 4 {
|
||||
debug x => _8;
|
||||
let _8: std::boxed::Box<dyn std::fmt::Display>;
|
||||
let mut _24: &[&str; 3];
|
||||
let _12: (&std::boxed::Box<dyn std::fmt::Display>, &u32);
|
||||
+ let _34: &std::boxed::Box<dyn std::fmt::Display>;
|
||||
+ let _35: &u32;
|
||||
scope 5 {
|
||||
- debug args => _12;
|
||||
+ debug ((args: (&Box<dyn std::fmt::Display>, &u32)).0: &std::boxed::Box<dyn std::fmt::Display>) => _34;
|
||||
+ debug ((args: (&Box<dyn std::fmt::Display>, &u32)).1: &u32) => _35;
|
||||
let _15: [core::fmt::rt::Argument<'_>; 2];
|
||||
scope 6 {
|
||||
debug args => _15;
|
||||
let mut _25: &[&str; 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_25 = const false;
|
||||
_28 = const false;
|
||||
- StorageLive(_1);
|
||||
+ StorageLive(_29);
|
||||
+ StorageLive(_30);
|
||||
+ StorageLive(_32);
|
||||
+ StorageLive(_33);
|
||||
+ nop;
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
|
|
@ -66,77 +79,93 @@
|
|||
_2 = Result::<Box<dyn std::fmt::Display>, <T as Err>::Err>::Ok(move _3);
|
||||
StorageDead(_3);
|
||||
- _1 = Foo::<T> { x: move _2, y: const 7_u32 };
|
||||
+ _29 = move _2;
|
||||
+ _30 = const 7_u32;
|
||||
+ _32 = move _2;
|
||||
+ _33 = const 7_u32;
|
||||
+ nop;
|
||||
StorageDead(_2);
|
||||
StorageLive(_5);
|
||||
_25 = const true;
|
||||
_28 = const true;
|
||||
- _5 = move (_1.0: std::result::Result<std::boxed::Box<dyn std::fmt::Display>, <T as Err>::Err>);
|
||||
+ _5 = move _29;
|
||||
+ _5 = move _32;
|
||||
StorageLive(_6);
|
||||
- _6 = copy (_1.1: u32);
|
||||
+ _6 = copy _30;
|
||||
+ _6 = copy _33;
|
||||
_7 = discriminant(_5);
|
||||
switchInt(move _7) -> [0: bb2, otherwise: bb7];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_8);
|
||||
_25 = const false;
|
||||
_28 = const false;
|
||||
_8 = move ((_5 as Ok).0: std::boxed::Box<dyn std::fmt::Display>);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
- StorageLive(_12);
|
||||
+ StorageLive(_34);
|
||||
+ StorageLive(_35);
|
||||
+ nop;
|
||||
StorageLive(_13);
|
||||
_24 = const foo::<T>::promoted[0];
|
||||
_13 = &(*_24);
|
||||
_12 = &(*_13);
|
||||
_13 = &_8;
|
||||
StorageLive(_14);
|
||||
_14 = &_6;
|
||||
- _12 = (move _13, move _14);
|
||||
+ _34 = move _13;
|
||||
+ _35 = move _14;
|
||||
+ nop;
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
StorageLive(_17);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
_20 = &_8;
|
||||
_19 = &(*_20);
|
||||
_18 = core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _19) -> [return: bb3, unwind unreachable];
|
||||
- _26 = deref_copy (_12.0: &std::boxed::Box<dyn std::fmt::Display>);
|
||||
+ _26 = deref_copy _34;
|
||||
_17 = &(*_26);
|
||||
_16 = core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _17) -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_19);
|
||||
StorageLive(_21);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
_23 = &_6;
|
||||
_22 = &(*_23);
|
||||
_21 = core::fmt::rt::Argument::<'_>::new_display::<u32>(move _22) -> [return: bb4, unwind unreachable];
|
||||
StorageDead(_17);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
- _27 = deref_copy (_12.1: &u32);
|
||||
+ _27 = deref_copy _35;
|
||||
_19 = &(*_27);
|
||||
_18 = core::fmt::rt::Argument::<'_>::new_display::<u32>(move _19) -> [return: bb4, unwind unreachable];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_22);
|
||||
_17 = [move _18, move _21];
|
||||
StorageDead(_21);
|
||||
StorageDead(_19);
|
||||
_15 = [move _16, move _18];
|
||||
StorageDead(_18);
|
||||
_16 = &_17;
|
||||
_15 = &(*_16);
|
||||
_11 = core::fmt::rt::<impl Arguments<'_>>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable];
|
||||
StorageDead(_16);
|
||||
StorageLive(_20);
|
||||
StorageLive(_21);
|
||||
_25 = const foo::<T>::promoted[0];
|
||||
_21 = &(*_25);
|
||||
_20 = &(*_21);
|
||||
StorageLive(_23);
|
||||
StorageLive(_24);
|
||||
_24 = &_15;
|
||||
_23 = &(*_24);
|
||||
_11 = core::fmt::rt::<impl Arguments<'_>>::new_v1::<3, 2>(move _20, move _23) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_12);
|
||||
StorageDead(_24);
|
||||
StorageDead(_23);
|
||||
StorageDead(_21);
|
||||
StorageDead(_20);
|
||||
_10 = _eprint(move _11) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_23);
|
||||
StorageDead(_20);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
StorageDead(_13);
|
||||
StorageDead(_15);
|
||||
- StorageDead(_12);
|
||||
+ StorageDead(_34);
|
||||
+ StorageDead(_35);
|
||||
+ nop;
|
||||
StorageDead(_10);
|
||||
_9 = const ();
|
||||
StorageDead(_9);
|
||||
|
|
@ -156,22 +185,22 @@
|
|||
|
||||
bb9: {
|
||||
StorageDead(_6);
|
||||
_26 = discriminant(_5);
|
||||
switchInt(move _26) -> [0: bb11, otherwise: bb13];
|
||||
_29 = discriminant(_5);
|
||||
switchInt(move _29) -> [0: bb11, otherwise: bb13];
|
||||
}
|
||||
|
||||
bb10: {
|
||||
_25 = const false;
|
||||
_28 = const false;
|
||||
StorageDead(_5);
|
||||
- StorageDead(_1);
|
||||
+ StorageDead(_29);
|
||||
+ StorageDead(_30);
|
||||
+ StorageDead(_32);
|
||||
+ StorageDead(_33);
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
|
||||
bb11: {
|
||||
switchInt(copy _25) -> [0: bb10, otherwise: bb12];
|
||||
switchInt(copy _28) -> [0: bb10, otherwise: bb12];
|
||||
}
|
||||
|
||||
bb12: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
// Test that `-Awarnings` suppresses warnings for unstable APIs.
|
||||
|
||||
use run_make_support::rustc;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ fn main() {
|
|||
|
||||
// Remove env vars to get `rustc`'s default
|
||||
let output = rustc()
|
||||
.target(target())
|
||||
.env_remove("MACOSX_DEPLOYMENT_TARGET")
|
||||
.env_remove("IPHONEOS_DEPLOYMENT_TARGET")
|
||||
.env_remove("WATCHOS_DEPLOYMENT_TARGET")
|
||||
|
|
@ -58,7 +57,6 @@ fn main() {
|
|||
run_in_tmpdir(|| {
|
||||
let rustc = || {
|
||||
let mut rustc = rustc();
|
||||
rustc.target(target());
|
||||
rustc.crate_type("lib");
|
||||
rustc.emit("obj");
|
||||
rustc.input("foo.rs");
|
||||
|
|
@ -82,7 +80,6 @@ fn main() {
|
|||
|
||||
let rustc = || {
|
||||
let mut rustc = rustc();
|
||||
rustc.target(target());
|
||||
rustc.crate_type("dylib");
|
||||
rustc.input("foo.rs");
|
||||
rustc.output("libfoo.dylib");
|
||||
|
|
@ -108,7 +105,6 @@ fn main() {
|
|||
run_in_tmpdir(|| {
|
||||
let rustc = || {
|
||||
let mut rustc = rustc();
|
||||
rustc.target(target());
|
||||
rustc.crate_type("bin");
|
||||
rustc.input("foo.rs");
|
||||
rustc.output("foo");
|
||||
|
|
@ -147,7 +143,6 @@ fn main() {
|
|||
run_in_tmpdir(|| {
|
||||
let rustc = || {
|
||||
let mut rustc = rustc();
|
||||
rustc.target(target());
|
||||
rustc.incremental("incremental");
|
||||
rustc.crate_type("lib");
|
||||
rustc.emit("obj");
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ fn has_sdk_version(file: &str, version: &str) {
|
|||
|
||||
fn main() {
|
||||
// Fetch rustc's inferred deployment target.
|
||||
let current_deployment_target =
|
||||
rustc().target(target()).print("deployment-target").run().stdout_utf8();
|
||||
let current_deployment_target = rustc().print("deployment-target").run().stdout_utf8();
|
||||
let current_deployment_target = current_deployment_target.split('=').last().unwrap().trim();
|
||||
|
||||
// Fetch current SDK version via. xcrun.
|
||||
|
|
@ -45,7 +44,7 @@ fn main() {
|
|||
let current_sdk_version = current_sdk_version.trim();
|
||||
|
||||
// Check the SDK version in the object file produced by the codegen backend.
|
||||
rustc().target(target()).crate_type("lib").emit("obj").input("foo.rs").output("foo.o").run();
|
||||
rustc().crate_type("lib").emit("obj").input("foo.rs").output("foo.o").run();
|
||||
// Set to 0, which means not set or "n/a".
|
||||
has_sdk_version("foo.o", "n/a");
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ fn main() {
|
|||
//
|
||||
// This is just to ensure that we don't set some odd version in `create_object_file`,
|
||||
// if the rmeta file is packed in a different way in the future, this can safely be removed.
|
||||
rustc().target(target()).crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
|
||||
rustc().crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
|
||||
// Extra .rmeta file (which is encoded as an object file).
|
||||
cmd("ar").arg("-x").arg("libfoo.rlib").arg("lib.rmeta").run();
|
||||
has_sdk_version("lib.rmeta", "n/a");
|
||||
|
|
@ -69,7 +68,6 @@ fn main() {
|
|||
// Test with clang
|
||||
let file_name = format!("foo_cc{file_ext}");
|
||||
rustc()
|
||||
.target(target())
|
||||
.crate_type("bin")
|
||||
.arg("-Clinker-flavor=gcc")
|
||||
.input("foo.rs")
|
||||
|
|
@ -80,7 +78,6 @@ fn main() {
|
|||
// Test with ld64
|
||||
let file_name = format!("foo_ld{file_ext}");
|
||||
rustc()
|
||||
.target(target())
|
||||
.crate_type("bin")
|
||||
.arg("-Clinker-flavor=ld")
|
||||
.input("foo.rs")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// Test that previously triggered a linker failure with root cause
|
||||
// similar to one found in the issue #69368.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile (needs to run doctests)
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use run_make_support::{cwd, diff, rustc, rustdoc};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile (needs to run host tool binary)
|
||||
|
||||
// Tests behavior of rustdoc `--test-runtool`.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-crate-type: dylib
|
||||
|
||||
// Tests the -Zembed-metadata compiler flag.
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/139165
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-windows
|
||||
//@ ignore-apple
|
||||
//@ ignore-wasm (`object` doesn't handle wasm object files)
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// This test should be replaced with one in tests/debuginfo once we can easily
|
||||
// tell via GDB or LLDB if debuginfo contains source code. Cheap tricks in LLDB
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
// `all-shared` should only emit files that can be shared between crates.
|
||||
// See https://github.com/rust-lang/rust/pull/83478
|
||||
|
||||
//@ needs-target-std
|
||||
|
||||
use run_make_support::{has_extension, has_prefix, path, rustdoc, shallow_find_files};
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
// See https://github.com/rust-lang/rust/pull/51946
|
||||
|
||||
//@ needs-target-std
|
||||
//@ ignore-windows
|
||||
//@ ignore-apple
|
||||
//@ only-elf
|
||||
// Reason: this feature only works when the output object format is ELF.
|
||||
// This won't be the case on Windows/OSX - for example, OSX produces a Mach-O binary.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-crate-type: proc-macro
|
||||
//@ ignore-musl (FIXME: can't find `-lunwind`)
|
||||
|
||||
// Inside dep-info emit files, #71858 made it so all accessed environment
|
||||
// variables are usefully printed. This test checks that this feature works
|
||||
// as intended by checking if the environment variables used in compilation
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// Test that we exit with the correct exit code for successful / unsuccessful / ICE compilations
|
||||
|
||||
use run_make_support::{rustc, rustdoc};
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@
|
|||
// Reason: the export-executable-symbols flag only works on Unix
|
||||
// due to hardcoded platform-specific implementation
|
||||
// (See #85673)
|
||||
//@ ignore-wasm32
|
||||
//@ ignore-wasm64
|
||||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
//@ ignore-wasm
|
||||
|
||||
use run_make_support::{bin_name, llvm_readobj, rustc};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// NOTE: `sdylib`'s platform support is basically just `dylib`'s platform support.
|
||||
//@ needs-crate-type: dylib
|
||||
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// NOTE: `sdylib`'s platform support is basically that of `dylib`.
|
||||
//@ needs-crate-type: dylib
|
||||
|
||||
use run_make_support::{dynamic_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// NOTE: `sdylib`'s platform support is basically that of `dylib`.
|
||||
//@ needs-crate-type: dylib
|
||||
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// In the following scenario:
|
||||
// 1. The crate foo, is referenced multiple times
|
||||
// 2. --extern foo=./path/to/libbar.rlib is specified to rustc
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
//
|
||||
// The --extern flag can override the default crate search of
|
||||
// the compiler and directly fetch a given path. There are a few rules
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// In this test, the rust library foo1 exists in two different locations, but only one
|
||||
// is required by the --extern flag. This test checks that the copy is ignored (as --extern
|
||||
// demands fetching only the original instance of foo1) and that no error is emitted, resulting
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// Almost identical to `extern-multiple-copies`, but with a variation in the --extern calls
|
||||
// and the addition of #[macro_use] in the rust code files, which used to break --extern
|
||||
// until #33625.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
//@ only-x86_64
|
||||
//@ only-linux
|
||||
//@ ignore-cross-compile
|
||||
// Reason: This is a platform-independent issue, no need to waste time testing
|
||||
// everywhere.
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
// See https://github.com/rust-lang/rust/pull/95604
|
||||
// See https://github.com/rust-lang/rust/issues/47384
|
||||
|
||||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-crate-type: cdylib
|
||||
//@ needs-dynamic-linking
|
||||
//@ ignore-wasm differences in object file formats causes errors in the llvm_objdump step.
|
||||
//@ ignore-windows differences in object file formats causes errors in the llvm_objdump step.
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
// was hashed by rustc in addition to the span length, and the fix still
|
||||
// works.
|
||||
|
||||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// for successful compilation.
|
||||
// See https://github.com/rust-lang/rust/issues/83112
|
||||
|
||||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
// which means the emitted artifacts should be shorter in length.
|
||||
// See https://github.com/rust-lang/rust/pull/16970
|
||||
|
||||
//@ needs-target-std
|
||||
//@ needs-asm-support
|
||||
//@ ignore-windows
|
||||
// Reason: Because of Windows exception handling, the code is not necessarily any shorter.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ needs-crate-type: dylib
|
||||
//@ needs-dynamic-linking
|
||||
|
||||
// When a fake library was given to the compiler, it would
|
||||
// result in an obscure and unhelpful error message. This test
|
||||
// creates a false "foo" dylib, and checks that the standard error
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// Non-regression test for issues #125474, #125484, #125646, with the repro taken from #125484. Some
|
||||
// queries use "used dependencies" while others use "speculatively loaded dependencies", and an
|
||||
// indexing ICE appeared in some cases when these were unexpectedly used in the same context.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// The byte positions in json format error logging used to have a small, difficult
|
||||
// to predict offset. This was changed to be the top of the file every time in #42973,
|
||||
// and this test checks that the measurements appearing in the standard error are correct.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-wasm (explicit linker invocations)
|
||||
|
||||
// Passing linker arguments to the compiler used to be lost or reordered in a messy way
|
||||
// as they were passed further to the linker. This was fixed in #70665, and this test
|
||||
// checks that linker arguments remain intact and in the order they were originally passed in.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-musl (not passed consecutively)
|
||||
// When native libraries are passed to the linker, there used to be an annoyance
|
||||
// where multiple instances of the same library in a row would cause duplication in
|
||||
// outputs. This has been fixed, and this test checks that it stays fixed.
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
use std::fmt::Write;
|
||||
|
||||
use run_make_support::{is_msvc, rustc};
|
||||
use run_make_support::{is_msvc, rustc, target};
|
||||
|
||||
fn main() {
|
||||
rustc().input("depa.rs").run();
|
||||
|
|
@ -33,9 +33,11 @@ fn needle_from_libs(libs: &[&str]) -> String {
|
|||
let mut needle = String::new();
|
||||
for lib in libs {
|
||||
if is_msvc() {
|
||||
let _ = needle.write_fmt(format_args!(r#""{lib}.lib" "#));
|
||||
needle.write_fmt(format_args!(r#""{lib}.lib" "#)).unwrap();
|
||||
} else if target().contains("wasm") {
|
||||
needle.write_fmt(format_args!(r#""-l" "{lib}" "#)).unwrap();
|
||||
} else {
|
||||
let _ = needle.write_fmt(format_args!(r#""-l{lib}" "#));
|
||||
needle.write_fmt(format_args!(r#""-l{lib}" "#)).unwrap();
|
||||
}
|
||||
}
|
||||
needle.pop(); // remove trailing space
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//@ ignore-cross-compile (need to run fake linker)
|
||||
|
||||
use run_make_support::{Rustc, diff, regex, rustc};
|
||||
|
||||
fn run_rustc() -> Rustc {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
// sessions.
|
||||
// See https://github.com/rust-lang/rust/issues/85019
|
||||
|
||||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{rfs, rust_lib_name, rustc};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,7 @@ fn run_test(variant: &str) {
|
|||
flags
|
||||
};
|
||||
println!("{variant} test...");
|
||||
rustc()
|
||||
.input(format!("foo_{variant}.rs"))
|
||||
.target(target())
|
||||
.linker("aarch64-linux-gnu-gcc")
|
||||
.run();
|
||||
rustc().input(format!("foo_{variant}.rs")).linker("aarch64-linux-gnu-gcc").run();
|
||||
gcc()
|
||||
.input(format!("bar_{variant}.c"))
|
||||
.input(dynamic_lib_name("foo"))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
//@ ignore-windows
|
||||
//@ only-x86_64
|
||||
//@ needs-target-std
|
||||
//@ needs-crate-type: dylib
|
||||
|
||||
use run_make_support::object::ObjectSymbol;
|
||||
use run_make_support::object::read::{File, Object, Symbol};
|
||||
use run_make_support::targets::is_windows;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// On MSVC the alternative naming format for static libraries (`libfoo.a`) is accepted in addition
|
||||
// to the default format (`foo.lib`).
|
||||
|
||||
//REMOVE@ only-msvc
|
||||
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
// This test is the same as native-link-modifier-rustc, but without rlibs.
|
||||
// See https://github.com/rust-lang/rust/issues/99425
|
||||
|
||||
//@ needs-target-std
|
||||
//@ ignore-cross-compile
|
||||
//@ ignore-apple
|
||||
//@ ignore-wasm
|
||||
// Reason: linking fails due to the unusual ".ext" staticlib name.
|
||||
|
||||
use run_make_support::rustc;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
CHECK: declare void @foo()
|
||||
CHECK: declare{{.*}} void @foo()
|
||||
CHECK-SAME: #[[ATTR_3:[0-9]+]]
|
||||
|
||||
CHECK: attributes #[[ATTR_3]]
|
||||
CHECK: attributes #[[ATTR_3]]
|
||||
CHECK-SAME: no-builtins
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
// `no_builtins` is an attribute related to LLVM's optimizations. In order to ensure that it has an
|
||||
// effect on link-time optimizations (LTO), it should be added to function declarations in a crate.
|
||||
// This test uses the `llvm-filecheck` tool to determine that this attribute is successfully
|
||||
|
|
@ -11,5 +10,6 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
|||
fn main() {
|
||||
rustc().input("no_builtins.rs").emit("link").run();
|
||||
rustc().input("main.rs").emit("llvm-ir").run();
|
||||
|
||||
llvm_filecheck().patterns("filecheck.main.txt").stdin_buf(rfs::read("main.ll")).run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ needs-target-std
|
||||
//
|
||||
//@ ignore-cross-compile
|
||||
|
||||
// The rlib produced by a no_builtins crate should be explicitly linked
|
||||
// during compilation, and as a result be present in the linker arguments.
|
||||
// See the comments inside this file for more details.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue