commit
5e944bb19c
1
.gitignore
vendored
1
.gitignore
vendored
@ -48,6 +48,7 @@ build/
|
||||
/dist/
|
||||
/unicode-downloads
|
||||
/target
|
||||
/library/target
|
||||
/src/bootstrap/target
|
||||
/src/tools/x/target
|
||||
# Created by default with `src/ci/docker/run.sh`
|
||||
|
319
Cargo.lock
319
Cargo.lock
@ -11,27 +11,11 @@ dependencies = [
|
||||
"gimli 0.28.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli 0.29.0",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
@ -66,16 +50,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
@ -256,7 +230,7 @@ version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line 0.21.0",
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@ -455,10 +429,6 @@ name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
@ -737,16 +707,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compiletest"
|
||||
version = "0.0.0"
|
||||
@ -787,14 +747,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
@ -1134,19 +1086,6 @@ version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
|
||||
|
||||
[[package]]
|
||||
name = "dlmalloc"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3264b043b8e977326c1ee9e723da2c1f8d09a99df52cacf00b4dbce5ac54414d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-core",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.12.0"
|
||||
@ -1348,16 +1287,6 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs-err"
|
||||
version = "2.11.0"
|
||||
@ -1504,8 +1433,6 @@ version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
"rustc-std-workspace-std",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
@ -1526,25 +1453,11 @@ version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"fallible-iterator",
|
||||
"indexmap",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.0"
|
||||
@ -1606,9 +1519,6 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -1630,17 +1540,6 @@ version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
@ -2065,9 +1964,6 @@ name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libdbus-sys"
|
||||
@ -2299,10 +2195,6 @@ name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
@ -2357,9 +2249,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2540,7 +2429,7 @@ version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.9",
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@ -2579,14 +2468,11 @@ version = "0.36.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"hashbrown",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
"ruzstd 0.7.0",
|
||||
"wasmparser 0.214.0",
|
||||
]
|
||||
@ -2710,29 +2596,6 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic_abort"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic_unwind"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
"unwind",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "papergrid"
|
||||
version = "0.11.0"
|
||||
@ -2987,23 +2850,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc_macro"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiler_builtins"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psm"
|
||||
version = "0.1.21"
|
||||
@ -3081,27 +2927,6 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "4.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e935efc5854715dfc0a4c9ef18dc69dee0ec3bf9cc3ab740db831c0fdd86a3"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi-alloc"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"r-efi",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -3132,15 +2957,6 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xoshiro"
|
||||
version = "0.6.0"
|
||||
@ -3282,20 +3098,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rinja"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2d47a46d7729e891c8accf260e9daa02ae6d570aa2a94fb1fb27eb5364a2323"
|
||||
checksum = "6d3762e3740cdbf2fd2be465cc2c26d643ad17353cc2e0223d211c1b096118bd"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"rinja_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_derive"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44dae9afe59d58ed8d988d67d1945f3638125d2fd2104058399382e11bd3ea2a"
|
||||
checksum = "fd01fd8e15e7d19c8b8052c1d428325131e02ff1633cdcf695190c2e56ab682c"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"memchr",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"once_map",
|
||||
@ -3308,10 +3126,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rinja_parser"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1771c78cd5d3b1646ef8d8f2ed100db936e8b291d3cc06e92a339ff346858c"
|
||||
checksum = "a2f6bf7cef118c6de21206edf0b3f19f5ede60006be674a58ca21b6e003a1b57"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"nom",
|
||||
]
|
||||
|
||||
@ -3352,10 +3171,6 @@ name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
@ -3416,27 +3231,6 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5c9f15eec8235d7cb775ee6f81891db79b98fd54ba1ad8fae565b88ef1ae4e2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-alloc"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-core"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-std"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_abi"
|
||||
version = "0.0.0"
|
||||
@ -5223,46 +5017,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "std"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"addr2line 0.22.0",
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"dlmalloc",
|
||||
"fortanix-sgx-abi",
|
||||
"hashbrown",
|
||||
"hermit-abi 0.4.0",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object 0.36.2",
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
"r-efi",
|
||||
"r-efi-alloc",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"rustc-demangle",
|
||||
"std_detect",
|
||||
"unwind",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "std_detect"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.7"
|
||||
@ -5366,15 +5120,6 @@ dependencies = [
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysroot"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc_macro",
|
||||
"std",
|
||||
"test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tabled"
|
||||
version = "0.15.0"
|
||||
@ -5459,16 +5204,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"getopts",
|
||||
"libc",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test-float-parse"
|
||||
version = "0.1.0"
|
||||
@ -5967,11 +5702,6 @@ name = "unicode-width"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
"rustc-std-workspace-std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
@ -5996,28 +5726,6 @@ dependencies = [
|
||||
"tidy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unwind"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
"unwinding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unwinding"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37a19a21a537f635c16c7576f22d0f2f7d63353c1337ad4ce0d8001c7952a25b"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli 0.28.1",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.2"
|
||||
@ -6089,11 +5797,6 @@ name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
|
37
Cargo.toml
37
Cargo.toml
@ -2,8 +2,6 @@
|
||||
resolver = "1"
|
||||
members = [
|
||||
"compiler/rustc",
|
||||
"library/std",
|
||||
"library/sysroot",
|
||||
"src/etc/test-float-parse",
|
||||
"src/rustdoc-json-types",
|
||||
"src/tools/build_helper",
|
||||
@ -61,23 +59,8 @@ exclude = [
|
||||
# not all `Cargo.toml` files are available, so we exclude the `x` binary,
|
||||
# so it can be invoked before the current checkout is set up.
|
||||
"src/tools/x",
|
||||
# stdarch has its own Cargo workspace
|
||||
"library/stdarch",
|
||||
]
|
||||
|
||||
[profile.release.package.compiler_builtins]
|
||||
# For compiler-builtins we always use a high number of codegen units.
|
||||
# The goal here is to place every single intrinsic into its own object
|
||||
# file to avoid symbol clashes with the system libgcc if possible. Note
|
||||
# that this number doesn't actually produce this many object files, we
|
||||
# just don't create more than this number of object files.
|
||||
#
|
||||
# It's a bit of a bummer that we have to pass this here, unfortunately.
|
||||
# Ideally this would be specified through an env var to Cargo so Cargo
|
||||
# knows how many CGUs are for this specific crate, but for now
|
||||
# per-crate configuration isn't specifiable in the environment.
|
||||
codegen-units = 10000
|
||||
|
||||
[profile.release.package.rustc-rayon-core]
|
||||
# The rustc fork of Rayon has deadlock detection code which intermittently
|
||||
# causes overflows in the CI (see https://github.com/rust-lang/rust/issues/90227)
|
||||
@ -85,19 +68,6 @@ codegen-units = 10000
|
||||
# FIXME: This workaround should be removed once #90227 is fixed.
|
||||
overflow-checks = false
|
||||
|
||||
# These dependencies of the standard library implement symbolication for
|
||||
# backtraces on most platforms. Their debuginfo causes both linking to be slower
|
||||
# (more data to chew through) and binaries to be larger without really all that
|
||||
# much benefit. This section turns them all to down to have no debuginfo which
|
||||
# helps to improve link times a little bit.
|
||||
[profile.release.package]
|
||||
addr2line.debug = 0
|
||||
adler.debug = 0
|
||||
gimli.debug = 0
|
||||
miniz_oxide.debug = 0
|
||||
object.debug = 0
|
||||
rustc-demangle.debug = 0
|
||||
|
||||
# These are very thin wrappers around executing lld with the right binary name.
|
||||
# Basically nothing within them can go wrong without having been explicitly logged anyway.
|
||||
# We ship these in every rustc tarball and even after compression they add up
|
||||
@ -120,10 +90,3 @@ codegen-units = 1
|
||||
# FIXME: LTO cannot be enabled for binaries in a workspace
|
||||
# <https://github.com/rust-lang/cargo/issues/9330>
|
||||
# lto = true
|
||||
|
||||
[patch.crates-io]
|
||||
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on
|
||||
# here
|
||||
rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
|
||||
rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' }
|
||||
rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }
|
||||
|
@ -196,6 +196,9 @@ builtin_macros_format_use_positional = consider using a positional formatting ar
|
||||
|
||||
builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
|
||||
|
||||
builtin_macros_global_asm_unsupported_operand = the `{$symbol}` operand cannot be used with `global_asm!`
|
||||
.label = the `{$symbol}` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
builtin_macros_global_asm_unsupported_option = the `{$symbol}` option cannot be used with `global_asm!`
|
||||
.label = the `{$symbol}` option is not meaningful for global-scoped inline assembly
|
||||
.suggestion = remove this option
|
||||
|
@ -28,6 +28,29 @@ pub struct AsmArgs {
|
||||
pub options_spans: Vec<Span>,
|
||||
}
|
||||
|
||||
/// Used for better error messages when operand types are used that are not
|
||||
/// supported by the current macro (e.g. `in` or `out` for `global_asm!`)
|
||||
///
|
||||
/// returns
|
||||
///
|
||||
/// - `Ok(true)` if the current token matches the keyword, and was expected
|
||||
/// - `Ok(false)` if the current token does not match the keyword
|
||||
/// - `Err(_)` if the current token matches the keyword, but was not expected
|
||||
fn eat_operand_keyword<'a>(p: &mut Parser<'a>, symbol: Symbol, expect: bool) -> PResult<'a, bool> {
|
||||
if expect {
|
||||
Ok(p.eat_keyword(symbol))
|
||||
} else {
|
||||
let span = p.token.span;
|
||||
if p.eat_keyword_noexpect(symbol) {
|
||||
// in gets printed as `r#in` otherwise
|
||||
let symbol = if symbol == kw::In { "in" } else { symbol.as_str() };
|
||||
Err(p.dcx().create_err(errors::GlobalAsmUnsupportedOperand { span, symbol }))
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_args<'a>(
|
||||
ecx: &ExtCtxt<'a>,
|
||||
sp: Span,
|
||||
@ -105,7 +128,7 @@ pub fn parse_asm_args<'a>(
|
||||
};
|
||||
|
||||
let mut explicit_reg = false;
|
||||
let op = if !is_global_asm && p.eat_keyword(kw::In) {
|
||||
let op = if eat_operand_keyword(p, kw::In, !is_global_asm)? {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
@ -113,15 +136,15 @@ pub fn parse_asm_args<'a>(
|
||||
}
|
||||
let expr = p.parse_expr()?;
|
||||
ast::InlineAsmOperand::In { reg, expr }
|
||||
} else if !is_global_asm && p.eat_keyword(sym::out) {
|
||||
} else if eat_operand_keyword(p, sym::out, !is_global_asm)? {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
|
||||
ast::InlineAsmOperand::Out { reg, expr, late: false }
|
||||
} else if !is_global_asm && p.eat_keyword(sym::lateout) {
|
||||
} else if eat_operand_keyword(p, sym::lateout, !is_global_asm)? {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
|
||||
ast::InlineAsmOperand::Out { reg, expr, late: true }
|
||||
} else if !is_global_asm && p.eat_keyword(sym::inout) {
|
||||
} else if eat_operand_keyword(p, sym::inout, !is_global_asm)? {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
@ -135,7 +158,7 @@ pub fn parse_asm_args<'a>(
|
||||
} else {
|
||||
ast::InlineAsmOperand::InOut { reg, expr, late: false }
|
||||
}
|
||||
} else if !is_global_asm && p.eat_keyword(sym::inlateout) {
|
||||
} else if eat_operand_keyword(p, sym::inlateout, !is_global_asm)? {
|
||||
let reg = parse_reg(p, &mut explicit_reg)?;
|
||||
if p.eat_keyword(kw::Underscore) {
|
||||
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
|
||||
@ -149,6 +172,9 @@ pub fn parse_asm_args<'a>(
|
||||
} else {
|
||||
ast::InlineAsmOperand::InOut { reg, expr, late: true }
|
||||
}
|
||||
} else if eat_operand_keyword(p, sym::label, !is_global_asm)? {
|
||||
let block = p.parse_block()?;
|
||||
ast::InlineAsmOperand::Label { block }
|
||||
} else if p.eat_keyword(kw::Const) {
|
||||
let anon_const = p.parse_expr_anon_const()?;
|
||||
ast::InlineAsmOperand::Const { anon_const }
|
||||
@ -164,9 +190,6 @@ pub fn parse_asm_args<'a>(
|
||||
path: path.clone(),
|
||||
};
|
||||
ast::InlineAsmOperand::Sym { sym }
|
||||
} else if !is_global_asm && p.eat_keyword(sym::label) {
|
||||
let block = p.parse_block()?;
|
||||
ast::InlineAsmOperand::Label { block }
|
||||
} else if allow_templates {
|
||||
let template = p.parse_expr()?;
|
||||
// If it can't possibly expand to a string, provide diagnostics here to include other
|
||||
|
@ -181,11 +181,10 @@
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{
|
||||
self as ast, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, Generics,
|
||||
Mutability, PatKind, TyKind, VariantData,
|
||||
Mutability, PatKind, VariantData,
|
||||
};
|
||||
use rustc_attr as attr;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_session::lint::builtin::BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
@ -1599,52 +1598,11 @@ fn create_struct_field_access_fields(
|
||||
),
|
||||
);
|
||||
if is_packed {
|
||||
// In general, fields in packed structs are copied via a
|
||||
// block, e.g. `&{self.0}`. The two exceptions are `[u8]`
|
||||
// and `str` fields, which cannot be copied and also never
|
||||
// cause unaligned references. These exceptions are allowed
|
||||
// to handle the `FlexZeroSlice` type in the `zerovec`
|
||||
// crate within `icu4x-0.9.0`.
|
||||
//
|
||||
// Once use of `icu4x-0.9.0` has dropped sufficiently, this
|
||||
// exception should be removed.
|
||||
let is_simple_path = |ty: &P<ast::Ty>, sym| {
|
||||
if let TyKind::Path(None, ast::Path { segments, .. }) = &ty.kind
|
||||
&& let [seg] = segments.as_slice()
|
||||
&& seg.ident.name == sym
|
||||
&& seg.args.is_none()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let exception = if let TyKind::Slice(ty) = &struct_field.ty.kind
|
||||
&& is_simple_path(ty, sym::u8)
|
||||
{
|
||||
Some("byte")
|
||||
} else if is_simple_path(&struct_field.ty, sym::str) {
|
||||
Some("string")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(ty) = exception {
|
||||
cx.sess.psess.buffer_lint(
|
||||
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
sp,
|
||||
ast::CRATE_NODE_ID,
|
||||
rustc_lint_defs::BuiltinLintDiag::ByteSliceInPackedStructWithDerive {
|
||||
ty: ty.to_string(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// Wrap the expression in `{...}`, causing a copy.
|
||||
field_expr = cx.expr_block(
|
||||
cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
|
||||
);
|
||||
}
|
||||
// Fields in packed structs are wrapped in a block, e.g. `&{self.0}`,
|
||||
// causing a copy instead of a (potentially misaligned) reference.
|
||||
field_expr = cx.expr_block(
|
||||
cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
|
||||
);
|
||||
}
|
||||
cx.expr_addr_of(sp, field_expr)
|
||||
})
|
||||
|
@ -851,6 +851,15 @@ pub(crate) struct GlobalAsmUnsupportedOption {
|
||||
pub(crate) full_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_global_asm_unsupported_operand)]
|
||||
pub(crate) struct GlobalAsmUnsupportedOperand<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) symbol: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_test_runner_invalid)]
|
||||
pub(crate) struct TestRunnerInvalid {
|
||||
|
@ -396,7 +396,7 @@ fn const_validate_mplace<'tcx>(
|
||||
let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
|
||||
let mut ref_tracking = RefTracking::new(mplace.clone());
|
||||
let mut inner = false;
|
||||
while let Some((mplace, path)) = ref_tracking.todo.pop() {
|
||||
while let Some((mplace, path)) = ref_tracking.next() {
|
||||
let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) {
|
||||
_ if cid.promoted.is_some() => CtfeValidationMode::Promoted,
|
||||
Some(mutbl) => CtfeValidationMode::Static { mutbl }, // a `static`
|
||||
|
@ -165,6 +165,13 @@ fn alignment_check(
|
||||
|
||||
/// Whether to enforce the validity invariant for a specific layout.
|
||||
fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool;
|
||||
/// Whether to enforce the validity invariant *recursively*.
|
||||
fn enforce_validity_recursively(
|
||||
_ecx: &InterpCx<'tcx, Self>,
|
||||
_layout: TyAndLayout<'tcx>,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether function calls should be [ABI](CallAbi)-checked.
|
||||
fn enforce_abi(_ecx: &InterpCx<'tcx, Self>) -> bool {
|
||||
|
@ -1006,8 +1006,11 @@ pub fn find_leaked_allocations(
|
||||
})
|
||||
}
|
||||
|
||||
/// Runs the close in "validation" mode, which means the machine's memory read hooks will be
|
||||
/// Runs the closure in "validation" mode, which means the machine's memory read hooks will be
|
||||
/// suppressed. Needless to say, this must only be set with great care! Cannot be nested.
|
||||
///
|
||||
/// We do this so Miri's allocation access tracking does not show the validation
|
||||
/// reads as spurious accesses.
|
||||
pub(super) fn run_for_validation<R>(&self, f: impl FnOnce() -> R) -> R {
|
||||
// This deliberately uses `==` on `bool` to follow the pattern
|
||||
// `assert!(val.replace(new) == old)`.
|
||||
|
@ -572,7 +572,10 @@ pub fn write_immediate(
|
||||
|
||||
if M::enforce_validity(self, dest.layout()) {
|
||||
// Data got changed, better make sure it matches the type!
|
||||
self.validate_operand(&dest.to_op(self)?)?;
|
||||
self.validate_operand(
|
||||
&dest.to_op(self)?,
|
||||
M::enforce_validity_recursively(self, dest.layout()),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -811,7 +814,10 @@ fn copy_op_inner(
|
||||
// Generally for transmutation, data must be valid both at the old and new type.
|
||||
// But if the types are the same, the 2nd validation below suffices.
|
||||
if src.layout().ty != dest.layout().ty && M::enforce_validity(self, src.layout()) {
|
||||
self.validate_operand(&src.to_op(self)?)?;
|
||||
self.validate_operand(
|
||||
&src.to_op(self)?,
|
||||
M::enforce_validity_recursively(self, src.layout()),
|
||||
)?;
|
||||
}
|
||||
|
||||
// Do the actual copy.
|
||||
@ -819,7 +825,10 @@ fn copy_op_inner(
|
||||
|
||||
if validate_dest && M::enforce_validity(self, dest.layout()) {
|
||||
// Data got changed, better make sure it matches the type!
|
||||
self.validate_operand(&dest.to_op(self)?)?;
|
||||
self.validate_operand(
|
||||
&dest.to_op(self)?,
|
||||
M::enforce_validity_recursively(self, dest.layout()),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -155,8 +155,8 @@ fn allow_immutable_unsafe_cell(self) -> bool {
|
||||
|
||||
/// State for tracking recursive validation of references
|
||||
pub struct RefTracking<T, PATH = ()> {
|
||||
pub seen: FxHashSet<T>,
|
||||
pub todo: Vec<(T, PATH)>,
|
||||
seen: FxHashSet<T>,
|
||||
todo: Vec<(T, PATH)>,
|
||||
}
|
||||
|
||||
impl<T: Clone + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH> {
|
||||
@ -169,8 +169,11 @@ pub fn new(op: T) -> Self {
|
||||
ref_tracking_for_consts.seen.insert(op);
|
||||
ref_tracking_for_consts
|
||||
}
|
||||
pub fn next(&mut self) -> Option<(T, PATH)> {
|
||||
self.todo.pop()
|
||||
}
|
||||
|
||||
pub fn track(&mut self, op: T, path: impl FnOnce() -> PATH) {
|
||||
fn track(&mut self, op: T, path: impl FnOnce() -> PATH) {
|
||||
if self.seen.insert(op.clone()) {
|
||||
trace!("Recursing below ptr {:#?}", op);
|
||||
let path = path();
|
||||
@ -435,88 +438,96 @@ fn check_safe_pointer(
|
||||
if self.ecx.scalar_may_be_null(Scalar::from_maybe_pointer(place.ptr(), self.ecx))? {
|
||||
throw_validation_failure!(self.path, NullPtr { ptr_kind })
|
||||
}
|
||||
// Do not allow pointers to uninhabited types.
|
||||
// Do not allow references to uninhabited types.
|
||||
if place.layout.abi.is_uninhabited() {
|
||||
let ty = place.layout.ty;
|
||||
throw_validation_failure!(self.path, PtrToUninhabited { ptr_kind, ty })
|
||||
}
|
||||
// Recursive checking
|
||||
if let Some(ref_tracking) = self.ref_tracking.as_deref_mut() {
|
||||
// Determine whether this pointer expects to be pointing to something mutable.
|
||||
let ptr_expected_mutbl = match ptr_kind {
|
||||
PointerKind::Box => Mutability::Mut,
|
||||
PointerKind::Ref(mutbl) => {
|
||||
// We do not take into account interior mutability here since we cannot know if
|
||||
// there really is an `UnsafeCell` inside `Option<UnsafeCell>` -- so we check
|
||||
// that in the recursive descent behind this reference (controlled by
|
||||
// `allow_immutable_unsafe_cell`).
|
||||
mutbl
|
||||
}
|
||||
};
|
||||
// Proceed recursively even for ZST, no reason to skip them!
|
||||
// `!` is a ZST and we want to validate it.
|
||||
if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr(), 0) {
|
||||
if let Some(ctfe_mode) = self.ctfe_mode {
|
||||
let mut skip_recursive_check = false;
|
||||
if let Some(GlobalAlloc::Static(did)) = self.ecx.tcx.try_get_global_alloc(alloc_id)
|
||||
// CTFE imposes restrictions on what references can point to.
|
||||
if let Ok((alloc_id, _offset, _prov)) =
|
||||
self.ecx.ptr_try_get_alloc_id(place.ptr(), 0)
|
||||
{
|
||||
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else { bug!() };
|
||||
// Special handling for pointers to statics (irrespective of their type).
|
||||
assert!(!self.ecx.tcx.is_thread_local_static(did));
|
||||
assert!(self.ecx.tcx.is_static(did));
|
||||
// Mode-specific checks
|
||||
match self.ctfe_mode {
|
||||
Some(
|
||||
CtfeValidationMode::Static { .. } | CtfeValidationMode::Promoted { .. },
|
||||
) => {
|
||||
// We skip recursively checking other statics. These statics must be sound by
|
||||
// themselves, and the only way to get broken statics here is by using
|
||||
// unsafe code.
|
||||
// The reasons we don't check other statics is twofold. For one, in all
|
||||
// sound cases, the static was already validated on its own, and second, we
|
||||
// trigger cycle errors if we try to compute the value of the other static
|
||||
// and that static refers back to us (potentially through a promoted).
|
||||
// This could miss some UB, but that's fine.
|
||||
// We still walk nested allocations, as they are fundamentally part of this validation run.
|
||||
// This means we will also recurse into nested statics of *other*
|
||||
// statics, even though we do not recurse into other statics directly.
|
||||
// That's somewhat inconsistent but harmless.
|
||||
skip_recursive_check = !nested;
|
||||
}
|
||||
Some(CtfeValidationMode::Const { .. }) => {
|
||||
// We can't recursively validate `extern static`, so we better reject them.
|
||||
if self.ecx.tcx.is_foreign_item(did) {
|
||||
throw_validation_failure!(self.path, ConstRefToExtern);
|
||||
if let Some(GlobalAlloc::Static(did)) =
|
||||
self.ecx.tcx.try_get_global_alloc(alloc_id)
|
||||
{
|
||||
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
|
||||
bug!()
|
||||
};
|
||||
// Special handling for pointers to statics (irrespective of their type).
|
||||
assert!(!self.ecx.tcx.is_thread_local_static(did));
|
||||
assert!(self.ecx.tcx.is_static(did));
|
||||
// Mode-specific checks
|
||||
match ctfe_mode {
|
||||
CtfeValidationMode::Static { .. }
|
||||
| CtfeValidationMode::Promoted { .. } => {
|
||||
// We skip recursively checking other statics. These statics must be sound by
|
||||
// themselves, and the only way to get broken statics here is by using
|
||||
// unsafe code.
|
||||
// The reasons we don't check other statics is twofold. For one, in all
|
||||
// sound cases, the static was already validated on its own, and second, we
|
||||
// trigger cycle errors if we try to compute the value of the other static
|
||||
// and that static refers back to us (potentially through a promoted).
|
||||
// This could miss some UB, but that's fine.
|
||||
// We still walk nested allocations, as they are fundamentally part of this validation run.
|
||||
// This means we will also recurse into nested statics of *other*
|
||||
// statics, even though we do not recurse into other statics directly.
|
||||
// That's somewhat inconsistent but harmless.
|
||||
skip_recursive_check = !nested;
|
||||
}
|
||||
CtfeValidationMode::Const { .. } => {
|
||||
// We can't recursively validate `extern static`, so we better reject them.
|
||||
if self.ecx.tcx.is_foreign_item(did) {
|
||||
throw_validation_failure!(self.path, ConstRefToExtern);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Dangling and Mutability check.
|
||||
let (size, _align, alloc_kind) = self.ecx.get_alloc_info(alloc_id);
|
||||
if alloc_kind == AllocKind::Dead {
|
||||
// This can happen for zero-sized references. We can't have *any* references to non-existing
|
||||
// allocations though, interning rejects them all as the rest of rustc isn't happy with them...
|
||||
// so we throw an error, even though this isn't really UB.
|
||||
// A potential future alternative would be to resurrect this as a zero-sized allocation
|
||||
// (which codegen will then compile to an aligned dummy pointer anyway).
|
||||
throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
|
||||
}
|
||||
// If this allocation has size zero, there is no actual mutability here.
|
||||
if size != Size::ZERO {
|
||||
let alloc_actual_mutbl = mutability(self.ecx, alloc_id);
|
||||
// Mutable pointer to immutable memory is no good.
|
||||
if ptr_expected_mutbl == Mutability::Mut
|
||||
&& alloc_actual_mutbl == Mutability::Not
|
||||
{
|
||||
throw_validation_failure!(self.path, MutableRefToImmutable);
|
||||
// Dangling and Mutability check.
|
||||
let (size, _align, alloc_kind) = self.ecx.get_alloc_info(alloc_id);
|
||||
if alloc_kind == AllocKind::Dead {
|
||||
// This can happen for zero-sized references. We can't have *any* references to
|
||||
// non-existing allocations in const-eval though, interning rejects them all as
|
||||
// the rest of rustc isn't happy with them... so we throw an error, even though
|
||||
// this isn't really UB.
|
||||
// A potential future alternative would be to resurrect this as a zero-sized allocation
|
||||
// (which codegen will then compile to an aligned dummy pointer anyway).
|
||||
throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
|
||||
}
|
||||
// In a const, everything must be completely immutable.
|
||||
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) {
|
||||
// If this allocation has size zero, there is no actual mutability here.
|
||||
if size != Size::ZERO {
|
||||
// Determine whether this pointer expects to be pointing to something mutable.
|
||||
let ptr_expected_mutbl = match ptr_kind {
|
||||
PointerKind::Box => Mutability::Mut,
|
||||
PointerKind::Ref(mutbl) => {
|
||||
// We do not take into account interior mutability here since we cannot know if
|
||||
// there really is an `UnsafeCell` inside `Option<UnsafeCell>` -- so we check
|
||||
// that in the recursive descent behind this reference (controlled by
|
||||
// `allow_immutable_unsafe_cell`).
|
||||
mutbl
|
||||
}
|
||||
};
|
||||
// Determine what it actually points to.
|
||||
let alloc_actual_mutbl = mutability(self.ecx, alloc_id);
|
||||
// Mutable pointer to immutable memory is no good.
|
||||
if ptr_expected_mutbl == Mutability::Mut
|
||||
|| alloc_actual_mutbl == Mutability::Mut
|
||||
&& alloc_actual_mutbl == Mutability::Not
|
||||
{
|
||||
throw_validation_failure!(self.path, ConstRefToMutable);
|
||||
throw_validation_failure!(self.path, MutableRefToImmutable);
|
||||
}
|
||||
// In a const, everything must be completely immutable.
|
||||
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) {
|
||||
if ptr_expected_mutbl == Mutability::Mut
|
||||
|| alloc_actual_mutbl == Mutability::Mut
|
||||
{
|
||||
throw_validation_failure!(self.path, ConstRefToMutable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -524,6 +535,15 @@ fn check_safe_pointer(
|
||||
if skip_recursive_check {
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
// This is not CTFE, so it's Miri with recursive checking.
|
||||
// FIXME: we do *not* check behind boxes, since creating a new box first creates it uninitialized
|
||||
// and then puts the value in there, so briefly we have a box with uninit contents.
|
||||
// FIXME: should we also skip `UnsafeCell` behind shared references? Currently that is not
|
||||
// needed since validation reads bypass Stacked Borrows and data race checks.
|
||||
if matches!(ptr_kind, PointerKind::Box) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
let path = &self.path;
|
||||
ref_tracking.track(place, || {
|
||||
@ -1072,11 +1092,23 @@ pub(crate) fn const_validate_operand(
|
||||
/// `op` is assumed to cover valid memory if it is an indirect operand.
|
||||
/// It will error if the bits at the destination do not match the ones described by the layout.
|
||||
#[inline(always)]
|
||||
pub fn validate_operand(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
|
||||
pub fn validate_operand(
|
||||
&self,
|
||||
op: &OpTy<'tcx, M::Provenance>,
|
||||
recursive: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
// Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's
|
||||
// still correct to not use `ctfe_mode`: that mode is for validation of the final constant
|
||||
// value, it rules out things like `UnsafeCell` in awkward places. It also can make checking
|
||||
// recurse through references which, for now, we don't want here, either.
|
||||
self.validate_operand_internal(op, vec![], None, None)
|
||||
// value, it rules out things like `UnsafeCell` in awkward places.
|
||||
if !recursive {
|
||||
return self.validate_operand_internal(op, vec![], None, None);
|
||||
}
|
||||
// Do a recursive check.
|
||||
let mut ref_tracking = RefTracking::empty();
|
||||
self.validate_operand_internal(op, vec![], Some(&mut ref_tracking), None)?;
|
||||
while let Some((mplace, path)) = ref_tracking.todo.pop() {
|
||||
self.validate_operand_internal(&mplace.into(), path, Some(&mut ref_tracking), None)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ fn might_permit_raw_init_strict<'tcx>(
|
||||
// This does *not* actually check that references are dereferenceable, but since all types that
|
||||
// require dereferenceability also require non-null, we don't actually get any false negatives
|
||||
// due to this.
|
||||
Ok(cx.validate_operand(&ot).is_ok())
|
||||
Ok(cx.validate_operand(&ot, /*recursive*/ false).is_ok())
|
||||
}
|
||||
|
||||
/// Implements the 'lax' (default) version of the `might_permit_raw_init` checks; see that function for
|
||||
|
@ -82,6 +82,9 @@ macro_rules! declare_features {
|
||||
/// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
|
||||
(removed, custom_derive, "1.32.0", Some(29644),
|
||||
Some("subsumed by `#[proc_macro_derive]`")),
|
||||
/// Allows default type parameters to influence type inference.
|
||||
(removed, default_type_parameter_fallback, "CURRENT_RUSTC_VERSION", Some(27336),
|
||||
Some("never properly implemented; requires significant design work")),
|
||||
/// Allows using `#[doc(keyword = "...")]`.
|
||||
(removed, doc_keyword, "1.28.0", Some(51315),
|
||||
Some("merged into `#![feature(rustdoc_internals)]`")),
|
||||
|
@ -431,8 +431,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
(unstable, custom_test_frameworks, "1.30.0", Some(50297)),
|
||||
/// Allows declarative macros 2.0 (`macro`).
|
||||
(unstable, decl_macro, "1.17.0", Some(39412)),
|
||||
/// Allows default type parameters to influence type inference.
|
||||
(unstable, default_type_parameter_fallback, "1.3.0", Some(27336)),
|
||||
/// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait
|
||||
(unstable, deprecated_safe, "1.61.0", Some(94978)),
|
||||
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
|
||||
|
@ -2952,6 +2952,17 @@ pub struct FnDecl<'hir> {
|
||||
pub lifetime_elision_allowed: bool,
|
||||
}
|
||||
|
||||
impl<'hir> FnDecl<'hir> {
|
||||
pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
|
||||
if let FnRetTy::Return(ty) = self.output
|
||||
&& let TyKind::InferDelegation(sig_id, _) = ty.kind
|
||||
{
|
||||
return Some(sig_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents what type of implicit self a function has, if any.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub enum ImplicitSelfKind {
|
||||
|
@ -54,13 +54,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
};
|
||||
}
|
||||
|
||||
// For a delegation item inherit generics from callee.
|
||||
if let Some(sig_id) = tcx.hir().opt_delegation_sig_id(def_id)
|
||||
&& let Some(generics) = inherit_generics_for_delegation_item(tcx, def_id, sig_id)
|
||||
{
|
||||
return generics;
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
let node = tcx.hir_node(hir_id);
|
||||
@ -234,6 +227,16 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
// inherit the generics of the item.
|
||||
Some(parent.to_def_id())
|
||||
}
|
||||
ItemKind::Fn(sig, _, _) => {
|
||||
// For a delegation item inherit generics from callee.
|
||||
if let Some(sig_id) = sig.decl.opt_delegation_sig_id()
|
||||
&& let Some(generics) =
|
||||
inherit_generics_for_delegation_item(tcx, def_id, sig_id)
|
||||
{
|
||||
return generics;
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
@ -335,8 +338,6 @@ enum Defaults {
|
||||
if default.is_some() {
|
||||
match allow_defaults {
|
||||
Defaults::Allowed => {}
|
||||
Defaults::FutureCompatDisallowed
|
||||
if tcx.features().default_type_parameter_fallback => {}
|
||||
Defaults::FutureCompatDisallowed => {
|
||||
tcx.node_span_lint(
|
||||
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
|
||||
|
@ -115,13 +115,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||
None => {}
|
||||
}
|
||||
|
||||
// For a delegation item inherit predicates from callee.
|
||||
if let Some(sig_id) = tcx.hir().opt_delegation_sig_id(def_id)
|
||||
&& let Some(predicates) = inherit_predicates_for_delegation_item(tcx, def_id, sig_id)
|
||||
{
|
||||
return predicates;
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
let node = tcx.hir_node(hir_id);
|
||||
|
||||
@ -151,6 +144,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||
ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => {
|
||||
is_trait = Some(self_bounds);
|
||||
}
|
||||
|
||||
ItemKind::Fn(sig, _, _) => {
|
||||
// For a delegation item inherit predicates from callee.
|
||||
if let Some(sig_id) = sig.decl.opt_delegation_sig_id()
|
||||
&& let Some(predicates) =
|
||||
inherit_predicates_for_delegation_item(tcx, def_id, sig_id)
|
||||
{
|
||||
return predicates;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
|
@ -242,7 +242,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> &'tcx [Ty<'tcx>] {
|
||||
let sig_id = tcx.hir().delegation_sig_id(def_id);
|
||||
let sig_id = tcx.hir().opt_delegation_sig_id(def_id).unwrap();
|
||||
let caller_sig = tcx.fn_sig(sig_id);
|
||||
if let Err(err) = check_constraints(tcx, def_id, sig_id) {
|
||||
let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1;
|
||||
|
@ -48,29 +48,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// Produces warning on the given node, if the current point in the
|
||||
/// function is unreachable, and there hasn't been another warning.
|
||||
pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) {
|
||||
// If span arose from a desugaring of `if` or `while`, then it is the condition itself,
|
||||
// which diverges, that we are about to lint on. This gives suboptimal diagnostics.
|
||||
// Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
|
||||
if span.is_desugaring(DesugaringKind::CondTemporary) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't lint if the result of an async block or async function is `!`.
|
||||
// This does not affect the unreachable lints *within* the body.
|
||||
if span.is_desugaring(DesugaringKind::Async) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't lint *within* the `.await` operator, since that's all just desugaring junk.
|
||||
// We only want to lint if there is a subsequent expression after the `.await`.
|
||||
if span.is_desugaring(DesugaringKind::Await) {
|
||||
return;
|
||||
}
|
||||
|
||||
let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() else {
|
||||
return;
|
||||
};
|
||||
|
||||
match span.desugaring_kind() {
|
||||
// If span arose from a desugaring of `if` or `while`, then it is the condition
|
||||
// itself, which diverges, that we are about to lint on. This gives suboptimal
|
||||
// diagnostics. Instead, stop here so that the `if`- or `while`-expression's
|
||||
// block is linted instead.
|
||||
Some(DesugaringKind::CondTemporary) => return,
|
||||
|
||||
// Don't lint if the result of an async block or async function is `!`.
|
||||
// This does not affect the unreachable lints *within* the body.
|
||||
Some(DesugaringKind::Async) => return,
|
||||
|
||||
// Don't lint *within* the `.await` operator, since that's all just desugaring
|
||||
// junk. We only want to lint if there is a subsequent expression after the
|
||||
// `.await` operator.
|
||||
Some(DesugaringKind::Await) => return,
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Don't warn twice.
|
||||
self.diverges.set(Diverges::WarnedAlways);
|
||||
|
||||
|
@ -543,7 +543,7 @@ macro_rules! add_lint_group {
|
||||
);
|
||||
store.register_removed(
|
||||
"suspicious_auto_trait_impls",
|
||||
"no longer needed, see #93367 \
|
||||
"no longer needed, see issue #93367 \
|
||||
<https://github.com/rust-lang/rust/issues/93367> for more information",
|
||||
);
|
||||
store.register_removed(
|
||||
@ -565,6 +565,11 @@ macro_rules! add_lint_group {
|
||||
"box_pointers",
|
||||
"it does not detect other kinds of allocations, and existed only for historical reasons",
|
||||
);
|
||||
store.register_removed(
|
||||
"byte_slice_in_packed_struct_with_derive",
|
||||
"converted into hard error, see issue #107457 \
|
||||
<https://github.com/rust-lang/rust/issues/107457> for more information",
|
||||
)
|
||||
}
|
||||
|
||||
fn register_internals(store: &mut LintStore) {
|
||||
|
@ -26,7 +26,6 @@
|
||||
BARE_TRAIT_OBJECTS,
|
||||
BINDINGS_WITH_VARIANT_NAME,
|
||||
BREAK_WITH_LABEL_AND_LOOP,
|
||||
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
COHERENCE_LEAK_CHECK,
|
||||
CONFLICTING_REPR_HINTS,
|
||||
@ -1267,7 +1266,7 @@
|
||||
Deny,
|
||||
"type parameter default erroneously allowed in invalid location",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
|
||||
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
||||
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
|
||||
};
|
||||
}
|
||||
@ -4315,39 +4314,6 @@
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
|
||||
/// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
|
||||
/// more built-in traits.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[repr(packed)]
|
||||
/// #[derive(Hash)]
|
||||
/// struct FlexZeroSlice {
|
||||
/// width: u8,
|
||||
/// data: [u8],
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// This was previously accepted but is being phased out, because fields in packed structs are
|
||||
/// now required to implement `Copy` for `derive` to work. Byte slices and string slices are a
|
||||
/// temporary exception because certain crates depended on them.
|
||||
pub BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
Warn,
|
||||
"`[u8]` or `str` used in a packed struct with `derive`",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
||||
reference: "issue #107457 <https://github.com/rust-lang/rust/issues/107457>",
|
||||
};
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments.
|
||||
///
|
||||
|
@ -747,18 +747,7 @@ pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
|
||||
}
|
||||
|
||||
pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option<DefId> {
|
||||
if let Some(ret) = self.get_fn_output(def_id)
|
||||
&& let FnRetTy::Return(ty) = ret
|
||||
&& let TyKind::InferDelegation(sig_id, _) = ty.kind
|
||||
{
|
||||
return Some(sig_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn delegation_sig_id(self, def_id: LocalDefId) -> DefId {
|
||||
self.opt_delegation_sig_id(def_id).unwrap()
|
||||
self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -472,7 +472,8 @@
|
||||
# This is mostly useful for tools; if you have changes to `compiler/` or `library/` they will be ignored.
|
||||
#
|
||||
# Set this to "if-unchanged" to only download if the compiler and standard library have not been modified.
|
||||
# Set this to `true` to download unconditionally (useful if e.g. you are only changing doc-comments).
|
||||
# Set this to `true` to download unconditionally. This is useful if you are working on tools, doc-comments,
|
||||
# or library (you will be able to build the standard library without needing to build the compiler).
|
||||
#download-rustc = false
|
||||
|
||||
# Number of codegen units to use for each compiler invocation. A value of 0
|
||||
|
489
library/Cargo.lock
Normal file
489
library/Cargo.lock
Normal file
@ -0,0 +1,489 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli 0.29.0",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlmalloc"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3264b043b8e977326c1ee9e723da2c1f8d09a99df52cacf00b4dbce5ac54414d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-core",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
"rustc-std-workspace-std",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"memchr",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic_abort"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "panic_unwind"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
"unwind",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc_macro"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiler_builtins"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "4.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e935efc5854715dfc0a4c9ef18dc69dee0ec3bf9cc3ab740db831c0fdd86a3"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi-alloc"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"r-efi",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-alloc"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-core"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-std"
|
||||
version = "1.99.0"
|
||||
dependencies = [
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "std"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"alloc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"dlmalloc",
|
||||
"fortanix-sgx-abi",
|
||||
"hashbrown",
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
"r-efi",
|
||||
"r-efi-alloc",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"rustc-demangle",
|
||||
"std_detect",
|
||||
"unwind",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "std_detect"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysroot"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc_macro",
|
||||
"std",
|
||||
"test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"getopts",
|
||||
"libc",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
"rustc-std-workspace-std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unwind"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"libc",
|
||||
"unwinding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unwinding"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37a19a21a537f635c16c7576f22d0f2f7d63353c1337ad4ce0d8001c7952a25b"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"gimli 0.28.1",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
44
library/Cargo.toml
Normal file
44
library/Cargo.toml
Normal file
@ -0,0 +1,44 @@
|
||||
[workspace]
|
||||
resolver = "1"
|
||||
members = [
|
||||
"std",
|
||||
"sysroot",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
# stdarch has its own Cargo workspace
|
||||
"stdarch",
|
||||
]
|
||||
|
||||
[profile.release.package.compiler_builtins]
|
||||
# For compiler-builtins we always use a high number of codegen units.
|
||||
# The goal here is to place every single intrinsic into its own object
|
||||
# file to avoid symbol clashes with the system libgcc if possible. Note
|
||||
# that this number doesn't actually produce this many object files, we
|
||||
# just don't create more than this number of object files.
|
||||
#
|
||||
# It's a bit of a bummer that we have to pass this here, unfortunately.
|
||||
# Ideally this would be specified through an env var to Cargo so Cargo
|
||||
# knows how many CGUs are for this specific crate, but for now
|
||||
# per-crate configuration isn't specifiable in the environment.
|
||||
codegen-units = 10000
|
||||
|
||||
# These dependencies of the standard library implement symbolication for
|
||||
# backtraces on most platforms. Their debuginfo causes both linking to be slower
|
||||
# (more data to chew through) and binaries to be larger without really all that
|
||||
# much benefit. This section turns them all to down to have no debuginfo which
|
||||
# helps to improve link times a little bit.
|
||||
[profile.release.package]
|
||||
addr2line.debug = 0
|
||||
adler.debug = 0
|
||||
gimli.debug = 0
|
||||
miniz_oxide.debug = 0
|
||||
object.debug = 0
|
||||
rustc-demangle.debug = 0
|
||||
|
||||
[patch.crates-io]
|
||||
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on
|
||||
# here
|
||||
rustc-std-workspace-core = { path = 'rustc-std-workspace-core' }
|
||||
rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' }
|
||||
rustc-std-workspace-std = { path = 'rustc-std-workspace-std' }
|
@ -5,7 +5,7 @@
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::iter::{FusedIterator, Peekable};
|
||||
use core::mem::ManuallyDrop;
|
||||
use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
|
||||
use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub};
|
||||
|
||||
use super::map::{BTreeMap, Keys};
|
||||
use super::merge_iter::MergeIterInner;
|
||||
@ -1182,6 +1182,178 @@ pub const fn len(&self) -> usize {
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Returns a [`Cursor`] pointing at the gap before the smallest element
|
||||
/// greater than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap before the smallest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let cursor = set.lower_bound(Bound::Included(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&1));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&2));
|
||||
///
|
||||
/// let cursor = set.lower_bound(Bound::Excluded(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let cursor = set.lower_bound(Bound::Unbounded);
|
||||
/// assert_eq!(cursor.peek_prev(), None);
|
||||
/// assert_eq!(cursor.peek_next(), Some(&1));
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn lower_bound<Q: ?Sized>(&self, bound: Bound<&Q>) -> Cursor<'_, T>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
Cursor { inner: self.map.lower_bound(bound) }
|
||||
}
|
||||
|
||||
/// Returns a [`CursorMut`] pointing at the gap before the smallest element
|
||||
/// greater than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap before the smallest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let mut set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let mut cursor = set.lower_bound_mut(Bound::Included(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&1));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&2));
|
||||
///
|
||||
/// let mut cursor = set.lower_bound_mut(Bound::Excluded(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let mut cursor = set.lower_bound_mut(Bound::Unbounded);
|
||||
/// assert_eq!(cursor.peek_prev(), None);
|
||||
/// assert_eq!(cursor.peek_next(), Some(&1));
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn lower_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
CursorMut { inner: self.map.lower_bound_mut(bound) }
|
||||
}
|
||||
|
||||
/// Returns a [`Cursor`] pointing at the gap after the greatest element
|
||||
/// smaller than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap after the greatest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let cursor = set.upper_bound(Bound::Included(&3));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&3));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&4));
|
||||
///
|
||||
/// let cursor = set.upper_bound(Bound::Excluded(&3));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let cursor = set.upper_bound(Bound::Unbounded);
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&4));
|
||||
/// assert_eq!(cursor.peek_next(), None);
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn upper_bound<Q: ?Sized>(&self, bound: Bound<&Q>) -> Cursor<'_, T>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
Cursor { inner: self.map.upper_bound(bound) }
|
||||
}
|
||||
|
||||
/// Returns a [`CursorMut`] pointing at the gap after the greatest element
|
||||
/// smaller than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap after the greatest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let mut set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Included(&3)) };
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&3));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&4));
|
||||
///
|
||||
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Excluded(&3)) };
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Unbounded) };
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&4));
|
||||
/// assert_eq!(cursor.peek_next(), None);
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
CursorMut { inner: self.map.upper_bound_mut(bound) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -1816,5 +1988,414 @@ fn min(mut self) -> Option<&'a T> {
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T: Ord> FusedIterator for Union<'_, T> {}
|
||||
|
||||
/// A cursor over a `BTreeSet`.
|
||||
///
|
||||
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth.
|
||||
///
|
||||
/// Cursors always point to a gap between two elements in the set, and can
|
||||
/// operate on the two immediately adjacent elements.
|
||||
///
|
||||
/// A `Cursor` is created with the [`BTreeSet::lower_bound`] and [`BTreeSet::upper_bound`] methods.
|
||||
#[derive(Clone)]
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub struct Cursor<'a, K: 'a> {
|
||||
inner: super::map::Cursor<'a, K, SetValZST>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
impl<K: Debug> Debug for Cursor<'_, K> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("Cursor")
|
||||
}
|
||||
}
|
||||
|
||||
/// A cursor over a `BTreeSet` with editing operations.
|
||||
///
|
||||
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can
|
||||
/// safely mutate the set during iteration. This is because the lifetime of its yielded
|
||||
/// references is tied to its own lifetime, instead of just the underlying map. This means
|
||||
/// cursors cannot yield multiple elements at once.
|
||||
///
|
||||
/// Cursors always point to a gap between two elements in the set, and can
|
||||
/// operate on the two immediately adjacent elements.
|
||||
///
|
||||
/// A `CursorMut` is created with the [`BTreeSet::lower_bound_mut`] and [`BTreeSet::upper_bound_mut`]
|
||||
/// methods.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub struct CursorMut<'a, K: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A = Global>
|
||||
{
|
||||
inner: super::map::CursorMut<'a, K, SetValZST, A>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
impl<K: Debug, A> Debug for CursorMut<'_, K, A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("CursorMut")
|
||||
}
|
||||
}
|
||||
|
||||
/// A cursor over a `BTreeSet` with editing operations, and which allows
|
||||
/// mutating elements.
|
||||
///
|
||||
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can
|
||||
/// safely mutate the set during iteration. This is because the lifetime of its yielded
|
||||
/// references is tied to its own lifetime, instead of just the underlying set. This means
|
||||
/// cursors cannot yield multiple elements at once.
|
||||
///
|
||||
/// Cursors always point to a gap between two elements in the set, and can
|
||||
/// operate on the two immediately adjacent elements.
|
||||
///
|
||||
/// A `CursorMutKey` is created from a [`CursorMut`] with the
|
||||
/// [`CursorMut::with_mutable_key`] method.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Since this cursor allows mutating elements, you must ensure that the
|
||||
/// `BTreeSet` invariants are maintained. Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub struct CursorMutKey<
|
||||
'a,
|
||||
K: 'a,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A = Global,
|
||||
> {
|
||||
inner: super::map::CursorMutKey<'a, K, SetValZST, A>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
impl<K: Debug, A> Debug for CursorMutKey<'_, K, A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("CursorMutKey")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K> Cursor<'a, K> {
|
||||
/// Advances the cursor to the next gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the end of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn next(&mut self) -> Option<&'a K> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Advances the cursor to the previous gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the start of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn prev(&mut self) -> Option<&'a K> {
|
||||
self.inner.prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to next element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the end of the set then `None` is returned
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_next(&self) -> Option<&'a K> {
|
||||
self.inner.peek_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the previous element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the start of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_prev(&self) -> Option<&'a K> {
|
||||
self.inner.peek_prev().map(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, A> CursorMut<'a, T, A> {
|
||||
/// Advances the cursor to the next gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the end of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn next(&mut self) -> Option<&T> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Advances the cursor to the previous gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the start of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn prev(&mut self) -> Option<&T> {
|
||||
self.inner.prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the next element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the end of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_next(&mut self) -> Option<&T> {
|
||||
self.inner.peek_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the previous element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the start of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_prev(&mut self) -> Option<&T> {
|
||||
self.inner.peek_prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a read-only cursor pointing to the same location as the
|
||||
/// `CursorMut`.
|
||||
///
|
||||
/// The lifetime of the returned `Cursor` is bound to that of the
|
||||
/// `CursorMut`, which means it cannot outlive the `CursorMut` and that the
|
||||
/// `CursorMut` is frozen for the lifetime of the `Cursor`.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn as_cursor(&self) -> Cursor<'_, T> {
|
||||
Cursor { inner: self.inner.as_cursor() }
|
||||
}
|
||||
|
||||
/// Converts the cursor into a [`CursorMutKey`], which allows mutating
|
||||
/// elements in the tree.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Since this cursor allows mutating elements, you must ensure that the
|
||||
/// `BTreeSet` invariants are maintained. Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn with_mutable_key(self) -> CursorMutKey<'a, T, A> {
|
||||
CursorMutKey { inner: unsafe { self.inner.with_mutable_key() } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, A> CursorMutKey<'a, T, A> {
|
||||
/// Advances the cursor to the next gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the end of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn next(&mut self) -> Option<&mut T> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Advances the cursor to the previous gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the start of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn prev(&mut self) -> Option<&mut T> {
|
||||
self.inner.prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the next element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the end of the set then `None` is returned
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_next(&mut self) -> Option<&mut T> {
|
||||
self.inner.peek_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the previous element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the start of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_prev(&mut self) -> Option<&mut T> {
|
||||
self.inner.peek_prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a read-only cursor pointing to the same location as the
|
||||
/// `CursorMutKey`.
|
||||
///
|
||||
/// The lifetime of the returned `Cursor` is bound to that of the
|
||||
/// `CursorMutKey`, which means it cannot outlive the `CursorMutKey` and that the
|
||||
/// `CursorMutKey` is frozen for the lifetime of the `Cursor`.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn as_cursor(&self) -> Cursor<'_, T> {
|
||||
Cursor { inner: self.inner.as_cursor() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_after_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_after_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_before_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_before_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_after(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_before(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Removes the next element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (before the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_next(&mut self) -> Option<T> {
|
||||
self.inner.remove_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_prev(&mut self) -> Option<T> {
|
||||
self.inner.remove_prev().map(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The key of the newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_after_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_after_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_before_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_before_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_after(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_before(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Removes the next element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (before the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_next(&mut self) -> Option<T> {
|
||||
self.inner.remove_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_prev(&mut self) -> Option<T> {
|
||||
self.inner.remove_prev().map(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub use super::map::UnorderedKeyError;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -264,6 +264,7 @@
|
||||
#![feature(sse4a_target_feature)]
|
||||
#![feature(tbm_target_feature)]
|
||||
#![feature(wasm_target_feature)]
|
||||
#![feature(x86_amx_intrinsics)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
// allow using `core::` in intra-doc links
|
||||
|
@ -617,8 +617,6 @@ pub const fn as_nanos(&self) -> u128 {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
@ -640,8 +638,6 @@ pub const fn abs_diff(self, other: Duration) -> Duration {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
@ -700,8 +696,6 @@ pub const fn saturating_add(self, rhs: Duration) -> Duration {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
@ -758,8 +752,6 @@ pub const fn saturating_sub(self, rhs: Duration) -> Duration {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
@ -814,8 +806,6 @@ pub const fn saturating_mul(self, rhs: u32) -> Duration {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit df3618d9f35165f4bc548114e511c49c29e1fd9b
|
||||
Subproject commit 47b929ddc521a78b0f699ba8d5c274d28593448a
|
@ -26,7 +26,8 @@
|
||||
use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{
|
||||
exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
|
||||
self, exe, get_clang_cl_resource_dir, get_closest_merge_base_commit, is_debug_info, is_dylib,
|
||||
symlink_dir, t, up_to_date,
|
||||
};
|
||||
use crate::{CLang, Compiler, DependencyType, GitRepo, Mode, LLVM_TOOLS};
|
||||
|
||||
@ -114,21 +115,43 @@ impl Step for Std {
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
// When downloading stage1, the standard library has already been copied to the sysroot, so
|
||||
// there's no need to rebuild it.
|
||||
let builder = run.builder;
|
||||
run.crate_or_deps("sysroot")
|
||||
.path("library")
|
||||
.lazy_default_condition(Box::new(|| !builder.download_rustc()))
|
||||
run.crate_or_deps("sysroot").path("library")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = std_crates_for_run_make(&run);
|
||||
let builder = run.builder;
|
||||
|
||||
// Force compilation of the standard library from source if the `library` is modified. This allows
|
||||
// library team to compile the standard library without needing to compile the compiler with
|
||||
// the `rust.download-rustc=true` option.
|
||||
let force_recompile =
|
||||
if builder.rust_info().is_managed_git_subrepository() && builder.download_rustc() {
|
||||
let closest_merge_commit = get_closest_merge_base_commit(
|
||||
Some(&builder.src),
|
||||
&builder.config.git_config(),
|
||||
&builder.config.stage0_metadata.config.git_merge_commit_email,
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Check if `library` has changes (returns false otherwise)
|
||||
!t!(helpers::git(Some(&builder.src))
|
||||
.args(["diff-index", "--quiet", &closest_merge_commit])
|
||||
.arg("--")
|
||||
.arg(builder.src.join("library"))
|
||||
.as_command_mut()
|
||||
.status())
|
||||
.success()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
run.builder.ensure(Std {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
||||
target: run.target,
|
||||
crates,
|
||||
force_recompile: false,
|
||||
force_recompile,
|
||||
extra_rust_args: &[],
|
||||
is_for_mir_opt_tests: false,
|
||||
});
|
||||
|
@ -1034,6 +1034,8 @@ fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./compiler/rustc_codegen_gcc/Cargo.toml"))
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./library/Cargo.toml"))
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./src/bootstrap/Cargo.toml"))
|
||||
.arg("--sync")
|
||||
.arg(builder.src.join("./src/tools/opt-dist/Cargo.toml"))
|
||||
|
@ -47,6 +47,7 @@ fn run(self, builder: &Builder<'_>) -> Self::Output {
|
||||
"src/tools/rust-analyzer/Cargo.toml",
|
||||
"compiler/rustc_codegen_cranelift/Cargo.toml",
|
||||
"compiler/rustc_codegen_gcc/Cargo.toml",
|
||||
"library/Cargo.toml",
|
||||
"src/bootstrap/Cargo.toml",
|
||||
"src/tools/rustbook/Cargo.toml",
|
||||
] {
|
||||
|
@ -1845,6 +1845,23 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
|
||||
config.llvm_from_ci = config.parse_download_ci_llvm(download_ci_llvm, asserts);
|
||||
|
||||
if config.llvm_from_ci {
|
||||
let warn = |option: &str| {
|
||||
println!(
|
||||
"WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
|
||||
);
|
||||
println!(
|
||||
"HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
|
||||
);
|
||||
};
|
||||
|
||||
if static_libstdcpp.is_some() {
|
||||
warn("static-libstdcpp");
|
||||
}
|
||||
|
||||
if link_shared.is_some() {
|
||||
warn("link-shared");
|
||||
}
|
||||
|
||||
// None of the LLVM options, except assertions, are supported
|
||||
// when using downloaded LLVM. We could just ignore these but
|
||||
// that's potentially confusing, so force them to not be
|
||||
@ -1854,9 +1871,6 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
|
||||
check_ci_llvm!(optimize_toml);
|
||||
check_ci_llvm!(thin_lto);
|
||||
check_ci_llvm!(release_debuginfo);
|
||||
// CI-built LLVM can be either dynamic or static. We won't know until we download it.
|
||||
check_ci_llvm!(link_shared);
|
||||
check_ci_llvm!(static_libstdcpp);
|
||||
check_ci_llvm!(targets);
|
||||
check_ci_llvm!(experimental_targets);
|
||||
check_ci_llvm!(clang_cl);
|
||||
|
@ -86,6 +86,9 @@ fn workspace_members(build: &Build) -> Vec<Package> {
|
||||
packages
|
||||
};
|
||||
|
||||
// Collects `metadata.packages` from all workspaces.
|
||||
collect_metadata("Cargo.toml")
|
||||
// Collects `metadata.packages` from the root and library workspaces.
|
||||
let mut packages = vec![];
|
||||
packages.extend(collect_metadata("Cargo.toml"));
|
||||
packages.extend(collect_metadata("library/Cargo.toml"));
|
||||
packages
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
rinja = { version = "0.2", default-features = false, features = ["config"] }
|
||||
rinja = { version = "0.3", default-features = false, features = ["config"] }
|
||||
base64 = "0.21.7"
|
||||
itertools = "0.12"
|
||||
indexmap = "2"
|
||||
|
@ -1677,13 +1677,16 @@ pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
|
||||
/// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
|
||||
///
|
||||
/// [clean]: crate::clean
|
||||
pub(crate) fn def_id(&self, cache: &Cache) -> Option<DefId> {
|
||||
let t: PrimitiveType = match *self {
|
||||
Type::Path { ref path } => return Some(path.def_id()),
|
||||
DynTrait(ref bounds, _) => return bounds.get(0).map(|b| b.trait_.def_id()),
|
||||
Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
|
||||
Primitive(p) => return cache.primitive_locations.get(&p).cloned(),
|
||||
BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
|
||||
BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
|
||||
BorrowedRef { ref type_, .. } => return type_.def_id(cache),
|
||||
Tuple(ref tys) => {
|
||||
if tys.is_empty() {
|
||||
PrimitiveType::Unit
|
||||
@ -1696,17 +1699,10 @@ fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
|
||||
Array(..) => PrimitiveType::Array,
|
||||
Type::Pat(..) => PrimitiveType::Pat,
|
||||
RawPointer(..) => PrimitiveType::RawPointer,
|
||||
QPath(box QPathData { ref self_type, .. }) => return self_type.inner_def_id(cache),
|
||||
QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
|
||||
Generic(_) | Infer | ImplTrait(_) => return None,
|
||||
};
|
||||
cache.and_then(|c| Primitive(t).def_id(c))
|
||||
}
|
||||
|
||||
/// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
|
||||
///
|
||||
/// [clean]: crate::clean
|
||||
pub(crate) fn def_id(&self, cache: &Cache) -> Option<DefId> {
|
||||
self.inner_def_id(Some(cache))
|
||||
Primitive(t).def_id(cache)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,153 +260,21 @@ fn is_from_private_dep(tcx: TyCtxt<'_>, cache: &Cache, def_id: DefId) -> bool {
|
||||
}
|
||||
|
||||
// Index this method for searching later on.
|
||||
if let Some(s) = item.name.or_else(|| {
|
||||
if item.is_stripped() {
|
||||
None
|
||||
} else if let clean::ImportItem(ref i) = *item.kind
|
||||
&& let clean::ImportKind::Simple(s) = i.kind
|
||||
{
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
let (parent, is_inherent_impl_item) = match *item.kind {
|
||||
clean::StrippedItem(..) => ((None, None), false),
|
||||
clean::AssocConstItem(..) | clean::AssocTypeItem(..)
|
||||
if self
|
||||
.cache
|
||||
.parent_stack
|
||||
.last()
|
||||
.is_some_and(|parent| parent.is_trait_impl()) =>
|
||||
let search_name = if !item.is_stripped() {
|
||||
item.name.or_else(|| {
|
||||
if let clean::ImportItem(ref i) = *item.kind
|
||||
&& let clean::ImportKind::Simple(s) = i.kind
|
||||
{
|
||||
// skip associated items in trait impls
|
||||
((None, None), false)
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
clean::TyMethodItem(..)
|
||||
| clean::TyAssocConstItem(..)
|
||||
| clean::TyAssocTypeItem(..)
|
||||
| clean::StructFieldItem(..)
|
||||
| clean::VariantItem(..) => (
|
||||
(
|
||||
Some(
|
||||
self.cache
|
||||
.parent_stack
|
||||
.last()
|
||||
.expect("parent_stack is empty")
|
||||
.item_id()
|
||||
.expect_def_id(),
|
||||
),
|
||||
Some(&self.cache.stack[..self.cache.stack.len() - 1]),
|
||||
),
|
||||
false,
|
||||
),
|
||||
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
|
||||
if self.cache.parent_stack.is_empty() {
|
||||
((None, None), false)
|
||||
} else {
|
||||
let last = self.cache.parent_stack.last().expect("parent_stack is empty 2");
|
||||
let did = match &*last {
|
||||
ParentStackItem::Impl {
|
||||
// impl Trait for &T { fn method(self); }
|
||||
//
|
||||
// When generating a function index with the above shape, we want it
|
||||
// associated with `T`, not with the primitive reference type. It should
|
||||
// show up as `T::method`, rather than `reference::method`, in the search
|
||||
// results page.
|
||||
for_: clean::Type::BorrowedRef { type_, .. },
|
||||
..
|
||||
} => type_.def_id(&self.cache),
|
||||
ParentStackItem::Impl { for_, .. } => for_.def_id(&self.cache),
|
||||
ParentStackItem::Type(item_id) => item_id.as_def_id(),
|
||||
};
|
||||
let path = did
|
||||
.and_then(|did| self.cache.paths.get(&did))
|
||||
// The current stack not necessarily has correlation
|
||||
// for where the type was defined. On the other
|
||||
// hand, `paths` always has the right
|
||||
// information if present.
|
||||
.map(|(fqp, _)| &fqp[..fqp.len() - 1]);
|
||||
((did, path), true)
|
||||
}
|
||||
}
|
||||
_ => ((None, Some(&*self.cache.stack)), false),
|
||||
};
|
||||
|
||||
match parent {
|
||||
(parent, Some(path)) if is_inherent_impl_item || !self.cache.stripped_mod => {
|
||||
debug_assert!(!item.is_stripped());
|
||||
|
||||
// A crate has a module at its root, containing all items,
|
||||
// which should not be indexed. The crate-item itself is
|
||||
// inserted later on when serializing the search-index.
|
||||
if item.item_id.as_def_id().is_some_and(|idx| !idx.is_crate_root())
|
||||
&& let ty = item.type_()
|
||||
&& (ty != ItemType::StructField
|
||||
|| u16::from_str_radix(s.as_str(), 10).is_err())
|
||||
{
|
||||
let desc =
|
||||
short_markdown_summary(&item.doc_value(), &item.link_names(self.cache));
|
||||
// For searching purposes, a re-export is a duplicate if:
|
||||
//
|
||||
// - It's either an inline, or a true re-export
|
||||
// - It's got the same name
|
||||
// - Both of them have the same exact path
|
||||
let defid = (match &*item.kind {
|
||||
&clean::ItemKind::ImportItem(ref import) => import.source.did,
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| item.item_id.as_def_id());
|
||||
// In case this is a field from a tuple struct, we don't add it into
|
||||
// the search index because its name is something like "0", which is
|
||||
// not useful for rustdoc search.
|
||||
self.cache.search_index.push(IndexItem {
|
||||
ty,
|
||||
defid,
|
||||
name: s,
|
||||
path: join_with_double_colon(path),
|
||||
desc,
|
||||
parent,
|
||||
parent_idx: None,
|
||||
exact_path: None,
|
||||
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
|
||||
self.cache.parent_stack.last()
|
||||
{
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
search_type: get_function_type_for_search(
|
||||
&item,
|
||||
self.tcx,
|
||||
clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
|
||||
parent,
|
||||
self.cache,
|
||||
),
|
||||
aliases: item.attrs.get_doc_aliases(),
|
||||
deprecation: item.deprecation(self.tcx),
|
||||
});
|
||||
}
|
||||
}
|
||||
(Some(parent), None) if is_inherent_impl_item => {
|
||||
// We have a parent, but we don't know where they're
|
||||
// defined yet. Wait for later to index this item.
|
||||
let impl_generics = clean_impl_generics(self.cache.parent_stack.last());
|
||||
self.cache.orphan_impl_items.push(OrphanImplItem {
|
||||
parent,
|
||||
item: item.clone(),
|
||||
impl_generics,
|
||||
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
|
||||
self.cache.parent_stack.last()
|
||||
{
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(name) = search_name {
|
||||
add_item_to_search_index(self.tcx, &mut self.cache, &item, name)
|
||||
}
|
||||
|
||||
// Keep track of the fully qualified path for this item.
|
||||
@ -572,6 +440,152 @@ fn is_from_private_dep(tcx: TyCtxt<'_>, cache: &Cache, def_id: DefId) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::Item, name: Symbol) {
|
||||
// Item has a name, so it must also have a DefId (can't be an impl, let alone a blanket or auto impl).
|
||||
let item_def_id = item.item_id.as_def_id().unwrap();
|
||||
let (parent_did, parent_path) = match *item.kind {
|
||||
clean::StrippedItem(..) => return,
|
||||
clean::AssocConstItem(..) | clean::AssocTypeItem(..)
|
||||
if cache.parent_stack.last().is_some_and(|parent| parent.is_trait_impl()) =>
|
||||
{
|
||||
// skip associated items in trait impls
|
||||
return;
|
||||
}
|
||||
clean::TyMethodItem(..)
|
||||
| clean::TyAssocConstItem(..)
|
||||
| clean::TyAssocTypeItem(..)
|
||||
| clean::StructFieldItem(..)
|
||||
| clean::VariantItem(..) => {
|
||||
// Don't index if containing module is stripped (i.e., private),
|
||||
// or if item is tuple struct/variant field (name is a number -> not useful for search).
|
||||
if cache.stripped_mod
|
||||
|| item.type_() == ItemType::StructField
|
||||
&& name.as_str().chars().all(|c| c.is_digit(10))
|
||||
{
|
||||
return;
|
||||
}
|
||||
let parent_did =
|
||||
cache.parent_stack.last().expect("parent_stack is empty").item_id().expect_def_id();
|
||||
let parent_path = &cache.stack[..cache.stack.len() - 1];
|
||||
(Some(parent_did), parent_path)
|
||||
}
|
||||
clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => {
|
||||
let last = cache.parent_stack.last().expect("parent_stack is empty 2");
|
||||
let parent_did = match &*last {
|
||||
// impl Trait for &T { fn method(self); }
|
||||
//
|
||||
// When generating a function index with the above shape, we want it
|
||||
// associated with `T`, not with the primitive reference type. It should
|
||||
// show up as `T::method`, rather than `reference::method`, in the search
|
||||
// results page.
|
||||
ParentStackItem::Impl { for_: clean::Type::BorrowedRef { type_, .. }, .. } => {
|
||||
type_.def_id(&cache)
|
||||
}
|
||||
ParentStackItem::Impl { for_, .. } => for_.def_id(&cache),
|
||||
ParentStackItem::Type(item_id) => item_id.as_def_id(),
|
||||
};
|
||||
let Some(parent_did) = parent_did else { return };
|
||||
// The current stack reflects the CacheBuilder's recursive
|
||||
// walk over HIR. For associated items, this is the module
|
||||
// where the `impl` block is defined. That's an implementation
|
||||
// detail that we don't want to affect the search engine.
|
||||
//
|
||||
// In particular, you can arrange things like this:
|
||||
//
|
||||
// #![crate_name="me"]
|
||||
// mod private_mod {
|
||||
// impl Clone for MyThing { fn clone(&self) -> MyThing { MyThing } }
|
||||
// }
|
||||
// pub struct MyThing;
|
||||
//
|
||||
// When that happens, we need to:
|
||||
// - ignore the `cache.stripped_mod` flag, since the Clone impl is actually
|
||||
// part of the public API even though it's defined in a private module
|
||||
// - present the method as `me::MyThing::clone`, its publicly-visible path
|
||||
// - deal with the fact that the recursive walk hasn't actually reached `MyThing`
|
||||
// until it's already past `private_mod`, since that's first, and doesn't know
|
||||
// yet if `MyThing` will actually be public or not (it could be re-exported)
|
||||
//
|
||||
// We accomplish the last two points by recording children of "orphan impls"
|
||||
// in a field of the cache whose elements are added to the search index later,
|
||||
// after cache building is complete (see `handle_orphan_impl_child`).
|
||||
match cache.paths.get(&parent_did) {
|
||||
Some((fqp, _)) => (Some(parent_did), &fqp[..fqp.len() - 1]),
|
||||
None => {
|
||||
handle_orphan_impl_child(cache, item, parent_did);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Don't index if item is crate root, which is inserted later on when serializing the index.
|
||||
// Don't index if containing module is stripped (i.e., private),
|
||||
if item_def_id.is_crate_root() || cache.stripped_mod {
|
||||
return;
|
||||
}
|
||||
(None, &*cache.stack)
|
||||
}
|
||||
};
|
||||
|
||||
debug_assert!(!item.is_stripped());
|
||||
|
||||
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
|
||||
// For searching purposes, a re-export is a duplicate if:
|
||||
//
|
||||
// - It's either an inline, or a true re-export
|
||||
// - It's got the same name
|
||||
// - Both of them have the same exact path
|
||||
let defid = match &*item.kind {
|
||||
clean::ItemKind::ImportItem(import) => import.source.did.unwrap_or(item_def_id),
|
||||
_ => item_def_id,
|
||||
};
|
||||
let path = join_with_double_colon(parent_path);
|
||||
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let search_type = get_function_type_for_search(
|
||||
&item,
|
||||
tcx,
|
||||
clean_impl_generics(cache.parent_stack.last()).as_ref(),
|
||||
parent_did,
|
||||
cache,
|
||||
);
|
||||
let aliases = item.attrs.get_doc_aliases();
|
||||
let deprecation = item.deprecation(tcx);
|
||||
let index_item = IndexItem {
|
||||
ty: item.type_(),
|
||||
defid: Some(defid),
|
||||
name,
|
||||
path,
|
||||
desc,
|
||||
parent: parent_did,
|
||||
parent_idx: None,
|
||||
exact_path: None,
|
||||
impl_id,
|
||||
search_type,
|
||||
aliases,
|
||||
deprecation,
|
||||
};
|
||||
cache.search_index.push(index_item);
|
||||
}
|
||||
|
||||
/// We have a parent, but we don't know where they're
|
||||
/// defined yet. Wait for later to index this item.
|
||||
/// See [`Cache::orphan_impl_items`].
|
||||
fn handle_orphan_impl_child(cache: &mut Cache, item: &clean::Item, parent_did: DefId) {
|
||||
let impl_generics = clean_impl_generics(cache.parent_stack.last());
|
||||
let impl_id = if let Some(ParentStackItem::Impl { item_id, .. }) = cache.parent_stack.last() {
|
||||
item_id.as_def_id()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let orphan_item =
|
||||
OrphanImplItem { parent: parent_did, item: item.clone(), impl_generics, impl_id };
|
||||
cache.orphan_impl_items.push(orphan_item);
|
||||
}
|
||||
|
||||
pub(crate) struct OrphanImplItem {
|
||||
pub(crate) parent: DefId,
|
||||
pub(crate) impl_id: Option<DefId>,
|
||||
|
@ -930,7 +930,7 @@ a.doc-anchor {
|
||||
left: -17px;
|
||||
/* We add this padding so that when the cursor moves from the heading's text to the anchor,
|
||||
the anchor doesn't disappear. */
|
||||
padding-right: 5px;
|
||||
padding-right: 10px;
|
||||
/* And this padding is used to make the anchor larger and easier to click on. */
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
@ -398,6 +398,8 @@ to Miri failing to detect cases of undefined behavior in a program.
|
||||
application instead of raising an error within the context of Miri (and halting
|
||||
execution). Note that code might not expect these operations to ever panic, so
|
||||
this flag can lead to strange (mis)behavior.
|
||||
* `-Zmiri-recursive-validation` is a *highly experimental* flag that makes validity checking
|
||||
recurse below references.
|
||||
* `-Zmiri-retag-fields[=<all|none|scalar>]` controls when Stacked Borrows retagging recurses into
|
||||
fields. `all` means it always recurses (the default, and equivalent to `-Zmiri-retag-fields`
|
||||
without an explicit value), `none` means it never recurses, `scalar` means it only recurses for
|
||||
|
@ -1 +1 @@
|
||||
1df0458781d6fd753a68c4cdc4de5313b1635dbd
|
||||
29e924841f06bb181d87494eba2783761bc1ddec
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_driver::Compilation;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
@ -53,6 +52,8 @@
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields, ValidationMode};
|
||||
|
||||
struct MiriCompilerCalls {
|
||||
miri_config: miri::MiriConfig,
|
||||
}
|
||||
@ -474,7 +475,9 @@ fn main() {
|
||||
} else if arg == "--" {
|
||||
after_dashdash = true;
|
||||
} else if arg == "-Zmiri-disable-validation" {
|
||||
miri_config.validate = false;
|
||||
miri_config.validation = ValidationMode::No;
|
||||
} else if arg == "-Zmiri-recursive-validation" {
|
||||
miri_config.validation = ValidationMode::Deep;
|
||||
} else if arg == "-Zmiri-disable-stacked-borrows" {
|
||||
miri_config.borrow_tracker = None;
|
||||
} else if arg == "-Zmiri-tree-borrows" {
|
||||
|
@ -68,7 +68,7 @@ pub enum IsolatedOp {
|
||||
Allow,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum BacktraceStyle {
|
||||
/// Prints a terser backtrace which ideally only contains relevant information.
|
||||
Short,
|
||||
@ -78,6 +78,16 @@ pub enum BacktraceStyle {
|
||||
Off,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ValidationMode {
|
||||
/// Do not perform any kind of validation.
|
||||
No,
|
||||
/// Validate the interior of the value, but not things behind references.
|
||||
Shallow,
|
||||
/// Fully recursively validate references.
|
||||
Deep,
|
||||
}
|
||||
|
||||
/// Configuration needed to spawn a Miri instance.
|
||||
#[derive(Clone)]
|
||||
pub struct MiriConfig {
|
||||
@ -85,7 +95,7 @@ pub struct MiriConfig {
|
||||
/// (This is still subject to isolation as well as `forwarded_env_vars`.)
|
||||
pub env: Vec<(OsString, OsString)>,
|
||||
/// Determine if validity checking is enabled.
|
||||
pub validate: bool,
|
||||
pub validation: ValidationMode,
|
||||
/// Determines if Stacked Borrows or Tree Borrows is enabled.
|
||||
pub borrow_tracker: Option<BorrowTrackerMethod>,
|
||||
/// Whether `core::ptr::Unique` receives special treatment.
|
||||
@ -162,7 +172,7 @@ impl Default for MiriConfig {
|
||||
fn default() -> MiriConfig {
|
||||
MiriConfig {
|
||||
env: vec![],
|
||||
validate: true,
|
||||
validation: ValidationMode::Shallow,
|
||||
borrow_tracker: Some(BorrowTrackerMethod::StackedBorrows),
|
||||
unique_is_unique: false,
|
||||
check_alignment: AlignmentCheck::Int,
|
||||
|
@ -153,7 +153,7 @@ fn emulate_intrinsic_by_name(
|
||||
// Would not be considered UB, or the other way around (`is_val_statically_known(0)`).
|
||||
"is_val_statically_known" => {
|
||||
let [arg] = check_arg_count(args)?;
|
||||
this.validate_operand(arg)?;
|
||||
this.validate_operand(arg, /*recursive*/ false)?;
|
||||
let branch: bool = this.machine.rng.get_mut().gen();
|
||||
this.write_scalar(Scalar::from_bool(branch), dest)?;
|
||||
}
|
||||
|
@ -142,6 +142,7 @@
|
||||
};
|
||||
pub use crate::eval::{
|
||||
create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
|
||||
ValidationMode,
|
||||
};
|
||||
pub use crate::helpers::{AccessKind, EvalContextExt as _};
|
||||
pub use crate::machine::{
|
||||
|
@ -187,7 +187,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
pub type MemoryKind = interpret::MemoryKind<MiriMemoryKind>;
|
||||
|
||||
/// Pointer provenance.
|
||||
#[derive(Clone, Copy)]
|
||||
// This needs to be `Eq`+`Hash` because the `Machine` trait needs that because validity checking
|
||||
// *might* be recursive and then it has to track which places have already been visited.
|
||||
// These implementations are a bit questionable, and it means we may check the same place multiple
|
||||
// times with different provenance, but that is in general not wrong.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Provenance {
|
||||
/// For pointers with concrete provenance. we exactly know which allocation they are attached to
|
||||
/// and what their borrow tag is.
|
||||
@ -215,24 +219,6 @@ pub enum Provenance {
|
||||
Wildcard,
|
||||
}
|
||||
|
||||
// This needs to be `Eq`+`Hash` because the `Machine` trait needs that because validity checking
|
||||
// *might* be recursive and then it has to track which places have already been visited.
|
||||
// However, comparing provenance is meaningless, since `Wildcard` might be any provenance -- and of
|
||||
// course we don't actually do recursive checking.
|
||||
// We could change `RefTracking` to strip provenance for its `seen` set but that type is generic so that is quite annoying.
|
||||
// Instead owe add the required instances but make them panic.
|
||||
impl PartialEq for Provenance {
|
||||
fn eq(&self, _other: &Self) -> bool {
|
||||
panic!("Provenance must not be compared")
|
||||
}
|
||||
}
|
||||
impl Eq for Provenance {}
|
||||
impl std::hash::Hash for Provenance {
|
||||
fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {
|
||||
panic!("Provenance must not be hashed")
|
||||
}
|
||||
}
|
||||
|
||||
/// The "extra" information a pointer has over a regular AllocId.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum ProvenanceExtra {
|
||||
@ -460,7 +446,7 @@ pub struct MiriMachine<'tcx> {
|
||||
pub(crate) isolated_op: IsolatedOp,
|
||||
|
||||
/// Whether to enforce the validity invariant.
|
||||
pub(crate) validate: bool,
|
||||
pub(crate) validation: ValidationMode,
|
||||
|
||||
/// The table of file descriptors.
|
||||
pub(crate) fds: shims::FdTable,
|
||||
@ -659,7 +645,7 @@ pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>)
|
||||
cmd_line: None,
|
||||
tls: TlsData::default(),
|
||||
isolated_op: config.isolated_op,
|
||||
validate: config.validate,
|
||||
validation: config.validation,
|
||||
fds: shims::FdTable::init(config.mute_stdout_stderr),
|
||||
dirs: Default::default(),
|
||||
layouts,
|
||||
@ -801,7 +787,7 @@ fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
fds,
|
||||
tcx: _,
|
||||
isolated_op: _,
|
||||
validate: _,
|
||||
validation: _,
|
||||
clock: _,
|
||||
layouts: _,
|
||||
static_roots: _,
|
||||
@ -943,7 +929,14 @@ fn alignment_check(
|
||||
|
||||
#[inline(always)]
|
||||
fn enforce_validity(ecx: &MiriInterpCx<'tcx>, _layout: TyAndLayout<'tcx>) -> bool {
|
||||
ecx.machine.validate
|
||||
ecx.machine.validation != ValidationMode::No
|
||||
}
|
||||
#[inline(always)]
|
||||
fn enforce_validity_recursively(
|
||||
ecx: &InterpCx<'tcx, Self>,
|
||||
_layout: TyAndLayout<'tcx>,
|
||||
) -> bool {
|
||||
ecx.machine.validation == ValidationMode::Deep
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -0,0 +1,8 @@
|
||||
//@compile-flags: -Zmiri-recursive-validation
|
||||
|
||||
fn main() {
|
||||
let x = 3u8;
|
||||
let xref = &x;
|
||||
let xref_wrong_type: &bool = unsafe { std::mem::transmute(xref) }; //~ERROR: encountered 0x03, but expected a boolean
|
||||
let _val = *xref_wrong_type;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
error: Undefined Behavior: constructing invalid value at .<deref>: encountered 0x03, but expected a boolean
|
||||
--> $DIR/recursive-validity-ref-bool.rs:LL:CC
|
||||
|
|
||||
LL | let xref_wrong_type: &bool = unsafe { std::mem::transmute(xref) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered 0x03, but expected a boolean
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
= note: inside `main` at $DIR/recursive-validity-ref-bool.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -23,8 +23,6 @@ run-make/no-alloc-shim/Makefile
|
||||
run-make/pdb-buildinfo-cl-cmd/Makefile
|
||||
run-make/pgo-gen-lto/Makefile
|
||||
run-make/pgo-indirect-call-promotion/Makefile
|
||||
run-make/print-calling-conventions/Makefile
|
||||
run-make/print-target-list/Makefile
|
||||
run-make/raw-dylib-alt-calling-convention/Makefile
|
||||
run-make/raw-dylib-c/Makefile
|
||||
run-make/redundant-libs/Makefile
|
||||
|
@ -54,6 +54,7 @@
|
||||
pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, &[&str])] = &[
|
||||
// The root workspace has to be first for check_rustfix to work.
|
||||
(".", EXCEPTIONS, Some((&["rustc-main"], PERMITTED_RUSTC_DEPENDENCIES)), &[]),
|
||||
("library", EXCEPTIONS_STDLIB, Some((&["sysroot"], PERMITTED_STDLIB_DEPENDENCIES)), &[]),
|
||||
// Outside of the alphabetical section because rustfmt formats it using multiple lines.
|
||||
(
|
||||
"compiler/rustc_codegen_cranelift",
|
||||
@ -90,7 +91,6 @@
|
||||
("colored", "MPL-2.0"), // rustfmt
|
||||
("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
|
||||
("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
|
||||
("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target. FIXME: this dependency violates the documentation comment above.
|
||||
("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
|
||||
("mdbook", "MPL-2.0"), // mdbook
|
||||
("option-ext", "MPL-2.0"), // cargo-miri (via `directories`)
|
||||
@ -108,6 +108,17 @@
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
/// These are exceptions to Rust's permissive licensing policy, and
|
||||
/// should be considered bugs. Exceptions are only allowed in Rust
|
||||
/// tooling. It is _crucial_ that no exception crates be dependencies
|
||||
/// of the Rust runtime (std/test).
|
||||
#[rustfmt::skip]
|
||||
const EXCEPTIONS_STDLIB: ExceptionList = &[
|
||||
// tidy-alphabetical-start
|
||||
("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target. FIXME: this dependency violates the documentation comment above.
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
// FIXME uncomment once rust-lang/stdarch#1462 lands
|
||||
/*
|
||||
const EXCEPTIONS_STDARCH: ExceptionList = &[
|
||||
@ -228,10 +239,6 @@
|
||||
"ring",
|
||||
];
|
||||
|
||||
/// These are the root crates that are part of the runtime. The licenses for
|
||||
/// these and all their dependencies *must not* be in the exception list.
|
||||
const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"];
|
||||
|
||||
const PERMITTED_DEPS_LOCATION: &str = concat!(file!(), ":", line!());
|
||||
|
||||
/// Crates rustc is allowed to depend on. Avoid adding to the list if possible.
|
||||
@ -240,7 +247,6 @@
|
||||
/// rustc. Please check with the compiler team before adding an entry.
|
||||
const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"addr2line",
|
||||
"adler",
|
||||
"ahash",
|
||||
"aho-corasick",
|
||||
@ -256,7 +262,6 @@
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"compiler_builtins",
|
||||
"cpufeatures",
|
||||
"crc32fast",
|
||||
"crossbeam-channel",
|
||||
@ -276,7 +281,6 @@
|
||||
"digest",
|
||||
"displaydoc",
|
||||
"dissimilar",
|
||||
"dlmalloc",
|
||||
"either",
|
||||
"elsa",
|
||||
"ena",
|
||||
@ -291,7 +295,6 @@
|
||||
"fluent-langneg",
|
||||
"fluent-syntax",
|
||||
"fnv",
|
||||
"fortanix-sgx-abi",
|
||||
"generic-array",
|
||||
"getopts",
|
||||
"getrandom",
|
||||
@ -354,12 +357,9 @@
|
||||
"pulldown-cmark-escape",
|
||||
"punycode",
|
||||
"quote",
|
||||
"r-efi",
|
||||
"r-efi-alloc",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_xorshift",
|
||||
"rand_xoshiro",
|
||||
"redox_syscall",
|
||||
"regex",
|
||||
@ -429,7 +429,6 @@
|
||||
"unicode-security",
|
||||
"unicode-width",
|
||||
"unicode-xid",
|
||||
"unwinding",
|
||||
"valuable",
|
||||
"version_check",
|
||||
"wasi",
|
||||
@ -463,6 +462,46 @@
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"addr2line",
|
||||
"adler",
|
||||
"allocator-api2",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"compiler_builtins",
|
||||
"dlmalloc",
|
||||
"fortanix-sgx-abi",
|
||||
"getopts",
|
||||
"gimli",
|
||||
"hashbrown",
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"memchr",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"r-efi",
|
||||
"r-efi-alloc",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rand_xorshift",
|
||||
"rustc-demangle",
|
||||
"unicode-width",
|
||||
"unwinding",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
"windows-targets",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"ahash",
|
||||
@ -556,9 +595,8 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
|
||||
check_permitted_dependencies(&metadata, workspace, permitted_deps, crates, bad);
|
||||
}
|
||||
|
||||
if workspace == "." {
|
||||
let runtime_ids = compute_runtime_crates(&metadata);
|
||||
check_runtime_license_exceptions(&metadata, runtime_ids, bad);
|
||||
if workspace == "library" {
|
||||
check_runtime_license_exceptions(&metadata, bad);
|
||||
checked_runtime_licenses = true;
|
||||
}
|
||||
}
|
||||
@ -583,16 +621,8 @@ pub fn has_missing_submodule(root: &Path, submodules: &[&str]) -> bool {
|
||||
///
|
||||
/// Unlike for tools we don't allow exceptions to the `LICENSES` list for the runtime with the sole
|
||||
/// exception of `fortanix-sgx-abi` which is only used on x86_64-fortanix-unknown-sgx.
|
||||
fn check_runtime_license_exceptions(
|
||||
metadata: &Metadata,
|
||||
runtime_ids: HashSet<&PackageId>,
|
||||
bad: &mut bool,
|
||||
) {
|
||||
fn check_runtime_license_exceptions(metadata: &Metadata, bad: &mut bool) {
|
||||
for pkg in &metadata.packages {
|
||||
if !runtime_ids.contains(&pkg.id) {
|
||||
// Only checking dependencies of runtime libraries here.
|
||||
continue;
|
||||
}
|
||||
if pkg.source.is_none() {
|
||||
// No need to check local packages.
|
||||
continue;
|
||||
@ -613,20 +643,6 @@ fn check_runtime_license_exceptions(
|
||||
continue;
|
||||
}
|
||||
|
||||
// This exception is due to the fact that the feature set of the
|
||||
// `object` crate is different between rustc and libstd. In the
|
||||
// standard library only a conservative set of features are enabled
|
||||
// which notably does not include the `wasm` feature which pulls in
|
||||
// this dependency. In the compiler, however, the `wasm` feature is
|
||||
// enabled. This exception is intended to be here so long as the
|
||||
// `EXCEPTIONS` above contains `wasmparser`, but once that goes away
|
||||
// this can be removed.
|
||||
if pkg.name == "wasmparser"
|
||||
&& pkg.license.as_deref() == Some("Apache-2.0 WITH LLVM-exception")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tidy_error!(bad, "invalid license `{}` in `{}`", license, pkg.id);
|
||||
}
|
||||
}
|
||||
@ -758,16 +774,6 @@ fn pkg_from_id<'a>(metadata: &'a Metadata, id: &PackageId) -> &'a Package {
|
||||
metadata.packages.iter().find(|p| &p.id == id).unwrap()
|
||||
}
|
||||
|
||||
/// Finds all the packages that are in the rust runtime.
|
||||
fn compute_runtime_crates<'a>(metadata: &'a Metadata) -> HashSet<&'a PackageId> {
|
||||
let mut result = HashSet::new();
|
||||
for name in RUNTIME_CRATES {
|
||||
let id = &pkg_from_name(metadata, name).id;
|
||||
deps_of(metadata, id, &mut result);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Recursively find all dependencies.
|
||||
fn deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId, result: &mut HashSet<&'a PackageId>) {
|
||||
if !result.insert(pkg_id) {
|
||||
|
@ -4,11 +4,6 @@
|
||||
|
||||
use crate::walk::{filter_dirs, walk};
|
||||
|
||||
fn is_edition_2021(mut line: &str) -> bool {
|
||||
line = line.trim();
|
||||
line == "edition = \"2021\""
|
||||
}
|
||||
|
||||
pub fn check(path: &Path, bad: &mut bool) {
|
||||
walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| {
|
||||
let file = entry.path();
|
||||
@ -17,8 +12,15 @@ pub fn check(path: &Path, bad: &mut bool) {
|
||||
return;
|
||||
}
|
||||
|
||||
let is_2021 = contents.lines().any(is_edition_2021);
|
||||
if !is_2021 {
|
||||
let is_2021 = contents.lines().any(|line| line.trim() == "edition = \"2021\"");
|
||||
|
||||
let is_workspace = contents.lines().any(|line| line.trim() == "[workspace]");
|
||||
let is_package = contents.lines().any(|line| line.trim() == "[package]");
|
||||
assert!(is_workspace || is_package);
|
||||
|
||||
// Check that all packages use the 2021 edition. Virtual workspaces don't allow setting an
|
||||
// edition, so these shouldn't be checked.
|
||||
if is_package && !is_2021 {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"{} doesn't have `edition = \"2021\"` on a separate line",
|
||||
|
19
tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
Normal file
19
tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
Normal file
@ -0,0 +1,19 @@
|
||||
//@ compile-flags: -O
|
||||
//@ min-llvm-version: 19
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub enum State {
|
||||
A([u8; 753]),
|
||||
B([u8; 753]),
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @update
|
||||
#[no_mangle]
|
||||
pub unsafe fn update(s: *mut State) {
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: store i8
|
||||
// CHECK-NEXT: ret
|
||||
let State::A(v) = s.read() else { std::hint::unreachable_unchecked() };
|
||||
s.write(State::B(v));
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//@ compile-flags: -C opt-level=3 -C target-cpu=cannonlake
|
||||
//@ only-x86_64
|
||||
|
||||
// In a previous implementation, _mm512_reduce_add_pd did the reduction with all fast-math flags
|
||||
// enabled, making it UB to reduce a vector containing a NaN.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(stdarch_x86_avx512, avx512_target_feature)]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
// CHECK-LABEL: @demo(
|
||||
#[no_mangle]
|
||||
#[target_feature(enable = "avx512f")] // Function-level target feature mismatches inhibit inlining
|
||||
pub unsafe fn demo() -> bool {
|
||||
// CHECK: %0 = tail call reassoc double @llvm.vector.reduce.fadd.v8f64(
|
||||
// CHECK: %_0.i = fcmp uno double %0, 0.000000e+00
|
||||
// CHECK: ret i1 %_0.i
|
||||
let res =
|
||||
unsafe { _mm512_reduce_add_pd(_mm512_set_pd(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, f64::NAN)) };
|
||||
res.is_nan()
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) --print calling-conventions
|
@ -6,7 +6,6 @@
|
||||
//! It also checks that some targets have the correct set cfgs.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::OsString;
|
||||
use std::iter::FromIterator;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -91,10 +90,8 @@ fn check_(output: &str, includes: &[&str], disallow: &[&str]) {
|
||||
// --print=cfg=PATH
|
||||
{
|
||||
let tmp_path = PathBuf::from(format!("{target}.cfg"));
|
||||
let mut print_arg = OsString::from("--print=cfg=");
|
||||
print_arg.push(tmp_path.as_os_str());
|
||||
|
||||
rustc().target(target).arg(print_arg).run();
|
||||
rustc().target(target).print(&format!("cfg={}", tmp_path.display())).run();
|
||||
|
||||
let output = rfs::read_to_string(&tmp_path);
|
||||
|
||||
|
@ -87,7 +87,7 @@ fn main() {
|
||||
|
||||
fn check(CheckCfg { args, contains }: CheckCfg) {
|
||||
let output =
|
||||
rustc().input("lib.rs").arg("-Zunstable-options").arg("--print=check-cfg").args(args).run();
|
||||
rustc().input("lib.rs").arg("-Zunstable-options").print("check-cfg").args(args).run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# Checks that all the targets returned by `rustc --print target-list` are valid
|
||||
# target specifications
|
||||
all:
|
||||
for target in $(shell $(BARE_RUSTC) --print target-list); do \
|
||||
$(BARE_RUSTC) --target $$target --print sysroot; \
|
||||
done
|
21
tests/run-make/print-target-list/rmake.rs
Normal file
21
tests/run-make/print-target-list/rmake.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Checks that all the targets returned by `rustc --print target-list` are valid
|
||||
// target specifications
|
||||
|
||||
use run_make_support::bare_rustc;
|
||||
|
||||
// FIXME(127877): certain experimental targets fail with creating a 'LLVM TargetMachine'
|
||||
// in CI, so we skip them
|
||||
const EXPERIMENTAL_TARGETS: &[&str] = &["avr", "m68k", "csky", "xtensa"];
|
||||
|
||||
fn main() {
|
||||
let targets = bare_rustc().print("target-list").run().stdout_utf8();
|
||||
|
||||
for target in targets.lines() {
|
||||
// skip experimental targets that would otherwise fail
|
||||
if EXPERIMENTAL_TARGETS.iter().any(|experimental| target.contains(experimental)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bare_rustc().target(target).print("sysroot").run();
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
//! This checks the output of some `--print` options when
|
||||
//! output to a file (instead of stdout)
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::{rfs, rustc, target};
|
||||
@ -44,10 +43,8 @@ fn check_(output: &str, includes: &[&str]) {
|
||||
// --print={option}=PATH
|
||||
let output = {
|
||||
let tmp_path = PathBuf::from(format!("{}.txt", args.option));
|
||||
let mut print_arg = OsString::from(format!("--print={}=", args.option));
|
||||
print_arg.push(tmp_path.as_os_str());
|
||||
|
||||
rustc().target(args.target).arg(print_arg).run();
|
||||
rustc().target(args.target).print(&format!("{}={}", args.option, tmp_path.display())).run();
|
||||
|
||||
rfs::read_to_string(&tmp_path)
|
||||
};
|
||||
|
@ -11,8 +11,7 @@ fn main() {
|
||||
let dylib_name = rustc()
|
||||
.crate_name(proc_crate_name)
|
||||
.crate_type("dylib")
|
||||
.arg("--print")
|
||||
.arg("file-names")
|
||||
.print("file-names")
|
||||
.arg("-")
|
||||
.run()
|
||||
.stdout_utf8();
|
||||
|
@ -146,5 +146,16 @@ fn main() {
|
||||
//~^ ERROR asm template must be a string literal
|
||||
global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
|
||||
//~^ ERROR asm template must be a string literal
|
||||
global_asm!("{}", label {});
|
||||
//~^ ERROR expected operand, options, or additional template string
|
||||
|
||||
global_asm!("{}", in(reg));
|
||||
//~^ ERROR the `in` operand cannot be used with `global_asm!`
|
||||
global_asm!("{}", out(reg));
|
||||
//~^ ERROR the `out` operand cannot be used with `global_asm!`
|
||||
global_asm!("{}", lateout(reg));
|
||||
//~^ ERROR the `lateout` operand cannot be used with `global_asm!`
|
||||
global_asm!("{}", inout(reg));
|
||||
//~^ ERROR the `inout` operand cannot be used with `global_asm!`
|
||||
global_asm!("{}", inlateout(reg));
|
||||
//~^ ERROR the `inlateout` operand cannot be used with `global_asm!`
|
||||
global_asm!("{}", label(reg));
|
||||
//~^ ERROR the `label` operand cannot be used with `global_asm!`
|
||||
|
@ -380,11 +380,41 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
|
||||
|
|
||||
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected operand, options, or additional template string
|
||||
--> $DIR/parse-error.rs:149:19
|
||||
error: the `in` operand cannot be used with `global_asm!`
|
||||
--> $DIR/parse-error.rs:150:19
|
||||
|
|
||||
LL | global_asm!("{}", label {});
|
||||
| ^^^^^^^^ expected operand, options, or additional template string
|
||||
LL | global_asm!("{}", in(reg));
|
||||
| ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
error: the `out` operand cannot be used with `global_asm!`
|
||||
--> $DIR/parse-error.rs:152:19
|
||||
|
|
||||
LL | global_asm!("{}", out(reg));
|
||||
| ^^^ the `out` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
error: the `lateout` operand cannot be used with `global_asm!`
|
||||
--> $DIR/parse-error.rs:154:19
|
||||
|
|
||||
LL | global_asm!("{}", lateout(reg));
|
||||
| ^^^^^^^ the `lateout` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
error: the `inout` operand cannot be used with `global_asm!`
|
||||
--> $DIR/parse-error.rs:156:19
|
||||
|
|
||||
LL | global_asm!("{}", inout(reg));
|
||||
| ^^^^^ the `inout` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
error: the `inlateout` operand cannot be used with `global_asm!`
|
||||
--> $DIR/parse-error.rs:158:19
|
||||
|
|
||||
LL | global_asm!("{}", inlateout(reg));
|
||||
| ^^^^^^^^^ the `inlateout` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
error: the `label` operand cannot be used with `global_asm!`
|
||||
--> $DIR/parse-error.rs:160:19
|
||||
|
|
||||
LL | global_asm!("{}", label(reg));
|
||||
| ^^^^^ the `label` operand is not meaningful for global-scoped inline assembly, remove it
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/parse-error.rs:39:37
|
||||
@ -441,6 +471,6 @@ help: consider using `const` instead of `let`
|
||||
LL | const bar: /* Type */ = 0;
|
||||
| ~~~~~ ++++++++++++
|
||||
|
||||
error: aborting due to 67 previous errors
|
||||
error: aborting due to 72 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0435`.
|
||||
|
@ -22,25 +22,22 @@
|
||||
struct X(Y);
|
||||
//~^ ERROR cannot move out of `self` which is behind a shared reference
|
||||
|
||||
// This is currently allowed, but will be phased out at some point. From
|
||||
// `zerovec` within icu4x-0.9.0.
|
||||
#[derive(Debug)]
|
||||
#[repr(packed)]
|
||||
struct FlexZeroSlice {
|
||||
width: u8,
|
||||
data: [u8],
|
||||
//~^ WARNING byte slice in a packed struct that derives a built-in trait
|
||||
//~^^ this was previously accepted
|
||||
//~^ ERROR cannot move
|
||||
//~| ERROR cannot move
|
||||
}
|
||||
|
||||
// Again, currently allowed, but will be phased out.
|
||||
#[derive(Debug)]
|
||||
#[repr(packed)]
|
||||
struct WithStr {
|
||||
width: u8,
|
||||
data: str,
|
||||
//~^ WARNING string slice in a packed struct that derives a built-in trait
|
||||
//~^^ this was previously accepted
|
||||
//~^ ERROR cannot move
|
||||
//~| ERROR cannot move
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,32 +1,3 @@
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:31:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: [u8],
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: string slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:41:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: str,
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0507]: cannot move out of `self` which is behind a shared reference
|
||||
--> $DIR/deriving-with-repr-packed.rs:22:10
|
||||
|
|
||||
@ -47,38 +18,43 @@ LL | struct X(Y);
|
||||
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error; 2 warnings emitted
|
||||
error[E0161]: cannot move a value of type `[u8]`
|
||||
--> $DIR/deriving-with-repr-packed.rs:29:5
|
||||
|
|
||||
LL | data: [u8],
|
||||
| ^^^^^^^^^^ the size of `[u8]` cannot be statically determined
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:31:5
|
||||
error[E0507]: cannot move out of `self.data` which is behind a shared reference
|
||||
--> $DIR/deriving-with-repr-packed.rs:29:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: [u8],
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^^^^^^ move occurs because `self.data` has type `[u8]`, which does not implement the `Copy` trait
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
warning: string slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:41:5
|
||||
error[E0161]: cannot move a value of type `str`
|
||||
--> $DIR/deriving-with-repr-packed.rs:38:5
|
||||
|
|
||||
LL | data: str,
|
||||
| ^^^^^^^^^ the size of `str` cannot be statically determined
|
||||
|
||||
error[E0507]: cannot move out of `self.data` which is behind a shared reference
|
||||
--> $DIR/deriving-with-repr-packed.rs:38:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: str,
|
||||
| ^^^^^^^^^
|
||||
| ^^^^^^^^^ move occurs because `self.data` has type `str`, which does not implement the `Copy` trait
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0161, E0507.
|
||||
For more information about an error, try `rustc --explain E0161`.
|
||||
|
@ -73,16 +73,6 @@ impl Copy for PackedManualCopy {}
|
||||
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct Unsized([u32]);
|
||||
|
||||
// A packed struct with an unsized `[u8]` field. This is currently allowed, but
|
||||
// causes a warning and will be phased out at some point.
|
||||
#[derive(Debug, Hash)]
|
||||
#[repr(packed)]
|
||||
struct PackedUnsizedU8([u8]);
|
||||
//~^ WARNING byte slice in a packed struct that derives a built-in trait
|
||||
//~^^ WARNING byte slice in a packed struct that derives a built-in trait
|
||||
//~^^^ this was previously accepted
|
||||
//~^^^^ this was previously accepted
|
||||
|
||||
trait Trait {
|
||||
type A;
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ----- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ---- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: this warning originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ----- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ---- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
@ -516,26 +516,6 @@ impl ::core::cmp::Ord for Unsized {
|
||||
}
|
||||
}
|
||||
|
||||
// A packed struct with an unsized `[u8]` field. This is currently allowed, but
|
||||
// causes a warning and will be phased out at some point.
|
||||
#[repr(packed)]
|
||||
struct PackedUnsizedU8([u8]);
|
||||
#[automatically_derived]
|
||||
impl ::core::fmt::Debug for PackedUnsizedU8 {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
::core::fmt::Formatter::debug_tuple_field1_finish(f,
|
||||
"PackedUnsizedU8", &&self.0)
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl ::core::hash::Hash for PackedUnsizedU8 {
|
||||
#[inline]
|
||||
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
|
||||
::core::hash::Hash::hash(&self.0, state)
|
||||
}
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
type A;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
|
||||
thread 'main' panicked at core/src/panicking.rs:$LINE:$COL:
|
||||
attempted to compute the size or alignment of extern type `Opaque`
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
thread caused non-unwinding panic. aborting.
|
||||
|
@ -1,4 +1,4 @@
|
||||
thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
|
||||
thread 'main' panicked at core/src/panicking.rs:$LINE:$COL:
|
||||
attempted to compute the size or alignment of extern type `A`
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
thread caused non-unwinding panic. aborting.
|
||||
|
@ -1,4 +1,4 @@
|
||||
thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
|
||||
thread 'main' panicked at core/src/panicking.rs:$LINE:$COL:
|
||||
attempted to compute the size or alignment of extern type `A`
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
thread caused non-unwinding panic. aborting.
|
||||
|
@ -1,21 +0,0 @@
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/feature-gate-default_type_parameter_fallback.rs:3:8
|
||||
|
|
||||
LL | fn avg<T=i32>(_: T) {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/feature-gate-default_type_parameter_fallback.rs:8:6
|
||||
|
|
||||
LL | impl<T=i32> S<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,3 +1,3 @@
|
||||
thread 'main' panicked at library/alloc/src/raw_vec.rs:LL:CC:
|
||||
thread 'main' panicked at alloc/src/raw_vec.rs:LL:CC:
|
||||
capacity overflow
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
@ -433,3 +433,25 @@ error: aborting due to 50 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0599, E0658, E0666.
|
||||
For more information about an error, try `rustc --explain E0053`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/where-allowed.rs:239:7
|
||||
|
|
||||
LL | impl <T = impl Debug> T {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/where-allowed.rs:246:36
|
||||
|
|
||||
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
fn avg<T=T::Item>(_: T) {}
|
||||
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
|
||||
//~| ERROR defaults for type parameters
|
||||
//~| WARN previously accepted
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,30 @@
|
||||
error[E0128]: generic parameters with a default cannot use forward declared identifiers
|
||||
--> $DIR/issue-26812.rs:3:10
|
||||
--> $DIR/issue-26812.rs:1:10
|
||||
|
|
||||
LL | fn avg<T=T::Item>(_: T) {}
|
||||
| ^^^^^^^ defaulted generic parameters cannot be forward declared
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/issue-26812.rs:1:8
|
||||
|
|
||||
LL | fn avg<T=T::Item>(_: T) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0128`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/issue-26812.rs:1:8
|
||||
|
|
||||
LL | fn avg<T=T::Item>(_: T) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
@ -72,3 +72,14 @@ error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0214, E0308, E0770.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/unusual-rib-combinations.rs:15:6
|
||||
|
|
||||
LL | fn c<T = u8()>() {}
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
@ -4,6 +4,6 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
thread 'main' panicked at $DIR/panic-in-cleanup.rs:16:9:
|
||||
BOOM
|
||||
stack backtrace:
|
||||
thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
|
||||
thread 'main' panicked at core/src/panicking.rs:$LINE:$COL:
|
||||
panic in a destructor during cleanup
|
||||
thread caused non-unwinding panic. aborting.
|
||||
|
@ -1,7 +1,7 @@
|
||||
thread 'main' panicked at $DIR/panic-in-ffi.rs:12:5:
|
||||
Test
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
|
||||
thread 'main' panicked at core/src/panicking.rs:$LINE:$COL:
|
||||
panic in a function that cannot unwind
|
||||
stack backtrace:
|
||||
thread caused non-unwinding panic. aborting.
|
||||
|
2
tests/ui/print-calling-conventions.rs
Normal file
2
tests/ui/print-calling-conventions.rs
Normal file
@ -0,0 +1,2 @@
|
||||
//@ compile-flags: --print calling-conventions
|
||||
//@ build-pass
|
34
tests/ui/print-calling-conventions.stdout
Normal file
34
tests/ui/print-calling-conventions.stdout
Normal file
@ -0,0 +1,34 @@
|
||||
C
|
||||
C-cmse-nonsecure-call
|
||||
C-unwind
|
||||
Rust
|
||||
aapcs
|
||||
aapcs-unwind
|
||||
avr-interrupt
|
||||
avr-non-blocking-interrupt
|
||||
cdecl
|
||||
cdecl-unwind
|
||||
efiapi
|
||||
fastcall
|
||||
fastcall-unwind
|
||||
msp430-interrupt
|
||||
ptx-kernel
|
||||
riscv-interrupt-m
|
||||
riscv-interrupt-s
|
||||
rust-call
|
||||
rust-cold
|
||||
rust-intrinsic
|
||||
stdcall
|
||||
stdcall-unwind
|
||||
system
|
||||
system-unwind
|
||||
sysv64
|
||||
sysv64-unwind
|
||||
thiscall
|
||||
thiscall-unwind
|
||||
unadjusted
|
||||
vectorcall
|
||||
vectorcall-unwind
|
||||
win64
|
||||
win64-unwind
|
||||
x86-interrupt
|
@ -1,3 +1,3 @@
|
||||
thread 'main' panicked at library/std/src/io/stdio.rs:LL:CC:
|
||||
thread 'main' panicked at std/src/io/stdio.rs:LL:CC:
|
||||
failed printing to stdout: Broken pipe (os error 32)
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
@ -12,3 +12,13 @@ LL | foo::<T, U>();
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:3:11
|
||||
|
|
||||
LL | fn foo<T, U = u64>() -> (T, U) {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
|
43
tests/ui/type/default_type_parameter_in_fn_or_impl.stderr
Normal file
43
tests/ui/type/default_type_parameter_in_fn_or_impl.stderr
Normal file
@ -0,0 +1,43 @@
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:3:8
|
||||
|
|
||||
LL | fn avg<T=i32>(_: T) {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:8:6
|
||||
|
|
||||
LL | impl<T=i32> S<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:3:8
|
||||
|
|
||||
LL | fn avg<T=i32>(_: T) {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:8:6
|
||||
|
|
||||
LL | impl<T=i32> S<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
Loading…
Reference in New Issue
Block a user